xref: /phasta/phSolver/compressible/get_h.c (revision 595995161822a203c8467e0e4a253d7bd7d6df32)
1*59599516SKenneth E. Jansen /* fortran wrapper for C program length which returns the length
2*59599516SKenneth E. Jansen    of an element in a given direction.
3*59599516SKenneth E. Jansen    */
4*59599516SKenneth E. Jansen #include "vec_func.h"
5*59599516SKenneth E. Jansen 
6*59599516SKenneth E. Jansen 
7*59599516SKenneth E. Jansen double length(double [][3],double []);
8*59599516SKenneth E. Jansen int intersect(double x[4][3],double u[],double points[4][3] );
9*59599516SKenneth E. Jansen int isPntInTri(double [][3],double [], double [], double );
10*59599516SKenneth E. Jansen 
11*59599516SKenneth E. Jansen #ifdef sun4_5
get_h_(double xtmp[][4],double u[],double * h)12*59599516SKenneth E. Jansen get_h_(double xtmp[][4], double u[], double *h)
13*59599516SKenneth E. Jansen #endif
14*59599516SKenneth E. Jansen #ifdef LINUX
15*59599516SKenneth E. Jansen get_h_(double xtmp[][4], double u[], double *h)
16*59599516SKenneth E. Jansen #endif
17*59599516SKenneth E. Jansen #ifdef ibm
18*59599516SKenneth E. Jansen get_h(double xtmp[][4], double u[], double *h)
19*59599516SKenneth E. Jansen #endif
20*59599516SKenneth E. Jansen #ifdef sgi
21*59599516SKenneth E. Jansen void get_h(double xtmp[][4], double u[], double *h)
22*59599516SKenneth E. Jansen #endif
23*59599516SKenneth E. Jansen #ifdef decalp
24*59599516SKenneth E. Jansen void get_h(double xtmp[][4], double u[], double *h)
25*59599516SKenneth E. Jansen #endif
26*59599516SKenneth E. Jansen #ifdef intel
27*59599516SKenneth E. Jansen void GET_H(double xtmp[][4], double u[], double *h)
28*59599516SKenneth E. Jansen #endif
29*59599516SKenneth E. Jansen {
30*59599516SKenneth E. Jansen   double x[4][3];
31*59599516SKenneth E. Jansen   int i,j;
32*59599516SKenneth E. Jansen   /*recall that arrays in fortran and C are transposed */
33*59599516SKenneth E. Jansen   for(i=0; i < 4; i++)
34*59599516SKenneth E. Jansen     for(j=0; j < 3; j++)
35*59599516SKenneth E. Jansen       x[i][j] = xtmp[j][i];
36*59599516SKenneth E. Jansen 
37*59599516SKenneth E. Jansen   *h = length(x,u);
38*59599516SKenneth E. Jansen }
39*59599516SKenneth E. Jansen 
length(double x[4][3],double u[])40*59599516SKenneth E. Jansen double length(double x[4][3],double u[] ){
41*59599516SKenneth E. Jansen   int nint;
42*59599516SKenneth E. Jansen   double tmp[3],he;
43*59599516SKenneth E. Jansen   double points[4][3];
44*59599516SKenneth E. Jansen 
45*59599516SKenneth E. Jansen   /* compute the intersection points. nint is returned
46*59599516SKenneth E. Jansen      as the number of faces that this line intersected
47*59599516SKenneth E. Jansen      within the tet */
48*59599516SKenneth E. Jansen   nint = intersect(x,u,points);
49*59599516SKenneth E. Jansen 
50*59599516SKenneth E. Jansen   /* if nint is larger than one, then the vector intersected
51*59599516SKenneth E. Jansen      an edge (nint=3) or corner (nint=4) of the tet. In this
52*59599516SKenneth E. Jansen      case, we need to make sure that we are computing the
53*59599516SKenneth E. Jansen      length between two different points. */
54*59599516SKenneth E. Jansen 
55*59599516SKenneth E. Jansen   if(nint > 1){			/* vecEqual returns 1 if
56*59599516SKenneth E. Jansen 				   these two vectors are the same.
57*59599516SKenneth E. Jansen 				   */
58*59599516SKenneth E. Jansen     if( vecEqual(points[0],points[1]) ){
59*59599516SKenneth E. Jansen       if( vecEqual(points[0],points[2]) ){
60*59599516SKenneth E. Jansen 	diffVt(points[0],points[3],tmp);
61*59599516SKenneth E. Jansen       }
62*59599516SKenneth E. Jansen       else{
63*59599516SKenneth E. Jansen 	diffVt(points[0],points[2],tmp);
64*59599516SKenneth E. Jansen       }
65*59599516SKenneth E. Jansen     }
66*59599516SKenneth E. Jansen     else{
67*59599516SKenneth E. Jansen       diffVt(points[0],points[1],tmp);
68*59599516SKenneth E. Jansen     }
69*59599516SKenneth E. Jansen   }
70*59599516SKenneth E. Jansen   else{
71*59599516SKenneth E. Jansen     diffVt(points[0],points[1],tmp);
72*59599516SKenneth E. Jansen   }
73*59599516SKenneth E. Jansen 
74*59599516SKenneth E. Jansen   /* compute the length of the element */
75*59599516SKenneth E. Jansen   he = vecMag(tmp);
76*59599516SKenneth E. Jansen   return he;
77*59599516SKenneth E. Jansen }
78*59599516SKenneth E. Jansen 
79*59599516SKenneth E. Jansen /*
80*59599516SKenneth E. Jansen    This function returns the intersection points of a line
81*59599516SKenneth E. Jansen    through the centroid of a tet in a given direction.
82*59599516SKenneth E. Jansen */
83*59599516SKenneth E. Jansen 
84*59599516SKenneth E. Jansen 
85*59599516SKenneth E. Jansen /* u_line is a function that defines the parametric equation
86*59599516SKenneth E. Jansen    of a line given a point on the lineg, a direction, and a
87*59599516SKenneth E. Jansen    parameter value */
88*59599516SKenneth E. Jansen 
89*59599516SKenneth E. Jansen void u_line(double s, double xc[3], double udir[3], double pnt[3]);
90*59599516SKenneth E. Jansen 
91*59599516SKenneth E. Jansen /*
92*59599516SKenneth E. Jansen   All points which intersect the tet are returned, however
93*59599516SKenneth E. Jansen   only two of them need be used. The value of the function on
94*59599516SKenneth E. Jansen   exit is the number of points of intersection, ie. the number
95*59599516SKenneth E. Jansen   of faces not parallel to udir */
96*59599516SKenneth E. Jansen 
intersect(double x[4][3],double u[],double points[4][3])97*59599516SKenneth E. Jansen int intersect(double x[4][3],double u[],double points[4][3] ){
98*59599516SKenneth E. Jansen   int pos = 0;
99*59599516SKenneth E. Jansen   double tol = 0.000001;
100*59599516SKenneth E. Jansen   double eps = 0.000001;
101*59599516SKenneth E. Jansen   int face,i,j,k;
102*59599516SKenneth E. Jansen   double xc[3];
103*59599516SKenneth E. Jansen   double xbar[3][3];
104*59599516SKenneth E. Jansen   double xref[3],v1[3],v2[3],normal[3];
105*59599516SKenneth E. Jansen   /* define local vertex numbers of four faces of the tet */
106*59599516SKenneth E. Jansen   int f_index[4][3] = {{0,1,2},{1,3,2},{0,2,3},{0,3,1}};
107*59599516SKenneth E. Jansen   double n_dot_u;
108*59599516SKenneth E. Jansen   double xr_xc[3], s, pt[3];
109*59599516SKenneth E. Jansen 
110*59599516SKenneth E. Jansen   /* compute centroid coordinates */
111*59599516SKenneth E. Jansen   for(i=0; i<3; i++)
112*59599516SKenneth E. Jansen     xc[i] = 0.25*(x[0][i]+x[1][i]+x[2][i]+x[3][i]);
113*59599516SKenneth E. Jansen 
114*59599516SKenneth E. Jansen   /* loop over each face */
115*59599516SKenneth E. Jansen   for( face= 0 ; face< 4; face++ ){
116*59599516SKenneth E. Jansen     /* compute coordinates of this face */
117*59599516SKenneth E. Jansen     for( j= 0 ; j<3 ; j++)
118*59599516SKenneth E. Jansen       for( k= 0; k< 3; k++)
119*59599516SKenneth E. Jansen 	xbar[j][k] = x[f_index[face][j]][k];
120*59599516SKenneth E. Jansen 
121*59599516SKenneth E. Jansen     /* set reference coordinate */
122*59599516SKenneth E. Jansen     if( face != 2 ){
123*59599516SKenneth E. Jansen       for( i= 0; i<3; i++ )
124*59599516SKenneth E. Jansen 	xref[i] = xbar[0][i];
125*59599516SKenneth E. Jansen     }
126*59599516SKenneth E. Jansen     else{			/* face 2 is the only face that
127*59599516SKenneth E. Jansen 				 can't use xbar[0] as a reference */
128*59599516SKenneth E. Jansen       for( i= 0; i<3; i++ )
129*59599516SKenneth E. Jansen 	xref[i] = xbar[1][i];
130*59599516SKenneth E. Jansen     }
131*59599516SKenneth E. Jansen 
132*59599516SKenneth E. Jansen     /* compute two vectors which describe the plane of this
133*59599516SKenneth E. Jansen        face */
134*59599516SKenneth E. Jansen     for( i=0; i< 3; i++){
135*59599516SKenneth E. Jansen       v1[i] = xbar[1][i] - xbar[0][i];
136*59599516SKenneth E. Jansen       v2[i] = xbar[2][i] - xbar[0][i];
137*59599516SKenneth E. Jansen     }
138*59599516SKenneth E. Jansen     /* get the normal to this plane */
139*59599516SKenneth E. Jansen     crossProd(v1,v2,normal);
140*59599516SKenneth E. Jansen 
141*59599516SKenneth E. Jansen     n_dot_u = dotProd(normal,u);
142*59599516SKenneth E. Jansen 
143*59599516SKenneth E. Jansen     /* if u is not parallel to this face, then find
144*59599516SKenneth E. Jansen        the point of intersection */
145*59599516SKenneth E. Jansen     if( fabs(n_dot_u) > eps ){
146*59599516SKenneth E. Jansen       diffVt( xref, xc, xr_xc );
147*59599516SKenneth E. Jansen 
148*59599516SKenneth E. Jansen       /* s is the parameter value where the line parallel to
149*59599516SKenneth E. Jansen 	 to the vector u intersects this face*/
150*59599516SKenneth E. Jansen       s = dotProd(normal,xr_xc)/n_dot_u;
151*59599516SKenneth E. Jansen 
152*59599516SKenneth E. Jansen       u_line(s,xc,u,pt); /* find intersection point */
153*59599516SKenneth E. Jansen 
154*59599516SKenneth E. Jansen       /* if this point lies on the tet, then save it */
155*59599516SKenneth E. Jansen       if( isPntInTri(xbar,normal,pt,tol) ){
156*59599516SKenneth E. Jansen 	for(i=0; i<3; i++)
157*59599516SKenneth E. Jansen 	  points[pos][i] = pt[i];
158*59599516SKenneth E. Jansen 	pos += 1;
159*59599516SKenneth E. Jansen       }
160*59599516SKenneth E. Jansen     }
161*59599516SKenneth E. Jansen     else{			/* do nothing */
162*59599516SKenneth E. Jansen 
163*59599516SKenneth E. Jansen     }
164*59599516SKenneth E. Jansen   }
165*59599516SKenneth E. Jansen 
166*59599516SKenneth E. Jansen   return pos;
167*59599516SKenneth E. Jansen }
168*59599516SKenneth E. Jansen 
169*59599516SKenneth E. Jansen /* parametric equation of the line passing through xc
170*59599516SKenneth E. Jansen    in the direction of u.
171*59599516SKenneth E. Jansen */
172*59599516SKenneth E. Jansen 
u_line(double s,double xc[3],double udir[3],double pnt[3])173*59599516SKenneth E. Jansen void u_line(double s, double xc[3], double udir[3], double pnt[3]){
174*59599516SKenneth E. Jansen   int i;
175*59599516SKenneth E. Jansen   for(i=0; i<3; i++)
176*59599516SKenneth E. Jansen     pnt[i] = xc[i]+s*udir[i];
177*59599516SKenneth E. Jansen }
178*59599516SKenneth E. Jansen 
179*59599516SKenneth E. Jansen 
diffVt(double vec1[3],double vec2[3],double ans[3])180*59599516SKenneth E. Jansen void diffVt(double vec1[3],double vec2[3], double ans[3]){
181*59599516SKenneth E. Jansen   ans[0] = vec1[0]-vec2[0];
182*59599516SKenneth E. Jansen   ans[1] = vec1[1]-vec2[1];
183*59599516SKenneth E. Jansen   ans[2] = vec1[2]-vec2[2];
184*59599516SKenneth E. Jansen }
185*59599516SKenneth E. Jansen 
crossProd(double a[3],double b[3],double ans[3])186*59599516SKenneth E. Jansen void crossProd(double a[3], double b[3], double ans[3]){
187*59599516SKenneth E. Jansen   ans[0] = a[1]*b[2]-b[1]*a[2];
188*59599516SKenneth E. Jansen   ans[1] = a[2]*b[0]-b[2]*a[0];
189*59599516SKenneth E. Jansen   ans[2] = a[0]*b[1]-b[0]*a[1];
190*59599516SKenneth E. Jansen }
191*59599516SKenneth E. Jansen 
dotProd(double a[3],double b[3])192*59599516SKenneth E. Jansen double dotProd(double a[3], double b[3]){
193*59599516SKenneth E. Jansen   return a[0]*b[0]+a[1]*b[1]+a[2]*b[2];
194*59599516SKenneth E. Jansen }
195*59599516SKenneth E. Jansen 
vecMag(double a[3])196*59599516SKenneth E. Jansen double vecMag(double a[3]){
197*59599516SKenneth E. Jansen   return sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);
198*59599516SKenneth E. Jansen }
199*59599516SKenneth E. Jansen 
vecEqual(double a[3],double b[3])200*59599516SKenneth E. Jansen int vecEqual(double a[3], double b[3]){
201*59599516SKenneth E. Jansen   return (a[0]==b[0] && a[1]==b[1] && a[2]==b[2]);
202*59599516SKenneth E. Jansen }
203*59599516SKenneth E. Jansen 
204*59599516SKenneth E. Jansen /*
205*59599516SKenneth E. Jansen Determines if a point is inside or out of a triangle
206*59599516SKenneth E. Jansen Pt will be declared in triangle if distance to side < tol
207*59599516SKenneth E. Jansen if u want the tolerancing to be relative to 't_xyz',
208*59599516SKenneth E. Jansen pass tol (absolute tolerance) * size of 't_xyz'
209*59599516SKenneth E. Jansen */
210*59599516SKenneth E. Jansen 
isPntInTri(double t_xyz[3][3],double t_normal[3],double p_xyz[3],double tol)211*59599516SKenneth E. Jansen int isPntInTri(
212*59599516SKenneth E. Jansen  double t_xyz[3][3],
213*59599516SKenneth E. Jansen  double t_normal[3], /* Normal to triangle (not normed) */
214*59599516SKenneth E. Jansen  double p_xyz[3],
215*59599516SKenneth E. Jansen  double tol
216*59599516SKenneth E. Jansen )
217*59599516SKenneth E. Jansen 
218*59599516SKenneth E. Jansen {
219*59599516SKenneth E. Jansen 
220*59599516SKenneth E. Jansen  double cross_p[3];
221*59599516SKenneth E. Jansen  double d;
222*59599516SKenneth E. Jansen  int side;
223*59599516SKenneth E. Jansen  int status;
224*59599516SKenneth E. Jansen  double cross_p_sqnorm;
225*59599516SKenneth E. Jansen  double dnbr;
226*59599516SKenneth E. Jansen  double dtol;
227*59599516SKenneth E. Jansen  double t_vec[3];
228*59599516SKenneth E. Jansen  double t_vec_norm;
229*59599516SKenneth E. Jansen  double tp_vec[3];
230*59599516SKenneth E. Jansen  double tp_vec_sqnorm;
231*59599516SKenneth E. Jansen 
232*59599516SKenneth E. Jansen  status= 1;
233*59599516SKenneth E. Jansen 
234*59599516SKenneth E. Jansen  for ( side= 0 ; side< 3 ; side++ ) {
235*59599516SKenneth E. Jansen 
236*59599516SKenneth E. Jansen     diffVt(t_xyz[(side+1)%3],t_xyz[side],t_vec);
237*59599516SKenneth E. Jansen     crossProd(t_normal,t_vec,cross_p);
238*59599516SKenneth E. Jansen     cross_p_sqnorm= dotProd(cross_p,cross_p);
239*59599516SKenneth E. Jansen 
240*59599516SKenneth E. Jansen     diffVt(p_xyz,t_xyz[side],tp_vec);
241*59599516SKenneth E. Jansen 
242*59599516SKenneth E. Jansen     d= dotProd(cross_p,tp_vec);
243*59599516SKenneth E. Jansen     dnbr= d * d;
244*59599516SKenneth E. Jansen     dtol= tol*tol*cross_p_sqnorm;
245*59599516SKenneth E. Jansen 
246*59599516SKenneth E. Jansen     if ( dnbr < dtol ) {
247*59599516SKenneth E. Jansen 
248*59599516SKenneth E. Jansen        /*
249*59599516SKenneth E. Jansen        Pt is considered to be on the side (extended to infinity)
250*59599516SKenneth E. Jansen        */
251*59599516SKenneth E. Jansen 
252*59599516SKenneth E. Jansen        /*
253*59599516SKenneth E. Jansen        Make sure distance to point 0 or 1 less than ...
254*59599516SKenneth E. Jansen        */
255*59599516SKenneth E. Jansen 
256*59599516SKenneth E. Jansen        t_vec_norm= vecMag(t_vec);
257*59599516SKenneth E. Jansen        dtol= t_vec_norm + tol;
258*59599516SKenneth E. Jansen        dtol *= dtol;
259*59599516SKenneth E. Jansen 
260*59599516SKenneth E. Jansen        tp_vec_sqnorm= dotProd(tp_vec,tp_vec);
261*59599516SKenneth E. Jansen        if ( tp_vec_sqnorm > dtol ) {
262*59599516SKenneth E. Jansen           status= 0;
263*59599516SKenneth E. Jansen           break;
264*59599516SKenneth E. Jansen        }
265*59599516SKenneth E. Jansen 
266*59599516SKenneth E. Jansen        diffVt(p_xyz,t_xyz[(side+1)%3],tp_vec);
267*59599516SKenneth E. Jansen        tp_vec_sqnorm= dotProd(tp_vec,tp_vec);
268*59599516SKenneth E. Jansen        if ( tp_vec_sqnorm > dtol ) {
269*59599516SKenneth E. Jansen           status= 0;
270*59599516SKenneth E. Jansen           break;
271*59599516SKenneth E. Jansen        }
272*59599516SKenneth E. Jansen 
273*59599516SKenneth E. Jansen        continue;
274*59599516SKenneth E. Jansen     }
275*59599516SKenneth E. Jansen 
276*59599516SKenneth E. Jansen     if ( d > 0.0 ) {
277*59599516SKenneth E. Jansen 
278*59599516SKenneth E. Jansen        /*
279*59599516SKenneth E. Jansen        Pt is strictly in the interior of the side
280*59599516SKenneth E. Jansen        */
281*59599516SKenneth E. Jansen     }
282*59599516SKenneth E. Jansen     else if ( d < 0.0 ) {
283*59599516SKenneth E. Jansen 
284*59599516SKenneth E. Jansen        /*
285*59599516SKenneth E. Jansen        Pt is strictly in the outisde of the side
286*59599516SKenneth E. Jansen        */
287*59599516SKenneth E. Jansen 
288*59599516SKenneth E. Jansen        status= 0;
289*59599516SKenneth E. Jansen        break;
290*59599516SKenneth E. Jansen     }
291*59599516SKenneth E. Jansen 
292*59599516SKenneth E. Jansen  }
293*59599516SKenneth E. Jansen 
294*59599516SKenneth E. Jansen  return status;
295*59599516SKenneth E. Jansen 
296*59599516SKenneth E. Jansen }
297*59599516SKenneth E. Jansen 
298*59599516SKenneth E. Jansen 
299*59599516SKenneth E. Jansen 
300*59599516SKenneth E. Jansen 
301*59599516SKenneth E. Jansen 
302*59599516SKenneth E. Jansen 
303*59599516SKenneth E. Jansen 
304*59599516SKenneth E. Jansen 
305*59599516SKenneth E. Jansen 
306*59599516SKenneth E. Jansen 
307*59599516SKenneth E. Jansen 
308