240 auto geometry =
SOLVER->getGeometry();
243 for (
size_t i = 0; i !=
solver->
stack.size(); ++i) {
255 size_t refine =
SOLVER->refine;
256 if (refine == 0) refine = 1;
258 #if defined(OPENMP_FOUND)
259 SOLVER->writelog(
LOG_DETAIL,
"Getting refractive indices for layer {}/{} (sampled at {} points) in thread {}",
262 SOLVER->writelog(
LOG_DETAIL,
"Getting refractive indices for layer {}/{} (sampled at {} points)",
267 throw BadInput(
SOLVER->getId(),
"no wavelength given: specify 'lam' or 'lam0'");
270 SOLVER->writelog(
LOG_DEBUG,
"Layer {:d} takes some materials parameters from inEpsilon", layer);
278 double factor = 1. /
double(refine);
293 auto material = geometry->getMaterial(
vec(
pl,
maty));
294 lock = material->lock();
297 throw BadInput(
solver->
getId(),
"complex permittivity tensor (Eps) for {} is NaN at lam={}nm and T={}K",
298 material->name(), lam,
Tl);
301 auto material = geometry->getMaterial(
vec(
pr,
maty));
302 lock = material->lock();
305 throw BadInput(
solver->
getId(),
"complex permittivity tensor (Eps) for {} is NaN at lam={}nm and T={}K",
306 material->name(), lam,
Tr);
319 for (
size_t i = 0; i !=
nN; ++i) {
320 for (
size_t j = refine*i, end = refine*(i+1); j != end; ++j) {
326 double h = (
pl -
mesh->tran()->at(j)) /
SOLVER->pml.size;
327 dcomplex
sy(1. + (
SOLVER->pml.factor-1.)*pow(h,
SOLVER->pml.order));
329 }
else if (j >
pir) {
330 double h = (
mesh->tran()->at(j) -
pr) /
SOLVER->pml.size;
331 dcomplex
sy(1. + (
SOLVER->pml.factor-1.)*pow(h,
SOLVER->pml.order));
338 throw BadInput(
solver->
getId(),
"polarization can be specified only for diagonal complex permittivity tensor (Eps)");
339 coeffs[layer].zz[i] += eps.c00;
342 throw BadInput(
solver->
getId(),
"polarization can be specified only for diagonal complex permittivity tensor (Eps)");
343 coeffs[layer].rxx[i] += 1./eps.c11;
344 coeffs[layer].yy[i] += eps.c22;
348 if (eps.c01 != 0. || eps.c10 != 0.) {
350 throw BadInput(
solver->
getId(),
"complex permittivity tensor (Eps) must be Hermitian for this solver");
353 throw BadInput(
solver->
getId(),
"symmetry can be specified only for diagonal complex permittivity tensor (Eps)");
358 rm = 1. / (eps.c00*eps.c11 - eps.c01.real()*eps.c01.real() - eps.c01.imag()*eps.c01.imag());
359 coeffs[layer].zx[i] += eps.c01;
366 coeffs[layer].zz[i] += eps.c00;
368 coeffs[layer].rxx[i] +=
nd?
rm*eps.c00 : 1./eps.c11;
370 coeffs[layer].yy[i] += eps.c22;
375 coeffs[layer].zz[i] *= factor;
377 coeffs[layer].rxx[i] *= factor;
378 coeffs[layer].yy[i] *= factor;
380 coeffs[layer].zz[i] *= factor;
383 coeffs[layer].zx[i] *= factor;
392 for (
size_t i = 1; i !=
nN; ++i)
398 for (
size_t i = 1; i !=
nN; ++i)
403 for (
size_t i = 1; i !=
nN; ++i)
409 for (
size_t i = 0; i !=
nN; ++i)
416 for (
size_t i = 1; i !=
nN; ++i)
431 std::fill_n(
coeffs[layer].zz.data()+1, n1, 0.);
433 std::fill_n(
coeffs[layer].rxx.data()+1, n1, 0.);
434 std::fill_n(
coeffs[layer].yy.data()+1, n1, 0.);
440 std::fill_n(
coeffs[layer].zz.data()+1, n1, 0.);
443 std::fill_n(
coeffs[layer].zx.data()+1, n1, 0.);
467 #if defined(OPENMP_FOUND)
468 SOLVER->writelog(
LOG_DETAIL,
"Getting refractive indices for layer {}/{} in thread {}",
475 throw BadInput(
SOLVER->getId(),
"no wavelength given: specify 'lam' or 'lam0'");
478 SOLVER->writelog(
LOG_DEBUG,
"Layer {:d} takes some materials parameters from inEpsilon", layer);
486 size_t mn =
mesh->tran()->size();
488 bool nd = eps0.c01 != 0.;
492 throw BadInput(
solver->
getId(),
"polarization can be specified only for diagonal complex permittivity tensor (Eps)");
493 rm = 1. / (eps0.c00*eps0.c11 - eps0.c01.real()*eps0.c01.real() - eps0.c01.imag()*eps0.c01.imag());
504 if (eps0.c00 != eps0.c22 || eps0.c11 != eps0.c22) {
519 const double b = 2*
PI / L;
520 for (
size_t i = 1; i < mn; ++i) {
522 if (!
eps1.equals(eps)) {
526 throw BadInput(
solver->
getId(),
"polarization can be specified only for diagonal complex permittivity tensor (Eps)");
527 rm = 1. / (eps.c00*eps.c11 - eps.c01.real()*eps.c01.real() - eps.c01.imag()*eps.c01.imag());
535 add_coeffs(start, end,
b, l, r,
coeffs[layer].zz, eps.c00 - eps0.c00);
537 add_coeffs(start, end,
b, l, r,
coeffs[layer].rxx, 1./eps.c11 -
reps0.c11);
538 add_coeffs(start, end,
b, l, r,
coeffs[layer].yy, eps.c22 - eps0.c22);
545 add_coeffs(start, end,
b, l, r,
coeffs[layer].zz, eps.c00 - eps0.c00);
547 add_coeffs(start, end,
b, l, r,
coeffs[layer].rxx, reps.c11 -
reps0.c11);
548 add_coeffs(start, end,
b, l, r,
coeffs[layer].yy, eps.c22 - eps0.c22);
552 throw BadInput(
solver->
getId(),
"symmetry can be specified only for diagonal complex permittivity tensor (Eps)");
556 add_coeffs(start, end,
b, l, r,
coeffs[layer].zx, eps.c01 - eps0.c01);
567 for (
size_t i = 0; i !=
nN; ++i) {
574 coeffs[layer].rxx[i] *= s;
591 const int order =
int(
SOLVER->getSize());
598 for (
int i = 0; i <= order; ++i)
600 for (
int j = 1; j <= order; ++j)
601 for (
int i = 0; i <= order; ++i)
607 for (
int i = 0; i <= order; ++i)
609 for (
int j = 1; j <= order; ++j)
610 for (
int i = 0; i <= order; ++i)
616 for (
int j = -order; j <= order; ++j) {
617 const size_t jt =
iEH(j);
618 for (
int i = -order; i <= order; ++i) {
619 const size_t it =
iEH(i);
627 for (
int j = -order; j <= order; ++j) {
628 const size_t jt =
iEH(j);
629 for (
int i = -order; i <= order; ++i) {
630 const size_t it =
iEH(i);
650 for (
int k = -
int(
nN)/2, end =
int(
nN+1)/2; k != end; ++k) {
651 size_t j = (k>=0)? k : k +
nN;
655 eps.c00 +=
coeffs[l].zz[j] * ff;
658 eps.c11 +=
coeffs[l].rxx[j] * ff;
659 eps.c22 +=
coeffs[l].yy[j] * ff;
662 eps.c00 +=
coeffs[l].zz[j] * ff;
663 eps.c11 +=
coeffs[l].rxx[j] * ff;
664 eps.c22 +=
coeffs[l].yy[j] * ff;
671 eps.c22 = eps.c11 = eps.c00;
676 eps.c11 = 1. / eps.c11;
683 for (std::size_t k = 0; k !=
nN; ++k) {
684 dcomplex ff = (k? 2. : 1.) *
cos(
PI *
double(k) * dest_mesh->at(i).c0 / (
right-
left));
687 eps.c00 +=
coeffs[l].zz[k] * ff;
690 eps.c11 +=
coeffs[l].rxx[k] * ff;
691 eps.c22 +=
coeffs[l].yy[k] * ff;
694 eps.c00 +=
coeffs[l].zz[k] * ff;
695 eps.c11 +=
coeffs[l].rxx[k] * ff;
696 eps.c22 +=
coeffs[l].yy[k] * ff;
702 eps.c22 = eps.c11 = eps.c00;
707 eps.c11 = 1. / eps.c11;
716 for (
size_t i = 0; i !=
nN; ++i) params[i].c00 =
coeffs[l].zz[i];
717 fft.execute(
reinterpret_cast<dcomplex*
>(params.
data(), 1));
719 eps.c22 = eps.c11 = eps.c00;
722 for (
size_t i = 0; i !=
nN; ++i) {
723 params[i].c11 =
coeffs[l].rxx[i];
724 params[i].c22 =
coeffs[l].yy[i];
726 fft.execute(
reinterpret_cast<dcomplex*
>(params.
data())+1, 1);
727 fft.execute(
reinterpret_cast<dcomplex*
>(params.
data())+2, 1);
729 for (
size_t i = 0; i !=
nN; ++i) params[i].c01 =
coeffs[l].zx[i];
730 fft.execute(
reinterpret_cast<dcomplex*
>(params.
data())+3, 1);
731 for (
size_t i = 0; i !=
nN; ++i) params[i].c10 =
conj(params[i].c01);
736 eps.c11 = 1. / eps.c11;
739 for (
size_t i = 0; i !=
nN; ++i) params[i].c00 =
coeffs[l].zz[i];
740 fft.execute(
reinterpret_cast<dcomplex*
>(params.
data()), 1);
742 eps.c11 = 1. / eps.c11;
756 params[
nN] = params[0];
759 return interpolate(src_mesh, params, dest_mesh, interp,
830 const int order =
int(
SOLVER->getSize());
849 for (
int i = 0; i <= order; ++i) {
853 for (
int j = 1; j <= order; ++j) {
858 if (
RE(i,i) == 0.)
RE(i,i) = 1
e-32;
859 if (
RH(i,i) == 0.)
RH(i,i) = 1
e-32;
865 for (
int i = 0; i <= order; ++i) {
869 for (
int j = 1; j <= order; ++j) {
874 if (
RE(i,i) == 0.)
RE(i,i) = 1
e-32;
875 if (
RH(i,i) == 0.)
RH(i,i) = 1
e-32;
888 for (
int i = -order; i <= order; ++i) {
890 const size_t it =
iEH(i);
891 for (
int j = -order; j <= order; ++j) {
892 const size_t jt =
iEH(j);
903 for (
int i = -order; i <= order; ++i) {
905 const size_t it =
iEH(i);
906 for (
int j = -order; j <= order; ++j) {
907 const size_t jt =
iEH(j);
919 const size_t NN =
N*
N;
933 for (
int i = 0; i <= order; ++i) {
936 for (
int j = 0; j <= order; ++j) {
937 int ijp = abs(i-j),
ijn = i+j;
957 for (
int i = 0; i <= order; ++i) {
960 for (
int j = 0; j <= order; ++j) {
961 int ijp = abs(i-j),
ijn = i+j;
983 for (
int i = -order; i <= order; ++i) {
986 for (
int j = -order; j <= order; ++j) {
1005 for (
int i = -order; i <= order; ++i) {
1008 for (
int j = -order; j <= order; ++j) {
1062 const int order =
int(
SOLVER->getSize());
1066 double vpos = level->vpos();
1076 for (
int i =
symmetric()? 0 : -order; i <= order; ++i) {
1078 field[
ieh].tran() = field[
ieh].vert() = 0.;
1079 if (
ieh != 0 || !dz) field[
ieh-dz].lon() = -
E[
ieh];
1082 for (
int i =
symmetric()? 0 : -order; i <= order; ++i) {
1084 field[
ieh].lon() = 0.;
1085 if (
ieh != 0 || !
dx)
1087 if (
ieh != 0 || !dz) {
1088 field[
ieh-dz].vert() = 0.;
1089 for (
int j =
symmetric()? 0 : -order; j <= order; ++j) {
1093 field[
ieh-dz].vert() /=
k0;
1097 for (
int i =
symmetric()? 0 : -order; i <= order; ++i) {
1099 if (
ieh != 0 || !
dx)
1101 if (
ieh != 0 || !dz) {
1102 field[
ieh-dz].lon() = -
E[
iEz(i)];
1103 field[
ieh-dz].vert() = 0.;
1104 for (
int j =
symmetric()? 0 : -order; j <= order; ++j) {
1108 field[
ieh-dz].vert() /=
k0;
1114 for (
int i =
symmetric()? 0 : -order; i <= order; ++i) {
1116 field[
ieh].tran() = field[
ieh].vert() = 0.;
1117 if (
ieh != 0 || !dz) field[
ieh-dz].lon() = H[
ieh];
1120 for (
int i =
symmetric()? 0 : -order; i <= order; ++i) {
1122 field[
ieh].lon() = 0.;
1123 if (
ieh != 0 || !
dx)
1125 if (
ieh != 0 || !dz) {
1129 field[
ieh-dz].vert() = 0.;
1130 for (
int j =
symmetric()? 0 : -order; j <= order; ++j) {
1135 field[
ieh-dz].vert() /=
k0;
1139 for (
int i =
symmetric()? 0 : -order; i <= order; ++i) {
1141 if (
ieh != 0 || !
dx)
1143 if (
ieh != 0 || !dz) {
1144 field[
ieh-dz].lon() = H[
iHz(i)];
1148 field[
ieh-dz].vert() = 0.;
1149 for (
int j =
symmetric()? 0 : -order; j <= order; ++j)
1153 field[
ieh-dz].vert() /=
k0;
1159 if (
dx) { field[field.size()-1].tran() = 0.; }
1160 if (dz) { field[field.size()-1].lon() = 0.; field[field.size()-1].vert() = 0.; }
1166 dcomplex B = 2*
PI *
I / L;
1169 for (
int k = -order; k <= order; ++k) {
1170 size_t j = (k>=0)? k : k +
N;
1172 for (
size_t i = 0; i != dest_mesh->size(); ++i) {
1173 double x = dest_mesh->at(i)[0];
1180 result.reset(dest_mesh->size());
1181 for (
size_t i = 0; i != dest_mesh->size(); ++i) {
1183 for (
int k = 1; k <= order; ++k) {
1184 double x = dest_mesh->at(i)[0];
1186 double cs = 2. *
cos(B * k * x);
1187 dcomplex
sn = 2. *
I *
sin(B * k * x);
1189 result[i].lon() += field[k].lon() *
sn;
1190 result[i].tran() += field[k].tran() * cs;
1191 result[i].vert() += field[k].vert() *
sn;
1193 result[i].lon() += field[k].lon() * cs;
1194 result[i].tran() += field[k].tran() *
sn;
1195 result[i].vert() += field[k].vert() * cs;
1203 fft_x.
execute(&(field.data()->tran()), 1);
1204 fft_yz.
execute(&(field.data()->lon()), 1);
1205 fft_yz.
execute(&(field.data()->vert()), 1);
1208 f.c0 = dcomplex(-f.c0.imag(), f.c0.real());
1209 f.c2 = dcomplex(-f.c2.imag(), f.c2.real());
1214 f.c1 = dcomplex(-f.c1.imag(), f.c1.real());
1226 fft_x.
execute(
reinterpret_cast<dcomplex*
>(field.data()));
1227 field[
N] = field[0];
1283 std::fill_n(Te.
data(), nr*
nc, 0.);
1284 std::fill_n(Te1.
data(), nr*
nc, 0.);
1287 for (std::size_t i = 0; i <
nc; i++) {
1288 Te(i,i) = Te1(i,i) = 1.;
1294 for (std::size_t i = 0; i <
n; i++) {
1298 dcomplex
a =
RE(2*i, 2*i),
b =
RE(2*i, 2*i+1), c =
RE(2*i+1, 2*i), d =
RE(2*i+1, 2*i+1);
1299 dcomplex s = sqrt(
a*d -
b*c);
1302 s = 1. / sqrt(
a*
a +
b*
b);
a *= s;
b *= s;
1303 s = 1. / sqrt(c*c + d*d); c *= s; d *= s;
1304 Te1(2*i, 2*i) =
a; Te1(2*i, 2*i+1) =
b;
1305 Te1(2*i+1, 2*i) = c; Te1(2*i+1, 2*i+1) = d;
1307 s = 1. / (
a*d -
b*c);
1308 Te(2*i, 2*i) = s * d; Te(2*i, 2*i+1) = - s *
b;
1309 Te(2*i+1, 2*i) = - s * c; Te(2*i+1, 2*i+1) = s *
a;
1315 const std::function<std::pair<dcomplex,dcomplex>(
size_t,
size_t)>&
vertical)
1317 const int order =
int(
SOLVER->getSize());
1323 size_t M = TE.
cols();
1331 std::fill_n(verts.
data(), verts.
rows() * verts.
cols(), 0.);
1336 for (
int i = 0; i <= order; ++i) {
1338 for (
int j = 0; j <= order; ++j)
1340 verts(i,m) = vert /
k0;
1346 for (
int i = -order; i <= order; ++i) {
1349 for (
int j = -order; j <= order; ++j) {
1353 verts(
ieh,m) = vert /
k0;
1361 for (
int i = 0; i <= order; ++i) {
1363 for (
int j = 0; j <= order; ++j)
1365 verts(i,m) = vert /
k0;
1371 for (
int i = -order; i <= order; ++i) {
1374 for (
int j = -order; j <= order; ++j)
1376 verts(
ieh,m) = vert /
k0;
1383 std::fill_n(verts.
data(), verts.
rows() * verts.
cols(), 0.);
1388 for (
int i = 0; i <= order; ++i) {
1394 for (
int j = 0; j <= order; ++j)
1397 verts(i,m) = vert /
k0;
1403 for (
int i = -order; i <= order; ++i) {
1410 for (
int j = -order; j <= order; ++j) {
1415 verts(
ieh,m) = vert /
k0;
1423 for (
int i = 0; i <= order; ++i) {
1429 for (
int j = 0; j <= order; ++j)
1432 verts(i,m) = vert /
k0;
1438 for (
int i = -order; i <= order; ++i) {
1445 for (
int j = -order; j <= order; ++j)
1448 verts(
ieh,m) = vert /
k0;
1465 for(
size_t i = 1; i !=
N; ++i) {
1483 for(
size_t i = 1; i !=
N; ++i) {
1502 for(
size_t i = 0; i !=
N; ++i) {
1518 for(
size_t i = 0; i !=
N; ++i) {
1540 for(
size_t i = 1; i !=
N; ++i) {
1558 for(
size_t i = 1; i !=
N; ++i) {
1577 for(
size_t i = 0; i !=
N; ++i) {
1593 for(
size_t i = 0; i !=
N; ++i) {