From 18f70251f23daec3fd40571369450d20908a41b4 Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de> Date: Wed, 7 Dec 2022 10:34:44 +0100 Subject: [PATCH] ZLimits duplicated in Base/Types/Span, for use in formfactors --- Base/Types/Span.cpp | 57 +++++++++++++++++++++++++ Base/Types/Span.h | 65 +++++++++++++++++++++++++++++ Resample/Particle/IReParticle.cpp | 1 - Resample/Particle/IReParticle.h | 4 +- Resample/Particle/ReCompound.cpp | 8 ++-- Resample/Particle/ReCompound.h | 2 +- Resample/Particle/ReMesocrystal.cpp | 4 +- Resample/Particle/ReMesocrystal.h | 2 +- Resample/Particle/ReParticle.cpp | 4 +- Resample/Particle/ReParticle.h | 2 +- Resample/Processed/ReSample.cpp | 3 +- Resample/Processed/Slicer.cpp | 22 +++++----- Resample/Processed/Slicer.h | 6 +-- 13 files changed, 151 insertions(+), 29 deletions(-) create mode 100644 Base/Types/Span.cpp create mode 100644 Base/Types/Span.h diff --git a/Base/Types/Span.cpp b/Base/Types/Span.cpp new file mode 100644 index 00000000000..368a3d8b3c4 --- /dev/null +++ b/Base/Types/Span.cpp @@ -0,0 +1,57 @@ +// ************************************************************************************************ +// +// BornAgain: simulate and fit reflection and scattering +// +//! @file Base/Types/Span.cpp +//! @brief Defines class Span. +//! +//! @homepage http://www.bornagainproject.org +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2018 +//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) +// +// ************************************************************************************************ + +#include "Base/Types/Span.h" +#include "Base/Util/Assert.h" +#include <algorithm> +#include <cmath> + +Span::Span(double _min, double _max) + : m_zmin(_min) + , m_zmax(_max) +{ + ASSERT(_min < _max); +} + +Span::Span() + : Span(-inf, inf) +{ +} + +bool Span::isFinite() const +{ + return !std::isinf(m_zmin) && !std::isinf(m_zmax); +} + +// TODO sep22: rm all the following if they remain UNUSED + +Span Span::enclosingInterval(const Span& left, const Span& right) +{ + return {std::min(left.zBottom(), right.zBottom()), std::max(left.zTop(), right.zTop())}; +} + +bool operator==(const Span& left, const Span& right) +{ + return (left.zBottom() == right.zBottom() && left.zTop() == right.zTop()); +} + +bool operator!=(const Span& left, const Span& right) +{ + return !(left == right); +} + +std::ostream& operator<<(std::ostream& ostr, const Span& limits) +{ + return ostr << "Lower: " << limits.zBottom() << ", Upper: " << limits.zTop(); +} diff --git a/Base/Types/Span.h b/Base/Types/Span.h new file mode 100644 index 00000000000..9db6ef2cbed --- /dev/null +++ b/Base/Types/Span.h @@ -0,0 +1,65 @@ +// ************************************************************************************************ +// +// BornAgain: simulate and fit reflection and scattering +// +//! @file Base/Types/Span.h +//! @brief Defines class Span. +//! +//! @homepage http://www.bornagainproject.org +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2018 +//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) +// +// ************************************************************************************************ + +#ifdef SWIG +#error no need to expose this header to Swig +#endif + +#ifndef USER_API +#ifndef BORNAGAIN_BASE_TYPES_SPAN_H +#define BORNAGAIN_BASE_TYPES_SPAN_H + +#include <cmath> +#include <iostream> +#include <limits> + +//! An interval. Limits are of type double, and may be infinite. +//! Used for the z-coordinate, especially when slicing form factors. +//! +//! @ingroup intern + +class Span { +public: + Span(); + Span(double _min, double _max); + + bool isFinite() const; + + double zBottom() const { return m_zmin; } + double zTop() const { return m_zmax; } + double zTopOr0() const { return std::isfinite(m_zmax) ? m_zmax : 0; } + double thicknessOr0() const { return isFinite() ? m_zmax - m_zmin : 0; } + + bool contains(double z) const { return m_zmin <= z && z <= m_zmax; } + + std::pair<double, double> pair() const { return {m_zmin, m_zmax}; } + + static constexpr double inf = std::numeric_limits<double>::infinity(); + + //! Returns the union of two Span (the minimal interval that contains both input intervals). + static Span enclosingInterval(const Span& left, const Span& right); + +private: + // members are not const because we need the implicit copy assignement operator + double m_zmin; + double m_zmax; +}; + +bool operator==(const Span& left, const Span& right); +bool operator!=(const Span& left, const Span& right); + +std::ostream& operator<<(std::ostream& ostr, const Span& limits); + +#endif // BORNAGAIN_BASE_TYPES_SPAN_H +#endif // USER_API diff --git a/Resample/Particle/IReParticle.cpp b/Resample/Particle/IReParticle.cpp index 17dd8e2c2dc..328ffa456bf 100644 --- a/Resample/Particle/IReParticle.cpp +++ b/Resample/Particle/IReParticle.cpp @@ -19,7 +19,6 @@ #include "Resample/Element/DiffuseElement.h" #include "Resample/Flux/MatrixFlux.h" #include "Resample/Flux/ScalarFlux.h" -#include "Resample/Slice/ZLimits.h" #include "Sample/Material/Admixtures.h" #include <memory> diff --git a/Resample/Particle/IReParticle.h b/Resample/Particle/IReParticle.h index 77739fca028..db3f32b5990 100644 --- a/Resample/Particle/IReParticle.h +++ b/Resample/Particle/IReParticle.h @@ -32,7 +32,7 @@ class IRotation; class Material; class SpinMatrix; class WavevectorInfo; -class ZLimits; +class Span; //! Abstract base class for reprocessed particles. //! @@ -62,7 +62,7 @@ public: //! form factor's shape. This is used for SSCA calculations virtual double radialExtension() const = 0; - virtual ZLimits Z_span() const = 0; + virtual Span Z_span() const = 0; //! Returns the total volume of the particle of this form factor's shape virtual double volume() const; diff --git a/Resample/Particle/ReCompound.cpp b/Resample/Particle/ReCompound.cpp index 9a2b1869d73..7d600b583d3 100644 --- a/Resample/Particle/ReCompound.cpp +++ b/Resample/Particle/ReCompound.cpp @@ -13,9 +13,9 @@ // ************************************************************************************************ #include "Resample/Particle/ReCompound.h" +#include "Base/Types/Span.h" #include "Base/Util/Assert.h" #include "Base/Vector/WavevectorInfo.h" // debug -#include "Resample/Slice/ZLimits.h" ReCompound::ReCompound(const std::optional<size_t>& i_layer) : IReParticle(i_layer) @@ -40,12 +40,12 @@ double ReCompound::radialExtension() const return result; } -ZLimits ReCompound::Z_span() const +Span ReCompound::Z_span() const { ASSERT(!m_components.empty()); - ZLimits result = m_components[0]->Z_span(); + Span result = m_components[0]->Z_span(); for (size_t i = 1; i < m_components.size(); ++i) - result = ZLimits::enclosingInterval(result, m_components[i]->Z_span()); + result = Span::enclosingInterval(result, m_components[i]->Z_span()); return result; } diff --git a/Resample/Particle/ReCompound.h b/Resample/Particle/ReCompound.h index cd7ca56edf2..71e8cbf08d8 100644 --- a/Resample/Particle/ReCompound.h +++ b/Resample/Particle/ReCompound.h @@ -38,7 +38,7 @@ public: double radialExtension() const override; - ZLimits Z_span() const override; + Span Z_span() const override; void addFormFactor(const IReParticle& formfactor); diff --git a/Resample/Particle/ReMesocrystal.cpp b/Resample/Particle/ReMesocrystal.cpp index 2d7855d7695..e73ad406a6d 100644 --- a/Resample/Particle/ReMesocrystal.cpp +++ b/Resample/Particle/ReMesocrystal.cpp @@ -15,9 +15,9 @@ #include "Resample/Particle/ReMesocrystal.h" #include "Base/Math/Constants.h" #include "Base/Spin/SpinMatrix.h" +#include "Base/Types/Span.h" #include "Base/Vector/WavevectorInfo.h" #include "Resample/Particle/ReParticle.h" -#include "Resample/Slice/ZLimits.h" ReMesocrystal::ReMesocrystal(const std::optional<size_t>& i_layer, const Lattice3D& lattice, const IReParticle& basis, const ReParticle& outer_shape, @@ -48,7 +48,7 @@ double ReMesocrystal::radialExtension() const return m_outer_shape->radialExtension(); } -ZLimits ReMesocrystal::Z_span() const +Span ReMesocrystal::Z_span() const { return m_outer_shape->Z_span(); } diff --git a/Resample/Particle/ReMesocrystal.h b/Resample/Particle/ReMesocrystal.h index a2cfe61915d..e92922a5f89 100644 --- a/Resample/Particle/ReMesocrystal.h +++ b/Resample/Particle/ReMesocrystal.h @@ -43,7 +43,7 @@ public: double volume() const override; double radialExtension() const override; - ZLimits Z_span() const override; + Span Z_span() const override; complex_t theFF(const WavevectorInfo& wavevectors) const override; SpinMatrix thePolFF(const WavevectorInfo& wavevectors) const override; diff --git a/Resample/Particle/ReParticle.cpp b/Resample/Particle/ReParticle.cpp index 8067b88ac8c..4ca8ec62ad9 100644 --- a/Resample/Particle/ReParticle.cpp +++ b/Resample/Particle/ReParticle.cpp @@ -13,9 +13,9 @@ // ************************************************************************************************ #include "Resample/Particle/ReParticle.h" +#include "Base/Types/Span.h" #include "Base/Util/Assert.h" #include "Base/Vector/WavevectorInfo.h" // debug -#include "Resample/Slice/ZLimits.h" #include "Sample/Material/Material.h" #include "Sample/Material/MaterialFactoryFuncs.h" #include "Sample/Particle/IFormFactor.h" @@ -113,7 +113,7 @@ SpinMatrix ReParticle::thePolFF(const WavevectorInfo& wavevectors) const return result; } -ZLimits ReParticle::Z_span() const +Span ReParticle::Z_span() const { RotMatrix transform = m_rotMatrix ? *m_rotMatrix : RotMatrix(); std::unique_ptr<const IRotation> total_rotation(IRotation::createRotation(transform)); diff --git a/Resample/Particle/ReParticle.h b/Resample/Particle/ReParticle.h index e01cfafe76b..3e291c34231 100644 --- a/Resample/Particle/ReParticle.h +++ b/Resample/Particle/ReParticle.h @@ -50,7 +50,7 @@ public: double radialExtension() const override; - ZLimits Z_span() const override; + Span Z_span() const override; const IFormFactor* iformfactor() const; diff --git a/Resample/Processed/ReSample.cpp b/Resample/Processed/ReSample.cpp index d7616b3541d..1262d45aa60 100644 --- a/Resample/Processed/ReSample.cpp +++ b/Resample/Processed/ReSample.cpp @@ -13,6 +13,7 @@ // ************************************************************************************************ #include "Resample/Processed/ReSample.h" +#include "Base/Types/Span.h" #include "Base/Util/Assert.h" #include "Resample/Coherence/CoheringSubparticles.h" #include "Resample/Flux/IFlux.h" @@ -252,7 +253,7 @@ ReLayout makeReLayout(const ParticleLayout& layout, const SliceStack& slices, do myparticle->translate(translation); // if subparticle is contained in this layer, set limits to infinite: - ZLimits limits; + Span limits; if (!single_layer) { double z1 = slice.zTopOr0(); limits = {slice.zBottom() - z1, slice.zTop() - z1}; diff --git a/Resample/Processed/Slicer.cpp b/Resample/Processed/Slicer.cpp index a8e93a2d06e..9841a2b78dd 100644 --- a/Resample/Processed/Slicer.cpp +++ b/Resample/Processed/Slicer.cpp @@ -15,12 +15,12 @@ #include "Resample/Processed/Slicer.h" #include "Base/Math/Constants.h" #include "Base/Math/Functions.h" +#include "Base/Types/Span.h" #include "Base/Util/Assert.h" #include "Base/Vector/RotMatrix.h" #include "Resample/Particle/ReCompound.h" #include "Resample/Particle/ReMesocrystal.h" #include "Resample/Particle/ReParticle.h" -#include "Resample/Slice/ZLimits.h" #include "Sample/HardParticle/HardParticles.h" #include "Sample/Material/MaterialFactoryFuncs.h" #include "Sample/Material/MaterialUtils.h" @@ -41,7 +41,7 @@ struct SlicingEffects { double dz_top; }; -SlicingEffects computeSlicingEffects(ZLimits limits, const R3& position, double height) +SlicingEffects computeSlicingEffects(Span limits, const R3& position, double height) { R3 new_position(position); double z_bottom = position.z(); @@ -60,7 +60,7 @@ SlicingEffects computeSlicingEffects(ZLimits limits, const R3& position, double return {new_position, dz_bottom, dz_top}; } -bool shapeIsContainedInLimits(const IFormFactor& formfactor, ZLimits limits, R3 translation, +bool shapeIsContainedInLimits(const IFormFactor& formfactor, Span limits, R3 translation, const IRotation* rotation) { double zbottom = formfactor.bottomZ(rotation) + translation.z(); @@ -69,7 +69,7 @@ bool shapeIsContainedInLimits(const IFormFactor& formfactor, ZLimits limits, R3 return limits.zBottom() <= zbottom && ztop <= limits.zTop(); } -bool shapeOutsideLimits(const IFormFactor& formfactor, ZLimits limits, R3 translation, +bool shapeOutsideLimits(const IFormFactor& formfactor, Span limits, R3 translation, const IRotation* rotation) { double zbottom = formfactor.bottomZ(rotation) + translation.z(); @@ -86,7 +86,7 @@ ReParticle* createTransformedFormFactor(const IFormFactor* formfactor, const R3& : nullptr); } -ReParticle* createParticleSlice(const IFormFactor* ff, ZLimits limits, const R3& translation, +ReParticle* createParticleSlice(const IFormFactor* ff, Span limits, const R3& translation, const IRotation* rot) { if (shapeOutsideLimits(*ff, limits, translation, rot)) @@ -263,7 +263,7 @@ IReParticle* processBasis(const IParticle* basis, const Material& ambientMat) OwningVector<IReParticle> Compute::Slicing::particlesInSlice(const IParticle* particle, - const ZLimits& limits, + const Span& limits, const Material& ambientMat) { if (const auto* p = dynamic_cast<const Particle*>(particle)) { @@ -374,12 +374,12 @@ OwningVector<IReParticle> Compute::Slicing::particlesInSlice(const IParticle* pa ASSERT(0); } -ZLimits Compute::Slicing::zSpan(const IParticle* particle) +Span Compute::Slicing::zSpan(const IParticle* particle) { if (const auto* p = dynamic_cast<const Particle*>(particle)) { ASSERT(p->pFormfactor()); std::unique_ptr<ReParticle> particleSlice( - createParticleSlice(p->pFormfactor(), ZLimits(), p->particlePosition(), p->rotation())); + createParticleSlice(p->pFormfactor(), Span(), p->particlePosition(), p->rotation())); if (!particleSlice) return {}; return particleSlice->Z_span(); @@ -387,10 +387,10 @@ ZLimits Compute::Slicing::zSpan(const IParticle* particle) } else if (const auto* p = dynamic_cast<const Compound*>(particle)) { const auto subparticles = p->decompose(); ASSERT(subparticles.size() > 0); - ZLimits result = zSpan(subparticles[0]); + Span result = zSpan(subparticles[0]); for (const auto* subparticle : subparticles) // TODO why no rotation and translation as for CoreAndShell ?? - result = ZLimits::enclosingInterval(result, zSpan(subparticle)); + result = Span::enclosingInterval(result, zSpan(subparticle)); return result; } else if (const auto* p = dynamic_cast<const CoreAndShell*>(particle)) { @@ -407,7 +407,7 @@ ZLimits Compute::Slicing::zSpan(const IParticle* particle) const IFormFactor* meso_formfactor = p->outerShape(); ASSERT(meso_formfactor); std::unique_ptr<ReParticle> new_shape( - createParticleSlice(meso_formfactor, ZLimits(), p->particlePosition(), p->rotation())); + createParticleSlice(meso_formfactor, Span(), p->particlePosition(), p->rotation())); return new_shape->Z_span(); diff --git a/Resample/Processed/Slicer.h b/Resample/Processed/Slicer.h index 2c37c0cb0b8..36a75063061 100644 --- a/Resample/Processed/Slicer.h +++ b/Resample/Processed/Slicer.h @@ -27,14 +27,14 @@ class IParticle; class Material; class IReParticle; -class ZLimits; +class Span; namespace Compute::Slicing { -OwningVector<IReParticle> particlesInSlice(const IParticle* particle, const ZLimits&, +OwningVector<IReParticle> particlesInSlice(const IParticle* particle, const Span&, const Material& ambientMat); -ZLimits zSpan(const IParticle* particle); +Span zSpan(const IParticle* particle); } // namespace Compute::Slicing -- GitLab