proteus
1.9.0
C/C++/Fortran libraries
Toggle main menu visibility
Loading...
Searching...
No Matches
work
cekees
proteus
proteus
equivalent_polynomials_utils.h
Go to the documentation of this file.
1
#ifndef EQUIVALENT_POYNOMIALS_UTILS
2
#define EQUIVALENT_POYNOMIALS_UTILS
3
namespace
equivalent_polynomials
4
{
5
template
<
int
nSpace>
6
inline
void
_calculate_normal
(
double
* phys_nodes_cut,
double
* level_set_normal);
7
8
template
<>
9
inline
void
_calculate_normal<1>
(
double
* phys_nodes_cut,
double
* level_set_normal)
10
{
11
const
unsigned
int
nSpace(1);
12
level_set_normal[0] = 1.0;
13
}
14
15
template
<>
16
inline
void
_calculate_normal<2>
(
double
* phys_nodes_cut,
double
* level_set_normal)
17
{
18
const
unsigned
int
nSpace(2);
19
double
level_set_tangent[2];
20
for
(
unsigned
int
I=0; I < nSpace; I++)
21
{
22
level_set_tangent[I] = phys_nodes_cut[3+I] - phys_nodes_cut[I];
//nodes always 3D
23
}
24
level_set_normal[0] = level_set_tangent[1];
25
level_set_normal[1] = - level_set_tangent[0];
26
double
norm = std::sqrt(level_set_normal[0]*level_set_normal[0] +
27
level_set_normal[1]*level_set_normal[1]);
28
if
(norm > 0.0)
29
for
(
unsigned
int
I=0; I < nSpace; I++)
30
level_set_normal[I] /= norm;
31
else
32
{
33
for
(
unsigned
int
I=0; I < nSpace; I++)
34
level_set_normal[I] =0.0;
35
level_set_normal[1] = 1.0;
36
}
37
}
38
39
template
<>
40
inline
void
_calculate_normal<3>
(
double
* phys_nodes_cut,
double
* level_set_normal)
41
{
42
const
unsigned
int
nSpace(3);
43
double
level_set_tangent_a[3], level_set_tangent_b[3];
44
for
(
unsigned
int
I=0; I < nSpace; I++)
45
{
46
level_set_tangent_a[I] = phys_nodes_cut[3+I] - phys_nodes_cut[I];
47
level_set_tangent_b[I] = phys_nodes_cut[6+I] - phys_nodes_cut[I];
48
}
49
level_set_normal[0] = level_set_tangent_a[1]*level_set_tangent_b[2]
50
- level_set_tangent_a[2]*level_set_tangent_b[1];
51
level_set_normal[1] = - level_set_tangent_a[0]*level_set_tangent_b[2]
52
+ level_set_tangent_a[2]*level_set_tangent_b[0];
53
level_set_normal[2] = level_set_tangent_a[0]*level_set_tangent_b[1]
54
- level_set_tangent_a[1]*level_set_tangent_b[0];
55
double
norm = std::sqrt(level_set_normal[0]*level_set_normal[0] +
56
level_set_normal[1]*level_set_normal[1] +
57
level_set_normal[2]*level_set_normal[2]);
58
if
(norm > 0.0)
59
for
(
unsigned
int
I=0; I < nSpace; I++)
60
level_set_normal[I] /= norm;
61
else
62
{
63
for
(
unsigned
int
I=0; I < nSpace; I++)
64
level_set_normal[I] =0.0;
65
level_set_normal[2] =1.0;
66
}
67
assert(std::fabs(1.0-level_set_normal[0]*level_set_normal[0] - level_set_normal[1]*level_set_normal[1] - level_set_normal[2]*level_set_normal[2]) < 1.0e-8);
68
}
69
70
inline
void
_calculate_normal_quad
(
double
* phys_nodes_cut_quad_01,
71
double
* phys_nodes_cut_quad_02,
72
double
* phys_nodes_cut_quad_31,
73
double
* phys_nodes_cut_quad_32,
74
double
* level_set_normal)
75
{
76
const
unsigned
int
nSpace(3);
77
double
level_set_tangent_a[3], level_set_tangent_b[3], level_set_tangent_c[3], level_set_normal_2[3];
78
for
(
unsigned
int
I=0; I < nSpace; I++)
79
{
80
level_set_tangent_a[I] = phys_nodes_cut_quad_02[I] - phys_nodes_cut_quad_01[I];
81
level_set_tangent_b[I] = phys_nodes_cut_quad_32[I] - phys_nodes_cut_quad_01[I];
82
level_set_tangent_c[I] = phys_nodes_cut_quad_31[I] - phys_nodes_cut_quad_01[I];
83
}
84
level_set_normal[0] = level_set_tangent_a[1]*level_set_tangent_b[2] - level_set_tangent_a[2]*level_set_tangent_b[1];
85
level_set_normal[1] = - level_set_tangent_a[0]*level_set_tangent_b[2] + level_set_tangent_a[2]*level_set_tangent_b[0];
86
level_set_normal[2] = level_set_tangent_a[0]*level_set_tangent_b[1] - level_set_tangent_a[1]*level_set_tangent_b[0];
87
double
norm = std::sqrt(level_set_normal[0]*level_set_normal[0] +
88
level_set_normal[1]*level_set_normal[1] +
89
level_set_normal[2]*level_set_normal[2]);
90
if
(norm > 0.0)
91
{
92
for
(
unsigned
int
I=0; I < nSpace; I++)
93
level_set_normal[I] = level_set_normal[I] / norm;
94
}
95
else
96
{
97
for
(
unsigned
int
I=0; I < nSpace; I++)
98
level_set_normal[I] =0.0;
99
level_set_normal[2] = 1.0;
100
}
101
assert(std::fabs(1.0-level_set_normal[0]*level_set_normal[0] - level_set_normal[1]*level_set_normal[1] - level_set_normal[2]*level_set_normal[2]) < 1.0e-8);
102
}
103
104
template
<
int
nP>
105
inline
void
_calculate_polynomial_1D
(
double
* xi,
double
* C_H,
double
* C_ImH,
double
* C_D,
double
& _H,
double
& _ImH,
double
& _D)
106
{
107
_H = 0.0;
108
_ImH = 0.0;
109
_D = 0.0;
110
unsigned
int
iDOF = 0;
111
double
x_pow_i=1.0;
112
for
(
unsigned
int
i=0; i < nP+1; i++, iDOF++)
113
{
114
double
psi
=x_pow_i;
115
_H += C_H[iDOF]*
psi
;
116
_ImH += C_ImH[iDOF]*
psi
;
117
_D += C_D[iDOF]*
psi
;
118
x_pow_i *= xi[0];
119
}
120
}
121
122
// calculate_edge_H / evaluate_edge_poly: the SCIFEM edge-restricted moment-fit Heaviside
123
// (ADR.h's ifem_boundaries facet term). Not a duplicate of _calculate_polynomial_1D above,
124
// despite the similar Horner loop: that function EVALUATES an already-computed (C_H,C_ImH,C_D)
125
// triple for a genuinely 1D *element* (Simplex<1,...>); calculate_edge_H instead COMPUTES a
126
// single H-only fit (via _set_Ainv<1,nP>/_calculate_b<1,nP> from
127
// equivalent_polynomials_coefficients.h) for one *edge* of a 2D/3D element, with the
128
// orientation-safe sign handling a facet needs. Orientation-safe: returns the fit for the
129
// indicator of {phi > 0} whichever way round the edge is parametrized. phi0/phi1 must have
130
// opposite signs (the edge must actually be cut).
131
template
<
int
nP>
132
inline
void
calculate_edge_H
(
double
phi0,
double
phi1,
double
C_H[nP + 1])
133
{
134
double
theta = -phi0 / (phi1 - phi0);
135
double
Ainv[(nP + 1) * (nP + 1)];
136
_set_Ainv<1, nP>
(Ainv);
137
double
b_H[nP + 1], b_ImH[nP + 1], b_dH[nP + 1];
138
_calculate_b<1, nP>
(&theta, b_H, b_ImH, b_dH);
139
// _calculate_b assumes H=1 for t>theta (phi increasing along t); use the complementary
140
// moments when phi decreases instead, so C_H always fits the indicator of {phi>0}.
141
const
double
*b = (phi1 > phi0) ? b_H : b_ImH;
142
for
(
int
i = 0; i <= nP; i++)
143
{
144
C_H[i] = 0.0;
145
for
(
int
j = 0; j <= nP; j++)
146
C_H[i] += Ainv[i * (nP + 1) + j] * b[j];
147
}
148
}
149
150
template
<
int
nP>
151
inline
double
evaluate_edge_poly
(
const
double
C[nP + 1],
double
t)
152
{
153
double
val = 0.0, tpow = 1.0;
154
for
(
int
i = 0; i <= nP; i++)
155
{
156
val += C[i] * tpow;
157
tpow *= t;
158
}
159
return
val;
160
}
161
162
template
<
int
nP>
163
inline
void
_calculate_polynomial_2D
(
double
* xi,
double
* C_H,
double
* C_ImH,
double
* C_D,
double
& _H,
double
& _ImH,
double
& _D)
164
{
165
_H = 0.0;
166
_ImH = 0.0;
167
_D = 0.0;
168
unsigned
int
iDOF = 0;
169
double
x_pow_i=1.0;
170
for
(
unsigned
int
i=0; i < nP+1; i++)
171
{
172
double
y_pow_j=1.0;
173
for
(
unsigned
int
j=0; j < nP+1-i; j++, iDOF++)
174
{
175
double
psi
=x_pow_i*y_pow_j;
176
_H += C_H[iDOF]*
psi
;
177
_ImH += C_ImH[iDOF]*
psi
;
178
_D += C_D[iDOF]*
psi
;
179
y_pow_j *= xi[1];
180
}
181
x_pow_i *= xi[0];
182
}
183
}
184
185
template
<
int
nP>
186
inline
void
_calculate_polynomial_3D
(
double
* xi,
double
* C_H,
double
* C_ImH,
double
* C_D,
double
& _H,
double
& _ImH,
double
& _D)
187
{
188
_H = 0.0;
189
_ImH = 0.0;
190
_D = 0.0;
191
unsigned
int
iDOF = 0;
192
double
x_pow_i=1.0;
193
for
(
unsigned
int
i=0; i < nP+1; i++)
194
{
195
double
y_pow_j=1.0;
196
for
(
unsigned
int
j=0; j < nP+1-i; j++)
197
{
198
double
x_pow_i_y_pow_j=x_pow_i*y_pow_j, z_pow_k=1.0;
199
for
(
unsigned
int
k=0; k < nP+1-i-j; k++, iDOF++)
200
{
201
double
psi
=x_pow_i_y_pow_j*z_pow_k;
202
_H += C_H[iDOF]*
psi
;
203
_ImH += C_ImH[iDOF]*
psi
;
204
_D += C_D[iDOF]*
psi
;
205
z_pow_k *= xi[2];
206
}
207
y_pow_j *= xi[1];
208
}
209
x_pow_i *= xi[0];
210
}
211
}
212
213
const
int
XX
(0),
XY
(1),
XZ
(2),
YX
(3),
YY
(4),
YZ
(5),
ZX
(6),
ZY
(7),
ZZ
(8);
214
215
template
<
int
nSpace>
216
inline
double
det
(
const
double
* A);
217
218
template
<>
219
inline
double
det<1>
(
const
double
* A)
220
{
221
return
A[0];
222
}
223
224
template
<>
225
inline
double
det<2>
(
const
double
* A)
226
{
227
return
A[0]*A[3] - A[1]*A[2];
228
}
229
230
template
<>
231
inline
double
det<3>
(
const
double
* A)
232
{
233
return
A[
XX
]*(A[
YY
]*A[
ZZ
] - A[
YZ
]*A[
ZY
]) -
234
A[
XY
]*(A[
YX
]*A[
ZZ
] - A[
YZ
]*A[
ZX
]) +
235
A[
XZ
]*(A[
YX
]*A[
ZY
] - A[
YY
]*A[
ZX
]);
236
}
237
238
template
<
int
nSpace>
239
inline
void
inv
(
const
double
* A,
double
* Ainv);
240
241
template
<>
242
inline
void
inv<1>
(
const
double
* A,
double
* Ainv)
243
{
244
Ainv[0] = 1.0/A[0];
245
}
246
247
template
<>
248
inline
void
inv<2>
(
const
double
* A,
double
* Ainv)
249
{
250
double
oneOverDet = 1.0/
det<2>
(A);
251
Ainv[0] = oneOverDet*A[3];
252
Ainv[1] = -oneOverDet*A[1];
253
Ainv[2] = -oneOverDet*A[2];
254
Ainv[3] = oneOverDet*A[0];
255
assert(fabs(Ainv[0]*A[0]+Ainv[1]*A[2]-1.0) < 1.0e-10);
256
assert(fabs(Ainv[0]*A[1]+Ainv[1]*A[3]) < 1.0e-10);
257
assert(fabs(Ainv[2]*A[0]+Ainv[3]*A[2]) < 1.0e-10);
258
assert(fabs(Ainv[2]*A[1]+Ainv[3]*A[3]-1.0) < 1.0e-10);
259
}
260
261
template
<>
262
inline
void
inv<3>
(
const
double
* A,
double
* Ainv)
263
{
264
double
oneOverDet = 1.0/
det<3>
(A);
265
Ainv[
XX
] = oneOverDet*(A[
YY
]*A[
ZZ
] - A[
YZ
]*A[
ZY
]);
266
Ainv[
YX
] = oneOverDet*(A[
YZ
]*A[
ZX
] - A[
YX
]*A[
ZZ
]);
267
Ainv[
ZX
] = oneOverDet*(A[
YX
]*A[
ZY
] - A[
YY
]*A[
ZX
]);
268
Ainv[
XY
] = oneOverDet*(A[
ZY
]*A[
XZ
] - A[
ZZ
]*A[
XY
]);
269
Ainv[
YY
] = oneOverDet*(A[
ZZ
]*A[
XX
] - A[
ZX
]*A[
XZ
]);
270
Ainv[
ZY
] = oneOverDet*(A[
ZX
]*A[
XY
] - A[
ZY
]*A[
XX
]);
271
Ainv[
XZ
] = oneOverDet*(A[
XY
]*A[
YZ
] - A[
XZ
]*A[
YY
]);
272
Ainv[
YZ
] = oneOverDet*(A[
XZ
]*A[
YX
] - A[
XX
]*A[
YZ
]);
273
Ainv[
ZZ
] = oneOverDet*(A[
XX
]*A[
YY
] - A[
XY
]*A[
YX
]);
274
}
275
}
//equivalent_polynomials
276
#endif
psi
Double psi
Definition
Headers.h:78
equivalent_polynomials
Definition
equivalent_polynomials.h:16
equivalent_polynomials::XZ
const int XZ(2)
equivalent_polynomials::_calculate_polynomial_2D
void _calculate_polynomial_2D(double *xi, double *C_H, double *C_ImH, double *C_D, double &_H, double &_ImH, double &_D)
Definition
equivalent_polynomials_utils.h:163
equivalent_polynomials::inv
void inv(const double *A, double *Ainv)
equivalent_polynomials::_calculate_normal_quad
void _calculate_normal_quad(double *phys_nodes_cut_quad_01, double *phys_nodes_cut_quad_02, double *phys_nodes_cut_quad_31, double *phys_nodes_cut_quad_32, double *level_set_normal)
Definition
equivalent_polynomials_utils.h:70
equivalent_polynomials::evaluate_edge_poly
double evaluate_edge_poly(const double C[nP+1], double t)
Definition
equivalent_polynomials_utils.h:151
equivalent_polynomials::_calculate_polynomial_1D
void _calculate_polynomial_1D(double *xi, double *C_H, double *C_ImH, double *C_D, double &_H, double &_ImH, double &_D)
Definition
equivalent_polynomials_utils.h:105
equivalent_polynomials::XY
const int XY(1)
equivalent_polynomials::ZY
const int ZY(7)
equivalent_polynomials::YY
const int YY(4)
equivalent_polynomials::calculate_edge_H
void calculate_edge_H(double phi0, double phi1, double C_H[nP+1])
Definition
equivalent_polynomials_utils.h:132
equivalent_polynomials::det
double det(const double *A)
equivalent_polynomials::ZZ
const int ZZ(8)
equivalent_polynomials::_set_Ainv
void _set_Ainv(double *Ainv)
equivalent_polynomials::_calculate_polynomial_3D
void _calculate_polynomial_3D(double *xi, double *C_H, double *C_ImH, double *C_D, double &_H, double &_ImH, double &_D)
Definition
equivalent_polynomials_utils.h:186
equivalent_polynomials::XX
const int XX(0)
equivalent_polynomials::_calculate_normal
void _calculate_normal(double *phys_nodes_cut, double *level_set_normal)
equivalent_polynomials::YZ
const int YZ(5)
equivalent_polynomials::_calculate_b
void _calculate_b(double *X_0, double *b_H, double *b_ImH, double *b_dH)
equivalent_polynomials::YX
const int YX(3)
equivalent_polynomials::ZX
const int ZX(6)
Generated on
for proteus by
1.18.0