diff --git a/Resample/Particle/IReParticle.h b/Resample/Particle/IReParticle.h index 6bedb92d6bea5b254caa0198ecaeeefdd0f36c49..58415fa01d1ca3182c3f68fbce7b04178e9bfa9c 100644 --- a/Resample/Particle/IReParticle.h +++ b/Resample/Particle/IReParticle.h @@ -17,7 +17,6 @@ #define BORNAGAIN_RESAMPLE_PARTICLE_IREPARTICLE_H #include "Base/Types/ICloneable.h" -#include "Param/Node/INode.h" #include "Sample/Scattering/ZLimits.h" #include <Eigen/Core> #include <heinz/Complex.h> @@ -33,10 +32,9 @@ class WavevectorInfo; //! which depends on the incoming and outgoing wave vectors ki and kf. //! If it only depends on the scattering vector q=ki-kf, then it is a DecoratedBorn. -class IReParticle : public ICloneable, public INode { +class IReParticle : public ICloneable { protected: IReParticle() = default; - IReParticle(const NodeMeta& meta, const std::vector<double>& PValues); public: ~IReParticle() override = default; diff --git a/Resample/Processed/Slicer.cpp b/Resample/Processed/Slicer.cpp index 30dd08be2fec600ea755e0c8936454a6b5355fcc..e750f580e2ea01db8793d97ab8ed49fb04575dba 100644 --- a/Resample/Processed/Slicer.cpp +++ b/Resample/Processed/Slicer.cpp @@ -15,6 +15,12 @@ #include "Sample/Processed/Slicer.h" #include "Resample/Particle/ReParticle.h" #include "Sample/HardParticle/HardParticles.h" +#include "Resample/Particle/ReCoreShell.h" +#include "Resample/Particle/ParticleInSlice.h" +#include "Resample/Particle/ReMesocrystal.h" +#include "Resample/Particle/ReCompound.h" +#include "Resample/Particle/ReParticle.h" +#include "Sample/Material/MaterialFactoryFuncs.h" namespace { @@ -267,3 +273,100 @@ ReParticle* preprocessor::createSlicedFormFactor(IBornFF& ff, throw std::runtime_error("Slicing of " + className() + " not supported for the given rotation!"); } + + +ParticleInSlice ParticleCoreShell::createParticleInSlice(const ZLimits& limits) const +{ + ASSERT(m_core && m_shell); + + // core + std::unique_ptr<Particle> P_core(m_core->clone()); + if (m_rotation) + P_core->rotate(*m_rotation); + P_core->translate(m_position); + auto sliced_core = P_core->createParticleInSlice(limits); + + // shell + std::unique_ptr<Particle> P_shell(m_shell->clone()); + if (m_rotation) + P_shell->rotate(*m_rotation); + P_shell->translate(m_position); + auto sliced_shell = P_shell->createParticleInSlice(limits); + if (!sliced_shell.sliced_ff) + return {}; + + ParticleInSlice result; + // if core out of limits, return sliced shell + if (!sliced_core.sliced_ff) { + result.sliced_ff = std::move(sliced_shell.sliced_ff); + result.admixtures.push_back(sliced_shell.admixtures.back()); + return result; + } + + // set core ambient material + if (sliced_shell.admixtures.size() != 1) + return {}; + auto shell_material = sliced_shell.admixtures[0].material; + sliced_core.sliced_ff->setAmbientMaterial(shell_material); + + // construct sliced particle + sliced_shell.admixtures.back().fraction -= sliced_core.admixtures.back().fraction; + result.sliced_ff = std::make_unique<ReCoreShell>(sliced_core.sliced_ff.release(), + sliced_shell.sliced_ff.release()); + result.admixtures.push_back(sliced_core.admixtures.back()); + result.admixtures.push_back(sliced_shell.admixtures.back()); + + return result; +} + +ParticleInSlice MesoCrystal::createParticleInSlice(const ZLimits& limits) const +{ + ASSERT(m_crystal && m_meso_formfactor); + + double unit_cell_volume = m_crystal->lattice()->unitCellVolume(); + if (unit_cell_volume <= 0) + return {}; + + ParticleInSlice result; + + std::unique_ptr<ReParticle> tem_ff( + m_meso_formfactor->createSlicedFormFactor(limits, m_rotation.get(), m_position)); + + const std::unique_ptr<Crystal> new_crystal( + m_crystal->transformed(m_rotation.get(), m_position)); + const std::unique_ptr<IReParticle> new_basis_ff(new_crystal->basis()->createFormFactor()); + + result.sliced_ff.reset(new ReMesocrystal(*new_crystal->lattice(), *new_basis_ff, *tem_ff, + new_crystal->position_variance())); + + Admixtures& regions = result.admixtures; + ASSERT(regions.empty()); + for (const auto& particle : m_crystal->basis()->decompose()) { + ParticleInSlice pis = particle->createParticleInSlice({}); + regions.insert(regions.end(), pis.admixtures.begin(), pis.admixtures.end()); + } + for (auto& region : regions) + region.fraction *= m_meso_formfactor->volume() / unit_cell_volume; + + return result; +} + +ParticleInSlice ParticleComposition::createParticleInSlice(const ZLimits&) const +{ + throw std::runtime_error("ParticleComposition does not yet support slicing"); +} + + +ParticleInSlice Particle::createParticleInSlice(const ZLimits& limits) const +{ + ASSERT(m_formfactor); + std::unique_ptr<ReParticle> sliced_ff( + m_formfactor->createSlicedFormFactor(limits, m_rotation.get(), m_position)); + if (!sliced_ff) + return {}; + double volume = sliced_ff->volume(); + Material transformed_material(m_rotation ? m_material.rotatedMaterial(m_rotation->rotMatrix()) + : m_material); + sliced_ff->setMaterial(transformed_material); + return {std::move(sliced_ff), {{{volume, transformed_material}}}}; +} diff --git a/Sample/Particle/Crystal.cpp b/Sample/Particle/Crystal.cpp index d77ee179ca0a0a60b0951d9113a333c9b75f42b4..9a0fb105b78fba0138b1b84ca6b9d1c0a55c6059 100644 --- a/Sample/Particle/Crystal.cpp +++ b/Sample/Particle/Crystal.cpp @@ -17,7 +17,6 @@ #include "Sample/Lattice/Lattice3D.h" #include "Sample/Particle/Particle.h" #include "Sample/Particle/ParticleComposition.h" -#include "Resample/Particle/ParticleInSlice.h" #include "Sample/Scattering/Rotations.h" Crystal::Crystal(const IParticle& basis, const Lattice3D& lattice, double position_variance) diff --git a/Sample/Particle/IParticle.cpp b/Sample/Particle/IParticle.cpp index c47742075576e606e4a6d72efe63f5239ce4fc0e..2e1193019840a8924d81d3c4f1069b1d06c0573f 100644 --- a/Sample/Particle/IParticle.cpp +++ b/Sample/Particle/IParticle.cpp @@ -13,7 +13,6 @@ // ************************************************************************************************ #include "Sample/Particle/IParticle.h" -#include "Resample/Particle/ParticleInSlice.h" #include "Sample/Scattering/Rotations.h" IParticle::~IParticle() = default; diff --git a/Sample/Particle/IParticle.h b/Sample/Particle/IParticle.h index b8525dd62b4bc19dd9411c61175a7fa316d2bad8..296530c67b20cc772b8ffac8ee1d5bf3079c1db2 100644 --- a/Sample/Particle/IParticle.h +++ b/Sample/Particle/IParticle.h @@ -21,10 +21,8 @@ #include <memory> #include <vector> -struct ParticleInSlice; class Rotations; class ZLimits; -class IReParticle; class IRotation; //! Abstract base class for Particle, ParticleComposition, ParticleCoreShell, MesoCrystal. @@ -42,9 +40,6 @@ public: //! Creates a form factor for this particle virtual IReParticle* createFormFactor() const; - //! Creates a sliced form factor for this particle - virtual ParticleInSlice createParticleInSlice(const ZLimits& limits) const = 0; - double abundance() const { return m_abundance; } //! Sets particle abundance. diff --git a/Sample/Particle/MesoCrystal.cpp b/Sample/Particle/MesoCrystal.cpp index 4822ab3cf131ee4af82de19f24efb32b51c371f9..cf93321ceebc45bad82e251abd247e78730bb6bc 100644 --- a/Sample/Particle/MesoCrystal.cpp +++ b/Sample/Particle/MesoCrystal.cpp @@ -15,8 +15,6 @@ #include "Sample/Particle/MesoCrystal.h" #include "Base/Util/Assert.h" #include "Sample/Particle/Crystal.h" -#include "Resample/Particle/ReMesocrystal.h" -#include "Resample/Particle/ParticleInSlice.h" #include "Sample/Scattering/IBornFF.h" #include "Sample/Scattering/Rotations.h" @@ -48,38 +46,6 @@ std::vector<const INode*> MesoCrystal::nodeChildren() const << IParticle::nodeChildren() << m_crystal << m_meso_formfactor; } -ParticleInSlice MesoCrystal::createParticleInSlice(const ZLimits& limits) const -{ - ASSERT(m_crystal && m_meso_formfactor); - - double unit_cell_volume = m_crystal->lattice()->unitCellVolume(); - if (unit_cell_volume <= 0) - return {}; - - ParticleInSlice result; - - std::unique_ptr<ReParticle> tem_ff( - m_meso_formfactor->createSlicedFormFactor(limits, m_rotation.get(), m_position)); - - const std::unique_ptr<Crystal> new_crystal( - m_crystal->transformed(m_rotation.get(), m_position)); - const std::unique_ptr<IReParticle> new_basis_ff(new_crystal->basis()->createFormFactor()); - - result.sliced_ff.reset(new ReMesocrystal(*new_crystal->lattice(), *new_basis_ff, *tem_ff, - new_crystal->position_variance())); - - Admixtures& regions = result.admixtures; - ASSERT(regions.empty()); - for (const auto& particle : m_crystal->basis()->decompose()) { - ParticleInSlice pis = particle->createParticleInSlice({}); - regions.insert(regions.end(), pis.admixtures.begin(), pis.admixtures.end()); - } - for (auto& region : regions) - region.fraction *= m_meso_formfactor->volume() / unit_cell_volume; - - return result; -} - const Crystal& MesoCrystal::particleStructure() const { ASSERT(m_crystal); diff --git a/Sample/Particle/MesoCrystal.h b/Sample/Particle/MesoCrystal.h index fbda66d7ce85ad7548939cefa4ab60038880e7bd..da248d6620a26848c090789df7bb14f3e563b6ff 100644 --- a/Sample/Particle/MesoCrystal.h +++ b/Sample/Particle/MesoCrystal.h @@ -34,8 +34,6 @@ public: std::string className() const final { return "MesoCrystal"; } std::vector<const INode*> nodeChildren() const override; - ParticleInSlice createParticleInSlice(const ZLimits& limits) const override; - const IBornFF* outerShape() const { return m_meso_formfactor.get(); } const Crystal& particleStructure() const; diff --git a/Sample/Particle/Particle.cpp b/Sample/Particle/Particle.cpp index 8bd159a3c5cb0d8412887424e6ac86d203c3bc66..eca525d210d0e524254399ae8c42a48cbb599bfa 100644 --- a/Sample/Particle/Particle.cpp +++ b/Sample/Particle/Particle.cpp @@ -15,9 +15,6 @@ #include "Sample/Particle/Particle.h" #include "Base/Util/Assert.h" #include "Base/Vector/RotMatrix.h" -#include "Sample/Material/MaterialFactoryFuncs.h" -#include "Resample/Particle/ParticleInSlice.h" -#include "Resample/Particle/ReParticle.h" #include "Sample/Scattering/Rotations.h" Particle::Particle(Material material, const IBornFF& formfactor) @@ -49,17 +46,3 @@ std::vector<const INode*> Particle::nodeChildren() const { return std::vector<const INode*>() << IParticle::nodeChildren() << m_formfactor; } - -ParticleInSlice Particle::createParticleInSlice(const ZLimits& limits) const -{ - ASSERT(m_formfactor); - std::unique_ptr<ReParticle> sliced_ff( - m_formfactor->createSlicedFormFactor(limits, m_rotation.get(), m_position)); - if (!sliced_ff) - return {}; - double volume = sliced_ff->volume(); - Material transformed_material(m_rotation ? m_material.rotatedMaterial(m_rotation->rotMatrix()) - : m_material); - sliced_ff->setMaterial(transformed_material); - return {std::move(sliced_ff), {{{volume, transformed_material}}}}; -} diff --git a/Sample/Particle/Particle.h b/Sample/Particle/Particle.h index b25718342db84365b5f613e40196c95b9b962b6d..7c8a8af525dcc46259f73eea7594d80eeca370af 100644 --- a/Sample/Particle/Particle.h +++ b/Sample/Particle/Particle.h @@ -32,8 +32,6 @@ public: std::string className() const override { return "Particle"; } std::vector<const INode*> nodeChildren() const override; - ParticleInSlice createParticleInSlice(const ZLimits& limits) const override; - const Material* material() const override { return &m_material; } const IBornFF* formFactor() const { return m_formfactor.get(); } diff --git a/Sample/Particle/ParticleComposition.cpp b/Sample/Particle/ParticleComposition.cpp index 05cb4fc153ea83b5d5250b17c162d33cf395dd3e..0371e326dff4905c724c0370d54cd822a4c4902e 100644 --- a/Sample/Particle/ParticleComposition.cpp +++ b/Sample/Particle/ParticleComposition.cpp @@ -14,8 +14,6 @@ #include "Sample/Particle/ParticleComposition.h" #include "Base/Util/Assert.h" -#include "Resample/Particle/ReCompound.h" -#include "Resample/Particle/ParticleInSlice.h" #include "Sample/Scattering/Rotations.h" ParticleComposition::ParticleComposition() {} @@ -85,12 +83,6 @@ IReParticle* ParticleComposition::createFormFactor() const return result; } -ParticleInSlice ParticleComposition::createParticleInSlice(const ZLimits&) const -{ - throw std::runtime_error("ParticleComposition does not yet support slicing"); -} - - void ParticleComposition::addParticle(const IParticle& particle) { m_particles.emplace_back(particle.clone()); diff --git a/Sample/Particle/ParticleComposition.h b/Sample/Particle/ParticleComposition.h index d53e0211e684ce6e97209feb8af310adbae275e1..df63d46e3423d0a9555f7f26544e815f832d3b7b 100644 --- a/Sample/Particle/ParticleComposition.h +++ b/Sample/Particle/ParticleComposition.h @@ -37,8 +37,6 @@ public: IReParticle* createFormFactor() const override; - ParticleInSlice createParticleInSlice(const ZLimits& limits) const override; - void addParticle(const IParticle& particle); void addParticle(const IParticle& particle, R3 position); void addParticles(const IParticle& particle, std::vector<R3> positions); diff --git a/Sample/Particle/ParticleCoreShell.cpp b/Sample/Particle/ParticleCoreShell.cpp index ac8a2fcb995e50a2bc7f954d91c98304fd5360c6..9cf3d5d58e8f3036e5a67c0d3336375f0d6cf4c4 100644 --- a/Sample/Particle/ParticleCoreShell.cpp +++ b/Sample/Particle/ParticleCoreShell.cpp @@ -15,9 +15,7 @@ #include "Sample/Particle/ParticleCoreShell.h" #include "Base/Util/Assert.h" -#include "Resample/Particle/ReCoreShell.h" #include "Sample/Particle/Particle.h" -#include "Resample/Particle/ParticleInSlice.h" #include "Sample/Scattering/Rotations.h" #include <memory> @@ -45,47 +43,3 @@ std::vector<const INode*> ParticleCoreShell::nodeChildren() const { return std::vector<const INode*>() << IParticle::nodeChildren() << m_core << m_shell; } - -ParticleInSlice ParticleCoreShell::createParticleInSlice(const ZLimits& limits) const -{ - ASSERT(m_core && m_shell); - - // core - std::unique_ptr<Particle> P_core(m_core->clone()); - if (m_rotation) - P_core->rotate(*m_rotation); - P_core->translate(m_position); - auto sliced_core = P_core->createParticleInSlice(limits); - - // shell - std::unique_ptr<Particle> P_shell(m_shell->clone()); - if (m_rotation) - P_shell->rotate(*m_rotation); - P_shell->translate(m_position); - auto sliced_shell = P_shell->createParticleInSlice(limits); - if (!sliced_shell.sliced_ff) - return {}; - - ParticleInSlice result; - // if core out of limits, return sliced shell - if (!sliced_core.sliced_ff) { - result.sliced_ff = std::move(sliced_shell.sliced_ff); - result.admixtures.push_back(sliced_shell.admixtures.back()); - return result; - } - - // set core ambient material - if (sliced_shell.admixtures.size() != 1) - return {}; - auto shell_material = sliced_shell.admixtures[0].material; - sliced_core.sliced_ff->setAmbientMaterial(shell_material); - - // construct sliced particle - sliced_shell.admixtures.back().fraction -= sliced_core.admixtures.back().fraction; - result.sliced_ff = std::make_unique<ReCoreShell>(sliced_core.sliced_ff.release(), - sliced_shell.sliced_ff.release()); - result.admixtures.push_back(sliced_core.admixtures.back()); - result.admixtures.push_back(sliced_shell.admixtures.back()); - - return result; -} diff --git a/Sample/Particle/ParticleCoreShell.h b/Sample/Particle/ParticleCoreShell.h index 1b6ab462d7126a950c1a6d7aa8c19b17caa08499..6f24dbc90dc45dc6f1e9f7429f259cd682352d2b 100644 --- a/Sample/Particle/ParticleCoreShell.h +++ b/Sample/Particle/ParticleCoreShell.h @@ -32,8 +32,6 @@ public: std::string className() const final { return "ParticleCoreShell"; } std::vector<const INode*> nodeChildren() const override; - ParticleInSlice createParticleInSlice(const ZLimits& limits) const override; - const Particle* shellParticle() const { return m_shell.get(); } const Particle* coreParticle() const { return m_core.get(); } diff --git a/Sample/Scattering/IBornFF.cpp b/Sample/Scattering/IBornFF.cpp index 47f0e3c79f04758525277fb77c3e4fcc746d5b98..629d033cd2cf9348b262848f8d3aaacee6815f14 100644 --- a/Sample/Scattering/IBornFF.cpp +++ b/Sample/Scattering/IBornFF.cpp @@ -20,7 +20,6 @@ #include "Base/Vector/WavevectorInfo.h" #include "Sample/Scattering/Rotations.h" #include "Sample/Shapes/IShape3D.h" -#include "Resample/Processed/Slicer.h" #include <stdexcept> #include <utility>