Skip to content

Cartesian meshes and local spaces

CartesianMacroMesh represents axis-aligned rectangles with shared faces and canonical orientations. Use it to configure global geometry, local refinement and face spaces independently. The method tutorials then define the local and global variational equations on those choices.

Select the global and local geometry

from pymhm.meshes.cartesian import CartesianMacroMesh

macro = CartesianMacroMesh(4, 4, bounds=(0.0, 1.0, 0.0, 1.0))
fine = macro.submesh(0, (8, 8))

The first pair specifies macrocell counts. bounds contains physical (xmin, xmax, ymin, ymax). Local subdivisions specify fine rectangles inside a selected macrocell; they do not change the global skeleton size.

For a bound hierarchy, supply an importable local mesh factory:

from functools import partial
from pymhm import MeshHierarchy

hierarchy = MeshHierarchy(macro, partial(macro.submesh, subdivisions=(8, 8)))

The portable geometry is created in the requesting worker. No native FEM object crosses a process boundary. When using another local mesh constructor, keep its macroface geometry consistent with the selected interface adapter.

Configure face degree, partition and continuity

from pymhm import bind_interface
from pymhm.fem.traces.interval import FaceSpace, SkeletonSpace

faces = tuple(FaceSpace.uniform(1, 4, continuous=True) for _ in macro.faces)
skeleton = SkeletonSpace(macro, faces)
interface = bind_interface(skeleton, convention="normal")

This gives a continuous P1 basis on four segments of each complete macroface. Continuity within a face does not impose continuity between unrelated faces. The normal convention declares a normal-oriented trace and supplies canonical-to-outward incidence signs. Its physical meaning follows the local equations: a normal-oriented multiplier can represent Darcy flux, a Robin quantity or pseudotraction. Use the value convention only when it matches the formulation you write.

The built-in Cartesian numerical coupling integrates over the union of local fine-edge and face-space breakpoints. These partitions need not coincide, but they must form a stable discrete pair. An excessively enriched skeleton can have invisible local modes; a small algebraic residual is not evidence of stability. Native UFL trace integration follows its supported facet-alignment contract in the FEniCSx guide.

Choose the volume element and material integration

A scalar local.native_space(degree=k) on a quadrilateral mesh provides the supported equispaced tensor-product Lagrange Qk pressure space. State the retained modes and physical moments in your provider; changing the cell family does not supply a PDE or select a pressure gauge.

Numerical Qk operators use tensor-product Gauss quadrature. A discontinuous CartesianCellField coefficient requires integration across its actual pixel interfaces. The shared Cartesian numerical owner splits integration rectangles at those interfaces; an aligned grid uses its uniform path. UFL forms instead need a corresponding native integration mesh or explicit subdomain integration. See heterogeneous coefficients.

Evaluate with the executed coefficient order

For a bound nodal field, register it in the provider and access its local views through solution.field(name). Each view retains the executed basis and returns its independent one-sided values. Numerical Qk evaluators follow their own recorded nodal order; do not reuse native coefficient vectors without the appropriate mapping.

Darcy flux is \(-K\nabla p\). A raw Qk gradient field is generally not H(div) conforming and does not imply fine-cell conservation. The integrated skeleton flux defines macro conservation. Use the recovery tutorials when a conforming recovered flux is required.

Cartesian geometry is axis aligned. Warped or curved quadrilateral cells need a different geometry/element adapter; this constructor does not silently approximate them as rectangles.