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 <math.h>
15#include "../ascot5.h"
16#include "wall_3d.h"
17#include "../math.h"
18#include "../list.h"
19#include "../octree.h"
20#include "../print.h"
21
45 real** offload_array, int** int_offload_array) {
46
47 /* Find min & max values of the volume occupied by the wall triangles. */
48 real xmin = (*offload_array)[0], xmax = (*offload_array)[0];
49 real ymin = (*offload_array)[1], ymax = (*offload_array)[1];
50 real zmin = (*offload_array)[2], zmax = (*offload_array)[2];
51 for(int i=0; i<offload_data->n*3; i++) {
52 xmin = fmin( xmin, (*offload_array)[i*3 + 0] );
53 xmax = fmax( xmax, (*offload_array)[i*3 + 0] );
54 ymin = fmin( ymin, (*offload_array)[i*3 + 1] );
55 ymax = fmax( ymax, (*offload_array)[i*3 + 1] );
56 zmin = fmin( zmin, (*offload_array)[i*3 + 2] );
57 zmax = fmax( zmax, (*offload_array)[i*3 + 2] );
58 }
59
60 /* Add a little bit of padding so we don't need to worry about triangles
61 clipping the edges */
62 offload_data->xmin = xmin - 0.1;
63 offload_data->xmax = xmax + 0.1;
64 offload_data->ymin = ymin - 0.1;
65 offload_data->ymax = ymax + 0.1;
66 offload_data->zmin = zmin - 0.1;
67 offload_data->zmax = zmax + 0.1;
68
69 /* Depth of the octree in which the triangles are sorted */
70 offload_data->depth = WALL_OCTREE_DEPTH;
71 int ngrid = 1;
72 for(int i = 0; i < offload_data->depth - 1; i++) {
73 ngrid *= 2;
74 }
75 offload_data->ngrid = ngrid;
76
77 offload_data->xgrid = (offload_data->xmax - offload_data->xmin)
78 / offload_data->ngrid;
79 offload_data->ygrid = (offload_data->ymax - offload_data->ymin)
80 / offload_data->ngrid;
81 offload_data->zgrid = (offload_data->zmax - offload_data->zmin)
82 / offload_data->ngrid;
83
84 print_out(VERBOSE_IO, "\n3D wall model (wall_3D)\n");
86 "Number of wall elements %d\n"
87 "Spanning xmin = %2.3f m, xmax = %2.3f m\n"
88 " ymin = %2.3f m, ymax = %2.3f m\n"
89 " zmin = %2.3f m, zmax = %2.3f m\n",
90 offload_data->n,
91 offload_data->xmin, offload_data->xmax, offload_data->ymin,
92 offload_data->ymax, offload_data->zmin, offload_data->zmax);
93
94 wall_3d_init_octree(offload_data, *offload_array, int_offload_array);
95
96 return 0;
97}
98
111 real** offload_array, int** int_offload_array) {
112 free(*offload_array);
113 *offload_array = NULL;
114
115 free(*int_offload_array);
116 *int_offload_array = NULL;
117}
118
132 real* offload_array, int* int_offload_array) {
133 w->n = offload_data->n;
134 w->xmin = offload_data->xmin;
135 w->xmax = offload_data->xmax;
136 w->xgrid = offload_data->xgrid;
137 w->ymin = offload_data->ymin;
138 w->ymax = offload_data->ymax;
139 w->ygrid = offload_data->ygrid;
140 w->zmin = offload_data->zmin;
141 w->zmax = offload_data->zmax;
142 w->zgrid = offload_data->zgrid;
143 w->depth = offload_data->depth;
144 w->ngrid = offload_data->ngrid;
145 w->wall_tris = &offload_array[0];
146
147 w->tree_array_size = offload_data->int_offload_array_length;
148 w->tree_array = &int_offload_array[0];
149}
150
162void wall_3d_init_tree(wall_3d_data* w, real* offload_array) {
163 /* create a list for holding the triangle ids in each cell */
164 int ncell = w->ngrid*w->ngrid*w->ngrid;
165 list_int_node** tri_list = (list_int_node**) malloc(ncell
166 *sizeof(list_int_node*));
167 int i;
168 for(i = 0; i < ncell; i++) {
169 list_int_create(&tri_list[i]);
170 }
171
172 /* iterate through all triangles and cells and fill the lists */
173 for(i = 0; i < w->n; i++) {
174 real t1[3], t2[3], t3[3];
175 t1[0] = offload_array[i*9];
176 t1[1] = offload_array[i*9+1];
177 t1[2] = offload_array[i*9+2];
178 t2[0] = offload_array[i*9+3];
179 t2[1] = offload_array[i*9+4];
180 t2[2] = offload_array[i*9+5];
181 t3[0] = offload_array[i*9+6];
182 t3[1] = offload_array[i*9+7];
183 t3[2] = offload_array[i*9+8];
184
185 int ix, iy, iz;
186 #pragma omp parallel for private(ix, iy, iz)
187 for(ix = 0; ix < w->ngrid; ix++) {
188 for(iy = 0; iy < w->ngrid; iy++) {
189 for(iz = 0; iz < w->ngrid; iz++) {
190 real c1[3], c2[3];
191 real epsilon = 1e-6;
192 c1[0] = w->xmin + ix * w->xgrid - epsilon;
193 c2[0] = w->xmin + (ix+1) * w->xgrid + epsilon;
194 c1[1] = w->ymin + iy * w->ygrid - epsilon;
195 c2[1] = w->ymin + (iy+1) * w->ygrid + epsilon;
196 c1[2] = w->zmin + iz * w->zgrid - epsilon;
197 c2[2] = w->zmin + (iz+1) * w->zgrid + epsilon;
198 int result = wall_3d_tri_in_cube(t1, t2, t3, c1, c2);
199 int cell_index = ix*w->ngrid*w->ngrid+iy*w->ngrid+iz;
200 if(result > 0) {
201 list_int_add(tri_list[cell_index], i);
202 }
203 }
204 }
205 }
206 }
207
208 /* construct an array from the triangle lists */
209 int list_size = 0;
210 for(i = 0; i < ncell; i++) {
211 list_size += list_int_size(tri_list[i]);
212 }
213
214 w->tree_array_size = 2*ncell + list_size;
215 w->tree_array = (int*) malloc((w->tree_array_size)*sizeof(int));
216
217 int next_empty_list = ncell;
218 for(i = 0; i < ncell; i++) {
219 w->tree_array[i] = next_empty_list;
220 w->tree_array[next_empty_list] = list_int_size(tri_list[i]);
221 int j;
222 for(j = 0; j < w->tree_array[next_empty_list]; j++) {
223 w->tree_array[next_empty_list+j+1] = list_int_get(tri_list[i], j);
224 }
225 next_empty_list += w->tree_array[next_empty_list] + 1;
226 list_int_free(&tri_list[i]);
227 }
228 free(tri_list);
229}
230
243 int** tree_array) {
244
245
246 if (w->n > 1000000){
248 "Starting to initialize 3D-wall octree with %d triangles.\n",
249 w->n);
250 }
251
252 /* Construct the octree and store triangles there */
253 octree_node* tree;
254 octree_create(&tree, w->xmin, w->xmax, w->ymin, w->ymax, w->zmin, w->zmax,
255 w->depth);
256 int i;
257 for(i = 0; i < w->n; i++) {
258 real t1[3], t2[3], t3[3];
259 t1[0] = offload_array[i*9];
260 t1[1] = offload_array[i*9+1];
261 t1[2] = offload_array[i*9+2];
262 t2[0] = offload_array[i*9+3];
263 t2[1] = offload_array[i*9+4];
264 t2[2] = offload_array[i*9+5];
265 t3[0] = offload_array[i*9+6];
266 t3[1] = offload_array[i*9+7];
267 t3[2] = offload_array[i*9+8];
268 octree_add(tree, t1, t2, t3, i);
269 if (i%1000000==0 && i > 0){
270 print_out(VERBOSE_NORMAL, " Adding triangle %10d/%d.\n",i,w->n);
271 }
272 }
273
274 /* Create lists for triangles in each grid square and fill the lists
275 by querying the octree in each grid point */
276 int ncell = w->ngrid*w->ngrid*w->ngrid;
277 list_int_node** tri_list =
278 (list_int_node**) malloc(ncell * sizeof(list_int_node*));
279 int ix, iy, iz;
280 for(ix = 0; ix < w->ngrid; ix++) {
281 for(iy = 0; iy < w->ngrid; iy++) {
282 for(iz = 0; iz < w->ngrid; iz++) {
283 real p[3];
284 p[0] = w->xmin + ix * w->xgrid + 0.5*w->xgrid;
285 p[1] = w->ymin + iy * w->ygrid + 0.5*w->ygrid;
286 p[2] = w->zmin + iz * w->zgrid + 0.5*w->zgrid;
287
288 int cell_index = ix*w->ngrid*w->ngrid+iy*w->ngrid+iz;
289 tri_list[cell_index] = octree_get(tree, p);
290 }
291 }
292 }
293
294 /* construct an array from the triangle lists */
295 int list_size = 0;
296 for(i = 0; i < ncell; i++) {
297 list_size += list_int_size(tri_list[i]);
298 }
299
300 w->int_offload_array_length = 2*ncell + list_size;
301 *tree_array = (int*) malloc((w->int_offload_array_length)*sizeof(int));
302
303 int next_empty_list = ncell;
304 for(i = 0; i < ncell; i++) {
305 /* First ncell elements store the position where the actual cell data
306 * begins in tree_array */
307 (*tree_array)[i] = next_empty_list;
308
309 /* The first data point in the actual cell data is the number of
310 * triangles in this cell */
311 (*tree_array)[next_empty_list] = list_int_size(tri_list[i]);
312
313 /* Store triangle IDs that are located in this cell */
314 for(int j = 0; j < (*tree_array)[next_empty_list]; j++) {
315 (*tree_array)[next_empty_list+j+1] = list_int_get(tri_list[i], j);
316 }
317 next_empty_list += (*tree_array)[next_empty_list] + 1;
318 }
319 free(tri_list);
320 octree_free(&tree);
321}
322
339int wall_3d_hit_wall(real r1, real phi1, real z1, real r2, real phi2,
340 real z2, wall_3d_data* wdata, real* w_coll) {
341 real rpz1[3], rpz2[3];
342 rpz1[0] = r1;
343 rpz1[1] = phi1;
344 rpz1[2] = z1;
345 rpz2[0] = r2;
346 rpz2[1] = phi2;
347 rpz2[2] = z2;
348
349 real q1[3], q2[3];
350 math_rpz2xyz(rpz1, q1);
351 math_rpz2xyz(rpz2, q2);
352
353 int ix1 = (int) floor((q1[0] - wdata->xmin)
354 / ((wdata->xmax - wdata->xmin) / (wdata->ngrid)));
355 int iy1 = (int) floor((q1[1] - wdata->ymin)
356 / ((wdata->ymax - wdata->ymin) / (wdata->ngrid)));
357 int iz1 = (int) floor((q1[2] - wdata->zmin)
358 / ((wdata->zmax - wdata->zmin) / (wdata->ngrid)));
359
360 int ix2 = (int) floor((q2[0] - wdata->xmin)
361 / ((wdata->xmax - wdata->xmin) / (wdata->ngrid)));
362 int iy2 = (int) floor((q2[1] - wdata->ymin)
363 / ((wdata->ymax - wdata->ymin) / (wdata->ngrid)));
364 int iz2 = (int) floor((q2[2] - wdata->zmin)
365 / ((wdata->zmax - wdata->zmin) / (wdata->ngrid)));
366
367 int hit_tri = 0;
368 real smallest_w = 1.1;
369
370 for(int i = 0; i <= abs(ix2-ix1); i++) {
371 for(int j = 0; j <= abs(iy2-iy1); j++) {
372 for(int k = 0; k <= abs(iz2-iz1); k++) {
373 int ix = ix1 + i*((int) copysign(1, ix2-ix1));
374 int iy = iy1 + j*((int) copysign(1, iy2-iy1));
375 int iz = iz1 + k*((int) copysign(1, iz2-iz1));
376
377 if(ix >= 0 && ix < wdata->ngrid && iy >= 0 && iy < wdata->ngrid
378 && iz >= 0 && iz < wdata->ngrid) {
379
380 int ilist = wdata->tree_array[ix*wdata->ngrid*wdata->ngrid
381 + iy*wdata->ngrid + iz];
382
383 for(int l = 0; l < wdata->tree_array[ilist]; l++) {
384 int itri = wdata->tree_array[ilist+l+1];
386 q1, q2,
387 &wdata->wall_tris[9*itri],
388 &wdata->wall_tris[9*itri+3],
389 &wdata->wall_tris[9*itri+6]);
390 if(w >= 0 && w < smallest_w) {
391 smallest_w = w;
392 hit_tri = itri+1;
393 }
394 }
395 }
396 }
397 }
398 }
399 *w_coll = smallest_w;
400 return hit_tri;
401}
402
419int wall_3d_hit_wall_full(real r1, real phi1, real z1, real r2, real phi2,
420 real z2, wall_3d_data* wdata, real* w_coll) {
421 real rpz1[3], rpz2[3];
422 rpz1[0] = r1;
423 rpz1[1] = phi1;
424 rpz1[2] = z1;
425 rpz2[0] = r2;
426 rpz2[1] = phi2;
427 rpz2[2] = z2;
428
429 real q1[3], q2[3];
430 math_rpz2xyz(rpz1, q1);
431 math_rpz2xyz(rpz2, q2);
432
433 int hit_tri = 0;
434 real smallest_w = 1.1;
435 real w;
436 int j;
437
438 for(j = 0; j < wdata->n; j++) {
439 w = wall_3d_tri_collision(q1, q2, &wdata->wall_tris[9*j],
440 &wdata->wall_tris[9*j+3], &wdata->wall_tris[9*j+6]);
441 if(w > 0) {
442 if(w < smallest_w) {
443 smallest_w = w;
444 hit_tri = j+1;
445 }
446 }
447 }
448
449 *w_coll = smallest_w;
450 return hit_tri;
451}
452
464int wall_3d_tri_in_cube(real t1[3], real t2[3], real t3[3], real bb1[3],
465 real bb2[3]) {
466 /* check if any point is inside the cube */
467 if(bb1[0] <= t1[0] && t1[0] <= bb2[0]
468 && bb1[1] <= t1[1] && t1[1] <= bb2[1]
469 && bb1[2] <= t1[2] && t1[2] <= bb2[2])
470 return 1;
471 if(bb1[0] < t2[0] && t2[0] <= bb2[0]
472 && bb1[1] <= t2[1] && t2[1] <= bb2[1]
473 && bb1[2] <= t2[2] && t2[2] <= bb2[2])
474 return 1;
475 if(bb1[0] <= t3[0] && t3[0] <= bb2[0]
476 && bb1[1] <= t3[1] && t3[1] <= bb2[1]
477 && bb1[2] <= t3[2] && t3[2] <= bb2[2])
478 return 1;
479
480 /* no such luck; check if any of the cube edges intersects the triangle */
481 real c000[3]; c000[0] = bb1[0]; c000[1] = bb1[1]; c000[2] = bb1[2];
482 real c100[3]; c100[0] = bb2[0]; c100[1] = bb1[1]; c100[2] = bb1[2];
483 real c010[3]; c010[0] = bb1[0]; c010[1] = bb2[1]; c010[2] = bb1[2];
484 real c110[3]; c110[0] = bb2[0]; c110[1] = bb2[1]; c110[2] = bb1[2];
485 real c001[3]; c001[0] = bb1[0]; c001[1] = bb1[1]; c001[2] = bb2[2];
486 real c101[3]; c101[0] = bb2[0]; c101[1] = bb1[1]; c101[2] = bb2[2];
487 real c011[3]; c011[0] = bb1[0]; c011[1] = bb2[1]; c011[2] = bb2[2];
488 real c111[3]; c111[0] = bb2[0]; c111[1] = bb2[1]; c111[2] = bb2[2];
489
490 if( wall_3d_tri_collision(c000, c100, t1, t2, t3) >= 0
491 || wall_3d_tri_collision(c000, c010, t1, t2, t3) >= 0
492 || wall_3d_tri_collision(c110, c010, t1, t2, t3) >= 0
493 || wall_3d_tri_collision(c110, c100, t1, t2, t3) >= 0
494 || wall_3d_tri_collision(c000, c001, t1, t2, t3) >= 0
495 || wall_3d_tri_collision(c010, c011, t1, t2, t3) >= 0
496 || wall_3d_tri_collision(c100, c101, t1, t2, t3) >= 0
497 || wall_3d_tri_collision(c110, c111, t1, t2, t3) >= 0
498 || wall_3d_tri_collision(c001, c101, t1, t2, t3) >= 0
499 || wall_3d_tri_collision(c001, c011, t1, t2, t3) >= 0
500 || wall_3d_tri_collision(c111, c011, t1, t2, t3) >= 0
501 || wall_3d_tri_collision(c111, c101, t1, t2, t3) >= 0)
502 return 1;
503
504 /* check for triangle edges intersecting cube quads */
505 if( wall_3d_quad_collision(t1, t2, c000, c100, c110, c010) == 1
506 || wall_3d_quad_collision(t1, t2, c000, c010, c011, c001) == 1
507 || wall_3d_quad_collision(t1, t2, c000, c100, c101, c001) == 1
508 || wall_3d_quad_collision(t1, t2, c010, c110, c111, c011) == 1
509 || wall_3d_quad_collision(t1, t2, c100, c101, c111, c110) == 1
510 || wall_3d_quad_collision(t1, t2, c001, c101, c111, c011) == 1)
511 return 1;
512 if( wall_3d_quad_collision(t3, t2, c000, c100, c110, c010) == 1
513 || wall_3d_quad_collision(t3, t2, c000, c010, c011, c001) == 1
514 || wall_3d_quad_collision(t3, t2, c000, c100, c101, c001) == 1
515 || wall_3d_quad_collision(t3, t2, c010, c110, c111, c011) == 1
516 || wall_3d_quad_collision(t3, t2, c100, c101, c111, c110) == 1
517 || wall_3d_quad_collision(t3, t2, c001, c101, c111, c011) == 1)
518 return 1;
519 if( wall_3d_quad_collision(t1, t3, c000, c100, c110, c010) == 1
520 || wall_3d_quad_collision(t1, t3, c000, c010, c011, c001) == 1
521 || wall_3d_quad_collision(t1, t3, c000, c100, c101, c001) == 1
522 || wall_3d_quad_collision(t1, t3, c010, c110, c111, c011) == 1
523 || wall_3d_quad_collision(t1, t3, c100, c101, c111, c110) == 1
524 || wall_3d_quad_collision(t1, t3, c001, c101, c111, c011) == 1)
525 return 1;
526 return 0;
527}
528
544double wall_3d_tri_collision(real q1[3], real q2[3], real t1[3], real t2[3],
545 real t3[3]) {
546 real q12[3], Q12[3];
547 Q12[0] = q2[0] - q1[0];
548 Q12[1] = q2[1] - q1[1];
549 Q12[2] = q2[2] - q1[2];
550 math_unit(Q12, q12);
551
552 real edge12[3];
553 edge12[0] = t2[0] - t1[0];
554 edge12[1] = t2[1] - t1[1];
555 edge12[2] = t2[2] - t1[2];
556
557 real edge13[3];
558 edge13[0] = t3[0] - t1[0];
559 edge13[1] = t3[1] - t1[1];
560 edge13[2] = t3[2] - t1[2];
561
562 real h[3];
563 math_cross(q12, edge13, h);
564 real det = math_dot(h, edge12);
565
566 /* Check that the triangle has non-zero area */
567 real normal[3], area;
568 math_cross(edge12, edge13, normal);
569 area = math_norm(normal);
570
571 real w = -1.0;
572 if( area > WALL_EPSILON ) {
573 /* If ray is parallel to the triangle, nudge it a little bit so we don't
574 have to handle annoying special cases */
575 if( fabs(det) < WALL_EPSILON ) {
576 Q12[0] = q2[0] - q1[0] + 2 * WALL_EPSILON * normal[0] / area;
577 Q12[1] = q2[1] - q1[1] + 2 * WALL_EPSILON * normal[1] / area;
578 Q12[2] = q2[2] - q1[2] + 2 * WALL_EPSILON * normal[2] / area;
579 math_unit(Q12, q12);
580 math_cross(q12, edge13, h);
581 det = math_dot(h, edge12);
582 }
583
584 real tq11[3];
585 tq11[0] = q1[0] - t1[0];
586 tq11[1] = q1[1] - t1[1];
587 tq11[2] = q1[2] - t1[2];
588
589 real n[3];
590 math_cross(tq11, edge12, n);
591
592 real u = math_dot(h, tq11) / det;
593 real v = math_dot(q12, n) / det;
594
595 if( ( u >= 0.0 && u <= 1.0 ) && ( v >= 0.0 && u + v <= 1.0 ) ) {
596 w = ( math_dot(n, edge13) / det ) / math_norm(Q12);
597 if( w > 1.0 ) {
598 w = -1.0;
599 }
600 }
601 }
602
603 return w;
604
605}
606
619int wall_3d_quad_collision(real q1[3], real q2[3], real t1[3], real t2[3],
620 real t3[3], real t4[3]) {
621 if(wall_3d_tri_collision(q1, q2, t1, t2, t3) >= 0
622 || wall_3d_tri_collision(q1, q2, t1, t3, t4) >= 0)
623 return 1;
624 else
625 return 0;
626}
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:28
#define math_unit(a, b)
Calculate unit vector b from a 3D vector a.
Definition math.h:70
#define math_rpz2xyz(rpz, xyz)
Convert cylindrical coordinates rpz to cartesian coordinates xyz.
Definition math.h:78
#define math_cross(a, b, c)
Calculate cross product for 3D vectors c = a x b.
Definition math.h:31
#define math_norm(a)
Calculate norm of 3D vector a.
Definition math.h:64
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:38
real zgrid
Definition wall_3d.h:48
int * tree_array
Array storing information what triangles given octree cell stores.
Definition wall_3d.h:63
real zmax
Definition wall_3d.h:47
real xmax
Definition wall_3d.h:41
real zmin
Definition wall_3d.h:46
real ymin
Definition wall_3d.h:43
int tree_array_size
Definition wall_3d.h:53
real xmin
Definition wall_3d.h:40
real * wall_tris
Definition wall_3d.h:52
real xgrid
Definition wall_3d.h:42
real ygrid
Definition wall_3d.h:45
real ymax
Definition wall_3d.h:44
3D wall offload data
Definition wall_3d.h:16
int int_offload_array_length
Definition wall_3d.h:32
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:464
void wall_3d_init_tree(wall_3d_data *w, real *offload_array)
Construct wall octree iteratively.
Definition wall_3d.c:162
void wall_3d_init(wall_3d_data *w, wall_3d_offload_data *offload_data, real *offload_array, int *int_offload_array)
Initialize wall data struct on target.
Definition wall_3d.c:131
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:419
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:544
int wall_3d_init_offload(wall_3d_offload_data *offload_data, real **offload_array, int **int_offload_array)
Initialize 3D wall data and check inputs.
Definition wall_3d.c:44
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:339
void wall_3d_init_octree(wall_3d_offload_data *w, real *offload_array, int **tree_array)
Construct wall octree recursively.
Definition wall_3d.c:242
void wall_3d_free_offload(wall_3d_offload_data *offload_data, real **offload_array, int **int_offload_array)
Free offload array and reset parameters.
Definition wall_3d.c:110
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:619
Header file for wall_3d.c.
#define WALL_EPSILON
Definition wall_3d.h:11