BornAgain  1.18.0
Simulate and fit neutron and x-ray scattering at grazing incidence
FeNiBilayerBuilder.cpp
Go to the documentation of this file.
1 // ************************************************************************** //
2 //
3 // BornAgain: simulate and fit scattering at grazing incidence
4 //
5 //! @file Sample/StandardSamples/FeNiBilayerBuilder.cpp
6 //! @brief Defines various sample builder classes to
7 //! test polarized specular computations
8 //!
9 //! @homepage http://www.bornagainproject.org
10 //! @license GNU General Public License v3 or higher (see COPYING)
11 //! @copyright Forschungszentrum Jülich GmbH 2020
12 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
13 //
14 // ************************************************************************** //
15 
18 #include "Base/Const/Units.h"
23 
24 namespace
25 {
28 
29 class Options
30 {
31 public:
32  int _NBilayers = 4;
33  double _angle = 0.;
34  double _magnetizationMagnitude = 1.e7;
35  double _thicknessFe = 100. * Units::angstrom;
36  double _thicknessNi = 40. * Units::angstrom;
37  double _sigmaRoughness = 0.;
38  int _effectiveSLD = 0;
39  RoughnessModel _roughnessModel = RoughnessModel::TANH;
40 
41  Options() {}
43  {
44  _NBilayers = n;
45  return *this;
46  }
47  Options angle(double angle)
48  {
49  _angle = angle;
50  return *this;
51  }
53  {
54  _magnetizationMagnitude = M;
55  return *this;
56  }
57  Options thicknessFe(double t)
58  {
59  _thicknessFe = t;
60  return *this;
61  }
62  Options thicknessNi(double t)
63  {
64  _thicknessNi = t;
65  return *this;
66  }
68  {
69  _sigmaRoughness = r;
70  return *this;
71  }
73  {
74  _effectiveSLD = i;
75  return *this;
76  }
78  {
79  _roughnessModel = rm;
80  return *this;
81  }
82 };
83 //! Creates the sample demonstrating an Fe-Ni Bilayer with and without roughness
84 //! @ingroup standard_samples
86 {
87 public:
88  FeNiBilayer(Options opt = {})
89  : NBilayers(opt._NBilayers), angle(opt._angle),
90  magnetizationMagnitude(opt._magnetizationMagnitude), thicknessFe(opt._thicknessFe),
91  thicknessNi(opt._thicknessNi), sigmaRoughness(opt._sigmaRoughness),
92  effectiveSLD(opt._effectiveSLD), roughnessModel(opt._roughnessModel)
93  {
94  if (angle != 0. && effectiveSLD != 0.)
95  throw std::runtime_error("Cannot perform scalar computation "
96  "for non-colinear magnetization");
97 
98  magnetizationVector = kvector_t(magnetizationMagnitude * std::sin(angle),
99  magnetizationMagnitude * std::cos(angle), 0);
100  sample = constructSample();
101  }
102 
103  MultiLayer* release() { return sample.release(); }
104 
105 private:
106  static constexpr auto sldFe = complex_t{8.02e-06, 0};
107  static constexpr auto sldAu = complex_t{4.6665e-6, 0};
108  static constexpr auto sldNi = complex_t{9.4245e-06, 0};
109 
111  double angle;
113  double thicknessFe;
114  double thicknessNi;
118 
120 
121  std::unique_ptr<MultiLayer> sample;
122 
123  std::unique_ptr<MultiLayer> constructSample();
124 };
125 
126 } // namespace
127 
128 const complex_t FeNiBilayer::sldFe;
129 const complex_t FeNiBilayer::sldAu;
130 const complex_t FeNiBilayer::sldNi;
131 
132 std::unique_ptr<MultiLayer> FeNiBilayer::constructSample()
133 {
134  auto sample = std::make_unique<MultiLayer>();
135 
136  auto m_ambient = MaterialBySLD("Ambient", 0.0, 0.0);
137  auto m_Fe =
138  effectiveSLD == 0
139  ? MaterialBySLD("Fe", sldFe.real(), sldFe.imag(), magnetizationVector)
140  : MaterialBySLD("Fe", sldFe.real() + effectiveSLD * rhoMconst * magnetizationMagnitude,
141  sldFe.imag(), kvector_t{0, 0, 0});
142 
143  auto m_Ni = MaterialBySLD("Ni", sldNi.real(), sldNi.imag());
144  auto m_Substrate = MaterialBySLD("Au", sldAu.real(), sldAu.imag());
145 
146  Layer l_Fe{m_Fe, thicknessFe};
147  Layer l_Ni{m_Ni, thicknessNi};
148 
149  LayerRoughness roughness{sigmaRoughness, 0., 0.};
150  sample->addLayer(Layer{m_ambient});
151 
152  for (auto i = 0; i < NBilayers; ++i) {
153  sample->addLayerWithTopRoughness(l_Fe, roughness);
154  sample->addLayerWithTopRoughness(l_Ni, roughness);
155  }
156 
157  sample->addLayerWithTopRoughness(Layer{m_Substrate}, roughness);
158  sample->setRoughnessModel(roughnessModel);
159  return sample;
160 }
161 
163 {
164  auto sample = FeNiBilayer{Options()};
165  return sample.release();
166 }
167 
169 {
170  auto sample = FeNiBilayer{
171  Options().sigmaRoughness(2. * Units::angstrom).roughnessModel(RoughnessModel::TANH)};
172  return sample.release();
173 }
174 
176 {
177  auto sample = FeNiBilayer{
178  Options().sigmaRoughness(2. * Units::angstrom).roughnessModel(RoughnessModel::NEVOT_CROCE)};
179  return sample.release();
180 }
181 
183 {
184  auto sample = FeNiBilayer{Options().angle(38. * Units::degree)};
185  return sample.release();
186 }
187 
189 {
190  auto sample = FeNiBilayer{Options()
191  .angle(38 * Units::degree)
192  .sigmaRoughness(2. * Units::angstrom)
193  .roughnessModel(RoughnessModel::TANH)};
194  return sample.release();
195 }
196 
198 {
199  auto sample = FeNiBilayer{Options()
200  .angle(38 * Units::degree)
201  .sigmaRoughness(2. * Units::angstrom)
202  .roughnessModel(RoughnessModel::NEVOT_CROCE)};
203  return sample.release();
204 }
std::complex< double > complex_t
Definition: Complex.h:20
Defines various sample builder classes to test polarized specular computations.
Defines class LayerRoughness.
Defines class Layer.
Factory functions used to create material instances.
Defines class MultiLayer.
Defines the values of physical constants (SI)
Defines some unit conversion factors and other constants in namespace Units.
BasicVector3D< double > kvector_t
Definition: Vectors3D.h:21
MultiLayer * buildSample() const
MultiLayer * buildSample() const
MultiLayer * buildSample() const
MultiLayer * buildSample() const
A roughness of interface between two layers.
A layer, with thickness (in nanometer) and material.
Definition: Layer.h:28
Our sample model: a stack of layers one below the other.
Definition: MultiLayer.h:42
RoughnessModel roughnessModel() const
Definition: MultiLayer.h:83
Creates the sample demonstrating an Fe-Ni Bilayer with and without roughness.
Material MaterialBySLD()
constexpr double g_factor_n
neutron g-factor
constexpr double h_bar
Reduced Plank constant, J s.
constexpr double m_n
Neutron mass, kg.
constexpr double mu_N
Nuclear magneton ( ), J/T.
static constexpr double angstrom
Definition: Units.h:25
static constexpr double degree
Definition: Units.h:40