diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index fe1820fc7..025b981b8 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -1,4 +1,4 @@ -# This workflow builds and deploys the html documentation for svZeroDPlus. +# This workflow builds and deploys the html documentation for svZeroDSolver. name: Documentation on: [push, pull_request] permissions: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0256c2bd7..6e1d78109 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -# This workflow builds and tests svZeroDPlus. It is built and tested on +# This workflow builds and tests svZeroDSolver. It is built and tested on # different versions of ubuntu and macOS. name: Build and test on: [push, pull_request] @@ -14,7 +14,7 @@ jobs: - name: Install ubuntu dependencies if: startsWith(matrix.os, 'ubuntu') run: sudo apt update && sudo apt install build-essential cmake lcov - - name: Install svZeroDPlus + - name: Install svZeroDSolver run: | conda create -n zerod python=3.11.4 conda run -n zerod pip install -e ".[dev]" @@ -59,10 +59,10 @@ jobs: run: | cd Release cpack - cp distribution/svZeroDPlus_* .. + cp distribution/svZeroDSolver_* .. - name: Upload installer uses: actions/upload-artifact@v3 with: name: ${{ matrix.os }} installer - path: svZeroDPlus_* - if-no-files-found: error \ No newline at end of file + path: svZeroDSolver_* + if-no-files-found: error diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b5386017..a098e9632 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -153,11 +153,11 @@ add_executable(svzerodcalibrator applications/svzerodcalibrator.cpp ) # ----------------------------------------------------------------------------- -# Setup building of the svzerodplus Python extension module. +# Setup building of the pysvzerod Python extension module. # ----------------------------------------------------------------------------- # Replace EXCLUDE_FROM_ALL with SHARED to test building the Python # shared library. -pybind11_add_module(svzerodplus EXCLUDE_FROM_ALL applications/svzerodplus.cpp) +pybind11_add_module(pysvzerod EXCLUDE_FROM_ALL applications/pysvzerod.cpp) # ----------------------------------------------------------------------------- # Add source sub-directories. @@ -185,7 +185,7 @@ target_include_directories(svzerodcalibrator PUBLIC ${CMAKE_SOURCE_DIR}/src/solve ) -target_include_directories(svzerodplus PUBLIC +target_include_directories(pysvzerod PUBLIC ${CMAKE_SOURCE_DIR}/src/algebra ${CMAKE_SOURCE_DIR}/src/model ${CMAKE_SOURCE_DIR}/src/optimize @@ -203,13 +203,13 @@ target_link_libraries(svzerodsolver PRIVATE nlohmann_json::nlohmann_json) target_link_libraries(svzerodcalibrator PRIVATE Eigen3::Eigen) target_link_libraries(svzerodcalibrator PRIVATE nlohmann_json::nlohmann_json) -target_link_libraries(svzerodplus PRIVATE Eigen3::Eigen) -target_link_libraries(svzerodplus PRIVATE nlohmann_json::nlohmann_json) -target_link_libraries(svzerodplus PRIVATE pybind11_json) -target_link_libraries(svzerodplus PRIVATE svzero_algebra_library) -target_link_libraries(svzerodplus PRIVATE svzero_model_library) -target_link_libraries(svzerodplus PRIVATE svzero_optimize_library) -target_link_libraries(svzerodplus PRIVATE svzero_solve_library) +target_link_libraries(pysvzerod PRIVATE Eigen3::Eigen) +target_link_libraries(pysvzerod PRIVATE nlohmann_json::nlohmann_json) +target_link_libraries(pysvzerod PRIVATE pybind11_json) +target_link_libraries(pysvzerod PRIVATE svzero_algebra_library) +target_link_libraries(pysvzerod PRIVATE svzero_model_library) +target_link_libraries(pysvzerod PRIVATE svzero_optimize_library) +target_link_libraries(pysvzerod PRIVATE svzero_solve_library) # Create distribution diff --git a/applications/svzerodplus.cpp b/applications/pysvzerod.cpp similarity index 98% rename from applications/svzerodplus.cpp rename to applications/pysvzerod.cpp index 86e69ceae..3bd5bd7e1 100644 --- a/applications/svzerodplus.cpp +++ b/applications/pysvzerod.cpp @@ -28,7 +28,7 @@ // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /** - * @file svzerodplus.cpp + * @file pysvzerod.cpp * @brief Python interface for svZeroDSolver */ #include @@ -42,7 +42,7 @@ namespace py = pybind11; -PYBIND11_MODULE(svzerodplus, m) { +PYBIND11_MODULE(pysvzerod, m) { using Solver = Solver; py::class_(m, "Solver") .def(py::init([](py::dict& config) { diff --git a/container/profiling/Dockerfile b/container/profiling/Dockerfile index 6b67c8da8..49ee0ddc2 100644 --- a/container/profiling/Dockerfile +++ b/container/profiling/Dockerfile @@ -20,13 +20,13 @@ RUN apt-get -q update && \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* -COPY . /opt/svzerodplus +COPY . /opt/pysvzerod -RUN mkdir -p /opt/svzerodplus-build/relwithdebinfo && \ - cd /opt/svzerodplus-build/relwithdebinfo && \ - cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo /opt/svzerodplus && \ +RUN mkdir -p /opt/pysvzerod-build/relwithdebinfo && \ + cd /opt/pysvzerod-build/relwithdebinfo && \ + cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo /opt/pysvzerod && \ cmake --build . --target svzerodsolver WORKDIR /opt/data -RUN chmod +x /opt/svzerodplus/container/profiling/entrypoint.sh -ENTRYPOINT ["/opt/svzerodplus/container/profiling/entrypoint.sh"] +RUN chmod +x /opt/pysvzerod/container/profiling/entrypoint.sh +ENTRYPOINT ["/opt/pysvzerod/container/profiling/entrypoint.sh"] diff --git a/container/profiling/entrypoint.sh b/container/profiling/entrypoint.sh index 1bac4f5a4..39d01f0e9 100644 --- a/container/profiling/entrypoint.sh +++ b/container/profiling/entrypoint.sh @@ -1,5 +1,5 @@ #! /bin/bash export LIBPROFILER=$(find /usr/lib -name "libprofiler.so") -LD_PRELOAD=$LIBPROFILER CPUPROFILE=/opt/main.prof CPUPROFILE_FREQUENCY=100000 /opt/svzerodplus-build/relwithdebinfo/svzerodsolver $@ /opt/output.csv -google-pprof --pdf /opt/svzerodplus-build/relwithdebinfo/svzerodsolver /opt/main.prof > profiling_report.pdf \ No newline at end of file +LD_PRELOAD=$LIBPROFILER CPUPROFILE=/opt/main.prof CPUPROFILE_FREQUENCY=100000 /opt/pysvzerod-build/relwithdebinfo/svzerodsolver $@ /opt/output.csv +google-pprof --pdf /opt/pysvzerod-build/relwithdebinfo/svzerodsolver /opt/main.prof > profiling_report.pdf diff --git a/distribution/CMakeLists.txt b/distribution/CMakeLists.txt index afaf89336..874100a21 100644 --- a/distribution/CMakeLists.txt +++ b/distribution/CMakeLists.txt @@ -7,10 +7,10 @@ if(ENABLE_DISTRIBUTION) # add description (shown in installer) set(CPACK_PACKAGE_VERSION "${TODAY}") - set(CPACK_PACKAGE_NAME "svZeroDPlus") + set(CPACK_PACKAGE_NAME "svZeroDSolver") set(CPACK_PACKAGE_VENDOR "SimVascular.org") set(CPACK_PACKAGE_CONTACT "SimVascular ") - set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "svZeroDPlus is a fast lumped-parameter solver for blood flow and pressure in hemodynamic networks") + set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "svZeroDSolver is a fast lumped-parameter solver for blood flow and pressure in hemodynamic networks") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/../LICENSE.txt") set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/readme.txt") @@ -48,4 +48,4 @@ if(ENABLE_DISTRIBUTION) set(CPACK_COMPONENTS_ALL applications libraries headers) include(CPack) -endif() \ No newline at end of file +endif() diff --git a/distribution/readme.txt b/distribution/readme.txt index 3a30c4b68..b351e7a71 100644 --- a/distribution/readme.txt +++ b/distribution/readme.txt @@ -1 +1 @@ -svZeroDPlus is a fast lumped-parameter solver for blood flow and pressure in hemodynamic networks. \ No newline at end of file +svZeroDSolver is a fast lumped-parameter solver for blood flow and pressure in hemodynamic networks. diff --git a/docs/Doxyfile b/docs/Doxyfile index 7a64ecdd3..f1cf2e449 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -4,7 +4,7 @@ # Project related configuration options #--------------------------------------------------------------------------- DOXYFILE_ENCODING = UTF-8 -PROJECT_NAME = svZeroDPlus +PROJECT_NAME = svZeroDSolver PROJECT_NUMBER = PROJECT_BRIEF = PROJECT_LOGO = diff --git a/docs/pages/developer_guide.md b/docs/pages/developer_guide.md index eaaefcb0e..749367290 100644 --- a/docs/pages/developer_guide.md +++ b/docs/pages/developer_guide.md @@ -4,15 +4,15 @@ # Architecture -svZeroDPlus is written in a highly modular manner to enable reuse of code +svZeroDSolver is written in a highly modular manner to enable reuse of code for many different applications. It is divided into a header based library in the `src` directory and a collection of different applications in the `applications` folder. Each application is written for a different use-case -of svZeroDPlus, namely: +of svZeroDSolver, namely: * svZeroDCalibrator in `svzerodcalibrator.cpp` * svZerodSolver in `svzerodsolver.cpp` -* Python API in `svzerodplus.cpp` +* Python API in `pysvzerod.cpp` The header-based library in the `src` folder contains classes and functions that are collectively used by all applications. A good overview over the general architecture can be found in the @@ -21,7 +21,7 @@ all applications. A good overview over the general architecture can be found in ## Build in debug mode -For debug purposes it is recommended to build svZeroDPlus in Debug mode. +For debug purposes it is recommended to build svZeroDSolver in Debug mode. ```bash mkdir Debug @@ -69,7 +69,7 @@ make codecheck ``` If the above commands do not work on your platform (it does not work on Sherlock at Stanford) -you can run the following command **from the svZeroDPlus folder** to format all your files: +you can run the following command **from the svZeroDSolver folder** to format all your files: ```bash find src/**/*.h src/**/*.cpp | xargs clang-format -style=Google -i @@ -142,8 +142,8 @@ to create a profiling report. The generation of profiling reports requires [Docker](https://docs.docker.com/get-docker/) to be installed on your machine. ```docker -docker build -t profile_svzerodplus -f container/profiling/Dockerfile . -docker run -it -v $(PWD):/opt/data --rm profile_svzerodplus path/to/simulation_config.json +docker build -t profile_svzerodsolver -f container/profiling/Dockerfile . +docker run -it -v $(PWD):/opt/data --rm profile_svzerodsolver path/to/simulation_config.json ``` This will generate a file called `profiling_report.pdf` in your current working directory. diff --git a/docs/pages/main.md b/docs/pages/main.md index 2ca954dfc..1268661f5 100644 --- a/docs/pages/main.md +++ b/docs/pages/main.md @@ -1,20 +1,20 @@ -@mainpage svZeroDPlus +@mainpage svZeroDSolver [TOC] -svZeroDPlus is an application for performing simulations with 0D/lumped-parameter +svZeroDSolver is an application for performing simulations with 0D/lumped-parameter computer models for cardiovascular flows. -Some noteworthy features of svZeroDPlus are: +Some noteworthy features of svZeroDSolver are: * It is completely modular. Users can create custom flow models by arranging blocks corresponding to blood vessels, junctions, different types of boundary conditions, etc. * It is written in C++ to enable high-performance applications. -* svZeroDPlus offers both a Python API and a C++ shared library to interface with other +* svZeroDSolver offers both a Python API and a C++ shared library to interface with other Python or C++-based applications. This allows it to be used in a fully coupled manner with other multi-physics solvers, and for parameter estimation, uncertainty quantification, etc. -* The svZeroDCalibrator application, which is included in svZeroDPlus, optimizes 0D +* The svZeroDCalibrator application, which is included in svZeroDSolver, optimizes 0D blood vessel parameters to recapitulate given time-varying flow and pressure measurements (for example, from a high-fidelity 3D simulation). This allows users to build accurate 0D models that reflect observed hemodynamics. @@ -44,13 +44,13 @@ You can find more details about governing equations in individual blocks, for ex - BloodVesselJunction - WindkesselBC -For implementation details, have a look at the [source code](https://github.com/StanfordCBCL/svZeroDPlus). +For implementation details, have a look at the [source code](https://github.com/simvascular/svZeroDSolver). [About SimVascular](https://simvascular.github.io) # Installation -svZeroDPlus can be installed in two different ways. For using the Python +svZeroDSolver can be installed in two different ways. For using the Python API, an installation via pip is recommended. ## Using pip @@ -59,12 +59,12 @@ For a pip installation, simply run the following command (cloning of the repository is not required): ```bash -pip install git+https://github.com/StanfordCBCL/svZeroDPlus.git +pip install git+https://github.com/simvascular/svZeroDSolver.git ``` ## Using CMake -If you want to build svZeroDPlus manually from source, clone the repository +If you want to build svZeroDSolver manually from source, clone the repository and run the following commands from the top directory of the project: ```bash @@ -115,38 +115,38 @@ For some applications it is beneficial to run svZeroDSolver directly from within another program. For example, this can be useful when many simulations need to be performed (e.g. for calibration, uncertainty quantification, ...). It is also allows using -svZeroDPlus with other solvers, for example as boundary conditions or +svZeroDSolver with other solvers, for example as boundary conditions or forcing terms. ### In C++ -SvZeroDPlus needs to be built using CMake to use the shared library interface. +SvZeroDSolver needs to be built using CMake to use the shared library interface. -Detailed examples of interfacing with svZeroDPlus from C++ codes are available -in the test cases at `svZeroDPlus/tests/test_interface`. +Detailed examples of interfacing with svZeroDSolver from C++ codes are available +in the test cases at `svZeroDSolver/tests/test_interface`. ### In Python Please make sure that -you installed svZerodPlus via pip to enable this feature. We start by -importing svzerodplus: +you installed svZerodSolver via pip to enable this feature. We start by +importing pysvzerod: ```python ->>> import svzerodplus +>>> import pysvzerod ``` Next, we create a solver from our configuration. The configuration can be specified by either a path to a JSON file: ```python ->>> solver = svzerodplus.Solver("tests/cases/steadyFlow_RLC_R.json") +>>> solver = pysvzerod.Solver("tests/cases/steadyFlow_RLC_R.json") ``` or as a Python dictionary: ```python >>> my_config = {...} ->>> solver = svzerodplus.Solver(my_config) +>>> solver = pysvzerod.Solver(my_config) ``` To run the simulation we add: @@ -202,7 +202,7 @@ There is also a function to retrieve the full result directly based on a given c ```python >>> my_config = {...} ->>> svzerodplus.simulate(my_config) +>>> pysvzerod.simulate(my_config) name time flow_in flow_out pressure_in pressure_out 0 branch0_seg0 0.00 5.0 5.0 1100.0 600.0 @@ -342,14 +342,14 @@ The result will be written to a JSON file. ### In Python svZeroDCalibrator can also be called directly from Python. -Please make sure that you installed svZerodPlus via pip to enable this feature. We start by -importing svzerodplus: +Please make sure that you installed svZerodSolver via pip to enable this feature. We start by +importing pysvzerod: ```python -import svzerodplus +import pysvzerod my_unoptimized_config = {...} -my_optimized_config = svzerodplus.calibrate(my_unoptimized_config) +my_optimized_config = pysvzerod.calibrate(my_unoptimized_config) ``` ## Configuration (file) diff --git a/setup.cfg b/setup.cfg index b458f3f89..07c091a5c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [metadata] -name = svzerodplus +name = pysvzerod version = 2.0 description = A fast C++ application for working with 0D models. long_description = file: README.md @@ -18,5 +18,5 @@ dev = [options.entry_points] console_scripts = - svzerodsolver = svzerodplus:run_simulation_cli - svzerodcalibrator = svzerodplus:run_calibration_cli + svzerodsolver = pysvzerod:run_simulation_cli + svzerodcalibrator = pysvzerod:run_calibration_cli diff --git a/setup.py b/setup.py index b50aedde4..c6f07fc59 100644 --- a/setup.py +++ b/setup.py @@ -2,6 +2,6 @@ from cmake_setuptools import CMakeExtension, CMakeBuildExt setup( - ext_modules=[CMakeExtension("svzerodplus")], + ext_modules=[CMakeExtension("pysvzerod")], cmdclass={"build_ext": CMakeBuildExt}, ) diff --git a/src/interface/interface.cpp b/src/interface/interface.cpp index 7bf37aa96..5887fee39 100644 --- a/src/interface/interface.cpp +++ b/src/interface/interface.cpp @@ -172,12 +172,13 @@ void initialize(std::string input_file_arg, int& problem_id, int& pts_per_cycle, num_output_steps = 1; throw std::runtime_error( "ERROR: Option output_mean_only has not been implemented when " - "using the svZeroDPlus interface library."); + "using the svZeroDSolver interface library."); } else if (!simparams.output_all_cycles) { num_output_steps = interface->pts_per_cycle_; throw std::runtime_error( "ERROR: Option output_last_cycle_only has been implemented but not " - "tested when using the svZeroDPlus interface library. Please test this " + "tested when using the svZeroDSolver interface library. Please test " + "this " "functionality before removing this message."); } else { num_output_steps = interface->num_time_steps_; @@ -510,7 +511,8 @@ void run_simulation(int problem_id, const double external_time, start_time = interface->times_[start_idx]; throw std::runtime_error( "ERROR: Option output_last_cycle_only has been implemented but not " - "tested when using the svZeroDPlus interface library. Please test this " + "tested when using the svZeroDSolver interface library. Please test " + "this " "functionality before removing this message."); } for (int t = start_idx; t < num_output_steps; t++) { diff --git a/svzerodplus.pyi b/svzerodplus.pyi index 5ed5dce6c..79081808b 100644 --- a/svzerodplus.pyi +++ b/svzerodplus.pyi @@ -1,7 +1,7 @@ -# This file contains the stubs for the public Python interface of svZeroDPlus. +# This file contains the stubs for the public Python interface of svZeroDSolver. # This is necessary for supporting auto-completion in Visual Studio Code or # PyCharm. -"""svZeroDPlus Python interface.""" +"""svZeroDSolver Python interface.""" from __future__ import annotations import numpy import typing diff --git a/tests/test_calibrator.py b/tests/test_calibrator.py index 180cf225f..67d8251ba 100644 --- a/tests/test_calibrator.py +++ b/tests/test_calibrator.py @@ -4,7 +4,7 @@ import numpy as np -from .utils import execute_svzerodplus, RTOL_PRES +from .utils import execute_pysvzerod, RTOL_PRES this_file_dir = os.path.abspath(os.path.dirname(__file__)) @@ -12,7 +12,7 @@ def test_steady_flow_calibration(): testfile = os.path.join(this_file_dir, "cases", "steadyFlow_calibration.json") - result, _ = execute_svzerodplus(testfile, "calibrator") + result, _ = execute_pysvzerod(testfile, "calibrator") calibrated_parameters = result["vessels"][0]["zero_d_element_values"] @@ -40,7 +40,7 @@ def test_calibration_vmr(model_id): this_file_dir, "cases", "vmr", "input", f"{model_id}_calibrate_from_0d.json" ) - result, _ = execute_svzerodplus(test, "calibrator") + result, _ = execute_pysvzerod(test, "calibrator") for i, vessel in enumerate(reference["vessels"]): for key, value in vessel["zero_d_element_values"].items(): diff --git a/tests/test_interface/test_01/main.cpp b/tests/test_interface/test_01/main.cpp index 27be1297f..cd6ba815b 100644 --- a/tests/test_interface/test_01/main.cpp +++ b/tests/test_interface/test_01/main.cpp @@ -1,4 +1,4 @@ -// Test interfacing to svZeroDPlus. +// Test interfacing to svZeroSolver. #include "../LPNSolverInterface/LPNSolverInterface.h" #include @@ -14,7 +14,7 @@ int main(int argc, char** argv) LPNSolverInterface interface; if (argc != 3) { - std::runtime_error("Usage: svZeroD_interface_test01 "); + std::runtime_error("Usage: svZeroD_interface_test01 "); } // Load shared library and get interface functions. diff --git a/tests/test_interface/test_02/main.cpp b/tests/test_interface/test_02/main.cpp index 73b66c371..45b5db429 100644 --- a/tests/test_interface/test_02/main.cpp +++ b/tests/test_interface/test_02/main.cpp @@ -1,4 +1,4 @@ -// Test interfacing to svZeroDPlus. +// Test interfacing to svZeroDSolver. #include "../LPNSolverInterface/LPNSolverInterface.h" #include @@ -45,7 +45,7 @@ int main(int argc, char** argv) LPNSolverInterface interface; if (argc != 3) { - std::runtime_error("Usage: svZeroD_interface_test01 "); + std::runtime_error("Usage: svZeroD_interface_test01 "); } // Load shared library and get interface functions. diff --git a/tests/test_io.py b/tests/test_io.py index 33da18f18..d40136259 100644 --- a/tests/test_io.py +++ b/tests/test_io.py @@ -3,7 +3,7 @@ from .utils import run_test_case_by_name, RTOL_FLOW, RTOL_PRES # use coarse absolute tolerances for gradient calculation -# we're comparing gradients from gen-alpha in svZeroDPlus with central differences in np.gradient +# we're comparing gradients from gen-alpha in svZeroDSolver with central differences in np.gradient ATOL = {"f": 0.6, "p": 800.0} ATOL_MEAN = {"f": 0.01, "p": 20.0} diff --git a/tests/utils.py b/tests/utils.py index a01f97593..327748af1 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -10,7 +10,7 @@ # (run executables instead of Python interface, much slower) from pytest import coverage -import svzerodplus +import pysvzerod this_file_dir = os.path.abspath(os.path.dirname(__file__)) @@ -18,12 +18,12 @@ RTOL_FLOW = 1.0e-8 -def execute_svzerodplus(testfile, mode): - """Execute svzerodplus (via Python interface or executable). +def execute_pysvzerod(testfile, mode): + """Execute pysvzerod (via Python interface or executable). Args: testfile: Path to the input file. - mode: svZeroDPlus application (solver or calibrator). + mode: svZeroDSolver application (solver or calibrator). """ assert mode in ["solver", "calibrator"], "unknown mode: " + mode @@ -45,9 +45,9 @@ def execute_svzerodplus(testfile, mode): else: # run via Python binding (fast) if mode == "solver": - result = svzerodplus.simulate(config) + result = pysvzerod.simulate(config) elif mode == "calibrator": - result = svzerodplus.calibrate(config) + result = pysvzerod.calibrate(config) return result, config @@ -63,7 +63,7 @@ def run_test_case_by_name(name, output_variable_based=False, folder="."): testfile = os.path.join(this_file_dir, "cases", name + ".json") # run test - result, config = execute_svzerodplus(testfile, "solver") + result, config = execute_pysvzerod(testfile, "solver") if not output_variable_based: output = {