Core#
Spaces#
For new public-facing mixed setups, prefer MixedSpaces(...).to_fe_space().
MixedFESpace remains available as a lower-level constructor for advanced
or internal usage.
- class fluxfem.core.FESpaceBase(*args, **kwargs)#
Protocol for FE space objects used by assembly.
This defines the minimal interface required by the core assembly routines: element-to-DOF connectivity, value dimension, and the ability to build per-element FormContext objects (test/trial fields plus quadrature data).
- fluxfem.core.FESpace#
alias of
FESpaceClosure
- class fluxfem.core.FESpacePytree(mesh: BaseMesh, basis: Basis3D, elem_dofs: jnp.ndarray, value_dim: int = 1, _n_dofs: int | None = None, _n_ldofs: int | None = None, data: SpaceData | None = None, _pattern_cache: PatternCache = <factory>, _kernel_cache: KernelCache = <factory>, _form_context_cache: dict[ContextCacheKey, FormContext]=<factory>, _elem_rows_cache: jnp.ndarray | None = None)#
FESpaceClosure with JAX pytree support.
Use this when a space must be carried through JAX transformations (jit/vmap), or stored inside other pytrees. Only mesh, basis, and elem_dofs are treated as children; metadata is preserved as auxiliary data.
- class fluxfem.core.MixedFESpace(fields: dict[str, FESpaceClosure], field_order: Sequence[str] | None = None, field_to_space_key: Mapping[str, str] | None = None, field_alias_space_keys: Mapping[str, Sequence[str]] | None = None)#
Mixed FE space composed of multiple scalar/vector spaces.
- Field DOFs are concatenated in field order:
[field0 dofs | field1 dofs | …]
- class fluxfem.core.MixedProblem(space: MixedFESpace, residuals: dict[str, Callable] | MixedWeakForm, params: object | None = None, pattern: object | None = None, n_chunks: int | None = None, pad_trace: bool = False)#
Lightweight wrapper for mixed residual assembly with cached compilation.
- class fluxfem.core.MixedBlockSystem(mixed: 'MixedFESpace', K: 'object', F: 'object', free_dofs: 'np.ndarray', dirichlet: 'MixedDirichletBC')#
- fluxfem.core.make_space(mesh: BaseMeshClosure, basis: Basis3D, element: ElementVector | None = None) FESpaceClosure#
Build an FE space from a mesh and basis.
element=None → scalar dof per node (elem_dofs = mesh.conn), value_dim=1 element=ElementVector(dim) → vector dof per node, value_dim=dim
- fluxfem.core.make_space_pytree(mesh: jax.tree_util.register_pytree_node_class, basis: Basis3D, element: ElementVector | None = None) jax.tree_util.register_pytree_node_class#
Build a pytree-compatible FE space.
- fluxfem.core.make_hex_space(mesh: HexMesh, dim: int = 1, intorder: int = 2) FESpaceClosure#
Create a trilinear hex space (8-node elements).
- fluxfem.core.make_hex_space_pytree(mesh: HexMesh, dim: int = 1, intorder: int = 2) jax.tree_util.register_pytree_node_class#
Create a pytree trilinear hex space (8-node elements).
Forms#
- class fluxfem.core.FormContext(test: FormFieldLike, trial: FormFieldLike, x_q: jnp.ndarray, w: jnp.ndarray, elem_id: jnp.ndarray | int = 0, spaces: dict[str, 'FieldPair'] | None = None, default_space: str | None = None)#
Bundle test/trial fields and quadrature data for element assembly.
- class fluxfem.core.MixedFormContext(bindings: dict[str, FieldPair], x_q: jnp.ndarray, w: jnp.ndarray, elem_id: jnp.ndarray | int = 0, unknown: FormFieldLike | None = None, spaces: dict[str, FieldPair] | None = None, default_space: str | None = None)#
FormContext for mixed formulations keyed by binding/field name.
- class fluxfem.core.VolumeContext(*args, **kwargs)#
Minimum interface for volume weak-form evaluation.
- class fluxfem.core.SurfaceContext(*args, **kwargs)#
Minimum interface for surface weak-form evaluation.
- class fluxfem.core.LinearForm(fn, *, kind: str)#
Linear form wrapper with volume/surface backends.
- class fluxfem.core.BilinearForm(fn, *, kind: str)#
Bilinear form wrapper with volume/surface backends.
- class fluxfem.core.ResidualForm(fn)#
Residual form wrapper.
- class fluxfem.core.MixedWeakForm(*, residuals: Mapping[str, Callable | Expr | MixedResidualBinding])#
Container for mixed weak-form residuals keyed by residual label.
- fluxfem.core.make_mixed_residuals(residuals: Mapping[str, Callable | Expr | MixedResidualBinding] | None = None, **kwargs) dict[str, Callable | Expr | MixedResidualBinding]#
Helper to build mixed residual dictionaries.
Example
res = make_mixed_residuals(u=res_u, p=res_p)
- fluxfem.core.bind_mixed_residual(target: str, fn: Callable | Expr, *, space: str | None = None) MixedResidualBinding#
Create an explicit mixed residual binding.
- fluxfem.core.kernel(*, kind: str, domain: str = 'volume')#
Decorator to tag raw kernels with kind/domain metadata for assembly inference.
Kernel metadata (ff.kernel)#
@ff.kernel attaches metadata used by space.assemble to infer the
form kind and domain. The following combinations are supported:
kind |
domain |
expected kernel signature |
|---|---|---|
bilinear |
volume |
|
linear |
volume |
|
linear |
surface |
|
residual |
volume |
|
jacobian |
volume |
|
Use domain="surface" with a surface-specific assembly helper. For most workflows
use SurfaceMesh.assemble_linear_form_on_space(...); lower-level options include
assemble_surface_linear_form and assemble_surface_bilinear_form when you need
explicit dim/n_total_nodes control.
Example (MixedProblem)#
mixed = ff.MixedSpaces(
{
"u": ff.ResidualSpaces(
test=ff.NamedSpace("V", space),
unknown=ff.NamedSpace("U", space),
),
"p": ff.ResidualSpaces(
test=ff.NamedSpace("Qv", space),
unknown=ff.NamedSpace("Q", space),
),
}
).to_fe_space()
residuals = ff.make_mixed_residuals(
u=ff.bind_mixed_residual("u", res_u, space="U"),
p=ff.bind_mixed_residual("p", res_p, space="Q"),
)
params = ff.Params(alpha=1.2, beta=-0.4)
pattern = mixed.get_sparsity_pattern(with_idx=True)
problem = ff.MixedProblem(mixed, residuals, params=params, pattern=pattern)
u0 = jnp.zeros(mixed.n_dofs)
K = problem.assemble_jacobian(u0)
R = problem.assemble_residual(u0)
Mixed naming convention:
ctx.test/ctx.trialfor simple single-space codectx.bindings["u"]for named mixed-field lookupctx.spaces["U"]for explicit space-key lookupalias keys such as
ctx.spaces["V"]can point to the same mixed field when a field was declared throughResidualSpaces/JacobianSpaces
Example (MixedBlockSystem)#
This helper currently applies to MixedSpaces(...).to_fe_space() /
MixedFESpace style layouts. It does not yet support
MixedRoleSpaces(...).to_fe_space().
blocks = {
"u": {"u": Kuu, "p": Kup},
"p": {"u": Kpu, "p": Kpp},
}
rhs = {"u": Fu, "p": Fp}
constraints = {"u": (u_dofs, u_vals)}
system = mixed.build_block_system(blocks=blocks, rhs=rhs, constraints=constraints)
u_free = solver.solve(system.K, system.F)
u_full = system.expand(u_free)
fields = system.split(u_full)
Assembly#
- fluxfem.core.make_sparsity_pattern(space: SpaceLike, *, with_idx: bool = True) Any#