Skip to content

Commit 3036351

Browse files
authored
Monodomain project (#407)
* addded some classes from oldexplicit_stabilized branch. Mainly, the problems description, datatype classes, explicit stabilized classes. Tested for IMEX on simple problems * added implicit,explicit,exponential integrator (in electrophysiology aka Rush-Larsen) * added exponential imex and mES, added parabolic_system in vec format * added new stabilized integrators using multirate, splitting and exponential approaches * before adding exponential_runge_kutta as underlying method, instead of the traditional collocation methods * added first order exponential runge kutta as underlying collocation method. To be generalized to higher order * generalized exponential runge kutta to higher order. Added exponential multirate stabilized method using exponential RK but must tbe checked properly * fixed a few things * optimized a few things * renamed project ExplicitStabilized to Monodomain * removed deprecated problems * fixed some renaming issues * did refactoring of code and put in Monodomain_NEW * removed old code and renamed new code * added finite difference discretization * added many things, cant remember * old convergence_controller * addded some classes from oldexplicit_stabilized branch. Mainly, the problems description, datatype classes, explicit stabilized classes. Tested for IMEX on simple problems * added implicit,explicit,exponential integrator (in electrophysiology aka Rush-Larsen) * added exponential imex and mES, added parabolic_system in vec format * added new stabilized integrators using multirate, splitting and exponential approaches * before adding exponential_runge_kutta as underlying method, instead of the traditional collocation methods * added first order exponential runge kutta as underlying collocation method. To be generalized to higher order * generalized exponential runge kutta to higher order. Added exponential multirate stabilized method using exponential RK but must tbe checked properly * fixed a few things * optimized a few things * renamed project ExplicitStabilized to Monodomain * removed deprecated problems * fixed some renaming issues * did refactoring of code and put in Monodomain_NEW * removed old code and renamed new code * added finite difference discretization * added many things, cant remember * added smooth TTP model for conv test, added DCT for 2D and 3D problems * added plot stuff and run scripts * fixed controller to original * removed explicit stabilized files * fixed other files * removed obsolete splittings from ionic models * removed old sbatch scripts * removed mass transfer and sweeper * fixed something * removed my base transfer * removed hook class pde * removed FD files * fixed some calls to FD stuff * removed FEM FEniCSx files * renamed FD_Vector to DCT_Vector * added hook for output and visualization script * removed plot scripts * removed run scripts, except convergence * removed convergence experiments script * fixed TestODE * added stability test in run_TestODE * added stability test in run_TestODE * added stability test in run_TestODE * removed obsolete stuff in TestODE * removed unneeded stuff from run_MonodomainODE * cleaned a bit run_MonodomainODE * removed utils/ * added few comments, cleaned a bit * removed schedule from workflow * restored tutorial step 7 A which I has modified time ago * run black on monodomain project * fixed a formatting thing * reformatted everything with black * Revert "revert formatted with black" This reverts commit 82c82e9. * added environment file for monodomain project, started to add stuff in workflow * added first test * added package tqdm to monodomain environment * added new TestODE using DCT_vectors instead of myfloat, moved phi_eval_lists from MonodomainODE to the sweeper * deleted old TestODE and myfloat stuff * renamed TestODEnew to TestODE * cleaned a bit * added stability, convergence and iterations tests. Changed a bit other scripts as needed * reactivated other tests in workflow * removed my tests temporarly * added monodomain marker to project pyproject.toml * changed files and function names for tests * fixed convergence test * made one test a bit shorter * added test for SDC on HH and fixed missing feature in SDC imex sweeper for monodomain * reformatted with correct black options * fixed a lint error * another lint error * adding tests with plot * modified convergence test * added test iterations in parallel * removed plot from tests * added plots without writing to file * added write to file * simplified plot * new plot * fixed plot in iterations parallel * added back all tests and plots * cleaned a bit * added README * fixed readme * modified comments in controllers * try to compute phi every step * removed my controllers, check u changed before comuting phis * enabled postprocessing in pipeline * added comments to data_type classes, removed unnecessary methods * added comments to hooks * added comments to the problem classes * added comments to the run scripts * added comments to sweepers and transfer classes * fixed the readme * decommented if in pipeline * removed recv_mprobe option * changed back some stuff outiside of monodomain project * same * again * fixed Thomas hints * removed old unneeded move coverage folders * fixed previously missed Thomas comments * begin change datatype * changed run_Monodomain * added prints * fixed prints * mod print * mod print * mod print * mod print * rading init val * rading init val * removed prints * removed prints * checking longer time * checking longer time * fixed call phi eval * trying 2D * trying 2D * new_data type passing tests * removed coverage folders * optmized phi eval lists * before changing phi type * changed eval phi lists * polished a bit * before switch indeces * reformatted phi computaiton to its traspose * before changing Q * optimized integral of exp terms * changed interfate to c++ code * moved definition of dtype u f * tests passed after code refactoring
1 parent d77e431 commit 3036351

34 files changed

+5468
-1
lines changed

.github/workflows/ci_pipeline.yml

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,53 @@ jobs:
144144
path: |
145145
data_libpressio
146146
coverage_libpressio_3.10.dat
147-
147+
148+
user_monodomain_tests_linux:
149+
runs-on: ubuntu-latest
150+
151+
defaults:
152+
run:
153+
shell: bash -l {0}
154+
155+
steps:
156+
- name: Checkout
157+
uses: actions/checkout@v3
158+
159+
- name: Install Conda environment with Micromamba
160+
uses: mamba-org/setup-micromamba@v1
161+
with:
162+
environment-file: "pySDC/projects/Monodomain/etc/environment-monodomain.yml"
163+
create-args: >-
164+
python=3.10
165+
166+
- name: Compile C++ ionic models
167+
env:
168+
IONIC_MODELS_PATH: "pySDC/projects/Monodomain/problem_classes/ionicmodels/cpp"
169+
run: |
170+
c++ -O3 -Wall -shared -std=c++11 -fPIC -fvisibility=hidden $(python3 -m pybind11 --includes) ${IONIC_MODELS_PATH}/bindings_definitions.cpp -o ${IONIC_MODELS_PATH}/ionicmodels$(python3-config --extension-suffix)
171+
172+
- name: Run pytest for CPU stuff
173+
run: |
174+
echo "print('Loading sitecustomize.py...')
175+
import coverage
176+
coverage.process_startup() " > sitecustomize.py
177+
coverage run -m pytest --continue-on-collection-errors -v --durations=0 pySDC/tests -m monodomain
178+
179+
- name: Make coverage report
180+
run: |
181+
mv data data_monodomain
182+
coverage combine
183+
mv .coverage coverage_monodomain_3.10.dat
184+
185+
- name: Uploading artifacts
186+
uses: actions/upload-artifact@v3
187+
with:
188+
name: cpu-test-artifacts
189+
path: |
190+
data_monodomain
191+
coverage_monodomain_3.10.dat
192+
193+
148194
# user_cpu_tests_macos:
149195
# runs-on: macos-12
150196
#
@@ -206,6 +252,7 @@ jobs:
206252
- lint
207253
- user_cpu_tests_linux
208254
- user_libpressio_tests
255+
- user_monodomain_tests_linux
209256
# - wait_for_gitlab
210257

211258
defaults:

docs/source/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ Projects
5252
projects/DAE.rst
5353
projects/compression.rst
5454
projects/second_order.rst
55+
projects/monodomain.rst
5556

5657

5758
API documentation
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.. include:: /../../pySDC/projects/Monodomain/README.rst
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
Exponential SDC for the Monodomain Equation in Cardiac Electrophysiology
2+
==============================================================================
3+
This project implements the exponential spectral deferred correction (ESDC) method for the monodomain equation in cardiac electrophysiology.
4+
The method proposed here is an adaptation of the `ESDC method proposed by T. Buvoli <https://doi.org/10.1137/19M1256166>`_ to the monodomain equation.
5+
In particular, the implicit-explicit Rush-Larsen method is used as correction scheme. Moreover, not all model components have exponential terms, therefore the resulting method is an hybrid between ESDC and the standard SDC method.
6+
7+
Monodomain equation
8+
-------------------
9+
The monodomain equation models the electrical activity in the heart. It is a reaction-diffusion equation coupled with an ordinary differential equation for the ionic model and is given by
10+
11+
.. math::
12+
\begin{align}
13+
\chi (C_m\frac{\partial V}{\partial t}+I_{ion}(V,z_E,z_e, t)) &= \nabla \cdot (D \nabla V) & \quad \text{in } &\Omega \times (0,T), \\
14+
\frac{\partial z_E}{\partial t} &= g_E(V,z_E,z_e) & \quad \text{in } &\Omega \times (0,T), \\
15+
\frac{\partial z_e}{\partial t} &= \Lambda_e(V)(z_e-z_{e,\infty}(V)) & \quad \text{in } &\Omega \times (0,T), \\
16+
\end{align}
17+
18+
plus the boundary conditions, where :math:`V(t,x)\in\mathbb{R}` is the transmembrane potential and :math:`z_E(t,x)\in\mathbb{R}^n`, :math:`z_e(t,x)\in\mathbb{R}^m` are the ionic model state variables.
19+
The ionic model right-hand side :math:`g_E` is a general nonlinear term, while :math:`\Lambda_e` is a diagonal matrix. The typical range for the number of unknowns :math:`N=1+n+m` is :math:`N\in [4,50]` and depends on the ionic model of choice.
20+
21+
Spatial discretization yields a system of ODEs which can be written in compact form as
22+
23+
.. math::
24+
\mathbf y'=f_I(\mathbf y)+f_E(\mathbf y)+f_e(\mathbf y),
25+
26+
where :math:`\mathbf y(t)\in\mathbb{R}^{M N}` is the vector of unknowns and :math:`M` the number of mesh nodes.
27+
Concerning the right-hand sides, :math:`f_I` is a linear term for the discrete diffusion, :math:`f_E` is a nonlinear but non-stiff term for :math:`I_{ion},g_E`, and :math:`f_e` is a severely stiff term for :math:`\Lambda_e(V)(z_e-z_{e,\infty}(V))`.
28+
29+
The standard (serial) way of integrating the monodomain equation is by using a splitting method, where :math:`f_I` is integrated implicitly, :math:`f_E` explicitly, and :math:`f_e` using the exponential Euler method (which is inexpensive due to the diagonal structure of :math:`\Lambda_e`). We denote this method as IMEXEXP.
30+
31+
The ESDC method for the monodomain equation
32+
-------------------------------------------
33+
A possible way to parallelize the integration of the monodomain equation is by employing the SDC method in combination with the IMEXEXP approach for the correction scheme (preconditioner).
34+
However, this approach is unstable due to the severe stiffness of :math:`f_e`.
35+
Therefore we propose a hybrid method, where we employ SDC for the :math:`f_I,f_E` terms and ESDC for the :math:`f_e` term. For the correcttion scheme we still use the IMEXEXP method.
36+
The resulting method can be seen as a particular case of ESDC and will be denoted by ESDC in the next figures, for simplicity.
37+
38+
Running the code
39+
----------------
40+
Due to their complexity, ionic models are coded in C++ and wrapped to Python. Therefore, before running any example you need to compile the ionic models by running the following command in the root folder:
41+
42+
.. code-block::
43+
44+
export IONIC_MODELS_PATH=pySDC/projects/Monodomain/problem_classes/ionicmodels/cpp
45+
c++ -O3 -Wall -shared -std=c++11 -fPIC -fvisibility=hidden $(python3 -m pybind11 --includes) ${IONIC_MODELS_PATH}/bindings_definitions.cpp -o ${IONIC_MODELS_PATH}/ionicmodels$(python3-config --extension-suffix)
46+
47+
Then an example can be run:
48+
49+
.. code-block::
50+
51+
cd pySDC/projects/Monodomain/run_scripts
52+
mpirun -n 4 python run_MonodomainODE_cli.py --dt 0.05 --end_time 0.2 --num_nodes 6,3 --domain_name cube_1D --refinements 0 --ionic_model_name TTP --truly_time_parallel --n_time_ranks 4
53+
54+
Stability
55+
---------
56+
We display here the stability domain of the ESDC and SDC methods, both with IMEXEXP as correction scheme, applied to the test problem
57+
58+
.. math::
59+
y'=\lambda_I y+\lambda_E y+\lambda_e y,
60+
61+
with :math:`\lambda_I,\lambda_E,\lambda_e` representing :math:`f_I,f_E,f_e`, respectively.
62+
We fix :math:`\lambda_E=-1` and vary the stiff terms :math:`\lambda_I,\lambda_e` only. We see that the ESDC method is stable for all tested values of :math:`\lambda_I,\lambda_e`, while SDC is not.
63+
64+
.. image:: ../../../data/stability_domain_IMEXEXP_EXPRK.png
65+
:scale: 60 %
66+
.. image:: ../../../data/stability_domain_IMEXEXP.png
67+
:scale: 60 %
68+
69+
Convergence
70+
-----------
71+
Here we verify convergence of the ESDC method for the monodomain equation.
72+
We fix the number of collocation nodes to :math:`m=6` and perform a convergence experiment fixing the number of sweeps to either :math:`k=3` or :math:`k=6`.
73+
We use the ten Tusscher-Panfilov ionic model, which is employed in practical applications.
74+
We see that we gain one order of accuracy per sweep, as expected.
75+
76+
.. image:: ../../../data/convergence_ESDC_fixed_iter.png
77+
:scale: 100 %
78+
79+
80+
Iterations
81+
----------
82+
Here we consider three methods:
83+
84+
* ESDC: with :math:`m=6` collocation nodes.
85+
* MLESDC: This is a multilevel version of ESDC with :math:`m=6` collocation nodes on the fine level and :math:`m=3` nodes on the coarse level.
86+
* PFASST: Combination of the PFASST parallelization method with MLESDC, using 24 processors.
87+
88+
We display the number of iterations required by each method to reach a given tolerance and the residual at convergence. As ionic model we use again the ten Tusscher-Panfilov model.
89+
We see that PFASST requires a reasonalbly small number of iterations, comparable to the serial counterparts ESDC and MLESDC.
90+
91+
.. image:: ../../../data/niter_VS_time.png
92+
:scale: 100 %
93+
.. image:: ../../../data/res_VS_time.png
94+
:scale: 100 %
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from pySDC.implementations.datatype_classes.mesh import MultiComponentMesh
2+
3+
4+
class imexexp_mesh(MultiComponentMesh):
5+
components = ['impl', 'expl', 'exp']
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: pySDC_monodomain
2+
channels:
3+
- conda-forge
4+
- defaults
5+
dependencies:
6+
- python
7+
- numpy
8+
- scipy>=0.17.1
9+
- matplotlib>=3.0
10+
- sympy>=1.0
11+
- numba>=0.35
12+
- dill>=0.2.6
13+
- pytest
14+
- pytest-benchmark
15+
- pytest-timeout
16+
- pytest-order
17+
- coverage[toml]
18+
- sphinx
19+
- numdifftools
20+
- pybind11
21+
- mpi4py
22+
- mpich
23+
- tqdm
24+
- pymp-pypi
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
from pySDC.core.Hooks import hooks
2+
3+
4+
class pde_hook(hooks):
5+
"""
6+
Hook class to write the solution to file.
7+
"""
8+
9+
def __init__(self):
10+
super(pde_hook, self).__init__()
11+
12+
def pre_run(self, step, level_number):
13+
"""
14+
Overwrite default routine called before time-loop starts
15+
It calls the default routine and then writes the initial value to file.
16+
"""
17+
super(pde_hook, self).pre_run(step, level_number)
18+
19+
L = step.levels[level_number]
20+
P = L.prob
21+
if level_number == 0 and L.time == P.t0:
22+
P.write_solution(L.u[0], P.t0)
23+
24+
def post_step(self, step, level_number):
25+
"""
26+
Overwrite default routine called after each step.
27+
It calls the default routine and then writes the solution to file.
28+
"""
29+
super(pde_hook, self).post_step(step, level_number)
30+
31+
if level_number == 0:
32+
L = step.levels[level_number]
33+
P = L.prob
34+
P.write_solution(L.uend, L.time + L.dt)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import time
2+
from pySDC.core.Hooks import hooks
3+
4+
5+
class post_iter_info_hook(hooks):
6+
"""
7+
Hook class to write additional iteration information to the command line.
8+
It is used to print the final residual, after u[0] has been updated with the new value from the previous step.
9+
This residual is the one used to check the convergence of the iteration and when running in parallel is different from
10+
the one printed at IT_FINE.
11+
"""
12+
13+
def __init__(self):
14+
super(post_iter_info_hook, self).__init__()
15+
16+
def post_iteration(self, step, level_number):
17+
"""
18+
Overwrite default routine called after each iteration.
19+
It calls the default routine and then writes the residual to the command line.
20+
We call this the residual at IT_END.
21+
"""
22+
super().post_iteration(step, level_number)
23+
self.__t1_iteration = time.perf_counter()
24+
25+
L = step.levels[level_number]
26+
27+
self.logger.info(
28+
"Process %2i on time %8.6f at stage %15s: ----------- Iteration: %2i --------------- " "residual: %12.8e",
29+
step.status.slot,
30+
L.time,
31+
"IT_END",
32+
step.status.iter,
33+
L.status.residual,
34+
)

0 commit comments

Comments
 (0)