BornAgain  1.19.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 reflection and scattering
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 
21 
22 namespace {
23 
24 //! Returns true if interference function is able to calculate particle density automatically,
25 //! which is the case for 2D functions.
26 bool particleDensityIsProvidedByInterference(const IInterferenceFunction& iff)
27 {
28  return iff.getName() == "Interference2DLattice" || iff.getName() == "Interference2DParaCrystal"
29  || iff.getName() == "Interference2DSuperLattice"
30  || iff.getName() == "InterferenceFinite2DLattice"
31  || iff.getName() == "InterferenceHardDisk";
32 }
33 } // namespace
34 
36  : m_weight(1.0), m_total_particle_density(0.01), m_interference_function(nullptr)
37 {
38  setName("ParticleLayout");
41 }
42 
43 ParticleLayout::ParticleLayout(const IAbstractParticle& particle, double abundance)
44  : m_weight(1.0), m_total_particle_density(0.01), m_interference_function(nullptr)
45 {
46  setName("ParticleLayout");
47  addParticle(particle, abundance);
50 }
51 
52 ParticleLayout::~ParticleLayout() = default; // needs member class definitions => don't move to .h
53 
55 {
56  ParticleLayout* result = new ParticleLayout();
57 
58  for (const auto* particle : m_particles)
59  result->addAndRegisterAbstractParticle(particle->clone());
60 
63 
65  result->setWeight(weight());
66 
67  return result;
68 }
69 
70 //! Adds particle to the layout with abundance, position and the rotation defined.
71 //! @param particle to be added
72 //! @param abundance Particle abundance
73 //! @param position Particle position
74 //! @param rotation Particle rotation
75 void ParticleLayout::addParticle(const IAbstractParticle& particle, double abundance,
76  const kvector_t position, const IRotation& rotation)
77 {
78  IAbstractParticle* particle_clone = particle.clone();
79  if (abundance >= 0.0)
80  particle_clone->setAbundance(abundance);
81  if (!rotation.isIdentity())
82  particle_clone->rotate(rotation);
83  if (position != kvector_t(0, 0, 0))
84  particle_clone->translate(position);
85  addAndRegisterAbstractParticle(particle_clone);
86 }
87 
88 //! Returns information on all particles (type and abundance)
89 //! and generates new particles if an IAbstractParticle denotes a collection
91 {
92  SafePointerVector<IParticle> particle_vector;
93  for (const auto* particle : m_particles) {
94  if (const auto* p_part_distr = dynamic_cast<const ParticleDistribution*>(particle)) {
95  SafePointerVector<IParticle> generated_particles = p_part_distr->generateParticles();
96  for (const IParticle* particle : generated_particles)
97  particle_vector.push_back(particle->clone());
98  } else if (const auto* p_iparticle = dynamic_cast<const IParticle*>(particle)) {
99  particle_vector.push_back(p_iparticle->clone());
100  }
101  }
102  return particle_vector;
103 }
104 
106 {
107  return m_interference_function.get();
108 }
109 
111 {
112  double result = 0.0;
113  for (const auto* particle : m_particles)
114  result += particle->abundance();
115  return result;
116 }
117 
118 //! Adds interference functions
120 {
121  setAndRegisterInterferenceFunction(interference_function.clone());
122 }
123 
125 {
126  double iff_density =
127  m_interference_function ? m_interference_function->getParticleDensity() : 0.0;
128  return iff_density > 0.0 ? iff_density : m_total_particle_density;
129 }
130 
131 //! Sets total particle surface density.
132 //! @param particle_density: number of particles per square nanometer
134 {
135  m_total_particle_density = particle_density;
136 }
137 
138 std::vector<const INode*> ParticleLayout::getChildren() const
139 {
140  std::vector<const INode*> result;
141  for (const auto* particle : m_particles)
142  result.push_back(particle);
143  result << m_interference_function;
144  return result;
145 }
146 
147 //! Adds particle information with simultaneous registration in parent class.
149 {
150  m_particles.push_back(child);
151  registerChild(child);
152 }
153 
154 //! Sets interference function with simultaneous registration in parent class
156 {
157  m_interference_function.reset(child);
158  registerChild(child);
159 
160  if (particleDensityIsProvidedByInterference(*m_interference_function))
162  else
164 }
165 
166 void ParticleLayout::registerParticleDensity(bool make_registered)
167 {
168  if (make_registered) {
169  if (!parameter("TotalParticleDensity"))
170  registerParameter("TotalParticleDensity", &m_total_particle_density);
171  } else {
172  removeParameter("TotalParticleDensity");
173  }
174 }
175 
177 {
178  registerParameter("Weight", &m_weight);
179 }
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 ISampleNode 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.
Abstract base class of interference functions.
virtual IInterferenceFunction * clone() const =0
Returns a clone of this ISampleNode object.
void registerChild(INode *node)
Definition: INode.cpp:57
const std::string & getName() const
void removeParameter(const std::string &name)
RealParameter * parameter(const std::string &name) const
Returns parameter with given 'name'.
void setName(const std::string &name)
RealParameter & registerParameter(const std::string &name, double *parpointer)
Abstract base class for Particle, ParticleComposition, ParticleCoreShell, MesoCrystal.
Definition: IParticle.h:33
Abstract base class for rotations.
Definition: Rotations.h:28
virtual bool isIdentity() const
Returns true if rotation matrix is identity matrix (no rotations)
Definition: Rotations.cpp:58
A particle type that is a parametric distribution of IParticle's.
Decorator class that adds particles to ISampleNode objects.
double weight() const
Returns the relative weight of this layout.
SafePointerVector< IAbstractParticle > m_particles
Vector of particle types.
std::unique_ptr< IInterferenceFunction > m_interference_function
void registerParticleDensity(bool make_registered=true)
void setTotalParticleSurfaceDensity(double particle_density)
Sets total particle surface density.
double getTotalAbundance() const
ParticleLayout * clone() const override
Returns a clone of this ISampleNode object.
~ParticleLayout() override
void setInterferenceFunction(const IInterferenceFunction &interference_function)
Adds interference functions.
const IInterferenceFunction * interferenceFunction() const
SafePointerVector< IParticle > particles() const
Returns information on all particles (type and abundance) and generates new particles if an IAbstract...
std::vector< const INode * > getChildren() const override
Returns a vector of children.
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 setWeight(double weight)
Sets the relative weight of this layout.
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.
double totalParticleSurfaceDensity() const
A vector of pointers, owned by *this, with methods to handle them safely.
void push_back(T *pointer)