C++ main module for emicrom Package  1.0
EMM_CubicAnisotropyOperator.h
Go to the documentation of this file.
1 #ifndef EMM_CubicAnisotropyOperator_H
2 #define EMM_CubicAnisotropyOperator_H
3 
4 
6 
7 
83 
85  // ATTRIBUTES
86 
87 
88 private:
89 
90 
91 public:
92 
93 
94  // ASSOCIATION
95 
96 private:
97 
98 
99 protected:
100 
101  // METHODS
102 
103  // CONSTRUCTORS
104 
108 
109  // DESTRUCTORS
110 
113  virtual ~EMM_CubicAnisotropyOperator(void);
114 
115 
116 public:
117 
118 
119  // SET methods
120  // ===========
121 
122 
123  // GET methods
124  // ===========
133  virtual tULLInt getMemorySize() const {
135  }
136 
137  //DATA Methods
138  //===========
139 
140 public:
141  /* \brief build the symmetric matrix of size 6
142  * @param nU: memory size of directions U
143  * @param U: anisotropy direction of size 3
144  * @param A: anisotropy matrix of size 6
145  *
146  * copy the nU elements for U into the morse matrix A
147  *
148  * @return the size of matrix A (nU)
149  */
150  static inline tUSInt BuildDiscretizedMatrix(const tUCInt& nU,
151  const tReal* U,
152  tReal* A) {
153  //copy only the directions
154  const tReal *Uk=U;
155  tReal *Ak=A;
156  for (tDimension k=0;k<nU;k++) {
157  (*Ak)=(*Uk);
158  Uk++;
159  Ak++;
160  }
161  return nU;
162  }
163 
164  //MAGNETIC Field Methods
165  //======================
166 
167 protected:
168 
183  virtual void computeMagneticExcitationField(const tUIndex& nCells,
184  const tDimension& dim,
185  const EMM_RealArray& sigma,
186  const tReal* M,
187  tReal *H) const;
188 
189 
224  const tDimension& dim,
225  const EMM_RealArray& sigma,
226  const tReal *M,
227  const tReal *D,
228  tReal *gradH)const;
229 
230 
231 public:
253  static inline tUSInt ComputeMagneticExcitation(const tReal& S,
254  const tReal& K1,
255  const tReal& K2,
256  const tUCInt& nA,
257  const tReal* A,
258  const tDimension& dim,
259  const tReal* M,
260  tReal* H,
261  const tUCInt& ldW,
262  tReal *work) {
263 
264 
265 
266 
267 
268 
269  //get the number of directions
270  tUCInt d,nDirs=nA/dim;
271  tDimension k;
272 
273 
274  //compute Mud=Mu[d]=\sigma_i*<M,Ud> = Mu[d+3]=Mut
275  memset(work,0,ldW*sizeof(tReal));
276 
277  const tReal* Ud=A;
278  tReal *Mud=work;
279  tReal *Mut=work+dim;
280  const tReal *Mk;
281  for(d=0;d<nDirs;d++) {
282  Mk=M;
283  for (k=0;k<dim;k++) {
284  (*Mud)+=(*Ud)*(*Mk);
285  Ud++;
286  Mk++;
287  }
288  (*Mud)*=S;
289  (*Mut)=(*Mud);
290  Mud++;
291  Mut++;
292  }
293 
294  //dH=Mu[d] * [ K1* (Mu[d+1]*Mu[d+1]+Mu[d+2]*Mu[d+2]) + K2* (Mu[d+1]*Mu[d+1]*Mu[d+2]*Mu[d+2]) ]
295  //H-=dH U[d]
296 
297  const tReal *Mu0=work;
298  const tReal *Mu1=(Mu0+1);
299  const tReal *Mu2=(Mu1+1);
300  tReal *Hk=H;
301  tReal dH;
302  const tReal *Adk=A;
303  for (d=0;d<nDirs;d++) {
304  //compute dH
305  dH=(*Mu0)*( K1*((*Mu1)*(*Mu1)+(*Mu2)*(*Mu2))+
306  K2*((*Mu1)*(*Mu1)*(*Mu2)*(*Mu2)) );
307  Mu0++;
308  Mu1++;
309  Mu2++;
310 
311  //add Ud.dH to H
312  Hk=H;
313  for (k=0;k<dim;k++) {
314  (*Hk)-=dH*(*Adk);
315  Adk++;
316  Hk++;
317  }
318  }
319  return nDirs*dim;
320  };
321 
322 
323 
324 public:
365  const tReal& K1,
366  const tReal& K2,
367  const tUCInt& nA,
368  const tReal* A,
369  const tDimension& dim,
370  const tReal* M,
371  const tReal* D,
372  tReal* gradH,
373  const tUCInt& ldW,
374  tReal *work) {
375 
376 
377  //get the number of directions
378  tUCInt d,nDirs=nA/dim;
379  tDimension k;
380 
381 
382  //compute Mud=Mu[d]=\sigma_i*<M,Ud> = Mu[d+3]
383  //compute Dud=Du[d]=\sigma_i*<D,Ud> = Mu[d+6]=Mu[d+9]
384  const tReal *Ud=A;
385  tReal *Mud=work;
386  tReal *Mut=work+3;
387 
388  const tReal *Mk;
389  const tReal *Dk;
390  tReal *Dud=work+6;
391  tReal *Dut=work+9;
392  tReal *gradHk;
393  tReal dG;
394 
395  //initialize the work array to 0
396  memset(work,0,ldW*sizeof(tReal));
397 
398  for(d=0;d<nDirs;d++) {
399  Mk=M;
400  Dk=D;
401  for (k=0;k<dim;k++) {
402  (*Mud)+=(*Ud)*(*Mk);
403  (*Dud)+=(*Ud)*(*Dk);
404  Ud++;
405  Mk++;
406  Dk++;
407  }
408  (*Mud)*=S;
409  (*Dud)*=S;
410  (*Mut)=(*Mud);
411  (*Dut)=(*Dud);
412  Mud++;
413  Mut++;
414  Dud++;
415  Dut++;
416 
417  }
418 
419  //dG=Mu[d] * [ 2K1* (Mu[d+1]*Du[d+1]+Mu[d+2]*Du[d+2])
420  // +2K2* (Mu[d+1]*Du[d+1]*Mu[d+2]*Mu[d+2] + Mu[d+1]*Mu[d+1]*Mu[d+2]*Du[d+2]) ] +
421  // Du[d] * [ K1* (Mu[d+1]*Mu[d+1]+Mu[d+2]*Mu[d+2]) +
422  // K2* (Mu[d+1]*Mu[d+1]*Mu[d+2]*Mu[d+2]) ]
423  //=>
424  //dG=2.Mu[d] * [ K1* (Mu[d+1]*Du[d+1]+Mu[d+2]*Du[d+2])
425  // +K2* Mu[d+1]*Mu[d+2]*(Du[d+1]*Mu[d+2] + Mu[d+1]*Du[d+2]) ] +
426  // Du[d] * [ K1* (Mu[d+1]*Mu[d+1]+Mu[d+2]*Mu[d+2]) +
427  // K2* (Mu[d+1]*Mu[d+1]*Mu[d+2]*Mu[d+2]) ]
428 
429  //gradH-=dG U[d]
430 
431  const tReal *Mu0=work;
432  const tReal *Mu1=(Mu0+1);
433  const tReal *Mu2=(Mu1+1);
434  const tReal *Du0=work+6;
435  const tReal *Du1=(Du0+1);
436  const tReal *Du2=(Du1+1);
437  const tReal *Adk=A;
438 
439  for (d=0;d<nDirs;d++) {
440  //compute dG
441  dG=2*(*Mu0)*( K1*((*Mu1)*(*Du1)+(*Mu2)*(*Du2)) +
442  K2*(*Mu1)*(*Mu2)*((*Du1)*(*Mu2)+(*Mu1)*(*Du2)))+
443  (*Du0)*( K1*((*Mu1)*(*Mu1)+(*Mu2)*(*Mu2))+
444  K2*((*Mu1)*(*Mu1)*(*Mu2)*(*Mu2)) );
445 
446  Mu0++;
447  Mu1++;
448  Mu2++;
449  Du0++;
450  Du1++;
451  Du2++;
452 
453  //add Ud.dH to H
454  gradHk=gradH;
455  for (k=0;k<dim;k++) {
456  (*gradHk)-=dG*(*Adk);
457  Adk++;
458  gradHk++;
459  }
460 
461  }
462  return dim*nDirs;
463 
464  };
465 
466 
467 
468 
469  //ENERGY methods
470  //==============
471 
481  tReal computeEnergy(const tUIndex& nCells,const tDimension& dim,
482  const EMM_RealArray& sigma,const tReal* M) const;
483 
484 
485 
486 public:
501  static inline void ComputeEnergy(const tReal& S,
502  const tReal& K1,
503  const tReal& K2,
504  const tUCInt& nA,
505  const tReal* A,
506  const tDimension& dim,
507  const tReal* M,
508  const tUCInt& ldW,
509  tReal* work,
510  tReal& E) {
511  tReal dE;
512  E=0;
513  //compute Mud=Mu[d]=\sigma_i*<M,Ud> = Mu[d+3]=Mut
514  memset(work,0,ldW*sizeof(tReal));
515  tReal *Muk,*Mud=work;
516  const tReal *Mk;
517  tUCInt d,nDirs=nA/dim;//number of anisotropy directions in [0,3[
518  tDimension k;
519 
520  const tReal *Adk=A;
521  for(d=0;d<nDirs;d++) {
522  Mk=M;
523  for (k=0;k<dim;k++) {
524  (*Mud)+=(*Adk)*(*Mk);
525  Adk++;
526  Mk++;
527  }
528  (*Mud)*=S;
529  Mud++;
530  }
531 
532  //K2 contribution
533  if (K2!=0) {
534  dE=K2;
535  Mud=work;
536  for (d=0;d<nDirs;d++) {
537  dE*=(*Mud)*(*Mud);
538  Mud++;
539  }
540  E+=dE;
541  }
542 
543  //K1 contribution
544  if (K1!=0) {
545  Mud=work;
546  for (d=0;d<nDirs;d++) {
547  dE=0;
548  Muk=work;
549  for (k=0;k<d;k++) {
550  dE+=(*Muk)*(*Muk);
551  Muk++;
552  }
553  E+=K1*(*Mud)*(*Mud)*dE;
554  Mud++;
555  }
556 
557  }
558 
559 
560 
561  }
562 
563 
564 
565 
566 
567 
568 };
569 
570 #endif
571 
DEFINE_SPTR(EMM_CubicAnisotropyOperator)
static const tReal Mu0
Definition: EMM_Object.h:28
tReal computeEnergy(const tUIndex &nCells, const tDimension &dim, const EMM_RealArray &sigma, const tReal *M) const
compute the energy of the anistropy operator
Definition: EMM_CubicAnisotropyOperator.cpp:23
virtual tBoolean computeMagneticExcitationFieldGradient(const tUIndex &nCells, const tDimension &dim, const EMM_RealArray &sigma, const tReal *M, const tReal *D, tReal *gradH) const
compute the gradient of the magnetic excitation field at M in the direction D
Definition: EMM_CubicAnisotropyOperator.cpp:431
#define tUCInt
Definition: types.h:21
#define tUSInt
Definition: types.h:28
#define tBoolean
Definition: types.h:139
static tUSInt ComputeMagneticExcitationGradient(const tReal &S, const tReal &K1, const tReal &K2, const tUCInt &nA, const tReal *A, const tDimension &dim, const tReal *M, const tReal *D, tReal *gradH, const tUCInt &ldW, tReal *work)
compute the magnetic excitation gradient at cell i
Definition: EMM_CubicAnisotropyOperator.h:364
virtual tULLInt getMemorySize() const
return the memory size in byte
Definition: EMM_CubicAnisotropyOperator.h:133
#define tDimension
Definition: EMM_Types.h:10
static tUSInt ComputeMagneticExcitation(const tReal &S, const tReal &K1, const tReal &K2, const tUCInt &nA, const tReal *A, const tDimension &dim, const tReal *M, tReal *H, const tUCInt &ldW, tReal *work)
compute the magnetic excitation at cell i
Definition: EMM_CubicAnisotropyOperator.h:253
SP_OBJECT(EMM_CubicAnisotropyOperator)
static void ComputeEnergy(const tReal &S, const tReal &K1, const tReal &K2, const tUCInt &nA, const tReal *A, const tDimension &dim, const tReal *M, const tUCInt &ldW, tReal *work, tReal &E)
compute the energy of the cell i
Definition: EMM_CubicAnisotropyOperator.h:501
virtual tULLInt getMemorySize() const
return the memory size in byte
Definition: EMM_AnisotropyOperator.h:132
virtual ~EMM_CubicAnisotropyOperator(void)
destroy
Definition: EMM_CubicAnisotropyOperator.cpp:14
This class describes the cubic anistropy operator of the landau lifschitz system EMM_LandauLifschitzS...
Definition: EMM_CubicAnisotropyOperator.h:82
#define tUIndex
Definition: types.h:126
This class describes a real array.
Definition: EMM_RealArray.h:16
virtual void computeMagneticExcitationField(const tUIndex &nCells, const tDimension &dim, const EMM_RealArray &sigma, const tReal *M, tReal *H) const
compute the normalized excitation magnetic field at M
Definition: EMM_CubicAnisotropyOperator.cpp:231
EMM_CubicAnisotropyOperator(void)
create
Definition: EMM_CubicAnisotropyOperator.cpp:10
This class describes the mixed anistropy operators of the landau lifschitz system EMM_LandauLifschitz...
Definition: EMM_AnisotropyOperator.h:53
#define tULLInt
Definition: types.h:45
#define tReal
Definition: types.h:118
static tUSInt BuildDiscretizedMatrix(const tUCInt &nU, const tReal *U, tReal *A)
Definition: EMM_CubicAnisotropyOperator.h:150