Skip to content

Top-level abstraction for partitioned FSI with growth and remodeling (svFSGe) #528

@Eleven7825

Description

@Eleven7825

Use Case

@mrp089 and I want to merge svFSGe a partitioned fluid-solid-growth-and-remodeling (FSGe) solver — into svMultiPhysics. svFSGe uses a partitioned approach where fluid, solid, and mesh motion are solved as separate subdomains, coupled at a shared interface. This is distinct from the existing monolithic Equation_FSI in svMultiPhysics, where fluid and solid share one linear system, one time loop, and one Integrator.

The partitioned approach is required because:

  • The fluid subdomain runs a full pulsatile time loop (N cardiac cycle steps) per coupling sub-iteration to produce time-averaged wall shear stress and pressure; or in steady fluid case, the last time step.
  • The solid subdomain is quasi-static — it takes a single load step with no time marching, only Newton iterations for equilibrium.
    These requirements cannot be satisfied by the current single-Simulation / single-Integrator architecture.

Problem

The current architecture assumes one Simulation owns one Integrator which owns one SolutionStates. This maps cleanly to the existing use cases (monolithic fluid, solid, FSI). However, for partitioned FSI:

There is no place to own the coupling loop. The load-step ramping, sub-iteration loop, and convergence check (IQN-ILS / Aitken relaxation) have no home in the current class hierarchy.

There is no place to own multiple independent time integrators. The fluid subdomain needs N time steps per coupling sub-iteration; the solid subdomain needs zero time steps. These cannot share one Integrator or one SolutionStates.

There is no abstraction for interface data exchange. The displacements, wall shear stress, and pressure that are transferred between fluid and solid at each coupling sub-iteration are not represented anywhere.

Solution

Build a PartitionedSimulation class on top of the existing Simulation / Integrator / SolutionStates stack introduced in #450. The existing classes are left unchanged — partitioning lives above them.

New abstractions:

InterfaceData — data exchanged at the fluid-solid interface each coupling sub-iteration:

struct InterfaceData {
    Array<double> displacement;  // interface node displacements (solid → fluid/mesh)
    Array<double> wss;           // wall shear stress (fluid → solid)
    Array<double> pressure;      // fluid pressure on wall (fluid → solid)
    // node mapping: fluid interface ↔ solid interface
};

CouplingAlgorithm — abstract strategy for the fixed-point acceleration method:

class CouplingAlgorithm {
public:
    virtual InterfaceData update(const InterfaceData& prev,
                                 const InterfaceData& curr, int n) = 0;
    virtual bool converged() const = 0;
};
// Concrete implementations: RelaxationCoupling, IQNCoupling, JFNKCoupling
PartitionedSimulation — top-level driver owning the coupling loop:

class PartitionedSimulation {
    Simulation fluid_sim;   // existing class, unchanged — runs N time steps
    Simulation solid_sim;   // existing class, unchanged — runs 1 quasi-static step
    Simulation mesh_sim;    // existing class, unchanged — deforms fluid mesh
    std::unique_ptr<CouplingAlgorithm> coupling;
    std::vector<double> load_param_vec;  // load parameter ramp

    void run();  // load step loop → sub-iteration loop → coupling step
};

The structure mirrors the Python svFSGe implementation directly:


PartitionedSimulation::run()
  for t in load_steps:
      predict(t)

      for n in sub_iterations:
          mesh_sim.iterate_solution()      // deform mesh
          fluid_sim.iterate_solution()     // N time steps → wss, pressure
          solid_sim.iterate_solution()     // 1 quasi-static step → displacement
          interface = coupling.update(prev, curr, n)
          if coupling.converged(): break
      solid_sim.commit()                   // advance G&R state

Proposed implementation sequence (building on #450):

  • Move iterate_solution() from main.cpp into Simulation as a public method, so it can be called externally by PartitionedSimulation.
  • Implement InterfaceData and the fluid-solid node mapping.
  • Implement CouplingAlgorithm with at least RelaxationCoupling as the first concrete strategy.
  • Implement PartitionedSimulation with the load step and sub-iteration loops.

Alternatives considered

We could keep developing on the current svFSGe

Additional context

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct and Contributing Guidelines

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions