14#include "arcane/utils/Iostream.h"
15#include "arcane/utils/ITraceMng.h"
18#include "arcane/core/GeometricUtilities.h"
29Real GeometricUtilities::QuadMapping::
32 Real3x3 jacobian = evaluateGradient(uvw);
34 Real d3 = jacobian.x.x * jacobian.y.y - jacobian.x.y * jacobian.y.x;
35 Real d2 = jacobian.x.z * jacobian.y.x - jacobian.x.y * jacobian.y.z;
36 Real d1 = jacobian.x.y * jacobian.y.z - jacobian.x.z * jacobian.y.y;
39 if (math::isNearlyZero(det))
42 Real inv_det = 1 / det;
44 jacobian.z.x = d1 * inv_det;
45 jacobian.z.y = d2 * inv_det;
46 jacobian.z.z = d3 * inv_det;
48 matrix.x.x = (jacobian.y.y * jacobian.z.z - jacobian.y.z * jacobian.z.y);
49 matrix.y.x = -(jacobian.y.x * jacobian.z.z - jacobian.y.z * jacobian.z.x);
50 matrix.z.x = (jacobian.y.x * jacobian.z.y - jacobian.y.y * jacobian.z.x);
52 matrix.x.y = -(jacobian.x.y * jacobian.z.z - jacobian.x.z * jacobian.z.y);
53 matrix.y.y = (jacobian.x.x * jacobian.z.z - jacobian.x.z * jacobian.z.x);
54 matrix.z.y = -(jacobian.x.x * jacobian.z.y - jacobian.x.y * jacobian.z.x);
56 matrix.x.z = (jacobian.x.y * jacobian.y.z - jacobian.x.z * jacobian.y.y);
57 matrix.y.z = -(jacobian.x.x * jacobian.y.z - jacobian.x.z * jacobian.y.x);
58 matrix.z.z = (jacobian.x.x * jacobian.y.y - jacobian.x.y * jacobian.y.x);
81 const Real wanted_precision = m_precision;
82 const Integer max_iteration = 1000;
84 Real u_new, v_new, w_new;
85 Real relative_error = 1.0;
88 uvw =
Real3(0.5, 0.5, 0.0);
90 Real3x3 inverse_jacobian_matrix;
92 while (relative_error > wanted_precision && nb_iter < max_iteration) {
95 computeInverseJacobian(uvw, inverse_jacobian_matrix);
97 u_new = uvw.
x + inverse_jacobian_matrix.
x.
x * (point.
x-new_pos.
x)
98 + inverse_jacobian_matrix.
y.
x * (point.
y-new_pos.
y)
99 + inverse_jacobian_matrix.
z.
x * (point.
z-new_pos.
z);
100 v_new = uvw.
y + inverse_jacobian_matrix.
x.
y * (point.
x-new_pos.
x)
101 + inverse_jacobian_matrix.
y.
y * (point.
y-new_pos.
y)
102 + inverse_jacobian_matrix.
z.
y * (point.
z-new_pos.
z);
108 relative_error = (u_new - uvw.
x) * (u_new - uvw.
x) +
109 (v_new - uvw.
y) * (v_new - uvw.
y) +
110 (w_new - uvw.
z) * (w_new - uvw.
z);
113 tm->
info() <<
"CARTESIAN_TO_ISO I=" << nb_iter <<
" uvw=" << uvw
114 <<
" new_pos=" << new_pos
115 <<
" error=" << relative_error;
121 return (relative_error > wanted_precision);
124Real3 GeometricUtilities::QuadMapping::
127 Real3 normal = QuadMapping::_normal();
128 Real norm = normal.
x * normal.
x + normal.
y * normal.
y + normal.
z * normal.
z;
145Real3 GeometricUtilities::QuadMapping::
148 Real3 n0 =
math::vecMul(m_pos[1] - m_pos[0], m_pos[2] - m_pos[0]);
149 Real3 n1 =
math::vecMul(m_pos[2] - m_pos[1], m_pos[3] - m_pos[1]);
150 Real3 n2 =
math::vecMul(m_pos[3] - m_pos[2], m_pos[0] - m_pos[2]);
151 Real3 n3 =
math::vecMul(m_pos[0] - m_pos[3], m_pos[1] - m_pos[3]);
152 Real3 normal = (n0 + n1 + n2 + n3) * 0.25;
172 Real epsi_newton = 1.0e-12;
173 int newton_loop_limit = 100;
182 Real3 normal = _normal();
183 for (
int i = 0; i < 4; ++i)
184 other_pos[i] = m_pos[i] + normal;
186 Real x0 = m_pos[0].x;
187 Real y0 = m_pos[0].y;
188 Real z0 = m_pos[0].z;
189 Real x1 = m_pos[1].x;
190 Real y1 = m_pos[1].y;
191 Real z1 = m_pos[1].z;
192 Real x2 = m_pos[2].x;
193 Real y2 = m_pos[2].y;
194 Real z2 = m_pos[2].z;
195 Real x3 = m_pos[3].x;
196 Real y3 = m_pos[3].y;
197 Real z3 = m_pos[3].z;
199 Real x4 = other_pos[0].
x;
200 Real y4 = other_pos[0].
y;
201 Real z4 = other_pos[0].
z;
202 Real x5 = other_pos[1].
x;
203 Real y5 = other_pos[1].
y;
204 Real z5 = other_pos[1].
z;
205 Real x6 = other_pos[2].
x;
206 Real y6 = other_pos[2].
y;
207 Real z6 = other_pos[2].
z;
208 Real x7 = other_pos[3].
x;
209 Real y7 = other_pos[3].
y;
210 Real z7 = other_pos[3].
z;
228 Real determinant = 0.0;
231 Real residue = 1.0e30;
238 for (inewt = 0; inewt < newton_loop_limit && residue > epsi_newton; inewt++) {
244 cx = + x0*((-1 + w0)*(-1 + u0)*(1 - v0)
245 - w0*(-1 + u0)*(1 - v0)
246 + (1 - w0)*u0*(1 - v0)
247 + (-1 + w0)*(-1 + u0)*v0
249 + x1*(-(w0*(-1 + u0)*v0) + (1 - w0)*u0*v0)
250 + x2*(w0*(-1 + u0)*v0 + w0*u0*v0)
251 + x3*(-(w0*u0*(-1 + v0)) - w0*(-1 + u0)*v0)
252 + x4*(-(w0*u0*(-1 + v0)) + (1 - w0)*u0*v0)
253 + x5*((-1 + w0)*u0*v0 + w0*u0*v0)
255 + x7*(-(w0*u0*(1 - v0)) + w0*u0*v0)
258 cxv = x0*(1 - w0)*(-1 + u0)
259 + x1*(-1 + w0)*(-1 + u0)
269 x0*(-1 + u0)*(1 - v0)
272 + x3*(-1 + u0)*(-1 + v0)
280 x0*(-1 + w0)*(1 - v0)
284 + x4*(-1 + w0)*(-1 + v0)
291 + y0*((-1 + w0)*(-1 + u0)*(1 - v0)
292 - w0*(-1 + u0)*(1 - v0)
293 + (1 - w0)*u0*(1 - v0)
294 + (-1 + w0)*(-1 + u0)*v0
296 + y1*(-(w0*(-1 + u0)*v0) + (1 - w0)*u0*v0)
297 + y2*(w0*(-1 + u0)*v0 + w0*u0*v0)
298 + y3*(-(w0*u0*(-1 + v0)) - w0*(-1 + u0)*v0)
299 + y4*(-(w0*u0*(-1 + v0)) + (1 - w0)*u0*v0)
300 + y5*((-1 + w0)*u0*v0 + w0*u0*v0)
302 + y7*(-(w0*u0*(1 - v0)) + w0*u0*v0)
306 y0*(1 - w0)*(-1 + u0)
307 + y1*(-1 + w0)*(-1 + u0)
317 y0*(-1 + u0)*(1 - v0)
320 + y3*(-1 + u0)*(-1 + v0)
327 cyu = y0*(-1 + w0)*(1 - v0)
331 + y4*(-1 + w0)*(-1 + v0)
337 cz = + z0*((-1 + w0)*(-1 + u0)*(1 - v0)
338 - w0*(-1 + u0)*(1 - v0)
339 + (1 - w0)*u0*(1 - v0)
340 + (-1 + w0)*(-1 + u0)*v0
342 + z1*(-(w0*(-1 + u0)*v0) + (1 - w0)*u0*v0)
343 + z2*(w0*(-1 + u0)*v0 + w0*u0*v0)
344 + z3*(-(w0*u0*(-1 + v0)) - w0*(-1 + u0)*v0)
345 + z4*(-(w0*u0*(-1 + v0)) + (1 - w0)*u0*v0)
346 + z5*((-1 + w0)*u0*v0 + w0*u0*v0)
348 + z7*(-(w0*u0*(1 - v0)) + w0*u0*v0)
352 z0*(1 - w0)*(-1 + u0)
353 + z1*(-1 + w0)*(-1 + u0)
363 z0*(-1 + u0)*(1 - v0)
366 + z3*(-1 + u0)*(-1 + v0)
374 z0*(-1 + w0)*(1 - v0)
378 + z4*(-1 + w0)*(-1 + v0)
384 determinant = cxv*cyu*czw -
385 cxu*cyv*czw - cxv*cyw*czu +
386 cxw*cyv*czu + cxu*cyw*czv -
390 tm->
info() <<
"ITERATION DETERMINANT = " << determinant <<
" " << u
391 <<
" " << v <<
" " << w;
393 if (math::abs(determinant) > 1e-14) {
395 u = (cxv*cyw*cz - cxw*cyv*cz - cxv*cy*czw
396 + cx*cyv*czw + cxw*cy*czv - cx*cyw*czv
397 + (- cyv*czw + cyw*czv) * x
398 + ( cxv*czw - cxw*czv) * y
399 + (- cxv*cyw + cxw*cyv) * z
402 v = (-cxu*cyw*cz + cxw*cyu*cz + cxu*cy*czw
403 - cx*cyu*czw - cxw*cy*czu + cx*cyw*czu
404 + ( cyu*czw - cyw*czu) * x
405 + (- cxu*czw + cxw*czu) * y
406 + ( cxu*cyw - cxw*cyu) * z
409 w = -(cxv*cyu*cz - cxu*cyv*cz - cxv*cy*czu
410 + cx*cyv*czu + cxu*cy*czv - cx*cyu*czv
411 + (- cyv*czu + cyu*czv) * x
412 + ( cxv*czu - cxu*czv) * y
413 + (- cxv*cyu + cxu*cyv) * z
416 residue = NormeLinf(
Real3(u,v,w),
Real3(u0,v0,w0));
420 tm->
info() <<
"Newton failure: determinant zero";
426 if (inewt == newton_loop_limit) {
428 tm->
info() <<
"Too many iterations in the newton";
434 iso -=
Real3(0.5, 0.5, 0.5);
436 uvw =
Real3(iso.
y, iso.
z, 0.0);
449 Real3 kDiff = v1 - point;
450 Real3 edge0 = v2 - v1;
451 Real3 edge1 = v3 - v1;
458 Real fDet = math::abs(fA00 * fA11 - fA01 * fA01);
459 Real alpha = fA01 * fB1 - fA11 * fB0;
460 Real beta = fA01 * fB0 - fA00 * fB1;
461 Real distance2 = 0.0;
464 if (alpha + beta <= fDet) {
472 distance2 = fA00 + (2.0) * fB0 + fC;
476 distance2 = fB0 * alpha + fC;
485 else if (-fB1 >= fA11) {
487 distance2 = fA11 + (2.0) * fB1 + fC;
491 distance2 = fB1 * beta + fC;
502 else if (-fB1 >= fA11) {
504 distance2 = fA11 + (2.0) * fB1 + fC;
508 distance2 = fB1 * beta + fC;
512 else if (beta < 0.0) {
519 else if (-fB0 >= fA00) {
521 distance2 = fA00 + (2.0) * fB0 + fC;
525 distance2 = fB0 * alpha + fC;
531 Real fInvDet = (1.0) / fDet;
534 distance2 = alpha * (fA00 * alpha + fA01 * beta + (2.0) * fB0) +
535 beta * (fA01 * alpha + fA11 * beta + (2.0) * fB1) + fC;
541 Real fTmp0 = fA01 + fB0;
542 Real fTmp1 = fA11 + fB1;
544 Real fNumer = fTmp1 - fTmp0;
545 Real fDenom = fA00 - 2.0f * fA01 + fA11;
546 if (fNumer >= fDenom) {
549 distance2 = fA00 + (2.0) * fB0 + fC;
552 alpha = fNumer / fDenom;
554 distance2 = alpha * (fA00 * alpha + fA01 * beta + 2.0f * fB0) +
555 beta * (fA01 * alpha + fA11 * beta + (2.0) * fB1) + fC;
562 distance2 = fA11 + (2.0) * fB1 + fC;
564 else if (fB1 >= 0.0) {
570 distance2 = fB1 * beta + fC;
574 else if (beta < 0.0) {
576 Real fTmp0 = fA01 + fB1;
577 Real fTmp1 = fA00 + fB0;
579 Real fNumer = fTmp1 - fTmp0;
580 Real fDenom = fA00 - (2.0) * fA01 + fA11;
581 if (fNumer >= fDenom) {
584 distance2 = fA11 + (2.0) * fB1 + fC;
587 beta = fNumer / fDenom;
589 distance2 = alpha * (fA00 * alpha + fA01 * beta + (2.0) * fB0) +
590 beta * (fA01 * alpha + fA11 * beta + (2.0) * fB1) + fC;
597 distance2 = fA00 + (2.0) * fB0 + fC;
599 else if (fB0 >= 0.0) {
605 distance2 = fB0 * alpha + fC;
611 Real fNumer = fA11 + fB1 - fA01 - fB0;
615 distance2 = fA11 + (2.0) * fB1 + fC;
618 Real fDenom = fA00 - 2.0f * fA01 + fA11;
619 if (fNumer >= fDenom) {
622 distance2 = fA00 + (2.0) * fB0 + fC;
625 alpha = fNumer / fDenom;
627 distance2 = alpha * (fA00 * alpha + fA01 * beta + (2.0) * fB0) +
628 beta * (fA01 * alpha + fA11 * beta + (2.0) * fB1) + fC;
639 return ProjectionInfo(distance2, region, alpha, beta,
projection);
648 Real3 edge0 = v2 - v1;
649 Real3 edge1 = point - v1;
652 Real alpha = dot_product / norm;
659 else if (alpha > 1.) {
661 distance = (point - v2).squareNormL2();
665 distance = (point - (v1 + alpha * edge0)).squareNormL2();
669 cout <<
"InfosDistance: v1=" << v1 <<
" v2=" << v2 <<
" point="
670 << point <<
" alpha=" << alpha
671 <<
" distance=" << distance
672 <<
" region=" << region
675 return ProjectionInfo(distance, region, alpha, 0.,
projection);
684 Real3 kDiff = v1 - point;
685 Real3 edge0 = v2 - v1;
686 Real3 edge1 = v3 - v1;
693 Real fDet = math::abs(fA00 * fA11 - fA01 * fA01);
695 Real alpha = fA01 * fB1 - fA11 * fB0;
696 Real beta = fA01 * fB0 - fA00 * fB1;
698 if (alpha + beta <= fDet) {
702 else if (beta < 0.0) {
718 Real3 edge0 = v2 - v1;
719 Real3 edge1 = point - v1;
724 if (dot_product > 0. && dot_product < norm)
Various mathematical functions.
Information about the projection of a point onto a segment or a triangle.
static ProjectionInfo projection(Real3 v1, Real3 v2, Real3 v3, Real3 point)
Projection of point point onto the triangle defined by v1, v2 and v3.
static bool isInside(Real3 v1, Real3 v2, Real3 v3, Real3 point)
Indicates if the projection of point point is inside the triangle defined by v1, v2 and v3.
bool cartesianToIso(Real3 point, Real3 &uvw, ITraceMng *tm)
Converts a Cartesian coordinate to an iso-parametric coordinate.
Real3 evaluatePosition(Real3 iso) const
Calculates Cartesian coordinates from iso-barycentric coordinates.
bool cartesianToIso2(Real3 point, Real3 &uvw, ITraceMng *tm)
Converts a Cartesian coordinate to an iso-parametric coordinate.
virtual TraceMessage info()=0
Stream for an information message.
Class managing a 3-dimensional real vector.
constexpr __host__ __device__ Real squareNormL2() const
Returns the square of the L2 norm of the triplet $ .
Class managing a 3x3 real matrix.
Real3 z
first element of the triplet
Real3 y
first element of the triplet
Real3 x
first element of the triplet
__host__ __device__ Real dot(Real2 u, Real2 v)
Dot product of u by v in .
T max(const T &a, const T &b, const T &c)
Returns the maximum of three elements.
__host__ __device__ Real3 vecMul(Real3 u, Real3 v)
Vector cross product of u by v in .
__host__ __device__ double sqrt(double v)
Square root of v.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.
double Real
Type representing a real number.
Real y
second component of the triplet
Real z
third component of the triplet
Real x
first component of the triplet