20 #include <Eigen/Dense>
25 const LayerRoughness* GetBottomRoughness(
const std::vector<Slice>& slices,
26 const size_t slice_index);
32 std::vector<complex_t> kz = KzComputation::computeReducedKz(slices, k);
37 const std::vector<complex_t>& kz)
const
39 if (slices.size() != kz.size())
40 throw std::runtime_error(
"Number of slices does not match the size of the kz-vector");
42 ISpecularStrategy::coeffs_t result;
43 for (
auto& coeff : computeTR(slices, kz))
44 result.push_back(std::make_unique<ScalarRTCoefficients>(coeff));
49 std::vector<ScalarRTCoefficients>
50 SpecularScalarStrategy::computeTR(
const std::vector<Slice>& slices,
51 const std::vector<complex_t>& kz)
const
53 const size_t N = slices.size();
54 std::vector<ScalarRTCoefficients> coeff(N);
56 for (
size_t i = 0; i < N; ++i)
60 coeff[0].t_r = {1.0, 0.0};
62 }
else if (kz[0] == 0.0) {
63 coeff[0].t_r = {1.0, -1.0};
64 for (
size_t i = 1; i < N; ++i)
65 coeff[i].t_r.setZero();
70 calculateUpFromLayer(coeff, slices, kz);
74 void SpecularScalarStrategy::setZeroBelow(std::vector<ScalarRTCoefficients>& coeff,
77 size_t N = coeff.size();
78 for (
size_t i = current_layer + 1; i < N; ++i) {
79 coeff[i].t_r.setZero();
83 void SpecularScalarStrategy::calculateUpFromLayer(std::vector<ScalarRTCoefficients>& coeff,
84 const std::vector<Slice>& slices,
85 const std::vector<complex_t>& kz)
const
87 auto N = slices.size();
89 coeff.back().t_r(0) = 1.0;
90 coeff.back().t_r(1) = 0.0;
91 std::vector<complex_t> factors(N - 1);
92 for (
int i = N - 2; i >= 0; i--) {
94 if (
const auto roughness = GetBottomRoughness(slices, i))
95 sigma = roughness->getSigma();
97 const auto mpmm = transition(kz[i], kz[i + 1], sigma);
98 const complex_t mp = mpmm.first;
99 const complex_t mm = mpmm.second;
101 const complex_t delta =
exp_I(kz[i] * slices[i].thickness());
103 complex_t S = mp + mm * coeff[i + 1].t_r(1);
107 coeff[i].t_r(1) = delta * (mm + mp * coeff[i + 1].t_r(1)) * S;
113 complex_t dumpingFactor = 1;
114 for (
size_t j = 1; j < N; ++j) {
115 dumpingFactor = dumpingFactor * factors[j - 1];
117 coeff[j].t_r(0) = dumpingFactor;
118 coeff[j].t_r(1) *= dumpingFactor;
124 const LayerRoughness* GetBottomRoughness(
const std::vector<Slice>& slices,
const size_t slice_index)
126 if (slice_index + 1 < slices.size())
127 return slices[slice_index + 1].topRoughness();
complex_t exp_I(complex_t z)
Returns exp(I*z), where I is the imaginary unit.
Declares functions in namespace KzComputation.
Defines class LayerRoughness.
Defines class SpecularScalarStrategy.
A roughness of interface between two layers.
virtual ISpecularStrategy::coeffs_t Execute(const std::vector< Slice > &slices, const kvector_t &k) const override
Computes refraction angles and transmission/reflection coefficients for given coherent wave propagati...