mgis.fenics
moduleThese pages are intended to describe the FEniCS
interface to MGIS
available in the mgis.fenics
Python module. This module has been developed in the spirit of providing
support to the implementation of generalized nonlinear behaviours
i.e. including multiple gradients and dual flux variables. It can also
be used as a simple interface to standard mechanical behaviours in small
or finite strain (see the plasticity demos below). We briefly describe
here the
general concepts underlying the module implementation.
Repository: a repository containing the demos sources files is available here
The provided documented demos have been designed to progressively
illustrate the use of the interface and the versatility of the approach
when implementing complex generalized behaviours, both on the
MFront
and FEniCS
sides. We recommend browsing
the demos in the following order:
mgis.fenics
moduleThis module has been developed based on the concepts exposed in the
Elasto-plastic
analysis implemented using the MFront
code generator
demo published on Numerical Tours of
Computational Mechanics using FEniCS. We suggest reading first this
demo as an introduction to this module implementation concepts. In
particular, the module relies on the notion of Quadrature
function spaces to express the constitutive relation at the quadrature
points level.
Compared to this initial solution, the mgis.fenics
module has several advantages and new features:
Quadrature
functions’ definition will however be handled
directly inside the MFrontNonlinearProblem
class.NewtonSolver
available in
FEniCS
instead of programming the Newton method
manually.MFrontOptimisationProblem
class).MFrontNonlinearMaterial
classThis class handles the loading of a MFront
behaviour
through MGIS
. In particular, it will contain the following
important attributes:
behaviour
: an instance of MGIS
Behaviour
class which handles all the information about a
specific MFront
behaviour. It is created by the
load
function which takes the path to a library, the name
of a behaviour and a modelling hypothesis.data_manager
: an instance of MGIS
MaterialDataManager
class which handles a bunch of
integration points. It is instantiated using behaviour
and
the number of integration pointsNote about finite strain behaviours
Before loading the behaviour, it is checked if the behaviour is a finite-strain one or not. In the former case, specific finite-strain options are used when calling
load
. Such options specify that the stress measure will be post-processed byMGIS
from Cauchy to First Piola Kirchhoff (PK1) stress and that the tangent operator will be given by \(\dfrac{\partial \text{PK1}}{\partial F}\) (DPK1_DF
).
A set of helper functions enables to retrieve information about
MFront
object names and sizes of the form
self.get_{1}_{2}
where {1}
can be any of material_property
,
external_state_variable
,
internal_state_variable
, gradient
,
flux
or tangent_block
and {2}
can
be any of names
or sizes
.
MFrontNonlinearProblem
classThis class handles the definition and resolution of a nonlinear
problem associated with a MFrontNonlinearMaterial
. Its main
attributes are:
u
: the unknown mechanical field \(u\) (a dolfin.Function
)material
: the associated
MFrontNonlinearMaterial
state_variables
: a dictionary of internal and external
state variables. External state variables are represented as
dolfin
objects whereas internal state variables are
represented as Quadrature
functions.gradients
: a dictionary of Gradient
objectsfluxes
: a dictionary of Flux
objectsresidual
: the nonlinear residual \(F(u)\)tangent_form
: the tangent bilinear form associated with
the residualsolver
: the non-linear solver (default is
NewtonSolver
)Its main methods are:
register_gradient
: registers a MFront
gradient with a UFL
expression (see the registration concept).register_external_state_variable
: registers a
MFront
external state variable with a UFL
expression (see the registration
concept).set_loading
: defines the external forces linear form
\(L(v)\) in the default residual
expressioninitialize
: initializes the functions associated with
gradients, fluxes, external and internal state variables objects and the
corresponding tangent blocks. All gradients and external state variables
must have been registered first. Automatic registration is performed
at the beginning of the method call. This method has to be called once
before calling solve
.update_constitutive_law
: performs the consitutive law
update. Currently, this method is called for all quadrature points
before assembling the residual or tangent form. Ideally, this should be
done locally during the assembly (see the
module current limitations).solve
: solves the associated non-linear problem using
solver
get_flux
: returns the function associated with a
fluxget_state_variable
: returns the function associated
with an internal state variableBy default, the nonlinear residual is assumed to take the following form: Find \(u\in V\) such that:
\[ \sum_{i=1}^p \int_{\Omega}\boldsymbol{\sigma}_i(u)\cdot\delta\mathbf{g}_i(v) \,\text{dx}- L(v) = 0 \quad \forall v\in V \qquad{(1)}\]
where the \(\boldsymbol{\sigma}_i(u)\) are a set of
fluxes as defined in the MFront
behaviour
using @Flux
and \(\mathbf{g}_i\) are the corresponding set of
gradients, declared using @Gradient
. \(\delta \mathbf{g}_i(v)\) denotes the
directional derivative of \(\mathbf{g}_i\) along direction \(v\), a TestFunction
of the
function space \(V\), and \(L(v)\) is a linear form which can be
expressed using standard UFL
operators. From the mechanical
point of view, this residual expresses the balance between internal and
external forces.
This generic form is suitable for most quasi-static mechanical problems but it does not necessarily encompass all possible situations. In particular, evolution equations such as transient heat transfer cannot be expressed in this form. However, this is not a limitation since the residual can also be redefined explicitly by the user (see Transient non-linear heat equation).
Either for the default or a user-defined one, the tangent operator
associated with the residual is computed automatically using either the
UFL
symbolic derivation ufl.derivative
for
simple terms (e.g. involving the unknown field \(u\)) or using tangent operator blocks
defined in the MFront
behaviour for the nonlinear fluxes
and internal state variables. More precisely, the variation of each flux
is given by:
\[ \dfrac{\partial \boldsymbol{\sigma}_i}{\partial u} = \sum_{j\in \text{blocks}(i)} \mathbb{T}^{\boldsymbol{\sigma}_i}_{\mathbf{g}_j}\cdot \delta \mathbf{g}_j(u) \]
where the flux \(\boldsymbol{\sigma}_i\) is assumed to depend on the gradients \(\mathbf{g}_j\) for \(j\in \text{blocks}(i)\) (which at least contains \(i\) itself in general) and \(\mathbb{T}^{\boldsymbol{\sigma}_i}_{\mathbf{g}_j} = \dfrac{\partial \boldsymbol{\sigma}_i}{\partial \mathbf{g}_j}\) is the tangent operator associated with the corresponding block. Variations of internal state variables are computed in the same manner.
In the default case, the tangent bilinear form therefore reads as:
\[ a_\text{tangent}(u, v) = \sum_{i=1}^p \sum_{j\in\text{blocks}(i)}\int_{\Omega}\delta\mathbf{g}_j(u)\cdot \mathbb{T}^{\boldsymbol{\sigma}_i}_{\mathbf{g}_j} \cdot\delta\mathbf{g}_i(v) \,\text{dx} \]
Flux
and
Gradient
objectsTwo helper classes have been defined to handle flux and gradient objects:
Gradient
class provides a representation of
MFront
gradient objects. Its main purpose is to provide the
corresponding UFL
expression, linking MFront
and FEniCS
concepts. It also handles:
UFL
tensorial representation to
MFront
vectorial conventions.Flux
class provides a representation of
MFront
flux objects. Its main purpose is to store the flux
values in the form of a Quadrature function, as well as the tangent
block structure of the flux, each of them also represented by a
Quadrature function.InternalStateVariable
class is the same as the
Flux
class but for internal state variables. Both classes
derive from the abstract QuadratureFunction
class.Inspecting the default case (1), MFront
provides access
to the flux names, shapes and values when performing the constitutive
update and also to the corresponding gradient. The definition of the
tangent operator blocks inside the MFront
behaviour also
gives access to the block structure \(\text{blocks}(i)\) for each flux.
The remaining information which must be provided from the
FEniCS
side are the unknown field \(u\) and its discretization space \(V\), the chosen integration measure \(\,\text{dx}\) (through the
quadrature_degree
keyword) and, finally, the expression of
each declared gradients \(\mathbf{g}_i\) in terms of the unknown
field \(u\).
This step is what we call registration of each gradient
which will be discussed in depth in the demos. Let us just mention that
the gradients can registered using the register_gradient
method of the MFrontNonlinearProblem
class or via an
automatic procedure if the gradient name matches predefined common
gradient objects e.g. "Strain"
,
"TemperatureGradient"
, etc.
MFrontOptimisationProblem
classThis class is a sibing to the MFrontNonlinearProblem
class. It enables to solve nonlinear optimisation problems, especially
bound-constrained problems using the default PETScTAOSolver
of the form:
\[ \min_{b_l \leq u \leq b_u} f(u) \] where \(b_l\) (resp. \(b_u\)) denotes a lower (resp. upper) bound on the optimisation variable \(u\in V\).
By default, the objective function \(f(u)\) corresponds to the material total
energy (stored + dissipated) computed from the
get_total_energy()
method. The optimisation problem
requires the definition of the gradient \(F(u)\) which, by default, corresponds to
(1) and its jacobian which is computed as discussed before.
The module has been developed using FEniCS
version
2019.1.0. An important reimplementation will be planned once the dolfinx
project will officially release a stable version. In particular, it
will aim at fixing the following current limitations:
dolfinx
project should offer the possibility of using
custom assemblers in which constitutive integration should be possible
at the local assembly levelFEniCS
and MGIS
objects have not been optimized.