Simulation Setup#
Base Geometry State#
- pystopt.simulation.as_state_container(cls: type) type [source]#
A decorator for subclasses of
GeometryState
.It transforms the subclass into a dataclass with the minimum required arithmetic operations from
arraycontext
.
- pystopt.simulation.reconstruct_discretization(actx: ArrayContext, orig_discr: Discretization, xlm: ndarray, *, keep_vertices: bool = False) Discretization [source]#
Reconstruct the geometry pointed at by dofdesc using the nodes from xlm.
The xlm variable must match the number of nodes or the spectral representation on the geometry described by dofdesc.
- Parameters:
keep_vertices – if True, the vertices are reconstructed by interpolating from the nodes xlm. Otherwise, they are set to None and assumed to be unused in the new discretization.
- Returns:
a new
Discretization
.
- class pystopt.simulation.GeometryWrangler(places: pytential.GeometryCollection, dofdesc: pytential.symbolic.primitives.DOFDescriptor, is_spectral: bool)[source]#
Bases:
object
- ambient_dim#
- places#
A
GeometryCollection
that contains all the geometries in the simulation. These are just used to describe the connectivity and initial state of the geometry.
- dofdesc#
A
DOFDescriptor
for the discretization being evolved, optimized or otherwise modified.
- is_spectral#
If True, the state is represented by the spectral coefficients of the geometry coordinates. Otherwise, the physical coordinates are used.
- get_initial_state(actx: ArrayContext) GeometryState [source]#
- Returns:
a
GeometryState
using the nodes ofdofdesc
as found inplaces
.
- to_state_type(ary: ArrayContainerT) ArrayContainerT [source]#
Projects ary to match the type of data in the
GeometryState
handled by this wrangler.If
is_spectral
is True, ary is expected to be aDOFArray
which will be projected to its spectral coefficients. Otherwise, it is returned as is.
- from_state_type(ary: ArrayContainerT) ArrayContainerT [source]#
Projects ary from the type of data in the
GeometryState
handled by this wrangler back to physical space.If
is_spectral
is True, ary is expected to be aSpectralDOFArray
of spectral coefficients, which will be projected to physical space. Otherwise, it is returned as is.
- class pystopt.simulation.GeometryState[source]#
Bases:
object
- x#
A set of nodes (or spectral coefficients for the same nodes) that describe the geometry from wrangler.
- wrangler#
- get_geometry_collection() pytential.GeometryCollection [source]#
Updates the discretization from
GeometryWrangler.places
using the nodes fromx
usingreconstruct_discretization()
.- Returns:
a new
GeometryCollection
containing the updated discretization, while preserving all other geometries in the collection.
- class pystopt.simulation.make_geometry_wrangler(places: pytential.GeometryCollection, *, dofdesc: pytential.symbolic.primitives.DOFDescriptorLike | None = None, is_spectral: bool = True)[source]#
Bases:
- class pystopt.simulation.MeshQualityHistoryCallback(norm: ~typing.Callable[[~typing.Any], float] | None, memory: ~typing.List[int] = <factory>, timestamp: ~typing.List[int] = <factory>, volume: ~typing.List[float] = <factory>, area: ~typing.List[float] = <factory>, h_max: ~typing.List[float] = <factory>, h_avg: ~typing.List[float] = <factory>, h_std: ~typing.List[float] = <factory>)[source]#
Bases:
PerformanceHistoryCallback
- volume#
Total volume of the closed surfaces in the geometry.
- area#
Total surface area of the closed surfaces in the geometry.
- h_max#
Maximum element area.
- h_avg#
Mean element area.
- h_std#
Element area standard deviation.
Unsteady Evolution#
- class pystopt.simulation.unsteady.GeometryEvolutionState[source]#
Bases:
GeometryState
- t#
Time at which the current state is computed. This is expected to be advanced by the time integrator together with the geometry. Note that, due to floating point operations, the time integrator \(t\) and this one may start diverging.
- class pystopt.simulation.unsteady.GeometryEvolutionWrangler(places: pytential.GeometryCollection, dofdesc: pytential.symbolic.primitives.DOFDescriptor, is_spectral: bool, evolution: StokesEvolutionOperator, context: Dict[str, Any], stabilizer_name: str, stabilizer_arguments: Dict[str, Any], filter_type: FilterType, filter_arguments: Dict[str, Any])[source]#
Bases:
GeometryWrangler
- evolution#
A
StokesEvolutionOperator
that symbolically describes the right-hand side terms.
- stabilizer_name#
The name of the stabilizer, see
make_stabilizer_from_name()
.
- stabilizer_arguments#
Passed to
make_stabilizer_from_name()
.
- filter_type#
- filter_arguments#
- apply_filter(actx: ArrayContext, places: pytential.GeometryCollection, ary: ArrayOrContainerT, *, force_spectral: bool | None = None) ArrayOrContainerT [source]#
Apply a filter to the given array ary.
By default, this function calls
apply_filter_by_type()
usingfilter_type
andfilter_arguments
.
- get_stabilizer()[source]#
- Returns:
a
PassiveStabilizer
described bystabilizer_name
. This can be used to compute a tangential velocity field. Note that a tangential forcing is only used ifforce_tangential_velocity
is set onevolution
.
- evolution_source_term(t: float, state: GeometryEvolutionState) GeometryEvolutionState [source]#
- class pystopt.simulation.unsteady.StokesEvolutionWrangler(places: pytential.GeometryCollection, dofdesc: pytential.symbolic.primitives.DOFDescriptor, is_spectral: bool, evolution: StokesEvolutionOperator, context: Dict[str, Any], stabilizer_name: str, stabilizer_arguments: Dict[str, Any], filter_type: FilterType, filter_arguments: Dict[str, Any], op: TwoPhaseStokesRepresentation, lambdas: Dict[str, float], gmres_arguments: Dict[str, Any])[source]#
- pystopt.simulation.unsteady.quasi_evolve_stokes(actx: ArrayContext, wrangler: GeometryEvolutionWrangler, step: TimeWrangler, *, tmax: float | None = None, maxit: float | None = None, callback: CallbackManager | None = None, verbose: bool = True) GeometryEvolutionState [source]#
- class pystopt.simulation.unsteady.AdjointGeometryEvolutionWrangler(forward: GeometryEvolutionWrangler)[source]#
Bases:
object
- forward#
A
StokesEvolutionWrangler
, whose properties and attributes are forwarded through this class.
- cost#
- cost_final#
- ad#
An adjoint operator constructed from the forward operator and
cost
. This operator is used to compute the adjoint state at each time step.
- evaluate_shape_gradient(actx: ArrayContext, places: pytential.GeometryCollection, *, context: Dict[str, Any] | None = None) ndarray [source]#
- evaluate_shape_gradient_final(actx: ArrayContext, state: GeometryEvolutionState, *, context: Dict[str, Any] | None = None) ndarray [source]#
- get_initial_state(actx: ArrayContext, state: GeometryEvolutionState) AdjointGeometryEvolutionState [source]#
- evolution_source_term(t: float, state: GeometryEvolutionState, adjoint: AdjointGeometryEvolutionState) AdjointGeometryEvolutionState [source]#
- class pystopt.simulation.unsteady.AdjointGeometryEvolutionState[source]#
Bases:
object
- evaluate_shape_gradient(state: GeometryEvolutionState)[source]#
- class pystopt.simulation.unsteady.AdjointStokesEvolutionState[source]#
Bases:
AdjointGeometryEvolutionState
- get_adjoint_density(state: StokesEvolutionState)[source]#
- class pystopt.simulation.unsteady.AdjointStokesEvolutionWrangler(forward: StokesEvolutionWrangler)[source]#
- pystopt.simulation.unsteady.quasi_evolve_adjoint(actx: ArrayContext, wrangler: AdjointStokesEvolutionWrangler, step: TimeWrangler, *, tmax: float | None = None, maxit: float | None = None, callback: CallbackManager | None = None, force_gc: bool = True, verbose: bool = True) AdjointStokesEvolutionState [source]#
- class pystopt.simulation.unsteady.StokesEvolutionCallbackManager(stop_file_name: Optional[pathlib.Path] = None, callbacks: Dict[str, pystopt.callbacks.CallbackCallable] = <factory>, short_circuit: bool = False, _force_gc: bool = True)[source]#
Bases:
CallbackManager
- class pystopt.simulation.unsteady.StokesEvolutionVisualizeCallback(norm: Callable[[Any], float] | None, visualize_file_series: Iterator[FileParts], overwrite: bool = False, frequency: int = 1)[source]#
Bases:
VisualizeCallback
- class pystopt.simulation.unsteady.StokesEvolutionHistoryCallback(norm: Optional[Callable[[Any], float]], memory: List[int] = <factory>, timestamp: List[int] = <factory>, volume: List[float] = <factory>, area: List[float] = <factory>, h_max: List[float] = <factory>, h_avg: List[float] = <factory>, h_std: List[float] = <factory>, deformation: List[float] = <factory>, u_dot_n: List[float] = <factory>, time: List[numpy.ndarray] = <factory>, centroid: List[numpy.ndarray] = <factory>)[source]#
Bases:
StokesHistoryCallback
- class pystopt.simulation.unsteady.AdjointStokesEvolutionCallbackManager(stop_file_name: Optional[pathlib.Path] = None, callbacks: Dict[str, pystopt.callbacks.CallbackCallable] = <factory>, short_circuit: bool = False, _force_gc: bool = True)[source]#
Bases:
CallbackManager
Unconstrained Shape Optimization#
These functions can be used to easily encapsulate and perform shape optimization without constraints. The general workflow using these classes is
wrangler = UnconstrainedShapeOptimizationWrangler(
cost=cost,
context=context,
filter_type=OutputType.Unfiltered,
filter_arguments={},
)
state0 = wrangler.get_initial_state(actx)
from pystopt.optimize import minimize_steepest
result = minimize_steepest(
fun=lambda x: x.cost,
x0=state0,
jac=lambda x: x.wrap(x.gradient),
callback=UnconstrainedShapeOptimizationCallbackManager(...),
options={"rtol": 1.0e-3}
)
All the complexity of reconstructing the geometry, applying filters and computing the cost and gradient are handled by the wrangler and state classes. Furthermore, the reconstructed values are cached on the state, so they are never out of sync or unnecessarily recomputed.
- pystopt.simulation.unconstrained.make_unconstrained_shape_optimization_wrangler(places: pytential.GeometryCollection, cost: ShapeFunctional, *, is_spectral: bool = True, dofdesc: pytential.symbolic.primitives.DOFDescriptorLike | None = None, context: Dict[str, Any] | None = None, filter_type: FilterType = FilterType.Unfiltered, filter_arguments: Dict[str, Any] | None = None) UnconstrainedShapeOptimizationWrangler [source]#
Construct a
UnconstrainedShapeOptimizationWrangler
.
- class pystopt.simulation.unconstrained.UnconstrainedShapeOptimizationWrangler(places: pytential.GeometryCollection, dofdesc: pytential.symbolic.primitives.DOFDescriptor, is_spectral: bool, cost: ShapeFunctional, context: Dict[str, Any], filter_type: FilterType, filter_arguments: Dict[str, Any])[source]#
Bases:
ShapeOptimizationWrangler
- class pystopt.simulation.unconstrained.UnconstrainedShapeOptimizationState[source]#
Bases:
ShapeOptimizationState
Stokes-Constrained Shape Optimization#
- pystopt.simulation.staticstokes.make_stokes_shape_optimization_wrangler(places: pytential.GeometryCollection, cost: ShapeFunctional, op: TwoPhaseStokesRepresentation, *, viscosity_ratio: float = 1.0, capillary_number: float = inf, is_spectral: bool = True, dofdesc: pytential.symbolic.primitives.DOFDescriptorLike | None = None, context: Dict[str, Any] | None = None, filter_type: FilterType = FilterType.Unfiltered, filter_arguments: Dict[str, Any] | None = None, gmres_arguments: Dict[str, Any] | None = None)[source]#
Construct a
StokesShapeOptimizationWrangler
.The arguments are described in
StokesShapeOptimizationWrangler
.
- class pystopt.simulation.staticstokes.StokesShapeOptimizationWrangler(places: pytential.GeometryCollection, dofdesc: pytential.symbolic.primitives.DOFDescriptor, is_spectral: bool, op: TwoPhaseStokesRepresentation, lambdas: Dict[str, float], context: Dict[str, Any], gmres_arguments: Dict[str, Any], filter_type: FilterType, filter_arguments: Dict[str, Any], cost: ShapeFunctional)[source]#
Bases:
ShapeOptimizationWrangler
,StokesGeometryWrangler
- ad#
A
TwoPhaseStokesRepresentation
for the adjoint equations.
- class pystopt.simulation.staticstokes.StokesShapeOptimizationState[source]#
Bases:
ShapeOptimizationState
,StokesGeometryState
- get_adjoint_density() ndarray [source]#
The density in the boundary integral representation of the adjoint Stokes variables.
The adjoint operator is obtained from
StokesShapeOptimizationWrangler.ad
and solved.- Returns:
the adjoint density in the boundary integral representation.
- class pystopt.simulation.staticstokes.StokesShapeOptimizationCallbackManager(stop_file_name: Optional[pathlib.Path] = None, callbacks: Dict[str, pystopt.callbacks.CallbackCallable] = <factory>, short_circuit: bool = False, _force_gc: bool = True)[source]#
- class pystopt.simulation.staticstokes.StokesShapeOptimizationVisualizeCallback(norm: Callable[[Any], float] | None, visualize_file_series: Iterator[FileParts], overwrite: bool = False, frequency: int = 1)[source]#
Bases:
VisualizeCallback
- class pystopt.simulation.staticstokes.StokesShapeOptimizationHistoryCallback(norm: Optional[Callable[[Any], float]], memory: List[int] = <factory>, timestamp: List[int] = <factory>, f: List[float] = <factory>, g: List[float] = <factory>, d: List[float] = <factory>, alpha: List[float] = <factory>, volume: List[float] = <factory>, area: List[float] = <factory>, h_max: List[float] = <factory>, h_avg: List[float] = <factory>, h_std: List[float] = <factory>, deformation: List[float] = <factory>, u_dot_n: List[float] = <factory>)[source]#
Bases:
StokesHistoryCallback
,OptimizationHistoryCallback
,PerformanceHistoryCallback
Quasi-static Stokes-Constrained Optimization#
- class pystopt.simulation.quasistokes.StokesUnsteadyOptimizationWrangler(time: TimeWrangler, forward: StokesCostEvolutionWrangler, checkpoint_directory_series: Iterator[FileParts], overwrite: bool)[source]#
Bases:
object
A wrangler for doing optimization on the quasi-static Stokes equations.
By default, this does not actually compute any cost and gradient for optimization, but only sets up the appropriate forward and adjoint evolution equations.
The optimization supports cost functionals of of the form
\[J = \int_0^T j_t(\mathbf{u}, \mathbf{X}) \,\mathrm{d}t + j_T(\mathbf{X}(T))\]with a time-dependent component \(j_t\) (given by
cost
) and a final-time component \(j_T\) (given bycost_final
).- ambient_dim#
- dofdesc#
- time#
A
TimeWrangler
used for the forward and adjoint evolution.
- forward#
A
StokesCostEvolutionWrangler
describing the forward evolution.
- adjoint#
A
AdjointStokesCostEvolutionWrangler
describing the adjoint evolution. This wrangler is completely defined from the forward problem and usesAdjointBoundaryCondition
for the boundary condition.
- checkpoint_directory_series#
A generator for directory names that will contain any output from the forward and adjoint evolution equations. This can also always return the same directory name, in which case it will overwrite the previous data.
- get_initial_state(actx: ArrayContext) StokesUnsteadyOptimizationState [source]#
- evolve_forward(state: StokesUnsteadyOptimizationState, wrangler: StokesCostEvolutionWrangler) StokesCostEvolutionState [source]#
Evolve the quasi-static Stokes equations forward in time from state using wrangler.
- Parameters:
checkpoint_directory_name – a given directory to store checkpointed data and other visualization files.
- Returns:
a
StokesCostEvolutionState
containing the geometry at the final time and the cost functional value, integrated over all the time interval.
- evolve_adjoint(state: StokesUnsteadyOptimizationState, final_evolution_state: StokesCostEvolutionState, wrangler: AdjointStokesCostEvolutionWrangler) AdjointStokesCostEvolutionState [source]#
Evolve the quasi-static adjoint Stokes equations backward in time from state using wrangler, starting from the final solution of the forward problem final_evolution_state (as given by
evolve_forward()
).- Parameters:
checkpoint_directory_name – a given directory to read checkpointed data from and store other visualization files.
- Returns:
an
AdjointStokesCostEvolutionState
containing the adjoint transverse field at \(t = 0\) and the gradient, integrated over all the time interval.
- class pystopt.simulation.quasistokes.StokesUnsteadyOptimizationState(x: ndarray, wrangler: StokesUnsteadyOptimizationWrangler, array_context: ArrayContext)[source]#
Bases:
object
- wrangler#
- checkpoint_directory_name#
Directory containing the checkpointed data for the forward problem.
- cost#
- gradient#
- class pystopt.simulation.quasistokes.GeometryCostEvolutionWrangler(places: pytential.GeometryCollection, dofdesc: pytential.symbolic.primitives.DOFDescriptor, is_spectral: bool, evolution: StokesEvolutionOperator, context: Dict[str, Any], stabilizer_name: str, stabilizer_arguments: Dict[str, Any], filter_type: FilterType, filter_arguments: Dict[str, Any], cost: ShapeFunctional | None, cost_final: ShapeFunctional | None)[source]#
Bases:
GeometryEvolutionWrangler
An evolution wrangler that handles costs of the form
\[J = J_t + J_T = \int_0^T g(t, \mathbf{X}) \,\mathrm{d}t + g_T(\mathbf{X})\]with a term that considers contributions from the open time horizon \((0, T)\) and a term that considers the state at the final time. Either one of these can be omitted.
- cost#
The time-dependent term \(J_t\) in the cost functional.
- cost_final#
The final time term \(J_T\) in the cost functional.
- class pystopt.simulation.quasistokes.GeometryCostEvolutionState[source]#
Bases:
GeometryEvolutionState
A geometry evolved using a velocity field that also handles time-dependent cost functionals.
Given a cost functional of the form
\[J = \int_0^T g(t) \,\mathrm{d}t\]we can alternatively express it as an ODE
\[\begin{split}\left\{ \begin{aligned} \frac{\mathrm{d} j}{t} =\,\, & g(t), \\ j(0) =\,\, & 0, \end{aligned} \right.\end{split}\]such that \(J = j(T)\). This allows using the same time integrator as for the evolution equation and maintain the same order of convergence when computing the cost.
- j#
The value of the cost integrated up to the current time, as explained above.
- class pystopt.simulation.quasistokes.StokesCostEvolutionWrangler(places: pytential.GeometryCollection, dofdesc: pytential.symbolic.primitives.DOFDescriptor, is_spectral: bool, evolution: StokesEvolutionOperator, context: Dict[str, Any], stabilizer_name: str, stabilizer_arguments: Dict[str, Any], filter_type: FilterType, filter_arguments: Dict[str, Any], cost: ShapeFunctional | None, cost_final: ShapeFunctional | None, op: TwoPhaseStokesRepresentation, lambdas: Dict[str, float], gmres_arguments: Dict[str, Any])[source]#
Bases:
StokesEvolutionWrangler
,GeometryCostEvolutionWrangler
- class pystopt.simulation.quasistokes.AdjointStokesCostEvolutionWrangler(forward: StokesCostEvolutionWrangler)[source]#
- class pystopt.simulation.quasistokes.AdjointStokesCostEvolutionState[source]#
Bases:
AdjointStokesEvolutionState
Helpers#
Mixin classes used to provide various functionality for shape optimization.
- class pystopt.simulation.ShapeOptimizationWrangler(places: pytential.GeometryCollection, dofdesc: pytential.symbolic.primitives.DOFDescriptor, is_spectral: bool, cost: ShapeFunctional, context: Dict[str, Any], filter_type: FilterType, filter_arguments: Dict[str, Any])[source]#
Bases:
GeometryWrangler
- cost#
A
ShapeFunctional
used for the optimization.
- context#
Additional symbolic variables used to define the cost functional that will be used in the evaluation.
- filter_type#
The type of filter to be used of class
FilterType
.
- filter_arguments#
Additional filter arguments, that actually define the filter in use.
- apply_filter(actx: ArrayContext, places: pytential.GeometryCollection, ary: ArrayOrContainerT, *, force_spectral: bool | None = None) ArrayOrContainerT [source]#
Apply a filter to the given array ary.
By default, this function calls
apply_filter_by_type()
usingfilter_type
andfilter_arguments
.
- get_sym_shape_cost() pytential.symbolic.primitives.var [source]#
Symbolic expression for the shape cost functional.
- Returns:
a fully tagged expression for the cost.
- evaluate_shape_cost(actx: ArrayContext, places: pytential.GeometryCollection, *, context: Dict[str, Any] | None = None) float [source]#
Evaluates the cost functional from
get_sym_shape_cost()
.- Returns:
the value of the cost functional.
- get_sym_shape_gradient() ndarray [source]#
Symbolic expression for the shape gradient.
This functionality needs to be implemented by the subclasses, as the cost functional is not sufficient to define the gradient in the presence of constraints.
- Returns:
a fully tagged expression for the gradient.
- evaluate_shape_gradient(actx: ArrayContext, places: pytential.GeometryCollection, *, context: Dict[str, Any] | None = None, force_spectral: bool | None = None) ndarray [source]#
Evaluates the shape gradient from
get_sym_shape_gradient()
.By default, the filter from
apply_filter()
is applied to the gradient. No additional modifications are performed.- Returns:
the shape gradient for the problem, as set up.
- class pystopt.simulation.ShapeOptimizationState[source]#
Bases:
GeometryState
State vector for shape optimization.
Generic functions for obtaining the cost value and the gradient. In the general case, these functions just forward to the shape variants below and are here just to offer an abstract interface to follow.
When the full (unparametrized) shape gradient is required, use the functions below.
- evaluate_shape_cost() float [source]#
- Returns:
the value of the cost functional at the current state.
- class pystopt.simulation.StokesGeometryWrangler(places: pytential.GeometryCollection, dofdesc: pytential.symbolic.primitives.DOFDescriptor, is_spectral: bool, op: TwoPhaseStokesRepresentation, lambdas: Dict[str, float], context: Dict[str, Any], gmres_arguments: Dict[str, Any], filter_type: FilterType, filter_arguments: Dict[str, Any])[source]#
Bases:
GeometryWrangler
- context#
Additional symbolic variable values used in evaluation.
- gmres_arguments#
A
dict
of additional parameters passed on tosingle_layer_solve()
.
- filter_type#
The type of filter to be used of class
FilterType
.
- filter_arguments#
Additional filter arguments, that actually define the filter in use.
- apply_filter(actx: ArrayContext, places: pytential.GeometryCollection, ary: ArrayOrContainerT, *, force_spectral: bool | None = None) ArrayOrContainerT [source]#
Apply a filter to the given array ary.
By default, this function calls
apply_filter_by_type()
usingfilter_type
andfilter_arguments
.
- get_stokes_solution(actx: ArrayContext, op: TwoPhaseStokesRepresentation, places: pytential.GeometryCollection, *, context: Dict[str, Any] | None = None, cached: bool = True) StokesSolution [source]#
Solves the Stokes problem on the given geometry in places.
- Parameters:
op – a
TwoPhaseStokesRepresentation
of the problem that can be solved for the density. This is not necessarily the same asop
.cached – if True, the density resulting from the solve is cached and used as an initial guess for subsequent calls to this function. The cache can be cleared at any time using
clear_density_cache()
.
- class pystopt.simulation.StokesGeometryState[source]#
Bases:
GeometryState
A
GeometryState
that contains the Stokes flow solution on the given geometry.- get_stokes_density() ndarray [source]#
- Returns:
the density in the boundary integral representation.
- get_stokes_velocity() ndarray [source]#
- Returns:
the velocity field for the current geometry using the density from
get_stokes_density()
.
Additional callbacks specifically for shape optimization.
- class pystopt.simulation.ShapeOptimizationCallbackManager(stop_file_name: ~pathlib.Path | None = None, callbacks: ~typing.Dict[str, ~pystopt.callbacks.CallbackCallable] = <factory>, short_circuit: bool = False, _force_gc: bool = True)[source]#
Bases:
CallbackManager
A callback manager that handles variables of the type
ShapeOptimizationState
.In particular, it expects a keyword argument of the type
CGCallbackInfo
containing the optimization information.- __call__(*args: Any, **kwargs: Any) int [source]#
Calls all the callbacks in
callbacks
and aggregates their return values.In addition to the input arguments, the manager also inserts the keyword ncalls, with the number of calls to this class.
- Returns:
\(0\) to stop the optimization and another integer otherwise.
Additional callbacks specifically for the Stokes equations.
- class pystopt.simulation.StokesHistoryCallback(norm: ~typing.Callable[[~typing.Any], float] | None, memory: ~typing.List[int] = <factory>, timestamp: ~typing.List[int] = <factory>, volume: ~typing.List[float] = <factory>, area: ~typing.List[float] = <factory>, h_max: ~typing.List[float] = <factory>, h_avg: ~typing.List[float] = <factory>, h_std: ~typing.List[float] = <factory>, deformation: ~typing.List[float] = <factory>, u_dot_n: ~typing.List[float] = <factory>)[source]#
Bases:
MeshQualityHistoryCallback
- deformation#
Deformation of the geometry in the \((x, y)\) plane.
- u_dot_n#
Maximum absolute value of the normal velocity, i.e. \(\|\mathbf{u} \cdot \mathbf{n}\|_\infty\).