19#include <boost/algorithm/string/predicate.hpp>
28 const ComplexFortranMatrix &wf,
const int nre,
const std::vector<double> &H,
const double convfact) {
31 const double eps = 1.e-6;
35 int nlevels = en.len();
40 for (
auto i = 1; i <= nlevels; i++) {
41 for (
auto j = 1; j <= nlevels; j++) {
42 const double den = en(i) - en(j);
43 if (
fabs(den) < eps) {
44 mu(i) += real(mumat(i, j) * conj(mumat(i, j)));
46 mu2(i) += real(mumat(i, j) * conj(mumat(i, j))) / den;
53 for (
size_t iT = 0; iT < nData; iT++) {
56 const double beta = 1 / (k_B * xValues[iT]);
57 for (
auto i = 1; i <= nlevels; i++) {
58 double expfact = exp(-beta * en(i));
60 U += ((
mu(i) * beta) - (2 * mu2(i))) * expfact;
67void calculate_powder(
double *out,
const double *xValues,
const size_t nData,
const DoubleFortranVector &en,
69 for (
size_t j = 0; j < nData; j++) {
73 std::vector<double>
H;
74 std::vector<double>
tmp(nData, 0.);
75 for (
int i = 0; i < 3; i++) {
78 calculate(&
tmp[0], xValues, nData, en, wf, nre, H, convfact);
79 for (
size_t j = 0; j < nData; j++) {
83 for (
size_t j = 0; j < nData; j++) {
102 throw std::invalid_argument(
"Hdir must be a three-element vector.");
105 double Hnorm = sqrt(H[0] * H[0] + H[1] * H[1] + H[2] * H[2]);
106 if (
fabs(Hnorm) > 1.e-6) {
107 for (
auto i = 0; i < 3; i++) {
113 const double NAMUB2cgs = 0.03232776;
117 const double NAMUB2si = 4.062426e-7;
121 double convfact = boost::iequals(unit,
"bohr") ? 0.057883818 : (boost::iequals(unit,
"SI") ? NAMUB2si : NAMUB2cgs);
128 calculate_powder(out, xValues, nData,
m_en,
m_wf,
m_nre, convfact);
130 calculate(out, xValues, nData,
m_en,
m_wf,
m_nre, H, convfact);
133 const double EPS = 1.e-6;
135 for (
size_t i = 0; i < nData; i++) {
136 out[i] /= (1. -
lambda * out[i]);
141 for (
size_t i = 0; i < nData; i++) {
146 for (
size_t i = 0; i < nData; i++) {
147 out[i] = 1. / out[i];
152 for (
size_t i = 0; i < nData; i++) {
162 declareParameter(
"Lambda", 0.0,
"Effective exchange interaction");
163 declareParameter(
"Chi0", 0.0,
"Background or remnant susceptibility");
const std::vector< double > * lambda
#define DECLARE_FUNCTION(classname)
Macro for declaring a new type of function to be used with the FunctionFactory.
Attribute is a non-fitting parameter.
std::vector< double > asVector() const
Returns vector<double> if attribute is vector<double>, throws exception otherwise.
std::string asString() const
Returns string value if attribute is a string, throws exception otherwise.
double asDouble() const
Returns double value if attribute is a double, throws exception otherwise.
bool asBool() const
Returns bool value if attribute is a bool, throws exception otherwise.
virtual Attribute getAttribute(const std::string &name) const
Return a value of attribute attName.
virtual double getParameter(size_t i) const =0
Get i-th parameter.
void declareAttribute(const std::string &name, const API::IFunction::Attribute &defaultValue)
Declare a single attribute.
void declareParameter(const std::string &name, double initValue=0, const std::string &description="") override
Declare a new parameter.
CrystalFieldPeaks is a function that calculates crystal field peak positions and intensities.
void calculateEigenSystem(DoubleFortranVector &en, ComplexFortranMatrix &wf, ComplexFortranMatrix &ham, ComplexFortranMatrix &hz, int &nre) const
Calculate the crystal field eigensystem.
CrystalFieldSusceptibility is a function that calculates the molar magnetic susceptibility (in cm^3/m...
void function1D(double *out, const double *xValues, const size_t nData) const override
Function you want to fit to.
CrystalFieldSusceptibilityBase()
ComplexFortranMatrix m_wf
CrystalFieldSusceptibilityCalculation()
void setEigensystem(const DoubleFortranVector &en, const ComplexFortranMatrix &wf, const int nre)
void function1D(double *out, const double *xValues, const size_t nData) const override
Function you want to fit to.
void setEigensystem(const DoubleFortranVector &en, const ComplexFortranMatrix &wf, const int nre)
void MANTID_CURVEFITTING_DLL calculateMagneticMomentMatrix(const ComplexFortranMatrix &ev, const std::vector< double > &Hdir, const int nre, ComplexFortranMatrix &mumat)
Calculate the full magnetic moment matrix in a particular eigenvector basis.
FortranMatrix< ComplexMatrix > ComplexFortranMatrix
FortranVector< EigenVector > DoubleFortranVector
MANTID_GEOMETRY_DLL Raster calculate(const Kernel::V3D &beamDirection, const IObject &shape, const double cubeSizeInMetre)
static constexpr double BoltzmannConstant
Boltzmann Constant in meV/K Taken from http://physics.nist.gov/cuu/Constants on 10/07/2012.