From b64994a389effc4a1ef34aafcadef86d1319321c Mon Sep 17 00:00:00 2001 From: Walter Van Herck <w.van.herck@fz-juelich.de> Date: Tue, 7 May 2013 16:50:05 +0200 Subject: [PATCH] Improved numerics for SpecularMatrix calculation --- Core/Algorithms/inc/SpecularMatrix.h | 3 +- Core/Algorithms/src/SpecularMatrix.cpp | 47 ++++++++++---------------- dev-tools/log/perf_history.txt | 1 + 3 files changed, 20 insertions(+), 31 deletions(-) diff --git a/Core/Algorithms/inc/SpecularMatrix.h b/Core/Algorithms/inc/SpecularMatrix.h index b0b988bbb02..bebd2e4bf85 100644 --- a/Core/Algorithms/inc/SpecularMatrix.h +++ b/Core/Algorithms/inc/SpecularMatrix.h @@ -68,8 +68,7 @@ private: bool m_use_roughness; void calculateEigenvalues(const MultiLayer& sample, const kvector_t& k, MultiLayerCoeff_t& coeff) const; - void calculateTransferMatrices(const MultiLayer& sample, const kvector_t& k, MultiLayerCoeff_t& coeff) const; - void calculateBoundaryValues(MultiLayerCoeff_t& coeff) const; + void calculateTransferAndBoundary(const MultiLayer& sample, const kvector_t& k, MultiLayerCoeff_t& coeff) const; }; #endif /* SPECULARMATRIX_H_ */ diff --git a/Core/Algorithms/src/SpecularMatrix.cpp b/Core/Algorithms/src/SpecularMatrix.cpp index 07b0c097f6b..f6cc9e96395 100644 --- a/Core/Algorithms/src/SpecularMatrix.cpp +++ b/Core/Algorithms/src/SpecularMatrix.cpp @@ -24,9 +24,7 @@ void SpecularMatrix::execute(const MultiLayer& sample, const kvector_t& k, calculateEigenvalues(sample, k, coeff); - calculateTransferMatrices(sample, k, coeff); - - calculateBoundaryValues(coeff); + calculateTransferAndBoundary(sample, k, coeff); } void SpecularMatrix::calculateEigenvalues(const MultiLayer& sample, @@ -42,13 +40,15 @@ void SpecularMatrix::calculateEigenvalues(const MultiLayer& sample, } } -void SpecularMatrix::calculateTransferMatrices(const MultiLayer& sample, +void SpecularMatrix::calculateTransferAndBoundary(const MultiLayer& sample, const kvector_t& k, MultiLayerCoeff_t& coeff) const { - // Layer 0 gets identity matrix: - coeff[0].l.setIdentity(); - coeff.L.setIdentity(); - for(size_t i=1; i<coeff.size()-1; ++i) { + size_t N = coeff.size(); + // Last layer boundary ensures no reflection + coeff[N-1].phi_psi(0) = -coeff[N-1].lambda; + coeff[N-1].phi_psi(1) = 1.0; + coeff[N-1].l.setIdentity(); + for(size_t i=N-2; i>0; --i) { complex_t lambda = coeff[i].lambda; complex_t kdlambda = k.mag()*sample.getLayer(i)->getThickness()*lambda; complex_t cosine_term = std::cos(kdlambda); @@ -57,28 +57,17 @@ void SpecularMatrix::calculateTransferMatrices(const MultiLayer& sample, k.mag()*sample.getLayer(i)->getThickness() : std::sin(kdlambda)/lambda; coeff[i].l(0,0) = cosine_term; - coeff[i].l(0,1) = -complex_t(0.0, 1.0)*lambda*lambda*sine_term; - coeff[i].l(1,0) = -complex_t(0.0, 1.0)*sine_term; + coeff[i].l(0,1) = complex_t(0.0, 1.0)*lambda*lambda*sine_term; + coeff[i].l(1,0) = complex_t(0.0, 1.0)*sine_term; coeff[i].l(1,1) = cosine_term; - coeff.L = coeff[i].l * coeff.L; + coeff[i].phi_psi = coeff[i].l * coeff[i+1].phi_psi; } - // Last layer also gets identity matrix: - size_t N = coeff.size(); - coeff[N-1].l.setIdentity(); -} - -void SpecularMatrix::calculateBoundaryValues(MultiLayerCoeff_t& coeff) const -{ - complex_t lambda0 = coeff[0].lambda; - size_t N = coeff.size(); - complex_t lambdaN = coeff[N-1].lambda; - complex_t denominator = (lambda0*coeff.L(0,0) + coeff.L(0,1) + lambdaN*(lambda0*coeff.L(1,0) + coeff.L(1,1))); - coeff.R = (lambda0*coeff.L(0,0) - coeff.L(0,1) + lambdaN*(lambda0*coeff.L(1,0) - coeff.L(1,1)))/denominator; - // Boundary values at bottom of top layer - // and top of first layer: - coeff[1].phi_psi(0) = coeff[0].phi_psi(0) = lambda0*(coeff.R - 1.0); - coeff[1].phi_psi(1) = coeff[0].phi_psi(1) = coeff.R + 1.0; - for(size_t i=2; i<coeff.size(); ++i) { - coeff[i].phi_psi = coeff[i-1].l*coeff[i-1].phi_psi; + // First layer boundary is also top layer boundary: + coeff[0].l.setIdentity(); + coeff[0].phi_psi = coeff[1].phi_psi; + // Normalize all boundary values with top layer transmitted wave: + complex_t T0 = coeff[0].T(); + for (size_t i=0; i<N; ++i) { + coeff[i].phi_psi = coeff[i].phi_psi/T0; } } diff --git a/dev-tools/log/perf_history.txt b/dev-tools/log/perf_history.txt index cf9e623a2a2..0dd59d8ac0b 100644 --- a/dev-tools/log/perf_history.txt +++ b/dev-tools/log/perf_history.txt @@ -246,3 +246,4 @@ # added performance method for matrix calculation of layer wave amplitudes 2013-05-07 16:05:21 | jcnsopc74 | macosx64, 2800 MHz | 294118 | 11.976 | 11.976 | 3.63636 | 1.05263e+06 | +2013-05-07 16:44:53 | jcnsopc74 | macosx64, 2800 MHz | 298507 | 11.9048 | 11.8343 | 3.63636 | 1.05263e+06 | -- GitLab