Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
DSCL.cpp
Go to the documentation of this file.
1/* This file is part of PIL, the Particle Interaction Library.
2 *
3 *
4 * MODEL is distributed without any warranty under the
5 * GNU General Public License (GPL) v2 <http://www.gnu.org/licenses/>.
6 */
7
8#ifndef model_DSCL_cpp_
9#define model_DSCL_cpp_
10
11#include <LatticeModule.h> // FLT_EPSILON
12#include <DSCL.h>
13
14namespace model
15{
21 /**********************************************************************/
22 template <int dim>
23 typename DSCL<dim>::MatrixDimD DSCL<dim>::getLatticeBasis(const LatticeTransitionMatrix<dim> &rm,
24 const typename DSCL<dim>::LatticeType &A,
25 const typename DSCL<dim>::LatticeType &B,
26 const bool &useRLLL)
27 {
28 // The transition matrix is T=P/sigma, where P=rm.integerMatrix is
29 // an integer matrix and sigma=rm.sigma is an integer
30 // The integer matrix P can be decomposed as P=X*D*Y using the Smith decomposition.
31 // X and Y are unimodular, and D is diagonal with D(k,k) dividing D(k+1,k+1)
32 // The decomposition also computes the matices U and V such that D=U*P*V
33 SmithDecomposition<dim> sd(rm.integerMatrix);
34
35 // From T=inv(A)*B=P/sigma=X*D*Y/sigma=X*D*inv(V)/sigma, we have
36 // B1*(sigma*I)=A1*D
37 // where
38 // B1=B*V
39 // A1=A*X
40 // Since V and X are unimodular matrices, B1 and A1 are new bases
41 // of the lattices B and A, respectively. Moreover, since
42 // (sigma*I) and D are diagonal, the columns of B1 and A1 are
43 // proportional, with rational proportionality factors different for each column.
44 // For example, columns "i" read
45 // b1_i*sigma=a1_i*D(i,i)
46 // Therefore, the i-th primitive vectors of the DSCL is
47 // c_i=b1_i*sigma/gcd(sigma,D(i,i))=a1_i*D(i,i)/gcd(sigma,D(i,i))
48 // or, in matrix form
49 // C=B1*N=A1*M, that is
50 // C=B*V*N=A*X*M
51 // where M=diag(D(i,i)/gcd(sigma,D(i,i))) and
52 // N=diag(sigma/gcd(sigma,D(i,i))) and
53
54 MatrixInt M(MatrixInt::Identity());
55 MatrixInt N(MatrixInt::Identity());
56 for (int i = 0; i < dim; ++i)
57 {
58 const IntValueType &dii = sd.matrixD()(i, i);
59 M(i, i) = dii / rm.gcd(rm.sigma, dii);
60 N(i, i) = rm.sigma / rm.gcd(rm.sigma, dii);
61 }
62
63 const MatrixDimD D1 = A.latticeBasis * sd.matrixX().template cast<double>() * N.template cast<double>().inverse();
64 const MatrixDimD D2 = B.latticeBasis * sd.matrixV().template cast<double>() * M.template cast<double>().inverse();
65 assert((D1 - D2).norm() < FLT_EPSILON && "DSCL calculation failed.");
66
67 if (useRLLL)
68 {
69 return RLLL(0.5 * (D1 + D2), 0.75).reducedBasis();
70 }
71 else
72 {
73 return 0.5 * (D1 + D2);
74 }
75 }
76
77 /**********************************************************************/
78 template <int dim>
79 DSCL<dim>::DSCL(const typename DSCL<dim>::LatticeType& A_in,
80 const typename DSCL<dim>::LatticeType& B_in,
81 const bool& useRLLL) :
82 /* init */ LatticeTransitionMatrix<dim>(A_in,B_in)
83 /* init */,Lattice<dim>(getLatticeBasis(*this,A_in,B_in,useRLLL),MatrixDimD::Identity())
84 {
85 // update(useRLLL);
86
87 if (true)
88 { //verify that A and B are multiples of DSCL
89
90 const MatrixDimD tempA(this->reciprocalBasis.transpose() * A_in.latticeBasis);
91 assert((tempA - tempA.array().round().matrix()).norm() < FLT_EPSILON && "A is not a multiple of DSCL");
92
93 const MatrixDimD tempB(this->reciprocalBasis.transpose() * B_in.latticeBasis);
94 assert((tempB - tempB.array().round().matrix()).norm() < FLT_EPSILON && "B is not a multiple of DSCL");
95 }
96 }
97
98 template class DSCL<3>;
99
100}
101#endif
Eigen::Matrix3d M
DSCL(const LatticeType &A_in, const LatticeType &B_in, const bool &useRLLL=true)
Definition DSCL.cpp:79
const MatrixDimD latticeBasis
Lattice(const MatrixDimD &A, const MatrixDimD &Q)
const MatrixDimD reciprocalBasis
const MatrixType & reducedBasis() const
initial point of the source segment B
function infiniteDisplacement syms Ax Ay Az Bx By Bz qx qy qz u L x y z real A
LatticeTransitionMatrix(const LatticeType &A_in, const LatticeType &B_in)
int i