/** # This file include mathematical operator for coord struct */ typedef struct ten{ coord x; coord y; #if dimension == 3 coord z; #endif }ten; /** declaration of the null coord*/ const coord Coord_nul = {0}; const tens tens_nul = {{0}}; #define Identity\ {{1,0,0},\ {0,1,0},\ {0,0,1}} const tens I = Identity; /** and operator on coord */ coord and_coord(coord a,coord b){ coord c = {(int)a.x && (int)b.x,(int)a.y &&(int) b.y,(int)a.z &&(int) b.z}; return c; } coord add_coord(coord a,coord b){ #if dimension == 2 coord c = {a.x+b.x, a.y+b.y}; #elif dimension == 3 coord c = {a.x+b.x, a.y+b.y, a.z+b.z}; #endif return c; } coord diff_coord(coord a,coord b){ #if dimension == 2 coord c = {a.x-b.x,a.y-b.y}; #elif dimension == 3 coord c = {a.x-b.x, a.y-b.y, a.z-b.z}; #endif return c; } coord mult_coord(coord a,double b){ #if dimension == 2 coord c = {a.x*b, a.y*b}; #elif dimension == 3 coord c = {a.x*b, a.y*b, a.z*b}; #endif return c; } coord div_coord(coord a,double b){ #if dimension == 2 coord c = {a.x/b, a.y/b}; #elif dimension == 3 coord c = {a.x/b, a.y/b, a.z/b}; #endif return c; } tens div_tens(tens a,double b){ einstein_sum(i,j){ a.i.j /= b; } return a; } tens mult_tens(tens a,double b){ einstein_sum(i,j){ a.i.j *= b; } return a; } tens add_tens(tens A,tens B){ einstein_sum(i,j){ A.i.j += B.i.j; } return A; } double tens_norm(tens A){ double norm = 0; einstein_sum(k,l){ norm = A.k.l * A.k.l; } norm = sqrt(norm); return norm; } double normL2_coord(coord a){ #if dimension == 2 double c = sqrt(pow(a.x,2)+pow(a.y,2)); #elif dimension == 3 double c = sqrt(pow(a.x,2)+pow(a.y,2)+pow(a.z,2)); #endif return c; } double normL2_coord_sq(coord a){ #if dimension == 2 double c = sq(a.x)+sq(a.y); #elif dimension == 3 double c = sq(a.x)+sq(a.y)+sq(a.z); #endif return c; } double normL2_ten(ten a){ #if dimension == 2 double c = sqrt(pow(a.x.x,2)+pow(a.y.y,2)+pow(a.x.y,2)+pow(a.y.x,2)); #elif dimension == 3 double c = sqrt(pow(a.x.x,2)+pow(a.y.y,2)+pow(a.z.z,2)+pow(a.x.y,2)+pow(a.y.x,2)+pow(a.x.z,2)+pow(a.z.x,2)+pow(a.z.y,2)+pow(a.y.z,2)); #endif return c; } //only in 3D for the cross product #if dimension == 3 coord cross_coord(coord a,coord b){ coord c = {a.y*b.z-a.z*b.y, a.z*b.x-a.x*b.z, a.x*b.y-a.y*b.x}; #elif dimension == 2 double cross_coord(coord a,coord b){ double c = a.x*b.y-a.y*b.x; #endif return c; } coord EigenValue(ten A){ double Delta = pow(A.x.x,2.) - 2.*A.x.x*A.y.y+pow(A.y.y,2.) +4.*A.x.y*A.y.x; coord Eig = {0.,0.}; if(Delta > 0){ Eig.x = 1./2.*( A.x.x + A.y.y - sqrt( Delta )); Eig.y = 1./2.*( A.x.x + A.y.y + sqrt( Delta )); } return Eig; } ten EigenVectors(ten A){ ten V; if(A.y.x != 0){ V.x.x = -1./(2.*A.y.x)*( - A.x.x + A.y.y + sqrt( pow(A.x.x,2.) - 2.*A.x.x*A.y.y+pow(A.y.y,2.) +4.*A.x.y*A.y.x ) ); V.x.y = 1.; V.y.x = -1./(2.*A.y.x)*( - A.x.x + A.y.y - sqrt( pow(A.x.x,2.) - 2*A.x.x*A.y.y+pow(A.y.y,2.) +4.*A.x.y*A.y.x ) ); V.y.y = 1.; }else if((A.x.x-A.y.y)!=0){ V.x.x = 1.; V.x.y = 0.; V.y.x = -A.x.y/(A.x.x-A.y.y); V.y.y = 1.; }else{ V.x.x = 1.; V.x.y = 0.; V.y.x = 0.; V.y.y = 1.; } V.x = div_coord(V.x,normL2_coord(V.x)); V.y = div_coord(V.y,normL2_coord(V.y)); return V; } /** Set the coordinate of a coord at the positive side of the domain */ coord POS_perio(coord pos,coord per){ foreach_dimension(){ if(per.x) pos.x = pos.x>0?pos.x:pos.x+Ls; } return pos; } /** compute the periodic distance between two coord */ coord dist_perio_coord(coord a,coord b){ foreach_dimension(){ if(a.x>0) b.x = (b.xa.x+Ls/2)*(-Ls)+b.x; } return diff_coord(a,b); } double dist_perio(coord a,coord b){ foreach_dimension(){ if(a.x>0) b.x = (b.xa.x+Ls/2)*(-Ls)+b.x; } return normL2_coord(diff_coord(a,b)); } /** compute the tranpsoe of a tensor */ tens transpsoe(tens A){ tens B; einstein_sum(i,j){ B.i.j = A.j.i; } return B; } tens sym(tens A){ tens B; einstein_sum(i,j){ B. i.j = 0.5*(A.i.j + A.j.i); } return B; } tens coord_prod(coord A,coord B){ tens C; einstein_sum(i,j){ C.i.j = A.i*B.j; } return C; } /** compute the symetric part of a tensor */