Skip to content

Commit fe4ec92

Browse files
committed
Handle tensor/vector repr in 2D and axisymmetric cases
1 parent 42609e3 commit fe4ec92

File tree

3 files changed

+309
-248
lines changed

3 files changed

+309
-248
lines changed

Diff for: bindings/python/mgis/fenics/gradient_flux.py

+59-32
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,22 @@
1717
get_quadrature_element,
1818
vector_to_tensor,
1919
)
20+
import mgis.behaviour as mgis_bv
2021

2122

2223
class QuadratureFunction:
2324
"""An abstract class for functions defined at quadrature points"""
24-
def __init__(self, name, shape):
25+
26+
def __init__(self, name, shape, hypothesis):
2527
self.shape = shape
2628
self.name = name
29+
self.hypothesis = hypothesis
2730

2831
def initialize_function(self, mesh, quadrature_degree):
2932
self.quadrature_degree = quadrature_degree
3033
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)
3536
self.function_space = FunctionSpace(mesh, We)
3637
self.function = Function(self.function_space, name=self.name)
3738

@@ -64,12 +65,13 @@ def project_on(self, space, degree, as_tensor=False, **kwargs):
6465
V = VectorFunctionSpace(self.mesh, space, degree, dim=self.shape)
6566
v = Function(V, name=self.name)
6667
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+
)
7375
return v
7476

7577

@@ -87,26 +89,45 @@ class Gradient(QuadratureFunction):
8789
This class is intended for internal use only. Gradient objects must be
8890
declared by the user using the registration concept.
8991
"""
90-
def __init__(self, variable, expression, name, symmetric=None):
92+
93+
def __init__(self, variable, expression, name, hypothesis, symmetric=None):
9194
self.variable = variable
9295
if symmetric is None:
9396
self.expression = expression
9497
# 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)
10298
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
108101
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)
110131
shape = ufl.shape(self.expression)
111132
if len(shape) == 1:
112133
self.shape = shape[0]
@@ -115,17 +136,20 @@ def __init__(self, variable, expression, name, symmetric=None):
115136
else:
116137
self.shape = shape
117138
self.name = name
139+
self.hypothesis = hypothesis
118140

119141
def __call__(self, v):
120142
return ufl.replace(self.expression, {self.variable: v})
121143

122144
def variation(self, v):
123145
""" Directional derivative in direction v """
124146
# 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+
)
129153
return ufl.algorithms.expand_derivatives(deriv)
130154

131155
def initialize_function(self, mesh, quadrature_degree):
@@ -148,15 +172,17 @@ def _evaluate_at_quadrature_points(self, x):
148172

149173
class Var(Gradient):
150174
""" 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)
153178

154179
def _evaluate_at_quadrature_points(self, x):
155180
local_project(x, self.function_space, self.dx, self.function)
156181

157182

158183
class QuadratureFunctionTangentBlocks(QuadratureFunction):
159184
"""An abstract class for Flux and InternalStateVariables"""
185+
160186
def initialize_tangent_blocks(self, variables):
161187
self.variables = variables
162188
values = [
@@ -170,7 +196,8 @@ def initialize_tangent_blocks(self, variables):
170196
),
171197
),
172198
name="d{}_d{}".format(self.name, v.name),
173-
) for v in self.variables
199+
)
200+
for v in self.variables
174201
]
175202
keys = [v.name for v in self.variables]
176203
self.tangent_blocks = dict(zip(keys, values))

0 commit comments

Comments
 (0)