72 lines
1.9 KiB
C++
72 lines
1.9 KiB
C++
// Copyright (2019-2023) Paul Scherrer Institute
|
|
|
|
#include <cmath>
|
|
#include "CrystalLattice.h"
|
|
|
|
#define DEG_TO_RAD static_cast<float>(M_PI/180.0)
|
|
|
|
CrystalLattice::CrystalLattice() {}
|
|
|
|
CrystalLattice::CrystalLattice(const UnitCell &cell) {
|
|
vec[0] = {cell.a, 0, 0};
|
|
vec[1] = {cell.b * cosf(cell.gamma * DEG_TO_RAD), cell.b * sinf(cell.gamma * DEG_TO_RAD), 0};
|
|
float cx = cell.c * cosf(cell.beta * DEG_TO_RAD);
|
|
float cy = cell.c
|
|
* (cosf(cell.alpha * DEG_TO_RAD) - cosf(cell.beta * DEG_TO_RAD) * cosf(cell.gamma * DEG_TO_RAD))
|
|
/ sinf(cell.gamma * DEG_TO_RAD);
|
|
vec[2] = {cx, cy, sqrtf(cell.c*cell.c-cx*cx-cy*cy)};
|
|
}
|
|
|
|
CrystalLattice CrystalLattice::ReciprocalLattice() const {
|
|
Eigen::Matrix3f m = GetEigenMatrix().transpose().inverse();
|
|
return {m};
|
|
}
|
|
|
|
UnitCell CrystalLattice::GetUnitCell() {
|
|
UnitCell cell;
|
|
cell.a = vec[0].Length();
|
|
cell.b = vec[1].Length();
|
|
cell.c = vec[2].Length();
|
|
cell.alpha = angle_deg(vec[1], vec[2]);
|
|
cell.beta = angle_deg(vec[0], vec[2]);
|
|
cell.gamma = angle_deg(vec[0], vec[1]);
|
|
return cell;
|
|
}
|
|
|
|
Coord &CrystalLattice::Vec0() {
|
|
return vec[0];
|
|
}
|
|
|
|
Coord &CrystalLattice::Vec1() {
|
|
return vec[1];
|
|
}
|
|
|
|
Coord &CrystalLattice::Vec2() {
|
|
return vec[2];
|
|
}
|
|
|
|
Eigen::Matrix3f CrystalLattice::GetEigenMatrix() const {
|
|
Eigen::Matrix3f m;
|
|
m << vec[0].x, vec[0].y, vec[0].z,
|
|
vec[1].x, vec[1].y, vec[1].z,
|
|
vec[2].x, vec[2].y, vec[2].z;
|
|
return m;
|
|
}
|
|
|
|
CrystalLattice::CrystalLattice(const Eigen::Matrix3f &m) {
|
|
for (int i = 0; i < 3; i++) {
|
|
vec[i].x = m(i, 0);
|
|
vec[i].y = m(i, 1);
|
|
vec[i].z = m(i, 2);
|
|
}
|
|
}
|
|
|
|
void CrystalLattice::Save(std::vector<float> &output) {
|
|
output.resize(9);
|
|
for (int i = 0; i < 3; i++) {
|
|
output[3 * i + 0] = vec[i].x;
|
|
output[3 * i + 1] = vec[i].y;
|
|
output[3 * i + 2] = vec[i].z;
|
|
}
|
|
}
|