Arcane  4.1.12.0
User documentation
Loading...
Searching...
No Matches
MathUtils.h
Go to the documentation of this file.
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* MathUtils.h (C) 2000-2025 */
9/* */
10/* Diverse mathematical functions. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_CORE_MATHUTILS_H
13#define ARCANE_CORE_MATHUTILS_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arcane/utils/Math.h"
18#include "arcane/utils/ArrayView.h"
19#include "arcane/utils/NumericTypes.h"
20#include "arcane/utils/Real2x2.h"
21#include "arcane/utils/Real3.h"
22#include "arcane/utils/Real2.h"
23
24#include "arcane/core/Algorithm.h"
25
26/*---------------------------------------------------------------------------*/
27/*---------------------------------------------------------------------------*/
28
29/*!
30 \brief Namespace for mathematical functions.
31
32 This namespace contains all the mathematical functions used
33 by the code.
34*/
35namespace Arcane::math
36{
37
38/*---------------------------------------------------------------------------*/
39/*---------------------------------------------------------------------------*/
40
41/*!
42 * \ingroup GroupMathUtils
43 * \brief Vector cross product of \a u by \a v in \f$R^3\f$.
44 *
45 * \deprecated Use cross() instead.
46 */
47ARCCORE_HOST_DEVICE inline Real3
49{
50 return Real3(
51 u.y * v.z - u.z * v.y,
52 u.z * v.x - u.x * v.z,
53 u.x * v.y - u.y * v.x);
54}
55
56/*---------------------------------------------------------------------------*/
57/*---------------------------------------------------------------------------*/
58
59/*!
60 * \ingroup GroupMathUtils
61 * \brief Vector cross product of \a u by \a v in \f$R^2\f$.
62 *
63 * \deprecated Use cross2D() instead.
64 */
65ARCCORE_HOST_DEVICE inline Real
67{
68 return Real(u.x * v.y - u.y * v.x);
69}
70
71/*---------------------------------------------------------------------------*/
72/*---------------------------------------------------------------------------*/
73
74/*!
75 * \ingroup GroupMathUtils
76 * \brief Vector cross product of \a u by \a v in \f$R^2\f$.
77 */
78ARCCORE_HOST_DEVICE inline Real
80{
81 return Real(u.x * v.y - u.y * v.x);
82}
83
84/*---------------------------------------------------------------------------*/
85/*---------------------------------------------------------------------------*/
86
87/*!
88 * \ingroup GroupMathUtils
89 * \brief Dot product of \a u by \a v in \f$R^2\f$.
90 *
91 * This is: \f$u{\cdot}v\f$
92 */
93ARCCORE_HOST_DEVICE inline Real
95{
96 return (u.x * v.x + u.y * v.y);
97}
98
99/*---------------------------------------------------------------------------*/
100/*---------------------------------------------------------------------------*/
101
102/*!
103 * \brief Dot product of \a u by \a v in \f$R^2\f$
104 *
105 * \ingroup GroupMathUtils
106 *
107 * This is: \f$u{\cdot}v\f$.
108 *
109 * \deprecated Use dot(Real2,Real2) instead
110 */
111ARCCORE_HOST_DEVICE inline Real
113{
114 return (u.x * v.x + u.y * v.y);
115}
116
117/*---------------------------------------------------------------------------*/
118/*---------------------------------------------------------------------------*/
119
120/*!
121 * \brief Dot product of \a u by \a v
122 *
123 * \ingroup GroupMathUtils
124 *
125 * This is: \f$u{\cdot}v\f$.
126 */
127ARCCORE_HOST_DEVICE inline Real
129{
130 return (u.x * v.x + u.y * v.y + u.z * v.z);
131}
132
133/*---------------------------------------------------------------------------*/
134/*---------------------------------------------------------------------------*/
135
136/*!
137 * \brief Dot product of \a u by \a v
138 *
139 * \ingroup GroupMathUtils
140 *
141 * This is: \f$u{\cdot}v\f$
142 *
143 * \deprecated Use dot(Real2,Real2) instead
144 */
145ARCCORE_HOST_DEVICE inline Real
147{
148 return (u.x * v.x + u.y * v.y + u.z * v.z);
149}
150
151/*---------------------------------------------------------------------------*/
152/*---------------------------------------------------------------------------*/
153
154/*!
155 * \brief Mixed product of \a u, \a v and \a w
156 *
157 * \ingroup GroupMathUtils
158 *
159 */
160ARCCORE_HOST_DEVICE inline Real
162{
163 return dot(u, vecMul(v, w));
164}
165
166/*---------------------------------------------------------------------------*/
167/*---------------------------------------------------------------------------*/
168
169/*!
170 * \brief Determinant of the matrix u,v,w
171 */
172ARCCORE_HOST_DEVICE inline Real
174{
175 return (
176 (u.x * (v.y * w.z - v.z * w.y)) +
177 (u.y * (v.z * w.x - v.x * w.z)) +
178 (u.z * (v.x * w.y - v.y * w.x)));
179}
180
181/*---------------------------------------------------------------------------*/
182/*---------------------------------------------------------------------------*/
183
184/*!
185 * \ingroup GroupMathUtils
186 * \brief Tensor product of two Real3 vectors.
187
188 Il s'agit de \f$\vec{u}=~^t(u_{x},u_{y},u_{z})\f$ et \f$\vec{v}=~^t(v_{x},v_{y},v_{z})\f$
189 et est noté \f$\vec{u} \otimes \vec{v}\f$, et est donné par~:
190
191 * Ux*Vx Ux*Vy Ux*Vz
192 *U \otimes V = Uy*Vx Uy*Vy Uy*Vz
193 * Uz*Vx Uz*Vy Uz*Vz
194 */
195inline Real3x3
197{
198 return Real3x3(u.x * v, u.y * v, u.z * v);
199}
200
201/*---------------------------------------------------------------------------*/
202/*---------------------------------------------------------------------------*/
203
204/*!
205 * \brief Matrix-vector product between a tensor and a vector.
206 *
207 * \ingroup GroupMathUtils
208 *
209 */
210ARCCORE_HOST_DEVICE inline Real3
212{
213 return Real3(dot(t.x, v), dot(t.y, v), dot(t.z, v));
214}
215ARCCORE_HOST_DEVICE inline Real2
217{
218 return Real2(dot(t.x, v), dot(t.y, v));
219}
220
221/*---------------------------------------------------------------------------*/
222/*---------------------------------------------------------------------------*/
223
224/*!
225 * \ingroup GroupMathUtils
226 * \brief Transposed(vector) matrix product between the transpose of a vector and a matrix.
227 *
228 * Returns the transposed vector of the result.
229 */
230ARCCORE_HOST_DEVICE inline Real3
232{
233 return Real3(dot(v, Real3(t.x.x, t.y.x, t.z.x)), dot(v, Real3(t.x.y, t.y.y, t.z.y)), dot(v, Real3(t.x.z, t.y.z, t.z.z)));
234}
235
236/*---------------------------------------------------------------------------*/
237/*---------------------------------------------------------------------------*/
238
239/*!
240 * \ingroup GroupMathUtils
241 * \brief Matrix-matrix product between two tensors.
242 */
243ARCCORE_HOST_DEVICE inline Real3x3
244matrixProduct(const Real3x3& t, const Real3x3& v)
245{
246 return Real3x3::fromLines(t.x.x * v.x.x + t.x.y * v.y.x + t.x.z * v.z.x,
247 t.x.x * v.x.y + t.x.y * v.y.y + t.x.z * v.z.y,
248 t.x.x * v.x.z + t.x.y * v.y.z + t.x.z * v.z.z,
249 t.y.x * v.x.x + t.y.y * v.y.x + t.y.z * v.z.x,
250 t.y.x * v.x.y + t.y.y * v.y.y + t.y.z * v.z.y,
251 t.y.x * v.x.z + t.y.y * v.y.z + t.y.z * v.z.z,
252 t.z.x * v.x.x + t.z.y * v.y.x + t.z.z * v.z.x,
253 t.z.x * v.x.y + t.z.y * v.y.y + t.z.z * v.z.y,
254 t.z.x * v.x.z + t.z.y * v.y.z + t.z.z * v.z.z);
255}
256
257/*---------------------------------------------------------------------------*/
258/*---------------------------------------------------------------------------*/
259
260/*!
261 * \brief Transpose the matrix.
262 * \deprecated Use matrixTranspose() instead.
263 */
264ARCCORE_HOST_DEVICE inline Real3x3
266{
267 return Real3x3(Real3(t.x.x, t.y.x, t.z.x),
268 Real3(t.x.y, t.y.y, t.z.y),
269 Real3(t.x.z, t.y.z, t.z.z));
270}
271
272/*---------------------------------------------------------------------------*/
273/*---------------------------------------------------------------------------*/
274
275/*!
276 * \ingroup GroupMathUtils
277 * \brief Transpose the matrix.
278 */
279ARCCORE_HOST_DEVICE inline Real3x3
281{
282 return Real3x3(Real3(t.x.x, t.y.x, t.z.x),
283 Real3(t.x.y, t.y.y, t.z.y),
284 Real3(t.x.z, t.y.z, t.z.z));
285}
286
287/*---------------------------------------------------------------------------*/
288/*---------------------------------------------------------------------------*/
289
290/*!
291 * \ingroup GroupMathUtils
292 * \brief Double contracted product of two tensors.
293 *
294 * U:V = sum_{i,j \in \{x,y,z \}} U_{i,j}V_{i,j}
295 */
296ARCCORE_HOST_DEVICE inline Real
298{
299 Real x1 = u.x.x * v.x.x;
300 Real x2 = u.x.y * v.x.y;
301 Real x3 = u.x.z * v.x.z;
302
303 Real y1 = u.y.x * v.y.x;
304 Real y2 = u.y.y * v.y.y;
305 Real y3 = u.y.z * v.y.z;
306
307 Real z1 = u.z.x * v.z.x;
308 Real z2 = u.z.y * v.z.y;
309 Real z3 = u.z.z * v.z.z;
310
311 return x1 + x2 + x3 + y1 + y2 + y3 + z1 + z2 + z3;
312}
313
314/*---------------------------------------------------------------------------*/
315/*---------------------------------------------------------------------------*/
316
317/*!
318 * \ingroup GroupMathUtils
319 * \brief Double contracted product of two tensors.
320 *
321 * U:V = sum_{i,j \in \{x,y,z \}} U_{i,j}V_{i,j}
322 */
323ARCCORE_HOST_DEVICE inline Real
325{
326 Real x1 = u.x.x * v.x.x;
327 Real x2 = u.x.y * v.x.y;
328
329 Real y1 = u.y.x * v.y.x;
330 Real y2 = u.y.y * v.y.y;
331
332 return x1 + x2 + y1 + y2;
333}
334
335/*---------------------------------------------------------------------------*/
336/*---------------------------------------------------------------------------*/
337
338/*---------------------------------------------------------------------------*/
339/*---------------------------------------------------------------------------*/
340
341/*!
342 * \brief Returns the minimum of two Real2
343 * \ingroup GroupMathUtils
344 */
345ARCCORE_HOST_DEVICE inline Real2
347{
348 return Real2(math::min(a.x, b.x), math::min(a.y, b.y));
349}
350
351/*!
352 * \brief Returns the minimum of two Real3s
353 * \ingroup GroupMathUtils
354 */
355ARCCORE_HOST_DEVICE inline Real3
357{
358 return Real3(math::min(a.x, b.x), math::min(a.y, b.y), math::min(a.z, b.z));
359}
360
361/*!
362 * \brief Returns the minimum of two Real2x2s
363 * \ingroup GroupMathUtils
364 */
365ARCCORE_HOST_DEVICE inline Real2x2
366min(const Real2x2& a, const Real2x2& b)
367{
368 return Real2x2(math::min(a.x, b.x), math::min(a.y, b.y));
369}
370
371/*!
372 * \brief Returns the minimum of two Real3x3s
373 * \ingroup GroupMathUtils
374 */
375ARCCORE_HOST_DEVICE inline Real3x3
376min(const Real3x3& a, const Real3x3& b)
377{
378 return Real3x3(math::min(a.x, b.x), math::min(a.y, b.y), math::min(a.z, b.z));
379}
380
381/*---------------------------------------------------------------------------*/
382/*---------------------------------------------------------------------------*/
383
384/*!
385 * \brief Returns the minimum of three elements.
386 *
387 * \ingroup GroupMathUtils
388 *
389 * Uses the < operator to determine the minimum.
390 */
391template <class T> inline T
392min(const T& a, const T& b, const T& c)
393{
394 return ((a < b) ? ((a < c) ? a : ((b < c) ? b : c)) : ((b < c) ? b : c));
395}
396
397/*---------------------------------------------------------------------------*/
398/*---------------------------------------------------------------------------*/
399
400/*!\brief Returns the maximum of three elements.
401 *
402 * \ingroup GroupMathUtils
403 *
404 * Uses the > operator to determine the maximum.
405 */
406template <class T> inline T
407max(const T& a, const T& b, const T& c)
408{
409 return ((a > b) ? ((a > c) ? a : c) : ((b > c) ? b : c));
410}
411
412/*---------------------------------------------------------------------------*/
413/*---------------------------------------------------------------------------*/
414
415/*!
416 * \brief Returns the maximum of two Real2s
417 * \ingroup GroupMathUtils
418 */
419ARCCORE_HOST_DEVICE inline Real2
421{
422 return Real2(math::max(a.x, b.x), math::max(a.y, b.y));
423}
424
425/*!
426 * \brief Returns the maximum of two Real3s
427 * \ingroup GroupMathUtils
428 */
429ARCCORE_HOST_DEVICE inline Real3
431{
432 return Real3(math::max(a.x, b.x), math::max(a.y, b.y), math::max(a.z, b.z));
433}
434
435/*!
436 * \brief Returns the maximum of two Real2x2s
437 * \ingroup GroupMathUtils
438 */
439ARCCORE_HOST_DEVICE inline Real2x2
440max(const Real2x2& a, const Real2x2& b)
441{
442 return Real2x2(math::max(a.x, b.x), math::max(a.y, b.y));
443}
444
445/*!
446 * \brief Returns the maximum of two Real3x3s
447 * \ingroup GroupMathUtils
448 */
449ARCCORE_HOST_DEVICE inline Real3x3
450max(const Real3x3& a, const Real3x3& b)
451{
452 return Real3x3(math::max(a.x, b.x), math::max(a.y, b.y), math::max(a.z, b.z));
453}
454
455/*---------------------------------------------------------------------------*/
456/*---------------------------------------------------------------------------*/
457
458/*---------------------------------------------------------------------------*/
459/*---------------------------------------------------------------------------*/
460
461/*!
462 * \brief Returns the minimum of four Reals
463 */
464ARCCORE_HOST_DEVICE inline Real
466{
467 return min(min(a, b), min(c, d));
468}
469
470/*---------------------------------------------------------------------------*/
471/*---------------------------------------------------------------------------*/
472
473/*!
474 * \brief Returns the maximum of four Reals
475 */
476ARCCORE_HOST_DEVICE inline Real
478{
479 return max(max(a, b), max(c, d));
480}
481
482/*---------------------------------------------------------------------------*/
483/*---------------------------------------------------------------------------*/
484
485/*!
486 * \brief Returns the minimum of eight <tt>Reals</tt>
487 */
488ARCCORE_HOST_DEVICE inline Real
489min8Real(const Real a[8])
490{
491 return min(min4Real(a[0], a[1], a[2], a[3]), min4Real(a[4], a[5], a[6], a[7]));
492}
493
494/*---------------------------------------------------------------------------*/
495/*---------------------------------------------------------------------------*/
496
497/*!
498 * \brief Returns the maximum of eight <tt>Reals</tt>
499 */
500inline Real max8Real(const Real a[8])
501{
502 return max(max4Real(a[0], a[1], a[2], a[3]), max4Real(a[4], a[5], a[6], a[7]));
503}
504
505/*---------------------------------------------------------------------------*/
506/*---------------------------------------------------------------------------*/
507
508/*!
509 * \ingroup GroupMathUtils
510 * \brief Returns the Min mod of four Reals
511 */
512ARCCORE_HOST_DEVICE inline Real
514{
515 Real zero = 0.;
516 return min4Real(max(a, zero), max(b, zero), max(c, zero), max(d, zero)) + max4Real(min(a, zero), min(b, zero), min(c, zero), min(d, zero));
517}
518/*---------------------------------------------------------------------------*/
519/*---------------------------------------------------------------------------*/
520
521/*!
522 * \ingroup GroupMathUtils
523 * \brief Returns the Min mod of two Reals
524 */
525ARCCORE_HOST_DEVICE inline Real
527{
528 Real zero = 0.;
529 return min(max(a, zero), max(b, zero)) + max(min(a, zero), min(b, zero));
530}
531
532/*---------------------------------------------------------------------------*/
533/*---------------------------------------------------------------------------*/
534
535/*!
536 * \ingroup GroupMathUtils
537 * \brief Returns the Max mod of two Reals
538 *
539 */
540ARCCORE_HOST_DEVICE inline Real
542{
543 Real zero = 0.;
544 return max(max(a, zero), max(b, zero)) + min(min(a, zero), min(b, zero));
545}
546
547/*---------------------------------------------------------------------------*/
548/*---------------------------------------------------------------------------*/
549
550/*!
551 * \brief Returns the relative error between two scalars \a a and \a b.
552 *
553 * The relative error is calculated by:
554 *
555 * \f$\frac{a-b}{|a|+|b|}\f$
556 */
557inline Real
559{
560 Real sum = math::abs(a) + math::abs(b);
561 return (isZero(sum)) ? (a - b) : (a - b) / sum;
562}
563
564/*---------------------------------------------------------------------------*/
565/*---------------------------------------------------------------------------*/
566
567/*!
568 * \brief Returns the relative error between two tensors \a T1 and \a T2.
569 *
570 * The relative error is calculated as the maximum of the relative errors
571 * on each of the tensor components.
572 *
573 */
574inline Real
575relativeError(const Real3x3& T1, const Real3x3& T2)
576{
577 Real err = 0;
578 err = math::max(err, math::abs(relativeError(T1.x.x, T2.x.x)));
579 err = math::max(err, math::abs(relativeError(T1.x.y, T2.x.y)));
580 err = math::max(err, math::abs(relativeError(T1.x.z, T2.x.z)));
581 err = math::max(err, math::abs(relativeError(T1.y.x, T2.y.x)));
582 err = math::max(err, math::abs(relativeError(T1.y.y, T2.y.y)));
583 err = math::max(err, math::abs(relativeError(T1.y.z, T2.y.z)));
584 err = math::max(err, math::abs(relativeError(T1.z.x, T2.z.x)));
585 err = math::max(err, math::abs(relativeError(T1.z.y, T2.z.y)));
586 err = math::max(err, math::abs(relativeError(T1.z.z, T2.z.z)));
587
588 return (err);
589}
590
591/*---------------------------------------------------------------------------*/
592/*---------------------------------------------------------------------------*/
593
594/*!
595 * \brief Returns the relative error between two scalars \a a and \a b relative to \a b
596 *
597 * The relative error is calculated by:
598 *
599 * \f$\frac{a-b}{(|b|)}\f$
600 */
601inline Real
603{
604 Real sum = math::abs(b);
605 return (isZero(sum)) ? (a - b) : (a - b) / sum;
606}
607
608/*---------------------------------------------------------------------------*/
609/*---------------------------------------------------------------------------*/
610
611/*!
612 * \brief Returns the relative error between two scalars \a a and \a b relative to \a a
613 *
614 * The relative error is calculated by:
615 *
616 * \f$\frac{a-b}{(|b|)}\f$
617 */
618inline Real
620{
621 Real sum = math::abs(a);
622 return (isZero(sum)) ? (a - b) : (a - b) / sum;
623}
624
625/*---------------------------------------------------------------------------*/
626/*---------------------------------------------------------------------------*/
627
628/*!
629 * \brief Searches for the extreme values of an array of pairs (x,y).
630 */
631inline bool
633 Real& ymin, Real& ymax, bool need_init)
634{
635 if (need_init) {
636 xmin = ymin = 0.;
637 xmax = ymax = 1.;
638 }
639
640 Integer size = array.size();
641 if (size == 0)
642 return false;
643
644 if (need_init) {
645 xmin = xmax = array[0].x;
646 ymin = ymax = array[0].y;
647 }
648
649 for (Integer i = 1; i < size; ++i) {
650 if (array[i].x < xmin)
651 xmin = array[i].x;
652 if (array[i].x > xmax)
653 xmax = array[i].x;
654
655 if (array[i].y < ymin)
656 ymin = array[i].y;
657 if (array[i].y > ymax)
658 ymax = array[i].y;
659 }
660 return true;
661}
662
663/*---------------------------------------------------------------------------*/
664/*---------------------------------------------------------------------------*/
665
666/*!
667 * \brief Calculates the determinant of a 3x3 matrix.
668 */
669ARCCORE_HOST_DEVICE inline Real
671{
672 return m.determinant();
673}
674
675/*---------------------------------------------------------------------------*/
676/*---------------------------------------------------------------------------*/
677
678/*!
679 * \brief Norm of a vector
680 *
681 * \deprecated Use Real3.abs() instead.
682 */
683inline Real
685{
686 Real norme = math::sqrt((v1.x) * (v1.x) + (v1.y) * (v1.y) + (v1.z) * (v1.z));
687 return norme;
688}
689/*---------------------------------------------------------------------------*/
690/*---------------------------------------------------------------------------*/
691
692/*!
693 * \brief Identity matrix.
694 */
695ARCCORE_HOST_DEVICE inline Real3x3
697{
698 return Real3x3(Real3(1.0, 0.0, 0.0),
699 Real3(0.0, 1.0, 0.0),
700 Real3(0.0, 0.0, 1.0));
701}
702
703/*---------------------------------------------------------------------------*/
704/*---------------------------------------------------------------------------*/
705
706/*!
707 * \brief Calculates the inverse of a matrix \a m assuming its determinant \a d is known
708 */
709ARCCORE_HOST_DEVICE inline Real3x3
711{
712 Real3x3 inv(Real3(m.y.y * m.z.z - m.y.z * m.z.y, -m.x.y * m.z.z + m.x.z * m.z.y, m.x.y * m.y.z - m.x.z * m.y.y),
713 Real3(m.z.x * m.y.z - m.y.x * m.z.z, -m.z.x * m.x.z + m.x.x * m.z.z, m.y.x * m.x.z - m.x.x * m.y.z),
714 Real3(-m.z.x * m.y.y + m.y.x * m.z.y, m.z.x * m.x.y - m.x.x * m.z.y, -m.y.x * m.x.y + m.x.x * m.y.y));
715 inv /= d;
716 return inv;
717}
718
719/*---------------------------------------------------------------------------*/
720/*---------------------------------------------------------------------------*/
721
722/*!
723 * \brief Calculates the inverse of a matrix \a m.
724 */
725ARCCORE_HOST_DEVICE inline Real3x3
727{
728 Real d = m.determinant();
729 return inverseMatrix(m, d);
730}
731
732/*---------------------------------------------------------------------------*/
733/*---------------------------------------------------------------------------*/
734
735/*!
736 * \brief Cross product of two 3-component vectors.
737 *
738 * \deprecated Use cross() instead.
739 */
740inline Real3
742{
743 Real3 v;
744 v.x = v1.y * v2.z - v1.z * v2.y;
745 v.y = v2.x * v1.z - v2.z * v1.x;
746 v.z = v1.x * v2.y - v1.y * v2.x;
747
748 return v;
749}
750
751/*---------------------------------------------------------------------------*/
752/*---------------------------------------------------------------------------*/
753
754/*!
755 * \ingroup GroupMathUtils
756 * \brief Cross product of two 3-component vectors.
757 */
758ARCCORE_HOST_DEVICE inline Real3
760{
761 Real3 v;
762 v.x = v1.y * v2.z - v1.z * v2.y;
763 v.y = v2.x * v1.z - v2.z * v1.x;
764 v.z = v1.x * v2.y - v1.y * v2.x;
765
766 return v;
767}
768
769/*---------------------------------------------------------------------------*/
770/*---------------------------------------------------------------------------*/
771
772/*!
773 * \ingroup GroupMathUtils
774 * \brief Normalization of a Real3.
775 * \pre The norm of \a v must not be zero.
776 */
777ARCCORE_HOST_DEVICE inline Real3
779{
780 Real norme = math::sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
781
782 return Real3(v.x / norme, v.y / norme, v.z / norme);
783}
784
785/*---------------------------------------------------------------------------*/
786/*---------------------------------------------------------------------------*/
787
788/*!
789 * \ingroup GroupMathUtils
790 * \brief Normalized cross product.
791 */
792inline Real3
794{
795 return normalizeReal3(cross(v1, v2));
796}
797
798/*---------------------------------------------------------------------------*/
799/*---------------------------------------------------------------------------*/
800
801/*!
802 * \ingroup GroupMathUtils
803 *
804 * \warning This method does not use the usual convention for Real3x3.
805 * It assumes they are stored in columns. Generally, you should use
806 * matrixTanspose() instead.
807 */
808inline Real3x3
810{
811 return Real3x3::fromColumns(m.x.x, m.x.y, m.x.z,
812 m.y.x, m.y.y, m.y.z,
813 m.z.x, m.z.y, m.z.z);
814}
815
816/*---------------------------------------------------------------------------*/
817/*---------------------------------------------------------------------------*/
818
819/*!
820 * \brief Multiplication of 2 3x3 matrices.
821 *
822 * \warning This method does not use the usual convention for Real3x3.
823 * It assumes they are stored in columns. Generally, you should use
824 * matrixProduct() instead.
825 */
826inline Real3x3
828{
830 m1.x.x * m2.x.x + m1.y.x * m2.x.y + m1.z.x * m2.x.z,
831 m1.x.y * m2.x.x + m1.y.y * m2.x.y + m1.z.y * m2.x.z,
832 m1.x.z * m2.x.x + m1.y.z * m2.x.y + m1.z.z * m2.x.z,
833 m1.x.x * m2.y.x + m1.y.x * m2.y.y + m1.z.x * m2.y.z,
834 m1.x.y * m2.y.x + m1.y.y * m2.y.y + m1.z.y * m2.y.z,
835 m1.x.z * m2.y.x + m1.y.z * m2.y.y + m1.z.z * m2.y.z,
836 m1.x.x * m2.z.x + m1.y.x * m2.z.y + m1.z.x * m2.z.z,
837 m1.x.y * m2.z.x + m1.y.y * m2.z.y + m1.z.y * m2.z.z,
838 m1.x.z * m2.z.x + m1.y.z * m2.z.y + m1.z.z * m2.z.z);
839}
840
841/*---------------------------------------------------------------------------*/
842/*---------------------------------------------------------------------------*/
843
844/*!
845 * \brief 3x3 matrix multiplied by a vector.
846 */
847ARCCORE_HOST_DEVICE inline Real3
849{
850 return Real3(m.x.x * v.x + m.x.y * v.y + m.x.z * v.z,
851 m.y.x * v.x + m.y.y * v.y + m.y.z * v.z,
852 m.z.x * v.x + m.z.y * v.y + m.z.z * v.z);
853}
854/*---------------------------------------------------------------------------*/
855/*---------------------------------------------------------------------------*/
856
857/*!
858 * \brief Checks if a matrix is the identity matrix.
859 */
860inline bool
861isNearlyId(Real3x3 m, Real epsilon = 1.e-10)
862{
863 static Real3x3 id = Real3x3(Real3(1., 0., 0.), Real3(0., 1., 0.), Real3(0., 0., 1.));
864 // static Real epsilon = 1.e-10;
865
866 Real3x3 m0 = m - id;
867
868 return (m0.x.x < epsilon) && (m0.x.y < epsilon) && (m0.x.z < epsilon) &&
869 (m0.y.x < epsilon) && (m0.y.y < epsilon) && (m0.y.z < epsilon) &&
870 (m0.z.x < epsilon) && (m0.z.y < epsilon) && (m0.z.z < epsilon);
871}
872
873/*---------------------------------------------------------------------------*/
874/*---------------------------------------------------------------------------*/
875
876/*!
877 * \ingroup GroupMathUtils
878 * \brief Symmetry of a vector \a u with respect to a normal plane \a n.
879 */
880inline Real3
882{
883 Real3 u_tilde;
884#ifdef ARCANE_CHECK
885 if (n.normL2() == 0) {
886 arcaneMathError(Convert::toDouble(n.normL2()), "planarSymetric");
887 }
888#endif
889 Real3 norm = n / n.normL2();
890 u_tilde = u - 2.0 * dot(norm, u) * norm;
891 return u_tilde;
892}
893
894/*---------------------------------------------------------------------------*/
895/*---------------------------------------------------------------------------*/
896
897/*!
898 * \ingroup GroupMathUtils
899 * \brief Symmetry of a vector u with respect to an axis defined by direction vector a.
900 */
901inline Real3
903{
904 Real3 u_tilde;
905#ifdef ARCANE_CHECK
906 if (a.normL2() == 0) {
907 arcaneMathError(Convert::toDouble(a.normL2()), "axisSymetric");
908 }
909#endif
910 Real3 norm = a / a.normL2();
911 u_tilde = 2.0 * dot(u, norm) * norm - u;
912 return u_tilde;
913}
914
915/*---------------------------------------------------------------------------*/
916/*---------------------------------------------------------------------------*/
917
918/*!
919 * \brief Adds the array \a copy_array to the instance.
920 *
921 * Since no memory allocation is performed, the
922 * number of elements in \a copy_array must be less than or equal to the
923 * current number of elements. If it is smaller, the elements of the
924 * current array located at the end of the array remain unchanged
925 */
926template <typename T> inline void
928{
929 Integer size = lhs.size();
930 ARCANE_ASSERT((copy_array.size() >= size), ("Bad size %d %d", copy_array.size(), size));
931 const T* copy_begin = copy_array.data();
932 T* to_ptr = lhs.data();
933 for (Integer i = 0; i < size; ++i)
934 to_ptr[i] += copy_begin[i];
935}
936
937/*!
938 * \brief Adds the array \a copy_array to the instance.
939 *
940 * Since no memory allocation is performed, the
941 * number of elements in \a copy_array must be less than or equal to the
942 * current number of elements. If it is smaller, the elements of the
943 * current array located at the end of the array remain unchanged
944 */
945template <typename T> inline void
947{
948 Integer size = lhs.size();
949 ARCANE_ASSERT((copy_array.size() >= size), ("Bad size %d %d", copy_array.size(), size));
950 const T* copy_begin = copy_array.data();
951 T* to_ptr = lhs.data();
952 for (Integer i = 0; i < size; ++i)
953 to_ptr[i] += copy_begin[i];
954}
955
956/*!
957 * \brief Subtracts the array \a copy_array from the instance.
958 *
959 * Since no memory allocation is performed, the
960 * number of elements in \a copy_array must be less than or equal to the
961 * current number of elements. If it is smaller, the elements of the
962 * current array located at the end of the array remain unchanged
963 */
964template <typename T> inline void
966{
967 Integer size = lhs.size();
968 ARCANE_ASSERT((copy_array.size() >= size), ("Bad size %d %d", copy_array.size(), size));
969 const T* copy_begin = copy_array.data();
970 T* to_ptr = lhs.data();
971 for (Integer i = 0; i < size; ++i)
972 to_ptr[i] -= copy_begin[i];
973}
974
975/*!
976 * \brief Subtracts the array \a copy_array from the instance.
977 *
978 * Since no memory allocation is performed, the
979 * number of elements in \a copy_array must be less than or equal to the
980 * current number of elements. If it is smaller, the elements of the
981 * current array located at the end of the array remain unchanged
982 */
983template <typename T> inline void
985{
986 Integer size = lhs.size();
987 ARCANE_ASSERT((copy_array.size() >= size), ("Bad size %d %d", copy_array.size(), size));
988 const T* copy_begin = copy_array.data();
989 T* to_ptr = lhs.data();
990 for (Integer i = 0; i < size; ++i)
991 to_ptr[i] -= copy_begin[i];
992}
993
994/*!
995 * \brief Multiplies the elements of the instance term-by-term by the
996 * elements of the array \a copy_array.
997 *
998 * Since no memory allocation
999 * is performed, the number of elements in \a copy_array
1000 * must be less than or equal to the current number of elements. If it
1001 * is smaller, the elements of the current array located at the end of the
1002 * array remain unchanged
1003 */
1004template <typename T> inline void
1006{
1007 Integer size = lhs.size();
1008 ARCANE_ASSERT((copy_array.size() >= size), ("Bad size %d %d", copy_array.size(), size));
1009 const T* copy_begin = copy_array.data();
1010 T* to_ptr = lhs.data();
1011 for (Integer i = 0; i < size; ++i)
1012 to_ptr[i] *= copy_begin[i];
1013}
1014
1015/*!
1016 * \brief Multiplies the elements of the instance term-by-term by the
1017 * elements of the array \a copy_array.
1018 *
1019 * Since no memory allocation
1020 * is performed, the number of elements in \a copy_array
1021 * must be less than or equal to the current number of elements. If it
1022 * is smaller, the elements of the current array located at the end of the
1023 * array remain unchanged
1024 */
1025template <typename T> inline void
1027{
1028 math::mult(lhs, copy_array.constView());
1029}
1030
1031/*!
1032 * \brief Multiplies all elements of the array by the real number \a o.
1033 */
1034template <typename T> inline void
1036{
1037 T* ptr = lhs.data();
1038 for (Integer i = 0, size = lhs.size(); i < size; ++i)
1039 ptr[i] *= o;
1040}
1041
1042/*!
1043 * \brief Raises all elements of the array to the power \a o.
1044 */
1045template <typename T> inline void
1047{
1048 T* ptr = lhs.data();
1049 for (Integer i = 0, size = lhs.size(); i < size; ++i)
1050 ptr[i] = math::pow(ptr[i], o);
1051}
1052
1053/*---------------------------------------------------------------------------*/
1054/*---------------------------------------------------------------------------*/
1055
1056} // namespace Arcane::math
1057
1058/*---------------------------------------------------------------------------*/
1059/*---------------------------------------------------------------------------*/
1060
1061#endif
Modifiable view of an array of type T.
constexpr const_pointer data() const noexcept
Pointer to the start of the view.
constexpr ConstArrayView< T > constView() const noexcept
Constant view of this view.
constexpr Integer size() const noexcept
Returns the size of the array.
Constant view of an array of type T.
constexpr const_pointer data() const noexcept
Pointer to the allocated memory.
constexpr Integer size() const noexcept
Number of elements in the array.
Class managing a 2-dimensional real vector.
Definition Real2.h:122
Class managing a 2x2 matrix of reals.
Definition Real2x2.h:55
Real2 x
First component.
Definition Real2x2.h:112
Real2 y
Second component.
Definition Real2x2.h:113
Class managing a 3-dimensional real vector.
Definition Real3.h:132
__host__ __device__ Real normL2() const
Returns the L2 norm of the triplet $ .
Definition Real3.h:585
Class managing a 3x3 real matrix.
Definition Real3x3.h:67
Real3 z
first element of the triplet
Definition Real3x3.h:131
constexpr __host__ static __device__ Real3x3 fromLines(Real ax, Real bx, Real cx, Real ay, Real by, Real cy, Real az, Real bz, Real cz)
Constructs the matrix ((ax,bx,cx),(ay,by,cy),(az,bz,cz)).
Definition Real3x3.h:151
Real3 y
first element of the triplet
Definition Real3x3.h:130
constexpr __host__ __device__ Real determinant() const
Determinant of the matrix.
Definition Real3x3.h:366
constexpr __host__ static __device__ Real3x3 fromColumns(Real ax, Real ay, Real az, Real bx, Real by, Real bz, Real cx, Real cy, Real cz)
Constructs the matrix ((ax,bx,cx),(ay,by,cy),(az,bz,cz)).
Definition Real3x3.h:145
Real3 x
first element of the triplet
Definition Real3x3.h:129
__host__ __device__ Real vecMul2D(Real3 u, Real3 v)
Vector cross product of u by v in .
Definition MathUtils.h:66
__host__ __device__ Real dot(Real2 u, Real2 v)
Dot product of u by v in .
Definition MathUtils.h:94
__host__ __device__ Real2 min(Real2 a, Real2 b)
Returns the minimum of two Real2.
Definition MathUtils.h:346
T max(const T &a, const T &b, const T &c)
Returns the maximum of three elements.
Definition MathUtils.h:407
__host__ __device__ Real3 vecMul(Real3 u, Real3 v)
Vector cross product of u by v in .
Definition MathUtils.h:48
Real3 normalizedCrossProduct3(Real3 v1, Real3 v2)
Normalized cross product.
Definition MathUtils.h:793
__host__ __device__ Real minMod(Real a, Real b, Real c, Real d)
Returns the Min mod of four Reals.
Definition MathUtils.h:513
__host__ __device__ Real minMod2(Real a, Real b)
Returns the Min mod of two Reals.
Definition MathUtils.h:526
__host__ __device__ Real cross2D(Real3 u, Real3 v)
Vector cross product of u by v in .
Definition MathUtils.h:79
__host__ __device__ Real scaMul(Real2 u, Real2 v)
Dot product of u by v in .
Definition MathUtils.h:112
__host__ __device__ Real3 prodVecTens(Real3 v, Real3x3 t)
Transposed(vector) matrix product between the transpose of a vector and a matrix.
Definition MathUtils.h:231
__host__ __device__ Real3 cross(Real3 v1, Real3 v2)
Cross product of two 3-component vectors.
Definition MathUtils.h:759
__host__ __device__ Real3 normalizeReal3(Real3 v)
Normalization of a Real3.
Definition MathUtils.h:778
Real3x3 prodTens(Real3 u, Real3 v)
Tensor product of two Real3 vectors.
Definition MathUtils.h:196
__host__ __device__ Real maxMod2(Real a, Real b)
Returns the Max mod of two Reals.
Definition MathUtils.h:541
__host__ __device__ Real3x3 matrixProduct(const Real3x3 &t, const Real3x3 &v)
Matrix-matrix product between two tensors.
Definition MathUtils.h:244
Real3x3 matrix3x3Transp(Real3x3 m)
Definition MathUtils.h:809
Real3 planarSymmetric(Real3 u, Real3 n)
Symmetry of a vector u with respect to a normal plane n.
Definition MathUtils.h:881
__host__ __device__ Real3 prodTensVec(Real3x3 t, Real3 v)
Matrix-vector product between a tensor and a vector.
Definition MathUtils.h:211
Real3 axisSymmetric(Real3 u, Real3 a)
Symmetry of a vector u with respect to an axis defined by direction vector a.
Definition MathUtils.h:902
__host__ __device__ Real mixteMul(Real3 u, Real3 v, Real3 w)
Mixed product of u, v and w.
Definition MathUtils.h:161
__host__ __device__ Real3x3 matrixTranspose(const Real3x3 &t)
Transpose the matrix.
Definition MathUtils.h:280
double toDouble(Real r)
Converts a Real to double.
Namespace for mathematical functions.
Definition MathUtils.h:36
__host__ __device__ double pow(double x, double y)
Power function.
Definition Math.h:175
Real relativeError(Real a, Real b)
Returns the relative error between two scalars a and b.
Definition MathUtils.h:558
__host__ __device__ Real min8Real(const Real a[8])
Returns the minimum of eight Reals.
Definition MathUtils.h:489
Real relativeError2(Real a, Real b)
Returns the relative error between two scalars a and b relative to b.
Definition MathUtils.h:602
__host__ __device__ double sqrt(double v)
Square root of v.
Definition Math.h:142
void power(ArrayView< T > lhs, T o)
Raises all elements of the array to the power o.
Definition MathUtils.h:1046
Real normeR3(Real3 v1)
Norm of a vector.
Definition MathUtils.h:684
Real relativeError1(Real a, Real b)
Returns the relative error between two scalars a and b relative to a.
Definition MathUtils.h:619
bool isNearlyId(Real3x3 m, Real epsilon=1.e-10)
Checks if a matrix is the identity matrix.
Definition MathUtils.h:861
bool searchExtrema(ConstArrayView< Real2 > array, Real &xmin, Real &xmax, Real &ymin, Real &ymax, bool need_init)
Searches for the extreme values of an array of pairs (x,y).
Definition MathUtils.h:632
__host__ __device__ Real doubleContraction(const Real3x3 &u, const Real3x3 &v)
Definition MathUtils.h:297
__host__ __device__ Real3 multiply(const Real3x3 &m, Real3 v)
3x3 matrix multiplied by a vector.
Definition MathUtils.h:848
bool isZero(const BuiltInProxy< _Type > &a)
Tests if a value is exactly equal to zero.
__host__ __device__ Real matDet(Real3 u, Real3 v, Real3 w)
Determinant of the matrix u,v,w.
Definition MathUtils.h:173
Real max8Real(const Real a[8])
Returns the maximum of eight Reals.
Definition MathUtils.h:500
__host__ __device__ Real3x3 matrix3x3Id()
Identity matrix.
Definition MathUtils.h:696
__host__ __device__ Real matrixDeterminant(Real3x3 m)
Calculates the determinant of a 3x3 matrix.
Definition MathUtils.h:670
void mult(ArrayView< T > lhs, ConstArrayView< T > copy_array)
Multiplies the elements of the instance term-by-term by the elements of the array copy_array.
Definition MathUtils.h:1005
__host__ __device__ Real min4Real(Real a, Real b, Real c, Real d)
Returns the minimum of four Reals.
Definition MathUtils.h:465
Real3 crossProduct3(Real3 v1, Real3 v2)
Cross product of two 3-component vectors.
Definition MathUtils.h:741
__host__ __device__ Real max4Real(Real a, Real b, Real c, Real d)
Returns the maximum of four Reals.
Definition MathUtils.h:477
Real3x3 matrix3x3Prod(Real3x3 m1, Real3x3 m2)
Multiplication of 2 3x3 matrices.
Definition MathUtils.h:827
__host__ __device__ Real3x3 inverseMatrix(const Real3x3 &m, Real d)
Calculates the inverse of a matrix m assuming its determinant d is known.
Definition MathUtils.h:710
void sub(ArrayView< T > lhs, ConstArrayView< T > copy_array)
Subtracts the array copy_array from the instance.
Definition MathUtils.h:965
__host__ __device__ Real3x3 transpose(const Real3x3 &t)
Transpose the matrix.
Definition MathUtils.h:265
void add(ArrayView< T > lhs, ConstArrayView< T > copy_array)
Adds the array copy_array to the instance.
Definition MathUtils.h:927
Int32 Integer
Type representing an integer.
double Real
Type representing a real number.
__host__ __device__ void arcaneMathError(long double arg_value, const char *func_name)
Signals an invalid argument in a mathematical function.
Real y
second component of the pair
Definition Real2.h:35
Real x
first component of the pair
Definition Real2.h:34
Real y
second component of the triplet
Definition Real3.h:36
Real z
third component of the triplet
Definition Real3.h:37
Real x
first component of the triplet
Definition Real3.h:35