Skip to content

Commit faf8ff2

Browse files
authored
Merge pull request #58 from bleyerj/vector-to-tensor-rep
Add as_tensor keyword to get_gradient/flux, fixes #56
2 parents 8e3d139 + 38982b3 commit faf8ff2

3 files changed

Lines changed: 37 additions & 11 deletions

File tree

bindings/python/mgis/fenics/gradient_flux.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
import numpy as np
1212
import ufl
1313
from .utils import local_project, symmetric_tensor_to_vector, \
14-
nonsymmetric_tensor_to_vector, get_quadrature_element
14+
nonsymmetric_tensor_to_vector, get_quadrature_element, \
15+
vector_to_tensor
1516

16-
<<<<<<< HEAD
1717
class QuadratureFunction:
1818
"""An abstract class for functions defined at quadrature points"""
1919
def __init__(self, name, shape):
@@ -31,7 +31,7 @@ def initialize_function(self, mesh, quadrature_degree):
3131
def update(self, x):
3232
self.function.vector().set_local(x)
3333

34-
def project_on(self, space, degree):
34+
def project_on(self, space, degree, as_tensor=False):
3535
"""
3636
Returns the projection on a standard CG/DG space
3737
@@ -42,13 +42,20 @@ def project_on(self, space, degree):
4242
FunctionSpace type ("CG", "DG",...)
4343
degree: int
4444
FunctionSpace degree
45+
as_tensor: bool
46+
Returned as a tensor if True, in vector notation otherwise
4547
"""
46-
if self.shape == 1:
48+
fun = self.function
49+
if as_tensor:
50+
fun = vector_to_tensor(self.function)
51+
shape = ufl.shape(fun)
52+
V = TensorFunctionSpace(self.mesh, space, degree, shape=shape)
53+
elif self.shape == 1:
4754
V = FunctionSpace(self.mesh, space, degree)
4855
else:
4956
V = VectorFunctionSpace(self.mesh, space, degree, dim=self.shape)
5057
v = Function(V, name=self.name)
51-
v.assign(project(self.function, V,
58+
v.assign(project(fun, V,
5259
form_compiler_parameters={"quadrature_degree": self.quadrature_degree}))
5360
return v
5461

bindings/python/mgis/fenics/nonlinear_problem.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ def update_constitutive_law(self):
390390
self.update_tangent_blocks()
391391
self.update_internal_state_variables()
392392

393-
def get_state_variable(self, name, project_on=None):
393+
def get_state_variable(self, name, project_on=None, as_tensor=False):
394394
"""
395395
Returns the function associated with an internal state variable
396396
@@ -411,9 +411,9 @@ def get_state_variable(self, name, project_on=None):
411411
if project_on is None:
412412
return self.state_variables["internal"][name].function
413413
else:
414-
return self.state_variables["internal"][name].project_on(*project_on)
414+
return self.state_variables["internal"][name].project_on(*project_on, as_tensor)
415415

416-
def get_flux(self, name, project_on=None):
416+
def get_flux(self, name, project_on=None, as_tensor=False):
417417
"""
418418
Returns the function associated with a flux
419419
@@ -434,9 +434,9 @@ def get_flux(self, name, project_on=None):
434434
if project_on is None:
435435
return self.fluxes[name].function
436436
else:
437-
return self.fluxes[name].project_on(*project_on)
437+
return self.fluxes[name].project_on(*project_on, as_tensor)
438438

439-
def get_gradient(self, name, project_on=None):
439+
def get_gradient(self, name, project_on=None, as_tensor=False):
440440
"""
441441
Returns the function associated with a gradient
442442
@@ -457,7 +457,7 @@ def get_gradient(self, name, project_on=None):
457457
if project_on is None:
458458
return self.gradients[name].function
459459
else:
460-
return self.gradients[name].project_on(*project_on)
460+
return self.gradients[name].project_on(*project_on, as_tensor)
461461

462462
def get_dissipated_energy(self):
463463
"""Dissipated energy computed from MFront @DissipatedEnergy"""

bindings/python/mgis/fenics/utils.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,25 @@ def nonsymmetric_tensor_to_vector(T, T22=0):
5353
else:
5454
raise NotImplementedError
5555

56+
def vector_to_tensor(T):
57+
""" Return vector following MFront conventions as a tensor """
58+
if ufl.shape(T)==(4,):
59+
return as_tensor([[T[0], T[3]/sqrt(2)],
60+
T[3]/sqrt(2), T[1]])
61+
elif ufl.shape(T)==(6,):
62+
return as_tensor([[T[0], T[3]/sqrt(2), T[4]/sqrt(2)],
63+
[T[3]/sqrt(2), T[1], T[5]/sqrt(2)],
64+
[T[4]/sqrt(2), T[5]/sqrt(2), T[2]]])
65+
elif ufl.shape(T)==(5,):
66+
return as_tensor([[T[0], T[3]],
67+
T[4], T[1]])
68+
elif ufl.shape(T)==(9,):
69+
return as_tensor([[T[0], T[3], T[5]],
70+
[T[4], T[1], T[7]],
71+
[T[6], T[8], T[2]]])
72+
else:
73+
raise NotImplementedError
74+
5675
def axi_grad(r, v):
5776
"""
5877
Axisymmetric gradient in cylindrical coordinate (er, etheta, ez) for:

0 commit comments

Comments
 (0)