BornAgain  1.18.0
Simulate and fit neutron and x-ray scattering at grazing incidence
ParticleLayout.cpp
Go to the documentation of this file.
1 // ************************************************************************** //
2 //
3 // BornAgain: simulate and fit scattering at grazing incidence
4 //
5 //! @file Sample/Aggregate/ParticleLayout.cpp
6 //! @brief Implements class ParticleLayout.
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2018
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************** //
14 
16 #include "Base/Types/Exceptions.h"
22 
23 namespace
24 {
25 
26 //! Returns true if interference function is able to calculate particle density automatically,
27 //! which is the case for 2D functions.
29 {
30  return iff.getName() == "Interference2DLattice" || iff.getName() == "Interference2DParaCrystal"
31  || iff.getName() == "Interference2DSuperLattice"
32  || iff.getName() == "InterferenceFinite2DLattice"
33  || iff.getName() == "InterferenceHardDisk";
34 }
35 } // namespace
36 
37 ParticleLayout::ParticleLayout() : mP_interference_function{nullptr}, m_total_particle_density{0.01}
38 {
39  setName("ParticleLayout");
42 }
43 
44 ParticleLayout::ParticleLayout(const IAbstractParticle& particle, double abundance)
45  : mP_interference_function{nullptr}, m_total_particle_density{0.01}
46 {
47  setName("ParticleLayout");
48  addParticle(particle, abundance);
51 }
52 
53 ParticleLayout::~ParticleLayout() = default; // needs member class definitions => don't move to .h
54 
56 {
57  ParticleLayout* p_result = new ParticleLayout();
58 
59  for (auto p_particle : m_particles)
60  p_result->addAndRegisterAbstractParticle(p_particle->clone());
61 
64 
66  p_result->setWeight(weight());
67 
68  return p_result;
69 }
70 
71 //! Adds particle to the layout with abundance, position and the rotation defined.
72 //! @param particle to be added
73 //! @param abundance Particle abundance
74 //! @param position Particle position
75 //! @param rotation Particle rotation
76 void ParticleLayout::addParticle(const IAbstractParticle& particle, double abundance,
77  const kvector_t position, const IRotation& rotation)
78 {
79  IAbstractParticle* particle_clone = particle.clone();
80  if (abundance >= 0.0)
81  particle_clone->setAbundance(abundance);
82  if (!rotation.isIdentity())
83  particle_clone->rotate(rotation);
84  if (position != kvector_t(0, 0, 0))
85  particle_clone->translate(position);
86  addAndRegisterAbstractParticle(particle_clone);
87 }
88 
89 //! Returns information on all particles (type and abundance)
90 //! and generates new particles if an IAbstractParticle denotes a collection
92 {
93  SafePointerVector<IParticle> particle_vector;
94  for (auto particle : m_particles) {
95  if (const auto* p_part_distr = dynamic_cast<const ParticleDistribution*>(particle)) {
96  SafePointerVector<IParticle> generated_particles = p_part_distr->generateParticles();
97  for (const IParticle* particle : generated_particles)
98  particle_vector.push_back(particle->clone());
99  } else if (const auto* p_iparticle = dynamic_cast<const IParticle*>(particle)) {
100  particle_vector.push_back(p_iparticle->clone());
101  }
102  }
103  return particle_vector;
104 }
105 
107 {
108  return mP_interference_function.get();
109 }
110 
112 {
113  double result = 0.0;
114  for (auto p_particle : m_particles) {
115  result += p_particle->abundance();
116  }
117  return result;
118 }
119 
120 //! Adds interference functions
122 {
123  setAndRegisterInterferenceFunction(interference_function.clone());
124 }
125 
127 {
128  double iff_density =
129  mP_interference_function ? mP_interference_function->getParticleDensity() : 0.0;
130  return iff_density > 0.0 ? iff_density : m_total_particle_density;
131 }
132 
133 //! Sets total particle surface density.
134 //! @param particle_density: number of particles per square nanometer
136 {
137  m_total_particle_density = particle_density;
138 }
139 
140 std::vector<const INode*> ParticleLayout::getChildren() const
141 {
142  std::vector<const INode*> result;
143  for (auto particle : m_particles)
144  result.push_back(particle);
145  result << mP_interference_function;
146  return result;
147 }
148 
149 //! Adds particle information with simultaneous registration in parent class.
151 {
152  m_particles.push_back(child);
153  registerChild(child);
154 }
155 
156 //! Sets interference function with simultaneous registration in parent class
158 {
159  mP_interference_function.reset(child);
160  registerChild(child);
161 
164  else
166 }
167 
168 void ParticleLayout::registerParticleDensity(bool make_registered)
169 {
170  if (make_registered) {
171  if (!parameter("TotalParticleDensity"))
172  registerParameter("TotalParticleDensity", &m_total_particle_density);
173  } else {
174  removeParameter("TotalParticleDensity");
175  }
176 }
177 
179 {
180  registerParameter("Weight", &m_weight);
181 }
Defines many exception classes in namespace Exceptionss.
Defines class InterferenceFunctionNone.
Defines class ParameterPool.
Defines class ParticleDistribution.
Defines class ParticleLayout.
Defines class Particle.
Defines class RealParameter.
BasicVector3D< double > kvector_t
Definition: Vectors3D.h:21
Interface for a generic particle.
void setAbundance(double abundance)
Sets particle abundance.
virtual IAbstractParticle * clone() const =0
Returns a clone of this ISample object.
virtual void translate(kvector_t translation)=0
Translates the particle with the given vector.
virtual void rotate(const IRotation &rotation)=0
Applies the given rotation to the particle.
Pure virtual base class of interference functions.
virtual IInterferenceFunction * clone() const =0
Returns a clone of this ISample object.
void setWeight(double weight)
Sets the relative weight of this layout.
Definition: ILayout.h:60
double m_weight
Definition: ILayout.h:63
double weight() const
Returns the relative weight of this layout.
Definition: ILayout.h:57
void registerChild(INode *node)
Definition: INode.cpp:58
RealParameter & registerParameter(const std::string &name, double *parpointer)
RealParameter * parameter(const std::string &name) const
Returns parameter with given 'name'.
void removeParameter(const std::string &name)
const std::string & getName() const
void setName(const std::string &name)
Pure virtual base class for Particle, ParticleComposition, ParticleCoreShell, MesoCrystal.
Definition: IParticle.h:33
Pure virtual interface for rotations.
Definition: Rotations.h:27
virtual bool isIdentity() const
Returns true if rotation matrix is identity matrix (no rotations)
Definition: Rotations.cpp:63
A particle type that is a parametric distribution of IParticle's.
Decorator class that adds particles to ISample objects.
SafePointerVector< IAbstractParticle > m_particles
Vector of particle types.
std::unique_ptr< IInterferenceFunction > mP_interference_function
void registerParticleDensity(bool make_registered=true)
double getTotalAbundance() const final override
Get total abundance of all particles.
SafePointerVector< IParticle > particles() const final override
Returns information on all particles (type and abundance) and generates new particles if an IAbstract...
~ParticleLayout() override
std::vector< const INode * > getChildren() const final override
Returns a vector of children (const).
void setInterferenceFunction(const IInterferenceFunction &interference_function)
Adds interference functions.
double totalParticleSurfaceDensity() const final override
Returns surface density of all particles.
void setTotalParticleSurfaceDensity(double particle_density) final override
Sets total particle surface density.
const IInterferenceFunction * interferenceFunction() const final override
Returns the interference function.
void setAndRegisterInterferenceFunction(IInterferenceFunction *child)
Sets interference function with simultaneous registration in parent class.
double m_total_particle_density
void addAndRegisterAbstractParticle(IAbstractParticle *child)
Adds particle information with simultaneous registration in parent class.
void addParticle(const IAbstractParticle &particle, double abundance=-1.0, const kvector_t position={}, const IRotation &rotation=IdentityRotation())
Adds particle to the layout with abundance, position and the rotation defined.
ParticleLayout * clone() const final override
Returns a clone of this ISample object.
A vector of pointers, owned by *this, with methods to handle them safely.
void push_back(T *pointer)
bool particleDensityIsProvidedByInterference(const IInterferenceFunction &iff)
Returns true if interference function is able to calculate particle density automatically,...