Manifold integral redesign#100
Conversation
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}.
Trivial but had to be done.
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
…o {geometry} directory
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.
…the mesh cell when possible
… with {parametrized_element_type}
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}
…and {parametrizedElementT} are compatibile
…n of Euclidean metric space
There was a problem hiding this comment.
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 toeuclidean_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.
…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) |
There was a problem hiding this comment.
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)); |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Thanks! I see the tests pass so I agree it shouldn't be an issue.
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
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.
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.
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.
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.
ManifoldManifoldis now equipped with anAtlas, which provides the local parametrizations of the mesh cells. Given a mesh cell, the manifold can construct aParametrizedElement, i.e. a local manifold element equipped with its parametrization and metric volume form.As a consequence,
GeometricSimplexno longer stores or knows about parametrizations. It remains a lower-level geometric object, while parametrization belongs to the manifold layer.IntegratorIntegratoris 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.
FunctionSpaceFunctionSpaceno 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.