BornAgain  1.19.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 reflection and scattering
4 //
5 //! @file Sample/Processed/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 
24 #include "Sample/Slice/Slice.h"
26 
27 namespace {
28 void ScaleRegionMap(std::map<size_t, std::vector<HomogeneousRegion>>& region_map, double factor)
29 {
30  for (auto& entry : region_map) {
31  for (auto& region : entry.second) {
32  region.m_volume *= factor;
33  }
34  }
35 }
36 } // namespace
37 
38 // ************************************************************************************************
39 // class ProcessedLayout
40 // ************************************************************************************************
41 
42 ProcessedLayout::ProcessedLayout(const ParticleLayout& layout, const std::vector<Slice>& slices,
43  double z_ref, const IFresnelMap* p_fresnel_map, bool polarized)
44  : m_fresnel_map(p_fresnel_map), m_polarized(polarized)
45 {
46  m_n_slices = slices.size();
47  collectFormFactors(layout, slices, z_ref);
48  if (const auto* iff = layout.interferenceFunction())
49  m_iff.reset(iff->clone());
50 }
51 
53 {
54  m_fresnel_map = other.m_fresnel_map;
55  m_polarized = other.m_polarized;
56  m_n_slices = other.m_n_slices;
57  m_surface_density = other.m_surface_density;
58  m_formfactors = std::move(other.m_formfactors);
59  m_iff = std::move(other.m_iff);
60  m_region_map = std::move(other.m_region_map);
61 }
62 
64 {
65  return m_n_slices;
66 }
67 
69 {
70  return m_surface_density;
71 }
72 
73 const std::vector<FormFactorCoherentSum>& ProcessedLayout::formFactorList() const
74 {
75  return m_formfactors;
76 }
77 
79 {
80  return m_iff.get();
81 }
82 
83 std::map<size_t, std::vector<HomogeneousRegion>> ProcessedLayout::regionMap() const
84 {
85  return m_region_map;
86 }
87 
89 
91  const std::vector<Slice>& slices, double z_ref)
92 {
93  double layout_abundance = layout.getTotalAbundance();
94  for (const auto* particle : layout.particles()) {
95  FormFactorCoherentSum ff_coh = processParticle(*particle, slices, z_ref);
96  ff_coh.scaleRelativeAbundance(layout_abundance);
97  m_formfactors.emplace_back(ff_coh);
98  }
99  double weight = layout.weight();
101  double scale_factor = m_surface_density / layout_abundance;
102  ScaleRegionMap(m_region_map, scale_factor);
103 }
104 
106  const std::vector<Slice>& slices,
107  double z_ref)
108 {
109  double abundance = particle.abundance();
110  auto sliced_ffs = SlicedFormFactorList::createSlicedFormFactors(particle, slices, z_ref);
111  auto region_map = sliced_ffs.regionMap();
112  ScaleRegionMap(region_map, abundance);
113  mergeRegionMap(region_map);
114  auto result = FormFactorCoherentSum(abundance);
115  for (size_t i = 0; i < sliced_ffs.size(); ++i) {
116  const auto ff_pair = sliced_ffs[i];
117  std::unique_ptr<IComputeFF> ff_framework;
118  if (slices.size() > 1) {
119  if (m_polarized)
120  ff_framework = std::make_unique<ComputeDWBAPol>(*ff_pair.first);
121  else
122  ff_framework = std::make_unique<ComputeDWBA>(*ff_pair.first);
123  } else {
124  if (m_polarized)
125  ff_framework = std::make_unique<ComputeBAPol>(*ff_pair.first);
126  else
127  ff_framework = std::make_unique<ComputeBA>(*ff_pair.first);
128  }
129 
130  size_t slice_index = ff_pair.second;
131  const Material slice_material = slices[slice_index].material();
132  ff_framework->setAmbientMaterial(slice_material);
133 
134  auto part = FormFactorCoherentPart(ff_framework.release());
135  part.setSpecularInfo(m_fresnel_map, slice_index);
136 
137  result.addCoherentPart(part);
138  }
139  return result;
140 }
141 
143  const std::map<size_t, std::vector<HomogeneousRegion>>& region_map)
144 {
145  for (const auto& entry : region_map) {
146  size_t layer_index = entry.first;
147  auto regions = entry.second;
148  m_region_map[layer_index].insert(m_region_map[layer_index].begin(), regions.begin(),
149  regions.end());
150  }
151 }
Defines class ComputeBAPol.
Defines class ComputeBA.
Defines class ComputeDWBAPol.
Defines class ComputeDWBA.
Defines class FormFactorCoherentSum.
Defines and implements the interface class IInterferenceFunction.
Defines interface IParticle.
Defines class ParticleLayout.
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.
void scaleRelativeAbundance(double total_abundance)
double abundance() const
Holds the necessary information to calculate the radiation wavefunction in every layer for different ...
Definition: IFresnelMap.h:34
Abstract base class of interference functions.
Abstract base class for Particle, ParticleComposition, ParticleCoreShell, MesoCrystal.
Definition: IParticle.h:33
A wrapper for underlying material implementation.
Definition: Material.h:29
Decorator class that adds particles to ISampleNode objects.
double weight() const
Returns the relative weight of this layout.
double getTotalAbundance() const
const IInterferenceFunction * interferenceFunction() const
SafePointerVector< IParticle > particles() const
Returns information on all particles (type and abundance) and generates new particles if an IAbstract...
double totalParticleSurfaceDensity() const
Data structure that contains preprocessed data for a single layout.
FormFactorCoherentSum processParticle(const IParticle &particle, const std::vector< Slice > &slices, double z_ref)
ProcessedLayout(const ParticleLayout &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
std::unique_ptr< IInterferenceFunction > m_iff
double m_surface_density
const std::vector< FormFactorCoherentSum > & formFactorList() const
void collectFormFactors(const ParticleLayout &layout, const std::vector< Slice > &slices, double z_ref)
const IInterferenceFunction * interferenceFunction() const
double surfaceDensity() const
const IFresnelMap * m_fresnel_map
static SlicedFormFactorList createSlicedFormFactors(const IParticle &particle, const std::vector< Slice > &slices, double z_ref)
matrixFFVector_t polarized(const SimulationElement &sim_element, const std::vector< FormFactorCoherentSum > &ff_wrappers)