MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
maia::geom Namespace Reference

Functions

template<typename T , MInt nDim>
MBool doBoxesOverlap (const T *const a, const T *const b)
 
template<typename T , MInt nDim>
MBool isBoxInsideBox (const T *const a, const T *const b)
 
template<typename T , MInt nDim>
MBool isPointInsideBox (const T *const p, const T *const b)
 
template<MInt nDim>
MBool isPointInsideSphere (const MFloat *const p, const MFloat *const c, const MFloat R)
 
template<MInt nDim>
MBool isPointInsideRingSegment (const MFloat *const p, const MFloat *const c, const MFloat *const R, const MFloat *const phi, const MInt axis)
 
template<MInt nDim>
MBool isBoxInsideSphere (const MFloat *const p, const MFloat *const c, const MFloat R)
 
template<typename T , MInt nDim>
MBool isSphereInsideBox (const T *const c, const T R, const T *const p)
 
template<MInt nDim>
MBool doBoxAndSphereOverlap (const MFloat *const b, const MFloat *const c, const MFloat R)
 
template<MInt nDim>
MBool doesLinePenetrateBox (const MFloat *const line, const MFloat *const bbox)
 
template<MInt nDim>
MBool doesLinePenetrateSphere (const MFloat *const line, const MFloat *const center, const MFloat radius)
 

Function Documentation

◆ doBoxAndSphereOverlap()

template<MInt nDim>
MBool maia::geom::doBoxAndSphereOverlap ( const MFloat *const  b,
const MFloat *const  c,
const MFloat  R 
)

Definition at line 123 of file geometryanalytic.h.

123 {
124 MFloat cp[nDim];
125 const MInt cornerCode[8][3] = {{0, 0, 0}, {nDim, 0, 0}, {0, nDim, 0}, {nDim, nDim, 0},
126 {0, 0, nDim}, {nDim, 0, nDim}, {0, nDim, nDim}, {nDim, nDim, nDim}};
127
128 // easy part
129 // is sphere center inside box?
130 if(maia::geom::isPointInsideBox<MFloat, nDim>(c, b)) {
131 return true;
132 }
133
134 // is a box corner in sphere?
135 for(MInt corner = 0; corner < IPOW2(nDim); corner++) {
136 for(MInt dim = 0; dim < nDim; dim++) {
137 cp[dim] = b[dim + cornerCode[corner][dim]];
138 }
139 if(maia::geom::isPointInsideSphere<nDim>(cp, c, R)) {
140 return true;
141 }
142 }
143
144 // 'tricky part' reducing the dimensions
145 // what region relative to the cube is the sphere center located in
146 MInt insideCnt = 0;
147 MFloat p[nDim];
148 MFloat lc[nDim];
149 for(MInt dim = 0; dim < nDim; dim++) {
150 if(c[dim] > b[dim] && c[dim] < b[dim + nDim]) {
151 p[dim] = F0;
152 lc[dim] = F0;
153 insideCnt++;
154 } else {
155 lc[dim] = c[dim];
156 p[dim] = (c[dim] <= b[dim]) ? b[dim] : b[dim + nDim];
157 }
158 }
159
160 // the closest point is a corner, we already checked them
161 if(insideCnt == 0) {
162 return false;
163 }
164
165 // the cosest point is found checking the outside dimensions
166 return maia::geom::isPointInsideSphere<nDim>(p, lc, R);
167}
constexpr MLong IPOW2(MInt x)
int32_t MInt
Definition: maiatypes.h:62
double MFloat
Definition: maiatypes.h:52
constexpr std::underlying_type< FcCell >::type p(const FcCell property)
Converts property name to underlying integer value.

◆ doBoxesOverlap()

template<typename T , MInt nDim>
MBool maia::geom::doBoxesOverlap ( const T *const  a,
const T *const  b 
)

Definition at line 19 of file geometryanalytic.h.

19 {
20 for(MInt dim = 0; dim < nDim; dim++) {
21 if((a[dim] > b[dim + nDim]) || b[dim] > a[dim + nDim]) {
22 return false;
23 }
24 }
25 return true;
26}
Definition: contexttypes.h:19

◆ doesLinePenetrateBox()

template<MInt nDim>
MBool maia::geom::doesLinePenetrateBox ( const MFloat *const  line,
const MFloat *const  bbox 
)

Definition at line 170 of file geometryanalytic.h.

170 {
171 IF_CONSTEXPR(nDim > 3 || nDim < 2) { mTerm(1, AT_, "neither 2 nor 3 dimensional"); }
172
173 // create a line bounding box
174 MFloat bbox_line[2 * nDim];
175 for(MInt dim = 0; dim < nDim; dim++) {
176 if(line[dim] < line[dim + nDim]) {
177 bbox_line[dim] = line[dim];
178 bbox_line[dim + nDim] = line[dim + nDim];
179 } else {
180 bbox_line[dim] = line[dim + nDim];
181 bbox_line[dim + nDim] = line[dim];
182 }
183 }
184
185 // check bounding boxes for overlap
186 // a separation axis can be found in the cartesian axis
187 if(!maia::geom::doBoxesOverlap<MFloat, nDim>(bbox_line, bbox)) {
188 return false;
189 }
190
191 // translate box to center and scale to unit cube
192 MFloat line_c[2 * nDim];
193 for(MInt dim = 0; dim < nDim; dim++) {
194 const MFloat halfLength = (bbox[dim + nDim] - bbox[dim]) / F2;
195 line_c[dim] = (line[dim] - bbox[dim]) / halfLength - 0.5;
196 line_c[dim + nDim] = (line[dim + nDim] - bbox[dim]) / halfLength - 0.5;
197 }
198
199 MFloat line_span[3] = {F0, F0, F0};
200 MFloat lineLength = F0;
201 for(MInt dim = 0; dim < nDim; dim++) {
202 line_span[dim] = line_c[dim + nDim] - line_c[dim];
203 lineLength += POW2(line_span[dim]);
204 }
205 lineLength = std::sqrt(lineLength);
206 for(MInt dim = 0; dim < nDim; dim++) {
207 line_span[dim] /= lineLength;
208 }
209
210 const MFloat radius = nDim * F1B4;
211 for(MInt e = 2; e > ((nDim == 2) ? 1 : -1); e--) {
212 // generate separation axis
213 MFloat axis[3];
214 MFloat e_vec[3] = {F0, F0, F0};
215 e_vec[e] = F1;
216 maia::math::cross(line_span, e_vec, axis);
217
218 // project one of the points on the axis
219 MFloat line_projection = F0;
220 for(MInt dim = 0; dim < nDim; dim++) {
221 line_projection += axis[dim] * line_c[dim];
222 }
223
224 // larger equal radius means no penetration but maybe a contactpoint
225 if(POW2(line_projection) >= radius) {
226 return false;
227 }
228
229 // project the corner of the cube ...
230 // which corner to project
231 MFloat corner_projection = F0;
232 for(MInt dim = 0; dim < nDim; dim++) {
233 corner_projection += axis[dim] * ((axis[dim] > 0) ? 0.5 : -0.5);
234 }
235
236 // larger equal radius means no penetration but maybe a contactpoint
237 if(std::fabs(line_projection) >= std::fabs(corner_projection)) {
238 return false;
239 }
240 }
241
242 // if no separation axis can be found, there has to be a penetration
243 return true;
244}
void mTerm(const MInt errorCode, const MString &location, const MString &message)
Definition: functions.cpp:29
constexpr Real POW2(const Real x)
Definition: functions.h:119
void cross(const T *const u, const T *const v, T *const c)
Definition: maiamath.h:101

◆ doesLinePenetrateSphere()

template<MInt nDim>
MBool maia::geom::doesLinePenetrateSphere ( const MFloat *const  line,
const MFloat *const  center,
const MFloat  radius 
)

Definition at line 247 of file geometryanalytic.h.

247 {
248 const MBool p1_inside = maia::geom::isPointInsideSphere<nDim>(line, center, radius);
249 const MBool p2_inside = maia::geom::isPointInsideSphere<nDim>(line + nDim, center, radius);
250
251 if(p1_inside && p2_inside) {
252 return false;
253 }
254
255 if(p1_inside != p2_inside) {
256 return true;
257 }
258
259 // at this point both end points of the line are outside the sphere
260
261 // create a line and sphere bounding box
262 MFloat bbox_line[2 * nDim];
263 MFloat bbox_sphere[2 * nDim];
264 for(MInt dim = 0; dim < nDim; dim++) {
265 bbox_sphere[dim] = center[dim] - radius;
266 bbox_sphere[dim + nDim] = center[dim] + radius;
267 if(line[dim] < line[dim + nDim]) {
268 bbox_line[dim] = line[dim];
269 bbox_line[dim + nDim] = line[dim + nDim];
270 } else {
271 bbox_line[dim] = line[dim + nDim];
272 bbox_line[dim + nDim] = line[dim];
273 }
274 }
275
276 // check bounding boxes for overlap
277 // a separation axis can be found in the cartesian axis
278 if(!maia::geom::doBoxesOverlap<MFloat, nDim>(bbox_line, bbox_sphere)) {
279 return false;
280 }
281
282 MFloat a = F0;
283 MFloat b = F0;
284 MFloat c = -POW2(radius);
285 for(MInt dim = 0; dim < nDim; dim++) {
286 const MFloat dl = line[dim + nDim] - line[dim];
287 const MFloat dlc = line[dim] - center[dim];
288 a += POW2(dl);
289 b += dl * dlc;
290 c += POW2(dlc);
291 }
292
293 const MFloat D = POW2(b / a) - c / a;
294 if(D <= F0) {
295 return false;
296 }
297
298 // at this point there have to be two valid intersections or none
299 // it should be enough to check one of them
300
301 const MFloat t_p = b / a + sqrt(D);
302
303 // check the intersection if they lie on the line segment
304 return (t_p <= F1) && (t_p >= F0);
305}
bool MBool
Definition: maiatypes.h:58

◆ isBoxInsideBox()

template<typename T , MInt nDim>
MBool maia::geom::isBoxInsideBox ( const T *const  a,
const T *const  b 
)

Definition at line 29 of file geometryanalytic.h.

29 {
30 for(MInt dim = 0; dim < nDim; dim++) {
31 if((a[dim] < b[dim]) || a[dim + nDim] > b[dim + nDim]) {
32 return false;
33 }
34 }
35 return true;
36}

◆ isBoxInsideSphere()

template<MInt nDim>
MBool maia::geom::isBoxInsideSphere ( const MFloat *const  p,
const MFloat *const  c,
const MFloat  R 
)

Definition at line 96 of file geometryanalytic.h.

96 {
97 MFloat pp[nDim];
98 const MInt cornerCode[8][3] = {{0, 0, 0}, {nDim, 0, 0}, {0, nDim, 0}, {nDim, nDim, 0},
99 {0, 0, nDim}, {nDim, 0, nDim}, {0, nDim, nDim}, {nDim, nDim, nDim}};
100 for(MInt corner = 0; corner < IPOW2(nDim); corner++) {
101 for(MInt dim = 0; dim < nDim; dim++) {
102 pp[dim] = p[dim + cornerCode[corner][dim]];
103 }
104 if(!(maia::geom::isPointInsideSphere<nDim>(pp, c, R))) {
105 return false;
106 }
107 }
108 return true;
109}

◆ isPointInsideBox()

template<typename T , MInt nDim>
MBool maia::geom::isPointInsideBox ( const T *const  p,
const T *const  b 
)

Definition at line 39 of file geometryanalytic.h.

39 {
40 for(MInt dim = 0; dim < nDim; dim++) {
41 if((p[dim] < b[dim]) || p[dim] > b[dim + nDim]) {
42 return false;
43 }
44 }
45 return true;
46}

◆ isPointInsideRingSegment()

template<MInt nDim>
MBool maia::geom::isPointInsideRingSegment ( const MFloat *const  p,
const MFloat *const  c,
const MFloat *const  R,
const MFloat *const  phi,
const MInt  axis 
)

Definition at line 62 of file geometryanalytic.h.

63 {
64 IF_CONSTEXPR(nDim == 2) {
65 std::cerr << "H-Patch not implemented for 2D, not refining any cells! Take care with the angle calculation in 2D "
66 "when fixing this!"
67 << std::endl;
68 return false;
69 }
70
71 std::array<MFloat, nDim> normalVector;
72 MFloat distance = F0;
73
74 // compute normal vector from axis to current point
75 for(MInt d = 0; d < nDim; d++) {
76 if(d == axis) {
77 normalVector[d] = F0;
78 } else {
79 normalVector[d] = p[d] - c[d];
80 distance += normalVector[d] * normalVector[d];
81 }
82 }
83
84 // check if cell is within r_min and r_max
85 distance = sqrt(distance);
86 if(distance < R[0] || distance > R[1]) return false;
87
88 // check if cell is within phi_min and phi_max
89 MFloat angle = atan2(normalVector[(axis + 2) % nDim], normalVector[(axis + 1) % nDim]) * 180.0 / PI;
90 if(angle < phi[0] || angle > phi[1]) return false;
91
92 return true;
93}
MFloat distance(const MFloat *a, const MFloat *b)
Definition: maiamath.h:249

◆ isPointInsideSphere()

template<MInt nDim>
MBool maia::geom::isPointInsideSphere ( const MFloat *const  p,
const MFloat *const  c,
const MFloat  R 
)

Definition at line 49 of file geometryanalytic.h.

49 {
50 MFloat r = F0;
51 for(MInt dim = 0; dim < nDim; dim++) {
52 r += POW2(p[dim] - c[dim]);
53 }
54 return std::sqrt(r) < R;
55}

◆ isSphereInsideBox()

template<typename T , MInt nDim>
MBool maia::geom::isSphereInsideBox ( const T *const  c,
const T  R,
const T *const  p 
)

Definition at line 112 of file geometryanalytic.h.

112 {
113 T bbox[2 * nDim];
114 for(MInt dim = 0; dim < nDim; dim++) {
115 bbox[dim] = c[dim] - R;
116 bbox[dim + nDim] = c[dim] + R;
117 }
118 return maia::geom::isBoxInsideBox<T, nDim>(bbox, p);
119}