dragonfly_sim.core.form_manager

Attributes

CELL_TAG

INTERIOR_FACET_TAG

Classes

FormManager

Owns the integration measures and the form graph.

Functions

_all_entities_meshtags(mesh, dim, value)

Module Contents

class dragonfly_sim.core.form_manager.FormManager(mesh_obj, model=None, measure_source=None)

Owns the integration measures and the form graph.

Instances come in two flavours, because the two things have different lifetimes:

  • MESH-LEVEL (model=None, reached as mesh_obj.form_manager): owns the measures. There is one per Mesh, so every model built on that Mesh integrates against the same measures.

    Mesh itself exposes no dx/dS/ds. It did briefly, as delegating properties, and that was worse than either alternative: a measure reached through the Mesh reads as though the Mesh owned it, which is the exact misreading that let the old construct_* methods overwrite measures in place underneath compiled forms and live postprocessor reads. Naming the owner at every use site is the point.

  • MODEL-LEVEL (model=…, measure_source=<the mesh-level one>): owns one model’s residual/Jacobian expressions and its compiled forms, and reads the measures through the mesh-level instance.

The measures are built incrementally, because the two construction calls are independent and the existing call order varies: set_up_sim builds the boundary measure first (it needs the facet split to tag the wall before the mesh warper is constructed) and dx/dS later, while some tests build dx/dS and never build ds at all.

_measures()

The manager that actually holds the measures (self, or the mesh-level one).

assemble_matrix_scipy(key, factory=None, csr=False)

The compiled form registered under key, assembled as a scipy sparse matrix.

NOTE the format. MatrixCSR.to_scipy() returns BSR, not CSR, whenever the space is blocked – which the Euler state space always is (block size 2 + dimensions). scipy’s BSR does not implement row indexing at all (it raises NotImplementedError), so pass csr=True for anything that slices rows. The default keeps the block structure, which is the cheaper representation when you only need matvecs.

build_boundary_measure(measure_metadata=None)

ds, over the boundary facet tagging already on the Mesh.

The tagging itself stays Mesh.tag_boundary_facets’ job and is NOT built here. It is mesh topology, not a measure: the mesh warper, the FFD wall-node selection and the meshtags XDMF export all read Mesh.meshtags without ever touching a form. Only the measure derived from it belongs to this class.

Unlike dx/dS this measure comes back UNrestricted, because every call site applies its own tag: ds(WALL_TAG), ds(INLET_TAG), …

build_cell_and_interior_facet_measures(measure_metadata=None)

dx and dS, tagged and backed by all-ones MeshTags.

Both come back already restricted to their tag, so a call site writes * forms.dx and gets dx(CELL_TAG).

build_residual(U_coeff=None)

The physical residual: interior + boundary flux terms.

U_coeff is accepted for backward compatibility but has no effect.

The physics itself stays on CompressibleEulerModel; this composes it.

compiled(key, factory=None)

The compiled form (dolfinx.fem.form) of the expression registered under key, compiled on first request and cached.

ufl_form(key, factory=None)

The UFL expression registered under key, building it on demand.

_cell_tags = None
_compiled
_dS = None
_ds = None
_dx = None
_interior_facet_tags = None
_measure_source = None
_ufl_forms
boundary_metadata = None
cell_metadata = None
property dS
property ds
property dx
mesh
mesh_obj
model = None
dragonfly_sim.core.form_manager._all_entities_meshtags(mesh, dim, value)
dragonfly_sim.core.form_manager.CELL_TAG = 1
dragonfly_sim.core.form_manager.INTERIOR_FACET_TAG = 1