18#include <boost/lexical_cast.hpp>
26UnitCell::UnitCell() : da(6), ra(6), errorda(6), G(3, 3), Gstar(3, 3), B(3, 3), ModHKL(3, 3), errorModHKL(3, 3) {
27 da[0] =
da[1] =
da[2] = 1.;
28 da[3] =
da[4] =
da[5] = M_PI_2;
39 : da(6), ra(6), errorda(6), G(3, 3), Gstar(3, 3), B(3, 3), ModHKL(3, 3), errorModHKL(3, 3) {
44 da[3] =
da[4] =
da[5] = M_PI_2;
55UnitCell::UnitCell(
double _a,
double _b,
double _c,
double _alpha,
double _beta,
double _gamma,
const int angleunit)
56 : da(6), ra(6), errorda(6), G(3, 3), Gstar(3, 3), B(3, 3), ModHKL(3, 3), errorModHKL(3, 3) {
96 throw(std::invalid_argument(
"lattice parameter index can change from 0 to 2 "));
267 double delta_V_alphaV = 0.0;
273 delta_V_alphaV = (Va2 - Va1) / V;
276 double delta_V_betaV = 0.0;
282 delta_V_betaV = (Va2 - Va1) / V;
285 double delta_V_gammaV = 0.0;
291 delta_V_gammaV = (Va2 - Va1) / V;
294 return V * sqrt(std::pow(
errora() /
a(), 2) + std::pow(
errorb() /
b(), 2) + std::pow(
errorc() /
c(), 2) +
295 std::pow(delta_V_alphaV, 2) + std::pow(delta_V_betaV, 2) + std::pow(delta_V_gammaV, 2));
303void UnitCell::set(
double _a,
double _b,
double _c,
double _alpha,
double _beta,
double _gamma,
const int angleunit) {
325void UnitCell::setError(
double _aerr,
double _berr,
double _cerr,
double _alphaerr,
double _betaerr,
double _gammaerr,
326 const int angleunit) {
353void UnitCell::setModHKL(
double _dh1,
double _dk1,
double _dl1,
double _dh2,
double _dk2,
double _dl2,
double _dh3,
354 double _dk3,
double _dl3) {
391 double _dl2err,
double _dh3err,
double _dk3err,
double _dl3err) {
444 ModHKL[0][0] = newModVec[0];
445 ModHKL[1][0] = newModVec[1];
446 ModHKL[2][0] = newModVec[2];
454 ModHKL[0][1] = newModVec[0];
455 ModHKL[1][1] = newModVec[1];
456 ModHKL[2][1] = newModVec[2];
464 ModHKL[0][2] = newModVec[0];
465 ModHKL[1][2] = newModVec[1];
466 ModHKL[2][2] = newModVec[2];
718double UnitCell::recAngle(
double h1,
double k1,
double l1,
double h2,
double k2,
double l2,
const int angleunit)
const {
719 V3D Q1(h1, k1, l1), Q2(h2, k2,
l2);
722 E = Q1.scalar_prod(Q2);
723 double temp = E /
dstar(h1, k1, l1) /
dstar(h2, k2,
l2);
745 return sqrt(recvolume);
768 throw std::invalid_argument(
"Invalid angles");
777 G[0][0] =
da[0] *
da[0];
778 G[1][1] =
da[1] *
da[1];
779 G[2][2] =
da[2] *
da[2];
780 G[0][1] =
da[0] *
da[1] * cos(
da[5]);
781 G[0][2] =
da[0] *
da[2] * cos(
da[4]);
782 G[1][2] =
da[1] *
da[2] * cos(
da[3]);
793 throw std::range_error(
"UnitCell not properly initialized");
797 throw std::range_error(
"UnitCell not properly initialized");
806 auto acosThreshold = [](
double x) {
return std::abs(
x) > 1e-15 ? acos(
x) : M_PI_2; };
807 ra[3] = acosThreshold(
Gstar[1][2] /
ra[1] /
ra[2]);
808 ra[4] = acosThreshold(
Gstar[0][2] /
ra[0] /
ra[2]);
809 ra[5] = acosThreshold(
Gstar[0][1] /
ra[0] /
ra[1]);
821 B[0][1] =
ra[1] * cos(
ra[5]);
822 B[0][2] =
ra[2] * cos(
ra[4]);
824 B[1][1] =
ra[1] * sin(
ra[5]);
825 B[1][2] = -
ra[2] * sin(
ra[4]) * cos(
da[3]);
828 B[2][2] = 1. /
da[2];
838 std::ostringstream msg;
839 msg <<
"UnitCell::recalculateFromGstar - Expected a 3x3 matrix but was "
842 throw std::invalid_argument(msg.str());
845 if (NewGstar[0][0] * NewGstar[1][1] * NewGstar[2][2] <= 0.)
846 throw std::invalid_argument(
"NewGstar");
851 da[0] = sqrt(
G[0][0]);
852 da[1] = sqrt(
G[1][1]);
853 da[2] = sqrt(
G[2][2]);
854 da[3] = acos(
G[1][2] /
da[1] /
da[2]);
855 da[4] = acos(
G[0][2] /
da[0] /
da[2]);
856 da[5] = acos(
G[0][1] /
da[0] /
da[1]);
861 return da == other.da;
867 out <<
"Lattice Parameters:" << std::fixed << std::setprecision(6) << std::setw(12) << unitCell.
a() << std::fixed
868 << std::setprecision(6) << std::setw(12) << unitCell.
b() << std::fixed << std::setprecision(6) << std::setw(12)
869 << unitCell.
c() << std::fixed << std::setprecision(6) << std::setw(12) << unitCell.
alpha() << std::fixed
870 << std::setprecision(6) << std::setw(12) << unitCell.
beta() << std::fixed << std::setprecision(6) << std::setw(12)
871 << unitCell.
gamma() << std::fixed << std::setprecision(6) <<
" " << std::setw(12) << unitCell.
volume();
876 out <<
"\nParameter Errors :" << std::fixed << std::setprecision(6) << std::setw(12) << unitCell.
errora()
877 << std::fixed << std::setprecision(6) << std::setw(12) << unitCell.
errorb() << std::fixed
878 << std::setprecision(6) << std::setw(12) << unitCell.
errorc() << std::fixed << std::setprecision(6)
879 << std::setw(12) << unitCell.
erroralpha() << std::fixed << std::setprecision(6) << std::setw(12)
880 << unitCell.
errorbeta() << std::fixed << std::setprecision(6) << std::setw(12) << unitCell.
errorgamma()
881 << std::fixed << std::setprecision(6) << std::setw(12) << unitCell.
errorvolume();
887 std::ostringstream stream;
888 stream << std::setprecision(9);
890 stream << unitCell.
a() <<
" " << unitCell.
b() <<
" " << unitCell.
c() <<
" " << unitCell.
alpha() <<
" "
891 << unitCell.
beta() <<
" " << unitCell.
gamma();
900 std::vector<double> components;
901 components.reserve(cellTokens.
size());
902 std::transform(cellTokens.
cbegin(), cellTokens.
cend(), std::back_inserter(components),
903 [](
const auto &token) { return boost::lexical_cast<double>(token); });
905 switch (components.size()) {
907 return UnitCell(components[0], components[1], components[2]);
909 return UnitCell(components[0], components[1], components[2], components[3], components[4], components[5]);
911 throw std::runtime_error(
"Failed to parse unit cell input string: " + unitCellString);
Class to implement unit cell of crystals.
double astar() const
Get reciprocal lattice parameter.
double betastar() const
Get reciprocal lattice parameter.
const Kernel::DblMatrix & getB() const
Get the B-matrix.
double alpha() const
Get lattice parameter.
UnitCell()
Default constructor.
double erroralpha(const int angleunit=angDegrees) const
Get lattice parameter error.
void set(double _a, double _b, double _c, double _alpha, double _beta, double _gamma, const int angleunit=angDegrees)
Set lattice parameters.
bool operator==(const UnitCell &other) const
double b2() const
Get reciprocal lattice parameter.
const Kernel::DblMatrix & getGstar() const
Get the reciprocal metric tensor.
std::vector< double > errorda
Error in lattice parameters (in and radians)
double a(int nd) const
Get lattice parameter a1-a3 as function of index (0-2)
int getMaxOrder() const
Get max order.
double c() const
Get lattice parameter.
const Kernel::DblMatrix & getModHKL() const
Get modulation vectors for satellites.
void setModerr3(double _dh3err, double _dk3err, double _dl3err)
Set modulation vectors for satellites.
double getdh(int j) const
Get modulation vectors for satellites.
const Kernel::V3D getVecErr(int j) const
Get errors for modulation vectors for satellites.
Kernel::DblMatrix Binv
Inverse of the B matrix.
double getdk(int j) const
Get modulation vectors for satellites.
double volume() const
Volume of the direct unit-cell.
void setModVec2(double _dh2, double _dk2, double _dl2)
Set modulation vectors for satellites.
double gammastar() const
Get reciprocal lattice parameter.
double alpha2() const
Get lattice parameter.
double a2() const
Get lattice parameter.
bool getCrossTerm() const
Get cross term boolean.
double getdl(int j) const
Get modulation vectors for satellites.
void setModerr1(double _dh1err, double _dk1err, double _dl1err)
Set modulation vectors for satellites.
double d(double h, double k, double l) const
Return d-spacing ( ) for a given h,k,l coordinate.
double errorgamma(const int angleunit=angDegrees) const
Get lattice parameter error.
double getdherr(int j) const
Get error of modulation vectors for satellites.
void setbeta(double _beta, const int angleunit=angDegrees)
Set lattice parameter.
double errorbeta(const int angleunit=angDegrees) const
Get lattice parameter error.
void setErrorc(double _cerr)
Set lattice parameter error.
void setalpha(double _alpha, const int angleunit=angDegrees)
Set lattice parameter.
Kernel::DblMatrix errorModHKL
void setModHKL(double _dh1, double _dk1, double _dl1, double _dh2, double _dk2, double _dl2, double _dh3, double _dk3, double _dl3)
Set modulation vectors for satellites.
double beta() const
Get lattice parameter.
void setError(double _aerr, double _berr, double _cerr, double _alphaerr, double _betaerr, double _gammaerr, const int angleunit=angDegrees)
Set lattice parameter errors.
void setgamma(double _gamma, const int angleunit=angDegrees)
Set lattice parameter.
double bstar() const
Get reciprocal lattice parameter.
double a() const
Get lattice parameter.
void setErrorgamma(double _gammaerr, const int angleunit=angDegrees)
Set lattice parameter error.
void calculateReciprocalLattice()
Private function to calculate reciprocal lattice parameters.
void setErroralpha(double _alphaerr, const int angleunit=angDegrees)
Set lattice parameter error.
std::vector< double > da
Lattice parameter a,b,c,alpha,beta,gamma (in and radians)
std::vector< double > ra
Reciprocal lattice parameters (in and radians)
void setErrorbeta(double _betaerr, const int angleunit=angDegrees)
Set lattice parameter error.
double a3() const
Get lattice parameter.
double beta1() const
Get reciprocal lattice parameter.
virtual void recalculate()
Private function, called at initialization or whenever lattice parameters are changed.
double getdlerr(int j) const
Get error of modulation vectors for satellites.
Kernel::DblMatrix G
Metric tensor.
void setErrorModHKL(const Kernel::DblMatrix &newErrorModHKL)
Set modulation vectors for satellites.
void setModerr(int i, double _dherr, double _dkerr, double _dlerr)
Set modulation vectors for satellites.
const Kernel::DblMatrix & getBinv() const
Get the inverse of the B-matrix.
const Kernel::DblMatrix & getG() const
Get the metric tensor.
Kernel::DblMatrix Gstar
Reciprocal lattice tensor.
void setErrorb(double _berr)
Set lattice parameter error.
bool operator!=(const UnitCell &other) const
double alpha1() const
Get lattice parameter.
void setModVec3(double _dh3, double _dk3, double _dl3)
Set modulation vectors for satellites.
double recVolume() const
Volume of the reciprocal lattice.
void calculateB()
Private function to calculate B matrix.
double b() const
Get lattice parameter.
double getdkerr(int j) const
Get error of modulation vectors for satellites.
double beta3() const
Get reciprocal lattice parameter.
double alphastar() const
Get reciprocal lattice parameter.
void setb(double _b)
Set lattice parameter.
const Kernel::V3D getModVec(int j) const
Get modulation vectors for satellites.
void calculateGstar()
Private function to calculate Gstar matrix.
double errorc() const
Get lattice parameter error.
double dstar(double h, double k, double l) const
Return d*=1/d ( ) for a given h,k,l coordinate.
double b1() const
Get reciprocal lattice parameter.
void setCrossTerm(bool CT)
Set modulation vectors for satellites.
double recAngle(double h1, double k1, double l1, double h2, double k2, double l2, const int angleunit=angDegrees) const
Calculate the angle in degrees or radians between two reciprocal vectors (h1,k1,l1) and (h2,...
double alpha3() const
Get lattice parameter.
double errorvolume() const
Get lattice parameter error.
virtual void recalculateFromGstar(const Kernel::Matrix< double > &NewGstar)
Recalculate lattice from reciprocal metric tensor (Gstar=transpose(UB)*UB)
void setErrora(double _aerr)
Set lattice parameter error.
void setModVec1(double _dh1, double _dk1, double _dl1)
Set modulation vectors for satellites.
void setc(double _c)
Set lattice parameter.
void setMaxOrder(int MaxO)
Set modulation vectors for satellites.
double beta2() const
Get reciprocal lattice parameter.
double cstar() const
Get reciprocal lattice parameter.
Kernel::DblMatrix B
B matrix for a right-handed coordinate system, in Busing-Levy convention.
double a1() const
Get lattice parameter.
void setModerr2(double _dh2err, double _dk2err, double _dl2err)
Set modulation vectors for satellites.
double b3() const
Get reciprocal lattice parameter.
double gamma() const
Get lattice parameter.
double errora() const
Get lattice parameter error.
void seta(double _a)
Set lattice parameter.
double errorb() const
Get lattice parameter error.
T determinant() const
Calculate the determinant.
T Invert()
LU inversion routine.
size_t numRows() const
Return the number of rows in the matrix.
size_t numCols() const
Return the number of columns in the matrix.
@ TOK_IGNORE_EMPTY
ignore empty tokens
std::size_t size() const noexcept
Get the total number of tokens.
ConstIterator cend() const
Const iterator referring to the past-the-end element in the container.
ConstIterator cbegin() const
Const iterator referring to first element in the container.
double norm() const noexcept
constexpr double deg2rad
Defines units/enum for Crystal work.
constexpr double rad2deg
Radians to degrees conversion factor.
MANTID_GEOMETRY_DLL UnitCell strToUnitCell(const std::string &unitCellString)
MANTID_GEOMETRY_DLL std::string unitCellToStr(const UnitCell &unitCell)
MANTID_GEOMETRY_DLL std::ostream & operator<<(std::ostream &stream, const PointGroup &self)
Returns a streamed representation of the PointGroup object.