BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
ProcessedSample Class Reference

Data structure that contains all the necessary data for scattering calculations. More...

Collaboration diagram for ProcessedSample:
[legend]

Public Member Functions

 ProcessedSample (const MultiLayer &sample, const SimulationOptions &options, bool forcePolarized=false)
 
 ~ProcessedSample ()
 
const std::vector< Slice > & averageSlices () const
 
const LayerRoughnessbottomRoughness (size_t i) const
 
bool containsMagneticMaterial () const
 
double crossCorrelationLength () const
 
double crossCorrSpectralFun (const kvector_t kvec, size_t j, size_t k) const
 Fourier transform of the correlation function of roughnesses between the interfaces. More...
 
kvector_t externalField () const
 
const IFresnelMapfresnelMap () const
 
bool hasRoughness () const
 
const std::vector< ProcessedLayout > & layouts () const
 
size_t numberOfSlices () const
 
double sliceBottomZ (size_t i) const
 
const std::vector< Slice > & slices () const
 
double sliceTopZ (size_t i) const
 

Private Member Functions

void addNSlices (size_t n, double thickness, const Material &material, const LayerRoughness *p_roughness=nullptr)
 
void addSlice (double thickness, const Material &material, const LayerRoughness *p_roughness=nullptr)
 
void initBFields ()
 
void initFresnelMap (const SimulationOptions &sim_options)
 
void initLayouts (const MultiLayer &sample)
 
void initSlices (const MultiLayer &sample, const SimulationOptions &options)
 
void mergeRegionMap (const std::map< size_t, std::vector< HomogeneousRegion >> &region_map)
 

Private Attributes

double m_crossCorrLength
 
kvector_t m_ext_field
 
std::unique_ptr< IFresnelMapm_fresnel_map
 
std::vector< ProcessedLayoutm_layouts
 
bool m_polarized
 
std::map< size_t, std::vector< HomogeneousRegion > > m_region_map
 
std::vector< Slicem_slices
 
double m_top_z
 

Detailed Description

Data structure that contains all the necessary data for scattering calculations.

If the usage of average materials is requested, layers and particles are sliced into multiple slices and the average material is calculated for each slice.

Definition at line 42 of file ProcessedSample.h.

Constructor & Destructor Documentation

◆ ProcessedSample()

ProcessedSample::ProcessedSample ( const MultiLayer sample,
const SimulationOptions options,
bool  forcePolarized = false 
)

Definition at line 111 of file ProcessedSample.cpp.

113  : m_slices{}
114  , m_top_z{0.0}
115  , m_polarized{forcePolarized}
117  , m_ext_field{sample.externalField()}
118 {
119  initSlices(sample, options);
120  m_fresnel_map = createFresnelMap(sample, m_slices, options);
121  initBFields();
122  initLayouts(sample);
123  initFresnelMap(options);
124 }
kvector_t externalField() const
Returns the external field applied to the multilayer (units: A/m)
Definition: MultiLayer.h:70
double crossCorrLength() const
Returns cross correlation length of roughnesses between interfaces.
Definition: MultiLayer.h:68
void initLayouts(const MultiLayer &sample)
std::vector< Slice > m_slices
void initSlices(const MultiLayer &sample, const SimulationOptions &options)
void initFresnelMap(const SimulationOptions &sim_options)
std::unique_ptr< IFresnelMap > m_fresnel_map
double m_crossCorrLength
kvector_t m_ext_field

References initBFields(), initFresnelMap(), initLayouts(), initSlices(), m_fresnel_map, and m_slices.

Here is the call graph for this function:

◆ ~ProcessedSample()

ProcessedSample::~ProcessedSample ( )
default

Member Function Documentation

◆ addNSlices()

void ProcessedSample::addNSlices ( size_t  n,
double  thickness,
const Material material,
const LayerRoughness p_roughness = nullptr 
)
private

Definition at line 303 of file ProcessedSample.cpp.

305 {
306  if (thickness <= 0.0)
307  return;
308  if (n == 0)
309  throw std::runtime_error("ProcessedSample::addNSlices: number of slices should be "
310  "bigger than zero.");
311  const double slice_thickness = thickness / n;
312  addSlice(slice_thickness, material, roughness);
313  for (size_t i = 1; i < n; ++i)
314  addSlice(slice_thickness, material);
315 }
void addSlice(double thickness, const Material &material, const LayerRoughness *p_roughness=nullptr)

References addSlice().

Referenced by initSlices().

Here is the call graph for this function:

◆ addSlice()

void ProcessedSample::addSlice ( double  thickness,
const Material material,
const LayerRoughness p_roughness = nullptr 
)
private

Definition at line 294 of file ProcessedSample.cpp.

296 {
297  if (roughness)
298  m_slices.emplace_back(thickness, material, *roughness);
299  else
300  m_slices.emplace_back(thickness, material);
301 }

References m_slices.

Referenced by addNSlices(), and initSlices().

◆ averageSlices()

const std::vector< Slice > & ProcessedSample::averageSlices ( ) const

Definition at line 138 of file ProcessedSample.cpp.

139 {
140  return m_fresnel_map->slices();
141 }

References m_fresnel_map.

Referenced by ProfileHelper::ProfileHelper().

◆ bottomRoughness()

const LayerRoughness * ProcessedSample::bottomRoughness ( size_t  i) const

Definition at line 163 of file ProcessedSample.cpp.

164 {
165  if (i + 2 > m_slices.size())
166  throw std::runtime_error("ProcessedSample::bottomRoughness: "
167  "index out of bounds.");
168  return m_slices[i + 1].topRoughness();
169 }

References m_slices.

Referenced by ProfileHelper::ProfileHelper(), RoughMultiLayerComputation::compute(), crossCorrSpectralFun(), and RoughMultiLayerComputation::get_sum8terms().

◆ containsMagneticMaterial()

bool ProcessedSample::containsMagneticMaterial ( ) const

Definition at line 191 of file ProcessedSample.cpp.

192 {
193  return m_polarized;
194 }

References m_polarized.

◆ crossCorrelationLength()

double ProcessedSample::crossCorrelationLength ( ) const

Definition at line 153 of file ProcessedSample.cpp.

154 {
155  return m_crossCorrLength;
156 }

References m_crossCorrLength.

Referenced by RoughMultiLayerComputation::compute().

◆ crossCorrSpectralFun()

double ProcessedSample::crossCorrSpectralFun ( const kvector_t  kvec,
size_t  j,
size_t  k 
) const

Fourier transform of the correlation function of roughnesses between the interfaces.

Definition at line 204 of file ProcessedSample.cpp.

205 {
206  if (m_crossCorrLength <= 0.0)
207  return 0.0;
208  const double z_j = sliceBottomZ(j);
209  const double z_k = sliceBottomZ(k);
210  const LayerRoughness* rough_j = bottomRoughness(j);
211  const LayerRoughness* rough_k = bottomRoughness(k);
212  if (!rough_j || !rough_k)
213  return 0.0;
214  const double sigma_j = rough_j->getSigma();
215  const double sigma_k = rough_k->getSigma();
216  if (sigma_j <= 0 || sigma_k <= 0)
217  return 0.0;
218  return 0.5
219  * ((sigma_k / sigma_j) * rough_j->getSpectralFun(kvec)
220  + (sigma_j / sigma_k) * rough_k->getSpectralFun(kvec))
221  * std::exp(-1 * std::abs(z_j - z_k) / m_crossCorrLength);
222 }
A roughness of interface between two layers.
double getSigma() const
Returns rms of roughness.
double getSpectralFun(const kvector_t kvec) const
Returns power spectral density of the surface roughness.
double sliceBottomZ(size_t i) const
const LayerRoughness * bottomRoughness(size_t i) const

References bottomRoughness(), LayerRoughness::getSigma(), LayerRoughness::getSpectralFun(), m_crossCorrLength, and sliceBottomZ().

Referenced by RoughMultiLayerComputation::compute().

Here is the call graph for this function:

◆ externalField()

kvector_t ProcessedSample::externalField ( ) const

Definition at line 158 of file ProcessedSample.cpp.

159 {
160  return m_ext_field;
161 }

References m_ext_field.

◆ fresnelMap()

const IFresnelMap * ProcessedSample::fresnelMap ( ) const

Definition at line 148 of file ProcessedSample.cpp.

149 {
150  return m_fresnel_map.get();
151 }

References m_fresnel_map.

Referenced by DepthProbeComputationTerm::compute(), and RoughMultiLayerComputation::get_sum8terms().

◆ hasRoughness()

bool ProcessedSample::hasRoughness ( ) const

Definition at line 196 of file ProcessedSample.cpp.

197 {
198  for (const auto& slice : m_slices)
199  if (slice.topRoughness())
200  return true;
201  return false;
202 }

References m_slices.

◆ initBFields()

void ProcessedSample::initBFields ( )
private

Definition at line 317 of file ProcessedSample.cpp.

318 {
319  if (m_slices.empty())
320  return;
321  const double m_z0 = m_slices[0].material().magnetization().z();
322  const double b_z = Slice::Magnetic_Permeability * (m_ext_field.z() + m_z0);
323  for (size_t i = 0; i < m_slices.size(); ++i) {
324  m_slices[i].initBField(m_ext_field, b_z);
325  }
326 }
T z() const
Returns z-component in cartesian coordinate system.
Definition: BasicVector3D.h:67
static constexpr double Magnetic_Permeability
Definition: Slice.h:62

References m_ext_field, m_slices, Slice::Magnetic_Permeability, and BasicVector3D< T >::z().

Referenced by ProcessedSample().

Here is the call graph for this function:

◆ initFresnelMap()

void ProcessedSample::initFresnelMap ( const SimulationOptions sim_options)
private

Definition at line 338 of file ProcessedSample.cpp.

339 {
340  if (sim_options.useAvgMaterials()) {
341  m_fresnel_map->setSlices(createAverageMaterialSlices(m_slices, m_region_map));
342  } else {
343  m_fresnel_map->setSlices(m_slices);
344  }
345 }
std::map< size_t, std::vector< HomogeneousRegion > > m_region_map
bool useAvgMaterials() const

References m_fresnel_map, m_region_map, m_slices, and SimulationOptions::useAvgMaterials().

Referenced by ProcessedSample().

Here is the call graph for this function:

◆ initLayouts()

void ProcessedSample::initLayouts ( const MultiLayer sample)
private

Definition at line 278 of file ProcessedSample.cpp.

279 {
280  double z_ref = -m_top_z;
281  m_polarized = m_polarized || sample.isMagnetic();
282 
283  for (size_t i = 0; i < sample.numberOfLayers(); ++i) {
284  if (i > 1)
285  z_ref -= sample.layer(i - 1)->thickness();
286  auto layer = sample.layer(i);
287  for (const auto* layout : layer->layouts()) {
288  m_layouts.emplace_back(*layout, m_slices, z_ref, m_fresnel_map.get(), m_polarized);
289  mergeRegionMap(m_layouts.back().regionMap());
290  }
291  }
292 }
bool isMagnetic() const
Returns true if there is any magnetic material in this ISampleNode.
Definition: ISampleNode.cpp:40
double thickness() const
Definition: Layer.h:38
const Layer * layer(size_t i_layer) const
Returns layer with given index.
Definition: MultiLayer.cpp:91
size_t numberOfLayers() const
Definition: MultiLayer.h:50
void mergeRegionMap(const std::map< size_t, std::vector< HomogeneousRegion >> &region_map)
std::vector< ProcessedLayout > m_layouts

References ISampleNode::isMagnetic(), MultiLayer::layer(), m_fresnel_map, m_layouts, m_polarized, m_slices, m_top_z, mergeRegionMap(), MultiLayer::numberOfLayers(), and Layer::thickness().

Referenced by ProcessedSample().

Here is the call graph for this function:

◆ initSlices()

void ProcessedSample::initSlices ( const MultiLayer sample,
const SimulationOptions options 
)
private

Definition at line 225 of file ProcessedSample.cpp.

226 {
227  if (sample.numberOfLayers() == 0)
228  return;
229  bool use_slicing = options.useAvgMaterials() && sample.numberOfLayers() > 1;
230  const auto layer_limits = particleRegions(sample, use_slicing);
231  for (size_t i = 0; i < sample.numberOfLayers(); ++i) {
232  const auto layer = sample.layer(i);
233  const auto n_slices = layer->numberOfSlices();
234  const ZLimits& slice_limits = layer_limits[i];
235  double tl = layer->thickness();
236  const Material* material = layer->material();
237  auto roughness = MultiLayerUtils::LayerTopRoughness(sample, i);
238  if (roughness && roughness->getSigma() <= 0)
239  roughness = nullptr;
240  // if no slicing is needed, create single slice for the layer
241  if (!slice_limits.isFinite() || n_slices == 0) {
242  if (i == sample.numberOfLayers() - 1)
243  tl = 0.0;
244  addSlice(tl, *material, roughness);
245  continue;
246  }
247  const double top = slice_limits.upperLimit().m_value;
248  const double bottom = slice_limits.lowerLimit().m_value;
249  // top layer
250  if (i == 0) {
251  if (top <= 0)
252  throw std::runtime_error("ProcessedSample::ProcessedSample: "
253  "top limit for top layer must be > 0.");
254  addSlice(0.0, *material);
255  addNSlices(n_slices, top - bottom, *material);
256  if (bottom > 0)
257  addSlice(bottom, *material);
258  m_top_z = top;
259  }
260  // middle or bottom layer
261  else {
262  if (top < 0) {
263  addSlice(-top, *material, roughness);
264  addNSlices(n_slices, top - bottom, *material);
265  } else {
266  addNSlices(n_slices, top - bottom, *material, roughness);
267  }
268  // middle layer
269  if (i < sample.numberOfLayers() - 1 && bottom > -tl)
270  addSlice(bottom + tl, *material);
271  // bottom layer
272  if (i == sample.numberOfLayers() - 1)
273  addSlice(0.0, *material);
274  }
275  }
276 }
unsigned int numberOfSlices() const
Definition: Layer.h:52
A wrapper for underlying material implementation.
Definition: Material.h:29
void addNSlices(size_t n, double thickness, const Material &material, const LayerRoughness *p_roughness=nullptr)
Class that contains upper and lower limits of the z-coordinate for the slicing of form factors.
Definition: ZLimits.h:45
OneSidedLimit lowerLimit() const
Definition: ZLimits.cpp:39
OneSidedLimit upperLimit() const
Definition: ZLimits.cpp:44
bool isFinite() const
Definition: ZLimits.cpp:32
const LayerRoughness * LayerTopRoughness(const MultiLayer &multilayer, size_t i)
Returns top roughness of layer.
double m_value
Definition: ZLimits.h:37

References addNSlices(), addSlice(), ZLimits::isFinite(), MultiLayer::layer(), MultiLayerUtils::LayerTopRoughness(), ZLimits::lowerLimit(), m_top_z, OneSidedLimit::m_value, MultiLayer::numberOfLayers(), Layer::numberOfSlices(), ZLimits::upperLimit(), and SimulationOptions::useAvgMaterials().

Referenced by ProcessedSample().

Here is the call graph for this function:

◆ layouts()

const std::vector< ProcessedLayout > & ProcessedSample::layouts ( ) const

Definition at line 143 of file ProcessedSample.cpp.

144 {
145  return m_layouts;
146 }

References m_layouts.

◆ mergeRegionMap()

void ProcessedSample::mergeRegionMap ( const std::map< size_t, std::vector< HomogeneousRegion >> &  region_map)
private

Definition at line 328 of file ProcessedSample.cpp.

330 {
331  for (const auto& entry : region_map) {
332  size_t i = entry.first;
333  auto& regions = entry.second;
334  m_region_map[i].insert(m_region_map[i].begin(), regions.begin(), regions.end());
335  }
336 }

References m_region_map.

Referenced by initLayouts().

◆ numberOfSlices()

size_t ProcessedSample::numberOfSlices ( ) const

Definition at line 128 of file ProcessedSample.cpp.

129 {
130  return m_slices.size();
131 }

References m_slices.

Referenced by ProfileHelper::ProfileHelper(), DepthProbeComputationTerm::compute(), RoughMultiLayerComputation::compute(), and sliceBottomZ().

◆ sliceBottomZ()

double ProcessedSample::sliceBottomZ ( size_t  i) const

Definition at line 178 of file ProcessedSample.cpp.

179 {
180  if (numberOfSlices() < 2)
181  return m_top_z;
182  // Last slice has no bottom:
183  if (i + 2 > numberOfSlices())
184  i = numberOfSlices() - 2;
185  double z = m_top_z;
186  for (size_t j = 1; j <= i; ++j)
187  z -= m_slices[j].thickness();
188  return z;
189 }
size_t numberOfSlices() const

References m_slices, m_top_z, and numberOfSlices().

Referenced by ProfileHelper::ProfileHelper(), DepthProbeComputationTerm::compute(), crossCorrSpectralFun(), and sliceTopZ().

Here is the call graph for this function:

◆ slices()

const std::vector< Slice > & ProcessedSample::slices ( ) const

Definition at line 133 of file ProcessedSample.cpp.

134 {
135  return m_slices;
136 }

References m_slices.

Referenced by RoughMultiLayerComputation::get_refractive_term(), and RoughMultiLayerComputation::get_sum8terms().

◆ sliceTopZ()

double ProcessedSample::sliceTopZ ( size_t  i) const

Definition at line 171 of file ProcessedSample.cpp.

172 {
173  if (i == 0)
174  return m_top_z;
175  return sliceBottomZ(i - 1);
176 }

References m_top_z, and sliceBottomZ().

Referenced by DepthProbeComputationTerm::compute().

Here is the call graph for this function:

Member Data Documentation

◆ m_crossCorrLength

double ProcessedSample::m_crossCorrLength
private

Definition at line 81 of file ProcessedSample.h.

Referenced by crossCorrelationLength(), and crossCorrSpectralFun().

◆ m_ext_field

kvector_t ProcessedSample::m_ext_field
private

Definition at line 82 of file ProcessedSample.h.

Referenced by externalField(), and initBFields().

◆ m_fresnel_map

std::unique_ptr<IFresnelMap> ProcessedSample::m_fresnel_map
private

◆ m_layouts

std::vector<ProcessedLayout> ProcessedSample::m_layouts
private

Definition at line 80 of file ProcessedSample.h.

Referenced by initLayouts(), and layouts().

◆ m_polarized

bool ProcessedSample::m_polarized
private

Definition at line 79 of file ProcessedSample.h.

Referenced by containsMagneticMaterial(), and initLayouts().

◆ m_region_map

std::map<size_t, std::vector<HomogeneousRegion> > ProcessedSample::m_region_map
private

Definition at line 83 of file ProcessedSample.h.

Referenced by initFresnelMap(), and mergeRegionMap().

◆ m_slices

std::vector<Slice> ProcessedSample::m_slices
private

◆ m_top_z

double ProcessedSample::m_top_z
private

Definition at line 78 of file ProcessedSample.h.

Referenced by initLayouts(), initSlices(), sliceBottomZ(), and sliceTopZ().


The documentation for this class was generated from the following files: