17
17
get_quadrature_element ,
18
18
vector_to_tensor ,
19
19
)
20
+ import mgis .behaviour as mgis_bv
20
21
21
22
22
23
class QuadratureFunction :
23
24
"""An abstract class for functions defined at quadrature points"""
24
- def __init__ (self , name , shape ):
25
+
26
+ def __init__ (self , name , shape , hypothesis ):
25
27
self .shape = shape
26
28
self .name = name
29
+ self .hypothesis = hypothesis
27
30
28
31
def initialize_function (self , mesh , quadrature_degree ):
29
32
self .quadrature_degree = quadrature_degree
30
33
self .mesh = mesh
31
- self .dx = Measure ("dx" ,
32
- metadata = {"quadrature_degree" : quadrature_degree })
33
- We = get_quadrature_element (mesh .ufl_cell (), quadrature_degree ,
34
- self .shape )
34
+ self .dx = Measure ("dx" , metadata = {"quadrature_degree" : quadrature_degree })
35
+ We = get_quadrature_element (mesh .ufl_cell (), quadrature_degree , self .shape )
35
36
self .function_space = FunctionSpace (mesh , We )
36
37
self .function = Function (self .function_space , name = self .name )
37
38
@@ -64,12 +65,13 @@ def project_on(self, space, degree, as_tensor=False, **kwargs):
64
65
V = VectorFunctionSpace (self .mesh , space , degree , dim = self .shape )
65
66
v = Function (V , name = self .name )
66
67
v .assign (
67
- project (fun ,
68
- V ,
69
- form_compiler_parameters = {
70
- "quadrature_degree" : self .quadrature_degree
71
- },
72
- ** kwargs ))
68
+ project (
69
+ fun ,
70
+ V ,
71
+ form_compiler_parameters = {"quadrature_degree" : self .quadrature_degree },
72
+ ** kwargs
73
+ )
74
+ )
73
75
return v
74
76
75
77
@@ -87,26 +89,45 @@ class Gradient(QuadratureFunction):
87
89
This class is intended for internal use only. Gradient objects must be
88
90
declared by the user using the registration concept.
89
91
"""
90
- def __init__ (self , variable , expression , name , symmetric = None ):
92
+
93
+ def __init__ (self , variable , expression , name , hypothesis , symmetric = None ):
91
94
self .variable = variable
92
95
if symmetric is None :
93
96
self .expression = expression
94
97
# TODO: treat axisymmetric case
95
- elif symmetric :
96
- if ufl .shape (expression ) == (2 , 2 ):
97
- self .expression = as_vector ([
98
- symmetric_tensor_to_vector (expression )[i ] for i in range (4 )
99
- ])
100
- else :
101
- self .expression = symmetric_tensor_to_vector (expression )
102
98
else :
103
- if ufl .shape (expression ) == (2 , 2 ):
104
- self .expression = as_vector ([
105
- nonsymmetric_tensor_to_vector (expression )[i ]
106
- for i in range (5 )
107
- ])
99
+ if symmetric :
100
+ converter = symmetric_tensor_to_vector
108
101
else :
109
- self .expression = nonsymmetric_tensor_to_vector (expression )
102
+ converter = nonsymmetric_tensor_to_vector
103
+ if hypothesis in [
104
+ mgis_bv .Hypothesis .PlaneStrain ,
105
+ mgis_bv .Hypothesis .Axisymmetrical ,
106
+ ]:
107
+ if ufl .shape (expression ) == (2 , 2 ):
108
+ T22 = 0
109
+ expression_2d = expression
110
+ elif ufl .shape (expression ) == (3 , 3 ):
111
+ T22 = expression [2 , 2 ]
112
+ expression_2d = ufl .as_tensor (
113
+ [[expression [i , j ] for j in range (2 )] for i in range (2 )]
114
+ )
115
+ self .expression = converter (expression_2d , T22 )
116
+ else :
117
+ self .expression = converter (expression )
118
+
119
+ # self.expression = as_vector(
120
+ # [converter(expression)[i] for i in range(4)]
121
+ # )
122
+ # else:
123
+ # self.expression = symmetric_tensor_to_vector(expression)
124
+ # else:
125
+ # if ufl.shape(expression) == (2, 2):
126
+ # self.expression = as_vector(
127
+ # [nonsymmetric_tensor_to_vector(expression)[i] for i in range(5)]
128
+ # )
129
+ # else:
130
+ # self.expression = nonsymmetric_tensor_to_vector(expression)
110
131
shape = ufl .shape (self .expression )
111
132
if len (shape ) == 1 :
112
133
self .shape = shape [0 ]
@@ -115,17 +136,20 @@ def __init__(self, variable, expression, name, symmetric=None):
115
136
else :
116
137
self .shape = shape
117
138
self .name = name
139
+ self .hypothesis = hypothesis
118
140
119
141
def __call__ (self , v ):
120
142
return ufl .replace (self .expression , {self .variable : v })
121
143
122
144
def variation (self , v ):
123
145
""" Directional derivative in direction v """
124
146
# return ufl.algorithms.expand_derivatives(ufl.derivative(self.expression, self.variable, v))
125
- deriv = sum ([
126
- ufl .derivative (self .expression , var , v_ )
127
- for (var , v_ ) in zip (split (self .variable ), split (v ))
128
- ])
147
+ deriv = sum (
148
+ [
149
+ ufl .derivative (self .expression , var , v_ )
150
+ for (var , v_ ) in zip (split (self .variable ), split (v ))
151
+ ]
152
+ )
129
153
return ufl .algorithms .expand_derivatives (deriv )
130
154
131
155
def initialize_function (self , mesh , quadrature_degree ):
@@ -148,15 +172,17 @@ def _evaluate_at_quadrature_points(self, x):
148
172
149
173
class Var (Gradient ):
150
174
""" A simple variable """
151
- def __init__ (self , variable , expression , name ):
152
- Gradient .__init__ (self , variable , expression , name )
175
+
176
+ def __init__ (self , variable , expression , name , hypothesis ):
177
+ Gradient .__init__ (self , variable , expression , name , hypothesis )
153
178
154
179
def _evaluate_at_quadrature_points (self , x ):
155
180
local_project (x , self .function_space , self .dx , self .function )
156
181
157
182
158
183
class QuadratureFunctionTangentBlocks (QuadratureFunction ):
159
184
"""An abstract class for Flux and InternalStateVariables"""
185
+
160
186
def initialize_tangent_blocks (self , variables ):
161
187
self .variables = variables
162
188
values = [
@@ -170,7 +196,8 @@ def initialize_tangent_blocks(self, variables):
170
196
),
171
197
),
172
198
name = "d{}_d{}" .format (self .name , v .name ),
173
- ) for v in self .variables
199
+ )
200
+ for v in self .variables
174
201
]
175
202
keys = [v .name for v in self .variables ]
176
203
self .tangent_blocks = dict (zip (keys , values ))
0 commit comments