338 for (
size_t v = 0;
v != verts->size(); ++
v) {
339 bool gain =
false,
computed =
false;
340 bool unique = !group_layers ||
layers.size() == 0;
342 std::vector<LayerItem> layer(
adapter.size());
343 for (
size_t i = 0; i !=
adapter.size(); ++i) {
345 layer[i].material = this->geometry->getMaterial(p);
346 for (
const std::string& role : this->geometry->getRolesAt(p)) {
347 if (role.substr(0, 3) ==
"opt")
348 layer[i].roles.insert(role);
349 else if (role ==
"unique") {
350 layer[i].roles.insert(role);
352 }
else if (role ==
"inEpsilon") {
353 layer[i].roles.insert(role);
355 }
else if (role ==
"QW" || role ==
"QD" || role ==
"gain") {
356 layer[i].roles.insert(role);
363 for (
size_t l = 0; l !=
layers.size(); ++l) {
365 for (
size_t i = 0; i !=
layers[l].size(); ++i) {
366 if (
layers[l][i] != layer[i]) {
378 stack.push_back(lcount++);
379 layers.emplace_back(std::move(layer));
380 lgained.push_back(gain);
384 assert(vbounds->size() == stack.size() - 1);
385 assert(verts->size() == stack.size());
390 if (group_layers && inTemperature.hasProvider() && !
isnan(max_temp_diff) && !
isinf(max_temp_diff) && !
isnan(temp_dist) &&
394 for (
size_t l = 0; l != nl; ++l) {
396 std::list<std::list<size_t>>
groups;
397 typedef std::list<std::list<size_t>>::iterator
ListIterator;
399 for (
size_t i = 0, j = 0; i != stack.size(); ++i) {
402 groups.emplace_back(std::list<size_t>({j++}));
405 size_t n = indices.size();
407 std::unique_ptr<double[]>
dists(
new double[
n *
n]);
408#define dists_at(a, b) dists[(a) * n + (b)]
409 for (
size_t i = 0; i !=
n; ++i) {
411 for (
size_t j = i + 1; j !=
n; ++j) {
413 for (
size_t k = 0; k !=
adapter.size(); ++k) {
437 if (
mdt > 0.66667 * max_temp_diff)
break;
443 for (++g; g !=
groups.end(); ++g) {
444 for (
ItemIterator i = g->begin();
i != g->end(); ++
i) stack[indices[*i]] = lcount;
445 lgained.push_back(lgained[l]);
446 lcomputed.push_back(lcomputed[l]);
451 assert(lgained.size() == lcount);
452 assert(lcomputed.size() == lcount);
454 if (!
isnan(interface_position)) {
456 vbounds->begin() + 1;
458 if (std::size_t(interface) > vbounds->size()) interface = vbounds->size();
463 std::ptrdiff_t
i1 =
interface - 1;
464 for (
size_t i = 0;
i < vbounds->size(); ++
i) {
465 if (stack[i] == stack[i + 1] && i !=
i1) {
467 vbounds->removePoint(i);
468 verts->removePoints(i, i + 2);
470 OrderedAxis::WarningOff
nowarn(verts);
472 }
else if (i == vbounds->size()) {
473 OrderedAxis::WarningOff
nowarn(verts);
476 verts->addPoint(0.5 * (vbounds->at(i - 1) + vbounds->at(i)));
485 if (vbounds->size() == 1)
break;
497 if (interface >= 0) {
498 double pos = vbounds->at(interface - 1);
506template <
typename BaseT>
511 if (!
isnan(
real(lam)))
throw BadInput(this->getId(),
"wavelength cannot be specified for outEpsilon in this solver");
514 setExpansionDefaults(
false);
523 while (
auto level = levels->yield()) {
524 double h = level->vpos();
525 size_t n = getLayerFor(h);
528 for (
size_t i = 0; i != level->size(); ++i)
result[level->index(i)] = data[i];
536template <
typename BaseT>
541 if (!
isnan(
real(lam)))
throw BadInput(this->getId(),
"wavelength cannot be specified for outRefractiveIndex in this solver");
552 throw BadInput(getId(),
"wrong refractive index component");
560 if (std::size_t(
RE.cols()) !=
N || std::size_t(
RE.rows()) !=
N)
RE.reset(
N,
N);
561 if (std::size_t(
RH.cols()) !=
N || std::size_t(
RH.rows()) !=
N)
RH.reset(
N,
N);
570 dcomplex k0 = 2
e3 *
M_PI / lam;
578 initTransfer(expansion,
true);
582 transfer->initDiagonalization();
583 transfer->diagonalizer->diagonalizeLayer(layer);
584 }
else if (!transfer->diagonalizer->isDiagonalized(layer))
585 transfer->diagonalizer->diagonalizeLayer(layer);
590 size_t layer = initIncidence(side, lam);
591 if (idx >= transfer->diagonalizer->matrixSize())
throw BadInput(getId(),
"wrong incident eignenmode index");
592 cvector incident(transfer->diagonalizer->matrixSize(), 0.);
595 scaleIncidentVector(incident, layer);
599template <
typename BaseT>
601 size_t layer = initIncidence(side, lam);
602 if (incident.
size() != transfer->diagonalizer->matrixSize())
throw BadInput(getId(),
"wrong incident vector size");
604 scaleIncidentVector(
result, layer);
610 size_t N =
transfer->diagonalizer->matrixSize();
611 for (
size_t i = 0; i !=
N; ++i) {
612 double P =
real(incident[i] *
conj(incident[i]));
618 for (
size_t i = 0; i !=
N; ++i) incident[i] *=
norm;
626 throw NotImplemented(getId(),
"CylindicalSolver::incidentVector");
642 size_t N =
transfer->diagonalizer->matrixSize();
647 for (
size_t i = 0; i !=
N; ++i) {
648 double P =
real(incident[i] *
conj(incident[i]));
668 size_t N =
transfer->diagonalizer->matrixSize();
673 for (
size_t i = 0; i !=
N; ++i) {
674 double P =
real(incident[i] *
conj(incident[i]));
678 for (
size_t i = 0; i !=
N; ++i) {
699 size_t N =
transfer->diagonalizer->matrixSize();
704 for (
size_t i = 0; i !=
N; ++i) {
705 double P =
real(incident[i] *
conj(incident[i]));
709 for (
size_t i = 0; i !=
N; ++i) {
724 return transfer->getReflectionVector(incident, side);
731 return transfer->getTransmissionVector(incident, side);
734template <
typename BaseT>
735template <PropagationDirection part>
740 double power = applyMode(num);
741 return transfer->getFieldE(power, dst_mesh, method,
part);
744template <
typename BaseT>
745template <PropagationDirection part>
750 double power = applyMode(num);
751 return transfer->getFieldH(power, dst_mesh, method,
part);
754template <
typename BaseT>
759 double power = applyMode(num);
760 return transfer->getFieldMagnitude(power, dst_mesh, method);