ASCOT5
Loading...
Searching...
No Matches
wall_3d.c
Go to the documentation of this file.
1
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15#include <math.h>
16#include "../ascot5.h"
17#include "wall_3d.h"
18#include "../math.h"
19#include "../list.h"
20#include "../octree.h"
21#include "../print.h"
22
24
45int wall_3d_init(wall_3d_data* data, int nelements, real* x1x2x3, real* y1y2y3,
46 real* z1z2z3, int* flag) {
47
48 /* The data is to be in the format
49 * [x1 y1 z1 x2 y2 z2 x3 y3 z3; ... ]
50 */
51 data->n = nelements;
52 data->wall_tris = (real*)malloc(9 * nelements * sizeof(real));
53 real xmin = x1x2x3[0], xmax = x1x2x3[0];
54 real ymin = y1y2y3[0], ymax = y1y2y3[0];
55 real zmin = z1z2z3[0], zmax = z1z2z3[0];
56 for(int i = 0; i < nelements; i++) {
57 for(int j = 0; j < 3; j++) {
58 data->wall_tris[i*9 + j*3 + 0] = x1x2x3[3*i+j];
59 data->wall_tris[i*9 + j*3 + 1] = y1y2y3[3*i+j];
60 data->wall_tris[i*9 + j*3 + 2] = z1z2z3[3*i+j];
61
62 /* Find min & max values of the volume occupied by the wall */
63 xmin = fmin( xmin, x1x2x3[3*i+j] );
64 xmax = fmax( xmax, x1x2x3[3*i+j] );
65 ymin = fmin( ymin, y1y2y3[3*i+j] );
66 ymax = fmax( ymax, y1y2y3[3*i+j] );
67 zmin = fmin( zmin, z1z2z3[3*i+j] );
68 zmax = fmax( zmax, z1z2z3[3*i+j] );
69 }
70 }
71
72 /* Add a little bit of padding so we don't need to worry about triangles
73 clipping the edges */
74 data->xmin = xmin - 0.1;
75 data->xmax = xmax + 0.1;
76 data->ymin = ymin - 0.1;
77 data->ymax = ymax + 0.1;
78 data->zmin = zmin - 0.1;
79 data->zmax = zmax + 0.1;
80
81 /* Depth of the octree in which the triangles are sorted */
83 int ngrid = 1;
84 for(int i = 0; i < data->depth - 1; i++) {
85 ngrid *= 2;
86 }
87 data->ngrid = ngrid;
88
89 data->xgrid = (data->xmax - data->xmin) / data->ngrid;
90 data->ygrid = (data->ymax - data->ymin) / data->ngrid;
91 data->zgrid = (data->zmax - data->zmin) / data->ngrid;
92
95
96 print_out(VERBOSE_IO, "\n3D wall model (wall_3D)\n");
98 "Number of wall elements %d\n"
99 "Spanning xmin = %2.3f m, xmax = %2.3f m\n"
100 " ymin = %2.3f m, ymax = %2.3f m\n"
101 " zmin = %2.3f m, zmax = %2.3f m\n",
102 data->n,
103 data->xmin, data->xmax, data->ymin,
104 data->ymax, data->zmin, data->zmax);
105
106 data->flag = (int*)malloc(nelements * sizeof(int));
107 memcpy(data->flag, flag, data->n * sizeof(int));
108
109 return 0;
110}
111
118 free(data->tree_array);
119 free(data->wall_tris);
120}
121
128 GPU_MAP_TO_DEVICE(
129 data->wall_flag[0:data->n],
130 data->wall_tris[0:data->n*9],
131 data->tree_array[0:data->tree_array_size]
132 )
133}
134
146void wall_3d_init_tree(wall_3d_data* w, real* offload_array) {
147 /* create a list for holding the triangle ids in each cell */
148 int ncell = w->ngrid*w->ngrid*w->ngrid;
149 list_int_node** tri_list = (list_int_node**) malloc(ncell
150 *sizeof(list_int_node*));
151 int i;
152 for(i = 0; i < ncell; i++) {
153 list_int_create(&tri_list[i]);
154 }
155
156 /* iterate through all triangles and cells and fill the lists */
157 for(i = 0; i < w->n; i++) {
158 real t1[3], t2[3], t3[3];
159 t1[0] = offload_array[i*9];
160 t1[1] = offload_array[i*9+1];
161 t1[2] = offload_array[i*9+2];
162 t2[0] = offload_array[i*9+3];
163 t2[1] = offload_array[i*9+4];
164 t2[2] = offload_array[i*9+5];
165 t3[0] = offload_array[i*9+6];
166 t3[1] = offload_array[i*9+7];
167 t3[2] = offload_array[i*9+8];
168
169 int ix, iy, iz;
170 #pragma omp parallel for private(ix, iy, iz)
171 for(ix = 0; ix < w->ngrid; ix++) {
172 for(iy = 0; iy < w->ngrid; iy++) {
173 for(iz = 0; iz < w->ngrid; iz++) {
174 real c1[3], c2[3];
175 real epsilon = 1e-6;
176 c1[0] = w->xmin + ix * w->xgrid - epsilon;
177 c2[0] = w->xmin + (ix+1) * w->xgrid + epsilon;
178 c1[1] = w->ymin + iy * w->ygrid - epsilon;
179 c2[1] = w->ymin + (iy+1) * w->ygrid + epsilon;
180 c1[2] = w->zmin + iz * w->zgrid - epsilon;
181 c2[2] = w->zmin + (iz+1) * w->zgrid + epsilon;
182 int result = wall_3d_tri_in_cube(t1, t2, t3, c1, c2);
183 int cell_index = ix*w->ngrid*w->ngrid+iy*w->ngrid+iz;
184 if(result > 0) {
185 list_int_add(tri_list[cell_index], i);
186 }
187 }
188 }
189 }
190 }
191
192 /* construct an array from the triangle lists */
193 int list_size = 0;
194 for(i = 0; i < ncell; i++) {
195 list_size += list_int_size(tri_list[i]);
196 }
197
198 w->tree_array = (int*) malloc((2*ncell + list_size)*sizeof(int));
199 w->tree_array_size = 2*ncell + list_size;
200
201 int next_empty_list = ncell;
202 for(i = 0; i < ncell; i++) {
203 w->tree_array[i] = next_empty_list;
204 w->tree_array[next_empty_list] = list_int_size(tri_list[i]);
205 int j;
206 for(j = 0; j < w->tree_array[next_empty_list]; j++) {
207 w->tree_array[next_empty_list+j+1] = list_int_get(tri_list[i], j);
208 }
209 next_empty_list += w->tree_array[next_empty_list] + 1;
210 list_int_free(&tri_list[i]);
211 }
212 free(tri_list);
213}
214
230 if (w->n > 1000000){
232 "Starting to initialize 3D-wall octree with %d triangles.\n",
233 w->n);
234 }
235
236 /* Construct the octree and store triangles there */
237 octree_node* tree;
238 octree_create(&tree, w->xmin, w->xmax, w->ymin, w->ymax, w->zmin, w->zmax,
239 w->depth);
240 int i;
241 for(i = 0; i < w->n; i++) {
242 real t1[3], t2[3], t3[3];
243 t1[0] = w->wall_tris[i*9];
244 t1[1] = w->wall_tris[i*9+1];
245 t1[2] = w->wall_tris[i*9+2];
246 t2[0] = w->wall_tris[i*9+3];
247 t2[1] = w->wall_tris[i*9+4];
248 t2[2] = w->wall_tris[i*9+5];
249 t3[0] = w->wall_tris[i*9+6];
250 t3[1] = w->wall_tris[i*9+7];
251 t3[2] = w->wall_tris[i*9+8];
252 octree_add(tree, t1, t2, t3, i);
253 if (i%1000000==0 && i > 0){
254 print_out(VERBOSE_NORMAL, " Adding triangle %10d/%d.\n",i,w->n);
255 }
256 }
257
258 /* Create lists for triangles in each grid square and fill the lists
259 by querying the octree in each grid point */
260 int ncell = w->ngrid*w->ngrid*w->ngrid;
261 list_int_node** tri_list =
262 (list_int_node**) malloc(ncell * sizeof(list_int_node*));
263 int ix, iy, iz;
264 for(ix = 0; ix < w->ngrid; ix++) {
265 for(iy = 0; iy < w->ngrid; iy++) {
266 for(iz = 0; iz < w->ngrid; iz++) {
267 real p[3];
268 p[0] = w->xmin + ix * w->xgrid + 0.5*w->xgrid;
269 p[1] = w->ymin + iy * w->ygrid + 0.5*w->ygrid;
270 p[2] = w->zmin + iz * w->zgrid + 0.5*w->zgrid;
271
272 int cell_index = ix*w->ngrid*w->ngrid+iy*w->ngrid+iz;
273 tri_list[cell_index] = octree_get(tree, p);
274 }
275 }
276 }
277
278 /* construct an array from the triangle lists */
279 int list_size = 0;
280 for(i = 0; i < ncell; i++) {
281 list_size += list_int_size(tri_list[i]);
282 }
283 w->tree_array = (int*) malloc((2*ncell + list_size)*sizeof(int));
284 w->tree_array_size = 2*ncell + list_size;
285
286 int next_empty_list = ncell;
287 for(i = 0; i < ncell; i++) {
288 /* First ncell elements store the position where the actual cell data
289 * begins in tree_array */
290 w->tree_array[i] = next_empty_list;
291
292 /* The first data point in the actual cell data is the number of
293 * triangles in this cell */
294 w->tree_array[next_empty_list] = list_int_size(tri_list[i]);
295
296 /* Store triangle IDs that are located in this cell */
297 for(int j = 0; j < w->tree_array[next_empty_list]; j++) {
298 w->tree_array[next_empty_list+j+1] = list_int_get(tri_list[i], j);
299 }
300 next_empty_list += w->tree_array[next_empty_list] + 1;
301 }
302 free(tri_list);
303 octree_free(&tree);
304}
305
322int wall_3d_hit_wall(real r1, real phi1, real z1, real r2, real phi2,
323 real z2, wall_3d_data* wdata, real* w_coll) {
324 real rpz1[3], rpz2[3];
325 rpz1[0] = r1;
326 rpz1[1] = phi1;
327 rpz1[2] = z1;
328 rpz2[0] = r2;
329 rpz2[1] = phi2;
330 rpz2[2] = z2;
331
332 real q1[3], q2[3];
333 math_rpz2xyz(rpz1, q1);
334 math_rpz2xyz(rpz2, q2);
335
336 int ix1 = (int) floor((q1[0] - wdata->xmin)
337 / ((wdata->xmax - wdata->xmin) / (wdata->ngrid)));
338 int iy1 = (int) floor((q1[1] - wdata->ymin)
339 / ((wdata->ymax - wdata->ymin) / (wdata->ngrid)));
340 int iz1 = (int) floor((q1[2] - wdata->zmin)
341 / ((wdata->zmax - wdata->zmin) / (wdata->ngrid)));
342
343 int ix2 = (int) floor((q2[0] - wdata->xmin)
344 / ((wdata->xmax - wdata->xmin) / (wdata->ngrid)));
345 int iy2 = (int) floor((q2[1] - wdata->ymin)
346 / ((wdata->ymax - wdata->ymin) / (wdata->ngrid)));
347 int iz2 = (int) floor((q2[2] - wdata->zmin)
348 / ((wdata->zmax - wdata->zmin) / (wdata->ngrid)));
349
350 int hit_tri = 0;
351 real smallest_w = 1.1;
352
353 for(int i = 0; i <= abs(ix2-ix1); i++) {
354 for(int j = 0; j <= abs(iy2-iy1); j++) {
355 for(int k = 0; k <= abs(iz2-iz1); k++) {
356 int ix = ix1 + i*((int) copysign(1, ix2-ix1));
357 int iy = iy1 + j*((int) copysign(1, iy2-iy1));
358 int iz = iz1 + k*((int) copysign(1, iz2-iz1));
359
360 if(ix >= 0 && ix < wdata->ngrid && iy >= 0 && iy < wdata->ngrid
361 && iz >= 0 && iz < wdata->ngrid) {
362
363 int ilist = wdata->tree_array[ix*wdata->ngrid*wdata->ngrid
364 + iy*wdata->ngrid + iz];
365
366 for(int l = 0; l < wdata->tree_array[ilist]; l++) {
367 int itri = wdata->tree_array[ilist+l+1];
369 q1, q2,
370 &wdata->wall_tris[9*itri],
371 &wdata->wall_tris[9*itri+3],
372 &wdata->wall_tris[9*itri+6]);
373 if(w >= 0 && w < smallest_w) {
374 smallest_w = w;
375 hit_tri = itri+1;
376 }
377 }
378 }
379 }
380 }
381 }
382 *w_coll = smallest_w;
383 return hit_tri;
384}
385
402int wall_3d_hit_wall_full(real r1, real phi1, real z1, real r2, real phi2,
403 real z2, wall_3d_data* wdata, real* w_coll) {
404 real rpz1[3], rpz2[3];
405 rpz1[0] = r1;
406 rpz1[1] = phi1;
407 rpz1[2] = z1;
408 rpz2[0] = r2;
409 rpz2[1] = phi2;
410 rpz2[2] = z2;
411
412 real q1[3], q2[3];
413 math_rpz2xyz(rpz1, q1);
414 math_rpz2xyz(rpz2, q2);
415
416 int hit_tri = 0;
417 real smallest_w = 1.1;
418 real w;
419 int j;
420
421 for(j = 0; j < wdata->n; j++) {
422 w = wall_3d_tri_collision(q1, q2, &wdata->wall_tris[9*j],
423 &wdata->wall_tris[9*j+3], &wdata->wall_tris[9*j+6]);
424 if(w > 0) {
425 if(w < smallest_w) {
426 smallest_w = w;
427 hit_tri = j+1;
428 }
429 }
430 }
431
432 *w_coll = smallest_w;
433 return hit_tri;
434}
435
447int wall_3d_tri_in_cube(real t1[3], real t2[3], real t3[3], real bb1[3],
448 real bb2[3]) {
449 /* check if any point is inside the cube */
450 if(bb1[0] <= t1[0] && t1[0] <= bb2[0]
451 && bb1[1] <= t1[1] && t1[1] <= bb2[1]
452 && bb1[2] <= t1[2] && t1[2] <= bb2[2])
453 return 1;
454 if(bb1[0] < t2[0] && t2[0] <= bb2[0]
455 && bb1[1] <= t2[1] && t2[1] <= bb2[1]
456 && bb1[2] <= t2[2] && t2[2] <= bb2[2])
457 return 1;
458 if(bb1[0] <= t3[0] && t3[0] <= bb2[0]
459 && bb1[1] <= t3[1] && t3[1] <= bb2[1]
460 && bb1[2] <= t3[2] && t3[2] <= bb2[2])
461 return 1;
462
463 /* no such luck; check if any of the cube edges intersects the triangle */
464 real c000[3]; c000[0] = bb1[0]; c000[1] = bb1[1]; c000[2] = bb1[2];
465 real c100[3]; c100[0] = bb2[0]; c100[1] = bb1[1]; c100[2] = bb1[2];
466 real c010[3]; c010[0] = bb1[0]; c010[1] = bb2[1]; c010[2] = bb1[2];
467 real c110[3]; c110[0] = bb2[0]; c110[1] = bb2[1]; c110[2] = bb1[2];
468 real c001[3]; c001[0] = bb1[0]; c001[1] = bb1[1]; c001[2] = bb2[2];
469 real c101[3]; c101[0] = bb2[0]; c101[1] = bb1[1]; c101[2] = bb2[2];
470 real c011[3]; c011[0] = bb1[0]; c011[1] = bb2[1]; c011[2] = bb2[2];
471 real c111[3]; c111[0] = bb2[0]; c111[1] = bb2[1]; c111[2] = bb2[2];
472
473 if( wall_3d_tri_collision(c000, c100, t1, t2, t3) >= 0
474 || wall_3d_tri_collision(c000, c010, t1, t2, t3) >= 0
475 || wall_3d_tri_collision(c110, c010, t1, t2, t3) >= 0
476 || wall_3d_tri_collision(c110, c100, t1, t2, t3) >= 0
477 || wall_3d_tri_collision(c000, c001, t1, t2, t3) >= 0
478 || wall_3d_tri_collision(c010, c011, t1, t2, t3) >= 0
479 || wall_3d_tri_collision(c100, c101, t1, t2, t3) >= 0
480 || wall_3d_tri_collision(c110, c111, t1, t2, t3) >= 0
481 || wall_3d_tri_collision(c001, c101, t1, t2, t3) >= 0
482 || wall_3d_tri_collision(c001, c011, t1, t2, t3) >= 0
483 || wall_3d_tri_collision(c111, c011, t1, t2, t3) >= 0
484 || wall_3d_tri_collision(c111, c101, t1, t2, t3) >= 0)
485 return 1;
486
487 /* check for triangle edges intersecting cube quads */
488 if( wall_3d_quad_collision(t1, t2, c000, c100, c110, c010) == 1
489 || wall_3d_quad_collision(t1, t2, c000, c010, c011, c001) == 1
490 || wall_3d_quad_collision(t1, t2, c000, c100, c101, c001) == 1
491 || wall_3d_quad_collision(t1, t2, c010, c110, c111, c011) == 1
492 || wall_3d_quad_collision(t1, t2, c100, c101, c111, c110) == 1
493 || wall_3d_quad_collision(t1, t2, c001, c101, c111, c011) == 1)
494 return 1;
495 if( wall_3d_quad_collision(t3, t2, c000, c100, c110, c010) == 1
496 || wall_3d_quad_collision(t3, t2, c000, c010, c011, c001) == 1
497 || wall_3d_quad_collision(t3, t2, c000, c100, c101, c001) == 1
498 || wall_3d_quad_collision(t3, t2, c010, c110, c111, c011) == 1
499 || wall_3d_quad_collision(t3, t2, c100, c101, c111, c110) == 1
500 || wall_3d_quad_collision(t3, t2, c001, c101, c111, c011) == 1)
501 return 1;
502 if( wall_3d_quad_collision(t1, t3, c000, c100, c110, c010) == 1
503 || wall_3d_quad_collision(t1, t3, c000, c010, c011, c001) == 1
504 || wall_3d_quad_collision(t1, t3, c000, c100, c101, c001) == 1
505 || wall_3d_quad_collision(t1, t3, c010, c110, c111, c011) == 1
506 || wall_3d_quad_collision(t1, t3, c100, c101, c111, c110) == 1
507 || wall_3d_quad_collision(t1, t3, c001, c101, c111, c011) == 1)
508 return 1;
509 return 0;
510}
511
527double wall_3d_tri_collision(real q1[3], real q2[3], real t1[3], real t2[3],
528 real t3[3]) {
529 real q12[3], Q12[3];
530 Q12[0] = q2[0] - q1[0];
531 Q12[1] = q2[1] - q1[1];
532 Q12[2] = q2[2] - q1[2];
533 math_unit(Q12, q12);
534
535 real edge12[3];
536 edge12[0] = t2[0] - t1[0];
537 edge12[1] = t2[1] - t1[1];
538 edge12[2] = t2[2] - t1[2];
539
540 real edge13[3];
541 edge13[0] = t3[0] - t1[0];
542 edge13[1] = t3[1] - t1[1];
543 edge13[2] = t3[2] - t1[2];
544
545 real h[3];
546 math_cross(q12, edge13, h);
547 real det = math_dot(h, edge12);
548
549 /* Check that the triangle has non-zero area */
550 real normal[3], area;
551 math_cross(edge12, edge13, normal);
552 area = math_norm(normal);
553
554 real w = -1.0;
555 if( area > WALL_EPSILON ) {
556 /* If ray is parallel to the triangle, nudge it a little bit so we don't
557 have to handle annoying special cases */
558 if( fabs(det) < WALL_EPSILON ) {
559 Q12[0] = q2[0] - q1[0] + 2 * WALL_EPSILON * normal[0] / area;
560 Q12[1] = q2[1] - q1[1] + 2 * WALL_EPSILON * normal[1] / area;
561 Q12[2] = q2[2] - q1[2] + 2 * WALL_EPSILON * normal[2] / area;
562 math_unit(Q12, q12);
563 math_cross(q12, edge13, h);
564 det = math_dot(h, edge12);
565 }
566
567 real tq11[3];
568 tq11[0] = q1[0] - t1[0];
569 tq11[1] = q1[1] - t1[1];
570 tq11[2] = q1[2] - t1[2];
571
572 real n[3];
573 math_cross(tq11, edge12, n);
574
575 real u = math_dot(h, tq11) / det;
576 real v = math_dot(q12, n) / det;
577
578 if( ( u >= 0.0 && u <= 1.0 ) && ( v >= 0.0 && u + v <= 1.0 ) ) {
579 w = ( math_dot(n, edge13) / det ) / math_norm(Q12);
580 if( w > 1.0 ) {
581 w = -1.0;
582 }
583 }
584 }
585
586 return w;
587
588}
589
602int wall_3d_quad_collision(real q1[3], real q2[3], real t1[3], real t2[3],
603 real t3[3], real t4[3]) {
604 if(wall_3d_tri_collision(q1, q2, t1, t2, t3) >= 0
605 || wall_3d_tri_collision(q1, q2, t1, t3, t4) >= 0)
606 return 1;
607 else
608 return 0;
609}
Main header file for ASCOT5.
double real
Definition ascot5.h:85
#define WALL_OCTREE_DEPTH
Default depth of octree struct.
Definition ascot5.h:134
int list_int_size(list_int_node *list)
Get list size.
Definition list.c:86
void list_int_create(list_int_node **list)
Create an empty list.
Definition list.c:16
void list_int_free(list_int_node **list)
Deallocate this list and all lists it is linked to.
Definition list.c:28
int list_int_get(list_int_node *list, int index)
Retrieve the data stored in a list node.
Definition list.c:69
void list_int_add(list_int_node *list, int data)
Add new node to the end of the chain.
Definition list.c:48
Header file for list.c.
Header file for math.c.
#define math_dot(a, b)
Calculate dot product a[3] dot b[3].
Definition math.h:31
#define math_unit(a, b)
Calculate unit vector b from a 3D vector a.
Definition math.h:73
#define math_rpz2xyz(rpz, xyz)
Convert cylindrical coordinates rpz to cartesian coordinates xyz.
Definition math.h:81
#define math_cross(a, b, c)
Calculate cross product for 3D vectors c = a x b.
Definition math.h:34
#define math_norm(a)
Calculate norm of 3D vector a.
Definition math.h:67
void octree_add(octree_node *node, real t1[3], real t2[3], real t3[3], int id)
Add triangle to the node(s) it belongs to.
Definition octree.c:123
void octree_free(octree_node **node)
Free octree node and all its child nodes.
Definition octree.c:91
void octree_create(octree_node **node, real x_min, real x_max, real y_min, real y_max, real z_min, real z_max, int depth)
Create octree of given depth.
Definition octree.c:46
list_int_node * octree_get(octree_node *node, real p[3])
Get that leaf node's linked list the given coordinate belongs to.
Definition octree.c:164
Header file for octree.c.
Macros for printing console output.
#define print_out(v,...)
Print to standard output.
Definition print.h:31
@ VERBOSE_NORMAL
Definition print.h:18
@ VERBOSE_IO
Definition print.h:20
Linked list node that stores int data.
Definition list.h:12
Struct representing single octree node.
Definition octree.h:17
3D wall data parameters
Definition wall_3d.h:16
real zgrid
Definition wall_3d.h:26
int * tree_array
Array storing information what triangles given octree cell stores.
Definition wall_3d.h:41
real zmax
Definition wall_3d.h:25
int * flag
Definition wall_3d.h:31
real xmax
Definition wall_3d.h:19
real zmin
Definition wall_3d.h:24
real ymin
Definition wall_3d.h:21
real xmin
Definition wall_3d.h:18
real * wall_tris
Definition wall_3d.h:30
real xgrid
Definition wall_3d.h:20
real ygrid
Definition wall_3d.h:23
real ymax
Definition wall_3d.h:22
int wall_3d_tri_in_cube(real t1[3], real t2[3], real t3[3], real bb1[3], real bb2[3])
Check if any part of a triangle is inside a box.
Definition wall_3d.c:447
void wall_3d_init_tree(wall_3d_data *w, real *offload_array)
Construct wall octree iteratively.
Definition wall_3d.c:146
int wall_3d_hit_wall_full(real r1, real phi1, real z1, real r2, real phi2, real z2, wall_3d_data *wdata, real *w_coll)
Check if trajectory from (r1, phi1, z1) to (r2, phi2, z2) intersects the wall against all triangles.
Definition wall_3d.c:402
double wall_3d_tri_collision(real q1[3], real q2[3], real t1[3], real t2[3], real t3[3])
Check if a line segment intersects a triangle.
Definition wall_3d.c:527
void wall_3d_free(wall_3d_data *data)
Free allocated resources.
Definition wall_3d.c:117
void wall_3d_offload(wall_3d_data *data)
Offload data to the accelerator.
Definition wall_3d.c:127
int wall_3d_init(wall_3d_data *data, int nelements, real *x1x2x3, real *y1y2y3, real *z1z2z3, int *flag)
Initialize 3D wall data and check inputs.
Definition wall_3d.c:45
int wall_3d_hit_wall(real r1, real phi1, real z1, real r2, real phi2, real z2, wall_3d_data *wdata, real *w_coll)
Check if trajectory from (r1, phi1, z1) to (r2, phi2, z2) intersects the wall using the octree struct...
Definition wall_3d.c:322
int wall_3d_quad_collision(real q1[3], real q2[3], real t1[3], real t2[3], real t3[3], real t4[3])
Check if a line segment intersects a quad (assumed planar)
Definition wall_3d.c:602
void wall_3d_init_octree(wall_3d_data *w)
Construct wall octree recursively.
Definition wall_3d.c:229
Header file for wall_3d.c.
#define WALL_EPSILON
Definition wall_3d.h:11