Skip to content

Implementing Basis Module #525

Description

@zasexton

Problem

In the solver, basis functions are hard-coded through a Fortran-style set of per-element dispatch tables, cached directly inside mesh and function-space data structures, and then copied, recomputed, or patched by special-case logic whenever we need mixed spaces or NURBS behavior. That makes basis evaluation tightly coupled to mesh storage, quadrature setup, and physics assembly. Adding new basis families or extending derivative support tends to spread changes across unrelated parts of the solver. A modular Basis folder therefore is necessary because it gives us a single mesh-agnostic interface for basis families, plus centralized construction, caching, and evaluation machinery, so different basis families (Lagrange, Bernstein, B-spline/NURBS, and vector bases) can be implemented once, tested once, and reused consistently across elements, geometry mappings, and assembly kernels instead of proliferating element-specific and physics-specific code paths.

  • Basis evaluation is implemented as a monolithic Fortran-port dispatch layer. Code/Source/solver/nn.cpp pulls in large element tables, and Code/Source/solver/nn_elem_gnn.h hard-codes closed-form N/Nx formulas per element type instead of exposing a reusable basis abstraction.
  • Basis state is stored directly on mesh and function-space containers rather than encapsulated in its own module. Code/Source/solver/ComMod.h and Code/Source/solver/ComMod.h embed N, Nx, Nxx, bounds, and quadrature data into fsType and mshType, while Code/Source/solver/nn.cpp and Code/Source/solver/fs.cpp allocate and populate those arrays procedurally.
  • Mixed spaces and extensibility are handled by special cases. Code/Source/solver/fs.cpp and Code/Source/solver/fs.cpp build Taylor-Hood spaces by copying or regenerating alternate shape tables, while NURBS support is still scattered as repeated update hooks or TODOs in places like Code/Source/solver/fluid.cpp, Code/Source/solver/eq_assem.cpp, and Code/Source/solver/nn.cpp.

Solution

To address the current solver’s basis-function, we should move all reference-element basis logic into a dedicated, mesh-agnostic Basis module with a common interface for evaluating values, gradients, and higher derivatives, and create those bases through a factory keyed by element family, order, continuity, and field type. Instead of storing handwritten N, Nx, and Nxx tables directly on mshType and fsType and rebuilding them through scattered element-specific branches, the mesh and element layers should hold lightweight basis and quadrature objects, while geometry mapping handles only the transformation from reference to physical space. Mixed discretizations such as Taylor-Hood should be represented as explicit mixed/composite elements rather than ad hoc control flow, and any future implemented NURBS/IGA support should be implemented as another basis family rather than a repeated special case. With caching and batched evaluation centralized in the basis layer, the same implementations can be reused consistently by physics assembly kernels, which reduces duplication, makes new basis families easier to add, and localizes both testing and performance optimization to a single part of the codebase.

This issue will outline Basis module design and API/ABI infrastructure.

Metadata

Metadata

Labels

OOP RefactorObject-Oriented Programming Refactor of Code

Type

No fields configured for Task.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions