14
14
15
15
from itertools import chain
16
16
import numpy
17
- import sympy
18
17
19
18
from FIAT import polynomial_set , jacobi , quadrature_schemes
20
19
@@ -58,9 +57,7 @@ def __init__(self, ref_el, target_shape, pt_dict, deriv_dict,
58
57
self .deriv_dict = deriv_dict
59
58
self .functional_type = functional_type
60
59
if len (deriv_dict ) > 0 :
61
- per_point = list (chain (* deriv_dict .values ()))
62
- alphas = [tuple (foo [1 ]) for foo in per_point ]
63
- self .max_deriv_order = max ([sum (foo ) for foo in alphas ])
60
+ self .max_deriv_order = max (sum (wac [1 ]) for wac in chain (* deriv_dict .values ()))
64
61
else :
65
62
self .max_deriv_order = 0
66
63
@@ -213,6 +210,7 @@ def __init__(self, ref_el, x, alpha):
213
210
def __call__ (self , fn ):
214
211
"""Evaluate the functional on the function fn. Note that this depends
215
212
on sympy being able to differentiate fn."""
213
+ import sympy
216
214
x , = self .deriv_dict
217
215
218
216
X = tuple (sympy .Symbol (f"X[{ i } ]" ) for i in range (len (x )))
@@ -224,28 +222,33 @@ def __call__(self, fn):
224
222
return df (* x )
225
223
226
224
227
- class PointNormalDerivative (Functional ):
225
+ class PointDirectionalDerivative (Functional ):
226
+ """Represents d/ds at a point."""
227
+ def __init__ (self , ref_el , s , pt , comp = (), shp = (), nm = None ):
228
+ sd = ref_el .get_spatial_dimension ()
229
+ alphas = tuple (map (tuple , numpy .eye (sd , dtype = int )))
230
+ dpt_dict = {pt : [(s [i ], tuple (alphas [i ]), comp ) for i in range (sd )]}
231
+
232
+ super ().__init__ (ref_el , shp , {}, dpt_dict , nm or "PointDirectionalDeriv" )
233
+
234
+
235
+ class PointNormalDerivative (PointDirectionalDerivative ):
228
236
"""Represents d/dn at a point on a facet."""
229
- def __init__ (self , ref_el , facet_no , pt ):
237
+ def __init__ (self , ref_el , facet_no , pt , comp = (), shp = () ):
230
238
n = ref_el .compute_normal (facet_no )
231
- self .n = n
232
- sd = ref_el .get_spatial_dimension ()
239
+ super ().__init__ (ref_el , n , pt , comp = comp , shp = shp , nm = "PointNormalDeriv" )
233
240
234
- alphas = []
235
- for i in range (sd ):
236
- alpha = [0 ] * sd
237
- alpha [i ] = 1
238
- alphas .append (alpha )
239
- dpt_dict = {pt : [(n [i ], tuple (alphas [i ]), tuple ()) for i in range (sd )]}
240
241
241
- super ().__init__ (ref_el , tuple (), {}, dpt_dict , "PointNormalDeriv" )
242
+ class PointTangentialDerivative (PointDirectionalDerivative ):
243
+ """Represents d/dt at a point on an edge."""
244
+ def __init__ (self , ref_el , edge_no , pt , comp = (), shp = ()):
245
+ t = ref_el .compute_edge_tangent (edge_no )
246
+ super ().__init__ (ref_el , t , pt , comp = comp , shp = shp , nm = "PointTangentialDeriv" )
242
247
243
248
244
- class PointNormalSecondDerivative (Functional ):
245
- """Represents d^/dn^2 at a point on a facet."""
246
- def __init__ (self , ref_el , facet_no , pt ):
247
- n = ref_el .compute_normal (facet_no )
248
- self .n = n
249
+ class PointSecondDerivative (Functional ):
250
+ """Represents d/ds1 d/ds2 at a point."""
251
+ def __init__ (self , ref_el , s1 , s2 , pt , comp = (), shp = (), nm = None ):
249
252
sd = ref_el .get_spatial_dimension ()
250
253
tau = numpy .zeros ((sd * (sd + 1 )// 2 ,))
251
254
@@ -257,14 +260,26 @@ def __init__(self, ref_el, facet_no, pt):
257
260
alpha [i ] += 1
258
261
alpha [j ] += 1
259
262
alphas .append (tuple (alpha ))
260
- tau [cur ] = n [i ]* n [j ]
263
+ tau [cur ] = s1 [i ] * s2 [ j ] + ( i != j ) * s2 [ i ] * s1 [j ]
261
264
cur += 1
262
265
263
- self .tau = tau
264
- self .alphas = alphas
265
- dpt_dict = {pt : [(n [i ], alphas [i ], tuple ()) for i in range (sd )]}
266
+ dpt_dict = {tuple (pt ): [(tau [i ], alphas [i ], comp ) for i in range (len (alphas ))]}
267
+
268
+ super ().__init__ (ref_el , shp , {}, dpt_dict , nm or "PointSecondDeriv" )
269
+
270
+
271
+ class PointNormalSecondDerivative (PointSecondDerivative ):
272
+ """Represents d^/dn^2 at a point on a facet."""
273
+ def __init__ (self , ref_el , facet_no , pt , comp = (), shp = ()):
274
+ n = ref_el .compute_normal (facet_no )
275
+ super ().__init__ (ref_el , n , n , pt , comp = comp , shp = shp , nm = "PointNormalSecondDeriv" )
266
276
267
- super ().__init__ (ref_el , tuple (), {}, dpt_dict , "PointNormalDeriv" )
277
+
278
+ class PointTangentialSecondDerivative (PointSecondDerivative ):
279
+ """Represents d^/dt^2 at a point on an edge."""
280
+ def __init__ (self , ref_el , edge_no , pt , comp = (), shp = ()):
281
+ t = ref_el .compute_edge_tangent (edge_no )
282
+ super ().__init__ (ref_el , t , t , pt , comp = comp , shp = shp , nm = "PointTangentialSecondDeriv" )
268
283
269
284
270
285
class PointDivergence (Functional ):
@@ -311,6 +326,26 @@ def __call__(self, fn):
311
326
return result
312
327
313
328
329
+ class IntegralMomentOfDerivative (Functional ):
330
+ """Functional giving directional derivative integrated against some function on a facet."""
331
+
332
+ def __init__ (self , ref_el , s , Q , f_at_qpts , comp = (), shp = ()):
333
+ self .f_at_qpts = f_at_qpts
334
+ self .Q = Q
335
+
336
+ sd = ref_el .get_spatial_dimension ()
337
+
338
+ points = Q .get_points ()
339
+ weights = numpy .multiply (f_at_qpts , Q .get_weights ())
340
+
341
+ alphas = tuple (map (tuple , numpy .eye (sd , dtype = int )))
342
+ dpt_dict = {tuple (pt ): [(wt * s [i ], alphas [i ], comp ) for i in range (sd )]
343
+ for pt , wt in zip (points , weights )}
344
+
345
+ super ().__init__ (ref_el , shp ,
346
+ {}, dpt_dict , "IntegralMomentOfDerivative" )
347
+
348
+
314
349
class IntegralMomentOfNormalDerivative (Functional ):
315
350
"""Functional giving normal derivative integrated against some function on a facet."""
316
351
0 commit comments