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