Skip to content

Feature request: Assembly of high-order polynomial nonlinear terms (e.g., trilinear forms) for reduced-order modelling #1220

@tiagomrns

Description

@tiagomrns

The feature request is related to the following problem
My team is working on reduced-order modelling (ROM) techniques for nonlinear problems, similar to what is done in the MORFEproject/MORFE2.0. In such methods, one often needs to precompute tensors that represent high-order polynomial nonlinearities. For example, given a weak form that contains a bilinear term like ∫ (u·∇)u · v dΩ, discretisation yields a trilinear form C(U, U, V) which can be represented as a third-order tensor H such that H(U, U, V) = H_{ijk} U_j U_k V_i. More generally, one may need terms of the form G(U1, U2) (bilinear) or H(U1, U2, U3) (trilinear) where each argument comes from a different finite element space (or the same).

Currently, Gridap provides excellent tools for assembling matrices from bilinear forms via assemble_matrix (which handles two FESpaces). However, for forms involving more than two FESpaces, there is no direct way to assemble the corresponding multi-dimensional arrays (tensors). This would be extremely valuable for ROM workflows, where one precomputes these tensors to enable efficient online evaluations.

Describing a possible solution
We propose adding functions similar to assemble_matrix but capable of handling an arbitrary number of FESpace arguments. For instance:

  • assemble_tensor(a, trial_fe1, trial_fe2, test_fe) for a trilinear form a(u1, u2, v) returning a 3‑D array (or a sparse representation thereof).
  • assemble_tensor(a, trial_fe1, trial_fe2, trial_fe3, test_fe) for quadrilinear forms, etc.

These functions would iterate over the degrees of freedom of each space and evaluate the form for combinations of basis functions, storing the result in a multi-dimensional container. For efficiency, sparsity patterns could be derived from the underlying meshes and finite element spaces, similar to how assemble_matrix uses a SparsityPattern.

Optionally, the user could also specify a test_fe and multiple trial_fe spaces in a flexible way (e.g., using a tuple of spaces). The output could be a dense or sparse tensor, depending on the problem size and sparsity.

Describing alternatives we have considered
One could manually loop over degrees of freedom and call evaluate on the weak form for each combination, but this is cumbersome, error‑prone, and does not leverage Gridap’s efficient cell‑wise assembly and sparsity handling. Another alternative is to use the existing assemble_matrix repeatedly by freezing some arguments, but that would be extremely inefficient for high‑order tensors.

Additional context
In reduced‑order modelling, after projecting the full‑order model onto a reduced basis, the nonlinear terms become low‑dimensional polynomial expressions. For a quadratic nonlinearity, one precomputes a third‑order tensor H (size N_r × N × N, where N_r is the number of test basis functions and N the number of trial basis functions). This tensor is then used online to compute the reduced nonlinear term as H_{ijk} q_j q_k. Similarly, for a cubic nonlinearity, a fourth‑order tensor is needed.

The current infrastructure in Gridap (e.g., FESpace, SparseMatrixAssemblers.jl) already contains many of the building blocks: cell iterators, local assembly loops, and sparsity pattern construction. Extending this to higher‑order tensors would likely involve:

  1. Creating a new assembler type that can handle multiple trial spaces.
  2. Implementing a routine to compute a sparsity pattern for the tensor (based on the support of basis functions from each space).
  3. Looping over cells and local degrees of freedom to fill the global tensor entries.

We believe this feature would greatly enhance Gridap’s capabilities for nonlinear and reduced‑order modelling, and we’d be happy to help with design discussions or even contribute if given some guidance.

Thank you for considering this request!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions