From dee5092fa04e628c1a64361c645a5c4e9e4c3062 Mon Sep 17 00:00:00 2001 From: Randolf Beerwerth <r.beerwerth@fz-juelich.de> Date: Mon, 23 Mar 2020 09:48:32 +0100 Subject: [PATCH] Introduce strategy pointers into IFresnelMap and SpecularComputationTerm --- Core/Computation/ProcessedSample.cpp | 6 ++++-- Core/Computation/SpecularComputation.cpp | 6 ++++-- Core/Computation/SpecularComputationTerm.cpp | 10 +++++++--- Core/Computation/SpecularComputationTerm.h | 13 ++++++++++--- Core/Multilayer/IFresnelMap.cpp | 3 ++- Core/Multilayer/IFresnelMap.h | 5 ++++- Core/Multilayer/MatrixFresnelMap.cpp | 6 +++--- Core/Multilayer/MatrixFresnelMap.h | 2 +- Core/Multilayer/ScalarFresnelMap.cpp | 13 ++++++------- Core/Multilayer/ScalarFresnelMap.h | 8 ++++---- 10 files changed, 45 insertions(+), 27 deletions(-) diff --git a/Core/Computation/ProcessedSample.cpp b/Core/Computation/ProcessedSample.cpp index c2dedc087a9..1cfb44024b5 100644 --- a/Core/Computation/ProcessedSample.cpp +++ b/Core/Computation/ProcessedSample.cpp @@ -24,6 +24,8 @@ #include "ScalarFresnelMap.h" #include "SimulationOptions.h" #include "Slice.h" +#include "SpecularScalarStrategy.h" +#include "SpecularMagneticStrategy.h" namespace { @@ -282,9 +284,9 @@ std::unique_ptr<IFresnelMap> CreateFresnelMap(const std::vector<Slice>& slices, { std::unique_ptr<IFresnelMap> P_result; if (ContainsMagneticSlice(slices)) - P_result.reset(new MatrixFresnelMap()); + P_result.reset(new MatrixFresnelMap(std::make_unique<SpecularMagneticStrategy>())); else - P_result.reset(new ScalarFresnelMap()); + P_result.reset(new ScalarFresnelMap(std::make_unique<SpecularScalarStrategy>())); if (options.isIntegrate()) P_result->disableCaching(); return P_result; diff --git a/Core/Computation/SpecularComputation.cpp b/Core/Computation/SpecularComputation.cpp index 6549b64ac56..addb6e6de70 100644 --- a/Core/Computation/SpecularComputation.cpp +++ b/Core/Computation/SpecularComputation.cpp @@ -16,6 +16,8 @@ #include "MultiLayer.h" #include "ProcessedSample.h" #include "ProgressHandler.h" +#include "SpecularScalarStrategy.h" +#include "SpecularMagneticStrategy.h" #include "SpecularSimulationElement.h" static_assert(std::is_copy_constructible<SpecularComputation>::value == false, @@ -33,9 +35,9 @@ SpecularComputation::SpecularComputation(const MultiLayer& multilayer, { if (mP_processed_sample->containsMagneticMaterial() || mP_processed_sample->externalField() != kvector_t{}) - m_computation_term.reset(new SpecularMatrixTerm); + m_computation_term.reset(new SpecularMatrixTerm(std::make_unique<SpecularMagneticStrategy>())); else - m_computation_term.reset(new SpecularScalarTerm); + m_computation_term.reset(new SpecularScalarTerm(std::make_unique<SpecularScalarStrategy>())); } SpecularComputation::~SpecularComputation() = default; diff --git a/Core/Computation/SpecularComputationTerm.cpp b/Core/Computation/SpecularComputationTerm.cpp index 85f5d1d0a29..1dbf8af825c 100644 --- a/Core/Computation/SpecularComputationTerm.cpp +++ b/Core/Computation/SpecularComputationTerm.cpp @@ -18,7 +18,9 @@ #include "SpecularScalarStrategy.h" #include "SpecularSimulationElement.h" -SpecularComputationTerm::SpecularComputationTerm() = default; +SpecularComputationTerm::SpecularComputationTerm(std::unique_ptr<ISpecularStrategy> strategy) : m_Strategy(std::move(strategy)) {}; + +SpecularScalarTerm::SpecularScalarTerm(std::unique_ptr<ISpecularStrategy> strategy) : SpecularComputationTerm(std::move(strategy)) {} SpecularComputationTerm::~SpecularComputationTerm() = default; @@ -48,17 +50,19 @@ void SpecularScalarTerm::eval(SpecularSimulationElement& elem, elem.setIntensity(std::norm(coeff.front()->getScalarR())); } +SpecularMatrixTerm::SpecularMatrixTerm(std::unique_ptr<ISpecularStrategy> strategy) : SpecularComputationTerm(std::move(strategy)) {} + SpecularMatrixTerm::~SpecularMatrixTerm() = default; void SpecularMatrixTerm::eval(SpecularSimulationElement& elem, const std::vector<Slice>& slices) const { - auto coeff = std::make_unique<SpecularMagneticStrategy>()->Execute(slices, elem.produceKz(slices)); + auto coeff = m_Strategy->Execute(slices, elem.produceKz(slices)); elem.setIntensity(intensity(elem, coeff.front())); } double SpecularMatrixTerm::intensity(const SpecularSimulationElement& elem, - SpecularMagneticStrategy::single_coeff_t& coeff) const + ISpecularStrategy::single_coeff_t& coeff) const { const auto& polarization = elem.polarizationHandler().getPolarization(); const auto& analyzer = elem.polarizationHandler().getAnalyzerOperator(); diff --git a/Core/Computation/SpecularComputationTerm.h b/Core/Computation/SpecularComputationTerm.h index 53390656a37..7111a1f1446 100644 --- a/Core/Computation/SpecularComputationTerm.h +++ b/Core/Computation/SpecularComputationTerm.h @@ -15,7 +15,7 @@ #ifndef SPECULARCOMPUTATIONTERM_H_ #define SPECULARCOMPUTATIONTERM_H_ -#include "SpecularMagneticStrategy.h" +#include "ISpecularStrategy.h" #include <memory> #include <vector> @@ -33,7 +33,7 @@ class Slice; class SpecularComputationTerm { public: - SpecularComputationTerm(); + SpecularComputationTerm(std::unique_ptr<ISpecularStrategy> strategy); virtual ~SpecularComputationTerm(); void setProgressHandler(ProgressHandler* p_progress); @@ -42,12 +42,16 @@ public: protected: virtual void eval(SpecularSimulationElement& elem, const std::vector<Slice>& slices) const = 0; + std::unique_ptr<ISpecularStrategy> m_Strategy; private: std::unique_ptr<DelayedProgressCounter> mP_progress_counter; }; class SpecularScalarTerm : public SpecularComputationTerm { +public: + SpecularScalarTerm(std::unique_ptr<ISpecularStrategy> strategy); +private: ~SpecularScalarTerm() override; protected: void eval(SpecularSimulationElement& elem, const std::vector<Slice>& slices) const override; @@ -55,11 +59,14 @@ protected: class SpecularMatrixTerm : public SpecularComputationTerm { +public: + SpecularMatrixTerm(std::unique_ptr<ISpecularStrategy> strategy); +private: ~SpecularMatrixTerm() override; protected: void eval(SpecularSimulationElement& elem, const std::vector<Slice>& slices) const override; double intensity(const SpecularSimulationElement& elem, - SpecularMagneticStrategy::single_coeff_t& coeff) const; + ISpecularStrategy::single_coeff_t& coeff) const; }; #endif /* SPECULARCOMPUTATIONTERM_H_ */ diff --git a/Core/Multilayer/IFresnelMap.cpp b/Core/Multilayer/IFresnelMap.cpp index 28fc199d36e..318bfd65ea0 100644 --- a/Core/Multilayer/IFresnelMap.cpp +++ b/Core/Multilayer/IFresnelMap.cpp @@ -15,7 +15,8 @@ #include "IFresnelMap.h" #include "Slice.h" -IFresnelMap::IFresnelMap() : m_use_cache(true) {} +IFresnelMap::IFresnelMap(std::unique_ptr<ISpecularStrategy> strategy) : m_use_cache(true), + m_Strategy(std::move(strategy)) {} void IFresnelMap::setSlices(const std::vector<Slice>& slices) { diff --git a/Core/Multilayer/IFresnelMap.h b/Core/Multilayer/IFresnelMap.h index 4b2b3c3472e..2dc6547abd9 100644 --- a/Core/Multilayer/IFresnelMap.h +++ b/Core/Multilayer/IFresnelMap.h @@ -16,6 +16,7 @@ #define IFRESNELMAP_H #include "ILayerRTCoefficients.h" +#include "ISpecularStrategy.h" #include "Slice.h" #include "Vectors3D.h" #include "WinDllMacros.h" @@ -32,7 +33,7 @@ class SimulationElement; class BA_CORE_API_ IFresnelMap { public: - IFresnelMap(); + IFresnelMap(std::unique_ptr<ISpecularStrategy> strategy); virtual ~IFresnelMap(); //! Retrieves the amplitude coefficients for a (time-reversed) outgoing wavevector. @@ -59,6 +60,8 @@ protected: std::vector<Slice> m_slices; bool m_use_cache; + + std::unique_ptr<ISpecularStrategy> m_Strategy; }; #endif // IFRESNELMAP_H diff --git a/Core/Multilayer/MatrixFresnelMap.cpp b/Core/Multilayer/MatrixFresnelMap.cpp index e25247094e2..03bfbfb578b 100644 --- a/Core/Multilayer/MatrixFresnelMap.cpp +++ b/Core/Multilayer/MatrixFresnelMap.cpp @@ -20,7 +20,7 @@ #include <functional> -MatrixFresnelMap::MatrixFresnelMap() = default; +MatrixFresnelMap::MatrixFresnelMap(std::unique_ptr<ISpecularStrategy> strategy) : IFresnelMap(std::move(strategy)) {}; MatrixFresnelMap::~MatrixFresnelMap() = default; @@ -60,7 +60,7 @@ MatrixFresnelMap::getCoefficients(const kvector_t& kvec, size_t layer_index, const std::vector<Slice>& slices, CoefficientHash& hash_table) const { if (!m_use_cache) { - auto coeffs = std::make_unique<SpecularMagneticStrategy>()->Execute(slices, kvec); + auto coeffs = m_Strategy->Execute(slices, kvec); return ISpecularStrategy::single_coeff_t(coeffs[layer_index]->clone()); } const auto& coef_vector = getCoefficientsFromCache(kvec, slices, hash_table); @@ -73,6 +73,6 @@ MatrixFresnelMap::getCoefficientsFromCache(kvector_t kvec, const std::vector<Sli { auto it = hash_table.find(kvec); if (it == hash_table.end()) - it = hash_table.emplace(kvec, std::make_unique<SpecularMagneticStrategy>()->Execute(slices, kvec)).first; + it = hash_table.emplace(kvec, m_Strategy->Execute(slices, kvec)).first; return it->second; } diff --git a/Core/Multilayer/MatrixFresnelMap.h b/Core/Multilayer/MatrixFresnelMap.h index 7c8fecf2f78..06b3a23afb6 100644 --- a/Core/Multilayer/MatrixFresnelMap.h +++ b/Core/Multilayer/MatrixFresnelMap.h @@ -35,7 +35,7 @@ class SimulationElement; class BA_CORE_API_ MatrixFresnelMap : public IFresnelMap { public: - MatrixFresnelMap(); + MatrixFresnelMap(std::unique_ptr<ISpecularStrategy> strategy); ~MatrixFresnelMap() override; MatrixFresnelMap(const MatrixFresnelMap& other) = delete; diff --git a/Core/Multilayer/ScalarFresnelMap.cpp b/Core/Multilayer/ScalarFresnelMap.cpp index 56e95614069..1b24d8f3ecb 100644 --- a/Core/Multilayer/ScalarFresnelMap.cpp +++ b/Core/Multilayer/ScalarFresnelMap.cpp @@ -19,7 +19,7 @@ #include "Vectors3D.h" #include <functional> -ScalarFresnelMap::ScalarFresnelMap() {} +ScalarFresnelMap::ScalarFresnelMap(std::unique_ptr<ISpecularStrategy> strategy) : IFresnelMap(std::move(strategy)) {} ScalarFresnelMap::~ScalarFresnelMap() = default; @@ -39,21 +39,20 @@ std::unique_ptr<const ILayerRTCoefficients> ScalarFresnelMap::getCoefficients(const kvector_t& kvec, size_t layer_index) const { if (!m_use_cache) { - auto coeffs = std::make_unique<SpecularScalarStrategy>()->Execute(m_slices, kvec); - return SpecularScalarStrategy::single_coeff_t(coeffs[layer_index]->clone()); + auto coeffs = m_Strategy->Execute(m_slices, kvec); + return ISpecularStrategy::single_coeff_t(coeffs[layer_index]->clone()); } const auto& coef_vector = getCoefficientsFromCache(kvec); - return SpecularScalarStrategy::single_coeff_t(coef_vector[layer_index]->clone()); + return ISpecularStrategy::single_coeff_t(coef_vector[layer_index]->clone()); } -const SpecularScalarStrategy::coeffs_t& +const ISpecularStrategy::coeffs_t& ScalarFresnelMap::getCoefficientsFromCache(kvector_t kvec) const { std::pair<double, double> k2_theta(kvec.mag2(), kvec.theta()); auto it = m_cache.find(k2_theta); if (it == m_cache.end()) { - it = m_cache.emplace(k2_theta, - std::make_unique<SpecularScalarStrategy>()->Execute(m_slices, kvec)).first; + it = m_cache.emplace(k2_theta, m_Strategy->Execute(m_slices, kvec)).first; } return it->second; } diff --git a/Core/Multilayer/ScalarFresnelMap.h b/Core/Multilayer/ScalarFresnelMap.h index 9a5ef0ce575..68d19d5b117 100644 --- a/Core/Multilayer/ScalarFresnelMap.h +++ b/Core/Multilayer/ScalarFresnelMap.h @@ -17,7 +17,7 @@ #include "IFresnelMap.h" #include "ScalarRTCoefficients.h" -#include "SpecularScalarStrategy.h" +#include "ISpecularStrategy.h" #include <cstddef> #include <unordered_map> #include <utility> @@ -33,7 +33,7 @@ class Slice; class BA_CORE_API_ ScalarFresnelMap : public IFresnelMap { public: - ScalarFresnelMap(); + ScalarFresnelMap(std::unique_ptr<ISpecularStrategy> strategy); ~ScalarFresnelMap() final; ScalarFresnelMap(const ScalarFresnelMap& other) = delete; @@ -52,8 +52,8 @@ private: std::unique_ptr<const ILayerRTCoefficients> getCoefficients(const kvector_t& kvec, size_t layer_index) const override; - const SpecularScalarStrategy::coeffs_t& getCoefficientsFromCache(kvector_t kvec) const; - mutable std::unordered_map<std::pair<double, double>, SpecularScalarStrategy::coeffs_t, + const ISpecularStrategy::coeffs_t& getCoefficientsFromCache(kvector_t kvec) const; + mutable std::unordered_map<std::pair<double, double>, ISpecularStrategy::coeffs_t, Hash2Doubles> m_cache; }; -- GitLab