File: IMaterialImpl.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 (78 lines) | stat: -rw-r--r-- 2,452 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
//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      Sample/Material/IMaterialImpl.cpp
//! @brief     Implements magnetic material base implementation.
//!
//! @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 "Sample/Material/IMaterialImpl.h"
#include "Base/Const/PhysicalConstants.h"
#include "Base/Spin/SpinMatrix.h"
#include "Base/Vector/WavevectorInfo.h"
#include "Sample/Material/MaterialUtil.h"
#include <memory>

namespace {

using PhysConsts::gamma_n;
using PhysConsts::mu_B;
using PhysConsts::r_e;

// The factor 1e-18 is here to have unit: m/A*nm^-2
constexpr double magnetization_prefactor = (gamma_n * r_e / 2.0 / mu_B) * 1e-18;

C3 OrthogonalToBaseVector(const C3& base, const R3& vector)
{
    if (base.mag2() == 0.0)
        return {};
    C3 projection = (base.dot(vector) / base.mag2()) * base;
    return vector.complex() - projection;
}

} // namespace


IMaterialImpl::IMaterialImpl(const std::string& name, const R3& magnetization)
    : m_name(name)
    , m_magnetization(magnetization)
{
}

IMaterialImpl* IMaterialImpl::inverted() const
{
    std::string name = isScalarMaterial() ? matName() : matName() + "_inv";
    IMaterialImpl* result = this->clone();
    result->setMagnetization(-magnetization());
    return result;
}

bool IMaterialImpl::isScalarMaterial() const
{
    return m_magnetization == R3();
}

bool IMaterialImpl::isMagneticMaterial() const
{
    return !isScalarMaterial();
}
SpinMatrix IMaterialImpl::polarizedSubtrSLD(const WavevectorInfo& wavevectors) const
{
    C3 mag_ortho = OrthogonalToBaseVector(wavevectors.getQ(), m_magnetization);
    complex_t unit_factor = scalarSubtrSLD(wavevectors.vacuumLambda());
    return MaterialUtil::MagnetizationCorrection(unit_factor, magnetization_prefactor, mag_ortho);
}

IMaterialImpl* IMaterialImpl::rotatedMaterial(const RotMatrix& transform) const
{
    R3 transformed_field = transform.transformed(m_magnetization);
    IMaterialImpl* result = this->clone();
    result->setMagnetization(transformed_field);
    return result;
}