315 self.Solver::initCalculation();
316 if (!self.transfer) {
317 self.initTransfer(self.getExpansion(),
false);
318 self.transfer->initDiagonalization();
319 self.transfer->diagonalizer->diagonalizeLayer(layer);
320 }
else if (!self.transfer->diagonalizer->isDiagonalized(layer)) {
321 self.transfer->diagonalizer->diagonalizeLayer(layer);
323 cdiagonal gamma = self.transfer->diagonalizer->Gamma(layer);
324 cmatrix TE = self.transfer->diagonalizer->TE(layer),
325 TH = self.transfer->diagonalizer->TH(layer);
326 return py::make_tuple(py::object(gamma), py::object(TE), py::object(TH));
1024 py::object wavelength,
1029 if (!self->Solver::initCalculation()) self->setExpansionDefaults(
false);
1030 if (!self->transfer) self->initTransfer(self->getExpansion(),
true);
1034 if (size != self->transfer->diagonalizer->matrixSize())
1035 throw BadInput(self->getId(),
"wrong incident vector size ({}, should be {}", size, self->transfer->diagonalizer->matrixSize());
1039 return UFUNC<double>([self, incident, side](
double lam)->
double {
1040 double k0 = 2
e3*
PI/lam;
1041 self->getExpansion().setK0(k0);
1042 return 100. * self->getReflection(self->incidentVector(side, incident, lam), side);
1048 py::object wavelength,
1053 if (!self->Solver::initCalculation()) self->setExpansionDefaults(
false);
1054 if (!self->transfer) self->initTransfer(self->getExpansion(),
true);
1058 if (size != self->transfer->diagonalizer->matrixSize())
1059 throw BadInput(self->getId(),
"wrong incident vector size ({}, should be {}", size, self->transfer->diagonalizer->matrixSize());
1063 return UFUNC<double>([self, incident, side](
double lam)->
double {
1064 double k0 = 2
e3*
PI/lam;
1065 self->getExpansion().setK0(k0);
1066 return 100. * self->getTransmission(self->incidentVector(side, incident, lam), side);
1116 typedef typename Class::wrapped_type
Solver;
1119 "Set interface at the bottom of the specified object.\n\n"
1121 " object (geometry object): object to set the interface at.\n"
1122 " path (path): Optional path specifying an instance of the object.",
1123 (py::arg(
"object"), py::arg(
"path")=py::object()));
1124 solver.def(
"set_interface", &Solver::setInterfaceAt,
1125 "Set interface as close as possible to the specified position.\n\n"
1127 " pos (float): Position, near which the interface will be located.", py::arg(
"pos"));
1128 solver.add_property(
"smooth", &Solver::getSmooth, &Solver::setSmooth,
"Smoothing parameter for material boundaries (increases convergence).");
1132 "Vertical posiotions of centers of each layer.\n\n"
1133 "At these positions materials and temperatures are probed.\n");
1135 solver.add_property(
"group_layers", &Solver::getGroupLayers, &Solver::setGroupLayers,
1136 "Layer grouping switch.\n\n"
1137 "If this property is ``True``, similar layers are grouped for efficiency.");
1139 "Maximum temperature difference between the layers in one group.\n\n"
1140 "If a temperature in a single layer varies vertically more than this value,\n"
1141 "the layer is split into two and put into separate groups. If this is empty,\n"
1142 "temperature gradient is ignored in layers grouping.\n\n");
1143 solver.add_property(
"temp_dist", &Solver::getTempDist, &Solver::setTempDist,
1144 "Temperature probing step.\n\n"
1145 "If :attr:`temp_diff` is not ``None``, the temperature is laterally probed\n"
1146 "in points approximately separated by this distance.\n");
1147 solver.add_property(
"temp_layer", &Solver::getTempLayer, &Solver::setTempLayer,
1148 "Temperature probing step.\n\n"
1149 "If :attr:`temp_diff` is not ``None``, this is the minimum thickness of sublayers\n"
1150 "resulting from temperature-gradient division.\n");
1155 solver.add_provider(
"outEpsilon", &Solver::outEpsilon,
"");
1156 solver.add_provider(
"outRefractiveIndex", &Solver::outRefractiveIndex,
"");
1157 solver.add_provider(
"outWavelength", &Solver::outWavelength,
"");
1158 solver.add_provider(
"outLightMagnitude", &Solver::outLightMagnitude,
"");
1159 solver.add_provider(
"outLightE", &Solver::outLightE,
"");
1160 solver.add_provider(
"outLightH", &Solver::outLightH,
"");
1161 solver.add_provider(
"outUpwardsLightE", &Solver::outUpwardsLightE,
"");
1162 solver.add_provider(
"outUpwardsLightH", &Solver::outUpwardsLightH,
"");
1163 solver.add_provider(
"outDownwardsLightE", &Solver::outDownwardsLightE,
"");
1164 solver.add_provider(
"outDownwardsLightH", &Solver::outDownwardsLightH,
"");
1165 solver.def_readwrite(
"root", &Solver::root,
1166 "Configuration of the root searching algorithm.\n\n"
1169 solver.add_property(
"vpml", py::make_function(&
Solver_vPML<Solver>, py::with_custodian_and_ward_postcall<0,1>()),
1171 "Vertical Perfectly Matched Layers boundary conditions.\n\n"
1172 ".. rubric:: Attributes\n\n"
1173 ".. autosummary::\n\n"
1174 " ~optical.modal.PML.factor\n"
1175 " ~optical.modal.PML.dist\n"
1176 " ~optical.modal.PML.size\n\n"
1177 "Attribute ``shape`` is ignored for vertical PML (it is always 0).\n"
1179 solver.add_property(
"transfer", &Solver::getTransferMethod, &Solver::setTransferMethod,
1180 "Preferred transfer method.\n\n"
1181 "Can take on of the following values:\n\n"
1182 "============ ====================================\n"
1183 "*auto* Automatically choose the best method\n"
1184 "*reflection* Reflection Transfer Method\n"
1185 "*admittance* Admittance Transfer Method\n"
1186 "*impedance* Impedance Transfer Method\n"
1187 "============ ====================================\n\n"
1188 "Reflection transfer can have optional suffix ``-admittance`` (default)\n"
1189 "or ``-impedance``, in which case the admittance/impedance matching is done\n"
1190 "at interface (for eigenmode search). You should prefer admittance if electric\n"
1191 "field is expected to have significant horizontal components (particularly\n"
1192 "at the interface) i.e. for TE-like modes and impedance for TM-like modes."
1195 "Type of determinant that is computed in root finding.\n\n"
1196 "This attribute specifies what is returned by the :meth:`get_determinant`\n"
1197 "method. Regardless of the determinant type, its value must be zero for any mode.\n\n"
1198 "Can take on of the following values that specified what quantity is computed\n"
1199 "for the characteristic matrix:\n\n"
1200 "============ ======================================\n"
1201 "*eigenvalue* Eigenvalue with the smallest magnitude\n"
1202 "*full* Determinant of the matrix\n"
1203 "============ ======================================\n"
1206 "Reference wavelength.\n\n"
1207 "This is a wavelength at which refractive index is retrieved from the structure.\n"
1208 "If this parameter is None, material parameters are computed each time,\n"
1209 "the wavelength changes even slightly (this is most accurate, but can be very\n"
1212 solver.def_readwrite(
"update_gain", &Solver::always_recompute_gain,
1213 "Recompute dynamic parameters.\n\n"
1214 "If this attribute is set to True, material parameters are always recomputed for\n"
1215 "layers with gain or permittivity provided by py::attr:`inEpsilon`. This allows\n"
1216 "to set 'lam0' for better efficiency and still consider slight changes of wavelength,\n"
1217 "where it matters the most.\n"
1221 u8"Get average integral of the squared electric field:\n\n"
1222 u8"\\\\[\\\\frac 1 2 \\\\int_{z_1}^{z_2} \\|E\\|^2.\\\\]\n\n"
1223 u8"In the lateral direction integration is performed over the whole domain.\n\n"
1225 u8" num (int): Computed mode number.\n"
1226 u8" z1 (float): Lower vertical bound of the integral.\n"
1227 u8" z2 (float): Upper vertical bound of the integral.\n\n"
1229 u8" float: Computed integral [V\\ :sup:`2` / m\\ :sup:`2`].\n"
1231 u8" This method may return incorrect results for layers with gain,\n"
1232 u8" due to the strong non-Hemiticity!\n"
1236 u8"Get average integral of the squared magnetic field:\n\n"
1237 u8"\\\\[\\\\frac 1 2 \\\\int_{z_1}^{z_2} \\|H\\|^2.\\\\]\n\n"
1238 u8"In the lateral direction integration is performed over the whole domain.\n\n"
1240 u8" num (int): Computed mode number.\n"
1241 u8" z1 (float): Lower vertical bound of the integral.\n"
1242 u8" z2 (float): Upper vertical bound of the integral.\n"
1244 u8" float: Computed integral [A\\ :sup:`2` / m\\ :sup:`2`].\n"
1246 u8" This method may return incorrect results for layers with gain,\n"
1247 u8" due to the strong non-Hemiticity!\n"