movement package¶
Submodules¶
movement.laplacian_smoothing module¶
- class LaplacianSmoother(mesh, timestep, **kwargs)[source]¶
Bases:
PrimeMover
Movement of a
mesh
is driven by a mesh velocity \(\mathbf{v}\), which is determined by solving a vector Laplace problem\[\nabla^2_{\boldsymbol{\xi}}\mathbf{v} = \boldsymbol{0}, \quad \boldsymbol{\xi}\in\Omega,\]under non-zero Dirichlet boundary conditions on a forced boundary section \(\partial\Omega_f\) and zero Dirichlet boundary conditions elsewhere:
\[\begin{split}\mathbf{v} = \left\{\begin{array}{rl} \mathbf{v}_D, & \boldsymbol{\xi}\in\partial\Omega_f\\ \boldsymbol{0}, & \boldsymbol{\xi}\in\partial\Omega\backslash\partial\Omega_f \end{array}\right.\end{split}\]where the computational coordinates \(\boldsymbol{\xi} := \mathbf{x}(t_0)\) are the physical coordinates at the beginning of the simulation.
- Parameters:
mesh (
firedrake.mesh.MeshGeometry
) – the physical mesh to be movedtimestep (
float
) – the timestep length used
- move(time, update_boundary_velocity=None, boundary_conditions=None, solver_parameters=None)[source]¶
Assemble and solve the Laplacian system and update the coordinates.
- Parameters:
time (
float
) – the current timeupdate_boundary_velocity (
Callable
with a single argument offloat
type) – function that updates the boundary conditions at the current timeboundary_conditions (
DirichletBC
orlist
thereof) – Dirichlet boundary conditions to be enforcedsolver_parameters (
dict
) – solver parameters for solving the Laplace equation
movement.math module¶
movement.monge_ampere module¶
Mesh movement based on solutions of equations of Monge-Ampère type.
- MongeAmpereMover(mesh, monitor_function, method='relaxation', **kwargs)[source]¶
Factory function for generating Monge-Ampère mesh movers.
Movement of a mesh is determined by a monitor_function \(m\) and an equation of Monge-Ampère type,
\[m(\mathbf{x})\det(\mathbf{I} + \mathbf{H}(\phi)) = \theta,\]for a convex scalar potential \(\phi=\phi(\boldsymbol{\xi})\), which is a function of the coordinates of the computational mesh. Here \(m=m(\mathbf{x})\) is a function of the coordinates of the physical mesh, \(\mathbf{I}\) is the identity matrix, \(\theta\) is a normalisation coefficient and \(\mathbf{H}(\phi)\) denotes the Hessian of \(\phi\) with respect to \(\boldsymbol{\xi}\).
Different implementations solve the Monge-Ampère equation in different ways. If the method argument is set to “relaxation” then it is solved in parabolised form in
MongeAmpereMover_Relaxation
. If the argument is set to “quasi_newton” then it is solved in its elliptic form using a quasi-Newton method inMongeAmpereMover_QuasiNewton
. Descriptions of both methods may be found in [MCB18].The physical mesh coordinates \(\mathbf{x}\) are updated according to
\[\mathbf{x} = \boldsymbol{\xi} + \nabla_{\boldsymbol{\xi}}\phi.\]- Parameters:
mesh (
firedrake.mesh.MeshGeometry
) – the physical meshmonitor_function (
Callable
) – a Python function which takes a mesh as inputmethod (
str
) – choose from ‘relaxation’ and ‘quasi_newton’phi_init (
firedrake.function.Function
) – initial guess for the scalar potentialH_init (
firedrake.function.Function
) – initial guess for the Hessianmaxiter (
int
) – maximum number of iterations for the solverrtol (
float
) – relative tolerance for the residualdtol (
float
) – divergence tolerance for the residualpseudo_timestep (
float
) – pseudo-timestep (only relevant to relaxation method)fixed_boundary_segments (
list
ofstr
orint
) – labels corresponding to boundary segments to be fixed with a zero Dirichlet condition. The ‘on_boundary’ label indicates the whole domain boundary
- Returns:
the Monge-Ampère Mover object
- Return type:
- class MongeAmpereMover_QuasiNewton(mesh, monitor_function, phi_init=None, H_init=None, **kwargs)[source]¶
Bases:
MongeAmpereMover_Base
The standard, elliptic form of the Monge-Ampère equation used for mesh movement is:
\[m(\mathbf{x})\det(\mathbf{I} + \mathbf{H}(\phi)) = \theta,\]for a convex scalar potential \(\phi=\phi(\boldsymbol{\xi})\), which is a function of the coordinates of the computational mesh. Here \(m=m(\mathbf{x})\) is a user-provided monitor function, which is a function of the coordinates of the physical mesh. \(\mathbf{I}\) is the identity matrix, \(\theta\) is a normalisation coefficient and \(\mathbf{H}(\phi)\) denotes the Hessian of \(\phi\) with respect to \(\boldsymbol{\xi}\).
In this mesh mover, the elliptic Monge-Ampère equation is solved using a quasi-Newton method (see [MCB18] for details).
This approach typically takes fewer than ten iterations to converge, but each iteration is relatively expensive.
- Parameters:
mesh (
firedrake.mesh.MeshGeometry
) – the physical meshmonitor_function (
Callable
) – a Python function which takes a mesh as inputphi_init (
firedrake.function.Function
) – initial guess for the scalar potentialH_init (
firedrake.function.Function
) – initial guess for the Hessianmaxiter (
int
) – maximum number of iterations for the Quasi-Newton solverrtol (
float
) – relative tolerance for the residualdtol (
float
) – divergence tolerance for the residual
- property equidistributor¶
Setup the equidistributor for the quasi-newton method.
The equidistributor solves
\[\int_{\Omega} \boldsymbol{\tau} \cdot \mathbf{H} \, \mathrm{d}x + \int_{\Omega} (\nabla \cdot \boldsymbol{\tau}) \cdot (\nabla \phi) \, \mathrm{d}x - \int_{\partial \Omega} (((\nabla \phi) \cdot \widehat{\mathbf{n}}) \cdot \boldsymbol{\tau}) \cdot \widehat{\mathbf{n}} \, \mathrm{d}s - \int_{\Omega} \psi (m \det(\mathbf{I} + \mathbf{H}) - \theta) \, \mathrm{d}x = 0, \quad \forall \boldsymbol{\tau} \in \mathbb{P}1^{d \times d}, \quad \forall \psi \in \mathbb{P}1,\]for the potential \(\phi\) and its Hessian \(\mathbf{H}\), where \(d\) is the spatial dimension and \(\widehat{\mathbf{n}}\) is a normal vector to the boundary.
- Returns:
the equidistributor
- Return type:
NonlinearVariationalSolver
- class MongeAmpereMover_Relaxation(mesh, monitor_function, phi_init=None, H_init=None, **kwargs)[source]¶
Bases:
MongeAmpereMover_Base
The standard, elliptic form of the Monge-Ampère equation used for mesh movement is:
\[m(\mathbf{x})\det(\mathbf{I} + \mathbf{H}(\phi)) = \theta,\]for a convex scalar potential \(\phi=\phi(\boldsymbol{\xi})\), which is a function of the coordinates of the computational mesh. Here \(m=m(\mathbf{x})\) is a user-provided monitor function, which is a function of the coordinates of the physical mesh. \(\mathbf{I}\) is the identity matrix, \(\theta\) is a normalisation coefficient and \(\mathbf{H}(\phi)\) denotes the Hessian of \(\phi\) with respect to \(\boldsymbol{\xi}\).
In this mesh mover, the Monge-Ampère equation is instead solved in a parabolised form using a pseudo-time relaxation,
\[-\frac\partial{\partial\tau}\Delta\phi = m(\mathbf{x})\det(\mathbf{I} + \mathbf{H}(\phi)) - \theta,\]where \(\tau\) is the pseudo-time variable. Forward Euler is used for the pseudo-time integration (see [MCB18] for details).
This approach typically takes tens or hundreds of iterations to converge, but each iteration is relatively cheap.
- Parameters:
mesh (
firedrake.mesh.MeshGeometry
) – the physical meshmonitor_function (
Callable
) – a Python function which takes a mesh as inputphi_init (
firedrake.function.Function
) – initial guess for the scalar potentialH_init (
firedrake.function.Function
) – initial guess for the Hessianpseudo_timestep (
float
) – pseudo-timestep to use for the relaxationmaxiter (
int
) – maximum number of iterations for the relaxationrtol (
float
) – relative tolerance for the residualdtol (
float
) – divergence tolerance for the residualfixed_boundary_segments (
list
ofstr
orint
) – labels corresponding to boundary segments to be fixed with a zero Dirichlet condition. The ‘on_boundary’ label indicates the whole domain boundary
- property equidistributor¶
Setup the equidistributor for the relaxation method.
The equidistributor solves the following equation:
\[\int_{\Omega} \tau : \mathbf{H} \, \mathrm{d}x = -\int_{\Omega} (\nabla \cdot \tau) \cdot (\nabla \phi) \, \mathrm{d}x + \int_{\partial \Omega} ((\nabla \phi \cdot \widehat{\mathbf{n}}) \cdot \tau) \cdot \widehat{\mathbf{n}} \, \mathrm{d}s, \quad \forall \tau \in \mathbb{P}1^{d \times d}\]for the Hessian \(\mathbf{H}\), where \(d\) is the spatial dimension and \(\widehat{\mathbf{n}}\) is a normal vector to the boundary.
- Returns:
the equidistributor
- Return type:
LinearVariationalSolver
- move()[source]¶
Run the relaxation method to convergence and update the mesh.
- Returns:
the iteration count
- Return type:
- property pseudotimestepper¶
Setup the pseudo-timestepper for the relaxation method.
Forward Euler is used for the pseudo-time integration (see [MCB18] for details). The pseudo-timestep may be set through the pseudo_timestep keyword argument to the constructor.
- Returns:
the pseudo-timestepper
- Return type:
LinearVariationalSolver
movement.mover module¶
- class PrimeMover(mesh, monitor_function=None, raise_convergence_errors=True, tangling_check=None, quadrature_degree=None)[source]¶
Bases:
ABC
Base class for all mesh movers.
- Parameters:
mesh (
firedrake.mesh.MeshGeometry
) – the physical meshmonitor_function (
Callable
) – a Python function which takes a mesh as inputraise_convergence_errors (
bool
) – convergence error handling behaviour: if True thenConvergenceError
s are raised, else warnings are raised and the program is allowed to continuetangling_check (
bool
) – check whether the mesh has tangled elements (by default on in the 2D case and off otherwise)quadrature_degree (
int
) – quadrature degree to be passed to Firedrakes measures
- property coefficient_of_variation¶
- Returns:
the coefficient of variation (σ/μ) of element volumes.
- Return type:
- to_computational_coordinates()[source]¶
Switch coordinates to correspond to the computational mesh
mathcal{H}_C
.
movement.solver_parameters module¶
movement.spring module¶
- SpringMover(*args, method='lineal', **kwargs)[source]¶
Movement of a
mesh
is determined by reinterpreting it as a structure of stiff beams and solving an associated discrete linear elasticity problem. (See [] for details.)- Parameters:
mesh (
firedrake.mesh.MeshGeometry
) – the physical mesh to be movedtimestep (
float
) – the timestep length usedmethod (
str
) – flavour of spring-based method to use
- class SpringMover_Lineal(mesh, timestep, **kwargs)[source]¶
Bases:
SpringMover_Base
Movement of a
mesh
is determined by reinterpreting it as a structure of stiff beams and solving an associated discrete linear elasticity problem.We consider the ‘lineal’ case, as described in [].
- Parameters:
mesh (
firedrake.mesh.MeshGeometry
) – the physical mesh to be movedtimestep (
float
) – the timestep length used
- class SpringMover_Torsional(*args, **kwargs)[source]¶
Bases:
SpringMover_Lineal
Movement of a
mesh
is determined by reinterpreting it as a structure of stiff beams and solving an associated discrete linear elasticity problem.We consider the ‘torsional’ case, as described in [].
- Parameters:
mesh (
firedrake.mesh.MeshGeometry
) – the physical mesh to be movedtimestep (
float
) – the timestep length used
movement.tangling module¶
- class MeshTanglingChecker(mesh, raise_error=True)[source]¶
Bases:
object
A class for tracking whether a mesh has tangled, i.e. whether any of its elements have become inverted.
- Parameters:
mesh (
firedrake.mesh.MeshGeometry
) – the mesh to track if tangledraise_error (
bool
) – ifTrue
, an error is raised if any element is tangled, otherwise a warning is raised
- check()[source]¶
Check whether any element orientations have changed since the tangling checker was created.
- property scaled_jacobian¶