BornAgain  1.19.79
Open-source research software to simulate and fit neutron and x-ray reflectometry and grazing-incidence small-angle scattering
Beam.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Device/Beam/Beam.cpp
6 //! @brief Implements class Beam.
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 
15 #include "Device/Beam/Beam.h"
16 #include "Base/Math/Constants.h"
17 #include "Base/Spin/SpinMatrix.h"
18 #include "Base/Util/Assert.h"
20 #include <heinz/Complex.h>
21 
22 namespace {
23 
24 // Allow for 90 degrees by adding a relatively small constant to pi/2
25 constexpr double INCLINATION_LIMIT = M_PI_2 + 1e-10;
26 
27 const auto wavelengthLimits = RealLimits::nonnegative();
28 const auto phiLimits = RealLimits::limited(-M_PI_2, M_PI_2);
29 
30 } // namespace
31 
32 
33 Beam::Beam(double intensity, double wavelength, const Direction& direction)
34  : m_intensity(intensity)
35  , m_wavelength(wavelength)
36  // , m_direction(direction)
37  , m_alpha(direction.alpha())
38  , m_phi(direction.phi())
39  , m_alphaLimits(RealLimits::limited(-INCLINATION_LIMIT, INCLINATION_LIMIT))
40 {
42 
43  wavelengthLimits.check("Wavelength", m_wavelength);
44  m_alphaLimits.check("InclinationAngle", m_alpha);
45  phiLimits.check("AzimuthalAngle", m_phi);
46 }
47 
49 {
50  return Beam(1.0, 1.0, {0, 0});
51 }
52 
53 Beam::Beam(const Beam& other)
54  : Beam(other.m_intensity, other.m_wavelength, other.direction())
55 {
57  if (other.m_shape_factor)
58  m_shape_factor.reset(other.m_shape_factor->clone());
59 }
60 
61 Beam& Beam::operator=(const Beam& other)
62 {
63  if (&other == this)
64  return *this;
65  m_intensity = other.m_intensity;
66  m_wavelength = other.m_wavelength;
67  // m_direction = other.m_direction;
68  m_alpha = other.m_alpha;
69  m_phi = other.m_phi;
71  if (other.m_shape_factor)
72  m_shape_factor.reset(other.m_shape_factor->clone());
73  else
74  m_shape_factor.release();
75  return *this;
76 }
77 
78 Beam::~Beam() = default;
79 
80 Beam* Beam::clone() const
81 {
82  return new Beam(*this);
83 }
84 
85 void Beam::setWavelength(double wavelength)
86 {
87  if (wavelength <= 0.0)
88  throw std::runtime_error("Invalid beam parameter: Wavelength can't be negative or zero.");
90 }
91 
92 void Beam::setDirection(const Direction& direction)
93 {
94  if (direction.alpha() < 0.0)
95  throw std::runtime_error(
96  "Invalid beam parameter: Inclination angle alpha_i can't be negative.");
97  // m_direction = direction;
99  m_phi = direction.phi();
100 }
101 
102 void Beam::setInclination(const double alpha)
103 {
104  m_alpha = alpha;
105 }
106 
108 {
109  m_alphaLimits = limits;
110 }
111 
113 {
114  return m_shape_factor.get();
115 }
116 
118 {
119  m_alphaLimits.check("inclination angle", value);
120  m_alpha = value;
121 }
122 
124 {
125  phiLimits.check("azimuthal angle", value);
126  m_phi = value;
127 }
128 
129 void Beam::setWavelengthGuarded(double value)
130 {
131  wavelengthLimits.check("wavelength", value);
132  m_wavelength = value;
133 }
134 
136 {
137  m_shape_factor.reset(shape_factor.clone());
138 }
139 
140 void Beam::setPolarization(const R3 bloch_vector)
141 {
142  if (bloch_vector.mag() > 1.0) {
143  throw std::runtime_error(
144  "Beam::setPolarization: "
145  "The given Bloch vector cannot represent a real physical ensemble");
146  }
147  m_beamPolarization = bloch_vector;
148 }
149 
150 R3 Beam::polVector() const
151 {
152  return m_beamPolarization;
153 }
154 
156 {
158 }
159 
160 std::vector<const INode*> Beam::nodeChildren() const
161 {
162  if (m_shape_factor)
163  return {m_shape_factor.get()};
164  return {};
165 }
Defines the macro ASSERT.
Defines class Beam.
Defines M_PI and some more mathematical constants.
#define M_PI_2
Definition: Constants.h:45
Defines class FootprintGauss.
Defines class SpinMatrix.
An incident neutron or x-ray beam.
Definition: Beam.h:28
double m_alpha
Definition: Beam.h:85
RealLimits m_alphaLimits
Definition: Beam.h:90
Direction direction() const
Definition: Beam.h:46
static Beam horizontalBeam()
Definition: Beam.cpp:48
void setAzimuthalAngleGuarded(double value)
Check for limits, set the value if within limits. Throws if limits are violated.
Definition: Beam.cpp:123
void setPolarization(R3 bloch_vector)
Sets the polarization density matrix according to the given Bloch vector.
Definition: Beam.cpp:140
R3 m_beamPolarization
Bloch vector encoding the beam's polarization.
Definition: Beam.h:88
void setDirection(const Direction &direction)
Definition: Beam.cpp:92
~Beam() override
double m_wavelength
Definition: Beam.h:83
void setInclinationAngleGuarded(double value)
Check for limits, set the value if within limits. Throws if limits are violated.
Definition: Beam.cpp:117
double m_phi
Definition: Beam.h:86
double wavelength() const
Definition: Beam.h:44
void setInclination(double alpha)
Definition: Beam.cpp:102
Beam & operator=(const Beam &other)
Definition: Beam.cpp:61
const IFootprintFactor * footprintFactor() const
Returns footprint factor.
Definition: Beam.cpp:112
void setWavelengthGuarded(double value)
Check for limits, set the value if within limits. Throws if limits are violated.
Definition: Beam.cpp:129
void setFootprintFactor(const IFootprintFactor &shape_factor)
Sets footprint factor to the beam.
Definition: Beam.cpp:135
std::unique_ptr< IFootprintFactor > m_shape_factor
footprint correction handler
Definition: Beam.h:87
void setInclinationLimits(const RealLimits &limits)
Definition: Beam.cpp:107
Beam * clone() const
Definition: Beam.cpp:80
void setWavelength(double wavelength)
Definition: Beam.cpp:85
SpinMatrix polMatrix() const
Returns the polarization density matrix (in spin basis along z-axis)
Definition: Beam.cpp:155
double m_intensity
beam intensity (neutrons/sec)
Definition: Beam.h:82
std::vector< const INode * > nodeChildren() const override
Returns all children.
Definition: Beam.cpp:160
R3 polVector() const
Returns polarization density as Bloch vector.
Definition: Beam.cpp:150
A direction in three-dimensional space.
Definition: Direction.h:24
double phi() const
Definition: Direction.h:37
double alpha() const
Definition: Direction.h:36
Abstract base for classes that calculate the beam footprint factor.
IFootprintFactor * clone() const override=0
Limits for a real fit parameter.
Definition: RealLimits.h:24
void check(const std::string &name, double value) const
Throws if value is outside limits. Parameter 'name' is for exception message.
Definition: RealLimits.cpp:170
static RealLimits nonnegative()
Creates an object which can have only positive values with 0. included.
Definition: RealLimits.cpp:124
static RealLimits limited(double left_bound_value, double right_bound_value)
Creates an object bounded from the left and right.
Definition: RealLimits.cpp:134
static SpinMatrix FromBlochVector(const R3 &v)
Constructs matrix (I+v*s)/2, where s is the Pauli vector.
Definition: SpinMatrix.cpp:41