SIRIUS 7.5.0
Electronic structure library and applications
lattice.hpp
Go to the documentation of this file.
1// Copyright (c) 2013-2021 Anton Kozhevnikov, Thomas Schulthess
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
5// the following conditions are met:
6//
7// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
8// following disclaimer.
9// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
10// and the following disclaimer in the documentation and/or other materials provided with the distribution.
11//
12// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
13// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
14// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
15// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
16// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
17// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
18// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19
20/** \file lattice.hpp
21 *
22 * \brief Crystal lattice functions.
23 */
24
25#include <algorithm>
26#include "core/r3/r3.hpp"
27#include "core/rte/rte.hpp"
28
29#ifndef __LATTICE_HPP__
30#define __LATTICE_HPP__
31
32namespace sirius {
33
34/// Compute a metric tensor.
35inline auto
37{
38 return dot(transpose(lat_vec__), lat_vec__);
39}
40
41/// Compute error of the symmetry-transformed metric tensor.
42inline double
44{
45 auto mt = metric_tensor(lat_vec__);
46
47 double diff{0};
48 auto mt1 = dot(dot(transpose(R__), mt), R__);
49 for (int i: {0, 1, 2}) {
50 for (int j: {0, 1, 2}) {
51 diff = std::max(diff, std::abs(mt1(i, j) - mt(i, j)));
52 }
53 }
54 return diff;
55}
56
57inline auto
58find_lat_sym(r3::matrix<double> const& lat_vec__, double tol__, double* mt_error__ = nullptr)
59{
60 std::vector<r3::matrix<int>> lat_sym;
61
62 auto r = {-1, 0, 1};
63
64 double mt_error_max{0};
65
66 for (int i00: r) {
67 for (int i01: r) {
68 for (int i02: r) {
69 for (int i10: r) {
70 for (int i11: r) {
71 for (int i12: r) {
72 for (int i20: r) {
73 for (int i21: r) {
74 for (int i22: r) {
75 /* build a trial symmetry operation */
76 r3::matrix<int> R({{i00, i01, i02}, {i10, i11, i12}, {i20, i21, i22}});
77 /* valid symmetry operation has a determinant of +/- 1 */
78 if (std::abs(R.det()) == 1) {
79 auto mt_error = metric_tensor_error(lat_vec__, R);
80 mt_error_max = std::max(mt_error_max, mt_error);
81 /* metric tensor should be invariant under symmetry operation */
82 if (mt_error < tol__) {
83 lat_sym.push_back(R);
84 }
85 }
86 }
87 }
88 }
89 }
90 }
91 }
92 }
93 }
94 }
95
96 if (mt_error__) {
97 *mt_error__ = mt_error_max;
98 }
99
100 if (lat_sym.size() == 0 || lat_sym.size() > 48) {
101 std::stringstream s;
102 s << "wrong number of lattice symmetries: " << lat_sym.size() << std::endl
103 << " lattice vectors : " << lat_vec__ << std::endl
104 << " tolerance : " << tol__ << std::endl
105 << " metric tensor error : " << mt_error_max;
106 RTE_THROW(s);
107 }
108
109 /* check if the set of symmetry operations is a group */
110 for (auto& R1: lat_sym) {
111 for (auto& R2: lat_sym) {
112 auto R3 = r3::dot(R1, R2);
113 if (std::find(lat_sym.begin(), lat_sym.end(), R3) == lat_sym.end()) {
114 std::stringstream s;
115 s << "lattice symmetries do not form a group" << std::endl;
116 for (auto& R: lat_sym) {
117 s << " sym.op : " << R << ", metric tensor error : " << metric_tensor_error(lat_vec__, R) << std::endl;
118 }
119 s << "R1 : " << R1 << std::endl;
120 s << "R2 : " << R2 << std::endl;
121 s << "R1 * R2 : " << R3 << " is not in group" << std::endl;
122 s << "metric tensor tolerance : " << tol__;
123 RTE_THROW(s);
124 }
125 }
126 }
127
128 return lat_sym;
129}
130
131}
132
133#endif
auto transpose(matrix< T > src)
Return transpose of the matrix.
Definition: r3.hpp:445
Namespace of the SIRIUS library.
Definition: sirius.f90:5
auto metric_tensor(r3::matrix< double > const &lat_vec__)
Compute a metric tensor.
Definition: lattice.hpp:36
double metric_tensor_error(r3::matrix< double > const &lat_vec__, r3::matrix< int > const &R__)
Compute error of the symmetry-transformed metric tensor.
Definition: lattice.hpp:43
Simple classes and functions to work with vectors and matrices of the R^3 space.
Eror and warning handling during run-time execution.