14#include "arcane/utils/Iostream.h"
15#include "arcane/utils/ITraceMng.h"
17#include "arcane/MathUtils.h"
18#include "arcane/GeometricUtilities.h"
29Real GeometricUtilities::QuadMapping::
30computeInverseJacobian(Real3 uvw,Real3x3& matrix)
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);
80 const Real wanted_precision = m_precision;
81 const Integer max_iteration = 1000;
83 Real u_new, v_new, w_new;
84 Real relative_error = 1.0 ;
87 uvw =
Real3(0.5,0.5,0.0);
89 Real3x3 inverse_jacobian_matrix;
91 while (relative_error>wanted_precision && nb_iter<max_iteration){
94 computeInverseJacobian(uvw,inverse_jacobian_matrix);
95 Real3 new_pos = evaluatePosition(uvw);
96 u_new = uvw.
x + inverse_jacobian_matrix.
x.
x * (point.
x-new_pos.
x)
97 + inverse_jacobian_matrix.
y.
x * (point.
y-new_pos.
y)
98 + inverse_jacobian_matrix.
z.
x * (point.
z-new_pos.
z);
99 v_new = uvw.
y + inverse_jacobian_matrix.
x.
y * (point.
x-new_pos.
x)
100 + inverse_jacobian_matrix.
y.
y * (point.
y-new_pos.
y)
101 + inverse_jacobian_matrix.
z.
y * (point.
z-new_pos.
z);
107 relative_error = (u_new - uvw.
x) * (u_new - uvw.
x) +
108 (v_new - uvw.
y) * (v_new - uvw.
y) +
109 (w_new - uvw.
z) * (w_new - uvw.
z) ;
112 tm->
info() <<
"CARTESIAN_TO_ISO I=" << nb_iter <<
" uvw=" << uvw
113 <<
" new_pos=" << new_pos
114 <<
" error=" << relative_error;
120 return (relative_error>wanted_precision);
123Real3 GeometricUtilities::QuadMapping::
126 Real3 normal= QuadMapping::_normal();
127 Real norm = normal.
x*normal.
x + normal.
y*normal.
y + normal.
z*normal.
z;
136 Real norm =
math::max(math::abs(v.
x),math::abs(v.
y));
144Real3 GeometricUtilities::QuadMapping::
147 Real3 n0 =
math::vecMul(m_pos[1] - m_pos[0],m_pos[2] - m_pos[0]);
148 Real3 n1 =
math::vecMul(m_pos[2] - m_pos[1],m_pos[3] - m_pos[1]);
149 Real3 n2 =
math::vecMul(m_pos[3] - m_pos[2],m_pos[0] - m_pos[2]);
150 Real3 n3 =
math::vecMul(m_pos[0] - m_pos[3],m_pos[1] - m_pos[3]);
151 Real3 normal = (n0+n1+n2+n3) * 0.25;
170 Real epsi_newton = 1.0e-12;
171 int newton_loop_limit = 100;
180 Real3 normal = _normal();
181 for(
int i=0; i<4; ++i )
182 other_pos[i] = m_pos[i] + normal;
184 Real x0 = m_pos[0].x;
185 Real y0 = m_pos[0].y;
186 Real z0 = m_pos[0].z;
187 Real x1 = m_pos[1].x;
188 Real y1 = m_pos[1].y;
189 Real z1 = m_pos[1].z;
190 Real x2 = m_pos[2].x;
191 Real y2 = m_pos[2].y;
192 Real z2 = m_pos[2].z;
193 Real x3 = m_pos[3].x;
194 Real y3 = m_pos[3].y;
195 Real z3 = m_pos[3].z;
197 Real x4 = other_pos[0].
x;
198 Real y4 = other_pos[0].
y;
199 Real z4 = other_pos[0].
z;
200 Real x5 = other_pos[1].
x;
201 Real y5 = other_pos[1].
y;
202 Real z5 = other_pos[1].
z;
203 Real x6 = other_pos[2].
x;
204 Real y6 = other_pos[2].
y;
205 Real z6 = other_pos[2].
z;
206 Real x7 = other_pos[3].
x;
207 Real y7 = other_pos[3].
y;
208 Real z7 = other_pos[3].
z;
226 Real determinant = 0.0;
229 Real residue = 1.0e30;
236 for(inewt=0; inewt<newton_loop_limit && residue>epsi_newton; inewt++ ) {
242 cx = + x0*((-1 + w0)*(-1 + u0)*(1 - v0)
243 - w0*(-1 + u0)*(1 - v0)
244 + (1 - w0)*u0*(1 - v0)
245 + (-1 + w0)*(-1 + u0)*v0
247 + x1*(-(w0*(-1 + u0)*v0) + (1 - w0)*u0*v0)
248 + x2*(w0*(-1 + u0)*v0 + w0*u0*v0)
249 + x3*(-(w0*u0*(-1 + v0)) - w0*(-1 + u0)*v0)
250 + x4*(-(w0*u0*(-1 + v0)) + (1 - w0)*u0*v0)
251 + x5*((-1 + w0)*u0*v0 + w0*u0*v0)
253 + x7*(-(w0*u0*(1 - v0)) + w0*u0*v0)
256 cxv = x0*(1 - w0)*(-1 + u0)
257 + x1*(-1 + w0)*(-1 + u0)
267 x0*(-1 + u0)*(1 - v0)
270 + x3*(-1 + u0)*(-1 + v0)
278 x0*(-1 + w0)*(1 - v0)
282 + x4*(-1 + w0)*(-1 + v0)
289 + y0*((-1 + w0)*(-1 + u0)*(1 - v0)
290 - w0*(-1 + u0)*(1 - v0)
291 + (1 - w0)*u0*(1 - v0)
292 + (-1 + w0)*(-1 + u0)*v0
294 + y1*(-(w0*(-1 + u0)*v0) + (1 - w0)*u0*v0)
295 + y2*(w0*(-1 + u0)*v0 + w0*u0*v0)
296 + y3*(-(w0*u0*(-1 + v0)) - w0*(-1 + u0)*v0)
297 + y4*(-(w0*u0*(-1 + v0)) + (1 - w0)*u0*v0)
298 + y5*((-1 + w0)*u0*v0 + w0*u0*v0)
300 + y7*(-(w0*u0*(1 - v0)) + w0*u0*v0)
304 y0*(1 - w0)*(-1 + u0)
305 + y1*(-1 + w0)*(-1 + u0)
315 y0*(-1 + u0)*(1 - v0)
318 + y3*(-1 + u0)*(-1 + v0)
325 cyu = y0*(-1 + w0)*(1 - v0)
329 + y4*(-1 + w0)*(-1 + v0)
335 cz = + z0*((-1 + w0)*(-1 + u0)*(1 - v0)
336 - w0*(-1 + u0)*(1 - v0)
337 + (1 - w0)*u0*(1 - v0)
338 + (-1 + w0)*(-1 + u0)*v0
340 + z1*(-(w0*(-1 + u0)*v0) + (1 - w0)*u0*v0)
341 + z2*(w0*(-1 + u0)*v0 + w0*u0*v0)
342 + z3*(-(w0*u0*(-1 + v0)) - w0*(-1 + u0)*v0)
343 + z4*(-(w0*u0*(-1 + v0)) + (1 - w0)*u0*v0)
344 + z5*((-1 + w0)*u0*v0 + w0*u0*v0)
346 + z7*(-(w0*u0*(1 - v0)) + w0*u0*v0)
350 z0*(1 - w0)*(-1 + u0)
351 + z1*(-1 + w0)*(-1 + u0)
361 z0*(-1 + u0)*(1 - v0)
364 + z3*(-1 + u0)*(-1 + v0)
372 z0*(-1 + w0)*(1 - v0)
376 + z4*(-1 + w0)*(-1 + v0)
382 determinant = cxv*cyu*czw -
383 cxu*cyv*czw - cxv*cyw*czu +
384 cxw*cyv*czu + cxu*cyw*czv -
388 tm->
info() <<
"ITERATION DETERMINANT = " << determinant <<
" " << u
389 <<
" " << v <<
" " << w;
391 if(math::abs(determinant)>1e-14){
393 u = (cxv*cyw*cz - cxw*cyv*cz - cxv*cy*czw
394 + cx*cyv*czw + cxw*cy*czv - cx*cyw*czv
395 + (- cyv*czw + cyw*czv) * x
396 + ( cxv*czw - cxw*czv) * y
397 + (- cxv*cyw + cxw*cyv) * z
400 v = (-cxu*cyw*cz + cxw*cyu*cz + cxu*cy*czw
401 - cx*cyu*czw - cxw*cy*czu + cx*cyw*czu
402 + ( cyu*czw - cyw*czu) * x
403 + (- cxu*czw + cxw*czu) * y
404 + ( cxu*cyw - cxw*cyu) * z
407 w = -(cxv*cyu*cz - cxu*cyv*cz - cxv*cy*czu
408 + cx*cyv*czu + cxu*cy*czv - cx*cyu*czv
409 + (- cyv*czu + cyu*czv) * x
410 + ( cxv*czu - cxu*czv) * y
411 + (- cxv*cyu + cxu*cyv) * z
414 residue = NormeLinf(
Real3(u,v,w),
Real3(u0,v0,w0));
418 tm->
info() <<
"echec du Newton : déterminant nul";
424 if (inewt == newton_loop_limit) {
426 tm->
info() <<
"Too many iterations in the newton";
432 iso -=
Real3(0.5,0.5,0.5);
447 Real3 kDiff = v1 - point;
448 Real3 edge0 = v2 - v1;
449 Real3 edge1 = v3 - v1;
456 Real fDet = math::abs(fA00*fA11-fA01*fA01);
457 Real alpha = fA01*fB1-fA11*fB0;
458 Real beta = fA01*fB0-fA00*fB1;
459 Real distance2 = 0.0;
462 if ( alpha + beta <= fDet ){
470 distance2 = fA00+(2.0)*fB0+fC;
474 distance2 = fB0*alpha+fC;
483 else if ( -fB1 >= fA11 ){
485 distance2 = fA11+(2.0)*fB1+fC;
489 distance2 = fB1*beta+fC;
500 else if ( -fB1 >= fA11 ){
502 distance2 = fA11+(2.0)*fB1+fC;
506 distance2 = fB1*beta+fC;
510 else if ( beta < 0.0 ){
517 else if ( -fB0 >= fA00 ){
519 distance2 = fA00+(2.0)*fB0+fC;
523 distance2 = fB0*alpha+fC;
529 Real fInvDet = (1.0)/fDet;
532 distance2 = alpha*(fA00*alpha+fA01*beta+(2.0)*fB0) +
533 beta*(fA01*alpha+fA11*beta+(2.0)*fB1)+fC;
539 Real fTmp0 = fA01 + fB0;
540 Real fTmp1 = fA11 + fB1;
541 if ( fTmp1 > fTmp0 ){
542 Real fNumer = fTmp1 - fTmp0;
543 Real fDenom = fA00-2.0f*fA01+fA11;
544 if ( fNumer >= fDenom ){
547 distance2 = fA00+(2.0)*fB0+fC;
550 alpha = fNumer/fDenom;
552 distance2 = alpha*(fA00*alpha+fA01*beta+2.0f*fB0) +
553 beta*(fA01*alpha+fA11*beta+(2.0)*fB1)+fC;
560 distance2 = fA11+(2.0)*fB1+fC;
562 else if (fB1 >= 0.0){
568 distance2 = fB1*beta+fC;
574 Real fTmp0 = fA01 + fB1;
575 Real fTmp1 = fA00 + fB0;
576 if ( fTmp1 > fTmp0 ){
577 Real fNumer = fTmp1 - fTmp0;
578 Real fDenom = fA00-(2.0)*fA01+fA11;
582 distance2 = fA11+(2.0)*fB1+fC;
585 beta = fNumer/fDenom;
587 distance2 = alpha*(fA00*alpha+fA01*beta+(2.0)*fB0) +
588 beta*(fA01*alpha+fA11*beta+(2.0)*fB1)+fC;
595 distance2 = fA00+(2.0)*fB0+fC;
603 distance2 = fB0*alpha+fC;
609 Real fNumer = fA11 + fB1 - fA01 - fB0;
613 distance2 = fA11+(2.0)*fB1+fC;
616 Real fDenom = fA00-2.0f*fA01+fA11;
617 if ( fNumer >= fDenom ){
620 distance2 = fA00+(2.0)*fB0+fC;
623 alpha = fNumer / fDenom;
625 distance2 = alpha*(fA00*alpha+fA01*beta+(2.0)*fB0) +
626 beta*(fA01*alpha+fA11*beta+(2.0)*fB1)+fC;
635 Real3 projection = v1 + alpha*edge0 + beta*edge1;
647 Real3 edge0 = v2 - v1;
648 Real3 edge1 = point - v1;
649 Real dot_product =
math::dot(edge0,edge1);
651 Real alpha = dot_product / norm;
660 distance = (point-v2).squareNormL2();
664 distance = (point - (v1 + alpha*edge0)).squareNormL2();
666 Real3 projection = v1 + alpha*edge0;
668 cout <<
"InfosDistance: v1=" << v1 <<
" v2=" << v2 <<
" point="
669 << point <<
" alpha=" << alpha
670 <<
" distance=" << distance
671 <<
" region=" << region
672 <<
" projection=" << projection <<
'\n';
683 Real3 kDiff = v1 - point;
684 Real3 edge0 = v2 - v1;
685 Real3 edge1 = v3 - v1;
692 Real fDet = math::abs(fA00*fA11-fA01*fA01);
694 Real alpha = fA01*fB1-fA11*fB0;
695 Real beta = fA01*fB0-fA00*fB1;
697 if ( alpha + beta <= fDet ){
701 else if ( beta < 0.0 ){
717 Real3 edge0 = v2 - v1;
718 Real3 edge1 = point - v1;
719 Real dot_product =
math::dot(edge0,edge1);
723 if (dot_product>0. && dot_product<norm)
static ProjectionInfo projection(Real3 v1, Real3 v2, Real3 v3, Real3 point)
Projection du point point au triangle défini par v1, v2 et v3.
static bool isInside(Real3 v1, Real3 v2, Real3 v3, Real3 point)
Indique si un la projection du point point est à l'intérieur du triangle défini par v1,...
bool cartesianToIso(Real3 point, Real3 &uvw, ITraceMng *tm)
Convertie une coordonnée cartérienne en coordonnée iso-paramétrique.
bool cartesianToIso2(Real3 point, Real3 &uvw, ITraceMng *tm)
Convertie une coordonnée cartérienne en coordonnée iso-paramétrique.
Classe gérant un vecteur de réel de dimension 3.
constexpr __host__ __device__ Real squareNormL2() const
Retourne la norme L2 au carré du triplet .
Classe gérant une matrice de réel de dimension 3x3.
Real3 z
premier élément du triplet
Real3 y
premier élément du triplet
Real3 x
premier élément du triplet
Interface du gestionnaire de traces.
virtual TraceMessage info()=0
Flot pour un message d'information.
__host__ __device__ Real dot(Real2 u, Real2 v)
Produit scalaire de u par v dans .
T max(const T &a, const T &b, const T &c)
Retourne le maximum de trois éléments.
__host__ __device__ Real3 vecMul(Real3 u, Real3 v)
Produit vectoriel de u par v. dans .
__host__ __device__ double sqrt(double v)
Racine carrée de v.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
double Real
Type représentant un réel.
Real y
deuxième composante du triplet
Real z
troisième composante du triplet
Real x
première composante du triplet