24 void CalculateEigenvalues(
const std::vector<Slice>& slices,
const kvector_t k,
25 std::vector<MatrixRTCoefficients_v1>& coeff);
26 void CalculateTransferAndBoundary(
const std::vector<Slice>& slices,
27 std::vector<MatrixRTCoefficients_v1>& coeff);
28 void SetForNoTransmission(std::vector<MatrixRTCoefficients_v1>& coeff);
35 std::vector<MatrixRTCoefficients_v1> result(slices.size());
36 CalculateEigenvalues(slices, k, result);
37 CalculateTransferAndBoundary(slices, result);
40 for (
auto& coeff : result)
41 resultConvert.push_back(std::make_unique<MatrixRTCoefficients_v1>(coeff));
49 throw std::runtime_error(
"Not implemented");
52 std::variant<complex_t, Eigen::Matrix2cd>
54 const std::vector<complex_t>& kz)
const
56 throw std::runtime_error(
"Not implemented");
60 void CalculateEigenvalues(
const std::vector<Slice>& slices,
const kvector_t k,
61 std::vector<MatrixRTCoefficients_v1>& coeff)
63 double mag_k = k.
mag();
64 double n_ref = slices[0].material().refractiveIndex(2 *
M_PI / mag_k).real();
65 double sign_kz = k.
z() > 0.0 ? -1.0 : 1.0;
66 for (
size_t i = 0; i < coeff.size(); ++i) {
67 coeff[i].m_scatt_matrix = slices[i].polarizedReducedPotential(k, n_ref);
68 coeff[i].m_kt = mag_k * slices[i].thickness();
69 coeff[i].m_a = coeff[i].m_scatt_matrix.trace() / 2.0;
71 sqrt(coeff[i].m_a * coeff[i].m_a - coeff[i].m_scatt_matrix.determinant());
72 coeff[i].m_bz = (coeff[i].m_scatt_matrix(0, 0) - coeff[i].m_scatt_matrix(1, 1)) / 2.0;
73 complex_t rad0 = coeff[i].m_a - coeff[i].m_b_mag;
74 complex_t rad1 = coeff[i].m_a + coeff[i].m_b_mag;
77 if (std::abs(rad0) < 1e-40)
79 if (std::abs(rad1) < 1e-40)
82 coeff[i].lambda(0) = sqrt(rad0);
83 coeff[i].lambda(1) = sqrt(rad1);
84 coeff[i].kz = mag_k * coeff[i].lambda * sign_kz;
89 void CalculateTransferAndBoundary(
const std::vector<Slice>& slices,
90 std::vector<MatrixRTCoefficients_v1>& coeff)
92 size_t N = coeff.size();
93 if (coeff[0].lambda == Eigen::Vector2cd::Zero() && N > 1) {
94 SetForNoTransmission(coeff);
99 coeff[N - 1].initializeBottomLayerPhiPsi();
101 coeff[N - 1].calculateTRMatrices();
103 coeff[0].calculateTRMatrices();
104 for (
int signed_index =
static_cast<int>(N) - 2; signed_index > 0; --signed_index) {
105 size_t i =
static_cast<size_t>(signed_index);
106 double t = slices[i].thickness();
107 coeff[i].calculateTRMatrices();
108 Eigen::Matrix4cd l = coeff[i].R1m * GetImExponential(coeff[i].kz(0) * t)
109 + coeff[i].T1m * GetImExponential(-coeff[i].kz(0) * t)
110 + coeff[i].R2m * GetImExponential(coeff[i].kz(1) * t)
111 + coeff[i].T2m * GetImExponential(-coeff[i].kz(1) * t);
112 coeff[i].phi_psi_plus = l * coeff[i + 1].phi_psi_plus;
113 coeff[i].phi_psi_min = l * coeff[i + 1].phi_psi_min;
119 coeff[0].phi_psi_plus = coeff[1].phi_psi_plus;
120 coeff[0].phi_psi_min = coeff[1].phi_psi_min;
124 Eigen::Vector2cd T0basisA = coeff[0].T1plus() + coeff[0].T2plus();
125 Eigen::Vector2cd T0basisB = coeff[0].T1min() + coeff[0].T2min();
131 Eigen::Vector4cd phipsitemp = cpA * coeff[0].phi_psi_plus + cpB * coeff[0].phi_psi_min;
132 coeff[0].phi_psi_min = cmA * coeff[0].phi_psi_plus + cmB * coeff[0].phi_psi_min;
133 coeff[0].phi_psi_plus = phipsitemp;
134 Eigen::Vector2cd T0plusV = coeff[0].T1plus() + coeff[0].T2plus();
135 Eigen::Vector2cd T0minV = coeff[0].T1min() + coeff[0].T2min();
138 coeff[0].phi_psi_min = coeff[0].phi_psi_min / T0min;
139 coeff[0].phi_psi_plus = coeff[0].phi_psi_plus / T0plus;
140 for (
size_t i = 1; i < N; ++i) {
141 phipsitemp = (cpA * coeff[i].phi_psi_plus + cpB * coeff[i].phi_psi_min) / T0plus;
142 coeff[i].phi_psi_min =
143 (cmA * coeff[i].phi_psi_plus + cmB * coeff[i].phi_psi_min) / T0min;
144 coeff[i].phi_psi_plus = phipsitemp;
149 void SetForNoTransmission(std::vector<MatrixRTCoefficients_v1>& coeff)
151 size_t N = coeff.size();
152 for (
size_t i = 0; i < N; ++i) {
153 coeff[i].phi_psi_plus.setZero();
154 coeff[i].phi_psi_min.setZero();
155 coeff[i].T1m = Eigen::Matrix4cd::Identity() / 4.0;
156 coeff[i].R1m = coeff[i].T1m;
157 coeff[i].T2m = coeff[i].T1m;
158 coeff[i].R2m = coeff[i].T1m;
164 if (exponent.imag() > -std::log(std::numeric_limits<double>::min()))
166 return std::exp(
I * exponent);
std::complex< double > complex_t
Defines class LayerInterface.
Defines class MultiLayer.
Defines class SpecularMagneticStrategy_v1.
double mag() const
Returns magnitude of the vector.
T z() const
Returns z-component in cartesian coordinate system.
std::vector< std::unique_ptr< const ILayerRTCoefficients > > coeffs_t
virtual std::variant< complex_t, Eigen::Matrix2cd > computeTopLayerR(const std::vector< Slice > &slices, const std::vector< complex_t > &kz) const override
ISpecularStrategy::coeffs_t Execute(const std::vector< Slice > &slices, const kvector_t &k) const
Computes refraction angle reflection/transmission coefficients for given sliced multilayer and waveve...