Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
Lattices_NEW/PeriodicLatticeInterpolant.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_PeriodicLatticeInterpolant_cpp_
9#define model_PeriodicLatticeInterpolant_cpp_
10
11#include <PeriodicLatticeInterpolant.h>
12
13namespace model
14{
15
16
17
18
19 /**********************************************************************/
20 template <int dim>
21 std::vector<typename PeriodicLatticeInterpolant<dim>::MatrixDim> PeriodicLatticeInterpolant<dim>::getSymMatrices(const int &rotSymm,
22 const std::vector<Eigen::Matrix<double, dim, 1>> &mirSymm)
23 {
24 std::vector<MatrixDim> temp;
25 for (int k = 0; k < rotSymm; ++k)
26 { // apply rotations
27 const double theta(k * 2.0 * M_PI / rotSymm);
28 const double c(cos(theta));
29 const double s(sin(theta));
30 temp.push_back((MatrixDim() << c, -s, s, c).finished());
31 }
32
33 for (const auto &N : mirSymm)
34 { // apply mirSymm to each existing entry in temp
35 const double nNorm(N.norm());
36 if (nNorm > FLT_EPSILON)
37 {
38 const VectorDim n(N / nNorm);
39 const auto temp1 = temp;
40 for (const auto &m : temp1)
41 {
42 temp.push_back(m * (MatrixDim::Identity() - 2.0 * n * n.transpose())); // mirror symm
43 }
44 }
45 }
46 return temp;
47 }
48
49 /**********************************************************************/
50 template <int dim>
51 Eigen::MatrixXd PeriodicLatticeInterpolant<dim>::getSinCosCoeffs(const Eigen::Matrix<double, Eigen::Dynamic, dim + 1> &f) const
52 {
59 Eigen::MatrixXd M(Eigen::MatrixXd::Zero(f.rows(), 2 * waveVectors.rows())); // sine and cosine coeffs for each row
60 Eigen::MatrixXd V(Eigen::MatrixXd::Zero(f.rows(), 1));
61 for (int i = 0; i < f.rows(); i++)
62 {
63 for (int j = 0; j < waveVectors.rows(); j++)
64 {
65 const auto sc(sinKXcosKX(j, f.template block<1, dim>(i, 0)));
66 M(i, 2 * j) = sc.first;
67 M(i, 2 * j + 1) = sc.second;
68 }
69 V(i) = f(i, 2);
70 }
71
72 // Some of the S and C coefficients may be identically zero. This means that some columns of M may be vanishing, we need to remove those colums
73 std::vector<int> nonZcols;
74 for (int j = 0; j < M.cols(); ++j)
75 {
76 if (M.col(j).squaredNorm() > FLT_EPSILON)
77 {
78 nonZcols.push_back(j);
79 }
80 }
81
82 Eigen::MatrixXd M1(M.rows(), nonZcols.size());
83 for (size_t j = 0; j < nonZcols.size(); ++j)
84 {
85 M1.col(j) = M.col(nonZcols[j]);
86 }
87
88 const Eigen::JacobiSVD<Eigen::MatrixXd> svd(M1);
89
90 // Solve
91 if (M1.rows() == M1.cols() && svd.rank() == M1.rows())
92 {
93 const double cond(svd.singularValues()(0) / svd.singularValues()(svd.singularValues().size() - 1));
94 if (cond > 1.0e3)
95 {
96 std::cout << "M1=\n"
97 << M1 << std::endl;
98 std::cout << "rank=" << svd.rank() << std::endl;
99 std::cout << "cond=" << cond << std::endl;
100 assert(cond < 1.0e3 && "Bad condition number");
101 }
102 const Eigen::VectorXd x(M1.lu().solve(V));
103
104 Eigen::VectorXd x1(Eigen::VectorXd::Zero(M.cols()));
105 for (size_t j = 0; j < nonZcols.size(); ++j)
106 {
107 x1(nonZcols[j]) = x(j);
108 }
109 return Eigen::Map<Eigen::MatrixXd>(x1.data(), 2, x1.rows() / 2); // reshape
110 }
111 else
112 {
113 std::cout << "M=\n"
114 << M << std::endl;
115 std::cout << "M1=\n"
116 << M1 << std::endl;
117 std::cout << "M1 has size " << M1.rows() << "x" << M1.cols() << ",and rank=" << svd.rank() << std::endl;
118 assert(false && "M1 MUST BE SQUARE AND FULL RANK");
119 return Eigen::MatrixXd::Zero(1, 1);
120 }
121 }
122
123 /**********************************************************************/
124 template <int dim>
125 std::pair<double, double> PeriodicLatticeInterpolant<dim>::sinKXcosKX(const int &r, const VectorDim &x) const
126 {
127 std::pair<double, double> sc(0.0, 0.0);
128 for (const auto &R : symMatrices)
129 {
130 const double KdotX(waveVectors.row(r).dot(R * x));
131 sc.first += sin(KdotX);
132 sc.second += cos(KdotX);
133 }
134 return sc;
135 }
136
137 /**********************************************************************/
138 template <int dim>
140 const Eigen::Matrix<double, Eigen::Dynamic, dim> &waveVectors_in,
141 const Eigen::Matrix<double, Eigen::Dynamic, dim + 1> &f,
142 const int &rotSymm,
143 const std::vector<Eigen::Matrix<double, dim, 1>> &N) : // rotSymm only works for 2d, in 3d we need to prescride axis and n-fold symm
144 /* init */ A(A_in)
145 /* init */,
146 B(2.0 * M_PI * A.inverse().transpose())
147 /* init */,
148 waveVectors((B * waveVectors_in.transpose()).transpose())
149 /* init */,
150 symMatrices(getSymMatrices(rotSymm, N))
151 /* init */,
152 sinCosCoeffs(getSinCosCoeffs(f).transpose())
153 {
156 }
157
158 /**********************************************************************/
159 template <int dim>
160 double PeriodicLatticeInterpolant<dim>::operator()(const VectorDim &x) const
161 {
162 double temp(0.0);
163 for (int r = 0; r < waveVectors.rows(); ++r)
164 {
165 const auto sc(sinKXcosKX(r, x));
166 temp += sinCosCoeffs(r, 0) * sc.first + sinCosCoeffs(r, 1) * sc.second;
167 }
168 return temp;
169 }
170
171template struct PeriodicLatticeInterpolant<2>;
172} // end namespace
173#endif
Eigen::Matrix3d M
Eigen::Vector3d V
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
c
Definition int_R.m:15
function int_R syms a b c u real f
Definition int_R.m:4
x
Definition int_R.m:12
float r
Definition plotLoops.py:41
Eigen::Matrix< double, 3, 1 > VectorDim
Definition pyMoDELib.cxx:66
Eigen::Matrix< double, 3, 3 > MatrixDim
Definition pyMoDELib.cxx:67
Eigen::MatrixXd getSinCosCoeffs(const Eigen::Matrix< double, Eigen::Dynamic, dim+1 > &f) const
PeriodicLatticeInterpolant(const MatrixDim &A_in, const Eigen::Matrix< double, Eigen::Dynamic, dim > &waveVectors_in, const Eigen::Matrix< double, Eigen::Dynamic, dim+1 > &f, const int &rotSymm, const std::vector< Eigen::Matrix< double, dim, 1 > > &N)
std::pair< double, double > sinKXcosKX(const int &r, const VectorDim &x) const
static std::vector< MatrixDim > getSymMatrices(const int &rotSymm, const std::vector< Eigen::Matrix< double, dim, 1 > > &mirSymm)
int j
int k
int i
vertex temp
void t struct mesh * m