BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
SlicedCylindersBuilder.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Sample/StandardSamples/SlicedCylindersBuilder.cpp
6 //! @brief Implements classes for testing slicing machinery.
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/Const/Units.h"
17 #include "Base/Math/Constants.h"
24 
25 namespace {
26 const double height(5 * Units::nm);
27 const double radius(5 * Units::nm);
28 const double wavelength(0.154); // nm
29 const int n_slices(3);
30 
31 //! Returns SLD input (in inverse square Angstroms) for MaterialBySLD from _delta_ and _beta_,
32 //! i.e. the input for HomogeneousMaterial.
33 complex_t getSLDFromN(double wavelength, double delta, double beta)
34 {
35  complex_t result{2 * delta - delta * delta + beta * beta, 2 * beta - 2 * delta * beta};
36  return result * M_PI / (wavelength * wavelength) * (Units::angstrom * Units::angstrom);
37 }
38 
39 complex_t averageSLD(complex_t sld_p, complex_t sld_l, double eff_vol)
40 {
41  return sld_l + eff_vol * (sld_p - sld_l);
42 }
43 } // namespace
44 
46 {
47  Material vacuum_material = HomogeneousMaterial("Vacuum", 0.0, 0.0);
48  Material substrate_material = HomogeneousMaterial("Substrate", 6e-6, 2e-8);
49  Material particle_material = HomogeneousMaterial("Particle", 6e-4, 2e-8);
50 
51  Layer vacuum_layer(vacuum_material);
52  Layer substrate_layer(substrate_material);
53 
54  FormFactorCylinder ff_cylinder(radius, height);
55 
56  Particle particle(particle_material, ff_cylinder);
57  ParticleLayout particle_layout(particle);
58 
59  vacuum_layer.addLayout(particle_layout);
60  vacuum_layer.setNumberOfSlices(n_slices);
61 
62  MultiLayer* multi_layer = new MultiLayer();
63  multi_layer->addLayer(vacuum_layer);
64  multi_layer->addLayer(substrate_layer);
65  return multi_layer;
66 }
67 
69 {
70  Material vacuum_material = MaterialBySLD("Vacuum", 0.0, 0.0);
71  complex_t sub_sld = getSLDFromN(wavelength, 6e-6, 2e-8);
72  Material substrate_material = MaterialBySLD("Substrate", sub_sld.real(), sub_sld.imag());
73  complex_t par_sld = getSLDFromN(wavelength, 6e-4, 2e-8);
74  Material particle_material = MaterialBySLD("Particle", par_sld.real(), par_sld.imag());
75 
76  Layer vacuum_layer(vacuum_material);
77  Layer substrate_layer(substrate_material);
78 
79  FormFactorCylinder ff_cylinder(radius, height);
80 
81  Particle particle(particle_material, ff_cylinder);
82  ParticleLayout particle_layout(particle);
83 
84  vacuum_layer.addLayout(particle_layout);
85  vacuum_layer.setNumberOfSlices(n_slices);
86 
87  MultiLayer* multi_layer = new MultiLayer();
88  multi_layer->addLayer(vacuum_layer);
89  multi_layer->addLayer(substrate_layer);
90  return multi_layer;
91 }
92 
94 {
95  const auto par_surf_density = ParticleLayout().totalParticleSurfaceDensity();
96 
97  complex_t vacuum_sld{0.0, 0.0};
98  Material vacuum_material = MaterialBySLD("Vacuum", vacuum_sld.real(), vacuum_sld.imag());
99  complex_t sub_sld = getSLDFromN(wavelength, 6e-6, 2e-8);
100  Material substrate_material = MaterialBySLD("Substrate", sub_sld.real(), sub_sld.imag());
101 
102  double eff_vol = par_surf_density * M_PI * radius * radius;
103  complex_t par_sld = getSLDFromN(wavelength, 6e-4, 2e-8);
104  complex_t avr_sld = averageSLD(par_sld, vacuum_sld, eff_vol);
105  Material avr_material = MaterialBySLD("Avr", avr_sld.real(), avr_sld.imag());
106 
107  Layer vacuum_layer(vacuum_material);
108  Layer avr_layer(avr_material, height / n_slices);
109  Layer substrate_layer(substrate_material);
110 
111  MultiLayer* multi_layer = new MultiLayer();
112  multi_layer->addLayer(vacuum_layer);
113  for (size_t i = 0; i < n_slices; ++i)
114  multi_layer->addLayer(avr_layer);
115  multi_layer->addLayer(substrate_layer);
116  return multi_layer;
117 }
std::complex< double > complex_t
Definition: Complex.h:20
Defines M_PI and some more mathematical constants.
#define M_PI
Definition: Constants.h:44
Defines class FormFactorCylinder.
Defines class Layer.
Factory functions used to create material instances.
Defines class MultiLayer.
Defines class ParticleLayout.
Defines class Particle.
Defines classes for testing slicing machinery.
Defines some unit conversion factors and other constants in namespace Units.
A circular cylinder.
A layer in a MultiLayer sample.
Definition: Layer.h:27
void setNumberOfSlices(unsigned int n_slices)
Definition: Layer.h:51
void addLayout(const ParticleLayout &decoration)
Definition: Layer.cpp:58
A wrapper for underlying material implementation.
Definition: Material.h:29
Our sample model: a stack of layers one below the other.
Definition: MultiLayer.h:41
void addLayer(const Layer &layer)
Adds layer with default (zero) roughness.
Definition: MultiLayer.cpp:53
Decorator class that adds particles to ISampleNode objects.
double totalParticleSurfaceDensity() const
A particle with a form factor and refractive index.
Definition: Particle.h:24
MultiLayer * buildSample() const
Material HomogeneousMaterial(const std::string &name, complex_t refractive_index, kvector_t magnetization)
Constructs a material with name, refractive_index and magnetization (in A/m).
static constexpr double nm
Definition: Units.h:39
static constexpr double angstrom
Definition: Units.h:34