1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
|
// ************************************************************************************************
//
// BornAgain: simulate and fit reflection and scattering
//
//! @file Sample/Particle/Compound.cpp
//! @brief Implements class Compound.
//!
//! @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 "Sample/Particle/Compound.h"
#include "Base/Type/Span.h"
#include "Base/Util/Assert.h"
#include "Sample/Scattering/Rotations.h"
Compound::Compound() = default;
Compound::~Compound() = default;
Compound* Compound::clone() const
{
auto* result = new Compound;
result->setAbundance(m_abundance);
for (auto* m_particle : m_particles)
result->addComponent(*m_particle);
if (rotation())
result->rotate(*rotation());
result->translate(particlePosition());
return result;
}
std::vector<const INode*> Compound::nodeChildren() const
{
std::vector<const INode*> result = IParticle::nodeChildren();
for (const IParticle* p : m_particles)
result.push_back(p);
return result;
}
OwningVector<IParticle> Compound::decompose() const
{
OwningVector<IParticle> result;
const auto* rot = rotation();
const auto& translation = particlePosition();
for (const auto& particle : m_particles) {
const auto sublist = particle->decompose();
for (const auto& subparticle : sublist) {
IParticle* new_subparticle = subparticle->clone();
if (rot)
new_subparticle->rotate(*rot);
new_subparticle->translate(translation);
result.push_back(new_subparticle);
}
}
return result;
}
void Compound::addComponent(const IParticle& particle)
{
m_particles.push_back(particle.clone());
}
void Compound::addComponent(const IParticle& particle, const R3& position)
{
m_particles.push_back(particle.clone()->translate(position));
}
// Please note, that positions is not const reference here. This is intentional, to
// enable python lists to std::vector conversion
void Compound::addComponents(const IParticle& particle, std::vector<R3> positions)
{
for (const auto& position : positions)
addComponent(particle, position);
}
std::vector<const IParticle*> Compound::particles() const
{
std::vector<const IParticle*> result;
for (const IParticle* p : m_particles)
result.push_back(p);
return result;
}
Span Compound::zSpan() const
{
Span result = m_particles[0]->zSpan();
for (size_t i = 1; i < m_particles.size(); ++i)
result = Span::unite(result, m_particles[i]->zSpan());
return result + particlePosition().z();
}
|