Feellgood
tetra.h
Go to the documentation of this file.
1 #ifndef tetra_h
2 #define tetra_h
3 
9 #include <set>
10 
11 #include "absorbing_ends.h"
12 #include "triangle.h"
13 #include "node.h"
14 #include "time_integration.h"
15 #include "element.h"
16 
20 namespace Tetra
21  {
24 constexpr double epsilon = EPSILON;
25 
26 constexpr int N = 4;
28 #if ONE_GAUSS_POINT
29  constexpr int NPI = 1;
32  constexpr double A = 1. / 4.;
33  constexpr double u[NPI] = {A};
34  constexpr double v[NPI] = {A};
35  constexpr double w[NPI] = {A};
36  constexpr double pds[NPI] = {1./6.};
40  constexpr double a[N][NPI] = {{1. - u[0] - v[0] - w[0]},
41  {u[0]},
42  {v[0]},
43  {w[0]}};
44 
46  const Eigen::Matrix<double,N,NPI> eigen_a = (Eigen::MatrixXd(N,NPI) << a[0][0],
47  a[1][0],
48  a[2][0],
49  a[3][0] ).finished();
50 #else
51  constexpr int NPI = 5;
53  constexpr double A = 1. / 4.;
54  constexpr double B = 1. / 6.;
55  constexpr double C = 1. / 2.;
56  constexpr double D = -2. / 15.;
57  constexpr double E = 3. / 40.;
58  constexpr double u[NPI] = {A, B, B, B, C};
59  constexpr double v[NPI] = {A, B, B, C, B};
60  constexpr double w[NPI] = {A, B, C, B, B};
61  constexpr double pds[NPI] = {D, E, E, E, E};
69  constexpr double a[N][NPI] = {{1. - u[0] - v[0] - w[0], 1. - u[1] - v[1] - w[1],
70  1. - u[2] - v[2] - w[2], 1. - u[3] - v[3] - w[3],
71  1. - u[4] - v[4] - w[4]},
72  {u[0], u[1], u[2], u[3], u[4]},
73  {v[0], v[1], v[2], v[3], v[4]},
74  {w[0], w[1], w[2], w[3], w[4]}};
75 
77  const Eigen::Matrix<double,N,NPI> eigen_a =
78  (Eigen::MatrixXd(N,NPI) << a[0][0], a[0][1], a[0][2], a[0][3], a[0][4],
79  a[1][0], a[1][1], a[1][2], a[1][3], a[1][4],
80  a[2][0], a[2][1], a[2][2], a[2][3], a[2][4],
81  a[3][0], a[3][1], a[3][2], a[3][3], a[3][4] ).finished();
82 #endif
83 
87 struct prm
88  {
89  std::string regName;
90  double alpha_LLG;
91  double A;
92  double DMI;
93  double Ms;
95  double K;
96  Eigen::Vector3d uk;
98  double K3;
99  Eigen::Matrix3d e;
101  double P;
102  double N0;
104  double sigma;
106  double lsd;
107  double lsf;
109  double volume = 0;
113  bool absorbing = false;
114 
115  void infos(void);
116  };
117 
135 class Tet : public element<N,NPI>
136  {
137 public:
144  inline Tet(const std::vector<Nodes::Node> &_p_node ,
145  const int _idx ,
146  const std::initializer_list<int> _i )
147  : element<N,NPI>(_p_node,_idx,_i), idx(0)
148  {
149  if (existNodes())
150  {
151  orientate(); // enforce the correct orientation
152 
153  Eigen::Matrix3d J;
154  double detJ = Jacobian(J);
155  Eigen::Matrix<double,N,Nodes::DIM> dadu; // Shape function derivatives
156  // (constant for linear tetrahedron)
157  dadu << -1., -1., -1., 1., 0., 0., 0., 1., 0., 0., 0., 1.;
158  da = dadu * J.inverse();
159 
160  for (int j = 0; j < NPI; j++)
161  { weight[j] = detJ * Tetra::pds[j]; }// if NPI=1 weight[0] is the tetrahedron volume
162  // do nothing lambda's (usefull for spin transfer torque)
163  extraField = [] ( const Eigen::Ref<const Eigen::Matrix<double,Nodes::DIM,Tetra::NPI>> ) {};
164  }
165  else
166  { std::cerr<<"Error: Tet constructor has out of bound index\n"; }
167  }
168 
171  Eigen::Matrix<double,N,Nodes::DIM> da;
172 
177  inline void interpolation(const std::function<double(Nodes::Node)>& getter,
178  Eigen::Ref<Eigen::Matrix<double,NPI,1>> result) const
179  {
180  Eigen::Matrix<double,N,1> scalar_nod;
181  for (int i = 0; i < N; i++) scalar_nod(i) = getter(getNode(i));
182  result = scalar_nod.transpose() * eigen_a;
183  }
184 
187  inline void interpolation(const std::function<Eigen::Vector3d(Nodes::Node)>& getter,
188  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> result,
189  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> Tx,
190  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> Ty,
191  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> Tz) const
192  {
193  Eigen::Matrix<double,Nodes::DIM,N> vec_nod;
194  for (int i = 0; i < N; i++) vec_nod.col(i) = getter(getNode(i));
195 
196  result = vec_nod * eigen_a;// interpolated value at Gauss point
197 
198  //Spatial derivatives: constant for linear elements, evaluated at any point including Gauss
199  //point
200  Tx = vec_nod * (da.col(Nodes::IDX_X)).replicate(1,NPI);
201  Ty = vec_nod * (da.col(Nodes::IDX_Y)).replicate(1,NPI);
202  Tz = vec_nod * (da.col(Nodes::IDX_Z)).replicate(1,NPI);
203  }
204 
208  inline void interpolation_field(const std::function<double(Nodes::Node)>& getter,
209  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> X) const
210  {
211  Eigen::Matrix<double,N,1> scalar_nod;
212  for (int i = 0; i < N; i++) scalar_nod(i) = getter(getNode(i));
213 
214  X.setZero();
215  for (int j = 0; j < NPI; j++)
216  {
217  for (int i = 0; i < N; i++)
218  {
219  X.col(j) -= (scalar_nod[i] * da.row(i));
220  }
221  }
222  }
223 
226  inline void interpolation(const std::function<double(Nodes::Node, Nodes::index)>& getter,
227  const Nodes::index idx, Eigen::Ref<Eigen::Matrix<double,Tetra::NPI,1>> result) const
228  {
229  Eigen::Matrix<double,N,1> scalar_nod;
230 
231  for (int i = 0; i < N; i++)
232  {
233  scalar_nod[i] = getter(getNode(i),idx);
234  }
235  result = scalar_nod.transpose() * eigen_a;
236  }
237 
248  void lumping(const Eigen::Ref<const Eigen::Matrix<double,NPI,1>> alpha_eff, double prefactor,
249  Eigen::Ref<Eigen::Matrix<double,3*N,3*N>> AE ) const;
250 
255  Eigen::Matrix<double,N,N> calcDiagBlock(const double c,
256  const Eigen::Matrix<double,N,1> &x) const;
257 
262  Eigen::Matrix<double,N,1> calcOffDiagBlock(const Nodes::index idx) const;
263 
264 
266  void DMI_bulk_OffDiag(timing const &prm_t, const double DMIbulk_bis,
267  Eigen::Ref<Eigen::Matrix<double,3*N,3*N>> AE) const;
268 
270  void DMI_bulk_BE(const double cst,
271  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> U,
272  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> dUdx,
273  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> dUdy,
274  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> dUdz,
275  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,N>> BE) const;
276 
280  void add_drift_BE(const Eigen::Ref<const Eigen::Matrix<double,NPI,1>> alpha, double s_dt,
281  double Vdrift,
282  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> U,
283  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> V,
284  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> dUd_,
285  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> dVd_,
286  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,N>> BE) const;
287 
290  Eigen::Matrix<double,NPI,1> calc_aniso_uniax(const Eigen::Ref<const Eigen::Vector3d> uk,
291  const double Kbis, const double s_dt,
292  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> U,
293  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> V,
294  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> H_aniso) const;
295 
298  Eigen::Matrix<double,NPI,1> calc_aniso_cub(const Eigen::Ref<const Eigen::Matrix3d> e ,
299  const double K3bis ,
300  const double s_dt ,
301  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> U ,
302  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> V ,
303  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> H_aniso ) const;
304 
308  Eigen::Matrix<double,Nodes::DIM,NPI> Hst_order2_contribution(const Eigen::Ref<const Eigen::Matrix<double,Nodes::DIM,NPI>> Hst,
309  const Eigen::Ref<const Eigen::Matrix<double,Nodes::DIM,NPI>> U ,
310  const Eigen::Ref<const Eigen::Matrix<double,Nodes::DIM,NPI>> V) const;
311 
316  void integrales( const Tetra::prm &param, const timing &prm_t,
317  const std::function< Eigen::Matrix<double,Nodes::DIM,NPI> (void)>& calc_Hext,
318  Nodes::index idx_dir, double Vdrift, const AbsorbingEnds &absorb);
319 
321  double exchangeEnergy(const Tetra::prm &param,
322  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> dudx,
323  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> dudy,
324  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> dudz) const;
325 
327  double DMIBulkEnergy(const Tetra::prm &param,
328  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> u,
329  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> dudx,
330  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> dudy,
331  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> dudz) const;
332 
334  double uniaxialAnisotropyEnergy(const Tetra::prm &param,
335  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> u) const;
336 
338  double cubicAnisotropyEnergy(const Tetra::prm &param,
339  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> u) const;
340 
342  Eigen::Matrix<double,Tetra::NPI,1> charges(const double &Ms,
343  const std::function<Eigen::Vector3d(const Nodes::Node&)> &getter) const override;
344 
346  double demagEnergy(const Tetra::prm &param,
347  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> dudx,
348  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> dudy,
349  Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> dudz,
350  Eigen::Ref<Eigen::Matrix<double,NPI,1>> phi) const;
351 
353  double zeemanEnergy(const Tetra::prm &param ,
354  const Eigen::Ref<const Eigen::Vector3d> Hext ,
355  const Eigen::Ref<const Eigen::Matrix<double,Nodes::DIM,Tetra::NPI>> u ) const;
356 
358  double zeemanEnergy(const Tetra::prm &param ,
359  double fieldAmp ,
360  const std::vector<Eigen::Matrix<double,Nodes::DIM,Tetra::NPI>> &spaceField,
362  const Eigen::Ref<const Eigen::Matrix<double,Nodes::DIM,Tetra::NPI>> u) const;
364 
366  double Jacobian(Eigen::Ref<Eigen::Matrix3d> J) const;
367 
369  double calc_vol(void) const;
370 
372  int idx;
373 
375  std::function<void( Eigen::Ref<Eigen::Matrix<double,Nodes::DIM,NPI>> H)> extraField;
376 
378  Eigen::Matrix<double,Nodes::DIM,NPI> getPtGauss(void) const override
379  {
380  Eigen::Matrix<double,Nodes::DIM,N> vec_nod;
381  for (int i = 0; i < N; i++)
382  {
383  vec_nod.col(i) << getNode(i).p;
384  }
385  return vec_nod*eigen_a;
386  }
387 
389  Eigen::Matrix<double,Nodes::DIM,NPI> gradV(const std::vector<double> &V) const;
390 
391 private:
393  void orientate(void) override;
394  }; // end class Tetra
395 
397  Eigen::Matrix<double,Nodes::DIM,Tetra::NPI> calc_Hst(const Tetra::Tet &tet,
398  const double prefactor,
399  const std::vector<Eigen::Vector3d> &s);
400 } // end namespace Tetra
401 
402 #endif /* tetra_h */
absorbing ends, to absorb the spin waves reaching the ends of a wire instead of reflecting them (sett...
Definition: tetra.h:136
double calc_vol(void) const
Definition: tetra.cpp:487
Eigen::Matrix< double, N, N > calcDiagBlock(const double c, const Eigen::Matrix< double, N, 1 > &x) const
Definition: tetra.cpp:102
double zeemanEnergy(const Tetra::prm &param, const Eigen::Ref< const Eigen::Vector3d > Hext, const Eigen::Ref< const Eigen::Matrix< double, Nodes::DIM, Tetra::NPI >> u) const
Definition: tetra.cpp:435
double cubicAnisotropyEnergy(const Tetra::prm &param, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> u) const
Definition: tetra.cpp:391
double Jacobian(Eigen::Ref< Eigen::Matrix3d > J) const
Definition: tetra.cpp:454
void DMI_bulk_BE(const double cst, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> U, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> dUdx, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> dUdy, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> dUdz, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, N >> BE) const
Definition: tetra.cpp:153
Eigen::Matrix< double, N, Nodes::DIM > da
Definition: tetra.h:171
double uniaxialAnisotropyEnergy(const Tetra::prm &param, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> u) const
Definition: tetra.cpp:381
double DMIBulkEnergy(const Tetra::prm &param, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> u, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> dudx, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> dudy, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> dudz) const
Definition: tetra.cpp:364
Eigen::Matrix< double, NPI, 1 > calc_aniso_cub(const Eigen::Ref< const Eigen::Matrix3d > e, const double K3bis, const double s_dt, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> U, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> V, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> H_aniso) const
Definition: tetra.cpp:210
double exchangeEnergy(const Tetra::prm &param, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> dudx, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> dudy, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> dudz) const
Definition: tetra.cpp:353
Eigen::Matrix< double, Tetra::NPI, 1 > charges(const double &Ms, const std::function< Eigen::Vector3d(const Nodes::Node &)> &getter) const override
Definition: tetra.cpp:408
Eigen::Matrix< double, N, 1 > calcOffDiagBlock(const Nodes::index idx) const
Definition: tetra.cpp:111
void DMI_bulk_OffDiag(timing const &prm_t, const double DMIbulk_bis, Eigen::Ref< Eigen::Matrix< double, 3 *N, 3 *N >> AE) const
Definition: tetra.cpp:119
Eigen::Matrix< double, Nodes::DIM, NPI > getPtGauss(void) const override
Definition: tetra.h:378
void add_drift_BE(const Eigen::Ref< const Eigen::Matrix< double, NPI, 1 >> alpha, double s_dt, double Vdrift, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> U, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> V, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> dUd_, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> dVd_, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, N >> BE) const
Definition: tetra.cpp:176
void interpolation(const std::function< double(Nodes::Node)> &getter, Eigen::Ref< Eigen::Matrix< double, NPI, 1 >> result) const
Definition: tetra.h:177
void interpolation(const std::function< Eigen::Vector3d(Nodes::Node)> &getter, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> result, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> Tx, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> Ty, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> Tz) const
Definition: tetra.h:187
Eigen::Matrix< double, Nodes::DIM, NPI > gradV(const std::vector< double > &V) const
Definition: tetra.cpp:47
int idx
Definition: tetra.h:372
void lumping(const Eigen::Ref< const Eigen::Matrix< double, NPI, 1 >> alpha_eff, double prefactor, Eigen::Ref< Eigen::Matrix< double, 3 *N, 3 *N >> AE) const
Definition: tetra.cpp:77
std::function< void(Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> H)> extraField
Definition: tetra.h:375
void orientate(void) override
Definition: tetra.cpp:471
Tet(const std::vector< Nodes::Node > &_p_node, const int _idx, const std::initializer_list< int > _i)
Definition: tetra.h:144
void interpolation_field(const std::function< double(Nodes::Node)> &getter, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> X) const
Definition: tetra.h:208
void interpolation(const std::function< double(Nodes::Node, Nodes::index)> &getter, const Nodes::index idx, Eigen::Ref< Eigen::Matrix< double, Tetra::NPI, 1 >> result) const
Definition: tetra.h:226
Eigen::Matrix< double, NPI, 1 > calc_aniso_uniax(const Eigen::Ref< const Eigen::Vector3d > uk, const double Kbis, const double s_dt, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> U, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> V, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> H_aniso) const
Definition: tetra.cpp:198
void integrales(const Tetra::prm &param, const timing &prm_t, const std::function< Eigen::Matrix< double, Nodes::DIM, NPI >(void)> &calc_Hext, Nodes::index idx_dir, double Vdrift, const AbsorbingEnds &absorb)
Definition: tetra.cpp:248
double demagEnergy(const Tetra::prm &param, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> dudx, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> dudy, Eigen::Ref< Eigen::Matrix< double, Nodes::DIM, NPI >> dudz, Eigen::Ref< Eigen::Matrix< double, NPI, 1 >> phi) const
Definition: tetra.cpp:422
Eigen::Matrix< double, Nodes::DIM, NPI > Hst_order2_contribution(const Eigen::Ref< const Eigen::Matrix< double, Nodes::DIM, NPI >> Hst, const Eigen::Ref< const Eigen::Matrix< double, Nodes::DIM, NPI >> U, const Eigen::Ref< const Eigen::Matrix< double, Nodes::DIM, NPI >> V) const
Definition: tetra.cpp:235
Template abstract class, mother class for tetraedrons and triangles.
Definition: element.h:30
Eigen::Matrix< double, NPI, 1 > weight
Definition: element.h:59
bool existNodes(void) const
Definition: element.h:119
const Nodes::Node & getNode(const int i) const
Definition: element.h:131
Definition: time_integration.h:13
index
Definition: node.h:33
constexpr double A
Definition: tetra.h:53
constexpr double a[N][NPI]
Definition: tetra.h:69
constexpr double B
Definition: tetra.h:54
constexpr int N
Definition: tetra.h:26
constexpr double epsilon
Definition: tetra.h:24
constexpr double w[NPI]
Definition: tetra.h:60
constexpr double D
Definition: tetra.h:56
constexpr int NPI
Definition: tetra.h:51
constexpr double C
Definition: tetra.h:55
constexpr double pds[NPI]
Definition: tetra.h:61
constexpr double v[NPI]
Definition: tetra.h:59
const Eigen::Matrix< double, N, NPI > eigen_a
Definition: tetra.h:77
constexpr double E
Definition: tetra.h:57
constexpr double u[NPI]
Definition: tetra.h:58
Eigen::Matrix< double, Nodes::DIM, Tetra::NPI > calc_Hst(const Tetra::Tet &tet, const double prefactor, const std::vector< Eigen::Vector3d > &s)
Definition: tetra.cpp:62
header to define struct Node
Definition: absorbing_ends.h:26
Definition: node.h:60
Eigen::Vector3d p
Definition: node.h:61
Definition: tetra.h:88
double P
Definition: tetra.h:101
bool absorbing
Definition: tetra.h:113
Eigen::Matrix3d e
Definition: tetra.h:99
double volume
Definition: tetra.h:109
Eigen::Vector3d uk
Definition: tetra.h:96
std::string regName
Definition: tetra.h:89
double A
Definition: tetra.h:91
double alpha_LLG
Definition: tetra.h:90
double N0
Definition: tetra.h:102
double lsd
Definition: tetra.h:106
double DMI
Definition: tetra.h:92
void infos(void)
Definition: tetra.cpp:14
double Ms
Definition: tetra.h:93
double lsf
Definition: tetra.h:107
double K
Definition: tetra.h:95
double K3
Definition: tetra.h:98
double sigma
Definition: tetra.h:104
contains namespace Triangle header containing Tri class, and some constants and a less_than operator ...