File: SliceStack.cpp

package info (click to toggle)
bornagain 23.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 103,936 kB
  • sloc: cpp: 423,131; python: 40,997; javascript: 11,167; awk: 630; sh: 318; ruby: 173; xml: 130; makefile: 51; ansic: 24
file content (82 lines) | stat: -rw-r--r-- 2,872 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      Resample/Slice/SliceStack.cpp
//! @brief     Implements class SliceStack.
//!
//! @homepage  http://www.bornagainproject.org
//! @license   GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
//  ************************************************************************************************

#include "Resample/Slice/SliceStack.h"
#include "Base/Util/Assert.h"
#include <algorithm>

void SliceStack::addTopSlice(double zbottom, const Material& material)
{
    this->emplace_back(Slice(ZLimits(zbottom, ZLimits::inf), material, {}, nullptr, 0.0));
}

void SliceStack::addSlice(double thickness, const Material& material,
                          const Roughness* const roughness, double rms)
{
    ASSERT(!this->empty());
    double top = this->back().low();
    ASSERT(thickness >= 0);
    std::unique_ptr<ZLimits> zRange;
    if (thickness == 0)
        zRange = std::make_unique<ZLimits>(-ZLimits::inf, top);
    else
        zRange = std::make_unique<ZLimits>(top - thickness, top);
    this->emplace_back(Slice(*zRange, material, {}, roughness, rms));
}

//! Adds n times the same slice to the stack.

void SliceStack::addNSlices(size_t n, double thickness, const Material& material,
                            const Roughness* const roughness, double rms)
{
    ASSERT(thickness > 0);
    ASSERT(n > 0);
    const double slice_thickness = thickness / n;
    addSlice(slice_thickness, material, roughness, rms);
    for (size_t i = 1; i < n; ++i)
        addSlice(slice_thickness, material);
}

SliceStack SliceStack::setBField(const R3& externalField)
{
    // Temporary forbid non-zero magnetization in fronting medium (see issue #654)
    if (this->at(0).material().magnetization() != R3())
        throw std::runtime_error("Processing fronting magnetization is not implemented yet.");

    // Temporary forbid non-zero external field (see issue #654)
    if (externalField != R3())
        throw std::runtime_error("Processing external field is not implemented yet.");

    if (this->empty())
        return *this;
    const double M_z0 = this->at(0).material().magnetization().z();
    const double H_z = externalField.z() + M_z0;
    for (Slice& slice : *this)
        slice.initBField(externalField, H_z);
    return *this;
}

const Roughness* SliceStack::bottomRoughness(size_t i_slice) const
{
    if (i_slice + 1 < size())
        return (*this)[i_slice + 1].topRoughness();
    return nullptr;
}

double SliceStack::bottomRMS(size_t i_slice) const
{
    if (i_slice + 1 < size())
        return (*this)[i_slice + 1].topRMS();
    return 0.0;
}