If you are using GitLab outside of the ILL, then you will need to use HTTPS and not SSH for clone/push/pull operations. If you are using the VPN, then SSH will work normally.

Commit ce57b567 authored by Tobias WEBER's avatar Tobias WEBER
parent 5425851e
......@@ -8,6 +8,7 @@ Neutrons
* (Shirane 2002), G. Shirane et al., "Neutron Scattering with a Triple-Axis Spectrometer", 2002, ISBN: 978-0521411264.
* (Squires 2012), G. L. Squires, "Thermal Neutron Scattering", 2012, ISBN: 9781139107808.
* (ILL Neutron Data Booklet), ISBN: 0-9704143-7-4, 2003, https://www.ill.eu/about-the-ill/documentation/
-------------------------------------------------------------------------------
......
......@@ -10,7 +10,6 @@
#include "../helper/flags.h"
#include "../helper/exception.h"
//#include "quat.h"
#include "linalg.h"
#include "linalg2.h"
#include "stat.h"
......@@ -37,6 +36,7 @@ public:
using t_vec = ublas::vector<T>;
using t_mat = ublas::matrix<T>;
protected:
bool m_bValid = 0;
t_vec m_vecX0;
......@@ -44,6 +44,7 @@ protected:
t_vec m_vecNorm;
T m_d;
public:
/**
* plane from a point and a normal
......@@ -258,21 +259,27 @@ public:
};
//------------------------------------------------------------------------------
template<typename T> class Line
{
public:
using t_vec = ublas::vector<T>;
using t_mat = ublas::matrix<T>;
protected:
t_vec m_vecX0;
t_vec m_vecDir;
public:
Line() {}
Line(const t_vec& vec0, const t_vec& dir)
: m_vecX0(vec0), m_vecDir(dir)
{}
......@@ -291,6 +298,25 @@ public:
const t_vec& GetDir() const { return m_vecDir; }
/**
* distance to a point
*/
T GetDist(const t_vec& vecPt) const
{
const t_vec& vecX0 = GetX0();
t_vec vecDir = GetDir() / veclen(GetDir());
// shift everything so that line goes through the origin
t_vec vecPtShift = vecPt - vecX0;
// project point on direction vector
t_vec vecClosestPt = inner(vecPtShift, vecDir) * vecDir;
// distance between point and projected point
return veclen(vecClosestPt - vecPtShift);
}
/**
* distance to line l1
*/
......@@ -299,14 +325,14 @@ public:
const Line<T>& l0 = *this;
// vector normal to both directions defining the distance line
t_vec vecNorm = cross_3(l0.GetDir(), l1.GetDir());
t_vec vecNorm = cross_3<t_vec>(l0.GetDir(), l1.GetDir());
T tlenNorm = veclen(vecNorm);
t_vec vec01 = l1.GetX0() - l0.GetX0();
// if the lines are parallel, any point (e.g. the X0s) can be used
// if the lines are parallel, any point (e.g. the x0s) can be used
if(float_equal(tlenNorm, T(0)))
return veclen(vec01);
return GetDist(l1.GetX0());
// project x0_1 - x0_0 onto vecNorm
T tdot = std::abs(inner(vec01, vecNorm));
......@@ -314,26 +340,6 @@ public:
}
/**
* distance to a point
*/
T GetDist(const t_vec& vecPt) const
{
const t_vec& vecX0 = GetX0();
const t_vec& vecDir = GetDir();
T tlenDir = veclen(vecDir);
// area of parallelogram spanned by vecDir and vecPt-vecX0
// == ||vecDir||*||vecPt-vecX0||*sin(th)
T tArea = veclen(cross_3(vecDir, vecPt-vecX0));
// length of perpendicular line from vecPt, also by sine theorem
// == ||vecPt-vecX0||*sin(th)
return tArea / tlenDir;
}
bool IsParallel(const Line<T>& line, T eps = tl::get_epsilon<T>()) const
{
return vec_is_collinear<t_vec>(GetDir(), line.GetDir(), eps);
......@@ -420,7 +426,7 @@ public:
const t_vec xp2 = plane.GetX0() + plane.GetDir1();
t_mat matDenom(N+1,N+1);
matDenom(0,0) = 1; matDenom(0,1) = 1; matDenom(0,2) = 1; matDenom(0,3) = 0;
matDenom(0,0) = 1; matDenom(0,1) = 1; matDenom(0,2) = 1; matDenom(0,3) = 0;
matDenom(1,0) = xp0[0]; matDenom(1,1) = xp1[0]; matDenom(1,2) = xp2[0]; matDenom(1,3) = dirl[0];
matDenom(2,0) = xp0[1]; matDenom(2,1) = xp1[1]; matDenom(2,2) = xp2[1]; matDenom(2,3) = dirl[1];
matDenom(3,0) = xp0[2]; matDenom(3,1) = xp1[2]; matDenom(3,2) = xp2[2]; matDenom(3,3) = dirl[2];
......@@ -430,7 +436,7 @@ public:
return false;
t_mat matNum(N+1,N+1);
matNum(0,0) = 1; matNum(0,1) = 1; matNum(0,2) = 1; matNum(0,3) = 1;
matNum(0,0) = 1; matNum(0,1) = 1; matNum(0,2) = 1; matNum(0,3) = 1;
matNum(1,0) = xp0[0]; matNum(1,1) = xp1[0]; matNum(1,2) = xp2[0]; matNum(1,3) = posl[0];
matNum(2,0) = xp0[1]; matNum(2,1) = xp1[1]; matNum(2,2) = xp2[1]; matNum(2,3) = posl[1];
matNum(3,0) = xp0[2]; matNum(3,1) = xp1[2]; matNum(3,2) = xp2[2]; matNum(3,3) = posl[2];
......@@ -448,19 +454,27 @@ public:
*
* pos0 + t0*dir0 = pos1 + t1*dir1
* pos0 - pos1 = t1*dir1 - t0*dir0
* exact: b = Mx -> M^(-1)*b = x
* approx: M^t b = M^t M x -> (M^t M)^(-1) * M^t b = x
* pos0 - pos1 = (-dir0 dir1) * (t0 t1)^t
* exact solution for the t params: (-dir0 dir1)^(-1) * (pos0 - pos1) = (t0 t1)^t
*
* generally:
* exact: b = M t -> M^(-1)*b = t
* approx.: M^t b = M^t M t -> (M^t M)^(-1) * M^t b = t
*/
bool intersect(const Line<T>& line, T& t, T eps = tl::get_epsilon<T>()) const
bool intersect(const Line<T>& line1, T& t0, T eps = tl::get_epsilon<T>(), T *pt1=nullptr) const
{
if(IsParallel(line, eps))
if(IsParallel(line1, eps))
{
t0 = 0;
if(pt1) *pt1 = 0;
return false;
}
const t_vec& pos0 = this->GetX0();
const t_vec& pos1 = line.GetX0();
const t_vec& pos1 = line1.GetX0();
const t_vec& dir0 = this->GetDir();
const t_vec& dir1 = line.GetDir();
const t_vec& dir1 = line1.GetDir();
const t_vec pos = pos0-pos1;
t_mat M = column_matrix({-dir0, dir1});
......@@ -473,9 +487,17 @@ public:
t_vec Mtb = prod_mv(Mt, pos);
t_vec params = prod_mv(MtMinv, Mtb);
t = params[0];
return true;
// get parameters
t0 = params[0];
T t1 = params[1];
if(pt1) *pt1 = t1;
// get closest points between the two lines
t_vec vecInters0 = (*this)(t0);
t_vec vecInters1 = line1(t1);
return veclen(vecInters1-vecInters0) <= eps;
}
......@@ -501,6 +523,7 @@ public:
return true;
}
/**
* middle perpendicular plane (in 3d)
*/
......@@ -586,9 +609,6 @@ bool intersect_line_poly(const Line<T>& line,
// is intersection point within polygon?
const t_vec vecFaceCentre = mean_value(vertPoly);
//std::ostringstream ostr;
//ostr << "intersect: " << vecIntersect << ", face centre: " << vecFaceCentre << "\n";
for(std::size_t iVert = 0; iVert < vertPoly.size(); ++iVert)
{
std::size_t iNextVert = iVert < (vertPoly.size()-1) ? iVert+1 : 0;
......@@ -604,9 +624,6 @@ bool intersect_line_poly(const Line<T>& line,
if(planeEdge.GetDist(vecIntersect) < -eps)
return false;
//ostr << "Face " << iVert << ": " << vecEdgeCentre << ", " << vecNorm << ", "
// << planeEdge.GetDist(vecIntersect) << "\n";
}
return true;
......@@ -740,7 +757,6 @@ t_vec get_face_normal(const t_cont<t_vec>& vecVerts, t_vec vecCentre,
if(inner(vecNorm, vecCentreToFace) < T(0))
vecNorm = -vecNorm;
//tl::log_debug("vec = ", vecCentreToFace, ",\tnorm = ", vecNorm);
return vecNorm;
}
......@@ -799,7 +815,7 @@ t_cont<t_cont<t_vec>> verts_to_polyhedron(
t_cont<t_vec>& vecPoly = vecPolys[iPlane];
// plane already in set?
if(plane.IsOnPlane(vert0, T(10)*eps) &&
if(plane.IsOnPlane(vert0, T(10)*eps) &&
plane.IsOnPlane(vert1, T(10)*eps) &&
plane.IsOnPlane(vert2, T(10)*eps))
{
......@@ -864,6 +880,7 @@ public:
using t_vec = ublas::vector<T>;
using t_mat = ublas::matrix<T>;
protected:
// x^T Q x + r x + s = 0
t_mat m_Q = zero_m<t_mat>(3,3);
......@@ -873,26 +890,36 @@ protected:
t_vec m_vecOffs = zero_v<t_vec>(3);
bool m_bQSymm = 1;
protected:
void CheckSymm()
{
m_bQSymm = is_symmetric(m_Q, std::cbrt(get_epsilon<T>()));
}
public:
Quadric() {}
Quadric(std::size_t iDim)
: m_Q(zero_m<t_mat>(iDim,iDim)), m_r(zero_v<t_vec>(iDim))
{ CheckSymm(); }
Quadric(const t_mat& Q) : m_Q(Q)
{ CheckSymm(); }
Quadric(const t_mat& Q, const t_vec& r, T s)
: m_Q(Q), m_r(r), m_s(s)
{ CheckSymm(); }
~Quadric() {}
void SetDim(std::size_t iDim) { m_Q.resize(iDim, iDim, 1); }
const Quadric<T>& operator=(const Quadric<T>& quad)
{
this->m_Q = quad.m_Q;
......@@ -904,6 +931,7 @@ public:
return *this;
}
Quadric<T>& operator=(Quadric<T>&& quad)
{
this->m_Q = std::move(quad.m_Q);
......@@ -915,20 +943,25 @@ public:
return *this;
}
Quadric(const Quadric<T>& quad) { *this = quad; }
Quadric(Quadric<T>&& quad) { *this = quad; }
void SetOffset(const t_vec& vec) { m_vecOffs = vec; }
const t_vec& GetOffset() const { return m_vecOffs; }
const t_mat& GetQ() const { return m_Q; }
const t_vec& GetR() const { return m_r; }
T GetS() const { return m_s; }
void SetQ(const t_mat& Q) { m_Q = Q; CheckSymm(); }
void SetR(const t_vec& r) { m_r = r; }
void SetS(T s) { m_s = s; }
T operator()(const t_vec& _x) const
{
t_vec x = _x-m_vecOffs;
......@@ -940,6 +973,7 @@ public:
return dQ + dR + m_s;
}
/**
* remove column and row iIdx
*/
......@@ -950,6 +984,7 @@ public:
m_vecOffs = remove_elem(m_vecOffs, iIdx);
}
void transform(const t_mat& S)
{
m_Q = tl::transform<t_mat>(m_Q, S, 1);
......
......@@ -43,7 +43,6 @@ T ferromag(const t_cont<t_vec>& vecNeighbours, const t_cont<std::complex<T>>& ve
return T(2)*tS*(J0 - J).real();
}
template<class t_vec = ublas::vector<double>,
typename T = typename t_vec::value_type,
typename t_cont = std::initializer_list<std::tuple<t_vec, std::complex<T>>>>
......@@ -56,10 +55,9 @@ T ferromag(const t_cont& lstNeighbours, const ublas::vector<T>& vecq, T tS)
// ----------------------------------------------------------------------------
/**
* Magnetic form factors
* @desc see: ILL Neutron Data Booklet sec. 2.5-1 (p. 60)
* @desc see: (ILL Neutron Data Booklet), sec. 2.5-1 (p. 60)
* @desc also see: https://www.ill.eu/sites/ccsl/ffacts/
*/
template<class T=double, template<class...> class t_vec=std::initializer_list>
......@@ -75,7 +73,6 @@ T j0_avg(T Q, const t_vec<T>& A, const t_vec<T>& a)
return tl::formfact<T, std::vector>(Q, vecA, vecB, c);
}
template<class T=double, template<class...> class t_vec=std::initializer_list>
T j2_avg(T Q, const t_vec<T>& A, const t_vec<T>& a)
{
......@@ -83,7 +80,6 @@ T j2_avg(T Q, const t_vec<T>& A, const t_vec<T>& a)
return j0_avg<T, t_vec>(Q, A, a) * s * s;
}
template<class T=double, template<class...> class t_vec=std::initializer_list>
T mag_formfact(T Q, T L, T S,
const t_vec<T>& A0, const t_vec<T>& a0,
......@@ -92,7 +88,6 @@ T mag_formfact(T Q, T L, T S,
return (L+T(2)*S) * j0_avg<T, t_vec>(Q, A0, a0) * L * j2_avg<T, t_vec>(Q, A2, a2);
}
/**
* form factor for transition metals (d orbitals, weak LS, spin-only)
* @desc see: (Squires 2012), p. 138
......@@ -109,7 +104,6 @@ std::tuple<T,T,T> mag_formfact_d(T Q, T g,
return std::tuple<T,T,T>(j0, j2, j0 + (T(1)-T(2)/g)*j2);
}
/**
* form factor for rare earths (f orbitals, strong LS, jj)
* @desc see: (Squires 2012), p. 139
......
This diff is collapsed.
......@@ -48,7 +48,6 @@ namespace tl
return s_funcs.at(wstr_to_str(strName))(t);
}
// real functions with two parameters
template<class t_str, class t_val,
typename std::enable_if<std::is_floating_point<t_val>::value>::type* =nullptr>
......@@ -63,14 +62,12 @@ namespace tl
return s_funcs.at(wstr_to_str(strName))(t1, t2);
}
// real constants
template<class t_str, class t_val,
typename std::enable_if<std::is_floating_point<t_val>::value>::type* =nullptr>
t_val get_const(const t_str& strName)
{
static const tl::t_energy_si<t_val> meV = get_one_meV<t_val>();
//static const tl::t_time_si<t_val> picosec = tl::get_one_picosecond<t_val>();
static const tl::t_time_si<t_val> sec = tl::get_one_second<t_val>();
static const tl::t_temperature_si<t_val> kelvin = tl::get_one_kelvin<t_val>();
static const tl::t_action_si<t_val> hbar = tl::get_hbar<t_val>();
......@@ -79,8 +76,8 @@ namespace tl
static const std::unordered_map</*t_str*/std::string, t_val> s_consts =
{
{ "pi", get_pi<t_val>() },
{ "hbar", t_val(hbar/meV/sec) }, // hbar in [meV s]
{ "kB", t_val(kB/meV*kelvin) }, // kB in [meV / K]
{ "hbar", t_val(hbar/meV/sec) }, // hbar in [meV s]
{ "kB", t_val(kB/meV*kelvin) }, // kB in [meV / K]
};
return s_consts.at(wstr_to_str(strName));
......@@ -100,7 +97,6 @@ namespace tl
return s_funcs.at(wstr_to_str(strName))(t);
}
// alternative: int functions with two parameters
template<class t_str, class t_val,
typename std::enable_if<std::is_integral<t_val>::value>::type* =nullptr>
......@@ -108,14 +104,13 @@ namespace tl
{
static const std::unordered_map</*t_str*/std::string, std::function<t_val(t_val, t_val)>> s_funcs =
{
{ "pow", [t1, t2](t_val t1, t_val t2) -> t_val { return t_val(std::pow(t1, t2)); } },
{ "mod", [t1, t2](t_val t1, t_val t2) -> t_val { return t1%t2; } },
{ "pow", [](t_val _t1, t_val _t2) -> t_val { return t_val(std::pow(_t1, _t2)); } },
{ "mod", [](t_val _t1, t_val _t2) -> t_val { return _t1 % _t2; } },
};
return s_funcs.at(wstr_to_str(strName))(t1, t2);
}
// alternative: int constants
template<class t_str, class t_val,
typename std::enable_if<std::is_integral<t_val>::value>::type* =nullptr>
......@@ -137,7 +132,6 @@ namespace tl
namespace asc = boost::spirit::ascii;
namespace ph = boost::phoenix;
template<class t_str, class t_val, class t_skip=asc::space_type>
class ExprGrammar : public qi::grammar<
typename t_str::const_iterator, t_val(), t_skip>
......@@ -233,7 +227,6 @@ namespace tl
~ExprGrammar() {}
};
template<class t_str/*=std::string*/, class t_val/*=double*/>
std::pair<bool, t_val> eval_expr(const t_str& str) noexcept
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment