13 #define obbox_calc_2 PREFIXED_NAME(obbox_calc_2)
14 #define obbox_calc_3 PREFIXED_NAME(obbox_calc_3)
24 unsigned g,
unsigned s,
unsigned n)
26 if(g==1)
for(;
n;--
n,in+=s) *out++ = *in;
29 for(;
n;--
n,in+=s) memcpy(out,in,g*
sizeof(
double)), out+=g;
35 const double idet = 1/(A[0]*A[3]-A[1]*A[2]);
37 inv[1] = -(idet*A[1]);
38 inv[2] = -(idet*A[2]);
44 const double a = A[4]*A[8]-A[5]*A[7],
45 b = A[5]*A[6]-A[3]*A[8],
46 c = A[3]*A[7]-A[4]*A[6],
47 idet = 1/(A[0]*a+A[1]*b+A[2]*c);
49 inv[1] = idet*(A[2]*A[7]-A[1]*A[8]);
50 inv[2] = idet*(A[1]*A[5]-A[2]*A[4]);
52 inv[4] = idet*(A[0]*A[8]-A[2]*A[6]);
53 inv[5] = idet*(A[2]*A[3]-A[0]*A[5]);
55 inv[7] = idet*(A[1]*A[6]-A[0]*A[7]);
56 inv[8] = idet*(A[0]*A[4]-A[1]*A[3]);
62 m.
min = b.min<a.min?b.min:a.min,
63 m.
max = a.max>b.max?a.max:b.max;
69 double a = (b.min+b.max)/2, l = (b.max-b.min)*(1+tol)/2;
75 static void bbox_2_tfm(
double *
out,
const double x0[2],
const double Ji[4],
76 const double *
x,
const double *
y,
unsigned n)
80 const double dx = x[
i]-x0[0], dy = y[
i]-x0[1];
81 out[
i] = Ji[0]*dx + Ji[1]*dy;
82 out[n+
i] = Ji[2]*dx + Ji[3]*dy;
86 static void bbox_3_tfm(
double *
out,
const double x0[3],
const double Ji[9],
87 const double *
x,
const double *
y,
const double *
z,
92 const double dx = x[
i]-x0[0], dy = y[
i]-x0[1], dz = z[
i]-x0[2];
93 out[
i] = Ji[0]*dx + Ji[1]*dy + Ji[2]*dz;
94 out[ n+
i] = Ji[3]*dx + Ji[4]*dy + Ji[5]*dz;
95 out[2*n+
i] = Ji[6]*dx + Ji[7]*dy + Ji[8]*dz;
103 const double x,
const double y)
105 const double bx = (x-b->
x[0].
min)*(b->
x[0].
max-x);
106 return bx<0 ? bx : (y-b->
x[1].
min)*(b->
x[1].
max-y);
111 const double x,
const double y)
114 if(bxy<0)
return bxy;
else {
115 const double dx = x-b->
c0[0], dy = y-b->
c0[1];
116 const double r = b->
A[0]*dx + b->
A[1]*dy,
117 s = b->
A[2]*dx + b->
A[3]*dy;
118 const double br = (r+1)*(1-r);
119 return br<0 ? br : (s+1)*(1-s);
125 #define DO_MAX(a,b) do { unsigned temp = b; if(temp>a) a=temp; } while(0)
128 const double *
const elx[2],
129 const unsigned n[2],
uint nel,
130 const unsigned m[2],
const double tol)
132 const double *x = elx[0], *y = elx[1];
133 const unsigned nr = n[0],
ns = n[1];
134 const unsigned mr = m[0], ms = m[1];
136 const unsigned nrs = nr*
ns;
140 unsigned wsize = 4*ns+2*ms;
144 data =
tmalloc(
double, 2*(nr+ns)+lbsize0+lbsize1+wsize);
147 double *
const I0r = data, *
const I0s = data+2*
nr;
148 double *
const lob_bnd_data_r = data+2*(nr+
ns),
149 *
const lob_bnd_data_s = data+2*(nr+ns)+lbsize0;
150 double *
const work = data+2*(nr+
ns)+lbsize0+lbsize1;
152 #define SETUP_DIR(r) do { \
153 lagrange_fun *const lag = gll_lag_setup(work, n##r); \
154 lag(I0##r, work,n##r,1, 0); \
155 lob_bnd_setup(lob_bnd_data_##r, n##r,m##r); \
162 for(;nel;--nel,x+=nrs,y+=nrs,++
out) {
163 double x0[2], J[4], Ji[4];
167 x0[0] =
tensor_ig2(J , I0r,nr, I0s,ns, x, work);
168 x0[1] =
tensor_ig2(J+2, I0r,nr, I0s,ns, y, work);
172 #define DO_BOUND(bnd,merge,r,x,work) do { \
173 struct dbl_range b = \
174 lob_bnd_1(lob_bnd_data_##r,n##r,m##r, x, work); \
175 if(merge) bnd=dbl_range_merge(bnd,b); else bnd=b; \
179 #define DO_EDGE(merge,r,x,y,work) do { \
180 DO_BOUND(ab[0],merge,r,x,work); \
181 DO_BOUND(ab[1],merge,r,y,work); \
182 bbox_2_tfm(work, x0,Ji, x,y,n##r); \
183 DO_BOUND(tb[0],merge,r,(work) ,(work)+2*n##r); \
184 DO_BOUND(tb[1],merge,r,(work)+n##r,(work)+2*n##r); \
188 DO_EDGE(1,r,&x[nrs-nr],&y[nrs-nr],work);
191 #define GET_EDGE(off) do { \
192 copy_strided(work , x+off,1,nr,ns); \
193 copy_strided(work+ns, y+off,1,nr,ns); \
194 DO_EDGE(1,s,work,work+ns,work+2*ns); \
208 const double av0=(tb[0].
min+tb[0].
max)/2, av1=(tb[1].
min+tb[1].
max)/2;
209 out->
c0[0] = x0[0] + J[0]*av0 + J[1]*av1;
210 out->
c0[1] = x0[1] + J[2]*av0 + J[3]*av1;
213 const double di0 = 2/((1+tol)*(tb[0].
max-tb[0].
min)),
214 di1 = 2/((1+tol)*(tb[1].
max-tb[1].
min));
215 out->
A[0]=di0*Ji[0], out->
A[1]=di0*Ji[1];
216 out->
A[2]=di1*Ji[2], out->
A[3]=di1*Ji[3];
226 const double *
const elx[3],
227 const unsigned n[3],
uint nel,
228 const unsigned m[3],
const double tol)
230 const double *x = elx[0], *y = elx[1], *
z = elx[2];
231 const unsigned nr = n[0],
ns = n[1], nt = n[2];
232 const unsigned mr = m[0], ms = m[1], mt = m[2];
234 const unsigned nrs = nr*
ns, nrst = nr*ns*nt;
239 unsigned wsize = 3*nr*ns+2*mr*(ns+ms+1);
240 DO_MAX(wsize,6*nr*nt+2*mr*(nt+mt+1));
241 DO_MAX(wsize,6*ns*nt+2*ms*(nt+mt+1));
242 DO_MAX(wsize,2*nr*ns+3*nr);
246 data =
tmalloc(
double, 2*(nr+ns+nt)+lbsize0+lbsize1+lbsize2+wsize);
249 double *
const I0r = data, *
const I0s = I0r+2*
nr, *
const I0t = I0s+2*
ns;
250 double *
const lob_bnd_data_r = data+2*(nr+ns+nt),
251 *
const lob_bnd_data_s = data+2*(nr+ns+nt)+lbsize0,
252 *
const lob_bnd_data_t = data+2*(nr+ns+nt)+lbsize0+lbsize1;
253 double *
const work = data+2*(nr+ns+nt)+lbsize0+lbsize1+lbsize2;
255 #define SETUP_DIR(r) do { \
256 lagrange_fun *const lag = gll_lag_setup(work, n##r); \
257 lag(I0##r, work,n##r,1, 0); \
258 lob_bnd_setup(lob_bnd_data_##r, n##r,m##r); \
265 for(;nel;--nel,x+=nrst,y+=nrst,z+=nrst,++
out) {
266 double x0[3], J[9], Ji[9];
270 #define EVAL_AT_0(d,x) \
271 x0[d] = tensor_ig3(J+3*d, I0r,nr, I0s,ns, I0t,nt, x, work)
277 #define DO_BOUND(bnd,merge,r,s,x,work) do { \
278 struct dbl_range b = \
279 lob_bnd_2(lob_bnd_data_##r,n##r,m##r, \
280 lob_bnd_data_##s,n##s,m##s, x, work); \
281 if(merge) bnd=dbl_range_merge(bnd,b); else bnd=b; \
285 #define DO_FACE(merge,r,s,x,y,z,work) do { \
286 DO_BOUND(ab[0],merge,r,s,x,work); \
287 DO_BOUND(ab[1],merge,r,s,y,work); \
288 DO_BOUND(ab[2],merge,r,s,z,work); \
289 bbox_3_tfm(work, x0,Ji, x,y,z,n##r*n##s); \
290 DO_BOUND(tb[0],merge,r,s,(work) ,(work)+3*n##r*n##s); \
291 DO_BOUND(tb[1],merge,r,s,(work)+ n##r*n##s,(work)+3*n##r*n##s); \
292 DO_BOUND(tb[2],merge,r,s,(work)+2*n##r*n##s,(work)+3*n##r*n##s); \
296 DO_FACE(1,r,s,&x[nrst-nrs],&y[nrst-nrs],&z[nrst-nrs],work);
299 #define GET_FACE(r,s,off,n1,n2,n3) do { \
300 copy_strided(work , x+off,n1,n2,n3); \
301 copy_strided(work+ n##r*n##s, y+off,n1,n2,n3); \
302 copy_strided(work+2*n##r*n##s, z+off,n1,n2,n3); \
303 DO_FACE(1,r,s,work,work+n##r*n##s,work+2*n##r*n##s,work+3*n##r*n##s); \
320 const double av0 = (tb[0].
min+tb[0].
max)/2,
321 av1 = (tb[1].
min+tb[1].
max)/2,
322 av2 = (tb[2].
min+tb[2].
max)/2;
323 out->
c0[0] = x0[0] + J[0]*av0 + J[1]*av1 + J[2]*av2;
324 out->
c0[1] = x0[1] + J[3]*av0 + J[4]*av1 + J[5]*av2;
325 out->
c0[2] = x0[2] + J[6]*av0 + J[7]*av1 + J[8]*av2;
328 const double di0 = 2/((1+tol)*(tb[0].
max-tb[0].
min)),
329 di1 = 2/((1+tol)*(tb[1].
max-tb[1].
min)),
330 di2 = 2/((1+tol)*(tb[2].
max-tb[2].min));
331 out->
A[0]=di0*Ji[0], out->
A[1]=di0*Ji[1], out->
A[2]=di0*Ji[2];
332 out->
A[3]=di1*Ji[3], out->
A[4]=di1*Ji[4], out->
A[5]=di1*Ji[5];
333 out->
A[6]=di2*Ji[6], out->
A[7]=di2*Ji[7], out->
A[8]=di2*Ji[8];
static double tensor_ig2(double g[2], const double *wtr, uint nr, const double *wts, uint ns, const double *u, double *work)
#define DO_EDGE(merge, r, x, y, work)
#define tmalloc(type, count)
static const unsigned mr[D]
static struct dbl_range dbl_range_merge(struct dbl_range a, struct dbl_range b)
#define DO_FACE(merge, r, s, x, y, z, work)
#define GET_FACE(r, s, off, n1, n2, n3)
static void mat_inv_3(double inv[9], const double A[9])
static void copy_strided(double *out, const double *in, unsigned g, unsigned s, unsigned n)
static double elx[NR *NS]
static void mat_inv_2(double inv[4], const double A[4])
static double obbox_axis_test_2(const struct obbox_2 *const b, const double x[2])
static unsigned lob_bnd_size(unsigned n, unsigned m)
static void bbox_3_tfm(double *out, const double x0[3], const double Ji[9], const double *x, const double *y, const double *z, unsigned n)
static const unsigned nr[3]
*Als dX *Qf *Qf *dX *em X inv(chol(A)) Ai
static void bbox_2_tfm(double *out, const double x0[2], const double Ji[4], const double *x, const double *y, unsigned n)
static double obbox_test_2(const struct obbox_2 *const b, const double x[2])
static double work[TNR *NS]
establishes some macros to establish naming conventions
static struct dbl_range dbl_range_expand(struct dbl_range b, double tol)
static double y[NR *NS *NT *N]
static double z[NR *NS *NT *N]