SimVascular / svZeroDSolver

A C++ lumped-parameter solver for blood flow and pressure in hemodynamic networks
https://simvascular.github.io/documentation/rom_simulation.html#0d-solver
Other
7 stars 18 forks source link

Memory issue in the python interface #92

Closed menon-karthik closed 9 months ago

menon-karthik commented 10 months ago

Description

The python interface has two ways to run a 0D simulation (see below) and both of them should produce the same result. However, for some cases where one or more blocks need to access members of Model (which itself is a member of Block), the two methods do not produce the same result.

Reproduction

Two ways to run a 0D simulation from Python are:

my_config = {...}
solver = svzerodplus.Solver(my_config)
solver.run()

and

my_config = {...}
svzerodplus.simulate(my_config)

When running cases that use ChamberElastanceInductor and ClosedLoopHeartPulmonary blocks, they need to access model->cardiac_cycle_period inside their respective update_time() functions. While the second method works fine, the first method produces weird results.

Expected behavior

The above two methods should produce the same result. I found that the problem in the first method is that when solver is returned to Python, and solver.run() is subsequently executed, the *model pointer in Block has somehow lost track of the model object it was supposed to be pointing to within Solver.

This is happening because Solver has a member that is a model object, not a pointer to model. But Block has a pointer to model. While solver is returned from C++ to Python, although Solver still keeps track of its model member, that memory address seems to change and Block therefore loses track of it.

Additional context

TL;DR - Pointers work better when interfacing between different codes. I made the model object in Solver a pointer, so both Solver and Block are now pointing to the same address.

Code of Conduct