Skip to content

Commit 98e4acd

Browse files
authored
Merge pull request #68 from thelfer/revert-67-fix-esv-tangent-blocks
Revert "Fix update of state variables as UFL expression"
2 parents caf7179 + d39c484 commit 98e4acd

46 files changed

Lines changed: 5317 additions & 4620 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CMakeLists.txt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@ cmake_minimum_required(VERSION 3.0)
33
include(cmake/modules/mgis.cmake)
44
project("mfront-generic-interface")
55

6-
set(CMAKE_CXX_STANDARD 17)
7-
set(CXX_STANDARD_REQUIRED ON)
8-
96
# portable-build
107
option(enable-portable-build "produce binary that can be shared between various machine (same architecture, same gcc version, different processors" OFF)
118

bindings/python/mgis/fenics/gradient_flux.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ def __init__(self, variable, expression, name, symmetric=None):
7777
self.variable = variable
7878
if symmetric is None:
7979
self.expression = expression
80-
# TODO: treat axisymmetric case
8180
elif symmetric:
8281
if ufl.shape(expression) == (2, 2):
8382
self.expression = as_vector([symmetric_tensor_to_vector(expression)[i] for i in range(4)])
@@ -125,8 +124,8 @@ def _evaluate_at_quadrature_points(self, x):
125124

126125
class Var(Gradient):
127126
""" A simple variable """
128-
def __init__(self, variable, expression, name):
129-
Gradient.__init__(self, variable, expression, name)
127+
# def __init__(self, variable, name):
128+
# return Gradient.__init__(self, variable, variable, name)
130129

131130
def _evaluate_at_quadrature_points(self, x):
132131
local_project(x, self.function_space, self.dx, self.function)

bindings/python/mgis/fenics/nonlinear_material.py

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
"""
1010
import mgis.behaviour as mgis_bv
1111
from .gradient_flux import Var
12-
from .utils import compute_on_quadrature
1312
import dolfin
1413
import subprocess
1514
import os
@@ -25,8 +24,7 @@ class MFrontNonlinearMaterial:
2524
This class handles the loading of a MFront behaviour through MGIS.
2625
"""
2726
def __init__(self, path, name, hypothesis="3d",
28-
material_properties={}, parameters={},
29-
rotation_matrix=None):
27+
material_properties={}, parameters={}):
3028
"""
3129
Parameters
3230
-----------
@@ -44,17 +42,12 @@ def __init__(self, path, name, hypothesis="3d",
4442
parameters : dict
4543
a dictionary of parameters. The dictionary keys must match the parameter
4644
names declared in the MFront behaviour. Values must be constants.
47-
rotation_matrix : Numpy array, list of list, UFL matrix
48-
a 3D rotation matrix expressing the rotation from the global
49-
frame to the material frame. The matrix can be spatially variable
50-
(either UFL matrix or function of Tensor type)
5145
"""
5246
self.path = path
5347
self.name = name
5448
# Defining the modelling hypothesis
5549
self.hypothesis = mgis_hypothesis[hypothesis]
5650
self.material_properties = material_properties
57-
self.rotation_matrix = rotation_matrix
5851
# Loading the behaviour
5952
try:
6053
self.load_behaviour()
@@ -81,39 +74,44 @@ def load_behaviour(self):
8174
else:
8275
self.behaviour = mgis_bv.load(self.path, self.name, self.hypothesis)
8376

84-
def set_data_manager(self, degree, ngauss, mesh):
77+
def set_data_manager(self, ngauss):
8578
# Setting the material data manager
8679
self.data_manager = mgis_bv.MaterialDataManager(self.behaviour, ngauss)
87-
self.update_material_properties(degree, mesh)
80+
self.update_material_properties()
8881

8982
def update_parameters(self, parameters):
9083
for (key, value) in parameters.items():
9184
self.behaviour.setParameter(key, value)
9285

93-
def update_material_properties(self, degree, mesh, material_properties=None):
86+
def update_material_properties(self, material_properties=None):
9487
if material_properties is not None:
9588
self.material_properties = material_properties
9689
for s in [self.data_manager.s0, self.data_manager.s1]:
9790
for (key, value) in self.material_properties.items():
9891
if type(value) in [int, float]:
9992
mgis_bv.setMaterialProperty(s, key, value)
10093
else:
101-
values = compute_on_quadrature(value, mesh, degree).vector().get_local()
102-
mgis_bv.setMaterialProperty(s, key, values, mgis_bv.MaterialStateManagerStorageMode.LocalStorage)
94+
if isinstance(value, dolfin.Function):
95+
value = value.vector().get_local()
96+
mgis_bv.setMaterialProperty(s, key, value, mgis_bv.MaterialStateManagerStorageMode.LocalStorage)
10397

104-
def update_external_state_variables(self, degree, mesh, external_state_variables):
98+
def update_external_state_variables(self, external_state_variables):
10599
s = self.data_manager.s1
106100
for (key, value) in external_state_variables.items():
107101
if type(value) in [int, float]:
108102
mgis_bv.setExternalStateVariable(s, key, value)
109103
elif isinstance(value, dolfin.Constant):
110104
mgis_bv.setExternalStateVariable(s, key, float(value))
111105
else:
112-
if isinstance(value, Var):
106+
if isinstance(value, dolfin.Function):
107+
values = value.vector().get_local()
108+
elif isinstance(value, Var):
113109
value.update()
114110
values = value.function.vector().get_local()
115111
else:
116-
values = compute_on_quadrature(value, mesh, degree).vector().get_local()
112+
print(isinstance(value, Var))
113+
print(value)
114+
raise NotImplementedError("{} type is not supported for external state variables".format(type(value)))
117115
mgis_bv.setExternalStateVariable(s, key, values, mgis_bv.MaterialStateManagerStorageMode.LocalStorage)
118116

119117
def get_parameter(self, name):

bindings/python/mgis/fenics/nonlinear_problem.py

Lines changed: 38 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def __init__(self, u, material, quadrature_degree=2, bcs=None):
6161
# compute Gauss points numbers
6262
self.ngauss = Function(self.W0).vector().local_size()
6363
# Set data manager
64-
self.material.set_data_manager(self.quadrature_degree, self.ngauss, self.mesh)
64+
self.material.set_data_manager(self.ngauss)
6565
# dummy function used for computing global quantity
6666
self._dummy_function = Function(self.W0)
6767

@@ -90,14 +90,6 @@ def __init__(self, u, material, quadrature_degree=2, bcs=None):
9090

9191
self.dt = 0
9292

93-
if self.material.rotation_matrix is not None:
94-
if isinstance(self.material.rotation_matrix, (list, tuple, np.ndarray)):
95-
self.rotation_values = np.asarray(self.material.rotation_matrix).ravel()
96-
else:
97-
self.rotation_values = compute_on_quadrature(self.material.rotation_matrix,
98-
self.mesh, self.quadrature_degree)
99-
self.rotation_values = self.rotation_values.vector().get_local()
100-
10193
self.state_variables = {"internal": None,
10294
"external": dict.fromkeys(self.material.get_external_state_variable_names(), None)}
10395
self.gradients = dict.fromkeys(self.material.get_gradient_names(), None)
@@ -202,9 +194,12 @@ def register_external_state_variable(self, name, expression):
202194
vtype = self.material.behaviour.external_state_variables[pos].type
203195
if vtype != mgis_bv.VariableType.Scalar:
204196
raise NotImplementedError("Only scalar external state variables are handled")
205-
if type(expression) == float:
206-
expression = Constant(expression)
207-
self.state_variables["external"].update({name: Var(self.u, expression, name)})
197+
if isinstance(expression, Constant):
198+
self.state_variables["external"].update({name: expression})
199+
elif type(expression) == float:
200+
self.state_variables["external"].update({name: Constant(expression)})
201+
else:
202+
self.state_variables["external"].update({name: Var(self.u, expression, name)})
208203

209204
def set_loading(self, Fext):
210205
"""
@@ -217,20 +212,38 @@ def set_loading(self, Fext):
217212
"""
218213
self._Fext = ufl.replace(Fext, {self.u: self.u_})
219214

215+
def set_quadrature_function_spaces(self):
216+
cell = self.mesh.ufl_cell()
217+
W0e = get_quadrature_element(cell, self.quadrature_degree)
218+
# scalar quadrature space
219+
self.W0 = FunctionSpace(self.mesh, W0e)
220+
# compute Gauss points numbers
221+
self.ngauss = Function(self.W0).vector().local_size()
222+
# Set data manager
223+
self.material.set_data_manager(self.ngauss)
224+
225+
# Get strain measure dimension
226+
self.strain_dim = ufl.shape(self.strain_measure(self.u))[0]
227+
# Define quadrature spaces for stress/strain and tangent matrix
228+
Wsige = get_quadrature_element(cell, self.quadrature_degree, self.strain_dim)
229+
# stress/strain quadrature space
230+
self.Wsig = FunctionSpace(self.mesh, Wsige)
231+
Wce = get_quadrature_element(cell, self.quadrature_degree, (self.strain_dim, self.strain_dim))
232+
# tangent matrix quadrature space
233+
self.WCt = FunctionSpace(self.mesh, Wce)
234+
220235
def initialize_external_state_variables(self):
221236
for (s, size) in zip(self.material.get_external_state_variable_names(), self.material.get_external_state_variable_sizes()):
222237
state_var = self.state_variables["external"][s]
223-
if isinstance(state_var, Constant):
224-
mgis_bv.setExternalStateVariable(self.material.data_manager.s0, s, float(state_var))
225-
else:
226-
if isinstance(state_var, Var):
227-
state_var.initialize_function(self.mesh, self.quadrature_degree)
228-
values = state_var.function.vector().get_local()
229-
else:
230-
values = compute_on_quadrature(state_var, self.mesh,
231-
self.quadrature_degree).vector().get_local()
238+
if isinstance(state_var, Gradient):
239+
state_var.initialize_function(self.mesh, self.quadrature_degree)
240+
values = state_var.function.vector().get_local()
232241
mgis_bv.setExternalStateVariable(self.material.data_manager.s0, s,
233242
values, mgis_bv.MaterialStateManagerStorageMode.LocalStorage)
243+
elif isinstance(state_var, Constant):
244+
mgis_bv.setExternalStateVariable(self.material.data_manager.s0, s, float(state_var))
245+
else:
246+
raise ValueError("External state variable '{}' has not been registered.".format(s))
234247

235248
def initialize_gradients(self):
236249
buff=0
@@ -274,7 +287,7 @@ def initialize_tangent_blocks(self):
274287
except:
275288
value = self.state_variables["external"].get(t[1], None)
276289
if value is not None and isinstance(value, Var):
277-
flux_gradients.append(value)
290+
flux_gradients.append(value)
278291
else:
279292
raise ValueError("'{}' could not be associated with a registered gradient or state variable.".format(t[1]))
280293
self.fluxes[f].initialize_tangent_blocks(flux_gradients)
@@ -334,23 +347,15 @@ def update_tangent_blocks(self):
334347
except KeyError:
335348
raise KeyError("'{}' could not be found as a flux or an internal state variable.")
336349
block_shape = self.flattened_block_shapes[i]
337-
tang_block_vals = self.material.data_manager.K[:,buff:buff+block_shape].ravel()
338-
if self.material.rotation_matrix is not None:
339-
mgis_bv.rotateTangentOperatorBlocks(tang_block_vals, self.material.behaviour,
340-
self.rotation_values)
341-
t.vector().set_local(tang_block_vals)
350+
t.vector().set_local(self.material.data_manager.K[:,buff:buff+block_shape].flatten())
342351
buff += block_shape
343352

344353
def update_fluxes(self):
345354
buff = 0
346355
for (i, f) in enumerate(self.material.get_flux_names()):
347356
flux = self.fluxes[f]
348357
block_shape = self.material.get_flux_sizes()[i]
349-
flux_vals = self.material.data_manager.s1.thermodynamic_forces[:,buff:buff+block_shape].ravel()
350-
if self.material.rotation_matrix is not None:
351-
mgis_bv.rotateThermodynamicForces(flux_vals, self.material.behaviour,
352-
self.rotation_values)
353-
flux.function.vector().set_local(flux_vals)
358+
flux.function.vector().set_local(self.material.data_manager.s1.thermodynamic_forces[:,buff:buff+block_shape].flatten())
354359
buff += block_shape
355360

356361
def update_gradients(self):
@@ -360,9 +365,6 @@ def update_gradients(self):
360365
gradient.update()
361366
block_shape = self.material.get_gradient_sizes()[i]
362367
grad_vals = gradient.function.vector().get_local()
363-
if self.material.rotation_matrix is not None:
364-
mgis_bv.rotateGradients(grad_vals, self.material.behaviour,
365-
self.rotation_values)
366368
if gradient.shape > 0:
367369
grad_vals = grad_vals.reshape((self.material.data_manager.n, gradient.shape))
368370
else:
@@ -382,8 +384,7 @@ def update_internal_state_variables(self):
382384
def update_constitutive_law(self):
383385
"""Performs the consitutive law update"""
384386
self.update_gradients()
385-
self.material.update_external_state_variables(self.quadrature_degree, self.mesh,
386-
self.state_variables["external"])
387+
self.material.update_external_state_variables(self.state_variables["external"])
387388
# integrate the behaviour
388389
mgis_bv.integrate(self.material.data_manager, self.integration_type,
389390
self.dt, 0, self.material.data_manager.n);

bindings/python/mgis/fenics/utils.py

Lines changed: 1 addition & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -118,48 +118,4 @@ def get_quadrature_element(cell, degree, dim=0):
118118
elif type(dim) == tuple:
119119
return TensorElement("Quadrature", cell, degree=degree, shape=dim, quad_scheme='default')
120120
else:
121-
raise ValueError("Wrong shape for dim=", dim)
122-
123-
def interpolate_on_quadrature(f, degree):
124-
V = f.function_space()
125-
Ve = V.ufl_element()
126-
if Ve.family()=="Quadrature":
127-
return f
128-
else:
129-
shape = Ve.value_shape()
130-
if len(shape) == 1:
131-
shape = shape[0]
132-
Vge = Ve.__class__("Quadrature", Ve.cell(), degree, shape,
133-
quad_scheme="default")
134-
Vg = FunctionSpace(V.mesh(), Vge)
135-
fg = Function(Vg)
136-
fg.interpolate(f)
137-
return fg
138-
139-
def project_on_quadrature(f, mesh, degree):
140-
shape = f.ufl_shape
141-
Vge = get_quadrature_element(mesh.ufl_cell(), degree, shape)
142-
Vg = FunctionSpace(mesh, Vge)
143-
dx = Measure("dx", domain=mesh, metadata={"quadrature_scheme": "default",
144-
"quadrature_degree": degree})
145-
fg = Function(Vg)
146-
fg.assign(local_project(f, Vg, dx))
147-
return fg
148-
149-
def compute_on_quadrature(f, mesh, degree):
150-
shape = f.ufl_shape
151-
Vge = get_quadrature_element(mesh.ufl_cell(), degree, shape)
152-
Vg = FunctionSpace(mesh, Vge)
153-
dx = Measure("dx", domain=mesh, metadata={"quadrature_scheme": "default",
154-
"quadrature_degree": degree})
155-
fg = Function(Vg)
156-
if (isinstance(f, function.function.Function) or
157-
isinstance(f, function.function.Constant) or
158-
isinstance(f, function.function.Expression)):
159-
fg.interpolate(f)
160-
# return interpolate_on_quadrature(f, degree)
161-
else:
162-
fg.assign(local_project(f, Vg, dx))
163-
return fg
164-
# fg.interpolate(f)
165-
# return project_on_quadrature(f, degree)
121+
raise ValueError("Wrong shape for dim=", dim)

0 commit comments

Comments
 (0)