9.2
general documentation
cs_math.h
Go to the documentation of this file.
1#ifndef CS_MATH_H
2#define CS_MATH_H
3
4/*============================================================================
5 * Mathematical base functions.
6 *============================================================================*/
7
8/*
9 This file is part of code_saturne, a general-purpose CFD tool.
10
11 Copyright (C) 1998-2026 EDF S.A.
12
13 This program is free software; you can redistribute it and/or modify it under
14 the terms of the GNU General Public License as published by the Free Software
15 Foundation; either version 2 of the License, or (at your option) any later
16 version.
17
18 This program is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
21 details.
22
23 You should have received a copy of the GNU General Public License along with
24 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
25 Street, Fifth Floor, Boston, MA 02110-1301, USA.
26*/
27
28/*----------------------------------------------------------------------------*/
29
30#include "base/cs_defs.h"
31
32/*----------------------------------------------------------------------------
33 * Standard C library headers
34 *----------------------------------------------------------------------------*/
35
36#include <assert.h>
37#include <math.h>
38
39#if (defined(__NVCC__) && defined(__CUDA_ARCH__)) \
40 || (defined(__HIPCC__) && defined(__HIP_DEVICE_COMPILE__)) \
41 || defined(SYCL_LANGUAGE_VERSION) \
42 || defined(HAVE_OPENMP_TARGET)
43#include <float.h>
44#endif
45
46#if defined(__cplusplus)
47#include <limits>
48#endif
49
50/*----------------------------------------------------------------------------
51 * Local headers
52 *----------------------------------------------------------------------------*/
53
54#if defined(DEBUG) && !defined(NDEBUG) /* Sanity check */
55#include "bft/bft_error.h"
56#endif
57
58/*----------------------------------------------------------------------------*/
59
61
62/*=============================================================================
63 * Local Macro definitions
64 *============================================================================*/
65
66/*============================================================================
67 * Type definition
68 *============================================================================*/
69
70/* Symmetric tensor component name */
71
72typedef enum {
73
79 XZ
80
82
83/*============================================================================
84 * Global variables
85 *============================================================================*/
86
87/* Numerical constants */
88
91
93static constexpr double cs_dbl_epsilon = std::numeric_limits<double>::epsilon();
94
96static constexpr double cs_dbl_min = std::numeric_limits<double>::min();
97
99static constexpr double cs_dbl_max = std::numeric_limits<double>::max();
100
102static constexpr cs_real_t cs_math_epzero = 1e-12;
103
105static constexpr cs_real_t cs_math_infinite_r = 1.e30;
106
108static constexpr cs_real_t cs_math_big_r = 1.e12;
109
111static constexpr cs_real_t cs_math_pi = 3.14159265358979323846;
112
113static constexpr cs_real_t cs_math_1ov3 = 1./3.;
114static constexpr cs_real_t cs_math_2ov3 = 2./3.;
115static constexpr cs_real_t cs_math_4ov3 = 4./3.;
116static constexpr cs_real_t cs_math_5ov3 = 5./3.;
117static constexpr cs_real_t cs_math_1ov6 = 1./6.;
118static constexpr cs_real_t cs_math_1ov12 = 1./12.;
119static constexpr cs_real_t cs_math_1ov24 = 1./24.;
120
121static constexpr cs_real_33_t cs_math_33_identity = {{1., 0., 0.,},
122 {0., 1., 0.},
123 {0., 0., 1.}};
124static constexpr cs_real_6_t cs_math_sym_33_identity = {1., 1., 1.,
125 0. ,0., 0.};
126
127/*----------------------------------------------------------------------------*/
128
130
131/*=============================================================================
132 * Templated inline functions
133 *============================================================================*/
134
135#if defined(__cplusplus)
136
137/*----------------------------------------------------------------------------*/
145/*----------------------------------------------------------------------------*/
146
147template <typename T>
148CS_F_HOST_DEVICE inline T
150{
151 return x*x;
152}
153
154/*----------------------------------------------------------------------------*/
167/*----------------------------------------------------------------------------*/
168
169template <typename T, typename U>
172 const T xb[3],
173 const U xc[3])
174{
175 return ((xb[0] - xa[0])*xc[0]+(xb[1] - xa[1])*xc[1]+(xb[2] - xa[2])*xc[2]);
176}
177
178/*----------------------------------------------------------------------------*/
190/*----------------------------------------------------------------------------*/
191
192template <typename T, typename U>
195 const U v[3])
196{
197 double uv = u[0]*v[0] + u[1]*v[1] + u[2]*v[2];
198
199 return uv;
200}
201
202/*----------------------------------------------------------------------------*/
214/*----------------------------------------------------------------------------*/
215
216template <typename T>
217CS_F_HOST_DEVICE inline T
219 const T v[3])
220{
221 T uv = u[0]*v[0] + u[1]*v[1] + u[2]*v[2];
222
223 return uv;
224}
225
226/*----------------------------------------------------------------------------*/
236/*----------------------------------------------------------------------------*/
237
238template <typename T>
239CS_F_HOST_DEVICE inline T
240cs_math_3_norm(const T v[3])
241{
242 return sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
243}
244
245/*----------------------------------------------------------------------------*/
253/*----------------------------------------------------------------------------*/
254
255template <typename T>
256CS_F_HOST_DEVICE inline T
257cs_math_33_trace(const T t[3][3])
258{
259 return (t[0][0] + t[1][1] + t[2][2]);
260}
261
262/*----------------------------------------------------------------------------*/
280/*----------------------------------------------------------------------------*/
281
282template <typename T, typename U, typename V>
285 const U t[6],
286 const V n2[3])
287{
288 return ( n1[0] * (t[0]*n2[0] + t[3]*n2[1] + t[5]*n2[2])
289 + n1[1] * (t[3]*n2[0] + t[1]*n2[1] + t[4]*n2[2])
290 + n1[2] * (t[5]*n2[0] + t[4]*n2[1] + t[2]*n2[2]));
291}
292
293/*----------------------------------------------------------------------------*/
304/*----------------------------------------------------------------------------*/
305
306template <cs_lnum_t stride>
309{
310 cs_real_t retval;
311
312 if (stride == 3)
313 retval = t[0]*t[0] + t[1]*t[1] + t[2]*t[2];
314 else if (stride == 6)
315 retval = t[0]*t[0] + t[1]*t[1] + t[2]*t[2]
316 + 2*t[3]*t[3] + 2*t[4]*t[4] + 2*t[5]*t[5];
317 else
318 retval = 1;
319
320 return retval;
321}
322
323/*----------------------------------------------------------------------------*/
333/*----------------------------------------------------------------------------*/
334
335template <typename T>
336CS_F_HOST_DEVICE inline T
338{
339 cs_real_t v2 = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
340
341 return v2;
342}
343
344/*----------------------------------------------------------------------------*/
356/*----------------------------------------------------------------------------*/
357
358template <typename T, typename U>
359CS_F_HOST_DEVICE inline void
360cs_math_3_normalize(const T vin[3],
361 U vout[3])
362{
363 cs_real_t norm = cs_math_3_norm(vin);
364
365 cs_real_t inv_norm = ((norm > cs_math_zero_threshold) ? 1. / norm : 0);
366
367 vout[0] = inv_norm * vin[0];
368 vout[1] = inv_norm * vin[1];
369 vout[2] = inv_norm * vin[2];
370}
371
372/*----------------------------------------------------------------------------*/
385/*----------------------------------------------------------------------------*/
386
387template <typename T, typename U, typename V>
388CS_F_HOST_DEVICE inline void
389cs_math_33_3_product(const T m[3][3],
390 const U v[3],
391 V *restrict mv)
392{
393 mv[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2];
394 mv[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2];
395 mv[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2];
396}
397
398/*----------------------------------------------------------------------------*/
412/*----------------------------------------------------------------------------*/
413
414template <typename T, typename U, typename V>
415CS_F_HOST_DEVICE inline void
417 const U v[3],
418 V *restrict mv)
419{
420 mv[0] = m[0]*v[0] + m[3]*v[1] + m[5]*v[2];
421 mv[1] = m[3]*v[0] + m[1]*v[1] + m[4]*v[2];
422 mv[2] = m[5]*v[0] + m[4]*v[1] + m[2]*v[2];
423}
424
425/*----------------------------------------------------------------------------*/
438/*----------------------------------------------------------------------------*/
439
440template <typename T, typename U, typename V>
441CS_F_HOST_DEVICE inline void
443 U factor,
444 V v[3])
445{
446 cs_real_t v_dot_n = (factor -1.) * cs_math_3_dot_product(v, n);
447 for (int i = 0; i < 3; i++)
448 v[i] += v_dot_n * n[i];
449}
450
451/*----------------------------------------------------------------------------*/
465/*----------------------------------------------------------------------------*/
466
467template <typename T, typename U, typename V>
470 const U t[3][3],
471 const V n2[3])
472{
473 cs_real_t n_t_n
474 = ( n1[0]*t[0][0]*n2[0] + n1[1]*t[1][0]*n2[0] + n1[2]*t[2][0]*n2[0]
475 + n1[0]*t[0][1]*n2[1] + n1[1]*t[1][1]*n2[1] + n1[2]*t[2][1]*n2[1]
476 + n1[0]*t[0][2]*n2[2] + n1[1]*t[1][2]*n2[2] + n1[2]*t[2][2]*n2[2]);
477 return n_t_n;
478}
479
480/*----------------------------------------------------------------------------*/
493/*----------------------------------------------------------------------------*/
494
495template <typename T, typename U, typename V>
496CS_F_HOST_DEVICE inline void
498 const U v[3],
499 V *restrict vout)
500{
501 vout[0] = v[0]*(1.-n[0]*n[0])- v[1]* n[1]*n[0] - v[2]* n[2]*n[0];
502 vout[1] = -v[0]* n[0]*n[1] + v[1]*(1.-n[1]*n[1])- v[2]* n[2]*n[1];
503 vout[2] = -v[0]* n[0]*n[2] - v[1]* n[1]*n[2] + v[2]*(1.-n[2]*n[2]);
504}
505
506/*----------------------------------------------------------------------------*/
518/*----------------------------------------------------------------------------*/
519
520template <typename T, typename U, typename V>
521CS_F_HOST_DEVICE inline void
523 const U v[3],
524 V *restrict uv)
525{
526 uv[0] = u[1]*v[2] - u[2]*v[1];
527 uv[1] = u[2]*v[0] - u[0]*v[2];
528 uv[2] = u[0]*v[1] - u[1]*v[0];
529}
530
531/*----------------------------------------------------------------------------*/
538/*----------------------------------------------------------------------------*/
539
540template <cs_lnum_t n, typename T>
541CS_F_HOST_DEVICE inline void
543 T b[n][n])
544{
545 T *p_a[n];
546 T t[n][n*2];
547
548 for (size_t i = 0; i < n; i++) {
549 p_a[i] = t[i];
550 for (size_t j = 0; j < n; j++) {
551 p_a[i][j] = a[i][j];
552 p_a[i][j+n] = 0;
553 }
554 p_a[i][i+n] = 1;
555 }
556
557 for (size_t i = 0; i < n; i++) {
558
559 // Pivot matrix rows (swap pointers)
560 for (size_t j = i+1; j < n; j++) {
561 if (cs::abs(p_a[i][i]) < cs::abs(p_a[j][i])) {
562 T* tmp = p_a[j];
563 p_a[j] = p_a[i];
564 p_a[i] = tmp;
565 }
566 }
567 // Linear combination of each row with other rows
568 for (size_t j = 0; j < n; j++) {
569 if (j != i) {
570 T s = p_a[j][i] / p_a[i][i];
571 for (size_t k = 0; k < 2*n; k++) {
572 p_a[j][k] -= p_a[i][k] * s;
573 }
574 }
575 }
576
577 }
578
579 // Scale and copy results
580 for (size_t i = 0; i < n; i++) {
581 T s = (T)1. / p_a[i][i];
582 for (size_t j = 0; j < n; j++) {
583 b[i][j] = p_a[i][n+j] * s;
584 }
585 }
586}
587
588/*----------------------------------------------------------------------------*/
596/*----------------------------------------------------------------------------*/
597
598template <typename T>
601{
602 T t[3][3] = {{a[0], a[3], a[5]},
603 {a[3], a[1], a[4]},
604 {a[5], a[4], a[2]}};
605 T s[3][3];
606
608
609 a[0] = s[0][0];
610 a[1] = s[1][1];
611 a[2] = s[2][2];
612
613 a[3] = s[0][1];
614 a[4] = s[1][2];
615 a[5] = s[0][2];
616}
617
618namespace cs {
619
620/*----------------------------------------------------------------------------*/
621/*
622 * \brief Return absolute value of a number.
623 *
624 * Specialized versions for floating point numbers should be faster than
625 * base version from cs_defs.h.
626 *
627 * \param[in] a value
628 *
629 * \return absolute value of a
630 */
631/*----------------------------------------------------------------------------*/
632
633CS_F_HOST_DEVICE inline double
634abs(const double a)
635{
636 return fabs(a);
637}
638
639CS_F_HOST_DEVICE inline float
640abs(const float a)
641{
642 return fabsf(a);
643}
644
645/*----------------------------------------------------------------------------*/
646/*
647 * \brief Return minimum of two values.
648 *
649 * Specialized versions for floating point numbers should be faster than
650 * base version from cs_defs.h.
651 *
652 * \param[in] a first value
653 * \param[in] b second value
654 *
655 * \return minimum of a and b
656 */
657/*----------------------------------------------------------------------------*/
658
659CS_F_HOST_DEVICE inline double
660min(const double a,
661 const double b)
662{
663 return fmin(a, b);
664}
665
666CS_F_HOST_DEVICE inline float
667min(const float a,
668 const float b)
669{
670 return fminf(a, b);
671}
672
673/*----------------------------------------------------------------------------*/
674/*
675 * \brief Return maximum of two values.
676 *
677 * Specialized versions for floating point numbers should be faster than
678 * base version from cs_defs.h.
679 *
680 * \param[in] a first value
681 * \param[in] b second value
682 *
683 * \return maximum of a and b
684 */
685/*----------------------------------------------------------------------------*/
686
687CS_F_HOST_DEVICE inline double
688max(const double a,
689 const double b)
690{
691 return fmax(a, b);
692}
693
694CS_F_HOST_DEVICE inline float
695max(const float a,
696 const float b)
697{
698 return fmaxf(a, b);
699}
700
701/*----------------------------------------------------------------------------*/
702/*
703 * \brief Clamp function for a given scalar value.
704 *
705 * Specialized versions for floating point numbers should be faster than
706 * base version from cs_defs.h.
707 *
708 * \param[in] x initial value
709 * \param[in] xmin min value for clamping
710 * \param[in] xmax max value for clamping
711 *
712 * \return clamped value which is 'x' if xmin < x < xmax or lower/upper bound
713 * otherwise
714 */
715/*----------------------------------------------------------------------------*/
716
717CS_F_HOST_DEVICE inline double
718clamp(const double x,
719 const double xmin,
720 const double xmax)
721{
722 return fmin(xmax, fmax(xmin, x));
723}
724
725CS_F_HOST_DEVICE inline float
726clamp(const float x,
727 const float xmin,
728 const float xmax)
729{
730 return fminf(xmax, fmaxf(xmin, x));
731}
732
733/*----------------------------------------------------------------------------*/
741/*----------------------------------------------------------------------------*/
742
743CS_F_HOST_DEVICE inline float
744pow2(float x)
745{
746 return x*x;
747}
748
749CS_F_HOST_DEVICE inline double
750pow2(double x)
751{
752 return x*x;
753}
754
755} // namespace cs
756
757#endif // defined(__cplusplus)
758
760
761/*=============================================================================
762 * Inline static functions
763 *============================================================================*/
764
765/*----------------------------------------------------------------------------*/
774/*----------------------------------------------------------------------------*/
775
776inline int
778 int k)
779{
780 int ret = 1;
781 assert(n >= k);
782
783 const int n_iter = (k > n-k) ? n-k : k;
784 for (int j = 1; j <= n_iter; j++, n--) {
785 if (n % j == 0)
786 ret *= n/j;
787 else if (ret % j == 0)
788 ret = ret/j*n;
789 else
790 ret = (ret*n)/j;
791 }
792
793 return ret;
794}
795
796/*----------------------------------------------------------------------------*/
804/*----------------------------------------------------------------------------*/
805
808{
809 cs_real_t ret = (x < 0) ? -x : x;
810
811 return ret;
812}
813
814/*----------------------------------------------------------------------------*/
822/*----------------------------------------------------------------------------*/
823
826 cs_real_t y)
827{
828 cs_real_t ret = (x < y) ? x : y;
829
830 return ret;
831}
832
833/*----------------------------------------------------------------------------*/
841/*----------------------------------------------------------------------------*/
842
845 cs_real_t y)
846{
847 cs_real_t ret = (x < y) ? y : x;
848
849 return ret;
850}
851
852/*----------------------------------------------------------------------------*/
863/*----------------------------------------------------------------------------*/
864
867 cs_real_t xmin,
868 cs_real_t xmax)
869{
870 cs_real_t ret = cs_math_fmin(xmax, cs_math_fmax(xmin, x));
871
872 return ret;
873}
874
875/*----------------------------------------------------------------------------*/
883/*----------------------------------------------------------------------------*/
884
887{
888 return x*x;
889}
890
891/*----------------------------------------------------------------------------*/
899/*----------------------------------------------------------------------------*/
900
903{
904 return x*x;
905}
906
907/*----------------------------------------------------------------------------*/
915/*----------------------------------------------------------------------------*/
916
919{
920 return x*x*x;
921}
922
923/*----------------------------------------------------------------------------*/
931/*----------------------------------------------------------------------------*/
932
935{
936 cs_real_t x2 = x * x;
937 return x2 * x2;
938}
939
940/*----------------------------------------------------------------------------*/
948/*----------------------------------------------------------------------------*/
949
952{
953 cs_real_t x2 = x * x;
954 return x * x2 * x2;
955}
956
957/*----------------------------------------------------------------------------*/
967/*----------------------------------------------------------------------------*/
968
971 const cs_real_t xb[3])
972{
973 cs_real_t v[3];
974
975 v[0] = xb[0] - xa[0];
976 v[1] = xb[1] - xa[1];
977 v[2] = xb[2] - xa[2];
978
979 return sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
980}
981
982/*----------------------------------------------------------------------------*/
992/*----------------------------------------------------------------------------*/
993
996 const cs_real_t xb[3],
997 const cs_real_t xc[3])
998{
999 return ((xb[0] - xa[0])*xc[0]+(xb[1] - xa[1])*xc[1]+(xb[2] - xa[2])*xc[2]);
1000}
1001
1002/*----------------------------------------------------------------------------*/
1012/*----------------------------------------------------------------------------*/
1013
1016 const cs_real_t xb[3])
1017{
1018 cs_real_t v[3] = {xb[0] - xa[0],
1019 xb[1] - xa[1],
1020 xb[2] - xa[2]};
1021
1022 return (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
1023}
1024
1025/*----------------------------------------------------------------------------*/
1034/*----------------------------------------------------------------------------*/
1035
1038 const cs_real_t v[3])
1039{
1040 cs_real_t uv = u[0]*v[0] + u[1]*v[1] + u[2]*v[2];
1041
1042 return uv;
1043}
1044
1045/*----------------------------------------------------------------------------*/
1055/*----------------------------------------------------------------------------*/
1056
1059 const cs_real_t t[3][3],
1060 const cs_real_t n2[3])
1061{
1062 cs_real_t n_t_n
1063 = ( n1[0]*t[0][0]*n2[0] + n1[1]*t[1][0]*n2[0] + n1[2]*t[2][0]*n2[0]
1064 + n1[0]*t[0][1]*n2[1] + n1[1]*t[1][1]*n2[1] + n1[2]*t[2][1]*n2[1]
1065 + n1[0]*t[0][2]*n2[2] + n1[1]*t[1][2]*n2[2] + n1[2]*t[2][2]*n2[2]);
1066 return n_t_n;
1067}
1068
1069/*----------------------------------------------------------------------------*/
1083/*----------------------------------------------------------------------------*/
1084
1087 const cs_real_t t[6],
1088 const cs_real_t n2[3])
1089{
1090 return ( n1[0] * (t[0]*n2[0] + t[3]*n2[1] + t[5]*n2[2])
1091 + n1[1] * (t[3]*n2[0] + t[1]*n2[1] + t[4]*n2[2])
1092 + n1[2] * (t[5]*n2[0] + t[4]*n2[1] + t[2]*n2[2]));
1093}
1094
1095/*----------------------------------------------------------------------------*/
1103/*----------------------------------------------------------------------------*/
1104
1107{
1108 return sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
1109}
1110
1111/*----------------------------------------------------------------------------*/
1119/*----------------------------------------------------------------------------*/
1120
1123{
1124 cs_real_t v2 = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
1125
1126 return v2;
1127}
1128
1129/*----------------------------------------------------------------------------*/
1138/*----------------------------------------------------------------------------*/
1139
1140CS_F_HOST_DEVICE inline void
1142 cs_real_t vout[3])
1143{
1144 cs_real_t norm = cs_math_3_norm(vin);
1145
1146 cs_real_t inv_norm = ((norm > cs_math_zero_threshold) ? 1. / norm : 0);
1147
1148 vout[0] = inv_norm * vin[0];
1149 vout[1] = inv_norm * vin[1];
1150 vout[2] = inv_norm * vin[2];
1151}
1152
1153/*----------------------------------------------------------------------------*/
1164/*----------------------------------------------------------------------------*/
1165
1166CS_F_HOST_DEVICE inline void
1168 const cs_real_t thres,
1169 cs_real_t vout[3])
1170{
1171 cs_real_t norm = cs_math_3_norm(vin);
1172
1173 cs_real_t inv_norm = ((norm > thres) ? 1. / norm : 1. / thres);
1174
1175 vout[0] = inv_norm * vin[0];
1176 vout[1] = inv_norm * vin[1];
1177 vout[2] = inv_norm * vin[2];
1178}
1179
1180/*----------------------------------------------------------------------------*/
1189/*----------------------------------------------------------------------------*/
1190
1191CS_F_HOST_DEVICE inline void
1193 const cs_real_t v[3],
1194 cs_real_t *restrict vout)
1195{
1196 vout[0] = v[0]*(1.-n[0]*n[0])- v[1]* n[1]*n[0] - v[2]* n[2]*n[0];
1197 vout[1] = -v[0]* n[0]*n[1] + v[1]*(1.-n[1]*n[1])- v[2]* n[2]*n[1];
1198 vout[2] = -v[0]* n[0]*n[2] - v[1]* n[1]*n[2] + v[2]*(1.-n[2]*n[2]);
1199}
1200
1201/*----------------------------------------------------------------------------*/
1211/*----------------------------------------------------------------------------*/
1212
1213CS_F_HOST_DEVICE inline void
1215 cs_real_t factor,
1216 cs_real_t t[3][3])
1217{
1218 cs_real_t n_t_n = (factor -1.) *
1219 ( n[0] * t[0][0] * n[0] + n[1] * t[1][0] * n[0] + n[2] * t[2][0] * n[0]
1220 + n[0] * t[0][1] * n[1] + n[1] * t[1][1] * n[1] + n[2] * t[2][1] * n[1]
1221 + n[0] * t[0][2] * n[2] + n[1] * t[1][2] * n[2] + n[2] * t[2][2] * n[2]);
1222 for (int i = 0; i < 3; i++) {
1223 for (int j = 0; j < 3; j++)
1224 t[i][j] += n_t_n * n[i] * n[j];
1225 }
1226}
1227
1228/*----------------------------------------------------------------------------*/
1237/*----------------------------------------------------------------------------*/
1238
1239CS_F_HOST_DEVICE inline void
1241 const cs_real_t v[3],
1242 cs_real_t *restrict mv)
1243{
1244 mv[0] += m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2];
1245 mv[1] += m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2];
1246 mv[2] += m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2];
1247}
1248
1249/*----------------------------------------------------------------------------*/
1258/*----------------------------------------------------------------------------*/
1259
1260CS_F_HOST_DEVICE inline void
1262 const cs_real_t v[3],
1263 cs_real_t *restrict mv)
1264{
1265 mv[0] = m[0][0]*v[0] + m[1][0]*v[1] + m[2][0]*v[2];
1266 mv[1] = m[0][1]*v[0] + m[1][1]*v[1] + m[2][1]*v[2];
1267 mv[2] = m[0][2]*v[0] + m[1][2]*v[1] + m[2][2]*v[2];
1268}
1269
1270/*----------------------------------------------------------------------------*/
1280/*----------------------------------------------------------------------------*/
1281
1282CS_F_HOST_DEVICE inline void
1284 const cs_real_t v[3],
1285 cs_real_t *restrict mv)
1286{
1287 mv[0] = m[0]*v[0] + m[3]*v[1] + m[5]*v[2];
1288 mv[1] = m[3]*v[0] + m[1]*v[1] + m[4]*v[2];
1289 mv[2] = m[5]*v[0] + m[4]*v[1] + m[2]*v[2];
1290}
1291
1292/*----------------------------------------------------------------------------*/
1302/*----------------------------------------------------------------------------*/
1303
1304CS_F_HOST_DEVICE inline void
1306 const cs_real_t v[3],
1307 cs_real_t *restrict mv)
1308{
1309 mv[0] += m[0] * v[0] + m[3] * v[1] + m[5] * v[2];
1310 mv[1] += m[3] * v[0] + m[1] * v[1] + m[4] * v[2];
1311 mv[2] += m[5] * v[0] + m[4] * v[1] + m[2] * v[2];
1312}
1313
1314/*----------------------------------------------------------------------------*/
1324/*----------------------------------------------------------------------------*/
1325
1328 const cs_real_t m2[6])
1329{
1330 return m1[0]*m2[0] + 2.*m1[3]*m2[3] + 2.*m1[5]*m2[5]
1331 + m1[1]*m2[1] + 2.*m1[4]*m2[4]
1332 + m1[2]*m2[2];
1333}
1334
1335/*----------------------------------------------------------------------------*/
1343/*----------------------------------------------------------------------------*/
1344
1347{
1348 return (t[0] + t[1] + t[2]);
1349}
1350
1351/*----------------------------------------------------------------------------*/
1360/*----------------------------------------------------------------------------*/
1361
1362CS_F_HOST_DEVICE inline void
1364 const cs_real_t v[6],
1365 cs_real_t *restrict mv)
1366{
1367 for (int i = 0; i < 6; i++) {
1368 for (int j = 0; j < 6; j++)
1369 mv[i] = m[i][j] * v[j];
1370 }
1371}
1372
1373/*----------------------------------------------------------------------------*/
1382/*----------------------------------------------------------------------------*/
1383
1384CS_F_HOST_DEVICE inline void
1386 const cs_real_t v[6],
1387 cs_real_t *restrict mv)
1388{
1389 for (int i = 0; i < 6; i++) {
1390 for (int j = 0; j < 6; j++)
1391 mv[i] += m[i][j] * v[j];
1392 }
1393}
1394
1395/*----------------------------------------------------------------------------*/
1403/*----------------------------------------------------------------------------*/
1404
1407{
1408 const cs_real_t com0 = m[1][1]*m[2][2] - m[2][1]*m[1][2];
1409 const cs_real_t com1 = m[2][1]*m[0][2] - m[0][1]*m[2][2];
1410 const cs_real_t com2 = m[0][1]*m[1][2] - m[1][1]*m[0][2];
1411
1412 return m[0][0]*com0 + m[1][0]*com1 + m[2][0]*com2;
1413}
1414
1415/*----------------------------------------------------------------------------*/
1423/*----------------------------------------------------------------------------*/
1424
1427{
1428 const cs_real_t com0 = m[1]*m[2] - m[4]*m[4];
1429 const cs_real_t com1 = m[4]*m[5] - m[3]*m[2];
1430 const cs_real_t com2 = m[3]*m[4] - m[1]*m[5];
1431
1432 return m[0]*com0 + m[3]*com1 + m[5]*com2;
1433}
1434
1435/*----------------------------------------------------------------------------*/
1443/*----------------------------------------------------------------------------*/
1444
1445CS_F_HOST_DEVICE inline void
1447 const cs_real_t v[3],
1448 cs_real_t *restrict uv)
1449{
1450 uv[0] = (u[0] + v[0]) / 2.0;
1451 uv[1] = (u[1] + v[1]) / 2.0;
1452 uv[2] = (u[2] + v[2]) / 2.0;
1453}
1454
1455/*----------------------------------------------------------------------------*/
1463/*----------------------------------------------------------------------------*/
1464
1465#if defined(__INTEL_COMPILER)
1466#pragma optimization_level 0 /* Bug with O1 or above with icc 15.0.1 20141023 */
1467#endif
1468
1469CS_F_HOST_DEVICE inline void
1471 const cs_real_t v[3],
1472 cs_real_t *restrict uv)
1473{
1474 uv[0] = u[1]*v[2] - u[2]*v[1];
1475 uv[1] = u[2]*v[0] - u[0]*v[2];
1476 uv[2] = u[0]*v[1] - u[1]*v[0];
1477}
1478
1479/*----------------------------------------------------------------------------*/
1489/*----------------------------------------------------------------------------*/
1490
1491#if defined(__INTEL_COMPILER)
1492#pragma optimization_level 0 /* Bug with O1 or above with icc 15.0.1 20141023 */
1493#endif
1494
1497 const cs_real_t v[3],
1498 const cs_real_t w[3])
1499{
1500 return (u[1]*v[2] - u[2]*v[1]) * w[0]
1501 + (u[2]*v[0] - u[0]*v[2]) * w[1]
1502 + (u[0]*v[1] - u[1]*v[0]) * w[2];
1503}
1504
1505/*----------------------------------------------------------------------------*/
1515/*----------------------------------------------------------------------------*/
1516
1517CS_F_HOST_DEVICE inline void
1519 cs_real_t axes[3][3])
1520{
1521 assert(cs_math_3_norm(vect) > cs_math_zero_threshold);
1522
1523 // Compute normal - third axis
1524 cs_math_3_normalize(vect, axes[2]);
1525
1526 // Compute base's first axis
1527 // First test projection of Ox
1528 cs_real_t Ox[3] = {1., 0., 0.};
1529 cs_real_t w[3] = {0.};
1530
1531 cs_math_3_orthogonal_projection(axes[2], Ox, w);
1532
1533 // If Ox projection is null, project Oy
1535 cs_real_t Oy[3] = {0., 1., 0.};
1536 cs_math_3_orthogonal_projection(axes[2], Oy, w);
1537 }
1538
1539 cs_math_3_normalize(w, axes[0]);
1540
1541 // Compute base's second axis using cross product
1542 cs_math_3_cross_product(axes[2], axes[0], axes[1]);
1543}
1544
1545/*----------------------------------------------------------------------------*/
1552/*----------------------------------------------------------------------------*/
1553
1554CS_F_HOST_DEVICE inline void
1556 cs_real_t out[3][3])
1557{
1558 out[0][0] = in[1][1]*in[2][2] - in[2][1]*in[1][2];
1559 out[0][1] = in[2][1]*in[0][2] - in[0][1]*in[2][2];
1560 out[0][2] = in[0][1]*in[1][2] - in[1][1]*in[0][2];
1561
1562 out[1][0] = in[2][0]*in[1][2] - in[1][0]*in[2][2];
1563 out[1][1] = in[0][0]*in[2][2] - in[2][0]*in[0][2];
1564 out[1][2] = in[1][0]*in[0][2] - in[0][0]*in[1][2];
1565
1566 out[2][0] = in[1][0]*in[2][1] - in[2][0]*in[1][1];
1567 out[2][1] = in[2][0]*in[0][1] - in[0][0]*in[2][1];
1568 out[2][2] = in[0][0]*in[1][1] - in[1][0]*in[0][1];
1569
1570 const double det = in[0][0]*out[0][0]+in[1][0]*out[0][1]+in[2][0]*out[0][2];
1571 const double invdet = 1./det;
1572
1573 out[0][0] *= invdet, out[0][1] *= invdet, out[0][2] *= invdet;
1574 out[1][0] *= invdet, out[1][1] *= invdet, out[1][2] *= invdet;
1575 out[2][0] *= invdet, out[2][1] *= invdet, out[2][2] *= invdet;
1576}
1577
1578/*----------------------------------------------------------------------------*/
1584/*----------------------------------------------------------------------------*/
1585
1586CS_F_HOST_DEVICE inline void
1588{
1589 cs_real_t a00 = a[1][1]*a[2][2] - a[2][1]*a[1][2];
1590 cs_real_t a01 = a[2][1]*a[0][2] - a[0][1]*a[2][2];
1591 cs_real_t a02 = a[0][1]*a[1][2] - a[1][1]*a[0][2];
1592 cs_real_t a10 = a[2][0]*a[1][2] - a[1][0]*a[2][2];
1593 cs_real_t a11 = a[0][0]*a[2][2] - a[2][0]*a[0][2];
1594 cs_real_t a12 = a[1][0]*a[0][2] - a[0][0]*a[1][2];
1595 cs_real_t a20 = a[1][0]*a[2][1] - a[2][0]*a[1][1];
1596 cs_real_t a21 = a[2][0]*a[0][1] - a[0][0]*a[2][1];
1597 cs_real_t a22 = a[0][0]*a[1][1] - a[1][0]*a[0][1];
1598
1599 double det_inv = 1. / (a[0][0]*a00 + a[1][0]*a01 + a[2][0]*a02);
1600
1601 a[0][0] = a00 * det_inv;
1602 a[0][1] = a01 * det_inv;
1603 a[0][2] = a02 * det_inv;
1604 a[1][0] = a10 * det_inv;
1605 a[1][1] = a11 * det_inv;
1606 a[1][2] = a12 * det_inv;
1607 a[2][0] = a20 * det_inv;
1608 a[2][1] = a21 * det_inv;
1609 a[2][2] = a22 * det_inv;
1610}
1611
1612/*----------------------------------------------------------------------------*/
1619/*----------------------------------------------------------------------------*/
1620
1621CS_F_HOST_DEVICE inline void
1623{
1624 cs_real_t a00 = a[1][1]*a[2][2] - a[2][1]*a[1][2];
1625 cs_real_t a01 = a[2][1]*a[0][2] - a[0][1]*a[2][2];
1626 cs_real_t a02 = a[0][1]*a[1][2] - a[1][1]*a[0][2];
1627 cs_real_t a11 = a[0][0]*a[2][2] - a[2][0]*a[0][2];
1628 cs_real_t a12 = a[1][0]*a[0][2] - a[0][0]*a[1][2];
1629 cs_real_t a22 = a[0][0]*a[1][1] - a[1][0]*a[0][1];
1630
1631 double det_inv = 1. / (a[0][0]*a00 + a[1][0]*a01 + a[2][0]*a02);
1632
1633 a[0][0] = a00 * det_inv;
1634 a[0][1] = a01 * det_inv;
1635 a[0][2] = a02 * det_inv;
1636 a[1][0] = a01 * det_inv;
1637 a[1][1] = a11 * det_inv;
1638 a[1][2] = a12 * det_inv;
1639 a[2][0] = a02 * det_inv;
1640 a[2][1] = a12 * det_inv;
1641 a[2][2] = a22 * det_inv;
1642}
1643
1644/*----------------------------------------------------------------------------*/
1654/*----------------------------------------------------------------------------*/
1655
1656CS_F_HOST_DEVICE inline void
1658 cs_real_t *restrict sout)
1659{
1660 double detinv;
1661
1662 sout[0] = s[1]*s[2] - s[4]*s[4];
1663 sout[1] = s[0]*s[2] - s[5]*s[5];
1664 sout[2] = s[0]*s[1] - s[3]*s[3];
1665 sout[3] = s[4]*s[5] - s[3]*s[2];
1666 sout[4] = s[3]*s[5] - s[0]*s[4];
1667 sout[5] = s[3]*s[4] - s[1]*s[5];
1668
1669 detinv = 1. / (s[0]*sout[0] + s[3]*sout[3] + s[5]*sout[5]);
1670
1671 sout[0] *= detinv;
1672 sout[1] *= detinv;
1673 sout[2] *= detinv;
1674 sout[3] *= detinv;
1675 sout[4] *= detinv;
1676 sout[5] *= detinv;
1677}
1678
1679/*----------------------------------------------------------------------------*/
1687/*----------------------------------------------------------------------------*/
1688
1689CS_F_HOST_DEVICE inline void
1691 const cs_real_t m2[3][3],
1692 cs_real_t mout[3][3])
1693{
1694 mout[0][0] = m1[0][0]*m2[0][0] + m1[0][1]*m2[1][0] + m1[0][2]*m2[2][0];
1695 mout[0][1] = m1[0][0]*m2[0][1] + m1[0][1]*m2[1][1] + m1[0][2]*m2[2][1];
1696 mout[0][2] = m1[0][0]*m2[0][2] + m1[0][1]*m2[1][2] + m1[0][2]*m2[2][2];
1697
1698 mout[1][0] = m1[1][0]*m2[0][0] + m1[1][1]*m2[1][0] + m1[1][2]*m2[2][0];
1699 mout[1][1] = m1[1][0]*m2[0][1] + m1[1][1]*m2[1][1] + m1[1][2]*m2[2][1];
1700 mout[1][2] = m1[1][0]*m2[0][2] + m1[1][1]*m2[1][2] + m1[1][2]*m2[2][2];
1701
1702 mout[2][0] = m1[2][0]*m2[0][0] + m1[2][1]*m2[1][0] + m1[2][2]*m2[2][0];
1703 mout[2][1] = m1[2][0]*m2[0][1] + m1[2][1]*m2[1][1] + m1[2][2]*m2[2][1];
1704 mout[2][2] = m1[2][0]*m2[0][2] + m1[2][1]*m2[1][2] + m1[2][2]*m2[2][2];
1705}
1706
1707/*----------------------------------------------------------------------------*/
1716/*----------------------------------------------------------------------------*/
1717
1718CS_F_HOST_DEVICE inline void
1720 const cs_real_t q[3][3],
1721 cs_real_t mout[3][3])
1722{
1723 /* _m = M.Q */
1724 cs_real_33_t _m;
1725 _m[0][0] = m[0][0]*q[0][0] + m[0][1]*q[1][0] + m[0][2]*q[2][0];
1726 _m[0][1] = m[0][0]*q[0][1] + m[0][1]*q[1][1] + m[0][2]*q[2][1];
1727 _m[0][2] = m[0][0]*q[0][2] + m[0][1]*q[1][2] + m[0][2]*q[2][2];
1728
1729 _m[1][0] = m[1][0]*q[0][0] + m[1][1]*q[1][0] + m[1][2]*q[2][0];
1730 _m[1][1] = m[1][0]*q[0][1] + m[1][1]*q[1][1] + m[1][2]*q[2][1];
1731 _m[1][2] = m[1][0]*q[0][2] + m[1][1]*q[1][2] + m[1][2]*q[2][2];
1732
1733 _m[2][0] = m[2][0]*q[0][0] + m[2][1]*q[1][0] + m[2][2]*q[2][0];
1734 _m[2][1] = m[2][0]*q[0][1] + m[2][1]*q[1][1] + m[2][2]*q[2][1];
1735 _m[2][2] = m[2][0]*q[0][2] + m[2][1]*q[1][2] + m[2][2]*q[2][2];
1736
1737 /* mout = Q^t _m */
1738 mout[0][0] = q[0][0]*_m[0][0] + q[1][0]*_m[1][0] + q[2][0]*_m[2][0];
1739 mout[0][1] = q[0][0]*_m[0][1] + q[1][0]*_m[1][1] + q[2][0]*_m[2][1];
1740 mout[0][2] = q[0][0]*_m[0][2] + q[1][0]*_m[1][2] + q[2][0]*_m[2][2];
1741
1742 mout[1][0] = q[0][1]*_m[0][0] + q[1][1]*_m[1][0] + q[2][1]*_m[2][0];
1743 mout[1][1] = q[0][1]*_m[0][1] + q[1][1]*_m[1][1] + q[2][1]*_m[2][1];
1744 mout[1][2] = q[0][1]*_m[0][2] + q[1][1]*_m[1][2] + q[2][1]*_m[2][2];
1745
1746 mout[2][0] = q[0][2]*_m[0][0] + q[1][2]*_m[1][0] + q[2][2]*_m[2][0];
1747 mout[2][1] = q[0][2]*_m[0][1] + q[1][2]*_m[1][1] + q[2][2]*_m[2][1];
1748 mout[2][2] = q[0][2]*_m[0][2] + q[1][2]*_m[1][2] + q[2][2]*_m[2][2];
1749}
1750
1751/*----------------------------------------------------------------------------*/
1760/*----------------------------------------------------------------------------*/
1761
1762CS_F_HOST_DEVICE inline void
1764 const cs_real_t q[3][3],
1765 cs_real_t mout[6])
1766{
1767 /* _m = M.Q */
1768 cs_real_33_t _m;
1769 _m[0][0] = m[0]*q[0][0] + m[3]*q[1][0] + m[5]*q[2][0];
1770 _m[0][1] = m[0]*q[0][1] + m[3]*q[1][1] + m[5]*q[2][1];
1771 _m[0][2] = m[0]*q[0][2] + m[3]*q[1][2] + m[5]*q[2][2];
1772
1773 _m[1][0] = m[3]*q[0][0] + m[1]*q[1][0] + m[4]*q[2][0];
1774 _m[1][1] = m[3]*q[0][1] + m[1]*q[1][1] + m[4]*q[2][1];
1775 _m[1][2] = m[3]*q[0][2] + m[1]*q[1][2] + m[4]*q[2][2];
1776
1777 _m[2][0] = m[5]*q[0][0] + m[4]*q[1][0] + m[2]*q[2][0];
1778 _m[2][1] = m[5]*q[0][1] + m[4]*q[1][1] + m[2]*q[2][1];
1779 _m[2][2] = m[5]*q[0][2] + m[4]*q[1][2] + m[2]*q[2][2];
1780
1781 /* mout = Q^t _m */
1782 mout[0] = q[0][0]*_m[0][0] + q[1][0]*_m[1][0] + q[2][0]*_m[2][0];
1783 mout[1] = q[0][1]*_m[0][1] + q[1][1]*_m[1][1] + q[2][1]*_m[2][1];
1784 mout[2] = q[0][2]*_m[0][2] + q[1][2]*_m[1][2] + q[2][2]*_m[2][2];
1785
1786 mout[3] = q[0][0]*_m[0][1] + q[1][0]*_m[1][1] + q[2][0]*_m[2][1];
1787 mout[4] = q[0][1]*_m[0][2] + q[1][1]*_m[1][2] + q[2][1]*_m[2][2];
1788 mout[5] = q[0][0]*_m[0][2] + q[1][0]*_m[1][2] + q[2][0]*_m[2][2];
1789}
1790
1791/*----------------------------------------------------------------------------*/
1800/*----------------------------------------------------------------------------*/
1801
1802CS_F_HOST_DEVICE inline void
1804 const cs_real_t q[3][3],
1805 cs_real_t mout[3][3])
1806{
1807 /* _m = M.Q^t */
1808 cs_real_33_t _m;
1809 _m[0][0] = m[0][0]*q[0][0] + m[0][1]*q[0][1] + m[0][2]*q[0][2];
1810 _m[0][1] = m[0][0]*q[1][0] + m[0][1]*q[1][1] + m[0][2]*q[1][2];
1811 _m[0][2] = m[0][0]*q[2][0] + m[0][1]*q[2][1] + m[0][2]*q[2][2];
1812
1813 _m[1][0] = m[1][0]*q[0][0] + m[1][1]*q[0][1] + m[1][2]*q[0][2];
1814 _m[1][1] = m[1][0]*q[1][0] + m[1][1]*q[1][1] + m[1][2]*q[1][2];
1815 _m[1][2] = m[1][0]*q[2][0] + m[1][1]*q[2][1] + m[1][2]*q[2][2];
1816
1817 _m[2][0] = m[2][0]*q[0][0] + m[2][1]*q[0][1] + m[2][2]*q[0][2];
1818 _m[2][1] = m[2][0]*q[1][0] + m[2][1]*q[1][1] + m[2][2]*q[1][2];
1819 _m[2][2] = m[2][0]*q[2][0] + m[2][1]*q[2][1] + m[2][2]*q[2][2];
1820
1821 /* mout = Q _m */
1822 mout[0][0] = q[0][0]*_m[0][0] + q[0][1]*_m[1][0] + q[0][2]*_m[2][0];
1823 mout[0][1] = q[0][0]*_m[0][1] + q[0][1]*_m[1][1] + q[0][2]*_m[2][1];
1824 mout[0][2] = q[0][0]*_m[0][2] + q[0][1]*_m[1][2] + q[0][2]*_m[2][2];
1825
1826 mout[1][0] = q[1][0]*_m[0][0] + q[1][1]*_m[1][0] + q[1][2]*_m[2][0];
1827 mout[1][1] = q[1][0]*_m[0][1] + q[1][1]*_m[1][1] + q[1][2]*_m[2][1];
1828 mout[1][2] = q[1][0]*_m[0][2] + q[1][1]*_m[1][2] + q[1][2]*_m[2][2];
1829
1830 mout[2][0] = q[2][0]*_m[0][0] + q[2][1]*_m[1][0] + q[2][2]*_m[2][0];
1831 mout[2][1] = q[2][0]*_m[0][1] + q[2][1]*_m[1][1] + q[2][2]*_m[2][1];
1832 mout[2][2] = q[2][0]*_m[0][2] + q[2][1]*_m[1][2] + q[2][2]*_m[2][2];
1833}
1834
1835/*----------------------------------------------------------------------------*/
1844/*----------------------------------------------------------------------------*/
1845
1846CS_F_HOST_DEVICE inline void
1848 const cs_real_t q[3][3],
1849 cs_real_t mout[6])
1850{
1851 /* _m = M.Q^t */
1852 cs_real_33_t _m;
1853 _m[0][0] = m[0]*q[0][0] + m[3]*q[0][1] + m[5]*q[0][2];
1854 _m[0][1] = m[0]*q[1][0] + m[3]*q[1][1] + m[5]*q[1][2];
1855 _m[0][2] = m[0]*q[2][0] + m[3]*q[2][1] + m[5]*q[2][2];
1856
1857 _m[1][0] = m[3]*q[0][0] + m[1]*q[0][1] + m[4]*q[0][2];
1858 _m[1][1] = m[3]*q[1][0] + m[1]*q[1][1] + m[4]*q[1][2];
1859 _m[1][2] = m[3]*q[2][0] + m[1]*q[2][1] + m[4]*q[2][2];
1860
1861 _m[2][0] = m[5]*q[0][0] + m[4]*q[0][1] + m[2]*q[0][2];
1862 _m[2][1] = m[5]*q[1][0] + m[4]*q[1][1] + m[2]*q[1][2];
1863 _m[2][2] = m[5]*q[2][0] + m[4]*q[2][1] + m[2]*q[2][2];
1864
1865 /* mout = Q _m */
1866 mout[0] = q[0][0]*_m[0][0] + q[0][1]*_m[1][0] + q[0][2]*_m[2][0];
1867 mout[1] = q[1][0]*_m[0][1] + q[1][1]*_m[1][1] + q[1][2]*_m[2][1];
1868 mout[2] = q[2][0]*_m[0][2] + q[2][1]*_m[1][2] + q[2][2]*_m[2][2];
1869
1870
1871 mout[3] = q[0][0]*_m[0][1] + q[0][1]*_m[1][1] + q[0][2]*_m[2][1];
1872 mout[4] = q[1][0]*_m[0][2] + q[1][1]*_m[1][2] + q[1][2]*_m[2][2];
1873 mout[5] = q[0][0]*_m[0][2] + q[0][1]*_m[1][2] + q[0][2]*_m[2][2];
1874}
1875
1876/*----------------------------------------------------------------------------*/
1885/*----------------------------------------------------------------------------*/
1886
1887CS_F_HOST_DEVICE inline void
1889 cs_real_t m_sym[3][3],
1890 cs_real_t m_ant[3][3])
1891{
1892 /* sym = 0.5 (m + m_transpose) */
1893 m_sym[0][0] = 0.5 * (m[0][0] + m[0][0]);
1894 m_sym[0][1] = 0.5 * (m[0][1] + m[1][0]);
1895 m_sym[0][2] = 0.5 * (m[0][2] + m[2][0]);
1896 m_sym[1][0] = 0.5 * (m[1][0] + m[0][1]);
1897 m_sym[1][1] = 0.5 * (m[1][1] + m[1][1]);
1898 m_sym[1][2] = 0.5 * (m[1][2] + m[2][1]);
1899 m_sym[2][0] = 0.5 * (m[2][0] + m[0][2]);
1900 m_sym[2][1] = 0.5 * (m[2][1] + m[1][2]);
1901 m_sym[2][2] = 0.5 * (m[2][2] + m[2][2]);
1902
1903 /* ant = 0.5 (m - m_transpose) */
1904 m_ant[0][0] = 0.5 * (m[0][0] - m[0][0]);
1905 m_ant[0][1] = 0.5 * (m[0][1] - m[1][0]);
1906 m_ant[0][2] = 0.5 * (m[0][2] - m[2][0]);
1907 m_ant[1][0] = 0.5 * (m[1][0] - m[0][1]);
1908 m_ant[1][1] = 0.5 * (m[1][1] - m[1][1]);
1909 m_ant[1][2] = 0.5 * (m[1][2] - m[2][1]);
1910 m_ant[2][0] = 0.5 * (m[2][0] - m[0][2]);
1911 m_ant[2][1] = 0.5 * (m[2][1] - m[1][2]);
1912 m_ant[2][2] = 0.5 * (m[2][2] - m[2][2]);
1913}
1914
1915/*----------------------------------------------------------------------------*/
1924/*----------------------------------------------------------------------------*/
1925
1928{
1929 /* sym = 0.5 (m + m_transpose) */
1930 return cs_math_pow2(m[0][0])
1931 + cs_math_pow2(m[1][1])
1932 + cs_math_pow2(m[2][2])
1933 + 0.5 * ( cs_math_pow2(m[0][1] + m[1][0])
1934 + cs_math_pow2(m[0][2] + m[2][0])
1935 + cs_math_pow2(m[1][2] + m[2][1]));
1936}
1937
1938/*----------------------------------------------------------------------------*/
1946/*----------------------------------------------------------------------------*/
1947
1948CS_F_HOST_DEVICE inline void
1950 const cs_real_t m2[3][3],
1951 cs_real_t (*restrict mout)[3])
1952{
1953 mout[0][0] += m1[0][0]*m2[0][0] + m1[0][1]*m2[1][0] + m1[0][2]*m2[2][0];
1954 mout[0][1] += m1[0][0]*m2[0][1] + m1[0][1]*m2[1][1] + m1[0][2]*m2[2][1];
1955 mout[0][2] += m1[0][0]*m2[0][2] + m1[0][1]*m2[1][2] + m1[0][2]*m2[2][2];
1956
1957 mout[1][0] += m1[1][0]*m2[0][0] + m1[1][1]*m2[1][0] + m1[1][2]*m2[2][0];
1958 mout[1][1] += m1[1][0]*m2[0][1] + m1[1][1]*m2[1][1] + m1[1][2]*m2[2][1];
1959 mout[1][2] += m1[1][0]*m2[0][2] + m1[1][1]*m2[1][2] + m1[1][2]*m2[2][2];
1960
1961 mout[2][0] += m1[2][0]*m2[0][0] + m1[2][1]*m2[1][0] + m1[2][2]*m2[2][0];
1962 mout[2][1] += m1[2][0]*m2[0][1] + m1[2][1]*m2[1][1] + m1[2][2]*m2[2][1];
1963 mout[2][2] += m1[2][0]*m2[0][2] + m1[2][1]*m2[1][2] + m1[2][2]*m2[2][2];
1964}
1965
1966/*----------------------------------------------------------------------------*/
1980/*----------------------------------------------------------------------------*/
1981
1982CS_F_HOST_DEVICE inline void
1984 const cs_real_t s2[6],
1985 cs_real_t *restrict sout)
1986{
1987 /* S11 */
1988 sout[0] = s1[0]*s2[0] + s1[3]*s2[3] + s1[5]*s2[5];
1989 /* S22 */
1990 sout[1] = s1[3]*s2[3] + s1[1]*s2[1] + s1[4]*s2[4];
1991 /* S33 */
1992 sout[2] = s1[5]*s2[5] + s1[4]*s2[4] + s1[2]*s2[2];
1993 /* S12 = S21 */
1994 sout[3] = s1[0]*s2[3] + s1[3]*s2[1] + s1[5]*s2[4];
1995 /* S23 = S32 */
1996 sout[4] = s1[3]*s2[5] + s1[1]*s2[4] + s1[4]*s2[2];
1997 /* S13 = S31 */
1998 sout[5] = s1[0]*s2[5] + s1[3]*s2[4] + s1[5]*s2[2];
1999}
2000
2001/*----------------------------------------------------------------------------*/
2014/*----------------------------------------------------------------------------*/
2015
2016CS_F_HOST_DEVICE inline void
2018 cs_real_t e[4])
2019{
2020 /* Distinguish 4 different cases to avoid division by 0 */
2021 if (fabs(1.+m[0][0]+m[1][1]+m[2][2]) > 1.0e-12) {
2022 // Case 1: e[0] is not equal to 0
2023 e[0] = 0.5*sqrt(1+m[0][0]+m[1][1]+m[2][2]);
2024 e[1] = 0.25*(m[2][1]-m[1][2])/e[0];
2025 e[2] = 0.25*(m[0][2]-m[2][0])/e[0];
2026 e[3] = 0.25*(m[1][0]-m[0][1])/e[0];
2027 }
2028 else if (fabs(1+m[0][0]-m[1][1]-m[2][2]) > 1.0e-12) {
2029 // Case 2: e[1] is not equal to 0
2030 e[1] = 0.5*sqrt(1+m[0][0]-m[1][1]-m[2][2]);
2031 e[0] = 0.25*(m[2][1]-m[1][2])/e[1];
2032 e[2] = 0.25*(m[1][0]+m[0][1])/e[1];
2033 e[3] = 0.25*(m[0][2]+m[2][0])/e[1];
2034 }
2035 else if (fabs(1-m[0][0]+m[1][1]-m[2][2]) > 1.0e-12) {
2036 // Case 3: e[2] is not equal to 0
2037 e[2] = 0.5*sqrt(1-m[0][0]+m[1][1]-m[2][2]);
2038 e[0] = 0.25*(m[0][2]-m[2][0])/e[2];
2039 e[1] = 0.25*(m[1][0]+m[0][1])/e[2];
2040 e[3] = 0.25*(m[2][1]+m[1][2])/e[2];
2041 }
2042 else if (fabs(1-m[0][0]-m[1][1]+m[2][2]) > 1.0e-12) {
2043 // Case 4: e[3] is not equal to 0
2044 e[3] = 0.5*sqrt(1-m[0][0]-m[1][1]+m[2][2]);
2045 e[0] = 0.25*(m[1][0]-m[0][1])/e[3];
2046 e[1] = 0.25*(m[0][2]+m[2][0])/e[3];
2047 e[2] = 0.25*(m[2][1]+m[1][2])/e[3];
2048 }
2049}
2050
2051/*----------------------------------------------------------------------------*/
2064/*----------------------------------------------------------------------------*/
2065
2066CS_F_HOST_DEVICE inline void
2068 cs_real_t m[3][3])
2069{
2070 m[0][0] = 2.*(e[0]*e[0]+e[1]*e[1]-0.5);
2071 m[0][1] = 2.*(e[1]*e[2]+e[0]*e[3]);
2072 m[0][2] = 2.*(e[1]*e[3]-e[0]*e[2]);
2073 m[1][0] = 2.*(e[1]*e[2]-e[0]*e[3]);
2074 m[1][1] = 2.*(e[0]*e[0]+e[2]*e[2]-0.5);
2075 m[1][2] = 2.*(e[2]*e[3]+e[0]*e[1]);
2076 m[2][0] = 2.*(e[1]*e[3]+e[0]*e[2]);
2077 m[2][1] = 2.*(e[2]*e[3]-e[0]*e[1]);
2078 m[2][2] = 2.*(e[0]*e[0]+e[3]*e[3]-0.5);
2079}
2080
2081/*----------------------------------------------------------------------------*/
2091/*----------------------------------------------------------------------------*/
2092
2093CS_F_HOST_DEVICE inline void
2095 const cs_real_t dir_r[3],
2096 cs_real_t euler[4])
2097{
2098 // The rotation axis is the result of the cross product between
2099 // the new direction vector and the main axis.
2100 cs_real_t n_rot[3];
2101
2102 // Use quaternion (cos(theta/2), sin(theta/2) n_rot)
2103 // where n_rot = dir ^ dir_r normalised
2104 // so also dir ^ (dir + dir_r)
2105 //
2106 // cos(theta/2) = || dir + dir_r|| / 2
2107 cs_real_t dir_p_dir_r[3] = {dir[0] + dir_r[0],
2108 dir[1] + dir_r[1],
2109 dir[2] + dir_r[2]};
2110 cs_real_t dir_p_dir_r_normed[3];
2111 cs_math_3_normalize(dir_p_dir_r, dir_p_dir_r_normed);
2112
2113 /* dir ^(dir + dir_r) / || dir + dir_r|| = sin(theta/2) n_rot
2114 * for the quaternion */
2115 cs_math_3_cross_product(dir, dir_p_dir_r_normed, n_rot);
2116
2117 /* quaternion, could be normalized afterwards
2118 *
2119 * Note that the division seems stupid but is not
2120 * in case of degenerated case where dir is null
2121 * */
2122 euler[0] = cs_math_3_norm(dir_p_dir_r)
2123 / (cs_math_3_norm(dir) + cs_math_3_norm(dir_r));
2124 euler[1] = n_rot[0];
2125 euler[2] = n_rot[1];
2126 euler[3] = n_rot[2];
2127}
2128
2129/*----------------------------------------------------------------------------*/
2137/*----------------------------------------------------------------------------*/
2138
2139CS_F_HOST_DEVICE inline void
2141 cs_real_t (*restrict sout)[6])
2142{
2143 const int t2v[3][3] = {{0, 3, 5},
2144 {3, 1, 4},
2145 {5, 4, 2}};
2146
2147 const int iv2t[6] = {0, 1, 2, 0, 1, 0};
2148 const int jv2t[6] = {0, 1, 2, 1, 2, 2};
2149
2150 for (int i = 0; i < 6; i++) {
2151 for (int j = 0; j < 6; j++)
2152 sout[i][j] = 0;
2153 }
2154
2155 /* Consider : W = s*R + R*s^t .
2156 * W_ij = Sum_{k<3} [s_ik*r_jk + s_jk*r_ik]
2157 * We look for A_(ij,pq) such as A*R = W
2158 *
2159 * so
2160 * A_(ij,jk) takes s_ik
2161 * and
2162 * A_(ij,ik) takes s_jk
2163 */
2164 for (int ij = 0; ij < 6; ij++) {
2165 int i = iv2t[ij];
2166 int j = jv2t[ij];
2167 for (int k = 0; k < 3; k++) {
2168 int ik = t2v[i][k];
2169 int jk = t2v[j][k];
2170
2171 sout[ij][ik] += s[j][k];
2172 sout[ij][jk] += s[i][k];
2173 }
2174 }
2175}
2176
2177/*----------------------------------------------------------------------------*/
2189/*----------------------------------------------------------------------------*/
2190
2191CS_F_HOST_DEVICE inline void
2193 const cs_real_t s2[6],
2194 const cs_real_t s3[6],
2195 cs_real_t (*restrict sout)[3])
2196{
2197 cs_real_t _sout[3][3];
2198
2199 /* S11 */
2200 _sout[0][0] = s1[0]*s2[0] + s1[3]*s2[3] + s1[5]*s2[5];
2201 /* S22 */
2202 _sout[1][1] = s1[3]*s2[3] + s1[1]*s2[1] + s1[4]*s2[4];
2203 /* S33 */
2204 _sout[2][2] = s1[5]*s2[5] + s1[4]*s2[4] + s1[2]*s2[2];
2205 /* S12 */
2206 _sout[0][1] = s1[0]*s2[3] + s1[3]*s2[1] + s1[5]*s2[4];
2207 /* S21 */
2208 _sout[1][0] = s2[0]*s1[3] + s2[3]*s1[1] + s2[5]*s1[4];
2209 /* S23 */
2210 _sout[1][2] = s1[3]*s2[5] + s1[1]*s2[4] + s1[4]*s2[2];
2211 /* S32 */
2212 _sout[2][1] = s2[3]*s1[5] + s2[1]*s1[4] + s2[4]*s1[2];
2213 /* S13 */
2214 _sout[0][2] = s1[0]*s2[5] + s1[3]*s2[4] + s1[5]*s2[2];
2215 /* S31 */
2216 _sout[2][0] = s2[0]*s1[5] + s2[3]*s1[4] + s2[5]*s1[2];
2217
2218 sout[0][0] = _sout[0][0]*s3[0] + _sout[0][1]*s3[3] + _sout[0][2]*s3[5];
2219 /* S22 */
2220 sout[1][1] = _sout[1][0]*s3[3] + _sout[1][1]*s3[1] + _sout[1][2]*s3[4];
2221 /* S33 */
2222 sout[2][2] = _sout[2][0]*s3[5] + _sout[2][1]*s3[4] + _sout[2][2]*s3[2];
2223 /* S12 */
2224 sout[0][1] = _sout[0][0]*s3[3] + _sout[0][1]*s3[1] + _sout[0][2]*s3[4];
2225 /* S21 */
2226 sout[1][0] = s3[0]*_sout[1][0] + s3[3]*_sout[1][1] + s3[5]*_sout[1][2];
2227 /* S23 */
2228 sout[1][2] = _sout[1][0]*s3[5] + _sout[1][1]*s3[4] + _sout[1][2]*s3[2];
2229 /* S32 */
2230 sout[2][1] = s3[3]*_sout[2][0] + s3[1]*_sout[2][1] + s3[4]*_sout[2][2];
2231 /* S13 */
2232 sout[0][2] = _sout[0][0]*s3[5] + _sout[0][1]*s3[4] + _sout[0][2]*s3[2];
2233 /* S31 */
2234 sout[2][0] = s3[0]*_sout[2][0] + s3[3]*_sout[2][1] + s3[5]*_sout[2][2];
2235}
2236
2237/*----------------------------------------------------------------------------*/
2244/*----------------------------------------------------------------------------*/
2245
2246CS_F_HOST_DEVICE inline void
2248 cs_nvec3_t *qv)
2249{
2250 cs_real_t magnitude = sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
2251
2252 qv->meas = magnitude;
2253 if (fabs(magnitude) > cs_math_zero_threshold) {
2254
2255 const cs_real_t inv = 1/magnitude;
2256 qv->unitv[0] = inv * v[0];
2257 qv->unitv[1] = inv * v[1];
2258 qv->unitv[2] = inv * v[2];
2259
2260 }
2261 else
2262 qv->unitv[0] = qv->unitv[1] = qv->unitv[2] = 0;
2263}
2264
2265/*----------------------------------------------------------------------------*/
2275/*----------------------------------------------------------------------------*/
2276
2277CS_F_HOST_DEVICE inline void
2279{
2280 /* Factorization */
2281
2282 // j=0
2283 const cs_real_t d00 = ldlt[0]; // m00
2284 assert(fabs(d00) > cs_math_zero_threshold);
2285
2286 const cs_real_t f00 = 1. / d00;
2287 const cs_real_t l10 = ldlt[1] * f00; // m01
2288 const cs_real_t l20 = ldlt[3] * f00; // m02
2289 const cs_real_t l30 = ldlt[6] * f00; // m03
2290
2291 // j=1
2292 const cs_real_t d11 = ldlt[2] - l10*l10*d00; // m11
2293 assert(fabs(d11) > cs_math_zero_threshold);
2294 const cs_real_t f11 = 1. / d11;
2295 const cs_real_t l21 = (ldlt[4] - l20*d00*l10) * f11; // m12
2296 const cs_real_t l31 = (ldlt[7] - l30*d00*l10) * f11; // m13
2297
2298 // j=2
2299 const cs_real_t d22 = ldlt[5] - l20*d00*l20 - l21*d11*l21; // m22
2300 assert(fabs(d22) > cs_math_zero_threshold);
2301 const cs_real_t f22 = 1. / d22;
2302 const cs_real_t l32 = (ldlt[8] - l30*d00*l20 - l31*d11*l21) * f22; // m23
2303
2304 // j=3
2305 const cs_real_t d33 = ldlt[9] - l30*d00*l30 - l31*d11*l31 - l32*d22*l32; // m33
2306 assert(fabs(d33) > cs_math_zero_threshold);
2307 const cs_real_t f33 = 1. / d33;
2308
2309 ldlt[0] = f00;
2310 ldlt[1] = l10;
2311 ldlt[2] = f11;
2312 ldlt[3] = l20;
2313 ldlt[4] = l21;
2314 ldlt[5] = f22;
2315 ldlt[6] = l30;
2316 ldlt[7] = l31;
2317 ldlt[8] = l32;
2318 ldlt[9] = f33;
2319}
2320
2321/*----------------------------------------------------------------------------*/
2334/*----------------------------------------------------------------------------*/
2335
2338 const cs_real_t rhs[4])
2339{
2340 /* f00, f11, f22, f33, l32, l31, l30, l21, l20, l10
2341 0 1 2 3 4 5 6 7 8 9 */
2342
2343 cs_real_t x[4]; /* solution */
2344
2345 x[0] = rhs[0];
2346 x[1] = rhs[1] - x[0]*ldlt[1];
2347 x[2] = rhs[2] - x[0]*ldlt[3] - x[1]*ldlt[4];
2348 x[3] = rhs[3] - x[0]*ldlt[6] - x[1]*ldlt[7] - x[2]*ldlt[8];
2349
2350 x[3] = x[3]*ldlt[9];
2351
2352 return x[3];
2353
2354 /*
2355 x[2] = x[2]*ldlt[5] - ldlt[8]*x[3];
2356 x[1] = x[1]*ldlt[2] - ldlt[7]*x[3] - ldlt[4]*x[2];
2357 x[0] = x[0]*ldlt[0] - ldlt[6]*x[3] - ldlt[3]*x[2] - ldlt[1]*x[1];
2358 */
2359}
2360
2361/*=============================================================================
2362 * Public function prototypes
2363 *============================================================================*/
2364
2365/*----------------------------------------------------------------------------*/
2366/*
2367 * \brief Compute the length (Euclidean norm) between two points xa and xb in
2368 * a Cartesian coordinate system of dimension 3
2369 *
2370 * \param[in] xa coordinate of the first extremity
2371 * \param[in] xb coordinate of the second extremity
2372 * \param[out] len pointer to the length of the vector va -> vb
2373 * \param[out] unitv unitary vector along xa -> xb
2374 */
2375/*----------------------------------------------------------------------------*/
2376
2379 const cs_real_t xb[3],
2380 cs_real_t *len,
2381 cs_real_3_t unitv);
2382
2383/*----------------------------------------------------------------------------*/
2395/*----------------------------------------------------------------------------*/
2396
2397void
2399 cs_real_t eig_vals[3]);
2400
2401/*----------------------------------------------------------------------------*/
2414/*----------------------------------------------------------------------------*/
2415
2416void
2417cs_math_33_eigen(const cs_real_t m[3][3],
2418 cs_real_t *eig_ratio,
2419 cs_real_t *eig_max);
2420
2421/*----------------------------------------------------------------------------*/
2432/*----------------------------------------------------------------------------*/
2433
2434double
2435cs_math_surftri(const cs_real_t xv[3],
2436 const cs_real_t xe[3],
2437 const cs_real_t xf[3]);
2438
2439/*----------------------------------------------------------------------------*/
2451/*----------------------------------------------------------------------------*/
2452
2453double
2454cs_math_voltet(const cs_real_t xv[3],
2455 const cs_real_t xe[3],
2456 const cs_real_t xf[3],
2457 const cs_real_t xc[3]);
2458
2459/*----------------------------------------------------------------------------*/
2472/*----------------------------------------------------------------------------*/
2473
2474void
2476 const cs_real_t tol_err,
2477 cs_real_t eig_val[3],
2478 cs_real_t eig_vec[3][3]);
2479
2480/*----------------------------------------------------------------------------*/
2489/*----------------------------------------------------------------------------*/
2490
2491void
2492cs_math_fact_lu(const int n,
2493 const cs_real_t *a,
2494 cs_real_t *a_lu);
2495
2496/*----------------------------------------------------------------------------*/
2505/*----------------------------------------------------------------------------*/
2506
2507void
2508cs_math_fw_and_bw_lu(const cs_real_t a_lu[],
2509 const int n,
2510 cs_real_t x[],
2511 const cs_real_t b[]);
2512
2513/*----------------------------------------------------------------------------*/
2514
2516
2517#endif /* CS_MATH_H */
#define restrict
Definition: cs_defs.h:148
#define BEGIN_C_DECLS
Definition: cs_defs.h:528
#define CS_F_HOST_DEVICE
Definition: cs_defs.h:555
double cs_real_t
Floating-point value.
Definition: cs_defs.h:332
cs_real_t cs_real_3_t[3]
vector of 3 floating-point values
Definition: cs_defs.h:349
cs_real_t cs_real_6_t[6]
vector of 6 floating-point values
Definition: cs_defs.h:351
#define END_C_DECLS
Definition: cs_defs.h:529
cs_real_t cs_real_33_t[3][3]
3x3 matrix of floating-point values
Definition: cs_defs.h:358
@ t
Definition: cs_field_pointer.h:91
@ k
Definition: cs_field_pointer.h:68
@ x2
Definition: cs_field_pointer.h:199
CS_F_HOST_DEVICE void cs_math_33_normal_scaling_add(const cs_real_t n[3], cs_real_t factor, cs_real_t t[3][3])
Add the dot product with a normal vector to the normal,normal component of a tensor: t += factor * n....
Definition: cs_math.h:1214
CS_F_HOST_DEVICE cs_real_t cs_math_3_dot_product(const T u[3], const U v[3])
Compute the dot product of two vectors of 3 real values.
Definition: cs_math.h:194
CS_F_HOST_DEVICE cs_real_t cs_math_square_norm(const cs_real_t t[stride])
Compute a square norm associated with a vector or tensor.
Definition: cs_math.h:308
CS_F_HOST_DEVICE void cs_nvec3(const cs_real_t v[3], cs_nvec3_t *qv)
Define a cs_nvec3_t structure from a cs_real_3_t.
Definition: cs_math.h:2247
CS_F_HOST_DEVICE void cs_math_3_average(const cs_real_t u[3], const cs_real_t v[3], cs_real_t *restrict uv)
Compute the average of two vector of dimension 3.
Definition: cs_math.h:1446
static constexpr double cs_dbl_max
Definition: cs_math.h:99
CS_F_HOST_DEVICE void cs_math_sym_33_transform_a_to_r(const cs_real_t m[6], const cs_real_t q[3][3], cs_real_t mout[6])
Compute transformation from absolute to relative reference frame Q M Q^t.
Definition: cs_math.h:1847
CS_F_HOST_DEVICE cs_real_t cs_math_sym_33_determinant(const cs_real_t m[6])
Compute the determinant of a 3x3 symmetric matrix.
Definition: cs_math.h:1426
CS_F_HOST_DEVICE cs_real_t cs_math_sym_44_partial_solve_ldlt(const cs_real_t ldlt[10], const cs_real_t rhs[4])
LDL^T: Modified Cholesky decomposition of a 4x4 SPD matrix. For more reference, see for instance http...
Definition: cs_math.h:2337
CS_F_HOST_DEVICE void cs_math_33_inv_cramer_in_place(cs_real_t a[3][3])
Inverse a 3x3 matrix in place, using Cramer's rule.
Definition: cs_math.h:1587
CS_F_HOST_DEVICE cs_real_t cs_math_pow4(cs_real_t x)
Compute the 4-th power of a real value.
Definition: cs_math.h:934
static constexpr cs_real_6_t cs_math_sym_33_identity
Definition: cs_math.h:124
static constexpr cs_real_t cs_math_1ov6
Definition: cs_math.h:117
CS_F_HOST_DEVICE cs_real_t cs_math_3_distance_dot_product(const T xa[3], const T xb[3], const U xc[3])
Compute .
Definition: cs_math.h:171
static constexpr cs_real_t cs_math_1ov24
Definition: cs_math.h:119
void cs_math_33_eig_val_vec(const cs_real_t m_in[3][3], const cs_real_t tol_err, cs_real_t eig_val[3], cs_real_t eig_vec[3][3])
Evaluate eigenvalues and eigenvectors of a real symmetric matrix m1[3,3]: m1*m2 = lambda*m2.
CS_F_HOST_DEVICE void cs_math_sym_44_factor_ldlt(cs_real_t ldlt[10])
LDL^T: Modified Cholesky decomposition of a 4x4 SPD matrix. For more reference, see for instance http...
Definition: cs_math.h:2278
static constexpr cs_real_t cs_math_epzero
Definition: cs_math.h:102
double cs_math_surftri(const cs_real_t xv[3], const cs_real_t xe[3], const cs_real_t xf[3])
Compute the area of the convex_hull generated by 3 points. This corresponds to the computation of the...
Definition: cs_math.cpp:336
CS_F_HOST_DEVICE cs_real_t cs_math_sym_33_sym_33_product_trace(const cs_real_t m1[6], const cs_real_t m2[6])
Compute the product of two symmetric matrices of 3x3 real values and take the trace....
Definition: cs_math.h:1327
CS_F_HOST_DEVICE void cs_math_33_product_add(const cs_real_t m1[3][3], const cs_real_t m2[3][3], cs_real_t(*restrict mout)[3])
Add the product of two 3x3 real matrices to a matrix.
Definition: cs_math.h:1949
CS_F_HOST_DEVICE T cs_math_sq(T x)
Compute the square of a real value.
Definition: cs_math.h:149
CS_F_HOST_DEVICE void cs_math_3_normalize_threshold(const cs_real_t vin[3], const cs_real_t thres, cs_real_t vout[3])
Normalise a vector of 3 real values and clip the norm using a threshold value.
Definition: cs_math.h:1167
static constexpr double cs_dbl_min
Definition: cs_math.h:96
static constexpr double cs_dbl_epsilon
Definition: cs_math.h:93
CS_F_HOST_DEVICE void cs_math_33_transform_a_to_r(const cs_real_t m[3][3], const cs_real_t q[3][3], cs_real_t mout[3][3])
Compute transformation from absolute to relative reference frame Q M Q^t.
Definition: cs_math.h:1803
CS_F_HOST_DEVICE cs_real_t cs_math_3_distance(const cs_real_t xa[3], const cs_real_t xb[3])
Compute the (euclidean) distance between two points xa and xb in a Cartesian coordinate system of dim...
Definition: cs_math.h:970
CS_F_HOST_DEVICE void cs_math_reduce_sym_prod_33_to_66(const cs_real_t s[3][3], cs_real_t(*restrict sout)[6])
Compute a 6x6 matrix A, equivalent to a 3x3 matrix s, such as: A*R_6 = R*s^t + s*R.
Definition: cs_math.h:2140
CS_F_HOST_DEVICE void cs_math_33t_3_product(const cs_real_t m[3][3], const cs_real_t v[3], cs_real_t *restrict mv)
Compute the product of the transpose of a matrix of 3x3 real values by a vector of 3 real values.
Definition: cs_math.h:1261
static constexpr cs_real_t cs_math_zero_threshold
Definition: cs_math.h:90
CS_F_HOST_DEVICE void cs_math_66_6_product_add(const cs_real_t m[6][6], const cs_real_t v[6], cs_real_t *restrict mv)
Compute the product of a matrix of 6x6 real values by a vector of 6 real values and add it to the vec...
Definition: cs_math.h:1385
CS_F_HOST_DEVICE cs_real_t cs_math_6_trace(const cs_real_t t[6])
Compute the trace of a symmetric tensor.
Definition: cs_math.h:1346
static constexpr cs_real_33_t cs_math_33_identity
Definition: cs_math.h:121
void cs_math_sym_33_eigen(const cs_real_t m[6], cs_real_t eig_vals[3])
Compute all eigenvalues of a 3x3 symmetric matrix with symmetric storage.
Definition: cs_math.cpp:124
CS_F_HOST_DEVICE void cs_math_33_rotation_into_quaternions(const cs_real_t m[3][3], cs_real_t e[4])
Compute the 4 Euler parameters (defining a quaternion) knowing the rotation matrix m Based on: J....
Definition: cs_math.h:2017
CS_F_HOST_DEVICE void cs_math_sym_33_3_product(const T m[6], const U v[3], V *restrict mv)
Compute the product of a symmetric matrix of 3x3 real values by a vector of 3 real values....
Definition: cs_math.h:416
CS_F_HOST_DEVICE void cs_math_3_orthonormal_basis(const cs_real_t vect[3], cs_real_t axes[3][3])
Build an orthonormal basis based on a first vector "vect". axes[0] is vect normalized,...
Definition: cs_math.h:1518
CS_F_HOST_DEVICE cs_real_t cs_math_pow5(cs_real_t x)
Compute the 5-th power of a real value.
Definition: cs_math.h:951
CS_F_HOST_DEVICE void cs_math_matrix_gauss_inverse(const T a[n][n], T b[n][n])
Inverse square, dense matrix using Gauss-Jordan elimination.
Definition: cs_math.h:542
CS_F_HOST_DEVICE void cs_math_33_3_product_add(const cs_real_t m[3][3], const cs_real_t v[3], cs_real_t *restrict mv)
Compute the product of a matrix of 3x3 real values by a vector of 3 real values add.
Definition: cs_math.h:1240
void cs_math_fw_and_bw_lu(const cs_real_t a_lu[], const int n, cs_real_t x[], const cs_real_t b[])
Compute forward and backward to solve an LU P*P system.
Definition: cs_math.cpp:584
static constexpr cs_real_t cs_math_1ov12
Definition: cs_math.h:118
CS_F_HOST_DEVICE cs_real_t cs_math_3_triple_product(const cs_real_t u[3], const cs_real_t v[3], const cs_real_t w[3])
Compute the triple product.
Definition: cs_math.h:1496
CS_F_HOST_DEVICE void cs_math_33_inv_cramer_sym_in_place(cs_real_t a[3][3])
Inverse a 3x3 symmetric matrix (with non-symmetric storage) in place, using Cramer's rule.
Definition: cs_math.h:1622
CS_F_HOST_DEVICE cs_real_t cs_math_clamp(cs_real_t x, cs_real_t xmin, cs_real_t xmax)
Clamp function for a given scalar value.
Definition: cs_math.h:866
int cs_math_binom(int n, int k)
Computes the binomial coefficient of n and k.
Definition: cs_math.h:777
CS_F_HOST_DEVICE cs_real_t cs_math_33_determinant(const cs_real_t m[3][3])
Compute the determinant of a 3x3 matrix.
Definition: cs_math.h:1406
CS_F_HOST_DEVICE cs_real_t cs_math_fmax(cs_real_t x, cs_real_t y)
Compute the max value of two real values.
Definition: cs_math.h:844
CS_F_HOST_DEVICE void cs_math_33_3_product(const T m[3][3], const U v[3], V *restrict mv)
Compute the product of a matrix of 3x3 real values by a vector of 3 real values.
Definition: cs_math.h:389
void cs_math_33_eigen(const cs_real_t m[3][3], cs_real_t *eig_ratio, cs_real_t *eig_max)
Compute max/min eigenvalues ratio and max. eigenvalue of a 3x3 symmetric matrix with non-symmetric st...
Definition: cs_math.cpp:213
CS_F_HOST_DEVICE cs_real_t cs_math_pow3(cs_real_t x)
Compute the cube of a real value.
Definition: cs_math.h:918
static constexpr cs_real_t cs_math_infinite_r
Definition: cs_math.h:105
CS_F_HOST_DEVICE void cs_math_3_normalize(const T vin[3], U vout[3])
Normalise a vector of 3 real values.
Definition: cs_math.h:360
CS_F_HOST_DEVICE cs_real_t cs_math_3_33_3_dot_product(const T n1[3], const U t[3][3], const V n2[3])
Compute the dot product of a tensor t with two vectors, n1 and n2.
Definition: cs_math.h:469
CS_F_HOST_DEVICE void cs_math_3_normal_scaling(const T n[3], U factor, V v[3])
Add the dot product with a normal vector to the normal direction to a vector.
Definition: cs_math.h:442
CS_F_HOST_DEVICE void cs_math_33_transform_r_to_a(const cs_real_t m[3][3], const cs_real_t q[3][3], cs_real_t mout[3][3])
Compute transformation from relative to absolute reference frame Q^t M Q.
Definition: cs_math.h:1719
CS_F_HOST_DEVICE cs_real_t cs_math_pow2(cs_real_t x)
Compute the square of a real value.
Definition: cs_math.h:902
CS_F_HOST_DEVICE void cs_math_sym_33_3_product_add(const cs_real_t m[6], const cs_real_t v[3], cs_real_t *restrict mv)
Compute the product of a symmetric matrix of 3x3 real values by a vector of 3 real values and add it ...
Definition: cs_math.h:1305
CS_F_HOST_DEVICE void cs_math_6_gauss_inverse_in_place(T a[6])
Inverse 3x3 symmetric matrix in place, using Gauss-Jordan elimination.
Definition: cs_math.h:600
CS_F_HOST_DEVICE T cs_math_3_square_norm(const T v[3])
Compute the square norm of a vector of 3 real values.
Definition: cs_math.h:337
static constexpr cs_real_t cs_math_5ov3
Definition: cs_math.h:116
void cs_math_fact_lu(const int n, const cs_real_t *a, cs_real_t *a_lu)
Compute LU factorization of an array of dense matrices of identical size.
Definition: cs_math.cpp:532
CS_F_HOST_DEVICE cs_real_t cs_math_fmin(cs_real_t x, cs_real_t y)
Compute the min value of two real values.
Definition: cs_math.h:825
cs_math_sym_tensor_component_t
Definition: cs_math.h:72
@ ZZ
Definition: cs_math.h:76
@ XY
Definition: cs_math.h:77
@ XZ
Definition: cs_math.h:79
@ YZ
Definition: cs_math.h:78
@ YY
Definition: cs_math.h:75
@ XX
Definition: cs_math.h:74
CS_F_HOST_DEVICE void cs_math_3_length_unitv(const cs_real_t xa[3], const cs_real_t xb[3], cs_real_t *len, cs_real_3_t unitv)
Compute the length (Euclidean norm) between two points xa and xb in a Cartesian coordinate system of ...
Definition: cs_math.cpp:303
CS_F_HOST_DEVICE T cs_math_33_trace(const T t[3][3])
Compute the trace of a 3x3 tensor.
Definition: cs_math.h:257
static constexpr cs_real_t cs_math_4ov3
Definition: cs_math.h:115
CS_F_HOST_DEVICE void cs_math_33_extract_sym_ant(const cs_real_t m[3][3], cs_real_t m_sym[3][3], cs_real_t m_ant[3][3])
Extract from the given matrix its symmetric and anti-symmetric part.
Definition: cs_math.h:1888
CS_F_HOST_DEVICE void cs_math_quaternions_from_2_vectors(const cs_real_t dir[3], const cs_real_t dir_r[3], cs_real_t euler[4])
Compute the 4 Euler parameters using 2 direction vectors one for the relative mean velocity in the gl...
Definition: cs_math.h:2094
static constexpr cs_real_t cs_math_2ov3
Definition: cs_math.h:114
CS_F_HOST_DEVICE void cs_math_sym_33_transform_r_to_a(const cs_real_t m[6], const cs_real_t q[3][3], cs_real_t mout[6])
Compute transformation from relative to absolute reference frame Q^t M Q.
Definition: cs_math.h:1763
CS_F_HOST_DEVICE void cs_math_3_orthogonal_projection(const T n[3], const U v[3], V *restrict vout)
Orthogonal projection of a vector with respect to a normalised vector.
Definition: cs_math.h:497
double cs_math_voltet(const cs_real_t xv[3], const cs_real_t xe[3], const cs_real_t xf[3], const cs_real_t xc[3])
Compute the volume of the convex_hull generated by 4 points. This is equivalent to the computation of...
Definition: cs_math.cpp:366
CS_F_HOST_DEVICE T cs_math_3_norm(const T v[3])
Compute the euclidean norm of a vector of dimension 3.
Definition: cs_math.h:240
CS_F_HOST_DEVICE void cs_math_3_cross_product(const T u[3], const U v[3], V *restrict uv)
Compute the cross product of two vectors of 3 real values.
Definition: cs_math.h:522
CS_F_HOST_DEVICE void cs_math_sym_33_inv_cramer(const cs_real_t s[6], cs_real_t *restrict sout)
Compute the inverse of a symmetric matrix using Cramer's rule.
Definition: cs_math.h:1657
CS_F_HOST_DEVICE void cs_math_66_6_product(const cs_real_t m[6][6], const cs_real_t v[6], cs_real_t *restrict mv)
Compute the product of a matrix of 6x6 real values by a vector of 6 real values.
Definition: cs_math.h:1363
CS_F_HOST_DEVICE cs_real_t cs_math_3_square_distance(const cs_real_t xa[3], const cs_real_t xb[3])
Compute the squared distance between two points xa and xb in a Cartesian coordinate system of dimensi...
Definition: cs_math.h:1015
CS_F_HOST_DEVICE void cs_math_sym_33_double_product(const cs_real_t s1[6], const cs_real_t s2[6], const cs_real_t s3[6], cs_real_t(*restrict sout)[3])
Compute the product of three symmetric matrices.
Definition: cs_math.h:2192
CS_F_HOST_DEVICE void cs_math_33_product(const cs_real_t m1[3][3], const cs_real_t m2[3][3], cs_real_t mout[3][3])
Compute the product of two 3x3 real valued matrices.
Definition: cs_math.h:1690
CS_F_HOST_DEVICE void cs_math_33_inv_cramer(const cs_real_t in[3][3], cs_real_t out[3][3])
Inverse a 3x3 matrix.
Definition: cs_math.h:1555
CS_F_HOST_DEVICE cs_real_t cs_math_fabs(cs_real_t x)
Compute the absolute value of a real value.
Definition: cs_math.h:807
static constexpr cs_real_t cs_math_pi
Definition: cs_math.h:111
static constexpr cs_real_t cs_math_big_r
Definition: cs_math.h:108
CS_F_HOST_DEVICE void cs_math_sym_33_product(const cs_real_t s1[6], const cs_real_t s2[6], cs_real_t *restrict sout)
Compute the product of two symmetric matrices.
Definition: cs_math.h:1983
CS_F_HOST_DEVICE void cs_math_quaternions_into_33_rotation(const cs_real_t e[4], cs_real_t m[3][3])
Compute the rotation matrix m (3x3 matrix) knowing the 4 Euler parameters (defining a quaternion) Bas...
Definition: cs_math.h:2067
CS_F_HOST_DEVICE cs_real_t cs_math_3_sym_33_3_dot_product(const T n1[3], const U t[6], const V n2[3])
Compute the dot product of a symmetric tensor t with two vectors, n1 and n2.
Definition: cs_math.h:284
static constexpr cs_real_t cs_math_1ov3
Definition: cs_math.h:113
CS_F_HOST_DEVICE cs_real_t cs_math_33_main_invariant_2(const cs_real_t m[3][3])
Compute the second main invariant of the symmetric part of a 3x3 tensor.
Definition: cs_math.h:1927
Definition: cs_algorithm.h:51
CS_F_HOST_DEVICE T max(const T a, const T b)
Definition: cs_defs.h:735
CS_F_HOST_DEVICE float pow2(float x)
Compute the square of a real value.
Definition: cs_math.h:744
CS_F_HOST_DEVICE float max(const float a, const float b)
Definition: cs_math.h:695
CS_F_HOST_DEVICE T clamp(const T x, const T xmin, const T xmax)
Definition: cs_defs.h:760
CS_F_HOST_DEVICE T min(const T a, const T b)
Definition: cs_defs.h:712
CS_F_HOST_DEVICE float min(const float a, const float b)
Definition: cs_math.h:667
CS_F_HOST_DEVICE T abs(const T a)
Definition: cs_defs.h:690
Definition: cs_defs.h:390
double meas
Definition: cs_defs.h:392
double unitv[3]
Definition: cs_defs.h:393