Skip to content

Add one line installer and pulsatile case#6

Open
Eleven7825 wants to merge 44 commits into
StanfordCBCL:masterfrom
Eleven7825:master
Open

Add one line installer and pulsatile case#6
Eleven7825 wants to merge 44 commits into
StanfordCBCL:masterfrom
Eleven7825:master

Conversation

@Eleven7825

Copy link
Copy Markdown
Contributor
  • Add a one line installer for the svFSGe
  • Add a pulsatile case using mean wss

shiyi and others added 30 commits February 5, 2026 16:09
- Add converted pulsatile Q waveform (pulsatile_flow.dat) from VMR source
  .flow files, converted from cm/s to mm/s to match kg/mm/s unit system
- Update steady_full.xml inlet BC to use Unsteady time dependence with
  the pulsatile temporal values file
- Add static BC file copy step in svfsi.py setup_files so pulsatile_flow.dat
  is staged into the run directory automatically
- Include source .flow files from Vascular Model Repository

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Increase Number_of_time_steps from 10 to 960 (10 cardiac cycles at dt=0.01s)
- Add run_fluid_only.py script for standalone fluid simulation without FSG
  coupling, handles mesh/BC file staging and runs svFSI directly

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Container named 'fsg-dev' now persists after exit
- Rerunning the script reconnects to existing container
- Uses 'sleep infinity' + 'docker exec' pattern for persistence
- Updated pip install to use requirements.txt (includes meshio)
- Shows container management commands on completion

Users can now:
- Exit and reconnect without losing setup
- Stop/start the container as needed
- See the container in 'docker ps -a'

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Instead of requiring requirements.txt, the script now has the package
list hardcoded. This makes it work even if requirements.txt is missing
or the repo state is inconsistent.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Creates a bootstrap script that can be downloaded and run via curl.
Handles repo cloning and Docker setup in one command.

Usage:
  curl -fsSL https://raw.githubusercontent.com/Eleven7825/svFSGe/master/scripts/install.sh | bash

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Prominently featured at the top of Quickstart section
- Explains prerequisites and what the command does
- Updated Quick Setup Script section to mention persistent container

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add setup_singularity.sh for automated Singularity environment setup
- Add install_singularity.sh for one-command installation on HPC
- Add run_simulation.sh helper script for easy simulation execution
- Update README.md with HPC installation instructions
- Support for read-only containers with user-space Python package installation
- Include verification step to ensure all dependencies are properly installed
…ive VTU copying

- Copies folder structure and all files except VTU/BIN from pulsatile/steady/gr_restart
- Copies only last 400 pulsatile VTU files to minimize transfer size
- Copies only last 10 steady VTU files
- Excludes all gr_restart VTU files completely
- Uses SSH ControlMaster for single authentication
- Strips carriage returns from remote SSH output for proper path handling
…be read from the json file"

This reverts commit 7c671a3.
Shiyi Chen and others added 14 commits March 27, 2026 10:24
Informational prints in extract_pulsatile_time_average and
extract_pulsatile_amplitude are now gated behind verbose=False by default.
Enable with "debug": true in the JSON config.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- fsg.py/svfsi.py: add iqn_ils_debug option (off by default) to save V, W,
  Q, R, column counts before/after QR filtering, and cc coefficients each
  IQN-ILS call; saved to debug_qr.npy on archive
- post.py: add plot_cc() to plot cc norm and heatmap with load-step
  transition lines; called automatically from main_arg when debug_qr.npy exists
- in_sim/partitioned_full_steep.json: new steep profile case (nmax=5,
  profile_beta with beta_min=2/beta_max=10, iqn_ils_debug enabled)
- in_svfsi_plus/gr_full_restart_steep.xml: solid XML with n_t_end=4 for
  steeper GR ramp (full load reached at t=3 out of 5 steps)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…verbose output

- fsg.py/svfsi.py: save load step t and sub-iter n alongside each IQN-ILS
  debug entry, removing need for fragile formula to reconstruct transitions
- post.py: derive transition lines directly from saved t array; fix path
  resolution for plot_cc in main_arg (two levels up from partitioned/converged)
- svfsi.py: suppress "extracted from N geometries" print unless debug=true
- in_sim/partitioned_full_debug.json: normal progressive profile case with
  iqn_ils_debug enabled for comparison against steep profile

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Draw a step line at ncols_after - 0.5 on the heatmap to clearly show
the boundary between active coefficients and NaN, making filtering
events (drops in the line) immediately visible.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When iqn_ils_reset=true, mat_V and mat_W are cleared at n=0 of each
new load step so IQN-ILS starts from scratch without reusing vectors
from previous time steps. Default is false (existing behavior).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- fsg.py: add iqn_ils_debug saving (cc, t, n per call), iqn_ils_reset flag
  to clear history vectors at each new load step, fallback to relaxation
  when mat_V is empty after reset
- post.py: add plot_cc() with 3-panel GridSpec figure (|c| heatmap log scale,
  ||c|| norm, coupling residual before/after IQN update); called from main_arg;
  use pcolormesh + dedicated colorbar column to fix x-axis alignment
- in_sim/partitioned_full_steep.json: set q=5, reset=true, profile_beta=true
…ot_cc

- Dummy invisible subplots in colorbar column for all rows so column widths match
- MaxNLocator(integer=True) for integer x-axis ticks
- Fix sharex() call (replace deprecated get_shared_x_axes().join())
- Remove legend from heatmap and norm subplots; residual shows only before/after/tol
- Sparser y-ticks on heatmap (every 2)
Saves and restores all state needed to resume from a converged load step:
- IQN-ILS history (mat_W, mat_V, dk, res, dtk)
- Coupling error and relaxation history (err, omega)
- Current and all previous converged solutions
- svFSI binary restart files (stFile_last.bin) snapshotted at checkpoint
  time to avoid corruption from subsequent failed load steps

Usage: set "save_restart": true in JSON to enable checkpointing.
Restart via "restart": "path/to/restart.npz" in JSON or -restart CLI flag.

Tested on steady case (nmax=2 + restart to nmax=3): sub-iteration counts,
IQN-ILS residuals, and displacement fields match to floating-point precision.
The load profile (how the G&R insult is ramped over the load steps) was
hard-coded inside svMultiPhysics' gr_equilibrated.cpp and could not be
changed from here. Expose it through the GR_equilibrated material params
and inject it from the simulation JSON:

- svfsi.py set_gr_load(): reads an optional "gr_load" section and patches
  the solid solver XML (<load_profile>/<load_steep>/<load_file>) per run,
  using the same regex-on-XML approach as the pulsatile step-count patch.
    profile: linear | tanh (default) | power | file
    steep:   tanh steepness / power exponent
    curve:   for "file", the load factor per step ([step, factor] pairs or
             a plain list); step 0 = pre-stress, 1..nloads = G&R loads.
  Omitting "gr_load" leaves the XML untouched -> svFSI defaults (tanh, 2.0),
  reproducing the historical behavior.

- Rename the top-level G&R load-step count nmax -> nloads (it clashed with
  coup["nmax"], the coupling-iteration cap). The old "nmax" is still
  accepted for backward compatibility. coup["nmax"] is unchanged.

Verified: fsg.py in_sim/partitioned_test.json matches test_reference/nmax_2
with both the tanh default and an equivalent file curve.

Requires the matching gr_equilibrated.cpp parser changes in svMultiPhysics
(FSGe branch); without them an older binary rejects the injected XML tags.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Companion to the load-profile work: the aneurysm insult (the spatial
elastin/stimulus knock-down that localizes the lesion) was a super-Gaussian
hard-coded in svMultiPhysics' gr_equilibrated.cpp. Expose it and inject it
from the simulation JSON.

- svfsi.py set_gr_insult(): reads an optional "gr_insult" section and patches
  the solid XML with the GR_equilibrated insult params, writing
  gr_insult_curve.dat for profile=file. Refactor the XML-patch and curve-write
  logic out of set_gr_load() into shared _patch_solid_xml()/_write_curve()
  helpers used by both.
    profile: gaussian (default) | file   (axial shape; azimuth stays gaussian)
    mag:     peak elastin loss fraction
    z_loc/z_wid/z_exp:        axial center/width (frac of length)/exponent
    asym, theta_wid/theta_exp: azimuthal localization
    curve:   for "file", axial factor f_axi vs normalized position z/lo
             ([z/lo, factor] pairs or a plain list)
  Knock-down at a point = mag * f_axi(z) * f_cir(azimuth). Omitting "gr_insult"
  leaves the XML untouched -> svFSI defaults reproduce the historical insult.

- partitioned_test.json: add an explicit gaussian gr_insult so the CI test
  also exercises the injection path (behavior unchanged).

Verified: fsg.py in_sim/partitioned_test.json matches test_reference/nmax_2
with the injected gaussian insult.

Requires the matching gr_equilibrated.cpp parser changes in svMultiPhysics
(FSGe branch); an older binary would reject the injected insult_* XML tags.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.

1 participant