MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
lptellipsoiddistance.cpp
Go to the documentation of this file.
1// Copyright (C) 2024 The m-AIA AUTHORS
2//
3// This file is part of m-AIA (https://git.rwth-aachen.de/aia/m-AIA/m-AIA)
4//
5// SPDX-License-Identifier: LGPL-3.0-only
6
8
10#include "UTIL/debug.h"
11#include "UTIL/functions.h"
12#include "UTIL/timer.h"
13
14using namespace std;
15
16/*Subroutine to calculate the distance of closest approach of two arbitrary ellipsoids*/
18 MFloat v7[3], MFloat s1, MFloat s2, MFloat s3, MFloat s4, MFloat s5, MFloat s6) {
19 TRACE();
20
21 for(MInt i = 0; i < 3; i++) {
22 di[i] = v1[i];
23 l1i[i] = v2[i];
24 m1i[i] = v3[i];
25 n1i[i] = v4[i];
26 l2i[i] = v5[i];
27 m2i[i] = v6[i];
28 n2i[i] = v7[i];
29 }
30 a1 = s1;
31 b1 = s2;
32 c1 = s3;
33 a2 = s4;
34 b2 = s5;
35 c2 = s6;
36
37 pi = 4.0 * atan(1.0);
38 gratio = (1.0 + sqrt(5.0)) * 0.5;
39 o1g = 1.0 / (1.0 + gratio);
40 tolerance = 1.0E-3;
41 delt = 1.0E-5;
42}
43
45 TRACE();
46
47 MFloat sol;
48 MFloat theta1, theta2, theta3, theta4, f1, f4, f3, f5, f6; // Search algorithm variables
49
50 norm(di, d);
51 norm(l1i, l1);
52 norm(l2i, l2);
53 norm(m1i, m1);
54 norm(m2i, m2);
55 norm(n1i, n1);
56 norm(n2i, n2);
57
58 crossP(d, l1, dxp0);
59 if(mag(dxp0) < 1.E-14) crossP(d, m1, dxp0);
60 norm(dxp0, p0);
61 crossP(p0, d, dxp0);
62
63 theta1 = 0.0;
64 theta2 = pi;
65 theta3 = theta1 + o1g * (theta2 - theta1);
66 theta4 = theta2 - o1g * (theta2 - theta1);
67 f1 = plane_int(theta1);
68 f3 = plane_int(theta3);
69 f4 = plane_int(theta4);
70
72 while((theta2 - theta1) > tolerance) {
73 if((f1 <= f3 && f3 <= f4) || (f3 <= f1 && f1 <= f4)) // case a
74 {
75 theta1 = theta3;
76 f1 = f3;
77 theta3 = theta4;
78 f3 = f4;
79 theta4 = theta2 - o1g * (theta2 - theta1);
80 f4 = plane_int(theta4);
81 } else if((f1 <= f4 && f4 <= f3) || (f4 <= f1 && f1 <= f3)) // case b
82 {
83 theta2 = theta4;
84 theta4 = theta3;
85 f4 = f3;
86 theta3 = theta1 + o1g * (theta2 - theta1);
87 f3 = plane_int(theta3);
88 } else // case c
89 {
90 f5 = plane_int(theta1 + delt);
91 if(f5 > f1) {
92 theta2 = theta3;
93 theta3 = theta1 + o1g * (theta2 - theta1);
94 theta4 = theta2 - o1g * (theta2 - theta1);
95 f3 = plane_int(theta3);
96 f4 = plane_int(theta4);
97 } else {
98 f6 = plane_int(theta1 - delt);
99 if(f6 < f1) {
100 theta2 = theta3;
101 theta3 = theta1 + o1g * (theta2 - theta1);
102 theta4 = theta2 - o1g * (theta2 - theta1);
103 f3 = plane_int(theta3);
104 f4 = plane_int(theta4);
105 } else {
106 theta1 = theta4;
107 f1 = f4;
108 theta3 = theta1 + o1g * (theta2 - theta1);
109 theta4 = theta2 - o1g * (theta2 - theta1);
110 f3 = plane_int(theta3);
111 f4 = plane_int(theta4);
112 }
113 }
114 }
115 }
116 sol = f4;
117
118
119 return sol;
120}
124/*Cross Product of two vectors*/
126 TRACE();
127
128 z[0] = x[1] * y[2] - x[2] * y[1];
129 z[1] = x[2] * y[0] - x[0] * y[2];
130 z[2] = x[0] * y[1] - x[1] * y[0];
131}
134/*Normalization of a vector*/
135void EllipsoidDistance::norm(MFloat vec[3], MFloat nvec[3]) {
136 TRACE();
137
138 MFloat length;
139 length = mag(vec);
140 if(approx(length, 0.0, MFloatEps)) {
141 nvec[0] = 0.0;
142 nvec[1] = 0.0;
143 nvec[2] = 0.0;
144 } else {
145 nvec[0] = vec[0] / length;
146 nvec[1] = vec[1] / length;
147 nvec[2] = vec[2] / length;
148 }
149}
152/*Magnitude of a vector*/
153MFloat EllipsoidDistance::mag(MFloat V[3]) { return sqrt(V[0] * V[0] + V[1] * V[1] + V[2] * V[2]); }
156/*Dot Product of two vectors*/
158 return Vec1[0] * Vec2[0] + Vec1[1] * Vec2[1] + Vec1[2] * Vec2[2];
159}
162/*Ellipses formed with the intersection of the ellipsoid with the plane*/
164 TRACE();
165
166 MFloat alpha1, beta1, gamma1, v1, u1, alpha2, beta2, gamma2, v2, u2;
167 MFloat l1x, l1y, m1x, m1y, n1x, n1y, l2x, l2y, m2x, m2y, n2x, n2y;
168 MFloat a2d1, a2d2, b2d1, b2d2, angle1, angle2; // Ellipses variables
169 MInt j;
170
171 for(j = 0; j < 3; j++)
172 p[j] = cos(theta) * p0[j] + sin(theta) * dxp0[j];
173 crossP(p, d, s);
174 l1x = dotP(l1, d);
175 l1y = dotP(l1, s);
176 m1x = dotP(m1, d);
177 m1y = dotP(m1, s);
178 n1x = dotP(n1, d);
179 n1y = dotP(n1, s);
180 alpha1 = l1x * l1x / (a1 * a1) + m1x * m1x / (b1 * b1) + n1x * n1x / (c1 * c1);
181 beta1 = l1y * l1x / (a1 * a1) + m1y * m1x / (b1 * b1) + n1x * n1y / (c1 * c1);
182 gamma1 = l1y * l1y / (a1 * a1) + m1y * m1y / (b1 * b1) + n1y * n1y / (c1 * c1);
183 v1 = sqrt(4.0 * beta1 * beta1 + (alpha1 - gamma1) * (alpha1 - gamma1));
184 angle1 = 0.5 * atan2(-2.0 * beta1, -(alpha1 - gamma1));
185 u1 = gamma1 + v1 * sin(angle1) * sin(angle1);
186 b2d1 = 1.0 / sqrt(u1);
187 a2d1 = 1.0 / sqrt(u1 - v1);
188 l2x = dotP(l2, d);
189 l2y = dotP(l2, s);
190 m2x = dotP(m2, d);
191 m2y = dotP(m2, s);
192 n2x = dotP(n2, d);
193 n2y = dotP(n2, s);
194 alpha2 = l2x * l2x / (a2 * a2) + m2x * m2x / (b2 * b2) + n2x * n2x / (c2 * c2);
195 beta2 = l2y * l2x / (a2 * a2) + m2y * m2x / (b2 * b2) + n2x * n2y / (c2 * c2);
196 gamma2 = l2y * l2y / (a2 * a2) + m2y * m2y / (b2 * b2) + n2y * n2y / (c2 * c2);
197 v2 = sqrt(4.0 * beta2 * beta2 + (alpha2 - gamma2) * (alpha2 - gamma2));
198 angle2 = 0.5 * atan2(-2.0 * beta2, -(alpha2 - gamma2));
199 u2 = gamma2 + v2 * sin(angle2) * sin(angle2);
200 b2d2 = 1.0 / sqrt(u2);
201 a2d2 = 1.0 / sqrt(u2 - v2);
202
203
204 return distance2d(a2d1, b2d1, a2d2, b2d2, angle1, angle2);
205}
208/*Distance of Closest Approach of two arbitrary ellipses*/
209MFloat EllipsoidDistance::distance2d(MFloat a1_input, MFloat b1_input, MFloat a2_input, MFloat b2_input, MFloat angle1,
210 MFloat angle2) {
211 TRACE();
212
213 MFloat eps1, eps2, k1dotd, k2dotd, k1dotk2, nu, Ap[2][2];
214 MFloat lambdaplus, lambdaminus, bp2, ap2, cosphi, tanphi2, delta, dp, qu2;
215 MFloat A, B, C, D, E, alpha, beta, gamma, P, Q, A2, B2;
216 complex<MFloat> U, y, qu, calpha;
217
218 eps1 = sqrt(1.0 - (b1_input * b1_input) / (a1_input * a1_input));
219 eps2 = sqrt(1.0 - (b2_input * b2_input) / (a2_input * a2_input));
220 k1dotd = cos(angle1);
221 k2dotd = cos(angle2);
222 k1dotk2 = cos(angle2 - angle1);
223 nu = a1_input / b1_input - 1.0;
224 Ap[0][0] =
225 b1_input * b1_input / (b2_input * b2_input)
226 * (1.0 + 0.5 * (1.0 + k1dotk2) * (nu * (2.0 + nu) - eps2 * eps2 * (1.0 + nu * k1dotk2) * (1.0 + nu * k1dotk2)));
227 Ap[1][1] =
228 b1_input * b1_input / (b2_input * b2_input)
229 * (1.0 + 0.5 * (1.0 - k1dotk2) * (nu * (2.0 + nu) - eps2 * eps2 * (1.0 - nu * k1dotk2) * (1.0 - nu * k1dotk2)));
230 Ap[0][1] = b1_input * b1_input / (b2_input * b2_input) * 0.5 * sqrt(1.0 - k1dotk2 * k1dotk2)
231 * (nu * (2.0 + nu) + eps2 * eps2 * (1.0 - nu * nu * k1dotk2 * k1dotk2));
232 lambdaplus =
233 0.5 * (Ap[0][0] + Ap[1][1]) + sqrt(0.25 * (Ap[0][0] - Ap[1][1]) * (Ap[0][0] - Ap[1][1]) + Ap[0][1] * Ap[0][1]);
234 lambdaminus =
235 0.5 * (Ap[0][0] + Ap[1][1]) - sqrt(0.25 * (Ap[0][0] - Ap[1][1]) * (Ap[0][0] - Ap[1][1]) + Ap[0][1] * Ap[0][1]);
236 bp2 = 1.0 / sqrt(lambdaplus);
237 ap2 = 1.0 / sqrt(lambdaminus);
238
239 if(approx(k1dotk2, 1.0, MFloatEps)) {
240 if(Ap[0][0] > Ap[1][1])
241 cosphi = b1_input * k1dotd / (a1_input * sqrt(1.0 - eps1 * eps1 * k1dotd * k1dotd));
242 else
243 cosphi = sqrt(1.0 - k1dotd * k1dotd) / sqrt(1.0 - eps1 * eps1 * k1dotd * k1dotd);
244 } else {
245 cosphi = 1.0
246 / sqrt(2.0 * (Ap[0][1] * Ap[0][1] + (lambdaplus - Ap[0][0]) * (lambdaplus - Ap[0][0]))
247 * (1.0 - eps1 * eps1 * k1dotd * k1dotd))
248 * (Ap[0][1] / sqrt(1.0 + k1dotk2)
249 * (b1_input / a1_input * k1dotd + k2dotd + (b1_input / a1_input - 1.0) * k1dotd * k1dotk2)
250 + (lambdaplus - Ap[0][0]) / sqrt(1.0 - k1dotk2)
251 * (b1_input / a1_input * k1dotd - k2dotd - (b1_input / a1_input - 1.0) * k1dotd * k1dotk2));
252 }
253
254 delta = ap2 * ap2 / (bp2 * bp2) - 1.0;
255 if(approx(delta, 0.0, MFloatEps) || approx(cosphi, 0.0, MFloatEps))
256 dp = 1.0 + ap2;
257 else {
258 tanphi2 = 1.0 / (cosphi * cosphi) - 1.0;
259 A = -(1.0 + tanphi2) / (bp2 * bp2);
260 B = -2.0 * (1.0 + tanphi2 + delta) / bp2;
261 C = -tanphi2 - (1.0 + delta) * (1.0 + delta) + (1.0 + (1.0 + delta) * tanphi2) / (bp2 * bp2);
262 D = 2.0 * (1.0 + tanphi2) * (1.0 + delta) / bp2;
263 E = (1.0 + tanphi2 + delta) * (1.0 + delta);
264 A2 = A * A;
265 B2 = B * B;
266 alpha = -3.0 * B2 / (8.0 * A2) + C / A;
267 beta = B2 * B / (8.0 * A2 * A) - B * C / (2.0 * A2) + D / A;
268 gamma = -3.0 * B2 * B2 / (256.0 * A2 * A2) + C * B2 / (16.0 * A2 * A) - B * D / (4.0 * A2) + E / A;
269 calpha = complex<MFloat>(alpha, 0.0);
270 if(approx(beta, 0.0, MFloatEps)) {
271 qu = complex<MFloat>(-B / (4.0 * A), 0.0)
272 + sqrt(0.5 * (-calpha + sqrt(complex<MFloat>(alpha * alpha - 4.0 * gamma, 0.0))));
273 } else {
274 P = -F1B12 * alpha * alpha - gamma;
275 Q = -alpha * alpha * alpha / 108.0 + F1B3 * alpha * gamma - 0.125 * beta * beta;
276 U = c_cbrt(complex<MFloat>(-Q * 0.5, 0.0) + sqrt(complex<MFloat>(Q * Q * 0.25 + P * P * P / 27.0, 0.0)));
277 if(approx(real(U), 0.0, MFloatEps) && approx(imag(U), 0.0, MFloatEps))
278 y = -5.0 * F1B6 * calpha - c_cbrt(complex<MFloat>(Q, 0.0));
279 else
280 y = -5.0 * F1B6 * calpha + U - complex<MFloat>(P, 0.0) / (3.0 * U);
281 qu = complex<MFloat>(-B / (4.0 * A), 0.0)
282 + 0.5
283 * (sqrt(calpha + 2.0 * y)
284 + sqrt(-(3.0 * calpha + 2.0 * y + 2.0 * complex<MFloat>(beta, 0.0) / sqrt(calpha + 2.0 * y))));
285 }
286 qu2 = abs(qu * qu);
287 dp = sqrt((qu2 - 1.0) / delta * (1.0 + bp2 * (1.0 + delta)) * (1.0 + bp2 * (1.0 + delta)) / qu2
288 + (1.0 - (qu2 - 1.0) / delta) * (1.0 + bp2) * (1.0 + bp2) / qu2);
289 }
290
291
292 return dp * b1_input / sqrt(1.0 - eps1 * eps1 * k1dotd * k1dotd);
293}
296/* Principal cubic root of a complex number */
297complex<MFloat> EllipsoidDistance::c_cbrt(complex<MFloat> x) {
298 TRACE();
299
300 MFloat a, b, r, phi, rn;
301 a = real(x);
302 b = imag(x);
303 r = sqrt(a * a + b * b);
304 phi = atan2(b, a);
305 phi /= 3.0;
306 rn = cbrt(r);
307
308 return complex<MFloat>(rn * cos(phi), rn * sin(phi));
309}
std::complex< MFloat > c_cbrt(std::complex< MFloat >)
void norm(MFloat *vec, MFloat *nvec)
void crossP(MFloat *x, MFloat *y, MFloat *z)
MFloat dotP(MFloat *Vec1, MFloat *Vec2)
MFloat distance2d(MFloat, MFloat, MFloat, MFloat, MFloat, MFloat)
EllipsoidDistance(MFloat di[3], MFloat l1i[3], MFloat m1i[3], MFloat n1i[3], MFloat l2i[3], MFloat m2i[3], MFloat n2i[3], MFloat a1, MFloat b1, MFloat c1, MFloat a2, MFloat b2, MFloat c2)
MBool approx(const T &, const U &, const T)
Definition: functions.h:272
int32_t MInt
Definition: maiatypes.h:62
double MFloat
Definition: maiatypes.h:52
Definition: contexttypes.h:19
define array structures