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 
46 MultiLayer* SlicedCylindersBuilder::buildSample() const
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 
69 MultiLayer* SLDSlicedCylindersBuilder::buildSample() const
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 
94 MultiLayer* AveragedSlicedCylindersBuilder::buildSample() const
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 }
Defines class FormFactorCylinder.
Defines class Layer.
Factory functions used to create material instances.
Defines M_PI and some more mathematical constants.
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
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
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).