Issue 512 3D-1D coupling#563
Conversation
…larify time argument
…nTotalModels, improve comment
…el initialization
…set_flowrates() for DIR
…et_bc_neu_l (pressure)
…D), fixes svZeroD DIR
…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
…ir in relax_factor
…oD_interface, delete legacy sv0D code, keep all svOneD 3D-1D coupling implementation
… compute_valM/compute_jacobian_and_normal const
Co-authored-by: taeoukkim <[email protected]>
…at the same model
|
@taeoukkim Pleas request some reviews for this PR too |
There was a problem hiding this comment.
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.
| 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 { |
| // 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; | ||
| } |
| // 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); |
| 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; |
| // 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. |
|
|
||
| // 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; | ||
| }; |
| <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 Report❌ Patch coverage is 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. 🚀 New features to boost your workflow:
|
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