C++ mpi module for stochmagnet_main Package
EXPR_Node.h
1 #ifndef EXPR_Node_H
2 #define EXPR_Node_H
3 
4 
5 #include "EXPR_Object.h"
6 
7 //numerics functions headers
8 #include "core_numeric.h"
9 
16 class EXPR_Node : public virtual EXPR_Object {
17 
18 private:
19  //attributes
20 
21  //unit bounding box
22  static const std::array<tBoolean,24> BOUNDING_BOX_POINTS;
23 
24 
25  //approximation for testing the bounding box
26  static tReal EPSILON;
27 
28  //bounding box after applying the transformation
29  std::array<tReal,3> mMinPoint;
30  std::array<tReal,3> mMaxPoint;
31 
32  //linear transformation of the node
33  //F(x)=alpha.x+beta
34  //F^{-1}(y)=A.(y-beta) A = alpha^{-1}
35  std::array<tReal,9> mAlpha;
36  std::array<tReal,9> mA;
37  std::array<tReal,3> mBeta;
38 
39  std::array<tReal,3> mWork;
40 
41 
42 private:
43  //associations
44 protected:
45  //builders
46 
49  EXPR_Node();
50 
51  //deleters
54  virtual ~EXPR_Node();
55 
56 
57 public:
58  //MEMORY
59  //======
67  virtual tMemSize getMemorySize() const override {
68  return sizeof(*this)+getContentsMemorySize();
69  }
70 
79  virtual tMemSize getContentsMemorySize() const override {
81  mem+=mBeta.size()*sizeof(tReal);
82  mem+=mA.size()*sizeof(tReal);
83  mem+=mAlpha.size()*sizeof(tReal);
84  mem+=mMinPoint.size()*sizeof(tReal);
85  mem+=mMaxPoint.size()*sizeof(tReal);
86  return mem;
87  }
88 
89  //methods
93  virtual void copy(const EXPR_Node& node) {
94  //copy the canonical bounding box
95 
96  memcpy(mMinPoint.data(),node.getBoundingBoxMinPoint().data(),sizeof(tReal)*mMinPoint.size());
97  memcpy(mMaxPoint.data(),node.getBoundingBoxMaxPoint().data(),sizeof(tReal)*mMaxPoint.size());
98 
99 
100  memcpy(mAlpha.data(),node.getAlpha().data(),sizeof(tReal)*mAlpha.size());
101  memcpy(mBeta.data(),node.getBeta().data(),sizeof(tReal)*mBeta.size());
102 
103  Inverse(mAlpha,mA);
104  }
105 
106 
107  //transformation methods
108  //=======================
109 
113  inline void setAlpha(std::initializer_list<tReal>&& alpha) {
114  auto iAlpha=std::cbegin(alpha);
115  for(auto& alpha_i:mAlpha) {
116  alpha_i=(*iAlpha);
117  iAlpha++;
118  }
119 
120  Inverse(mAlpha,mA);
121  }
122 
126  inline void setBeta(std::initializer_list<tReal>&& beta) {
127  auto iBeta=std::cbegin(beta);
128  for(auto& beta_i:mBeta) {
129  beta_i=(*iBeta);
130  iBeta++;
131  }
132  }
136  inline void addToBeta(std::initializer_list<tReal>&& beta) {
137  auto iBeta=std::cbegin(beta);
138  for(auto& bi: mBeta) {
139  bi+=(*iBeta);
140  iBeta++;
141  };
142  }
143 
147  inline const std::array<tReal,3>& getBeta() const {
148  return mBeta;
149  }
153  inline const std::array<tReal,9>& getAlpha() const {
154  return mAlpha;
155  }
156 
157 
158  //affine transformation
159  //=====================
160 
166  inline void leftComposition(const std::array<tReal,9>& A,
167  const std::array<tReal,3>& B) {
168  //F(X)=(A o Id(x) +B) o (alpha.Id(x)+beta)
169  //F(x)=A.(alpha.x+beta)+B=A.alpha.x+A.beta+B
170  //beta=A.beta+beta
171  //alpha:=A.alpha
172 
173  //Y=A.beta
174  tReal *iW=mWork.data();//iterator on W
175  const tReal *eW=iW;eW+=mWork.size();//end iterator on W
176 
177  const tReal *Aik=A.data();//iterator on A
178 
179  tReal *iBeta=mBeta.data();//itertaor on mBeta
180  const tReal *eBeta=iBeta;eBeta+=mBeta.size();//end of iterator on beta
181 
182  while (iW!=eW) {//loop on i in {0,1,2}
183 
184  //Wi=0
185  (*iW)=0;
186 
187  iBeta=mBeta.data();
188  while (iBeta!=eBeta) {//loop on k in {0,1,2}
189 
190  (*iW)+=(*Aik)*(*iBeta);
191 
192  //next k
193  Aik++;
194  iBeta++;
195  }
196 
197  //next i
198  iW++;
199  }
200 
201  //beta=Y+B=A.beta+B
202  iBeta=mBeta.data();
203  iW=mWork.data();//ietartor on work array W
204  const tReal *iB=B.data();
205  while (iBeta!=eBeta) {
206 
207  //beta_i=W_i+B_i
208  (*iBeta)=(*iW)+(*iB);
209 
210  //next i
211  iBeta++;
212  iW++;
213  iB++;
214  }
215 
216  //Alpha:=A.Alpha
217  alphaLeftComposition(A);
218 
219  }
220 
221 
225  inline void leftComposition(const std::array<tReal,9>& A) {
226  //F(X)=(A o Id(x)) o (alpha.Id(x)+beta)
227  //F(x)=A.(alpha.x+beta)=A.alpha.x+A.beta
228  //beta=A.beta+beta
229  //alpha:=A.alpha
230 
231  //Y=A.beta
232 
233  tReal *iW=mWork.data();//iterator on W
234  const tReal *eW=iW;eW+=mWork.size();//end iterator on W
235 
236  const tReal *Aik=A.data();//iterator on A
237 
238  tReal *iBeta=mBeta.data();//iterator on beta
239  const tReal *eBeta=iBeta;eBeta+=mBeta.size();//end of iterator on beta
240 
241  while (iW!=eW) {//loop on i in {0,1,2}
242  (*iW)=0;
243 
244  //computes W=A.beta
245  iBeta=mBeta.data();
246  while (iBeta!=eBeta) {//loop on k in {0,1,2}
247 
248  //Wi=Aik.beta_k
249  (*iW)+=(*Aik)*(*iBeta);
250 
251  //next k
252  Aik++;
253  iBeta++;
254  }
255 
256  //next i
257  iW++;
258  }
259 
260  //beta:=W and W=A.beta
261  memcpy(mBeta.data(),mWork.data(),mWork.size()*sizeof(tReal));
262 
263 
264 
265  //Alpha:=A.Alpha
266  alphaLeftComposition(A);
267  }
268 
269 
270  //canonical transformations
271  //=========================
272 
276  inline void rotation(const tReal& theta) {
277  tReal c=cos(theta);
278  tReal s=sin(theta);
279  if (fabs(s)<1.e-12) s=0;
280  if (fabs(c)<1.e-12) c=0;
281  std::array<tReal,9> rot={0,0,0,0,0,0,0,0,0};
282  rot[0]=c;
283  rot[1]=-s;
284  rot[3]=s;
285  rot[4]=c;
286  rot[8]=1.;
287  leftComposition(rot);
288  }
295  inline void rotation(const tReal& theta,const tReal& Ax,const tReal& Ay,const tReal& Az) {
296  tReal c=cos(theta);
297  tReal s=sin(theta);
298  if (fabs(s)<1.e-12) s=0;
299  if (fabs(c)<1.e-12) c=0;
300  std::array<tReal,9> rot={0,0,0,0,0,0,0,0,0};
301  tReal N=sqrt(Ax*Ax+Ay*Ay+Az*Az);
302  tReal Ux=Ax/N;
303  tReal Uy=Ay/N;
304  tReal Uz=Az/N;
305 
306  rot[0]=Ux*Ux*(1-c)+c;
307  rot[1]=Ux*Uy*(1-c)-Uz*s;
308  rot[2]=Ux*Uz*(1-c)+Uy*s;
309 
310  rot[3]=Uy*Ux*(1-c)+Uz*s;
311  rot[4]=Uy*Uy*(1-c)+c;
312  rot[5]=Uy*Uz*(1-c)-Ux*s;
313 
314  rot[6]=Uz*Ux*(1-c)-Uy*s;
315  rot[7]=Uz*Uy*(1-c)+Ux*s;
316  rot[8]=Uz*Uz*(1-c)+c;
317  leftComposition(rot);
318  }
328  inline void rotation(const tReal& theta,
329  const tReal& Ax,const tReal& Ay,const tReal& Az,
330  const tReal& Cx,const tReal& Cy,const tReal& Cz) {
331 
332 
333  tReal c=cos(theta);
334  tReal s=sin(theta);
335  if (fabs(s)<1.e-12) s=0;
336  if (fabs(c)<1.e-12) c=0;
337  std::array<tReal,9> rot={0,0,0,0,0,0,0,0,0};
338  tReal N=sqrt(Ax*Ax+Ay*Ay+Az*Az);
339 
340  std::array<tReal,3> U;
341  tReal &Ux=U[0];
342  Ux=Ax/N;
343  tReal &Uy=U[1];
344  Uy=Ay/N;
345  tReal &Uz=U[2];
346  Uz=Az/N;
347 
348  rot[0]=Ux*Ux*(1-c)+c;
349  rot[1]=Ux*Uy*(1-c)-Uz*s;
350  rot[2]=Ux*Uz*(1-c)+Uy*s;
351 
352  rot[3]=Uy*Ux*(1-c)+Uz*s;
353  rot[4]=Uy*Uy*(1-c)+c;
354  rot[5]=Uy*Uz*(1-c)-Ux*s;
355 
356  rot[6]=Uz*Ux*(1-c)-Uy*s;
357  rot[7]=Uz*Uy*(1-c)+Ux*s;
358  rot[8]=Uz*Uz*(1-c)+c;
359 
360  //P=Rot_{theta,U,C}(M)
361  //CP=Rot_{theta,U,0)(CM)
362  //P=Rot_{theta,U,0)(M)-Rot_{theta,U,0)(C)+C
363  const tReal *Rij=rot.data();
364  Ux=Cx;
365  Ux-=(*Rij)*Cx;Rij++;
366  Ux-=(*Rij)*Cy;Rij++;
367  Ux-=(*Rij)*Cz;Rij++;
368  Uy=Cy;
369  Uy-=(*Rij)*Cx;Rij++;
370  Uy-=(*Rij)*Cy;Rij++;
371  Uy-=(*Rij)*Cz;Rij++;
372  Uz=Cz;
373  Uz-=(*Rij)*Cx;Rij++;
374  Uz-=(*Rij)*Cy;Rij++;
375  Uz-=(*Rij)*Cz;Rij++;
376 
377  leftComposition(rot,U);
378  }
379 
385  inline void translate(const std::array<tReal,3>& T) {
386  const tReal *iT=T.data();
387  for(auto& Bi:mBeta) {
388  Bi+=(*iT);
389  iT++;
390  }
391  }
392 
393 
394 
395 private:
400  inline static void Inverse(const std::array<tReal,9>& A,std::array<tReal,9>& invA) {
401  const tReal *alpha=A.data();
402 
403  const tReal &A00=*alpha;alpha++;
404  const tReal &A01=*alpha;alpha++;
405  const tReal &A02=*alpha;alpha++;
406  const tReal &A10=*alpha;alpha++;
407  const tReal &A11=*alpha;alpha++;
408  const tReal &A12=*alpha;alpha++;
409  const tReal &A20=*alpha;alpha++;
410  const tReal &A21=*alpha;alpha++;
411  const tReal &A22=*alpha;
412 
413 
414  tReal *beta=invA.data();
415  tReal detA=A00*A11*A22+A01*A12*A20+A02*A10*A21-A02*A11*A20-A12*A21*A00-A22*A01*A10;
416  *beta=(A11*A22-A12*A21)/detA;beta++;
417  *beta=(A02*A21-A01*A22)/detA;beta++;
418  *beta=(A01*A12-A02*A11)/detA;beta++;
419  *beta=(A12*A20-A10*A22)/detA;beta++;
420  *beta=(A00*A22-A02*A20)/detA;beta++;
421  *beta=(A02*A10-A00*A12)/detA;beta++;
422  *beta=(A10*A21-A11*A20)/detA;beta++;
423  *beta=(A01*A20-A00*A21)/detA;beta++;
424  *beta=(A00*A11-A01*A10)/detA;
425  }
426 
430  inline void alphaLeftComposition(const std::array<tReal,9>& B) {
431  //alpha:=B.alpha
432 
433  //mA=B.alpha;
434  //=>Aij=Bik*alpha_kj
435 
436  //mAlpha:=mA
437 
438  //A=mA
439  tReal *Aij=mA.data();
440 
441  const tReal *Bik,*Bi=B.data(),*eBi=Bi+B.size();
442  tReal *alpha_j,*alpha_kj;
443  const tReal *eAlpha=mAlpha.data()+3;
444  const tReal *Bie;
445  //A=B.alpha
446  while (Bi!=eBi) {//loop on row i in {0,1,2}
447  //alpha_.j
448  alpha_j=mAlpha.data();//j-column of alpha
449  while (alpha_j!=eAlpha) {//loop on colum j in {0,12}
450  (*Aij)=0;
451 
452  Bik=Bi;//i-row of B matrix
453  Bie=Bi;Bie+=3;//end of i-row of B matrix
454  alpha_kj=alpha_j;
455  while (Bik!=Bie) {
456 
457  //Aij=Bik.alpha_kj
458  (*Aij)+=(*Bik)*(*alpha_kj);
459 
460  //next k
461  Bik++;
462  alpha_kj+=3;
463  }
464 
465  //next j
466  Aij++;
467  alpha_j++;
468  }
469  //next i
470  Bi+=3;
471  }
472 
473  //alpha=mA;
474  memcpy(mAlpha.data(),mA.data(),mA.size()*sizeof(tReal));
475 
476  //mA=mAlpha^{-1}
477  Inverse(mAlpha,mA);
478  }
479 
480 
481 protected:
485  inline void apply(std::array<tReal,3>& P) const {
486 
487 
488  tReal Px=P[0];
489  tReal Py=P[1];
490  tReal Pz=P[2];
491 
492  P[0]=mAlpha[0]*(Px)+mAlpha[1]*(Py)+mAlpha[2]*(Pz)+mBeta[0];
493  P[1]=mAlpha[3]*(Px)+mAlpha[4]*(Py)+mAlpha[5]*(Pz)+mBeta[1];
494  P[2]=mAlpha[6]*(Px)+mAlpha[7]*(Py)+mAlpha[8]*(Pz)+mBeta[2];
495 
496  }
502  inline tBoolean apply(const std::array<tReal,3>& P,std::array<tReal,3>& Q) const {
503 
504  if (P.data()==Q.data()) return false;
505 
506  //Y=alpha.P+beta
507 
508  //iterators on beta
509  const tReal *iB=mBeta.data();
510  const tReal *eB=iB;eB+=mBeta.size();
511 
512  //ietaror on Q=F(P);
513  tReal *iQ=Q.data();
514 
515  //iterator on P
516  const tReal *iP;//iterator on P
517  const tReal *eP=P.data();eP+=P.size();//end iterator on P
518 
519  //iterator on alpha
520  const tReal *Aki=mAlpha.data();
521 
522  while (iB!=eB) {//k loop in {0,1,2}
523  //Q=B
524  (*iQ)=(*iB);
525 
526  //Q=B+A.P
527  iP=P.data();
528  while (iP!=eP) {//i loop on {0,1,2}
529 
530  //Q+=Aki.Pi
531  (*iQ)+=(*Aki)*(*iP);
532 
533  //next i
534  Aki++;
535  iP++;
536  }
537 
538  //next k
539  iQ++;
540  iB++;
541  }
542 
543  return true;
544  }
545 
546 
550  inline void applyInverse(std::array<tReal,3>& P) const {
551 
552 
553  tReal Px=P[0];
554  tReal Py=P[1];
555  tReal Pz=P[2];
556 
557  P[0]=mA[0]*(Px-mBeta[0])+mA[1]*(Py-mBeta[1])+mA[2]*(Pz-mBeta[2]);
558  P[1]=mA[3]*(Px-mBeta[0])+mA[4]*(Py-mBeta[1])+mA[5]*(Pz-mBeta[2]);
559  P[2]=mA[6]*(Px-mBeta[0])+mA[7]*(Py-mBeta[1])+mA[8]*(Pz-mBeta[2]);
560 
561  }
567  inline tBoolean applyInverse(const std::array<tReal,3>& P,
568  std::array<tReal,3>& Q) const {
569 
570 
571  if (P.data()==Q.data()) return false;
572 
573  //iterators on beta
574  const tReal *iB=mBeta.data();
575 
576 
577  //itartor on Q=F^-1(P);
578  tReal *iQ=Q.data();
579  const tReal *eQ=iQ;eQ+=Q.size();
580 
581  //iterator on P
582  const tReal *iP;
583  const tReal *eP=P.data();eP+=P.size();
584 
585  //iterator on alpha
586  const tReal *Aki=mA.data();
587 
588  //P=F(P)=alpha.Q+beta
589  //Q=alpha^{-1}.(P-beta)
590  //Q=A.(P-beta)
591 
592 
593  while (iQ!=eQ) {//loop on k in {0,1,2}
594 
595  //Q=0
596  (*iQ)=0;
597 
598  iP=P.data();
599  iB=mBeta.data();
600  while (iP!=eP) { //loop on i in {0,1,2}
601 
602  //Q=A.(P-beta)
603  (*iQ)+=(*Aki)*((*iP)-(*iB));
604 
605  //next i
606  Aki++;
607  iP++;
608  iB++;
609  }
610 
611  //next k
612  iQ++;
613  }
614 
615  return true;
616  }
617 
618 
619 
620 
621 
622 
623  //bounding box methods
624  //===================
625 public:
629  inline static void SetEpsilon(const tReal& eps) {EPSILON=eps;};
630 
634  inline static const tReal& GetEpsilon() {
635  return EPSILON;
636  }
641  virtual void adimensionize(const tReal& L,std::map<tString,tBoolean>& alreadyComputed);
642 
643 
647  virtual void computeBoundingBox(std::map<tString,tBoolean>& alreadyComputed)=0;
648 
652  inline const std::array<tReal,3>& getBoundingBoxMinPoint() const {
653  return mMinPoint;
654  }
658  inline const std::array<tReal,3>& getBoundingBoxMaxPoint() const {
659  return mMaxPoint;
660  }
661 
665  inline std::array<tReal,3>& getBoundingBoxMinPoint() {
666  return mMinPoint;
667  }
671  inline std::array<tReal,3>& getBoundingBoxMaxPoint() {
672  return mMaxPoint;
673  }
674 
675 
676 protected:
677 
683  void linearTransformBoundingBox(std::array<tReal,3>& P,std::array<tReal,3>& Q) const ;
684 
685 
686 
687  //is inside methods
688  //=================
689 public:
694  inline tBoolean isInsideBoundingBox(const std::array<tReal,3>& P) const {
695  //test if the point M is in the bounding box
696  const tReal *mk=mMinPoint.data();
697  const tReal *Mk=mMaxPoint.data();
698  for(auto& Pk:P) {
699  if ( (EPSILON<(*mk)-(Pk)) || ((Pk)-(*Mk)>EPSILON) ) return false;
700  Mk++;
701  mk++;
702  }
703 
704  return true;
705  }
706 
711  virtual tBoolean isInside(std::array<tReal,3> M) const=0;
712 
713 
714 
715 
716 
717 public:
721  virtual tString toString() const override;
722 };
723 
724 
725 
726 
727 #endif
728 
virtual tMemSize getContentsMemorySize() const
return nthe memory size of the included associations
Definition: CORE_Object.h:278
This class is a base class of the binary tree.
Definition: EXPR_Node.h:16
virtual void adimensionize(const tReal &L, std::map< tString, tBoolean > &alreadyComputed)
adimensionize the node
Definition: EXPR_Node.cpp:135
virtual tMemSize getContentsMemorySize() const override
return nthe memory size of the included associations
Definition: EXPR_Node.h:79
void addToBeta(std::initializer_list< tReal > &&beta)
add to the constant by column
Definition: EXPR_Node.h:136
void leftComposition(const std::array< tReal, 9 > &A, const std::array< tReal, 3 > &B)
compose by the affine function
Definition: EXPR_Node.h:166
const std::array< tReal, 9 > & getAlpha() const
get the alpha value
Definition: EXPR_Node.h:153
static void SetEpsilon(const tReal &eps)
set the tolerance error
Definition: EXPR_Node.h:629
std::array< tReal, 3 > & getBoundingBoxMaxPoint()
get the max point bounding box of the node for writing
Definition: EXPR_Node.h:671
const std::array< tReal, 3 > & getBoundingBoxMinPoint() const
get the min point bounding box of the node for reading
Definition: EXPR_Node.h:652
void linearTransformBoundingBox(std::array< tReal, 3 > &P, std::array< tReal, 3 > &Q) const
compute the bounding box after transformation
Definition: EXPR_Node.cpp:44
virtual tBoolean isInside(std::array< tReal, 3 > M) const =0
return true if the point is in the bounding box of the node
void rotation(const tReal &theta, const tReal &Ax, const tReal &Ay, const tReal &Az, const tReal &Cx, const tReal &Cy, const tReal &Cz)
compute the rotation of the geometry with angle theta and axis (Ax,Ay,Az)a and center (Cx,...
Definition: EXPR_Node.h:328
virtual tMemSize getMemorySize() const override
return the memory size of the class
Definition: EXPR_Node.h:67
virtual ~EXPR_Node()
delete the class
Definition: EXPR_Node.cpp:40
std::array< tReal, 3 > & getBoundingBoxMinPoint()
get the min point bounding box of the node for writing
Definition: EXPR_Node.h:665
void leftComposition(const std::array< tReal, 9 > &A)
compose by the affine function
Definition: EXPR_Node.h:225
const std::array< tReal, 3 > & getBeta() const
get the beta value
Definition: EXPR_Node.h:147
void rotation(const tReal &theta, const tReal &Ax, const tReal &Ay, const tReal &Az)
compute the rotation of the geometry with angle theta and axis (Ax,Ay,Az)
Definition: EXPR_Node.h:295
tBoolean applyInverse(const std::array< tReal, 3 > &P, std::array< tReal, 3 > &Q) const
apply the inverse transformation to point P
Definition: EXPR_Node.h:567
void translate(const std::array< tReal, 3 > &T)
translate the geometry
Definition: EXPR_Node.h:385
tBoolean isInsideBoundingBox(const std::array< tReal, 3 > &P) const
return true if the point P is in the bounding box
Definition: EXPR_Node.h:694
void setBeta(std::initializer_list< tReal > &&beta)
set the constant by column
Definition: EXPR_Node.h:126
void setAlpha(std::initializer_list< tReal > &&alpha)
set the matrix alpha by row
Definition: EXPR_Node.h:113
EXPR_Node()
create the class
Definition: EXPR_Node.cpp:18
virtual tString toString() const override
return the string representation of this
Definition: EXPR_Node.cpp:145
const std::array< tReal, 3 > & getBoundingBoxMaxPoint() const
get the max point bounding box of the node for reading
Definition: EXPR_Node.h:658
tBoolean apply(const std::array< tReal, 3 > &P, std::array< tReal, 3 > &Q) const
apply the transformation to point P
Definition: EXPR_Node.h:502
void apply(std::array< tReal, 3 > &P) const
apply the transformation to point P
Definition: EXPR_Node.h:485
static const tReal & GetEpsilon()
get the tolerance error
Definition: EXPR_Node.h:634
virtual void computeBoundingBox(std::map< tString, tBoolean > &alreadyComputed)=0
compute the bounding box of the node
void rotation(const tReal &theta)
compute the rotation of the geometry with angle theta and k-axis
Definition: EXPR_Node.h:276
void applyInverse(std::array< tReal, 3 > &P) const
apply the inverse transformation to point P
Definition: EXPR_Node.h:550
virtual void copy(const EXPR_Node &node)
copy
Definition: EXPR_Node.h:93
This class is the base class of all the parser package.
Definition: EXPR_Object.h:27