Skip to content

Issue 512 3D-1D coupling#563

Open
taeoukkim wants to merge 50 commits into
SimVascular:mainfrom
taeoukkim:issue-512-pr-from-fa058d0-clean
Open

Issue 512 3D-1D coupling#563
taeoukkim wants to merge 50 commits into
SimVascular:mainfrom
taeoukkim:issue-512-pr-from-fa058d0-clean

Conversation

@taeoukkim
Copy link
Copy Markdown

Current situation

resolves #512

Release Notes

New features:
(1) 3D–1D coupling for both Dirichlet and Neumann boundary conditions
(2) RCR boundary condition support with 0D/1D coupling interfaces
(3) Dirichlet-type 3D–0D coupling implemented
(4) Enabled simultaneous use of 1D and 0D coupling in a single model

Documentation

I will also update documentation.

Testing

Successfully compiled on macOS.
Tested with 3D–1D coupling cases.
Tested with mixed 3D–1D and 3D–0D coupling configurations.

Code of Conduct & Contributing Guidelines

taeoukkim added 30 commits June 3, 2026 16:33
…e DOFs from linear solve

For 1D Dirichlet coupling, `iBC_Dir` is cleared in read_files.cpp so that
set_bc_cpl routes the BC correctly. However this caused fsi_ls_ini to skip
registering the face with the FSILS linear solver as a Dirichlet (BC_TYPE_Dir)
constraint. As a result, the preconditioner did not zero out those rows/columns,
and the linear solver overwrote the velocity values applied by set_bc_dir with
the NS solution, producing a lower-than-expected centerline velocity (~47 vs ~63.66).

Fix: detect Coupled-DIR faces in fsi_ls_ini and register them as BC_TYPE_Dir so
their DOFs are properly excluded from Ax=b.
- CouplingInterfaceParameters: add Coupling_ramp_steps (int) and
  Coupling_ramp_ref_pressure (double) XML parameters
- CoupledBoundaryCondition: add oned_ramp_steps_ / oned_ramp_ref_pressure_
  private members with set_oned_ramp() / get_oned_ramp_steps() /
  get_oned_ramp_ref_pressure() accessors; propagate through all
  copy/move constructors and assignment operators
- read_files.cpp: read ramp params from CouplingInterfaceParameters and
  store them in lBc.coupled_bc via set_oned_ramp()
- svOneD_subroutines.cpp: OneDModelState gains ramp_steps,
  ramp_ref_pressure, step_count fields; init_svOneD reads them from
  coupled_bc; calc_svOneD applies linear pressure ramp for DIR coupling;
  step_count is incremented on every committed (BCFlag=='L') step
Implements exponential smoothing of the pressure boundary condition
sent to the 1D solver (DIR coupling only):

  P_sent = omega * P_target + (1 - omega) * P_prev_sent

where P_target has already been through the ramp filter.

- Parameters.h/cpp: add Coupling_dir_relax_factor parameter (default 1.0)
- CoupledBoundaryCondition.h/cpp: add oned_relax_factor_ field, getter,
  setter, copy/move and distribute() broadcast
- read_files.cpp: parse and apply the new parameter
- svOneD_subroutines.cpp: add relax_factor / P_prev_sent_old/new to
  OneDModelState; apply under-relaxation after ramp; update history
  only on BCFlag=='L' committed steps; NEU coupling untouched
taeoukkim and others added 20 commits June 3, 2026 17:25
…oD_interface, delete legacy sv0D code, keep all svOneD 3D-1D coupling implementation
… compute_valM/compute_jacobian_and_normal const
@aabrown100-git
Copy link
Copy Markdown
Collaborator

@taeoukkim Pleas request some reviews for this PR too

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Implements 3D–1D coupling via a dynamically loaded svOneDSolver interface and extends the existing 3D–0D coupling infrastructure to support mixed 0D/1D coupling per-face, including coexistence with RCR boundaries.

Changes:

  • Added svOneDSolver dynamic-library interface and coupling subroutines, with MPI-parallel initialization/stepping per coupled face.
  • Updated BC parsing/routing and BC application to support 1D coupling (Dirichlet + Neumann) and mixed 0D/1D configurations, including adjusted handling for DIR-coupled faces in the linear system/BC application.
  • Extended CoupledBoundaryCondition to carry 1D metadata plus ramp/relax history; added an example coupling case under tests/cases.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
tests/cases/fluid/pipe_svOneD_2faces/solver.xml Adds an example/test-case solver.xml for 3D–1D coupling on two faces.
Code/Source/solver/txt.cpp Updates end-of-step coupling integration to support mixed svZeroD/svOneD and RCR coexistence.
Code/Source/solver/svZeroD_interface.cpp Updates svZeroD coupled-face indexing (exclude 1D faces) and adds ramp/relax history handling + DIR-flow broadcast.
Code/Source/solver/svOneD_subroutines.h Declares svOneD init/step entry points.
Code/Source/solver/svOneD_subroutines.cpp Implements 3D–1D coupling orchestration, MPI ownership, stepping, and relaxation/ramping.
Code/Source/solver/svOneD_interface/OneDSolverInterface.h Adds a dlopen/dlsym wrapper API for the svOneDSolver interface library.
Code/Source/solver/svOneD_interface/OneDSolverInterface.cpp Implements dynamic symbol loading and wrapper calls into the 1D shared library.
Code/Source/solver/set_bc.cpp Updates coupled BC derivative evaluation, mixed solver calling, RCR integration indexing, and DIR-coupled handling in Dir/Neu application.
Code/Source/solver/read_files.cpp Extends XML parsing/routing for svOneD per-face input files and enables mixed 0D/1D coupling configuration rules.
Code/Source/solver/Parameters.h Adds svOneDSolver interface parameter list + coupling-interface parameters for per-face 1D input and ramp/relax knobs.
Code/Source/solver/Parameters.cpp Implements XML parameter parsing for svOneD interface + coupling-interface additions.
Code/Source/solver/distribute.cpp Broadcasts svOneD interface metadata and ensures cplBC state is distributed correctly with RCR coexistence.
Code/Source/solver/CoupledBoundaryCondition.h Extends CoupledBoundaryCondition with svOneD input file + ramp/relax state and adds new cap-surface exception types.
Code/Source/solver/CoupledBoundaryCondition.cpp Implements distribution of new fields and adds additional cap-surface robustness checks + DIR flow broadcast helper.
Code/Source/solver/ComMod.h Adds svOneD interface type and new flags/fields in coupling-related structs.
Code/Source/solver/ComMod.cpp Implements svOneDSolverInterfaceType::set_data.
Code/Source/solver/CMakeLists.txt Adds new svOneD sources to the solver build.
Code/Source/solver/baf_ini.cpp Initializes svOneD coupling during solver init and tags RCR faces for integration.

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

Comment on lines +308 to +316
if (bc.coupled_bc.get_bc_type() == BoundaryConditionType::bType_Neu) {
// NEU coupling: apply under-relaxation to the 3D flow rate Q sent to
// the 1D solver to damp timestep-to-timestep oscillations in the input.
// No ramping is applied here; ramping is applied to the *output* pressure
// P that the 1D solver returns (Phase 2 below).
const double omega = st.relax_factor;
params[3] = omega * bc.coupled_bc.get_Qo() + (1.0 - omega) * st.Q_prev_sent_new;
params[4] = omega * bc.coupled_bc.get_Qn() + (1.0 - omega) * st.Q_prev_sent_new;
} else {
Comment on lines +333 to +338
// Step 2: apply under-relaxation (damps timestep-to-timestep oscillations).
// P_sent = omega * P_target + (1 - omega) * P_prev_sent
const double omega = st.relax_factor;
params[3] = omega * P_target_old + (1.0 - omega) * st.P_prev_sent_new;
params[4] = omega * P_target_new + (1.0 - omega) * st.P_prev_sent_new;
}
Comment on lines +461 to +468
// Step 1: apply flow ramp (scales Q from ramp_ref over the first ramp_steps steps).
int ramp_steps = bc->coupled_bc.get_oned_ramp_steps();
double Q_target_old, Q_target_new;
if (ramp_steps > 0) {
double ramp_factor = std::min(1.0, static_cast<double>(bc->coupled_bc.get_ramp_step_count()) / ramp_steps);
double Q_ref = bc->coupled_bc.get_oned_ramp_ref_pressure(); // ref value (0.0 by default)
Q_target_old = Q_ref + ramp_factor * (raw_Q_old - Q_ref);
Q_target_new = Q_ref + ramp_factor * (raw_Q_new - Q_ref);
Comment on lines +212 to +220
std::string oned_input_file_; ///< Path to svOneDSolver input file (empty for svZeroD BCs)
/// @brief Pressure ramp parameters for 1D coupling initialization (DIR coupling only).
int oned_ramp_steps_ = 0; ///< Number of ramp steps (0 = disabled)
double oned_ramp_ref_pressure_ = 0.0; ///< Reference pressure at step 0

/// @brief Under-relaxation factor for pressure passed to the 1D solver (DIR coupling only).
/// Applied as: P_sent = omega * P_new + (1 - omega) * P_prev_sent.
/// Range: (0, 1]. Default 1.0 = no relaxation.
double oned_relax_factor_ = 1.0;
Comment on lines +809 to +814
// Ramp for 1D coupling initialization (both DIR and NEU coupling).
// Over the first Coupling_ramp_steps committed time steps the value passed
// to the 1D solver is linearly ramped:
// DIR: pressure P ramped from Coupling_ramp_ref_pressure to actual 3D P.
// NEU: flow rate Q ramped from 0 to actual 3D Q (ref pressure not used).
// Set Coupling_ramp_steps = 0 (default) to disable.
Comment on lines 204 to 211

// Coupled BC class
CoupledBoundaryCondition coupled_bc;

// svOneD: per-face 1D solver input file path (set when Time_dependence=Coupled
// and svOneDSolver_interface is active).
std::string oned_input_file;
};
Comment on lines +101 to +130
<svOneDSolver_interface>
<Coupling_type> semi-implicit </Coupling_type>
<Shared_library> /path/to/svOneDSolver/build/lib/libsvOneDSolver_interface.so </Shared_library>
</svOneDSolver_interface>

<!-- Inlet: prescribed flow waveform -->
<Add_BC name="lumen_inlet" >
<Type> Dir </Type>
<Time_dependence> Unsteady </Time_dependence>
<Temporal_values_file_path> lumen_inlet.flw </Temporal_values_file_path>
<Zero_out_perimeter> true </Zero_out_perimeter>
<Impose_flux> true </Impose_flux>
</Add_BC>

<!-- Outlet 1: coupled to 1D model via 1dmodel1.in -->
<Add_BC name="lumen_outlet1" >
<Type> Neu </Type>
<Time_dependence> Coupled </Time_dependence>
<Coupling_interface>
<svOneDSolver_input_file> 1dmodel1.in </svOneDSolver_input_file>
</Coupling_interface>
</Add_BC>

<!-- Outlet 2: coupled to 1D model via 1dmodel2.in -->
<Add_BC name="lumen_outlet2" >
<Type> Neu </Type>
<Time_dependence> Coupled </Time_dependence>
<Coupling_interface>
<svOneDSolver_input_file> 1dmodel2.in </svOneDSolver_input_file>
</Coupling_interface>
@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 5, 2026

Codecov Report

❌ Patch coverage is 31.22302% with 478 lines in your changes missing coverage. Please review.
✅ Project coverage is 68.26%. Comparing base (f521770) to head (91033e6).

Files with missing lines Patch % Lines
Code/Source/solver/svOneD_subroutines.cpp 0.00% 145 Missing ⚠️
Code/Source/solver/CoupledBoundaryCondition.cpp 19.64% 90 Missing ⚠️
Code/Source/solver/read_files.cpp 40.93% 88 Missing ⚠️
...ce/solver/svOneD_interface/OneDSolverInterface.cpp 0.00% 56 Missing ⚠️
Code/Source/solver/set_bc.cpp 67.46% 27 Missing ⚠️
Code/Source/solver/svZeroD_interface.cpp 54.23% 27 Missing ⚠️
Code/Source/solver/CoupledBoundaryCondition.h 40.74% 16 Missing ⚠️
Code/Source/solver/Parameters.cpp 55.00% 9 Missing ⚠️
Code/Source/solver/txt.cpp 58.82% 7 Missing ⚠️
Code/Source/solver/baf_ini.cpp 57.14% 6 Missing ⚠️
... and 3 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #563      +/-   ##
==========================================
- Coverage   69.04%   68.26%   -0.79%     
==========================================
  Files         181      184       +3     
  Lines       34121    34696     +575     
  Branches     5897     5995      +98     
==========================================
+ Hits        23560    23684     +124     
- Misses      10424    10875     +451     
  Partials      137      137              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.

3D-1D coupling

3 participants