Skip to content

Manifold integral redesign#100

Merged
biancagi merged 52 commits into
mainfrom
manifold-integral-redesign
Jul 4, 2026
Merged

Manifold integral redesign#100
biancagi merged 52 commits into
mainfrom
manifold-integral-redesign

Conversation

@biancagi

@biancagi biancagi commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

This PR introduces a redesign of the manifold, integral, function space, finite element, and weak-form integration layers. The main goal is to clarify the separation of responsibilities between the mesh topology, the manifold geometry, and the finite element discretization.

In the new design, mesh cells remain purely geometric/topological objects, while manifolds provide the local parametrization and metric information needed to interpret those cells as elements of a manifold. Function spaces no longer store finite element objects directly; instead, they build finite elements on demand by combining mesh cells with the required local manifold geometry and shape functions.

The integration layer has also been redesigned to use this information directly from the element being integrated. This avoids re-implementing parts of the manifold layer inside the integrator and removes hidden assumptions about the element parametrization or metric volume form.

Main changes

  1. Moved differential operators to a dedicated namespace

Differential operators have been moved to the new operators namespace, making their role explicit and keeping them separate from the geometry, manifold, and finite element layers. This is a first step towards metric-aware differential operators.

  1. Renamed Euclidean metric types

Euclidean metrics and metric spaces have been renamed to make their Euclidean nature explicit in the type names. This avoids ambiguity with the more general metric structures that @Pawel024 has been working on.

  1. Redesigned isoparametric finite elements

Isoparametric finite elements are now self-contained finite element objects. They carry all the local information needed for finite element computations, including the element parametrization, the metric volume form, and of course the shape functions.

This makes the finite element the natural object passed to blocks and integrators: all geometric and interpolation data required for integration can be accessed from the element itself.

  1. Redesigned weak-form blocks

The weak-form integration layer has been simplified. A weak form now stores a single left-hand-side block and a single right-hand-side block, rather than collections of blocks.

Support for composing multiple contributions will be added later through an algebra of (compatible) blocks.

  1. Redesigned Manifold

Manifold is now equipped with an Atlas, which provides the local parametrizations of the mesh cells. Given a mesh cell, the manifold can construct a ParametrizedElement, i.e. a local manifold element equipped with its parametrization and metric volume form.

As a consequence, GeometricSimplex no longer stores or knows about parametrizations. It remains a lower-level geometric object, while parametrization belongs to the manifold layer.

  1. Redesigned Integrator

Integrator is now fully integrated with the geometry layer. It no longer hard-codes an element parametrization; instead, it uses the parametrization and metric volume form provided by the element being integrated.

This makes integration independent of a specific element geometry implementation and allows the same integration machinery to work with elements provided by the manifold layer.

  1. Redesigned FunctionSpace

FunctionSpace no longer stores finite element instances. Instead, it builds them on demand by endowing mesh cells with the required local element geometry and shape functions.

In practice, the function space now acts as the layer that combines the mesh cell, the local manifold geometry provided by the manifold/atlas, and the finite element interpolation data.

biancagi and others added 30 commits March 8, 2026 15:36
After this revision, it is now possible to implement 'geomertry-aware' differential operators. Before this change, since {differential.h} was within {fields}, there would be a cyclic dependency between fields->geometry->fields.
Vectors of one component no longer cast to their atomic type after rev. 7736bfe of {pyre/tensor}.
The first half of this test is trivial; the other half follows an incorrect logic. In fact this test checks that the gradient in parametric space equals the gradient in cartesian space, which of course is not true in general.
…ring

Align parametric coordinates with the standard reference-space convention.
Use {1.0} instead of {1}.
… geometric simplices given metric volume form and coordinate system
These tests will be re-enabled once higher order parametrizations are implemented.
The weakform stores a single left hand side block and a single right hand side block, as opposed to a collection of them.
This requires implementing an algebra of blocks, so we can mix and match them before handing them ot the weakform.
Also, this means that blocks do not need to derive from a common parent class any more.
A manifold is now equipped with an {Atlas}, which provides the parametrization of elements in the manifold. The {parametrization} method has hence been removed from {GeometricSimplex}.

Also, now manifolds are able to expose fully-fledged parametrized elements with attached their own metric volume form.

The {Integrator} class is now fully integrated with the differential geometry layer, so it does no longer feel that things are done twice (e.g. element parametrization).

The Poisson benchmark has been temporarily commented out as the function space and blocks still need to adjust to the new design.
Finite elements are now templated with respect to the parametrized element, which provides the geometric context. Finite elements have now access to their own parametrization, which can be used to compute the compute the coordinates of the nodes without resorting to the coordinate system.

The function space class does not store the finite elements any more, but it builds them on the fly upon request by endowing mesh cells with local element geometry information (manifold element) and shape functions.
biancagi added 18 commits June 22, 2026 15:07
Make explicit the assumption that the metric space to be built is Euclidean.
… infer the space dimension from the value of {D} of {node_t}

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR redesigns manifold integration by making the metric volume form an explicit part of manifold construction and by shifting element geometry/parametrization responsibilities into a new atlas/parametrized-element model. It also splits differential calculus out of fields into a dedicated operators interface and refactors FEM element construction/discretization to use trait-based finite element families and per-cell connectivity tables.

Changes:

  • Require an explicit metric volume form when constructing manifolds; add Atlas, ParametrizedElement, and element views to support on-demand parametrized elements.
  • Rewrite quadrature integration to evaluate parametrizations/Jacobians and metric volume forms at quadrature points (weights normalized to 1, scaled by reference simplex measure).
  • Introduce mito::operators (gradient/divergence) and update tutorials/tests/benchmarks; rename metric APIs to euclidean_metric / euclidean_metric_space; refactor FEM elements/weakforms accordingly.

Reviewed changes

Copilot reviewed 141 out of 143 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tutorial/5_divergence_theorem_2D_in_3D/main.cc Use mito::operators namespace in tutorial.
tutorial/4_divergence_theorem_2D/main.cc Pass explicit metric volume form when building manifolds; use operators.
tutorial/3_fields/main.cc Use mito::operators namespace in tutorial.
tests/mito.lib/quadrature/quadrature_triangle_2D.cc Construct manifold with explicit metric volume form.
tests/mito.lib/quadrature/quadrature_segment_3D.cc Update segment factory call signature.
tests/mito.lib/quadrature/quadrature_segment_1D.cc Construct manifold with explicit metric volume form; minor numeric literal cleanup.
tests/mito.lib/operators/gradient_non_square.cc Switch tests from fields to operators.
tests/mito.lib/operators/calculus_vector_field.cc Switch tests from fields to operators.
tests/mito.lib/operators/calculus_scalar_field.cc Switch tests from fields to operators.
tests/mito.lib/operators/calculus_identities.cc Switch tests from fields to operators.
tests/mito.lib/mesh/tetra_rectangle_2D.cc New mesh refinement/area test using geometry::volume + metric form.
tests/mito.lib/mesh/tetra_cube_3D.cc Update volume validation to sum per-cell geometry::volume.
tests/mito.lib/mesh/half_ball.cc Move manifold volume test to mesh/volume computation with metric form.
tests/mito.lib/mesh/disk_polar_cartesian.cc Move manifold volume test to mesh/volume computation with metric form.
tests/mito.lib/mesh/disk_change_coordinates.cc Move manifold volume test to mesh/volume computation with metric form.
tests/mito.lib/manifolds/tetra_rectangle_2D.cc Remove old manifolds-based tetra rectangle volume test.
tests/mito.lib/manifolds/spherical_gradient.cc Switch metric space type to euclidean_metric_space.
tests/mito.lib/manifolds/polar_gradient.cc Switch metric space type to euclidean_metric_space.
tests/mito.lib/manifolds/manifold_elements_view.cc New test for iterating parametrized manifold elements.
tests/mito.lib/manifolds/euclidean_gradient.cc Switch metric space type to euclidean_metric_space.
tests/mito.lib/io/vtk_mesh_writer_2D.py Update expected VTK mesh sizes.
tests/mito.lib/integration/quadrature_load_mesh_2D.cc Construct manifold with explicit metric volume form.
tests/mito.lib/integration/quadrature_load_mesh_2D_mpi.cc Construct manifold with explicit metric volume form.
tests/mito.lib/integration/quadrature_flip_segment_3D.cc Update segment factory call signature.
tests/mito.lib/integration/divergence_theorem.cc Use operators::divergence and explicit metric volume form manifold.
tests/mito.lib/geometry/triangle_3D.nb New notebook artifact for reference calculation.
tests/mito.lib/geometry/triangle_3D.cc Replace manifold-based area check with direct metric-form contraction.
tests/mito.lib/geometry/triangle_2D.cc Replace manifold-based area check with geometry::volume + metric form.
tests/mito.lib/geometry/tetrahedron_3D.cc Replace manifold-based volume check with geometry::volume + metric form.
tests/mito.lib/geometry/spherical_metric_space.cc Switch to euclidean_metric_space.
tests/mito.lib/geometry/segment_2D.cc New geometry test for segment length via restricted volume form.
tests/mito.lib/geometry/polar_metric_space.cc Switch to euclidean_metric_space.
tests/mito.lib/geometry/metric.cc Rename metrics to euclidean_metric and add compatibility static_asserts.
tests/mito.lib/geometry/euclidean_metric_space.cc Switch to euclidean_metric_space.
tests/mito.lib/geometry/euclidean_metric_1D.cc New 1D Euclidean metric test.
tests/mito.lib/geometry/cell_directors.cc Update simplex factories to new signatures.
tests/mito.lib/geometry/barycenter_triangle_3D.cc Update triangle factory signature.
tests/mito.lib/geometry/barycenter_triangle_2D.cc Update triangle factory signature.
tests/mito.lib/geometry/barycenter_tetrahedron_3D.cc Update tetrahedron factory signature.
tests/mito.lib/geometry/barycenter_segment_3D.cc Update segment factory signature.
tests/mito.lib/geometry/barycenter_segment_2D.cc Update segment factory signature.
tests/mito.lib/geometry/barycenter_segment_1D.cc Update segment factory signature.
tests/mito.lib/fem/shape_functions_triangle_p2.cc Rename to parametric coordinates and update node locations.
tests/mito.lib/fem/shape_functions_triangle_p1.cc Rename to parametric coordinates and update node locations.
tests/mito.lib/fem/localize_field.cc Remove outdated FEM localization test.
tests/mito.lib/fem/isoparametric_triangle.cc Refactor FEM test to build parametrized elements + trait-based finite elements.
tests/mito.lib/fem/isoparametric_segment.cc Refactor FEM test to build parametrized elements + trait-based finite elements.
tests/mito.lib/fem/fem_field.cc Update function space element iteration and manifold construction API.
tests/mito.lib/fem/block_mass.cc Refactor mass block tests to trait-based finite elements + parametrized elements.
tests/mito.lib/fem/block_mass_segment.cc Refactor segment mass block test to trait-based finite elements + parametrized elements.
tests/mito.lib/fem/block_grad_grad.cc Refactor grad-grad block tests to trait-based finite elements + parametrized elements.
tests/mito.lib/fem/block_grad_grad_segment.cc Refactor segment grad-grad block test to trait-based finite elements + parametrized elements.
tests/input/rectangle.geo Reorder line loop/orientation for rectangle geometry.
lib/mito/utilities/utilities.h Add tuple-like concept utilities for tuple contraction.
lib/mito/utilities/externals.h Add <tuple>/<unordered_map> includes to externals.
lib/mito/tensor/Form.h Add tuple-like contraction overloads for forms.
lib/mito/tensor/externals.h Include utilities for tuple-like support.
lib/mito/quadrature/QuadratureTable.h Rename “barycentric” to “parametric” in quadrature point type docs.
lib/mito/quadrature/Integrator.h Rewrite integrator to compute metric volume element at quadrature points.
lib/mito/operators/public.h New public header aggregating operators API.
lib/mito/operators/forward.h New operators forward header.
lib/mito/operators/factories.h New (currently empty) operators factories header.
lib/mito/operators/externals.h New operators externals (includes geometry).
lib/mito/operators/differential.h Move gradient/divergence into mito::operators namespace.
lib/mito/operators/api.h New (currently empty) operators api header.
lib/mito/operators.h New top-level operators include.
lib/mito/manifolds/public.h Publish new atlas/parametrized element/view headers.
lib/mito/manifolds/ParametrizedElement.h New parametrized element type (cell + parametrization + metric form).
lib/mito/manifolds/ManifoldElementsView.h New iterable view producing parametrized elements on demand.
lib/mito/manifolds/Manifold.h Refactor manifold to store atlas + metric volume form; expose element view.
lib/mito/manifolds/forward.h Add forward declarations/concepts for new manifold types.
lib/mito/manifolds/factories.h Add atlas/parametrized_element factories; require metric form for manifolds.
lib/mito/manifolds/Atlas.h New atlas class providing cell parametrizations under a coordinate system.
lib/mito/manifolds/api.h Add aliases and declarations for atlas/parametrized elements/views.
lib/mito/io/vtk/NodeVTKWriter.h Adjust VTK writer to new function space/finite element type plumbing.
lib/mito/geometry/utilities.h Add geometry::volume(cell, coord_system, volume_form) helper.
lib/mito/geometry/spherical/metric.h Rename spherical metric specialization to euclidean_metric.
lib/mito/geometry/spherical/api.h Rename spherical metric API to euclidean_metric.
lib/mito/geometry/ReferenceSimplex.h Rename reference simplex area to measure; redefine xi<> layout.
lib/mito/geometry/public.h Switch public include from metric_space.h to euclidean_metric_space.h.
lib/mito/geometry/polar/metric.h Rename polar metric specialization to euclidean_metric.
lib/mito/geometry/polar/api.h Rename polar metric API to euclidean_metric.
lib/mito/geometry/metric.h Rename metric template to euclidean_metric.
lib/mito/geometry/GeometricSimplex.h Expose xi<I>() on simplices; remove old parametrization method.
lib/mito/geometry/forward.h Add compatible_metric_c concept.
lib/mito/geometry/factories.h Update segment/triangle/tetrahedron factories to node-arg signatures.
lib/mito/geometry/euclidean_metric_space.h Rename metric_space to euclidean_metric_space; update internals.
lib/mito/geometry/cartesian/metric.h Rename cartesian metric specialization to euclidean_metric.
lib/mito/geometry/cartesian/api.h Rename cartesian metric API to euclidean_metric.
lib/mito/functions/forward.h Treat coordinate outputs as tensor-valued for function concepts.
lib/mito/fields/public.h Remove differential calculus include (moved to operators).
lib/mito/fem/Weakform.h Simplify weakform to hold one LHS and one RHS block (by value).
lib/mito/fem/public.h Reorder includes and publish function-space element view.
lib/mito/fem/norms.h Switch to operators::gradient and trait-based block types.
lib/mito/fem/FunctionSpaceElementsView.h New iterable view producing finite elements on demand.
lib/mito/fem/FunctionSpace.h Refactor to connectivity-table-based discretization + element view.
lib/mito/fem/forward.h Update function space / weakform forward declarations and concepts.
lib/mito/fem/FemField.h Make FemField independent of function space type; localize via connectivity.
lib/mito/fem/factories.h Update function_space/weakform/discrete_system factories for new APIs.
lib/mito/fem/elements/tri2/ShapeTriangleP2.h Update reference xi usage and switch gradients to operators::gradient.
lib/mito/fem/elements/tri2/public.h Add forward header and adjust publish/include order.
lib/mito/fem/elements/tri2/IsoparametricTriangleP2.h Refactor element to wrap parametrized element + trait-based connectivity.
lib/mito/fem/elements/tri2/forward.h New forward declaration for templated P2 triangle element.
lib/mito/fem/elements/tri2/DiscretizerCG.h Discretize into a per-cell connectivity table (no element container).
lib/mito/fem/elements/tri2/api.h Define finite_element_family traits for quadratic triangles.
lib/mito/fem/elements/tri1/ShapeTriangleP1.h Update reference xi usage and switch gradients to operators::gradient.
lib/mito/fem/elements/tri1/public.h Add forward header and adjust publish/include order.
lib/mito/fem/elements/tri1/IsoparametricTriangleP1.h Refactor element to wrap parametrized element + trait-based connectivity.
lib/mito/fem/elements/tri1/forward.h New forward declaration for templated P1 triangle element.
lib/mito/fem/elements/tri1/DiscretizerCG.h Discretize into a per-cell connectivity table (no element container).
lib/mito/fem/elements/tri1/api.h Define finite_element_family traits for linear triangles.
lib/mito/fem/elements/seg1/ShapeSegmentP1.h Update reference xi usage and switch gradients to operators::gradient.
lib/mito/fem/elements/seg1/public.h Add forward header and adjust publish/include order.
lib/mito/fem/elements/seg1/IsoparametricSegmentP1.h Refactor element to wrap parametrized element + trait-based connectivity.
lib/mito/fem/elements/seg1/forward.h New forward declaration for templated P1 segment element.
lib/mito/fem/elements/seg1/DiscretizerCG.h Discretize into a per-cell connectivity table (no element container).
lib/mito/fem/elements/seg1/api.h Define finite_element_family traits for linear segments.
lib/mito/fem/elements/public.h Remove legacy base element headers from public surface.
lib/mito/fem/elements/IsoparametricTriangle.h Remove legacy non-templated base triangle element.
lib/mito/fem/elements/IsoparametricSegment.h Remove legacy non-templated base segment element.
lib/mito/fem/elements/forward.h Add concept for parametrized-element compatibility.
lib/mito/fem/elements/externals.h Include operators for shape-function gradient construction.
lib/mito/fem/elements/elements_library.h Introduce forward for finite_element_family trait template.
lib/mito/fem/elements/Discretizer.h Update discretizer plumbing to fill connectivity tables.
lib/mito/fem/elements/api.h Add finite_element(...) factory from parametrized element + connectivity.
lib/mito/fem/DiscreteSystem.h Make DiscreteSystem depend on an explicit weakform type.
lib/mito/fem/blocks/SourceTermBlock.h Refactor block API to be traits-based and non-virtual.
lib/mito/fem/blocks/public.h Remove virtual AssemblyBlock include from public surface.
lib/mito/fem/blocks/MassBlock.h Refactor block API to be traits-based and non-virtual.
lib/mito/fem/blocks/L2NormBlock.h Refactor block API to be traits-based and non-virtual.
lib/mito/fem/blocks/GradGradBlock.h Refactor block API to be traits-based and non-virtual.
lib/mito/fem/blocks/forward.h Add finite-element instance concept and update comments/decls.
lib/mito/fem/blocks/AssemblyBlock.h Remove legacy virtual base block type.
lib/mito/fem/blocks/api.h Remove assembly_block_t alias; keep concrete block aliases.
lib/mito/fem/api.h Update FEM public aliases/factories for new templates and weakform/system signatures.
lib/mito/coordinates/Coordinates.h Publish Coordinates::size.
extensions/mito/mito.cc Update Python bindings to new manifold type/constructor signature.
benchmarks/mito.lib/pdes/poisson.cc Update benchmark to new manifold + weakform construction APIs.
benchmarks/mito.lib/operators/laplacian.cc Switch benchmark from fields to operators.
benchmarks/mito.lib/integration/integration.cc Construct manifold with explicit metric volume form.
.cmake/mito_tests_mito_lib.cmake Update test list for moved/added geometry/mesh/operators tests.
.cmake/mito_benchmarks_mito_lib.cmake Update benchmark list from fields to operators.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lib/mito/manifolds/Manifold.h
Comment thread lib/mito/manifolds/ParametrizedElement.h
Comment thread lib/mito/fem/forward.h
biancagi and others added 3 commits June 25, 2026 20:46
…n and metric volume form by reference

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
// function to compute the gradient of a vector field
template <vector_field_c F>
template <fields::vector_field_c F>
constexpr auto gradient(const F & field)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will need to somehow unify the gradient definitions here with the gradient I had added to the operators namespace in the induced-metric branch:

namespace mito::operators {

    // full-manifold gradient: grad f = g^{-1} * (df/dx)
    constexpr auto gradient(
        const fields::scalar_field_c auto & f,
        const auto & metric_field)
    {
        auto g_inv = functions::inverse(metric_field);
        auto df = gradient(f);
        return g_inv * df;
    }

    // submanifold gradient: grad f = J * (g_induced^{-1} * df/dxi), result in ambient space
    constexpr auto gradient(
        const fields::scalar_field_c auto & f,
        const auto & metric_field,
        const auto & jacobian_field)
    {
        auto g_inv = functions::inverse(metric_field);
        auto df = gradient(f);
        return jacobian_field * (g_inv * df);
    }

}

constexpr auto w = measure * quadrature_rule.weight(q);

// precompute the common factor
auto factor = w * tensor::determinant(element.jacobian()(xi));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed this line to

auto factor = w * element.volume_element()(xi);

in the fem-1d-embedded-in-2d branch since the determinant will only work for square Jacobians (and hence not cases of embedded elements). Then, inside the elements I contract the volume form with directors instead. But I think this change still applies cleanly also after your refactor so it's likely not an issue

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I see the tests pass so I agree it shouldn't be an issue.

@biancagi biancagi merged commit 8ad8bf2 into main Jul 4, 2026
4 checks passed
@biancagi biancagi deleted the manifold-integral-redesign branch July 4, 2026 05:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants