BornAgain  1.19.79
Open-source research software to simulate and fit neutron and x-ray reflectometry and grazing-incidence small-angle scattering
ReParticle.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Resample/Particle/ReParticle.cpp
6 //! @brief Implements interface class ReParticle.
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/Vector/RotMatrix.h"
17 #include "Base/Vector/WavevectorInfo.h" // debug
22 
23 ReParticle::ReParticle(IFormFactor* ff, const Material* material, const Material* ambient_material,
24  const R3* position, const RotMatrix* rotMatrix)
25  : m_ff(std::move(ff))
26  , m_material(std::move(material))
27  , m_ambient_material(std::move(ambient_material))
28  , m_position(std::move(position))
29  , m_rotMatrix(std::move(rotMatrix))
30 {
31 }
32 
34  : ReParticle(ff.clone(), nullptr, nullptr, nullptr, nullptr)
35 {
36 }
37 
38 ReParticle::~ReParticle() = default;
39 
41 {
42  return new ReParticle(m_ff->clone(), m_material ? new Material(*m_material) : nullptr,
44  m_position ? new R3(*m_position) : nullptr,
45  m_rotMatrix ? new RotMatrix(*m_rotMatrix) : nullptr);
46 }
47 
48 
50  const IRotation* rot, R3 translation)
51 {
52  auto* result = new ReParticle(formfactor);
53  if (rot && !rot->isIdentity())
54  result->setRotMatrix(rot->rotMatrix());
55  if (translation != R3())
56  result->setPosition(translation);
57  return result;
58 }
59 
60 void ReParticle::setMaterial(const Material& material)
61 {
62  m_material = std::make_unique<Material>(material);
63 }
64 
65 void ReParticle::setAmbientMaterial(const Material& ambient_material)
66 {
67  m_ambient_material = std::make_unique<Material>(ambient_material);
68 }
69 
70 void ReParticle::setPosition(const R3& position)
71 {
72  m_position = std::make_unique<R3>(position);
73 }
74 
75 void ReParticle::setRotMatrix(const RotMatrix& rotMatrix)
76 {
77  m_rotMatrix = std::make_unique<RotMatrix>(rotMatrix);
78 }
79 
80 double ReParticle::volume() const
81 {
82  return m_ff->volume();
83 }
84 
86 {
87  return m_ff->radialExtension();
88 }
89 
91 {
92  return m_ff.get();
93 }
94 
95 complex_t ReParticle::formfactor_at_bottom(C3 q) const
96 {
97  return m_ff->formfactor_at_bottom(q);
98 }
99 
100 complex_t ReParticle::theFF(const WavevectorInfo& wavevectors) const
101 {
102  WavevectorInfo wavevectors2 =
103  m_rotMatrix ? wavevectors.transformed(m_rotMatrix->Inverse()) : wavevectors;
104  complex_t result = m_ff->theFF(wavevectors2);
106  result = (m_material->scalarSubtrSLD(wavevectors2)
107  - m_ambient_material->scalarSubtrSLD(wavevectors2))
108  * result;
109  if (m_position)
110  result *= exp_I(m_position->dot(wavevectors.getQ()));
111  return result;
112 }
113 
115 {
116  WavevectorInfo wavevectors2 =
117  m_rotMatrix ? wavevectors.transformed(m_rotMatrix->Inverse()) : wavevectors;
118  SpinMatrix result = m_ff->thePolFF(wavevectors2);
120  // the conjugated linear part of time reversal operator T
121  // (T=UK with K complex conjugate operator and U is linear)
122  SpinMatrix time_reverse_conj(0, 1, -1, 0);
123  // the interaction and time reversal taken together:
124  SpinMatrix V_eff = time_reverse_conj
125  * (m_material->polarizedSubtrSLD(wavevectors2)
126  - m_ambient_material->polarizedSubtrSLD(wavevectors2));
127  result *= V_eff;
128  }
129  if (m_position)
130  return result *= exp_I(m_position->dot(wavevectors.getQ()));
131  return result;
132 }
133 
134 double ReParticle::bottomZ(const IRotation* rotation) const
135 {
136  RotMatrix transform = rotation ? rotation->rotMatrix() : RotMatrix();
137  if (m_rotMatrix)
138  transform = transform * *m_rotMatrix;
139  std::unique_ptr<const IRotation> total_rotation(IRotation::createRotation(transform));
140  double result = m_ff->bottomZ(total_rotation.get());
141  if (m_position)
142  result += (rotation ? rotation->transformed(*m_position) : *m_position).z();
143  return result;
144 }
145 
146 double ReParticle::topZ(const IRotation* rotation) const
147 {
148  RotMatrix transform = rotation ? rotation->rotMatrix() : RotMatrix();
149  if (m_rotMatrix)
150  transform = transform * *m_rotMatrix;
151  std::unique_ptr<const IRotation> total_rotation(IRotation::createRotation(transform));
152  double result = m_ff->topZ(total_rotation.get());
153  if (m_position)
154  result += (rotation ? rotation->transformed(*m_position) : *m_position).z();
155  return result;
156 }
Defines interface IDecoratableBorn.
Factory functions used to create material instances.
Defines and implements class Material.
Defines interface class ReParticle.
Declares class RotMatrix.
Defines IRotation classes.
Defines WavevectorInfo.
Abstract base class for Born form factors.
Definition: IFormFactor.h:36
Abstract base class for rotations.
Definition: Rotations.h:29
virtual RotMatrix rotMatrix() const =0
Returns transformation.
R3 transformed(const R3 &v) const
Definition: Rotations.cpp:42
virtual bool isIdentity() const
Returns true if rotation matrix is identity matrix (no rotations)
Definition: Rotations.cpp:47
static IRotation * createRotation(const RotMatrix &transform)
Definition: Rotations.cpp:28
A wrapper for underlying material implementation.
Definition: Material.h:35
A reprocessed simple particle, with shape m_ff.
Definition: ReParticle.h:33
std::unique_ptr< const RotMatrix > m_rotMatrix
Definition: ReParticle.h:77
double radialExtension() const override
Returns the (approximate in some cases) radial size of the particle of this form factor's shape....
Definition: ReParticle.cpp:85
double topZ(const IRotation *rotation) const override
Returns the z-coordinate of the lowest point in this shape after a given rotation.
Definition: ReParticle.cpp:146
void setMaterial(const Material &material)
Sets the material of the scatterer.
Definition: ReParticle.cpp:60
const IFormFactor * formfactor_at_bottom() const
Definition: ReParticle.cpp:90
~ReParticle() override
ReParticle(const IFormFactor &ff)
Definition: ReParticle.cpp:33
std::unique_ptr< const Material > m_material
Definition: ReParticle.h:74
void setAmbientMaterial(const Material &ambient_material) override
Sets the ambient material.
Definition: ReParticle.cpp:65
SpinMatrix thePolFF(const WavevectorInfo &wavevectors) const override
Returns scattering amplitude for matrix interactions.
Definition: ReParticle.cpp:114
double bottomZ(const IRotation *rotation) const override
Returns the z-coordinate of the lowest point in this shape after a given rotation.
Definition: ReParticle.cpp:134
ReParticle * clone() const override
Definition: ReParticle.cpp:40
void setRotMatrix(const RotMatrix &rotMatrix)
Definition: ReParticle.cpp:75
std::unique_ptr< const IFormFactor > m_ff
Definition: ReParticle.h:68
std::unique_ptr< const Material > m_ambient_material
Definition: ReParticle.h:75
void setPosition(const R3 &position)
Definition: ReParticle.cpp:70
static ReParticle * createTransformedFormFactor(const IFormFactor &formfactor, const IRotation *rot, R3 translation)
Definition: ReParticle.cpp:49
double volume() const override
Returns the total volume of the particle of this form factor's shape.
Definition: ReParticle.cpp:80
std::unique_ptr< const R3 > m_position
Definition: ReParticle.h:76
complex_t theFF(const WavevectorInfo &wavevectors) const override
Returns scattering amplitude for complex wavevectors ki, kf.
Definition: ReParticle.cpp:100
Rotation matrix in three dimensions. Represents group SO(3). Internal parameterization based on quate...
Definition: RotMatrix.h:25
Holds all wavevector information relevant for calculating form factors.
WavevectorInfo transformed(const RotMatrix &transform) const
C3 getQ() const