7
7
8
8
9
9
def dot (u , v , x : list , a : list , b : list ):
10
- assert (len (a ) == len (b ) == len (x ))
10
+ assert (len (a ) == len (b ) == len (x ))
11
11
I = u * v
12
12
for i in reversed (range (len (a ))):
13
13
I = sp .integrate (I , (x [i ], a [i ], b [i ])).expand ()
@@ -44,19 +44,22 @@ def orthonormalized_basis(dims, order, x, a, b):
44
44
V = []
45
45
if dims == 1 :
46
46
# Generate the monomial basis
47
- Vl = sorted (itermonomials (x , order ), key = monomial_key ('grlex' , list (reversed (x ))))
47
+ Vl = sorted (itermonomials (x , order ),
48
+ key = monomial_key ('grlex' , list (reversed (x ))))
48
49
# Orthonormalize the line's polynomial basis
49
50
Vlo = gram_schmidt (Vl , x , a , b )
50
51
V = normalize (Vlo , x , a , b )
51
52
if dims == 2 :
52
53
# Generate the monomial basis
53
- Vf = sorted (itermonomials (x , order ), key = monomial_key ('grlex' , list (reversed (x ))))
54
+ Vf = sorted (itermonomials (x , order ),
55
+ key = monomial_key ('grlex' , list (reversed (x ))))
54
56
# Orthonormalize the triangle's polynomial basis'
55
57
Vfo = gram_schmidt (Vf , x , a , b )
56
58
V = normalize (Vfo , x , a , b )
57
59
if dims == 3 :
58
60
# Generate the monomial basis
59
- Vt = sorted (itermonomials (x , order ), key = monomial_key ('grlex' , list (reversed (x ))))
61
+ Vt = sorted (itermonomials (x , order ),
62
+ key = monomial_key ('grlex' , list (reversed (x ))))
60
63
# Orthonormalize the tetrahedron's polynomial basis'
61
64
Vto = gram_schmidt (Vt , x , a , b )
62
65
V = normalize (Vto , x , a , b )
@@ -88,11 +91,11 @@ def divergence_free_basis(V: list, dims: int, x: list, a: list, b: list):
88
91
H = sp .Matrix .zeros (len (V ), dims * len (V ))
89
92
for n in range (len (G )):
90
93
gn = G [n ]
91
- assert (len (gn ) == len (x ))
94
+ assert (len (gn ) == len (x ))
92
95
div = divergence (gn , x )
93
96
# Compute the coefficients of div(gn) w.r.t. orthonormal basis V
94
97
for i in range (len (V )):
95
- H [i ,n ] = dot (div , V [i ], x , a , b )
98
+ H [i , n ] = dot (div , V [i ], x , a , b )
96
99
97
100
HN = H .nullspace ()
98
101
GG = sp .Matrix (G ).transpose ()
@@ -102,12 +105,13 @@ def divergence_free_basis(V: list, dims: int, x: list, a: list, b: list):
102
105
F .append (sp .simplify (fi ))
103
106
for fi in F :
104
107
div = sp .simplify (divergence (fi , x ))
105
- assert (div == 0 )
108
+ assert (div == 0 )
106
109
return F
107
110
111
+
108
112
def header (file ):
109
113
file .write (
110
- """#ifndef PBAT_MATH_POLYNOMIAL_BASIS_H
114
+ """#ifndef PBAT_MATH_POLYNOMIAL_BASIS_H
111
115
#define PBAT_MATH_POLYNOMIAL_BASIS_H
112
116
113
117
/**
@@ -137,16 +141,17 @@ class DivergenceFreePolynomialBasis;
137
141
"""
138
142
)
139
143
144
+
140
145
def footer (file ):
141
146
file .write (
142
- """
147
+ """
143
148
} // namespace math
144
149
} // namespace pbat
145
150
146
151
#endif // PBAT_MATH_POLYNOMIAL_BASIS_H
147
152
"""
148
153
)
149
-
154
+
150
155
151
156
def codegen (file , V : list , X : list , order : int , orthonormal = False ):
152
157
dimV = len (V )
@@ -157,10 +162,11 @@ def codegen(file, V: list, X: list, order: int, orthonormal=False):
157
162
code = cg .codegen (V , lhs = sp .MatrixSymbol ("P" , len (V ), 1 ))
158
163
GV = V .jacobian (X )
159
164
jaccode = cg .codegen (GV , lhs = sp .MatrixSymbol ("G" , * GV .shape ))
160
- AV = sp .Matrix ([[sp .integrate (V [i ], X [d ]) for i in range (len (V ))] for d in range (len (X ))])
165
+ AV = sp .Matrix ([[sp .integrate (V [i ], X [d ])
166
+ for i in range (len (V ))] for d in range (len (X ))])
161
167
antiderivscode = cg .codegen (AV , lhs = sp .MatrixSymbol ("P" , * AV .shape ))
162
168
file .write (
163
- f"""
169
+ f"""
164
170
template <>
165
171
class { classname } <{ nvariables } , { order } >
166
172
{{
@@ -169,21 +175,21 @@ class {classname}<{nvariables}, {order}>
169
175
inline static constexpr std::size_t kOrder = { order } ;
170
176
inline static constexpr std::size_t kSize = { dimV } ;
171
177
172
- [[maybe_unused]] Vector<kSize> eval([[maybe_unused]] Vector<kDims> const& X) const
178
+ [[maybe_unused]] Vector<kSize> eval([[maybe_unused]] Vector<kDims> const& X) const
173
179
{{
174
180
Vector<kSize> P;
175
181
{ cg .tabulate (code , spaces = 8 )}
176
182
return P;
177
- }}
178
-
183
+ }}
184
+
179
185
[[maybe_unused]] Matrix<kDims, kSize> derivatives([[maybe_unused]] Vector<kDims> const& X) const
180
186
{{
181
187
Matrix<kDims, kSize> Gm;
182
188
Scalar* G = Gm.data();
183
189
{ cg .tabulate (jaccode , spaces = 8 )}
184
190
return Gm;
185
191
}}
186
-
192
+
187
193
[[maybe_unused]] Matrix<kSize, kDims> antiderivatives([[maybe_unused]] Vector<kDims> const& X) const
188
194
{{
189
195
Matrix<kSize, kDims> Pm;
@@ -202,7 +208,7 @@ def div_free_codegen(file, F: list, X: list, order: int):
202
208
F = sp .Matrix (F ).transpose ()
203
209
code = cg .codegen (F , lhs = sp .MatrixSymbol ("P" , * F .shape ))
204
210
file .write (
205
- f"""
211
+ f"""
206
212
template <>
207
213
class { classname } <{ nvariables } , { order } >
208
214
{{
@@ -211,7 +217,7 @@ class {classname}<{nvariables}, {order}>
211
217
inline static constexpr std::size_t kOrder = { order } ;
212
218
inline static constexpr std::size_t kSize = { dimF } ;
213
219
214
- [[maybe_unused]] Matrix<kSize, kDims> eval([[maybe_unused]] Vector<kDims> const& X) const
220
+ [[maybe_unused]] Matrix<kSize, kDims> eval([[maybe_unused]] Vector<kDims> const& X) const
215
221
{{
216
222
Matrix<kSize, kDims> Pm;
217
223
Scalar* P = Pm.data();
@@ -221,6 +227,7 @@ class {classname}<{nvariables}, {order}>
221
227
}};
222
228
""" )
223
229
230
+
224
231
if __name__ == "__main__" :
225
232
X = sp .Matrix (sp .MatrixSymbol ("X" , 3 , 1 ))
226
233
@@ -230,7 +237,8 @@ class {classname}<{nvariables}, {order}>
230
237
)
231
238
parser .add_argument ("-o" , "--order" , help = "Maximum degree of the polynomial basis functions" , type = int ,
232
239
dest = "order" , default = 1 )
233
- parser .add_argument ("-d" , "--dry-run" , help = "Prints computed polynomial basis' to stdout" , type = bool , dest = "dry_run" )
240
+ parser .add_argument ("-d" , "--dry-run" , help = "Prints computed polynomial basis' to stdout" ,
241
+ action = "store_true" , dest = "dry_run" )
234
242
args = parser .parse_args ()
235
243
236
244
# polynomial order
@@ -261,7 +269,7 @@ class {classname}<{nvariables}, {order}>
261
269
for v in Vfo :
262
270
print (v )
263
271
264
- Vto = orthonormalized_basis (2 , order , xt , ta , tb )
272
+ Vto = orthonormalized_basis (3 , order , xt , ta , tb )
265
273
print ("Orthonormal Polynomial Basis of order={} on the reference tetrahedron" .format (order ))
266
274
for v in Vto :
267
275
print (v )
@@ -270,61 +278,70 @@ class {classname}<{nvariables}, {order}>
270
278
header (file )
271
279
272
280
file .write ("\n /**\n * Monomial basis in 1D\n */\n " )
273
- for o in range (order ):
274
- V = sorted (itermonomials (xl , o + 1 ), key = monomial_key ('lex' , list (reversed (xl ))))
275
- codegen (file , V , xl , o + 1 )
281
+ for o in range (order + 2 ):
282
+ V = sorted (itermonomials (xl , o ),
283
+ key = monomial_key ('lex' , list (reversed (xl ))))
284
+ codegen (file , V , xl , o )
276
285
file .write ("\n /**\n * Monomial basis in 2D\n */\n " )
277
- for o in range (order ):
278
- V = sorted (itermonomials (xf , o + 1 ), key = monomial_key ('lex' , list (reversed (xf ))))
279
- codegen (file , V , xf , o + 1 )
286
+ for o in range (order + 2 ):
287
+ V = sorted (itermonomials (xf , o ),
288
+ key = monomial_key ('lex' , list (reversed (xf ))))
289
+ codegen (file , V , xf , o )
280
290
file .write ("\n /**\n * Monomial basis in 3D\n */\n " )
281
- for o in range (order ):
282
- V = sorted (itermonomials (xt , o + 1 ), key = monomial_key ('lex' , list (reversed (xt ))))
283
- codegen (file , V , xt , o + 1 )
291
+ for o in range (order + 1 ):
292
+ V = sorted (itermonomials (xt , o ),
293
+ key = monomial_key ('lex' , list (reversed (xt ))))
294
+ codegen (file , V , xt , o )
284
295
285
296
Vl = []
286
297
dVl = []
287
- for o in range (order ):
288
- V = orthonormalized_basis (1 ,o + 1 , xl , la , lb )
298
+ for o in range (order + 1 ):
299
+ V = orthonormalized_basis (1 , o , xl , la , lb )
289
300
Vl .append (V )
290
301
dVl .append (divergence_free_basis (V , 1 , xl , la , lb ))
291
302
292
303
Vf = []
293
304
dVf = []
294
- for o in range (order ):
295
- V = orthonormalized_basis (2 ,o + 1 , xf , fa , fb )
305
+ for o in range (order + 1 ):
306
+ V = orthonormalized_basis (2 , o , xf , fa , fb )
296
307
Vf .append (V )
297
308
dVf .append (divergence_free_basis (V , 2 , xf , fa , fb ))
298
309
299
310
Vt = []
300
311
dVt = []
301
- for o in range (order ):
302
- V = orthonormalized_basis (3 ,o + 1 , xt , ta , tb )
312
+ for o in range (order + 1 ):
313
+ V = orthonormalized_basis (3 , o , xt , ta , tb )
303
314
Vt .append (V )
304
315
dVt .append (divergence_free_basis (V , 3 , xt , ta , tb ))
305
316
306
- file .write ("\n /**\n * Orthonormalized polynomial basis on reference line\n */\n " )
307
- for o in range (order ):
308
- codegen (file , Vl [o ], xl , o + 1 , orthonormal = True )
309
-
310
- file .write ("\n /**\n * Orthonormalized polynomial basis on reference triangle\n */\n " )
311
- for o in range (order ):
312
- codegen (file , Vf [o ], xf , o + 1 , orthonormal = True )
313
-
314
- file .write ("\n /**\n * Orthonormalized polynomial basis on reference tetrahedron\n */\n " )
315
- for o in range (order ):
316
- codegen (file , Vt [o ], xt , o + 1 , orthonormal = True )
317
-
318
- file .write ("\n /**\n * Divergence free polynomial basis on reference line\n */\n " )
319
- for o in range (order ):
320
- div_free_codegen (file , dVl [o ], xl , o + 1 )
321
-
322
- file .write ("\n /**\n * Divergence free polynomial basis on reference triangle\n */\n " )
323
- for o in range (order ):
324
- div_free_codegen (file , dVf [o ], xf , o + 1 )
325
-
326
- file .write ("\n /**\n * Divergence free polynomial basis on reference tetrahedron\n */\n " )
327
- for o in range (order ):
328
- div_free_codegen (file , dVt [o ], xt , o + 1 )
317
+ file .write (
318
+ "\n /**\n * Orthonormalized polynomial basis on reference line\n */\n " )
319
+ for o in range (order + 1 ):
320
+ codegen (file , Vl [o ], xl , o , orthonormal = True )
321
+
322
+ file .write (
323
+ "\n /**\n * Orthonormalized polynomial basis on reference triangle\n */\n " )
324
+ for o in range (order + 1 ):
325
+ codegen (file , Vf [o ], xf , o , orthonormal = True )
326
+
327
+ file .write (
328
+ "\n /**\n * Orthonormalized polynomial basis on reference tetrahedron\n */\n " )
329
+ for o in range (order + 1 ):
330
+ codegen (file , Vt [o ], xt , o , orthonormal = True )
331
+
332
+ file .write (
333
+ "\n /**\n * Divergence free polynomial basis on reference line\n */\n " )
334
+ for o in range (order + 1 ):
335
+ div_free_codegen (file , dVl [o ], xl , o )
336
+
337
+ file .write (
338
+ "\n /**\n * Divergence free polynomial basis on reference triangle\n */\n " )
339
+ for o in range (order + 1 ):
340
+ div_free_codegen (file , dVf [o ], xf , o )
341
+
342
+ file .write (
343
+ "\n /**\n * Divergence free polynomial basis on reference tetrahedron\n */\n " )
344
+ for o in range (order + 1 ):
345
+ div_free_codegen (file , dVt [o ], xt , o )
329
346
330
347
footer (file )
0 commit comments