338 layer[i].roles.insert(role);
340 }
else if (role ==
"inEpsilon") {
341 layer[i].roles.insert(role);
343 }
else if (role ==
"QW" || role ==
"QD" || role ==
"gain") {
344 layer[i].roles.insert(role);
351 for (
size_t l = 0; l !=
layers.size(); ++l) {
353 for (
size_t i = 0;
i !=
layers[l].size(); ++
i) {
354 if (
layers[l][i] != layer[i]) {
366 stack.push_back(lcount++);
367 layers.emplace_back(std::move(layer));
368 lgained.push_back(gain);
378 if (group_layers && inTemperature.hasProvider() && !
isnan(max_temp_diff) && !
isinf(max_temp_diff) && !
isnan(temp_dist) &&
382 for (
size_t l = 0; l !=
nl; ++l) {
383 std::vector<size_t> indices;
384 std::list<std::list<size_t>>
groups;
385 typedef std::list<std::list<size_t>>::iterator
ListIterator;
387 for (
size_t i = 0, j = 0;
i !=
stack.size(); ++
i) {
389 indices.push_back(i);
390 groups.emplace_back(std::list<size_t>({j++}));
393 size_t n = indices.size();
395 std::unique_ptr<double[]>
dists(
new double[
n *
n]);
396#define dists_at(a, b) dists[(a) * n + (b)]
397 for (
size_t i = 0;
i !=
n; ++
i) {
399 for (
size_t j = i + 1; j !=
n; ++j) {
401 for (
size_t k = 0; k !=
adapter.size(); ++k) {
425 if (
mdt > 0.66667 * max_temp_diff)
break;
431 for (++g; g !=
groups.end(); ++g) {
432 for (
ItemIterator i = g->begin();
i != g->end(); ++
i) stack[indices[*i]] = lcount;
433 lgained.push_back(lgained[l]);
434 lcomputed.push_back(lcomputed[l]);
439 assert(lgained.size() == lcount);
440 assert(lcomputed.size() == lcount);
442 if (!
isnan(interface_position)) {
444 vbounds->begin() + 1;
446 if (std::size_t(interface) > vbounds->size()) interface = vbounds->size();
451 std::ptrdiff_t
i1 =
interface - 1;
452 for (
size_t i = 0;
i < vbounds->size(); ++
i) {
453 if (stack[i] == stack[i + 1] && i !=
i1) {
455 vbounds->removePoint(i);
456 verts->removePoints(i, i + 2);
458 OrderedAxis::WarningOff
nowarn(verts);
460 }
else if (i == vbounds->size()) {
461 OrderedAxis::WarningOff
nowarn(verts);
464 verts->addPoint(0.5 * (vbounds->at(i - 1) + vbounds->at(i)));
473 if (vbounds->size() == 1)
break;
485 if (interface >= 0) {
486 double pos = vbounds->at(interface - 1);
494template <
typename BaseT>
499 if (!
isnan(
real(lam)))
throw BadInput(this->getId(),
"wavelength cannot be specified for outEpsilon in this solver");
502 setExpansionDefaults(
false);
511 while (
auto level = levels->yield()) {
512 double h = level->vpos();
513 size_t n = getLayerFor(h);
516 for (
size_t i = 0; i != level->size(); ++i)
result[level->index(i)] = data[i];
524template <
typename BaseT>
529 if (!
isnan(
real(lam)))
throw BadInput(this->getId(),
"wavelength cannot be specified for outRefractiveIndex in this solver");
540 throw BadInput(getId(),
"wrong refractive index component");
548 if (std::size_t(
RE.cols()) !=
N || std::size_t(
RE.rows()) !=
N)
RE.reset(
N,
N);
549 if (std::size_t(
RH.cols()) !=
N || std::size_t(
RH.rows()) !=
N)
RH.reset(
N,
N);
558 dcomplex k0 = 2
e3 *
M_PI / lam;
566 initTransfer(expansion,
true);
570 transfer->initDiagonalization();
571 transfer->diagonalizer->diagonalizeLayer(layer);
572 }
else if (!transfer->diagonalizer->isDiagonalized(layer))
573 transfer->diagonalizer->diagonalizeLayer(layer);
578 size_t layer = initIncidence(side, lam);
579 if (idx >= transfer->diagonalizer->matrixSize())
throw BadInput(getId(),
"wrong incident eignenmode index");
580 cvector incident(transfer->diagonalizer->matrixSize(), 0.);
583 scaleIncidentVector(incident, layer);
587template <
typename BaseT>
589 size_t layer = initIncidence(side, lam);
590 if (incident.
size() != transfer->diagonalizer->matrixSize())
throw BadInput(getId(),
"wrong incident vector size");
592 scaleIncidentVector(
result, layer);
598 size_t N =
transfer->diagonalizer->matrixSize();
599 for (
size_t i = 0; i !=
N; ++i) {
600 double P =
real(incident[i] *
conj(incident[i]));
606 for (
size_t i = 0; i !=
N; ++i) incident[i] *=
norm;
614 throw NotImplemented(getId(),
"CylindicalSolver::incidentVector");
630 size_t N =
transfer->diagonalizer->matrixSize();
635 for (
size_t i = 0; i !=
N; ++i) {
636 double P =
real(incident[i] *
conj(incident[i]));
656 size_t N =
transfer->diagonalizer->matrixSize();
661 for (
size_t i = 0; i !=
N; ++i) {
662 double P =
real(incident[i] *
conj(incident[i]));
666 for (
size_t i = 0; i !=
N; ++i) {
687 size_t N =
transfer->diagonalizer->matrixSize();
692 for (
size_t i = 0; i !=
N; ++i) {
693 double P =
real(incident[i] *
conj(incident[i]));
697 for (
size_t i = 0; i !=
N; ++i) {
712 return transfer->getReflectionVector(incident, side);
719 return transfer->getTransmissionVector(incident, side);
722template <
typename BaseT>
723template <PropagationDirection part>
728 double power = applyMode(num);
729 return transfer->getFieldE(power, dst_mesh, method,
part);
732template <
typename BaseT>
733template <PropagationDirection part>
738 double power = applyMode(num);
739 return transfer->getFieldH(power, dst_mesh, method,
part);
742template <
typename BaseT>
747 double power = applyMode(num);
748 return transfer->getFieldMagnitude(power, dst_mesh, method);