To treat the transformation from physical to reference space in a more natural way, global derivatives and the measures dx/ds are replaced by their local equivalents transformed through J/invJ/detJ.
This process involves the following steps:
The Transformation class
Transformation is a class with a singleton instance T defined in the transformation module
T has the attributes J, invJ, detJ, after it has been initialised with the coordinate field (via init)
transform(coordinates) returns T initialised with coordinates
UFL code is prepended by
x = state.vector_field['Coordinates']
T = transform(x)
in a preprocessing step
UFL derivation and measure operators are overridden in the namespace the UFL code is exectued:
grad = lambda u: inner(T.invJ, ufl.grad(u))
div = lambda u: ufl.div(inner(T.invJ, u))
dx = T.detJ * ufl.dx
This results in a natural integration of all transformations by simply executing the UFL code with these operators brought into the namespace.
To treat the transformation from physical to reference space in a more natural way, global derivatives and the measures
dx
/ds
are replaced by their local equivalents transformed throughJ
/invJ
/detJ
.This process involves the following steps:
The
Transformation
classTransformation
is a class with a singleton instanceT
defined in thetransformation
moduleT
has the attributesJ
,invJ
,detJ
, after it has been initialised with the coordinate field (viainit
)transform(coordinates)
returnsT
initialised withcoordinates
UFL code is prepended by
in a preprocessing step
UFL derivation and measure operators are overridden in the namespace the UFL code is exectued:
This results in a natural integration of all transformations by simply executing the UFL code with these operators brought into the namespace.