BornAgain  1.18.0
Simulate and fit neutron and x-ray scattering at grazing incidence
ProcessedLayout.cpp
Go to the documentation of this file.
1 // ************************************************************************** //
2 //
3 // BornAgain: simulate and fit scattering at grazing incidence
4 //
5 //! @file Core/Computation/ProcessedLayout.cpp
6 //! @brief Implements class ProcessedLayout.
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 
23 #include "Sample/Slice/Slice.h"
25 
26 namespace
27 {
28 void ScaleRegionMap(std::map<size_t, std::vector<HomogeneousRegion>>& region_map, double factor);
29 }
30 
31 ProcessedLayout::ProcessedLayout(const ILayout& layout, const std::vector<Slice>& slices,
32  double z_ref, const IFresnelMap* p_fresnel_map, bool polarized)
33  : mp_fresnel_map(p_fresnel_map), m_polarized(polarized)
34 {
35  m_n_slices = slices.size();
36  collectFormFactors(layout, slices, z_ref);
37  if (auto p_iff = layout.interferenceFunction())
38  mP_iff.reset(p_iff->clone());
39 }
40 
42 {
43  mp_fresnel_map = other.mp_fresnel_map;
44  m_polarized = other.m_polarized;
45  m_n_slices = other.m_n_slices;
46  m_surface_density = other.m_surface_density;
47  m_formfactors = std::move(other.m_formfactors);
48  mP_iff = std::move(other.mP_iff);
49  m_region_map = std::move(other.m_region_map);
50 }
51 
53 {
54  return m_n_slices;
55 }
56 
58 {
59  return m_surface_density;
60 }
61 
62 const std::vector<FormFactorCoherentSum>& ProcessedLayout::formFactorList() const
63 {
64  return m_formfactors;
65 }
66 
68 {
69  return mP_iff.get();
70 }
71 
72 std::map<size_t, std::vector<HomogeneousRegion>> ProcessedLayout::regionMap() const
73 {
74  return m_region_map;
75 }
76 
78 
79 void ProcessedLayout::collectFormFactors(const ILayout& layout, const std::vector<Slice>& slices,
80  double z_ref)
81 {
82  double layout_abundance = layout.getTotalAbundance();
83  for (auto p_particle : layout.particles()) {
84  auto ff_coh = ProcessParticle(*p_particle, slices, z_ref);
85  ff_coh.scaleRelativeAbundance(layout_abundance);
86  m_formfactors.push_back(std::move(ff_coh));
87  }
88  double weight = layout.weight();
90  double scale_factor = m_surface_density / layout_abundance;
91  ScaleRegionMap(m_region_map, scale_factor);
92 }
93 
95  const std::vector<Slice>& slices,
96  double z_ref)
97 {
98  double abundance = particle.abundance();
99  auto sliced_ffs = SlicedFormFactorList::createSlicedFormFactors(particle, slices, z_ref);
100  auto region_map = sliced_ffs.regionMap();
101  ScaleRegionMap(region_map, abundance);
102  mergeRegionMap(region_map);
103  auto result = FormFactorCoherentSum(abundance);
104  for (size_t i = 0; i < sliced_ffs.size(); ++i) {
105  auto ff_pair = sliced_ffs[i];
106  std::unique_ptr<IFormFactor> P_ff_framework;
107  if (slices.size() > 1) {
108  if (m_polarized)
109  P_ff_framework = std::make_unique<FormFactorDWBAPol>(*ff_pair.first);
110  else
111  P_ff_framework = std::make_unique<FormFactorDWBA>(*ff_pair.first);
112  } else {
113  if (m_polarized)
114  P_ff_framework = std::make_unique<FormFactorBAPol>(*ff_pair.first);
115  else
116  P_ff_framework.reset(ff_pair.first->clone());
117  }
118 
119  size_t slice_index = ff_pair.second;
120  const Material slice_material = slices[slice_index].material();
121  P_ff_framework->setAmbientMaterial(slice_material);
122 
123  auto part = FormFactorCoherentPart(P_ff_framework.release());
124  part.setSpecularInfo(mp_fresnel_map, slice_index);
125 
126  result.addCoherentPart(part);
127  }
128  return result;
129 }
130 
132  const std::map<size_t, std::vector<HomogeneousRegion>>& region_map)
133 {
134  for (auto& entry : region_map) {
135  size_t layer_index = entry.first;
136  auto regions = entry.second;
137  m_region_map[layer_index].insert(m_region_map[layer_index].begin(), regions.begin(),
138  regions.end());
139  }
140 }
141 
142 namespace
143 {
144 void ScaleRegionMap(std::map<size_t, std::vector<HomogeneousRegion>>& region_map, double factor)
145 {
146  for (auto& entry : region_map) {
147  for (auto& region : entry.second) {
148  region.m_volume *= factor;
149  }
150  }
151 }
152 } // namespace
Defines class FormFactorBAPol.
Defines class FormFactorCoherentSum.
Defines class FormFactorDWBAPol.
Defines class FormFactorDWBA.
Defines and implements the interface class IInterferenceFunction.
Defines and implements interface class ILayout.
Defines interface IParticle.
Defines class ProcessedLayout.
Defines class Slice.
Defines class SlicedFormFactorList.
Information about single particle form factor and specular info of the embedding layer.
Information about particle form factor and abundance.
double abundance() const
Holds the necessary information to calculate the radiation wavefunction in every layer for different ...
Definition: IFresnelMap.h:30
Pure virtual base class of interference functions.
Pure virtual interface class to equip a sample layer with scattering properties.
Definition: ILayout.h:32
virtual const IInterferenceFunction * interferenceFunction() const =0
Returns the interference function.
virtual double getTotalAbundance() const =0
Get total abundance of all particles.
virtual SafePointerVector< IParticle > particles() const =0
Returns information on all particles (type and abundance) and generates new particles if an IAbstract...
virtual double totalParticleSurfaceDensity() const =0
Returns surface density of all particles.
double weight() const
Returns the relative weight of this layout.
Definition: ILayout.h:57
Pure virtual base class for Particle, ParticleComposition, ParticleCoreShell, MesoCrystal.
Definition: IParticle.h:33
A wrapper for underlying material implementation.
Definition: Material.h:29
Data structure that contains preprocessed data for a single layout.
ProcessedLayout(const ILayout &layout, const std::vector< Slice > &slices, double z_ref, const IFresnelMap *p_fresnel_map, bool polarized)
void mergeRegionMap(const std::map< size_t, std::vector< HomogeneousRegion >> &region_map)
std::map< size_t, std::vector< HomogeneousRegion > > m_region_map
size_t numberOfSlices() const
std::vector< FormFactorCoherentSum > m_formfactors
std::map< size_t, std::vector< HomogeneousRegion > > regionMap() const
double m_surface_density
std::unique_ptr< IInterferenceFunction > mP_iff
void collectFormFactors(const ILayout &layout, const std::vector< Slice > &slices, double z_ref)
const std::vector< FormFactorCoherentSum > & formFactorList() const
FormFactorCoherentSum ProcessParticle(const IParticle &particle, const std::vector< Slice > &slices, double z_ref)
const IInterferenceFunction * interferenceFunction() const
const IFresnelMap * mp_fresnel_map
double surfaceDensity() const
static SlicedFormFactorList createSlicedFormFactors(const IParticle &particle, const std::vector< Slice > &slices, double z_ref)
void ScaleRegionMap(std::map< size_t, std::vector< HomogeneousRegion >> &region_map, double factor)