diff --git a/Sample/Processed/ProcessedSample.cpp b/Sample/Processed/ProcessedSample.cpp index dc15d10671c8140c05f285879bc906548d02206c..64a705434a623a677c6185caf2dae1365e5ccd24 100644 --- a/Sample/Processed/ProcessedSample.cpp +++ b/Sample/Processed/ProcessedSample.cpp @@ -179,7 +179,10 @@ void ProcessedSample::initSlices(const MultiLayer& sample, const SimulationOptio if (!slice_limits.isFinite() || N == 0) { if (i == sample.numberOfLayers() - 1) tl = 0.0; - m_slices.addSlice(tl, *material, roughness); + if (i==0) + m_slices.addTopSlice(tl, *material); + else + m_slices.addSlice(tl, *material, roughness); continue; } const double top = slice_limits.zTop(); @@ -189,7 +192,7 @@ void ProcessedSample::initSlices(const MultiLayer& sample, const SimulationOptio if (top <= 0) throw std::runtime_error("ProcessedSample::ProcessedSample: " "top limit for top layer must be > 0."); - m_slices.addSlice(0.0, *material); // semiinfinite top slice + m_slices.addTopSlice(top, *material); // semiinfinite top slice m_slices.addNSlices(N, top - bottom, *material); if (bottom > 0) m_slices.addSlice(bottom, *material); diff --git a/Sample/Scattering/ZLimits.h b/Sample/Scattering/ZLimits.h index 13c8cbc09437e455d60ef3e7add38cdf3118c66d..6e5fefc9f5b0bdf0ad243cb0a48f1f1d533c0e3d 100644 --- a/Sample/Scattering/ZLimits.h +++ b/Sample/Scattering/ZLimits.h @@ -38,6 +38,7 @@ public: double zBottom() const { return m_zmin; } double zTop() const { return m_zmax; } double thickness() const { return m_zmax - m_zmin; } + double thickness_or_zero() const { return isFinite() ? m_zmax - m_zmin : 0; } static constexpr double inf = std::numeric_limits<double>::infinity(); diff --git a/Sample/Slice/Slice.cpp b/Sample/Slice/Slice.cpp index e41538ac552b988f8fd9739910e37d1b949f42eb..8b1ddbcf03a0d5c5da95aff737ed1bf812c8c087 100644 --- a/Sample/Slice/Slice.cpp +++ b/Sample/Slice/Slice.cpp @@ -17,29 +17,30 @@ #include "Sample/Slice/LayerRoughness.h" #include "Sample/Slice/SliceStack.h" -Slice::Slice(double thickness, const Material& material, const kvector_t& B_field, +Slice::Slice(const ZLimits& zRange, const Material& material, const kvector_t& B_field, LayerRoughness* const roughness) - : m_thickness(thickness), m_material(material), m_B_field(B_field), m_top_roughness(roughness) + : m_zRange(zRange), m_material(material), m_B_field(B_field), m_top_roughness(roughness) { } -Slice::Slice(double thickness, const Material& material) : Slice(thickness, material, {}, nullptr) +Slice::Slice(const ZLimits& zRange, const Material& material) + : Slice(zRange, material, {}, nullptr) { } -Slice::Slice(double thickness, const Material& material, const LayerRoughness& top_roughness) - : Slice(thickness, material, {}, top_roughness.clone()) +Slice::Slice(const ZLimits& zRange, const Material& material, const LayerRoughness& top_roughness) + : Slice(zRange, material, {}, top_roughness.clone()) { } Slice::Slice(const Slice& other) - : Slice(other.m_thickness, other.m_material, other.m_B_field, + : Slice(other.m_zRange, other.m_material, other.m_B_field, other.m_top_roughness ? other.m_top_roughness->clone() : nullptr) { } Slice::Slice(Slice&& other) - : m_thickness{other.m_thickness} + : m_zRange{other.m_zRange} , m_material{std::move(other.m_material)} , m_B_field{other.m_B_field} , m_top_roughness{std::move(other.m_top_roughness)} @@ -58,9 +59,19 @@ const Material& Slice::material() const return m_material; } +double Slice::zBottom() const +{ + return m_zRange.zBottom(); +} + +double Slice::zTop() const +{ + return m_zRange.zTop(); +} + double Slice::thickness() const { - return m_thickness; + return m_zRange.thickness_or_zero(); } const LayerRoughness* Slice::topRoughness() const diff --git a/Sample/Slice/Slice.h b/Sample/Slice/Slice.h index 8c737f4e228f98b941532b0b36a420048f680f28..d52daa750ed62ec4e6886af51912d3a230f14bd4 100644 --- a/Sample/Slice/Slice.h +++ b/Sample/Slice/Slice.h @@ -21,6 +21,7 @@ #define BORNAGAIN_SAMPLE_SLICE_SLICE_H #include "Sample/Material/Material.h" +#include "Sample/Scattering/ZLimits.h" #include <memory> class LayerRoughness; @@ -31,10 +32,10 @@ class LayerRoughness; class Slice { public: - Slice(double thickness, const Material& material, const kvector_t& B_field, + Slice(const ZLimits& zRange, const Material& material, const kvector_t& B_field, LayerRoughness* const roughness); - Slice(double thickness, const Material& material); - Slice(double thickness, const Material& material, const LayerRoughness& top_roughness); + Slice(const ZLimits& zRange, const Material& material); + Slice(const ZLimits& zRange, const Material& material, const LayerRoughness& top_roughness); Slice(const Slice& other); Slice(Slice&& other); ~Slice(); @@ -42,6 +43,8 @@ public: void setMaterial(const Material& material); const Material& material() const; + double zBottom() const; + double zTop() const; double thickness() const; const LayerRoughness* topRoughness() const; @@ -61,7 +64,7 @@ public: void invertBField(); private: - const double m_thickness; + const ZLimits m_zRange; Material m_material; kvector_t m_B_field; //!< cached value of magnetic induction std::unique_ptr<const LayerRoughness> m_top_roughness; diff --git a/Sample/Slice/SliceStack.cpp b/Sample/Slice/SliceStack.cpp index e0eb1df39535c8002c350e5e521191ba8f126f98..d5ff5b65e242e335ccdc921c3d907195909ae739 100644 --- a/Sample/Slice/SliceStack.cpp +++ b/Sample/Slice/SliceStack.cpp @@ -16,13 +16,26 @@ #include "Base/Utils/Assert.h" #include "Sample/Slice/Slice.h" +void SliceStack::addTopSlice(double zbottom, const Material& material) +{ + this->emplace_back(Slice(ZLimits(zbottom, ZLimits::inf), material)); +} + void SliceStack::addSlice(double thickness, const Material& material, const LayerRoughness* roughness) { + ASSERT(this->size()>0); + double top = this->back().zBottom(); + ASSERT(thickness>=0); + std::unique_ptr<ZLimits> zRange; + if (thickness==0) + zRange = std::make_unique<ZLimits>(-ZLimits::inf, top); + else + zRange = std::make_unique<ZLimits>(top-thickness, top); if (roughness) - this->emplace_back(Slice(thickness, material, *roughness)); + this->emplace_back(Slice(*zRange, material, *roughness)); else - this->emplace_back(Slice(thickness, material)); + this->emplace_back(Slice(*zRange, material)); } //! Adds n times the same slice to the stack. @@ -30,8 +43,7 @@ void SliceStack::addSlice(double thickness, const Material& material, void SliceStack::addNSlices(size_t n, double thickness, const Material& material, const LayerRoughness* roughness) { - if (thickness <= 0.0) - return; + ASSERT(thickness>0); ASSERT(n > 0); const double slice_thickness = thickness / n; addSlice(slice_thickness, material, roughness); diff --git a/Sample/Slice/SliceStack.h b/Sample/Slice/SliceStack.h index 30f26776f2fd6c7c8e1eaa11cbd61ee21ee2c1cd..4362758857f418cec89816f45e5237df1bc6ebc9 100644 --- a/Sample/Slice/SliceStack.h +++ b/Sample/Slice/SliceStack.h @@ -32,8 +32,7 @@ class Slice; class SliceStack : public std::vector<Slice> { public: - void addTopSlice(double zbottom, const Material& material, - const LayerRoughness* roughness = nullptr); + void addTopSlice(double zbottom, const Material& material); void addSlice(double thickness, const Material& material, const LayerRoughness* roughness = nullptr); void addNSlices(size_t n, double thickness, const Material& material, diff --git a/Sample/StandardSamples/MagneticLayersBuilder.cpp b/Sample/StandardSamples/MagneticLayersBuilder.cpp index 9397d9734356b39e205276aff5f9d0512292bc5b..815faaa8a0ea80634d55602c182c1409e1b350c2 100644 --- a/Sample/StandardSamples/MagneticLayersBuilder.cpp +++ b/Sample/StandardSamples/MagneticLayersBuilder.cpp @@ -112,12 +112,10 @@ MultiLayer* MagneticLayerBuilder::buildSample() const particle_layout.addParticle(particle, 1.0); Layer vacuum_layer(vacuum_material); - Layer intermediate_layer(layer_material); - intermediate_layer.addLayout(particle_layout); + vacuum_layer.addLayout(particle_layout); Layer substrate_layer(substrate_material); multi_layer->addLayer(vacuum_layer); - multi_layer->addLayer(intermediate_layer); multi_layer->addLayer(substrate_layer); return multi_layer; } diff --git a/Tests/UnitTests/Core/Fresnel/SpecularScanTest.cpp b/Tests/UnitTests/Core/Fresnel/SpecularScanTest.cpp index e547d949ad0116a7878268f299172b0c43e404c0..3cffac065eed362e5fa80e53247eaadfa40c04e7 100644 --- a/Tests/UnitTests/Core/Fresnel/SpecularScanTest.cpp +++ b/Tests/UnitTests/Core/Fresnel/SpecularScanTest.cpp @@ -224,7 +224,7 @@ TEST_F(SpecularScanTest, GenerateSimElements) std::vector<SpecularSimulationElement> sim_elements3 = scan2.generateSimulationElements(instrument); SliceStack slices; - slices.emplace_back(0., MaterialBySLD()); + slices.addTopSlice(0., MaterialBySLD()); for (size_t i = 0; i < sim_elements3.size(); ++i) { const auto generatedKzs = sim_elements3[i].produceKz(slices); EXPECT_EQ(generatedKzs[0].imag(), 0.); diff --git a/Tests/UnitTests/Core/Sample/RTTest.cpp b/Tests/UnitTests/Core/Sample/RTTest.cpp index 530e66d5063a76e74b8a7fb4d771e55a19f47ae2..7edd8f0ff1f3b47f9fa38aeb95b8464595030c6f 100644 --- a/Tests/UnitTests/Core/Sample/RTTest.cpp +++ b/Tests/UnitTests/Core/Sample/RTTest.cpp @@ -94,7 +94,6 @@ TEST_F(RTTest, SplitBilayers) for (size_t i = 0; i < n; ++i) { sample2.addLayer(Layer(amat, 100)); sample2.addLayer(Layer(bmat, 100)); - sample2.addLayer(Layer(amat, 0)); sample2.addLayer(Layer(bmat, 100)); } sample2.addLayer(substrate); @@ -138,7 +137,6 @@ TEST_F(RTTest, Overflow) for (size_t i = 0; i < n; ++i) { sample2.addLayer(Layer(amat, 1000)); sample2.addLayer(Layer(bmat, 100000)); - sample2.addLayer(Layer(amat, 0)); sample2.addLayer(Layer(bmat, 100000)); } sample2.addLayer(substrate);