BornAgain  1.19.79
Open-source research software to simulate and fit neutron and x-ray reflectometry and grazing-incidence small-angle scattering
FeNiBilayerBuilder.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
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 using Units::deg;
25 
26 namespace {
27 
28 auto constexpr rhoMconst = -PhysConsts::m_n * PhysConsts::g_factor_n * PhysConsts::mu_N
30 
31 const complex_t sldFe = complex_t{8.02e-06, 0};
32 const complex_t sldAu = complex_t{4.6665e-6, 0};
33 const complex_t sldNi = complex_t{9.4245e-06, 0};
34 
35 class Options {
36 public:
37  int m_NBilayers = 4;
38  double m_angle = 0.;
39  double m_magnetizationMagnitude = 1.e7;
40  double m_thicknessFe = 100. * Units::angstrom;
41  double m_thicknessNi = 40. * Units::angstrom;
42  double m_sigmaRoughness = 0.;
43  int m_effectiveSLD = 0;
44  RoughnessModel m_roughnessModel = RoughnessModel::TANH;
45 
46  Options() = default;
47  Options NBilayers(int n)
48  {
49  m_NBilayers = n;
50  return *this;
51  }
52  Options angle(double angle)
53  {
54  m_angle = angle;
55  return *this;
56  }
57  Options magnetizationMagnitude(double M)
58  {
59  m_magnetizationMagnitude = M;
60  return *this;
61  }
62  Options thicknessFe(double t)
63  {
64  m_thicknessFe = t;
65  return *this;
66  }
67  Options thicknessNi(double t)
68  {
69  m_thicknessNi = t;
70  return *this;
71  }
72  Options sigmaRoughness(double r)
73  {
74  m_sigmaRoughness = r;
75  return *this;
76  }
77  Options effectiveSLD(int i)
78  {
79  m_effectiveSLD = i;
80  return *this;
81  }
82  Options roughnessModel(RoughnessModel rm)
83  {
84  m_roughnessModel = rm;
85  return *this;
86  }
87 };
88 //! Creates the sample demonstrating an Fe-Ni Bilayer with and without roughness
89 //! @ingroup standard_samples
90 class FeNiBilayer {
91 public:
92  explicit FeNiBilayer(Options opt = {})
93  : NBilayers(opt.m_NBilayers)
94  , angle(opt.m_angle)
95  , magnetizationMagnitude(opt.m_magnetizationMagnitude)
96  , thicknessFe(opt.m_thicknessFe)
97  , thicknessNi(opt.m_thicknessNi)
98  , sigmaRoughness(opt.m_sigmaRoughness)
99  , effectiveSLD(opt.m_effectiveSLD)
100  , roughnessModel(opt.m_roughnessModel)
101  {
102  if (angle != 0. && effectiveSLD != 0.)
103  throw std::runtime_error("Cannot perform scalar computation "
104  "for non-colinear magnetization");
105 
106  magnetizationVector = R3(magnetizationMagnitude * std::sin(angle),
107  magnetizationMagnitude * std::cos(angle), 0);
108  sample = constructSample();
109  }
110 
111  MultiLayer* release() { return sample.release(); }
112 
113 private:
114  int NBilayers;
115  double angle;
116  double magnetizationMagnitude;
117  double thicknessFe;
118  double thicknessNi;
119  double sigmaRoughness;
120  int effectiveSLD;
121  RoughnessModel roughnessModel;
122 
123  R3 magnetizationVector;
124 
125  std::unique_ptr<MultiLayer> sample;
126 
127  std::unique_ptr<MultiLayer> constructSample();
128 };
129 
130 } // namespace
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(), R3{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. * deg)};
185  return sample.release();
186 }
187 
189 {
190  auto sample = FeNiBilayer{Options()
191  .angle(38 * deg)
192  .sigmaRoughness(2. * Units::angstrom)
193  .roughnessModel(RoughnessModel::TANH)};
194  return sample.release();
195 }
196 
198 {
199  auto sample = FeNiBilayer{Options()
200  .angle(38 * deg)
201  .sigmaRoughness(2. * Units::angstrom)
202  .roughnessModel(RoughnessModel::NEVOT_CROCE)};
203  return sample.release();
204 }
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.
A roughness of interface between two layers.
A layer in a MultiLayer sample.
Definition: Layer.h:26
Our sample model: a stack of layers one below the other.
Definition: MultiLayer.h:43
RoughnessModel roughnessModel() const
Definition: MultiLayer.h:67
Material MaterialBySLD()
MultiLayer * createFeNiBilayerNC()
MultiLayer * createFeNiBilayerSpinFlip()
MultiLayer * createFeNiBilayerTanh()
MultiLayer * createFeNiBilayerSpinFlipNC()
MultiLayer * createFeNiBilayer()
MultiLayer * createFeNiBilayerSpinFlipTanh()
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 deg
Definition: Units.h:46
static constexpr double angstrom
Definition: Units.h:34