109 lines
3.8 KiB
C++
109 lines
3.8 KiB
C++
// Copyright (2019-2022) Paul Scherrer Institute
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
#include <catch2/catch.hpp>
|
|
#include "../writer/HDF5Objects.h"
|
|
#include "../indexing/IndexerWrapper.h"
|
|
|
|
#define make_unit_cell(a1,a2,a3,a4,a5,a6) UnitCell{.a = a1, .b = a2, .c = a3, .alpha = a4, .beta = a5, .gamma = a6}
|
|
|
|
TEST_CASE("CrystalLattice") {
|
|
CrystalLattice l(make_unit_cell(50,60,80, 90, 90, 90));
|
|
REQUIRE(l.Vec0().Length() == Approx(50));
|
|
REQUIRE(l.Vec1().Length() == Approx(60));
|
|
REQUIRE(l.Vec2().Length() == Approx(80));
|
|
REQUIRE(angle_deg(l.Vec0(), l.Vec2()) == 90);
|
|
REQUIRE(angle_deg(l.Vec0(), l.Vec1()) == 90);
|
|
REQUIRE(angle_deg(l.Vec1(), l.Vec2()) == 90);
|
|
|
|
l = CrystalLattice(make_unit_cell(30, 40, 70, 90, 95, 90));
|
|
REQUIRE(l.Vec0().Length() == Approx(30));
|
|
REQUIRE(l.Vec1().Length() == Approx(40));
|
|
REQUIRE(l.Vec2().Length() == Approx(70));
|
|
REQUIRE(angle_deg(l.Vec0(), l.Vec2()) == 95);
|
|
REQUIRE(angle_deg(l.Vec0(), l.Vec1()) == 90);
|
|
REQUIRE(angle_deg(l.Vec1(), l.Vec2()) == 90);
|
|
|
|
l = CrystalLattice(make_unit_cell(45, 45, 70, 90, 90, 120));
|
|
REQUIRE(l.Vec0().Length() == Approx(45));
|
|
REQUIRE(l.Vec1().Length() == Approx(45));
|
|
REQUIRE(l.Vec2().Length() == Approx(70));
|
|
REQUIRE(angle_deg(l.Vec0(), l.Vec2()) == Approx(90));
|
|
REQUIRE(angle_deg(l.Vec0(), l.Vec1()) == Approx(120));
|
|
REQUIRE(angle_deg(l.Vec1(), l.Vec2()) == Approx(90));
|
|
}
|
|
|
|
TEST_CASE("CrystalLattice_ReciprocalLattice") {
|
|
CrystalLattice l(make_unit_cell(50,60,80, 78, 80, 120));
|
|
CrystalLattice rl = l.ReciprocalLattice();
|
|
|
|
REQUIRE(l.Vec0() * rl.Vec0() == Approx(1.0));
|
|
REQUIRE(l.Vec0() * rl.Vec1() < 1e-5);
|
|
REQUIRE(l.Vec0() * rl.Vec2() < 1e-5);
|
|
|
|
REQUIRE(l.Vec1() * rl.Vec0() < 1e-5);
|
|
REQUIRE(l.Vec1() * rl.Vec1() == Approx(1.0));
|
|
REQUIRE(l.Vec1() * rl.Vec2() < 1e-5);
|
|
|
|
REQUIRE(l.Vec2() * rl.Vec0() < 1e-5);
|
|
REQUIRE(l.Vec2() * rl.Vec1() < 1e-5);
|
|
REQUIRE(l.Vec2() * rl.Vec2() == Approx(1.0));
|
|
}
|
|
|
|
TEST_CASE("CrystalLattice_EigenMatrix") {
|
|
CrystalLattice l1(make_unit_cell(50,60,80, 78, 80, 120));
|
|
auto m = l1.GetEigenMatrix();
|
|
CrystalLattice l2(m);
|
|
REQUIRE(l2.Vec0().x == Approx(l1.Vec0().x));
|
|
REQUIRE(l2.Vec1().y == Approx(l1.Vec1().y));
|
|
REQUIRE(l2.Vec2().x == Approx(l1.Vec2().x));
|
|
}
|
|
|
|
inline double round_err(double x) {
|
|
return std::abs(x - std::round(x));
|
|
}
|
|
|
|
TEST_CASE("FastFeedbackIndexer","[Indexing]") {
|
|
std::vector<Coord> hkl;
|
|
for (int i = 1; i < 7; i++)
|
|
for (int j = 1; j<6; j++)
|
|
for (int k = 1; k < 4; k++)
|
|
hkl.emplace_back(i,j,k);
|
|
|
|
std::vector<UnitCell> cells;
|
|
cells.emplace_back(make_unit_cell(30,40,50,90,90,90));
|
|
cells.emplace_back(make_unit_cell(80,80,90,90,90,120));
|
|
cells.emplace_back(make_unit_cell(40,45,80,90,82.5,90));
|
|
|
|
for (auto &c: cells) {
|
|
CrystalLattice l(c);
|
|
CrystalLattice recip_l = l.ReciprocalLattice();
|
|
|
|
std::vector<Coord> recip;
|
|
recip.reserve(hkl.size());
|
|
for (const auto &i: hkl)
|
|
recip.emplace_back(i.x * recip_l.Vec0() + i.y * recip_l.Vec1() + i.z * recip_l.Vec2());
|
|
|
|
IndexerWrapper wrapper;
|
|
|
|
wrapper.Setup(c);
|
|
auto ret = wrapper.Run(recip);
|
|
REQUIRE(!ret.empty());
|
|
|
|
//auto uc = ret[0].GetUnitCell();
|
|
//REQUIRE(c.a == Approx(uc.a));
|
|
//REQUIRE(c.b == Approx(uc.b));
|
|
//REQUIRE(c.c == Approx(uc.c));
|
|
|
|
double err[3] = {0.0, 0.0, 0.0};
|
|
for (const auto &iter: recip) {
|
|
err[0] += round_err(ret[0].Vec0() * iter);
|
|
err[1] += round_err(ret[0].Vec1() * iter);
|
|
err[2] += round_err(ret[0].Vec2() * iter);
|
|
}
|
|
REQUIRE (err[0] < 0.001 * recip.size());
|
|
REQUIRE (err[1] < 0.001 * recip.size());
|
|
REQUIRE (err[2] < 0.001 * recip.size());
|
|
}
|
|
}
|