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;
}
|