From eec07f75584619e6a485c01a33e54b21aacf446d Mon Sep 17 00:00:00 2001 From: Henrik Finsberg Date: Thu, 11 Jan 2024 15:08:33 +0100 Subject: [PATCH 1/7] Start porting from cbcbeat to fenics-beat --- setup.cfg | 2 +- src/simcardems/ep_model.py | 228 +- src/simcardems/models/em_model.py | 7 +- .../models/pureEP_ORdmm_Land/__init__.py | 4 +- .../models/pureEP_ORdmm_Land/cell_model.py | 6215 ++++++++++++----- .../models/pureEP_ORdmm_Land/em_model.py | 112 +- src/simcardems/runner.py | 17 +- tests/test_models.py | 1 + 8 files changed, 4785 insertions(+), 1801 deletions(-) diff --git a/setup.cfg b/setup.cfg index dadcc021..9d9a756a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -19,8 +19,8 @@ packages = find: install_requires = ap-features cardiac-geometries - cbcbeat click + fenics-beat fenics-pulse h5py matplotlib diff --git a/src/simcardems/ep_model.py b/src/simcardems/ep_model.py index c5da5b47..55f4a344 100644 --- a/src/simcardems/ep_model.py +++ b/src/simcardems/ep_model.py @@ -2,15 +2,19 @@ import json from pathlib import Path +from typing import Callable from typing import Dict +from typing import NamedTuple from typing import Optional from typing import Type from typing import TYPE_CHECKING -import cbcbeat +import beat import dolfin import pulse +# import cbcbeat + try: import ufl_legacy as ufl except ImportError: @@ -22,13 +26,26 @@ if TYPE_CHECKING: from .models.em_model import BaseEMCoupling - from .models.cell_model import BaseCellModel + + # from .models.cell_model import BaseCellModel logger = utils.getLogger(__name__) +class CellModel(NamedTuple): + init_states: Dict[str, float] | Dict[int, Dict[str, float]] + parameters: Dict[str, float] | Dict[int, Dict[str, float]] + v_index: int | Dict[int, int] + fun: Callable | Dict[int, Callable] + markers = None + + @property + def num_states(self): + return len(self.init_states) + + def setup_cell_model( - cls, + model, coupling: BaseEMCoupling, cell_params=None, cell_inits=None, @@ -36,55 +53,82 @@ def setup_cell_model( drug_factors_file=None, popu_factors_file=None, disease_state=Config.disease_state, -): - cell_params = handle_cell_params( - cell_params=cell_params, - disease_state=disease_state, - drug_factors_file=drug_factors_file, - popu_factors_file=popu_factors_file, - CellModel=cls, - ) +) -> CellModel: + # cell_params = handle_cell_params( + # cell_params=cell_params, + # disease_state=disease_state, + # drug_factors_file=drug_factors_file, + # popu_factors_file=popu_factors_file, + # CellModel=cls, + # ) + if cell_params is None: + parameters = model.init_parameter_values() + else: + parameters = cell_params + + # cell_inits = handle_cell_inits( + # cell_inits=cell_inits, + # cell_init_file=cell_init_file, + # model=model + # ) + if cell_inits is None: + init_states = model.init_state_values() + else: + init_states = cell_inits - cell_inits = handle_cell_inits( - cell_inits=cell_inits, - cell_init_file=cell_init_file, - CellModel=cls, - ) + # return cls( + # init_conditions=cell_inits, + # params=cell_params, + # coupling=coupling, + # ) + + # model = beat.cellmodels.torord_dyn_chloride.mid - return cls( - init_conditions=cell_inits, - params=cell_params, - coupling=coupling, + return CellModel( + init_states=init_states, + parameters=parameters, + v_index=model.state_index("v"), + fun=model.forward_generalized_rush_larsen, ) def setup_solver( dt, - cellmodel: cbcbeat.CardiacCellModel, + cellmodel: CellModel, coupling: BaseEMCoupling, scheme=Config.ep_ode_scheme, theta=Config.ep_theta, preconditioner=Config.ep_preconditioner, PCL=Config.PCL, -) -> cbcbeat.SplittingSolver: +) -> beat.MonodomainSplittingSolver: # Set-up cardiac model - ps = setup_splitting_solver_parameters( - theta=theta, - preconditioner=preconditioner, - dt=dt, - scheme=scheme, - ) - ep_heart = setup_model( - cellmodel, + # ps = setup_splitting_solver_parameters( + # theta=theta, + # preconditioner=preconditioner, + # dt=dt, + # scheme=scheme, + # ) + pde = setup_model( coupling.geometry.ep_mesh, PCL=PCL, microstructure=coupling.geometry.microstructure_ep, stimulus_domain=coupling.geometry.stimulus_domain, ) - solver = cbcbeat.SplittingSolver(ep_heart, params=ps) + + ode = beat.odesolver.DolfinODESolver( + pde.state, + num_states=cellmodel.num_states, + fun=cellmodel.fun, + init_states=cellmodel.init_states, + parameters=cellmodel.parameters, + v_index=cellmodel.v_index, + ) + # solver = cbcbeat.SplittingSolver(ep_heart, params=ps) + solver = beat.MonodomainSplittingSolver(pde=pde, ode=ode) + # Extract the solution fields and set the initial conditions - (vs_, vs, vur) = solver.solution_fields() - vs_.assign(cellmodel.initial_conditions()) + # (vs_, vs, vur) = solver.solution_fields() + # vs_.assign(cellmodel.initial_conditions()) coupling.register_ep_model(solver) coupling.print_ep_info() @@ -141,7 +185,6 @@ def harmonic_mean(a, b): def setup_model( - cellmodel: cbcbeat.CardiacCellModel, mesh: dolfin.Mesh, microstructure: pulse.Microstructure, stimulus_domain: geometry.StimulusDomain, @@ -150,7 +193,7 @@ def setup_model( C_m: float = 0.01, duration: float = 2.0, A: float = 50_000.0, -) -> cbcbeat.CardiacModel: +) -> beat.MonodomainModel: """Set-up cardiac model based on benchmark parameters @@ -192,7 +235,7 @@ def setup_model( s = "((std::fmod(time,PCL) >= start) & (std::fmod(time,PCL) <= duration + start)) ? amplitude : 0.0" - I_s = dolfin.Expression( + I_s_expr = dolfin.Expression( s, time=time, start=0.0, @@ -201,65 +244,14 @@ def setup_model( PCL=PCL, degree=0, ) - # Store input parameters in cardiac model - stimulus = cbcbeat.Markerwise( - (I_s,), - (stimulus_domain.marker,), - stimulus_domain.domain, - ) - petsc_options = [ - ["ksp_type", "cg"], - ["pc_type", "gamg"], - ["pc_gamg_verbose", "10"], - ["pc_gamg_square_graph", "0"], - ["pc_gamg_coarse_eq_limit", "3000"], - ["mg_coarse_pc_type", "redundant"], - ["mg_coarse_sub_pc_type", "lu"], - ["mg_levels_ksp_type", "richardson"], - ["mg_levels_ksp_max_it", "3"], - ["mg_levels_pc_type", "sor"], - ] - for opt in petsc_options: - dolfin.PETScOptions.set(*opt) - - heart = cbcbeat.CardiacModel( - domain=mesh, - time=time, - M_i=M, - M_e=None, - cell_models=cellmodel, - stimulus=stimulus, - applied_current=None, + dx = dolfin.Measure("dx", domain=mesh, subdomain_data=stimulus_domain.domain)( + stimulus_domain.marker, ) + I_s = beat.base_model.Stimulus(dz=dx, expr=I_s_expr) - return heart - - -def setup_splitting_solver_parameters( - dt, - theta=0.5, - preconditioner="sor", - scheme="GRL1", -): - ps = cbcbeat.SplittingSolver.default_parameters() - ps["pde_solver"] = "monodomain" - ps["MonodomainSolver"]["linear_solver_type"] = "iterative" - ps["MonodomainSolver"]["theta"] = theta - ps["MonodomainSolver"]["preconditioner"] = preconditioner - ps["MonodomainSolver"]["default_timestep"] = dt - ps["MonodomainSolver"]["use_custom_preconditioner"] = False - ps["theta"] = theta - ps["enable_adjoint"] = False - ps["apply_stimulus_current_to_pde"] = True - # ps["BasicCardiacODESolver"]["scheme"] = scheme - ps["CardiacODESolver"]["scheme"] = scheme - # ps["ode_solver_choice"] = "BasicCardiacODESolver" - # ps["BasicCardiacODESolver"]["V_polynomial_family"] = "CG" - # ps["BasicCardiacODESolver"]["V_polynomial_degree"] = 1 - # ps["BasicCardiacODESolver"]["S_polynomial_family"] = "CG" - # ps["BasicCardiacODESolver"]["S_polynomial_degree"] = 1 - return ps + params = {"preconditioner": "sor", "use_custom_preconditioner": False} + return beat.MonodomainModel(time=time, mesh=mesh, M=M, I_s=I_s, params=params) def file_exist(filename: Optional[str], suffix: str) -> bool: @@ -311,29 +303,29 @@ def handle_cell_params( return cell_params_tmp -def handle_cell_inits( - CellModel: Type[cbcbeat.CardiacCellModel], - cell_inits: Optional[Dict[str, float]] = None, - cell_init_file: str = "", -) -> Dict[str, float]: - cell_inits_tmp = CellModel.default_initial_conditions() - if file_exist(cell_init_file, ".json"): - cell_inits_tmp.update(load_json(cell_init_file)) - - if file_exist(cell_init_file, ".h5"): - cell_inits_tmp.update(load_json(cell_init_file)) - from .save_load_functions import load_initial_conditions_from_h5 - - cell_inits = load_initial_conditions_from_h5( - cell_init_file, - CellModel=CellModel, - ) - - # FIXME: This is a bit confusing, since it will overwrite the - # inputs from the cell_init_file. There should be only one way to - # do this IMO. I think this might be difficult for the user to reason - # about. I think in general we should handle the loading from files - # at higher level. - if cell_inits is not None: - cell_inits_tmp.update(cell_inits) - return cell_inits_tmp +# def handle_cell_inits( +# CellModel, +# cell_inits: Optional[Dict[str, float]] = None, +# cell_init_file: str = "", +# ) -> Dict[str, float]: +# cell_inits_tmp = CellModel. +# if file_exist(cell_init_file, ".json"): +# cell_inits_tmp.update(load_json(cell_init_file)) + +# if file_exist(cell_init_file, ".h5"): +# cell_inits_tmp.update(load_json(cell_init_file)) +# from .save_load_functions import load_initial_conditions_from_h5 + +# cell_inits = load_initial_conditions_from_h5( +# cell_init_file, +# CellModel=CellModel, +# ) + +# # FIXME: This is a bit confusing, since it will overwrite the +# # inputs from the cell_init_file. There should be only one way to +# # do this IMO. I think this might be difficult for the user to reason +# # about. I think in general we should handle the loading from files +# # at higher level. +# if cell_inits is not None: +# cell_inits_tmp.update(cell_inits) +# return cell_inits_tmp diff --git a/src/simcardems/models/em_model.py b/src/simcardems/models/em_model.py index f65fa3ea..8b2ec887 100644 --- a/src/simcardems/models/em_model.py +++ b/src/simcardems/models/em_model.py @@ -3,7 +3,7 @@ import typing from pathlib import Path -import cbcbeat +import beat import dolfin import pulse @@ -40,7 +40,7 @@ def setup_EM_model( coupling = cls_EMCoupling(geometry, **state_params) cellmodel = ep_model.setup_cell_model( - cls=cls_CellModel, + model=cls_CellModel, coupling=coupling, cell_init_file=config.cell_init_file, drug_factors_file=config.drug_factors_file, @@ -57,6 +57,7 @@ def setup_EM_model( PCL=config.PCL, cellmodel=cellmodel, ) + coupling.register_ep_model(solver) mech_heart = mechanics_model.setup_solver( @@ -150,7 +151,7 @@ def dt_mechanics(self) -> float: def coupling_type(self): "CustomType" - def register_ep_model(self, solver: cbcbeat.SplittingSolver) -> None: + def register_ep_model(self, solver: beat.MonodomainSplittingSolver) -> None: pass def register_mech_model(self, solver: pulse.MechanicsProblem) -> None: diff --git a/src/simcardems/models/pureEP_ORdmm_Land/__init__.py b/src/simcardems/models/pureEP_ORdmm_Land/__init__.py index 3404af1c..9ecd0eac 100644 --- a/src/simcardems/models/pureEP_ORdmm_Land/__init__.py +++ b/src/simcardems/models/pureEP_ORdmm_Land/__init__.py @@ -1,8 +1,10 @@ from . import cell_model +from . import cell_model as CellModel from . import em_model -from .cell_model import ORdmmLandPureEp as CellModel from .em_model import EMCoupling +# from .cell_model import ORdmmLandPureEp as CellModel + ActiveModel = None loggers = [ "simcardems.models.pure_ep_ORdmm_Land.cell_model.logger", diff --git a/src/simcardems/models/pureEP_ORdmm_Land/cell_model.py b/src/simcardems/models/pureEP_ORdmm_Land/cell_model.py index cb6de16a..90f5f4ff 100644 --- a/src/simcardems/models/pureEP_ORdmm_Land/cell_model.py +++ b/src/simcardems/models/pureEP_ORdmm_Land/cell_model.py @@ -1,1674 +1,4645 @@ -"""This module contains a ORdmm_Land_em_coupling cardiac cell model - -The module was autogenerated from a gotran ode file -""" -from collections import OrderedDict -from typing import Dict - -import dolfin - -try: - import ufl_legacy as ufl -except ImportError: - import ufl -from dolfin import as_vector -from dolfin import Constant - -from ... import utils -from ..cell_model import BaseCellModel - -logger = utils.getLogger(__name__) - - -def Max(a, b): - return (a + b + abs(a - b)) / Constant(2.0) - - -def Min(a, b): - return (a + b - abs(a - b)) / Constant(2.0) - - -class ORdmmLandPureEp(BaseCellModel): - def __init__(self, params=None, init_conditions=None, **kwargs): - """ - Create cardiac cell model - - *Arguments* - params (dict, :py:class:`dolfin.Mesh`, optional) - optional model parameters - init_conditions (dict, :py:class:`dolfin.Mesh`, optional) - optional initial conditions - """ - logger.debug("Initialize ORdmm Land model") - - super().__init__(params, init_conditions) - - @staticmethod - def update_disease_parameters( - params: Dict[str, float], - disease_state: str = "healthy", - ) -> None: - if disease_state.lower() == "hf": - logger.info("Update scaling parameters for heart failure model") - params["HF_scaling_CaMKa"] = 1.50 - params["HF_scaling_Jrel_inf"] = pow(0.8, 8.0) - params["HF_scaling_Jleak"] = 1.3 - params["HF_scaling_Jup"] = 0.45 - params["HF_scaling_GNaL"] = 1.3 - params["HF_scaling_GK1"] = 0.68 - params["HF_scaling_thL"] = 1.8 - params["HF_scaling_Gto"] = 0.4 - params["HF_scaling_Gncx"] = 1.6 - params["HF_scaling_Pnak"] = 0.7 - params["HF_scaling_cat50_ref"] = 0.6 - - @staticmethod - def default_parameters() -> Dict[str, float]: - """Set-up and return default parameters. - - Parameters - ---------- - disease_state : str, optional - String with "hf" or "healthy", by default "healthy". - If "hf", then parameters representing heart failure - will be used. - - Returns - ------- - OrderedDict - Dictionary with default values - """ - params = OrderedDict( - [ - ("scale_ICaL", 1.018), - ("scale_IK1", 1.414), - ("scale_IKr", 1.119), - ("scale_IKs", 1.648), - ("scale_INaL", 2.274), - ("celltype", 0), - ("cao", 1.8), - ("ko", 5.4), - ("nao", 140.0), - ("F", 96485.0), - ("R", 8314.0), - ("T", 310.0), - ("L", 0.01), - ("rad", 0.0011), - ("Ahf", 0.99), - ("GNa", 31), - ("thL", 200.0), - ("Gto", 0.02), - ("delta_epi", 1.0), - ("Aff", 0.6), - ("Kmn", 0.002), - ("k2n", 1000.0), - ("tjca", 75.0), - ("zca", 2.0), - ("bt", 4.75), - ("Beta0", 2.3), - ("Beta1", -2.4), - ("Tot_A", 25), - ("Tref", 120), - ("Trpn50", 0.35), - ("calib", 1), - ("cat50_ref", 0.805), - ("emcoupling", 1), - ("etal", 200), - ("etas", 20), - ("gammas", 0.0085), - ("gammaw", 0.615), - ("isacs", 0), - ("ktrpn", 0.1), - ("ku", 0.04), - ("kuw", 0.182), - ("kws", 0.012), - ("mode", 1), - ("ntm", 2.4), - ("ntrpn", 2.0), - ("p_a", 2.1), - ("p_b", 9.1), - ("p_k", 7.0), - ("phi", 2.23), - ("rs", 0.25), - ("rw", 0.5), - ("CaMKo", 0.05), - ("KmCaM", 0.0015), - ("KmCaMK", 0.15), - ("aCaMK", 0.05), - ("bCaMK", 0.00068), - ("PKNa", 0.01833), - ("Gncx", 0.0008), - ("KmCaAct", 0.00015), - ("kasymm", 12.5), - ("kcaoff", 5000.0), - ("kcaon", 1500000.0), - ("kna1", 15.0), - ("kna2", 5.0), - ("kna3", 88.12), - ("qca", 0.167), - ("qna", 0.5224), - ("wca", 60000.0), - ("wna", 60000.0), - ("wnaca", 5000.0), - ("H", 1e-07), - ("Khp", 1.698e-07), - ("Kki", 0.5), - ("Kko", 0.3582), - ("Kmgatp", 1.698e-07), - ("Knai0", 9.073), - ("Knao0", 27.78), - ("Knap", 224.0), - ("Kxkur", 292.0), - ("MgADP", 0.05), - ("MgATP", 9.8), - ("Pnak", 30.0), - ("delta", -0.155), - ("eP", 4.2), - ("k1m", 182.4), - ("k1p", 949.5), - ("k2m", 39.4), - ("k2p", 687.2), - ("k3m", 79300.0), - ("k3p", 1899.0), - ("k4m", 40.0), - ("k4p", 639.0), - ("zk", 1.0), - ("GKb", 0.003), - ("PNab", 3.75e-10), - ("PCab", 2.5e-08), - ("GpCa", 0.0005), - ("Esac_ns", -10.0), - ("Gsac_k", 1.097904761904762), - ("Gsac_ns", 0.006), - ("lambda_max", 1.1), - ("amp", -80.0), - ("duration", 0.5), - ("BSLmax", 1.124), - ("BSRmax", 0.047), - ("KmBSL", 0.0087), - ("KmBSR", 0.00087), - ("cmdnmax", 0.05), - ("csqnmax", 10.0), - ("kmcmdn", 0.00238), - ("kmcsqn", 0.8), - ("kmtrpn", 0.0005), - ("trpnmax", 0.07), - ("lmbda", 1.0), - ("dLambda", 0.0), - # Drug factors - ("scale_drug_INa", 1.0), - ("scale_drug_INaL", 1.0), - ("scale_drug_Ito", 1.0), - ("scale_drug_ICaL", 1.0), - ("scale_drug_IKr", 1.0), - ("scale_drug_IKs", 1.0), - ("scale_drug_IK1", 1.0), - ("scale_drug_IKb", 1.0), - ("scale_drug_INab", 1.0), - ("scale_drug_ICab", 1.0), - ("scale_drug_IpCa", 1.0), - ("scale_drug_Isacns", 1.0), - ("scale_drug_Isack", 1.0), - # Population factors - ("scale_popu_GNa", 1.0), - ("scale_popu_GCaL", 1.0), - ("scale_popu_Gto", 1.0), - ("scale_popu_GNaL", 1.0), - ("scale_popu_GKr", 1.0), - ("scale_popu_GKs", 1.0), - ("scale_popu_GK1", 1.0), - ("scale_popu_GbK", 1.0), - ("scale_popu_KNCX", 1.0), - ("scale_popu_KNaK", 1.0), - ("scale_popu_GbNa", 1.0), - ("scale_popu_GbCa", 1.0), - ("scale_popu_KpCa", 1.0), - ("scale_popu_KRyR", 1.0), - ("scale_popu_KSERCA", 1.0), - ("scale_popu_Kleak", 1.0), - ("scale_popu_nTm", 1.0), - ("scale_popu_CaT50ref", 1.0), - ("scale_popu_Tref", 1.0), - ("scale_popu_kuw", 1.0), - ("scale_popu_kws", 1.0), - ("scale_popu_kTRPN", 1.0), - ("scale_popu_nTRPN", 1.0), - ("scale_popu_ku", 1.0), - ("scale_popu_TRPN50", 1.0), - ("scale_popu_rw", 1.0), - ("scale_popu_rs", 1.0), - # HF scaling factors - ("HF_scaling_CaMKa", 1.0), - ("HF_scaling_Jrel_inf", 1.0), - ("HF_scaling_Jleak", 1.0), - ("HF_scaling_Jup", 1.0), - ("HF_scaling_GNaL", 1.0), - ("HF_scaling_GK1", 1.0), - ("HF_scaling_thL", 1.0), - ("HF_scaling_Gto", 1.0), - ("HF_scaling_Gncx", 1.0), - ("HF_scaling_Pnak", 1.0), - ("HF_scaling_cat50_ref", 1.0), - ], - ) +import math - return params - - @staticmethod - def default_initial_conditions(): - "Set-up and return default initial conditions." - ic = OrderedDict( - [ - ("v", -87), - ("CaMKt", 0), - ("m", 0), - ("hf", 1), - ("hs", 1), - ("j", 1), - ("hsp", 1), - ("jp", 1), - ("mL", 0), - ("hL", 1), - ("hLp", 1), - ("a", 0), - ("iF", 1), - ("iS", 1), - ("ap", 0), - ("iFp", 1), - ("iSp", 1), - ("d", 0), - ("ff", 1), - ("fs", 1), - ("fcaf", 1), - ("fcas", 1), - ("jca", 1), - ("ffp", 1), - ("fcafp", 1), - ("nca", 0), - ("xrf", 0), - ("xrs", 0), - ("xs1", 0), - ("xs2", 0), - ("xk1", 1), - ("Jrelnp", 0), - ("Jrelp", 0), - ("nai", 7), - ("nass", 7), - ("ki", 145), - ("kss", 145), - ("cass", 0.0001), - ("cansr", 1.2), - ("cajsr", 1.2), - ("XS", 0), - ("XW", 0), - ("CaTrpn", 0), - ("TmB", 1), - ("Cd", 0), - ("cai", 0.0001), - ("Zetas", 0), - ("Zetaw", 0), - ], - ) - return ic - - def _I(self, v, s, time): - """ - Original gotran transmembrane current dV/dt - """ - time = time if time else Constant(0.0) - logger.debug("Evaluate transmembrane current") - # Assign states - assert len(s) == 47 - ( - CaMKt, - m, - hf, - hs, - j, - hsp, - jp, - mL, - hL, - hLp, - a, - iF, - iS, - ap, - iFp, - iSp, - d, - ff, - fs, - fcaf, - fcas, - jca, - ffp, - fcafp, - nca, - xrf, - xrs, - xs1, - xs2, - xk1, - Jrelnp, - Jrelp, - nai, - nass, - ki, - kss, - cass, - cansr, - cajsr, - XS, - XW, - CaTrpn, - TmB, - Cd, - cai, - Zetas, - Zetaw, - ) = s - - # Assign parameters - scale_ICaL = self._parameters["scale_ICaL"] - scale_IK1 = self._parameters["scale_IK1"] - scale_IKr = self._parameters["scale_IKr"] - scale_IKs = self._parameters["scale_IKs"] - scale_INaL = self._parameters["scale_INaL"] - cao = self._parameters["cao"] - ko = self._parameters["ko"] - nao = self._parameters["nao"] - F = self._parameters["F"] - R = self._parameters["R"] - T = self._parameters["T"] - CaMKo = self._parameters["CaMKo"] - KmCaM = self._parameters["KmCaM"] - KmCaMK = self._parameters["KmCaMK"] - PKNa = self._parameters["PKNa"] - Ahf = self._parameters["Ahf"] - GNa = self._parameters["GNa"] - Gto = self._parameters["Gto"] - Aff = self._parameters["Aff"] - zca = self._parameters["zca"] - Gncx = self._parameters["Gncx"] - KmCaAct = self._parameters["KmCaAct"] - kasymm = self._parameters["kasymm"] - kcaoff = self._parameters["kcaoff"] - kcaon = self._parameters["kcaon"] - kna1 = self._parameters["kna1"] - kna2 = self._parameters["kna2"] - kna3 = self._parameters["kna3"] - qca = self._parameters["qca"] - qna = self._parameters["qna"] - wca = self._parameters["wca"] - wna = self._parameters["wna"] - wnaca = self._parameters["wnaca"] - H = self._parameters["H"] - Khp = self._parameters["Khp"] - Kki = self._parameters["Kki"] - Kko = self._parameters["Kko"] - Kmgatp = self._parameters["Kmgatp"] - Knai0 = self._parameters["Knai0"] - Knao0 = self._parameters["Knao0"] - Knap = self._parameters["Knap"] - Kxkur = self._parameters["Kxkur"] - MgADP = self._parameters["MgADP"] - MgATP = self._parameters["MgATP"] - Pnak = self._parameters["Pnak"] - delta = self._parameters["delta"] - eP = self._parameters["eP"] - k1m = self._parameters["k1m"] - k1p = self._parameters["k1p"] - k2m = self._parameters["k2m"] - k2p = self._parameters["k2p"] - k3m = self._parameters["k3m"] - k3p = self._parameters["k3p"] - k4m = self._parameters["k4m"] - k4p = self._parameters["k4p"] - zk = self._parameters["zk"] - GKb = self._parameters["GKb"] - PNab = self._parameters["PNab"] - PCab = self._parameters["PCab"] - GpCa = self._parameters["GpCa"] - lmbda = self._parameters["lmbda"] - # Drug factor - scale_drug_INa = self._parameters["scale_drug_INa"] - scale_drug_INaL = self._parameters["scale_drug_INaL"] - scale_drug_Ito = self._parameters["scale_drug_Ito"] - scale_drug_ICaL = self._parameters["scale_drug_ICaL"] - scale_drug_IKr = self._parameters["scale_drug_IKr"] - scale_drug_IKs = self._parameters["scale_drug_IKs"] - scale_drug_IK1 = self._parameters["scale_drug_IK1"] - scale_drug_IKb = self._parameters["scale_drug_IKb"] - scale_drug_INab = self._parameters["scale_drug_INab"] - scale_drug_ICab = self._parameters["scale_drug_ICab"] - scale_drug_IpCa = self._parameters["scale_drug_IpCa"] - scale_drug_Isacns = self._parameters["scale_drug_Isacns"] - scale_drug_Isack = self._parameters["scale_drug_Isack"] - # Population factors - scale_popu_GNa = self._parameters["scale_popu_GNa"] - scale_popu_GCaL = self._parameters["scale_popu_GCaL"] - scale_popu_Gto = self._parameters["scale_popu_Gto"] - scale_popu_GNaL = self._parameters["scale_popu_GNaL"] - scale_popu_GKr = self._parameters["scale_popu_GKr"] - scale_popu_GKs = self._parameters["scale_popu_GKs"] - scale_popu_GK1 = self._parameters["scale_popu_GK1"] - scale_popu_GbK = self._parameters["scale_popu_GbK"] - scale_popu_KNCX = self._parameters["scale_popu_KNCX"] - scale_popu_KNaK = self._parameters["scale_popu_KNaK"] - scale_popu_GbNa = self._parameters["scale_popu_GbNa"] - scale_popu_GbCa = self._parameters["scale_popu_GbCa"] - scale_popu_KpCa = self._parameters["scale_popu_KpCa"] - # Systolic Heart Failure (HF with preserved ejection fraction) - HF_scaling_CaMKa = self._parameters["HF_scaling_CaMKa"] - HF_scaling_GNaL = self._parameters["HF_scaling_GNaL"] - HF_scaling_GK1 = self._parameters["HF_scaling_GK1"] - HF_scaling_Gto = self._parameters["HF_scaling_Gto"] - HF_scaling_Gncx = self._parameters["HF_scaling_Gncx"] - HF_scaling_Pnak = self._parameters["HF_scaling_Pnak"] - - # Init return args - current = [ufl.zero()] * 1 - - # Expressions for the CaMKt component - CaMKb = CaMKo * (1.0 - CaMKt) / (1.0 + KmCaM / cass) - CaMKa = (CaMKb + CaMKt) * HF_scaling_CaMKa - - # Expressions for the reversal potentials component - ENa = R * T * ufl.ln(nao / nai) / F - EK = R * T * ufl.ln(ko / ki) / F - EKs = R * T * ufl.ln((ko + PKNa * nao) / (PKNa * nai + ki)) / F - vffrt = (F * F) * v / (R * T) - vfrt = F * v / (R * T) - - # Expressions for the I_Na component - Ahs = 1.0 - Ahf - h = Ahf * hf + Ahs * hs - hp = Ahf * hf + Ahs * hsp - fINap = 1.0 / (1.0 + KmCaMK / CaMKa) - INa = ( - GNa - * scale_drug_INa - * scale_popu_GNa - * ufl.elem_pow(m, 3.0) - * (-ENa + v) - * ((1.0 - fINap) * h * j + fINap * hp * jp) - ) +import numpy - # Expressions for the INaL component - GNaL = 0.0075 * scale_INaL * scale_drug_INaL * scale_popu_GNaL * HF_scaling_GNaL - fINaLp = 1.0 / (1.0 + KmCaMK / CaMKa) - INaL = (-ENa + v) * ((1.0 - fINaLp) * hL + fINaLp * hLp) * GNaL * mL - - # Expressions for the Ito component - AiF = 1.0 / (1.0 + 0.24348537187522867 * ufl.exp(0.006613756613756614 * v)) - AiS = 1.0 - AiF - i = AiF * iF + AiS * iS - ip = AiF * iFp + AiS * iSp - fItop = 1.0 / (1.0 + KmCaMK / CaMKa) - Ito = ( - Gto - * scale_drug_Ito - * scale_popu_Gto - * HF_scaling_Gto - * (-EK + v) - * ((1.0 - fItop) * a * i + ap * fItop * ip) - ) - # Expressions for the ICaL ICaNa ICaK component - Afs = 1.0 - Aff - f = Aff * ff + Afs * fs - Afcaf = 0.3 + 0.6 / (1.0 + 0.36787944117144233 * ufl.exp(0.1 * v)) - Afcas = 1.0 - Afcaf - fca = Afcaf * fcaf + Afcas * fcas - fp = Aff * ffp + Afs * fs - fcap = Afcaf * fcafp + Afcas * fcas - PhiCaL = ( - 4.0 - * (-0.341 * cao + cass * ufl.exp(2.0 * vfrt)) - * vffrt - / (-1.0 + ufl.exp(2.0 * vfrt)) - ) - PhiCaNa = ( - 1.0 - * (-0.75 * nao + 0.75 * ufl.exp(1.0 * vfrt) * nass) - * vffrt - / (-1.0 + ufl.exp(1.0 * vfrt)) - ) - PhiCaK = ( - 1.0 - * (-0.75 * ko + 0.75 * ufl.exp(1.0 * vfrt) * kss) - * vffrt - / (-1.0 + ufl.exp(1.0 * vfrt)) - ) - PCa = 0.0001 * scale_ICaL * scale_drug_ICaL * scale_popu_GCaL - PCap = 1.1 * PCa - PCaNa = 0.00125 * PCa - PCaK = 0.0003574 * PCa - PCaNap = 0.00125 * PCap - PCaKp = 0.0003574 * PCap - fICaLp = 1.0 / (1.0 + KmCaMK / CaMKa) - ICaL = (1.0 - fICaLp) * ( - (1.0 - nca) * f + fca * jca * nca - ) * PCa * PhiCaL * d + ( - (1.0 - nca) * fp + fcap * jca * nca - ) * PCap * PhiCaL * d * fICaLp - ICaNa = (1.0 - fICaLp) * ( - (1.0 - nca) * f + fca * jca * nca - ) * PCaNa * PhiCaNa * d + ( - (1.0 - nca) * fp + fcap * jca * nca - ) * PCaNap * PhiCaNa * d * fICaLp - ICaK = (1.0 - fICaLp) * ( - (1.0 - nca) * f + fca * jca * nca - ) * PCaK * PhiCaK * d + ( - (1.0 - nca) * fp + fcap * jca * nca - ) * PCaKp * PhiCaK * d * fICaLp - - # Expressions for the IKr component - Axrf = 1.0 / (1.0 + 4.197299094734718 * ufl.exp(0.02617115938236064 * v)) - Axrs = 1.0 - Axrf - xr = Axrf * xrf + Axrs * xrs - rkr = 1.0 / ( - (1.0 + 2.0820090840784555 * ufl.exp(0.013333333333333334 * v)) - * (1.0 + 0.7165313105737893 * ufl.exp(0.03333333333333333 * v)) - ) - GKr = 0.046 * scale_IKr * scale_drug_IKr * scale_popu_GKr - IKr = 0.4303314829119352 * ufl.sqrt(ko) * (-EK + v) * GKr * rkr * xr - - # Expressions for the IKs component - KsCa = 1.0 + 0.6 / (1.0 + 6.481821026062645e-07 * ufl.elem_pow(1.0 / cai, 1.4)) - GKs = 0.0034 * scale_IKs * scale_drug_IKs * scale_popu_GKs - IKs = (-EKs + v) * GKs * KsCa * xs1 * xs2 - rk1 = 1.0 / ( - 1.0 - + 69220.6322106767 - * ufl.exp(0.10534077741493732 * v - 0.27388602127883704 * ko) - ) - GK1 = 0.1908 * scale_IK1 * scale_drug_IK1 * scale_popu_GK1 * HF_scaling_GK1 - IK1 = ufl.sqrt(ko) * (-EK + v) * GK1 * rk1 * xk1 - - # Expressions for the INaCa_i component - hca = ufl.exp(F * qca * v / (R * T)) - hna = ufl.exp(F * qna * v / (R * T)) - h1_i = 1 + (1 + hna) * nai / kna3 - h2_i = hna * nai / (kna3 * h1_i) - h3_i = 1.0 / h1_i - h4_i = 1.0 + (1 + nai / kna2) * nai / kna1 - h5_i = (nai * nai) / (kna1 * kna2 * h4_i) - h6_i = 1.0 / h4_i - h7_i = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 - h8_i = nao / (kna3 * h7_i * hna) - h9_i = 1.0 / h7_i - h10_i = 1.0 + kasymm + nao * (1.0 + nao / kna2) / kna1 - h11_i = (nao * nao) / (kna1 * kna2 * h10_i) - h12_i = 1.0 / h10_i - k1_i = cao * kcaon * h12_i - k2_i = kcaoff - k3p_i = wca * h9_i - k3pp_i = wnaca * h8_i - k3_i = k3p_i + k3pp_i - k4p_i = wca * h3_i / hca - k4pp_i = wnaca * h2_i - k4_i = k4p_i + k4pp_i - k5_i = kcaoff - k6_i = kcaon * cai * h6_i - k7_i = wna * h2_i * h5_i - k8_i = wna * h11_i * h8_i - x1_i = (k2_i + k3_i) * k5_i * k7_i + (k6_i + k7_i) * k2_i * k4_i - x2_i = (k1_i + k8_i) * k4_i * k6_i + (k4_i + k5_i) * k1_i * k7_i - x3_i = (k2_i + k3_i) * k6_i * k8_i + (k6_i + k7_i) * k1_i * k3_i - x4_i = (k1_i + k8_i) * k3_i * k5_i + (k4_i + k5_i) * k2_i * k8_i - E1_i = x1_i / (x1_i + x2_i + x3_i + x4_i) - E2_i = x2_i / (x1_i + x2_i + x3_i + x4_i) - E3_i = x3_i / (x1_i + x2_i + x3_i + x4_i) - E4_i = x4_i / (x1_i + x2_i + x3_i + x4_i) - allo_i = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cai, 2.0)) - zna = 1.0 - JncxNa_i = E3_i * k4pp_i - E2_i * k3pp_i + 3.0 * E4_i * k7_i - 3.0 * E1_i * k8_i - JncxCa_i = E2_i * k2_i - E1_i * k1_i - INaCa_i = ( - 0.8 - * Gncx - * scale_popu_KNCX - * HF_scaling_Gncx - * (zca * JncxCa_i + zna * JncxNa_i) - * allo_i - ) +class ORdmmLandPureEp: + pass - # Expressions for the INaCa_ss component - h1 = 1.0 + (1.0 + hna) * nass / kna3 - h2 = hna * nass / (kna3 * h1) - h3 = 1.0 / h1 - h4 = 1.0 + (1 + nass / kna2) * nass / kna1 - h5 = (nass * nass) / (kna1 * kna2 * h4) - h6 = 1.0 / h4 - h7 = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 - h8 = nao / (kna3 * h7 * hna) - h9 = 1.0 / h7 - h10 = 1.0 + kasymm + nao * (1 + nao / kna2) / kna1 - h11 = (nao * nao) / (kna1 * kna2 * h10) - h12 = 1.0 / h10 - k1 = cao * kcaon * h12 - k2 = kcaoff - k3p_ss = wca * h9 - k3pp = wnaca * h8 - k3 = k3p_ss + k3pp - k4p_ss = wca * h3 / hca - k4pp = wnaca * h2 - k4 = k4p_ss + k4pp - k5 = kcaoff - k6 = kcaon * cass * h6 - k7 = wna * h2 * h5 - k8 = wna * h11 * h8 - x1_ss = (k2 + k3) * k5 * k7 + (k6 + k7) * k2 * k4 - x2_ss = (k1 + k8) * k4 * k6 + (k4 + k5) * k1 * k7 - x3_ss = (k2 + k3) * k6 * k8 + (k6 + k7) * k1 * k3 - x4_ss = (k1 + k8) * k3 * k5 + (k4 + k5) * k2 * k8 - E1_ss = x1_ss / (x1_ss + x2_ss + x3_ss + x4_ss) - E2_ss = x2_ss / (x1_ss + x2_ss + x3_ss + x4_ss) - E3_ss = x3_ss / (x1_ss + x2_ss + x3_ss + x4_ss) - E4_ss = x4_ss / (x1_ss + x2_ss + x3_ss + x4_ss) - allo_ss = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cass, 2.0)) - JncxNa_ss = E3_ss * k4pp - E2_ss * k3pp + 3.0 * E4_ss * k7 - 3.0 * E1_ss * k8 - JncxCa_ss = E2_ss * k2 - E1_ss * k1 - INaCa_ss = ( - 0.2 - * Gncx - * scale_popu_KNCX - * HF_scaling_Gncx - * (zca * JncxCa_ss + zna * JncxNa_ss) - * allo_ss - ) - # Expressions for the INaK component - Knai = Knai0 * ufl.exp(0.3333333333333333 * F * delta * v / (R * T)) - Knao = Knao0 * ufl.exp(0.3333333333333333 * F * (1.0 - delta) * v / (R * T)) - P = eP / (1.0 + H / Khp + nai / Knap + ki / Kxkur) - a1 = ( - k1p - * ufl.elem_pow(nai / Knai, 3.0) - / ( - -1.0 - + ufl.elem_pow(1.0 + ki / Kki, 2.0) - + ufl.elem_pow(1.0 + nai / Knai, 3.0) - ) +def parameter_index(name: str) -> float: + """Return the index of the parameter with the given name + + Arguments + --------- + name : str + The name of the parameter + + Returns + ------- + float + The index of the parameter + + Raises + ------ + KeyError + If the name is not a valid parameter + """ + + data = { + "Aff": 0, + "Ahf": 1, + "BSLmax": 2, + "BSRmax": 3, + "Beta0": 4, + "Beta1": 5, + "CaMKo": 6, + "Esac_ns": 7, + "F": 8, + "GKb": 9, + "GNa": 10, + "Gncx": 11, + "GpCa": 12, + "Gsac_k": 13, + "Gsac_ns": 14, + "Gto": 15, + "H": 16, + "Khp": 17, + "Kki": 18, + "Kko": 19, + "KmBSL": 20, + "KmBSR": 21, + "KmCaAct": 22, + "KmCaM": 23, + "KmCaMK": 24, + "Kmgatp": 25, + "Kmn": 26, + "Knai0": 27, + "Knao0": 28, + "Knap": 29, + "Kxkur": 30, + "L": 31, + "MgADP": 32, + "MgATP": 33, + "PCab": 34, + "PKNa": 35, + "PNab": 36, + "Pnak": 37, + "R": 38, + "T": 39, + "Tot_A": 40, + "Tref": 41, + "Trpn50": 42, + "aCaMK": 43, + "amp": 44, + "bCaMK": 45, + "bt": 46, + "calib": 47, + "cao": 48, + "cat50_ref": 49, + "celltype": 50, + "cmdnmax": 51, + "csqnmax": 52, + "dLambda": 53, + "delta": 54, + "delta_epi": 55, + "duration": 56, + "eP": 57, + "emcoupling": 58, + "etal": 59, + "etas": 60, + "gammas": 61, + "gammaw": 62, + "isacs": 63, + "k1m": 64, + "k1p": 65, + "k2m": 66, + "k2n": 67, + "k2p": 68, + "k3m": 69, + "k3p": 70, + "k4m": 71, + "k4p": 72, + "kasymm": 73, + "kcaoff": 74, + "kcaon": 75, + "kmcmdn": 76, + "kmcsqn": 77, + "kmtrpn": 78, + "kna1": 79, + "kna2": 80, + "kna3": 81, + "ko": 82, + "ktrpn": 83, + "ku": 84, + "kuw": 85, + "kws": 86, + "lambda_max": 87, + "lmbda": 88, + "mode": 89, + "nao": 90, + "ntm": 91, + "ntrpn": 92, + "p_a": 93, + "p_b": 94, + "p_k": 95, + "phi": 96, + "qca": 97, + "qna": 98, + "rad": 99, + "rs": 100, + "rw": 101, + "scale_HF_CaMKa": 102, + "scale_HF_GK1": 103, + "scale_HF_GNaL": 104, + "scale_HF_Gncx": 105, + "scale_HF_Gto": 106, + "scale_HF_Jleak": 107, + "scale_HF_Jrel_inf": 108, + "scale_HF_Jup": 109, + "scale_HF_Pnak": 110, + "scale_HF_cat50_ref": 111, + "scale_HF_thL": 112, + "scale_ICaL": 113, + "scale_IK1": 114, + "scale_IKr": 115, + "scale_IKs": 116, + "scale_INaL": 117, + "scale_drug_ICaL": 118, + "scale_drug_ICab": 119, + "scale_drug_IK1": 120, + "scale_drug_IKb": 121, + "scale_drug_IKr": 122, + "scale_drug_IKs": 123, + "scale_drug_INa": 124, + "scale_drug_INaL": 125, + "scale_drug_INab": 126, + "scale_drug_IpCa": 127, + "scale_drug_Isack": 128, + "scale_drug_Isacns": 129, + "scale_drug_Ito": 130, + "thL": 131, + "tjca": 132, + "trpnmax": 133, + "wca": 134, + "wna": 135, + "wnaca": 136, + "zca": 137, + "zk": 138, + } + return data[name] + + +def state_index(name: str) -> float: + """Return the index of the state with the given name + + Arguments + --------- + name : str + The name of the state + + Returns + ------- + float + The index of the state + + Raises + ------ + KeyError + If the name is not a valid state + """ + + data = { + "hL": 0, + "a": 1, + "ap": 2, + "d": 3, + "ff": 4, + "fs": 5, + "hf": 6, + "hs": 7, + "m": 8, + "xrf": 9, + "xrs": 10, + "xs1": 11, + "CaMKt": 12, + "xk1": 13, + "Zetaw": 14, + "XS": 15, + "XW": 16, + "TmB": 17, + "hLp": 18, + "iF": 19, + "iS": 20, + "fcaf": 21, + "fcas": 22, + "jca": 23, + "j": 24, + "fcafp": 25, + "ffp": 26, + "hsp": 27, + "jp": 28, + "mL": 29, + "xs2": 30, + "Zetas": 31, + "nca": 32, + "CaTrpn": 33, + "iFp": 34, + "iSp": 35, + "cajsr": 36, + "cansr": 37, + "kss": 38, + "Cd": 39, + "Jrelnp": 40, + "Jrelp": 41, + "ki": 42, + "cass": 43, + "nass": 44, + "cai": 45, + "nai": 46, + "v": 47, + } + return data[name] + + +def init_parameter_values(**values): + """Initialize parameter values""" + # Aff=0.6, Ahf=0.99, BSLmax=1.124, BSRmax=0.047, Beta0=2.3 + # Beta1=-2.4, CaMKo=0.05, Esac_ns=-10, F=96485.0, GKb=0.003 + # GNa=31, Gncx=0.0008, GpCa=0.0005, Gsac_k=(0.2882*800)/210 + # Gsac_ns=0.006, Gto=0.02, H=1e-07, Khp=1.698e-07, Kki=0.5 + # Kko=0.3582, KmBSL=0.0087, KmBSR=0.00087, KmCaAct=0.00015 + # KmCaM=0.0015, KmCaMK=0.15, Kmgatp=1.698e-07, Kmn=0.002 + # Knai0=9.073, Knao0=27.78, Knap=224.0, Kxkur=292.0, L=0.01 + # MgADP=0.05, MgATP=9.8, PCab=2.5e-08, PKNa=0.01833 + # PNab=3.75e-10, Pnak=30, R=8314.0, T=310.0, Tot_A=25, Tref=120 + # Trpn50=0.35, aCaMK=0.05, amp=-80.0, bCaMK=0.00068, bt=4.75 + # calib=1, cao=1.8, cat50_ref=0.805, celltype=0, cmdnmax=0.05 + # csqnmax=10.0, dLambda=0, delta=-0.155, delta_epi=1.0 + # duration=0.5, eP=4.2, emcoupling=1, etal=200, etas=20 + # gammas=0.0085, gammaw=0.615, isacs=0, k1m=182.4, k1p=949.5 + # k2m=39.4, k2n=1000.0, k2p=687.2, k3m=79300.0, k3p=1899.0 + # k4m=40.0, k4p=639.0, kasymm=12.5, kcaoff=5000.0 + # kcaon=1500000.0, kmcmdn=0.00238, kmcsqn=0.8, kmtrpn=0.0005 + # kna1=15.0, kna2=5.0, kna3=88.12, ko=5.4, ktrpn=0.1, ku=0.04 + # kuw=0.182, kws=0.012, lambda_max=1.1, lmbda=1, mode=1 + # nao=140.0, ntm=2.4, ntrpn=2, p_a=2.1, p_b=9.1, p_k=7 + # phi=2.23, qca=0.167, qna=0.5224, rad=0.0011, rs=0.25, rw=0.5 + # scale_HF_CaMKa=1.0, scale_HF_GK1=1.0, scale_HF_GNaL=1.0 + # scale_HF_Gncx=1.0, scale_HF_Gto=1.0, scale_HF_Jleak=1.0 + # scale_HF_Jrel_inf=1.0, scale_HF_Jup=1.0, scale_HF_Pnak=1.0 + # scale_HF_cat50_ref=1.0, scale_HF_thL=1.0, scale_ICaL=1.018 + # scale_IK1=1.414, scale_IKr=1.119, scale_IKs=1.648 + # scale_INaL=2.274, scale_drug_ICaL=1.0, scale_drug_ICab=1.0 + # scale_drug_IK1=1.0, scale_drug_IKb=1.0, scale_drug_IKr=1.0 + # scale_drug_IKs=1.0, scale_drug_INa=1.0, scale_drug_INaL=1.0 + # scale_drug_INab=1.0, scale_drug_IpCa=1.0 + # scale_drug_Isack=1.0, scale_drug_Isacns=1.0 + # scale_drug_Ito=1.0, thL=200.0, tjca=75.0, trpnmax=0.07 + # wca=60000.0, wna=60000.0, wnaca=5000.0, zca=2.0, zk=1.0 + + parameters = numpy.array( + [ + 0.6, + 0.99, + 1.124, + 0.047, + 2.3, + -2.4, + 0.05, + -10, + 96485.0, + 0.003, + 31, + 0.0008, + 0.0005, + (0.2882 * 800) / 210, + 0.006, + 0.02, + 1e-07, + 1.698e-07, + 0.5, + 0.3582, + 0.0087, + 0.00087, + 0.00015, + 0.0015, + 0.15, + 1.698e-07, + 0.002, + 9.073, + 27.78, + 224.0, + 292.0, + 0.01, + 0.05, + 9.8, + 2.5e-08, + 0.01833, + 3.75e-10, + 30, + 8314.0, + 310.0, + 25, + 120, + 0.35, + 0.05, + -80.0, + 0.00068, + 4.75, + 1, + 1.8, + 0.805, + 0, + 0.05, + 10.0, + 0, + -0.155, + 1.0, + 0.5, + 4.2, + 1, + 200, + 20, + 0.0085, + 0.615, + 0, + 182.4, + 949.5, + 39.4, + 1000.0, + 687.2, + 79300.0, + 1899.0, + 40.0, + 639.0, + 12.5, + 5000.0, + 1500000.0, + 0.00238, + 0.8, + 0.0005, + 15.0, + 5.0, + 88.12, + 5.4, + 0.1, + 0.04, + 0.182, + 0.012, + 1.1, + 1, + 1, + 140.0, + 2.4, + 2, + 2.1, + 9.1, + 7, + 2.23, + 0.167, + 0.5224, + 0.0011, + 0.25, + 0.5, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.018, + 1.414, + 1.119, + 1.648, + 2.274, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 200.0, + 75.0, + 0.07, + 60000.0, + 60000.0, + 5000.0, + 2.0, + 1.0, + ], + ) + + for key, value in values.items(): + parameters[parameter_index(key)] = value + + return parameters + + +def init_state_values(**values): + """Initialize state values""" + # hL=1, a=0, ap=0, d=0, ff=1, fs=1, hf=1, hs=1, m=0, xrf=0 + # xrs=0, xs1=0, CaMKt=0, xk1=1, Zetaw=0, XS=0, XW=0, TmB=1 + # hLp=1, iF=1, iS=1, fcaf=1, fcas=1, jca=1, j=1, fcafp=1, ffp=1 + # hsp=1, jp=1, mL=0, xs2=0, Zetas=0, nca=0, CaTrpn=0, iFp=1 + # iSp=1, cajsr=1.2, cansr=1.2, kss=145, Cd=0, Jrelnp=0, Jrelp=0 + # ki=145, cass=0.0001, nass=7, cai=0.0001, nai=7, v=-87 + + states = numpy.array( + [ + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1.2, + 1.2, + 145, + 0, + 0, + 0, + 145, + 0.0001, + 7, + 0.0001, + 7, + -87, + ], + ) + + for key, value in values.items(): + states[state_index(key)] = value + + return states + + +def rhs(t, states, parameters): + # Assign states + hL = states[0] + a = states[1] + ap = states[2] + d = states[3] + ff = states[4] + fs = states[5] + hf = states[6] + hs = states[7] + m = states[8] + xrf = states[9] + xrs = states[10] + xs1 = states[11] + CaMKt = states[12] + xk1 = states[13] + Zetaw = states[14] + XS = states[15] + XW = states[16] + TmB = states[17] + hLp = states[18] + iF = states[19] + iS = states[20] + fcaf = states[21] + fcas = states[22] + jca = states[23] + j = states[24] + fcafp = states[25] + ffp = states[26] + hsp = states[27] + jp = states[28] + mL = states[29] + xs2 = states[30] + Zetas = states[31] + nca = states[32] + CaTrpn = states[33] + iFp = states[34] + iSp = states[35] + cajsr = states[36] + cansr = states[37] + kss = states[38] + Cd = states[39] + Jrelnp = states[40] + Jrelp = states[41] + ki = states[42] + cass = states[43] + nass = states[44] + cai = states[45] + nai = states[46] + v = states[47] + + # Assign parameters + Aff = parameters[0] + Ahf = parameters[1] + BSLmax = parameters[2] + BSRmax = parameters[3] + Beta0 = parameters[4] + Beta1 = parameters[5] + CaMKo = parameters[6] + Esac_ns = parameters[7] + F = parameters[8] + GKb = parameters[9] + GNa = parameters[10] + Gncx = parameters[11] + GpCa = parameters[12] + Gsac_k = parameters[13] + Gsac_ns = parameters[14] + Gto = parameters[15] + H = parameters[16] + Khp = parameters[17] + Kki = parameters[18] + Kko = parameters[19] + KmBSL = parameters[20] + KmBSR = parameters[21] + KmCaAct = parameters[22] + KmCaM = parameters[23] + KmCaMK = parameters[24] + Kmgatp = parameters[25] + Kmn = parameters[26] + Knai0 = parameters[27] + Knao0 = parameters[28] + Knap = parameters[29] + Kxkur = parameters[30] + L = parameters[31] + MgADP = parameters[32] + MgATP = parameters[33] + PCab = parameters[34] + PKNa = parameters[35] + PNab = parameters[36] + Pnak = parameters[37] + R = parameters[38] + T = parameters[39] + Tot_A = parameters[40] + Tref = parameters[41] + Trpn50 = parameters[42] + aCaMK = parameters[43] + amp = parameters[44] + bCaMK = parameters[45] + bt = parameters[46] + calib = parameters[47] + cao = parameters[48] + cat50_ref = parameters[49] + celltype = parameters[50] + cmdnmax = parameters[51] + csqnmax = parameters[52] + dLambda = parameters[53] + delta = parameters[54] + delta_epi = parameters[55] + duration = parameters[56] + eP = parameters[57] + emcoupling = parameters[58] + etal = parameters[59] + etas = parameters[60] + gammas = parameters[61] + gammaw = parameters[62] + isacs = parameters[63] + k1m = parameters[64] + k1p = parameters[65] + k2m = parameters[66] + k2n = parameters[67] + k2p = parameters[68] + k3m = parameters[69] + k3p = parameters[70] + k4m = parameters[71] + k4p = parameters[72] + kasymm = parameters[73] + kcaoff = parameters[74] + kcaon = parameters[75] + kmcmdn = parameters[76] + kmcsqn = parameters[77] + kmtrpn = parameters[78] + kna1 = parameters[79] + kna2 = parameters[80] + kna3 = parameters[81] + ko = parameters[82] + ktrpn = parameters[83] + ku = parameters[84] + kuw = parameters[85] + kws = parameters[86] + lambda_max = parameters[87] + lmbda = parameters[88] + mode = parameters[89] + nao = parameters[90] + ntm = parameters[91] + ntrpn = parameters[92] + p_a = parameters[93] + p_b = parameters[94] + p_k = parameters[95] + phi = parameters[96] + qca = parameters[97] + qna = parameters[98] + rad = parameters[99] + rs = parameters[100] + rw = parameters[101] + scale_HF_CaMKa = parameters[102] + scale_HF_GK1 = parameters[103] + scale_HF_GNaL = parameters[104] + scale_HF_Gncx = parameters[105] + scale_HF_Gto = parameters[106] + scale_HF_Jleak = parameters[107] + scale_HF_Jrel_inf = parameters[108] + scale_HF_Jup = parameters[109] + scale_HF_Pnak = parameters[110] + scale_HF_cat50_ref = parameters[111] + scale_HF_thL = parameters[112] + scale_ICaL = parameters[113] + scale_IK1 = parameters[114] + scale_IKr = parameters[115] + scale_IKs = parameters[116] + scale_INaL = parameters[117] + scale_drug_ICaL = parameters[118] + scale_drug_ICab = parameters[119] + scale_drug_IK1 = parameters[120] + scale_drug_IKb = parameters[121] + scale_drug_IKr = parameters[122] + scale_drug_IKs = parameters[123] + scale_drug_INa = parameters[124] + scale_drug_INaL = parameters[125] + scale_drug_INab = parameters[126] + scale_drug_IpCa = parameters[127] + scale_drug_Isack = parameters[128] + scale_drug_Isacns = parameters[129] + scale_drug_Ito = parameters[130] + thL = parameters[131] + tjca = parameters[132] + trpnmax = parameters[133] + wca = parameters[134] + wna = parameters[135] + wnaca = parameters[136] + zca = parameters[137] + zk = parameters[138] + + # Assign expressions + values = numpy.zeros_like(states) + zna = 1.0 + Isac_P_k = 0 + Isac_P_ns = 0 + Afcaf = 0.3 + 0.6 / (numpy.exp((v - 10.0) / 10.0) + 1.0) + AiF = 1.0 / (numpy.exp((v - 213.6) / 151.2) + 1.0) + Axrf = 1.0 / (numpy.exp((v + 54.81) / 38.21) + 1.0) + ass = 1.0 / (numpy.exp((-(v - 14.34)) / 14.82) + 1.0) + assp = 1.0 / (numpy.exp((-(v - 24.34)) / 14.82) + 1.0) + dss = 1.0 / (numpy.exp((-(v + 3.94)) / 4.23) + 1.0) + dti_develop = 1.354 + 0.0001 / ( + numpy.exp((-(v - 12.23)) / 0.2154) + numpy.exp((v - 167.4) / 15.89) + ) + dti_recover = 1.0 - 0.5 / (numpy.exp((v + 70.0) / 20.0) + 1.0) + fss = 1.0 / (numpy.exp((v + 19.58) / 3.696) + 1.0) + hLss = 1.0 / (numpy.exp((v + 87.61) / 7.488) + 1.0) + hLssp = 1.0 / (numpy.exp((v + 93.81) / 7.488) + 1.0) + hss = 1.0 / (numpy.exp((v + 78.5) / 6.22) + 1) + hssp = 1.0 / (numpy.exp(((v + 78.5) + 6.2) / 6.22) + 1) + iss = 1.0 / (numpy.exp((v + 43.94) / 5.711) + 1.0) + mLss = 1.0 / (numpy.exp((-(v + 42.85)) / 5.264) + 1.0) + mss = 1.0 / (numpy.exp((-((v + 39.57) + 9.4)) / 7.5) + 1.0) + rkr = (1.0 * (1.0 / (numpy.exp((v + 55.0) / 75.0) + 1.0))) / ( + numpy.exp((v - 10.0) / 30.0) + 1.0 + ) + ta = 1.0515 / ( + 1.0 / ((1.2089 * (numpy.exp((-(v - 18.4099)) / 29.3814) + 1.0))) + + 3.5 / (numpy.exp((v + 100.0) / 29.3814) + 1.0) + ) + td = 0.6 + 1.0 / (numpy.exp((-0.05) * (v + 6.0)) + numpy.exp(0.09 * (v + 14.0))) + tfcaf = 7.0 + 1.0 / ( + 0.04 * numpy.exp((-(v - 4.0)) / 7.0) + 0.04 * numpy.exp((v - 4.0) / 7.0) + ) + tfcas = 100.0 + 1.0 / ( + 0.00012 * numpy.exp((-v) / 3.0) + 0.00012 * numpy.exp(v / 7.0) + ) + tff = 7.0 + 1.0 / ( + 0.0045 * numpy.exp((-(v + 20.0)) / 10.0) + 0.0045 * numpy.exp((v + 20.0) / 10.0) + ) + tfs = 1000.0 + 1.0 / ( + 3.5e-05 * numpy.exp((-(v + 5.0)) / 4.0) + 3.5e-05 * numpy.exp((v + 5.0) / 6.0) + ) + thf = 1.0 / ( + 6.149 * numpy.exp((v + 0.5096) / 20.27) + + 1.432e-05 * numpy.exp((-(v + 1.196)) / 6.285) + ) + ths = 1.0 / ( + 0.009794 * numpy.exp((-(v + 17.95)) / 28.05) + + 0.3343 * numpy.exp((v + 5.73) / 56.66) + ) + tj = 2.038 + 1.0 / ( + 0.3052 * numpy.exp((v + 0.9941) / 38.45) + + 0.02136 * numpy.exp((-(v + 100.6)) / 8.281) + ) + tm = 1.0 / ( + 6.765 * numpy.exp((v + 11.64) / 34.77) + + 8.552 * numpy.exp((-(v + 77.42)) / 5.955) + ) + txk1 = 122.2 / (numpy.exp((-(v + 127.2)) / 20.36) + numpy.exp((v + 236.8) / 69.33)) + txrf = 12.98 + 1.0 / ( + 4.123e-05 * numpy.exp((-(v - 47.78)) / 20.38) + + 0.3652 * numpy.exp((v - 31.66) / 3.869) + ) + txrs = 1.865 + 1.0 / ( + 1.128e-05 * numpy.exp((-(v - 29.74)) / 25.94) + + 0.06629 * numpy.exp((v - 34.7) / 7.355) + ) + txs1 = 817.3 + 1.0 / ( + 0.0002326 * numpy.exp((v + 48.28) / 17.8) + + 0.001292 * numpy.exp((-(v + 210.0)) / 230.0) + ) + txs2 = 1.0 / ( + 0.01 * numpy.exp((v - 50.0) / 20.0) + 0.0193 * numpy.exp((-(v + 66.54)) / 31.0) + ) + xkb = 1.0 / (numpy.exp((-(v - 14.48)) / 18.34) + 1.0) + xrss = 1.0 / (numpy.exp((-(v + 8.337)) / 6.789) + 1.0) + xs1ss = 1.0 / (numpy.exp((-(v + 11.6)) / 8.932) + 1.0) + Afs = 1.0 - Aff + Ageo = L * ((2 * 3.14) * rad) + rad * ((2 * 3.14) * rad) + vcell = L * (rad * ((3.14 * 1000) * rad)) + Ahs = 1.0 - Ahf + Aw = (Tot_A * rs) / (rs + rw * (1 - rs)) + Jupnp = (0.004375 * cai) / (cai + 0.00092) + Jupp = ((0.004375 * 2.75) * cai) / ((cai + 0.00092) - 0.00017) + KsCa = 1.0 + 0.6 / ((3.8e-05 / cai) ** 1.4 + 1.0) + Bcai = 1.0 / ((cmdnmax * kmcmdn) / (cai + kmcmdn) ** 2.0 + 1.0) + Bcajsr = 1.0 / ((csqnmax * kmcsqn) / (cajsr + kmcsqn) ** 2.0 + 1.0) + Jdiff = (-cai + cass) / 0.2 + Bcass = 1.0 / ( + (BSLmax * KmBSL) / (KmBSL + cass) ** 2.0 + + ((BSRmax * KmBSR) / (KmBSR + cass) ** 2.0 + 1.0) + ) + CaMKb = (CaMKo * (1.0 - CaMKt)) / (KmCaM / cass + 1.0) + CaTrpn_max = (CaTrpn) * (CaTrpn > 0) + (0) * numpy.logical_not((CaTrpn > 0)) + vffrt = (F * (F * v)) / ((R * T)) + vfrt = (F * v) / ((R * T)) + EK = ((R * T) / F) * numpy.log(ko / ki) + rk1 = 1.0 / (numpy.exp((-2.6 * ko + (v + 105.8)) / 9.493) + 1.0) + xk1ss = 1.0 / ( + numpy.exp((-((2.5538 * ko + v) + 144.59)) / (1.5692 * ko + 3.8115)) + 1.0 + ) + ENa = ((R * T) / F) * numpy.log(nao / nai) + EKs = ((R * T) / F) * numpy.log((PKNa * nao + ko) / (PKNa * nai + ki)) + GK1 = scale_HF_GK1 * ((0.1908 * scale_IK1) * scale_drug_IK1) + GKr = (0.046 * scale_IKr) * scale_drug_IKr + GKs = (0.0034 * scale_IKs) * scale_drug_IKs + GNaL = scale_HF_GNaL * ((0.0075 * scale_INaL) * scale_drug_INaL) + km2n = 1.0 * jca + IpCa = (cai * (GpCa * scale_drug_IpCa)) / (cai + 0.0005) + Istim = (amp) * (duration >= t) + (0) * numpy.logical_not((duration >= t)) + JdiffK = (-ki + kss) / 2.0 + JdiffNa = (-nai + nass) / 2.0 + Jtr = (-cajsr + cansr) / 100.0 + Jleak = ((0.0039375 * cansr) * scale_HF_Jleak) / 15.0 + Knai = Knai0 * numpy.exp((F * (delta * v)) / (((3.0 * R) * T))) + Knao = Knao0 * numpy.exp((F * (v * (1.0 - delta))) / (((3.0 * R) * T))) + P = eP / (((H / Khp + 1.0) + nai / Knap) + ki / Kxkur) + PCa = (0.0001 * scale_ICaL) * scale_drug_ICaL + XW_max = (XW) * (XW > 0) + (0) * numpy.logical_not((XW > 0)) + XS_max = (XS) * (XS > 0) + (0) * numpy.logical_not((XS > 0)) + XU = -XW + (-XS + (1 - TmB)) + a2 = k2p + a4 = ((MgATP * k4p) / Kmgatp) / (1.0 + MgATP / Kmgatp) + a_rel = 0.5 * bt + btp = 1.25 * bt + tau_rel_tmp = bt / (1.0 + 0.0123 / cajsr) + allo_i = 1.0 / ((KmCaAct / cai) ** 2.0 + 1.0) + allo_ss = 1.0 / ((KmCaAct / cass) ** 2.0 + 1.0) + b1 = MgADP * k1m + cs = ((kws * phi) * (rw * (1 - rs))) / rs + ksu = (kws * rw) * (-1 + 1 / rs) + cw = ((kuw * phi) * ((1 - rs) * (1 - rw))) / ((rw * (1 - rs))) + kwu = kuw * (-1 + 1 / rw) - kws + gammasu = ( + gammas * Zetas * 1 * (Zetas > 0) + + 0 + * (~(Zetas > 0)) + * numpy.logical_and.reduce( + ( + numpy.logical_or((Zetas > -1), (Zetas > 0)), + numpy.logical_or((Zetas > 0), (Zetas < -1)), + numpy.logical_or.reduce( + ((Zetas >= -1), (Zetas <= 0), (Zetas > -1 / 2)), + ), + ), ) - b1 = MgADP * k1m - a2 = k2p - b2 = ( - k2m - * ufl.elem_pow(nao / Knao, 3.0) - / ( - -1.0 - + ufl.elem_pow(1.0 + ko / Kko, 2.0) - + ufl.elem_pow(1.0 + nao / Knao, 3.0) + + (-Zetas - 1) * 1 * (Zetas < -1) + + 0 + * (~(Zetas < -1)) + * ( + ~numpy.logical_and.reduce( + ( + numpy.logical_or((Zetas > -1), (Zetas > 0)), + numpy.logical_or((Zetas > 0), (Zetas < -1)), + numpy.logical_or.reduce( + ((Zetas >= -1), (Zetas <= 0), (Zetas > -1 / 2)), + ), + ), ) ) - a3 = ( - k3p - * ufl.elem_pow(ko / Kko, 2.0) + ) + gammawu = gammaw * numpy.abs(Zetaw) + h10 = (nao / kna1) * (1 + nao / kna2) + (kasymm + 1.0) + h10_i = (nao / kna1) * (1.0 + nao / kna2) + (kasymm + 1.0) + h4 = (nass / kna1) * (1 + nass / kna2) + 1.0 + h4_i = (nai / kna1) * (1 + nai / kna2) + 1.0 + hca = numpy.exp((F * (qca * v)) / ((R * T))) + hna = numpy.exp((F * (qna * v)) / ((R * T))) + k2 = kcaoff + k2_i = kcaoff + k5 = kcaoff + k5_i = kcaoff + kb = (Trpn50**ntm * ku) / (-rw * (1 - rs) + (1 - rs)) + lambda_min12 = (lmbda) * (lmbda < 1.2) + (1.2) * numpy.logical_not((lmbda < 1.2)) + thLp = scale_HF_thL * (3.0 * thL) + tiF = ( + delta_epi + * ( + 1 / ( - -1.0 - + ufl.elem_pow(1.0 + ko / Kko, 2.0) - + ufl.elem_pow(1.0 + nao / Knao, 3.0) + 0.3933 * numpy.exp((-(v + 100.0)) / 100.0) + + 0.08004 * numpy.exp((v + 50.0) / 16.59) ) ) - b3 = H * k3m * P / (1.0 + MgATP / Kmgatp) - a4 = MgATP * k4p / (Kmgatp * (1.0 + MgATP / Kmgatp)) - b4 = ( - k4m - * ufl.elem_pow(ki / Kki, 2.0) + + 4.562 + ) + tiS = ( + delta_epi + * ( + 1 / ( - -1.0 - + ufl.elem_pow(1.0 + ki / Kki, 2.0) - + ufl.elem_pow(1.0 + nai / Knai, 3.0) + 0.001416 * numpy.exp((-(v + 96.52)) / 59.05) + + 1.78e-08 * numpy.exp((v + 114.1) / 8.079) ) ) - x1 = a1 * a2 * a4 + a1 * a2 * b3 + a2 * b3 * b4 + b2 * b3 * b4 - x2 = a1 * a2 * a3 + a2 * a3 * b4 + a3 * b1 * b4 + b1 * b2 * b4 - x3 = a2 * a3 * a4 + a3 * a4 * b1 + a4 * b1 * b2 + b1 * b2 * b3 - x4 = a1 * a3 * a4 + a1 * a4 * b2 + a1 * b2 * b3 + b2 * b3 * b4 - E1 = x1 / (x1 + x2 + x3 + x4) - E2 = x2 / (x1 + x2 + x3 + x4) - E3 = x3 / (x1 + x2 + x3 + x4) - E4 = x4 / (x1 + x2 + x3 + x4) - JnakNa = 3.0 * E1 * a3 - 3.0 * E2 * b3 - JnakK = 2.0 * E4 * b1 - 2.0 * E3 * a1 - INaK = Pnak * scale_popu_KNaK * HF_scaling_Pnak * (zk * JnakK + zna * JnakNa) - - # Expressions for the IKb component - xkb = 1.0 / (1.0 + 2.202363450949239 * ufl.exp(-0.05452562704471101 * v)) - IKb = GKb * scale_popu_GbK * scale_drug_IKb * (-EK + v) * xkb - - # Expressions for the INab component - INab = ( - PNab - * scale_drug_INab - * scale_popu_GbNa - * (-nao + ufl.exp(vfrt) * nai) - * vffrt - / (-1.0 + ufl.exp(vfrt)) + + 23.62 + ) + Afcas = 1.0 - Afcaf + AiS = 1.0 - AiF + Axrs = 1.0 - Axrf + fcass = fss + dhL_dt = (-hL + hLss) / ((scale_HF_thL * thL)) + values[0] = dhL_dt + jss = hss + da_dt = (-a + ass) / ta + values[1] = da_dt + dap_dt = (-ap + assp) / ta + values[2] = dap_dt + dd_dt = (-d + dss) / td + values[3] = dd_dt + tfcafp = 2.5 * tfcaf + tffp = 2.5 * tff + dff_dt = (-ff + fss) / tff + values[4] = dff_dt + dfs_dt = (-fs + fss) / tfs + values[5] = dfs_dt + dhf_dt = (-hf + hss) / thf + values[6] = dhf_dt + thsp = 3.0 * ths + dhs_dt = (-hs + hss) / ths + values[7] = dhs_dt + tjp = 1.46 * tj + tmL = tm + dm_dt = (-m + mss) / tm + values[8] = dm_dt + dxrf_dt = (-xrf + xrss) / txrf + values[9] = dxrf_dt + dxrs_dt = (-xrs + xrss) / txrs + values[10] = dxrs_dt + xs2ss = xs1ss + dxs1_dt = (-xs1 + xs1ss) / txs1 + values[11] = dxs1_dt + f = Aff * ff + Afs * fs + fp = Aff * ffp + Afs * fs + Acap = 2 * Ageo + vjsr = 0.0048 * vcell + vmyo = 0.68 * vcell + vnsr = 0.0552 * vcell + vss = 0.02 * vcell + h = Ahf * hf + Ahs * hs + hp = Ahf * hf + Ahs * hsp + As = Aw + CaMKa = scale_HF_CaMKa * (CaMKb + CaMKt) + dCaMKt_dt = -CaMKt * bCaMK + (CaMKb * aCaMK) * (CaMKb + CaMKt) + values[12] = dCaMKt_dt + ICab = ( + (vffrt * (4.0 * (PCab * scale_drug_ICab))) + * (cai * numpy.exp(2.0 * vfrt) - 0.341 * cao) + ) / (numpy.exp(2.0 * vfrt) - 1.0) + INab = ((vffrt * (PNab * scale_drug_INab)) * (nai * numpy.exp(vfrt) - nao)) / ( + numpy.exp(vfrt) - 1.0 + ) + PhiCaK = ((1.0 * vffrt) * (-0.75 * ko + (0.75 * kss) * numpy.exp(1.0 * vfrt))) / ( + numpy.exp(1.0 * vfrt) - 1.0 + ) + PhiCaL = ((4.0 * vffrt) * (-0.341 * cao + cass * numpy.exp(2.0 * vfrt))) / ( + numpy.exp(2.0 * vfrt) - 1.0 + ) + PhiCaNa = ( + (1.0 * vffrt) * (-0.75 * nao + (0.75 * nass) * numpy.exp(1.0 * vfrt)) + ) / (numpy.exp(1.0 * vfrt) - 1.0) + IKb = (xkb * (GKb * scale_drug_IKb)) * (-EK + v) + dxk1_dt = (-xk1 + xk1ss) / txk1 + values[13] = dxk1_dt + IK1 = (xk1 * (rk1 * (GK1 * math.sqrt(ko)))) * (-EK + v) + IKs = (xs2 * (xs1 * (GKs * KsCa))) * (-EKs + v) + anca = 1.0 / (k2n / km2n + (Kmn / cass + 1.0) ** 4.0) + a1 = (k1p * (nai / Knai) ** 3.0) / ( + ((1.0 + ki / Kki) ** 2.0 + (1.0 + nai / Knai) ** 3.0) - 1.0 + ) + b4 = (k4m * (ki / Kki) ** 2.0) / ( + ((1.0 + ki / Kki) ** 2.0 + (1.0 + nai / Knai) ** 3.0) - 1.0 + ) + a3 = (k3p * (ko / Kko) ** 2.0) / ( + ((1.0 + ko / Kko) ** 2.0 + (1.0 + nao / Knao) ** 3.0) - 1.0 + ) + b2 = (k2m * (nao / Knao) ** 3.0) / ( + ((1.0 + ko / Kko) ** 2.0 + (1.0 + nao / Knao) ** 3.0) - 1.0 + ) + b3 = (H * (P * k3m)) / (1.0 + MgATP / Kmgatp) + PCaK = 0.0003574 * PCa + PCaNa = 0.00125 * PCa + PCap = 1.1 * PCa + a_relp = 0.5 * btp + tau_relp_tmp = btp / (1.0 + 0.0123 / cajsr) + tau_rel = (0.001) * (tau_rel_tmp < 0.001) + (tau_rel_tmp) * numpy.logical_not( + (tau_rel_tmp < 0.001), + ) + dZetaw_dt = Aw * dLambda - Zetaw * cw + values[14] = dZetaw_dt + dXS_dt = -XS * gammasu + (-XS * ksu + XW * kws) + values[15] = dXS_dt + dXW_dt = -XW * gammawu + (-XW * kws + (XU * kuw - XW * kwu)) + values[16] = dXW_dt + h11 = (nao * nao) / ((kna2 * (h10 * kna1))) + h12 = 1.0 / h10 + h11_i = (nao * nao) / ((kna2 * (h10_i * kna1))) + h12_i = 1.0 / h10_i + h5 = (nass * nass) / ((kna2 * (h4 * kna1))) + h6 = 1.0 / h4 + h5_i = (nai * nai) / ((kna2 * (h4_i * kna1))) + h6_i = 1.0 / h4_i + h1 = (nass / kna3) * (hna + 1) + 1 + h1_i = (nai / kna3) * (hna + 1) + 1 + h7 = (nao / kna3) * (1.0 + 1.0 / hna) + 1.0 + h7_i = (nao / kna3) * (1.0 + 1.0 / hna) + 1.0 + dTmB_dt = -TmB * CaTrpn ** (ntm / 2) * ku + XU * ( + kb * CaTrpn ** ((-ntm) / 2) * (CaTrpn ** ((-ntm) / 2) < 100) + + 100 * (~(CaTrpn ** ((-ntm) / 2) < 100)) + ) + if numpy.isnan(dTmB_dt): + dTmB_dt = 0 + values[17] = dTmB_dt + C = lambda_min12 - 1 + cat50 = scale_HF_cat50_ref * (Beta1 * (lambda_min12 - 1) + cat50_ref) + lambda_min087 = (lambda_min12) * (lambda_min12 < 0.87) + (0.87) * numpy.logical_not( + (lambda_min12 < 0.87), + ) + dhLp_dt = (-hLp + hLssp) / thLp + values[18] = dhLp_dt + tiFp = tiF * (dti_develop * dti_recover) + diF_dt = (-iF + iss) / tiF + values[19] = diF_dt + tiSp = tiS * (dti_develop * dti_recover) + diS_dt = (-iS + iss) / tiS + values[20] = diS_dt + fca = Afcaf * fcaf + Afcas * fcas + fcap = Afcaf * fcafp + Afcas * fcas + i = AiF * iF + AiS * iS + ip = AiF * iFp + AiS * iSp + xr = Axrf * xrf + Axrs * xrs + dfcaf_dt = (-fcaf + fcass) / tfcaf + values[21] = dfcaf_dt + dfcas_dt = (-fcas + fcass) / tfcas + values[22] = dfcas_dt + djca_dt = (fcass - jca) / tjca + values[23] = djca_dt + dj_dt = (-j + jss) / tj + values[24] = dj_dt + dfcafp_dt = (-fcafp + fcass) / tfcafp + values[25] = dfcafp_dt + dffp_dt = (-ffp + fss) / tffp + values[26] = dffp_dt + dhsp_dt = (-hsp + hssp) / thsp + values[27] = dhsp_dt + djp_dt = (-jp + jss) / tjp + values[28] = djp_dt + dmL_dt = (-mL + mLss) / tmL + values[29] = dmL_dt + dxs2_dt = (-xs2 + xs2ss) / txs2 + values[30] = dxs2_dt + dZetas_dt = As * dLambda - Zetas * cs + values[31] = dZetas_dt + fICaLp = 1.0 / (1.0 + KmCaMK / CaMKa) + fINaLp = 1.0 / (1.0 + KmCaMK / CaMKa) + fINap = 1.0 / (1.0 + KmCaMK / CaMKa) + fItop = 1.0 / (1.0 + KmCaMK / CaMKa) + fJrelp = 1.0 / (1.0 + KmCaMK / CaMKa) + fJupp = 1.0 / (1.0 + KmCaMK / CaMKa) + dnca_dt = anca * k2n - km2n * nca + values[32] = dnca_dt + x2 = b4 * (a2 * a3) + (b4 * (a3 * b1) + (a3 * (a1 * a2) + b4 * (b1 * b2))) + x1 = a2 * (a1 * b3) + (b3 * (a2 * b4) + (a2 * (a1 * a4) + b3 * (b2 * b4))) + x3 = b1 * (a3 * a4) + (a4 * (b1 * b2) + (a4 * (a2 * a3) + b1 * (b2 * b3))) + x4 = a1 * (b2 * b3) + (a1 * (a4 * b2) + (a1 * (a3 * a4) + b2 * (b3 * b4))) + PCaKp = 0.0003574 * PCap + PCaNap = 0.00125 * PCap + tau_relp = (0.001) * (tau_relp_tmp < 0.001) + (tau_relp_tmp) * numpy.logical_not( + (tau_relp_tmp < 0.001), + ) + k1 = kcaon * (cao * h12) + k1_i = kcaon * (cao * h12_i) + k6 = kcaon * (cass * h6) + k6_i = kcaon * (cai * h6_i) + h2 = (hna * nass) / ((h1 * kna3)) + h3 = 1.0 / h1 + h2_i = (hna * nai) / ((h1_i * kna3)) + h3_i = 1.0 / h1_i + h8 = nao / ((h7 * (hna * kna3))) + h9 = 1.0 / h7 + h8_i = nao / ((h7_i * (hna * kna3))) + h9_i = 1.0 / h7_i + F1 = numpy.exp(C * p_b) - 1 + dCd = C - Cd + dCaTrpn_dt = ktrpn * (-CaTrpn + ((1000 * cai) / cat50) ** ntrpn * (1 - CaTrpn)) + values[33] = dCaTrpn_dt + h_lambda_prima = Beta0 * ((lambda_min087 + lambda_min12) - 1.87) + 1 + diFp_dt = (-iFp + iss) / tiFp + values[34] = diFp_dt + diSp_dt = (-iSp + iss) / tiSp + values[35] = diSp_dt + IKr = (rkr * (xr * (GKr * (0.4303314829119352 * math.sqrt(ko))))) * (-EK + v) + ICaL = (d * (PhiCaL * (PCa * (1.0 - fICaLp)))) * ( + f * (1.0 - nca) + nca * (fca * jca) + ) + (d * (PhiCaL * (PCap * fICaLp))) * (fp * (1.0 - nca) + nca * (fcap * jca)) + INaL = (mL * (GNaL * (-ENa + v))) * (fINaLp * hLp + hL * (1.0 - fINaLp)) + INa = (m**3.0 * ((GNa * scale_drug_INa) * (-ENa + v))) * ( + j * (h * (1.0 - fINap)) + jp * (fINap * hp) + ) + Ito = ((scale_HF_Gto * (Gto * scale_drug_Ito)) * (-EK + v)) * ( + i * (a * (1.0 - fItop)) + ip * (ap * fItop) + ) + Jrel = Jrelnp * (1.0 - fJrelp) + Jrelp * fJrelp + Jup = -Jleak + (Jupnp * (1.0 - fJupp) + scale_HF_Jup * (Jupp * fJupp)) + E1 = x1 / (x4 + (x3 + (x1 + x2))) + E2 = x2 / (x4 + (x3 + (x1 + x2))) + E3 = x3 / (x4 + (x3 + (x1 + x2))) + E4 = x4 / (x4 + (x3 + (x1 + x2))) + ICaK = (d * (PhiCaK * (PCaK * (1.0 - fICaLp)))) * ( + f * (1.0 - nca) + nca * (fca * jca) + ) + (d * (PhiCaK * (PCaKp * fICaLp))) * (fp * (1.0 - nca) + nca * (fcap * jca)) + ICaNa = (d * (PhiCaNa * (PCaNa * (1.0 - fICaLp)))) * ( + f * (1.0 - nca) + nca * (fca * jca) + ) + (d * (PhiCaNa * (PCaNap * fICaLp))) * (fp * (1.0 - nca) + nca * (fcap * jca)) + k4pp = h2 * wnaca + k7 = wna * (h2 * h5) + k4p_ss = (h3 * wca) / hca + k4pp_i = h2_i * wnaca + k7_i = wna * (h2_i * h5_i) + k4p_i = (h3_i * wca) / hca + k3pp = h8 * wnaca + k8 = wna * (h11 * h8) + k3p_ss = h9 * wca + k3pp_i = h8_i * wnaca + k8_i = wna * (h11_i * h8_i) + k3p_i = h9_i * wca + eta = (etas) * (dCd < 0) + (etal) * numpy.logical_not((dCd < 0)) + J_TRPN = dCaTrpn_dt * trpnmax + h_lambda = (h_lambda_prima) * (h_lambda_prima > 0) + (0) * numpy.logical_not( + (h_lambda_prima > 0), + ) + Jrel_inf = ((-ICaL) * a_rel) / (((1.5 * scale_HF_Jrel_inf) / cajsr) ** 8.0 + 1.0) + Jrel_infp = ((-ICaL) * a_relp) / (((1.5 * scale_HF_Jrel_inf) / cajsr) ** 8.0 + 1.0) + dcajsr_dt = Bcajsr * (-Jrel + Jtr) + values[36] = dcajsr_dt + dcansr_dt = Jup - (Jtr * vjsr) / vnsr + values[37] = dcansr_dt + JnakNa = 3.0 * (E1 * a3 - E2 * b3) + JnakK = 2.0 * (-E3 * a1 + E4 * b1) + dkss_dt = -JdiffK + (Acap * (-ICaK)) / ((F * vss)) + values[38] = dkss_dt + k4 = k4p_ss + k4pp + k4_i = k4p_i + k4pp_i + k3 = k3p_ss + k3pp + k3_i = k3p_i + k3pp_i + Fd = dCd * eta + dCd_dt = (p_k * (C - Cd)) / eta + values[39] = dCd_dt + Ta = (h_lambda * (Tref / rs)) * (XS * (Zetas + 1) + XW * Zetaw) + dJrelnp_dt = (Jrel_inf - Jrelnp) / tau_rel + values[40] = dJrelnp_dt + dJrelp_dt = (Jrel_infp - Jrelp) / tau_relp + values[41] = dJrelp_dt + INaK = (Pnak * scale_HF_Pnak) * (JnakK * zk + JnakNa * zna) + x2_ss = (k1 * k7) * (k4 + k5) + (k4 * k6) * (k1 + k8) + x2_i = (k1_i * k7_i) * (k4_i + k5_i) + (k4_i * k6_i) * (k1_i + k8_i) + x1_ss = (k2 * k4) * (k6 + k7) + (k5 * k7) * (k2 + k3) + x3_ss = (k1 * k3) * (k6 + k7) + (k6 * k8) * (k2 + k3) + x4_ss = (k2 * k8) * (k4 + k5) + (k3 * k5) * (k1 + k8) + x1_i = (k2_i * k4_i) * (k6_i + k7_i) + (k5_i * k7_i) * (k2_i + k3_i) + x3_i = (k1_i * k3_i) * (k6_i + k7_i) + (k6_i * k8_i) * (k2_i + k3_i) + x4_i = (k2_i * k8_i) * (k4_i + k5_i) + (k3_i * k5_i) * (k1_i + k8_i) + Tp = p_a * (F1 + Fd) + dki_dt = ( + Acap + * ( + -( + -2.0 * INaK + + ( + Istim + + (Isac_P_ns / 3 + (Isac_P_k + (IKb + (IK1 + (IKs + (IKr + Ito)))))) + ) + ) ) - - # Expressions for the ICab component - ICab = ( - 4.0 - * PCab - * scale_drug_ICab - * scale_popu_GbCa - * (-0.341 * cao + cai * ufl.exp(2.0 * vfrt)) - * vffrt - / (-1.0 + ufl.exp(2.0 * vfrt)) + ) / ((F * vmyo)) + (JdiffK * vss) / vmyo + values[42] = dki_dt + E1_ss = x1_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) + E2_ss = x2_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) + E3_ss = x3_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) + E4_ss = x4_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) + E1_i = x1_i / (x4_i + (x3_i + (x1_i + x2_i))) + E2_i = x2_i / (x4_i + (x3_i + (x1_i + x2_i))) + E3_i = x3_i / (x4_i + (x3_i + (x1_i + x2_i))) + E4_i = x4_i / (x4_i + (x3_i + (x1_i + x2_i))) + Ttot = Ta + Tp + JncxCa_ss = -E1_ss * k1 + E2_ss * k2 + JncxNa_ss = -E2_ss * k3pp + (E3_ss * k4pp + 3.0 * (-E1_ss * k8 + E4_ss * k7)) + JncxCa_i = -E1_i * k1_i + E2_i * k2_i + JncxNa_i = -E2_i * k3pp_i + (E3_i * k4pp_i + 3.0 * (-E1_i * k8_i + E4_i * k7_i)) + INaCa_ss = (allo_ss * ((0.2 * Gncx) * scale_HF_Gncx)) * ( + JncxCa_ss * zca + JncxNa_ss * zna + ) + INaCa_i = (allo_i * ((0.8 * Gncx) * scale_HF_Gncx)) * ( + JncxCa_i * zca + JncxNa_i * zna + ) + dcass_dt = Bcass * ( + -Jdiff + + ( + (Acap * (-(ICaL - 2.0 * INaCa_ss))) / (((2.0 * F) * vss)) + + (Jrel * vjsr) / vss ) - - # Expressions for the IpCa component - IpCa = GpCa * scale_drug_IpCa * scale_popu_KpCa * cai / (0.0005 + cai) - - # Expressions for the Isac (Pueyo)--> ns + k component - Gsac_ns = 0.006 * scale_drug_Isacns - Esac_ns = -10.0 - lambda_max = 1.1 - Gsac_k = (0.2882 * 800.0 / 210.0) * scale_drug_Isack # Pueyo endo - - Isac_P_ns = ufl.conditional( - ufl.lt(lmbda, 1.0), - 0.0, - Gsac_ns * ((lmbda - 1.0) / (lambda_max - 1.0)) * (v - Esac_ns), + ) + values[43] = dcass_dt + dnass_dt = -JdiffNa + (Acap * (-(ICaNa + 3.0 * INaCa_ss))) / ((F * vss)) + values[44] = dnass_dt + dcai_dt = Bcai * ( + -J_TRPN + + ( + ( + (Acap * (-(Isac_P_ns / 3 + (-2.0 * INaCa_i + (ICab + IpCa))))) + / (((2.0 * F) * vmyo)) + - (Jup * vnsr) / vmyo + ) + + (Jdiff * vss) / vmyo ) - Isac_P_k = ufl.conditional( - ufl.lt(lmbda, 1.0), - 0.0, - Gsac_k - * ((lmbda - 1.0) / (lambda_max - 1.0)) - * (1.0 / (1.0 + ufl.exp((19.05 - v) / (29.98)))), + ) + values[45] = dcai_dt + dnai_dt = ( + Acap + * (-(Isac_P_ns / 3 + (INab + (3.0 * INaK + (3.0 * INaCa_i + (INa + INaL)))))) + ) / ((F * vmyo)) + (JdiffNa * vss) / vmyo + values[46] = dnai_dt + dv_dt = -( + Isac_P_k + + ( + Isac_P_ns + + ( + Istim + + ( + ICab + + ( + IpCa + + ( + IKb + + ( + INab + + ( + INaK + + ( + INaCa_ss + + ( + INaCa_i + + ( + IK1 + + ( + IKs + + ( + IKr + + ( + ICaK + + ( + ICaNa + + ( + ICaL + + ( + Ito + + (INa + INaL) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) ) + ) + values[47] = dv_dt - # Expressions for the Istim component - Istim = 0 # amp*(ufl.le(time, duration)) - - # Expressions for the membrane potential component - current[0] = ( - -Isac_P_k - - Isac_P_ns - - ICaK - - ICaL - - ICaNa - - ICab - - IK1 - - IKb - - IKr - - IKs - - INa - - INaCa_i - - INaCa_ss - - INaK - - INaL - - INab - - IpCa - - Istim - - Ito - ) + return values - # Return results - return current[0] - - def I(self, v, s, time=None): # noqa: E741, E743 - """ - Transmembrane current - - I = -dV/dt - - """ - return -self._I(v, s, time) - - def F(self, v, s, time=None): - """ - Right hand side for ODE system - """ - logger.debug("Evaluate RHS") - time = time if time else Constant(0.0) - - # Assign states - assert len(s) == 47 - ( - CaMKt, - m, - hf, - hs, - j, - hsp, - jp, - mL, - hL, - hLp, - a, - iF, - iS, - ap, - iFp, - iSp, - d, - ff, - fs, - fcaf, - fcas, - jca, - ffp, - fcafp, - nca, - xrf, - xrs, - xs1, - xs2, - xk1, - Jrelnp, - Jrelp, - nai, - nass, - ki, - kss, - cass, - cansr, - cajsr, - XS, - XW, - CaTrpn, - TmB, - Cd, - cai, - Zetas, - Zetaw, - ) = s - - # Assign parameters - scale_ICaL = self._parameters["scale_ICaL"] - scale_IK1 = self._parameters["scale_IK1"] - scale_IKr = self._parameters["scale_IKr"] - scale_IKs = self._parameters["scale_IKs"] - scale_INaL = self._parameters["scale_INaL"] - cao = self._parameters["cao"] - ko = self._parameters["ko"] - nao = self._parameters["nao"] - F = self._parameters["F"] - R = self._parameters["R"] - T = self._parameters["T"] - L = self._parameters["L"] - rad = self._parameters["rad"] - CaMKo = self._parameters["CaMKo"] - KmCaM = self._parameters["KmCaM"] - KmCaMK = self._parameters["KmCaMK"] - aCaMK = self._parameters["aCaMK"] - bCaMK = self._parameters["bCaMK"] - PKNa = self._parameters["PKNa"] - Ahf = self._parameters["Ahf"] - GNa = self._parameters["GNa"] - thL = self._parameters["thL"] - Gto = self._parameters["Gto"] - delta_epi = self._parameters["delta_epi"] - Aff = self._parameters["Aff"] - Kmn = self._parameters["Kmn"] - k2n = self._parameters["k2n"] - tjca = self._parameters["tjca"] - zca = self._parameters["zca"] - Gncx = self._parameters["Gncx"] - KmCaAct = self._parameters["KmCaAct"] - kasymm = self._parameters["kasymm"] - kcaoff = self._parameters["kcaoff"] - kcaon = self._parameters["kcaon"] - kna1 = self._parameters["kna1"] - kna2 = self._parameters["kna2"] - kna3 = self._parameters["kna3"] - qca = self._parameters["qca"] - qna = self._parameters["qna"] - wca = self._parameters["wca"] - wna = self._parameters["wna"] - wnaca = self._parameters["wnaca"] - H = self._parameters["H"] - Khp = self._parameters["Khp"] - Kki = self._parameters["Kki"] - Kko = self._parameters["Kko"] - Kmgatp = self._parameters["Kmgatp"] - Knai0 = self._parameters["Knai0"] - Knao0 = self._parameters["Knao0"] - Knap = self._parameters["Knap"] - Kxkur = self._parameters["Kxkur"] - MgADP = self._parameters["MgADP"] - MgATP = self._parameters["MgATP"] - Pnak = self._parameters["Pnak"] - delta = self._parameters["delta"] - eP = self._parameters["eP"] - k1m = self._parameters["k1m"] - k1p = self._parameters["k1p"] - k2m = self._parameters["k2m"] - k2p = self._parameters["k2p"] - k3m = self._parameters["k3m"] - k3p = self._parameters["k3p"] - k4m = self._parameters["k4m"] - k4p = self._parameters["k4p"] - zk = self._parameters["zk"] - GKb = self._parameters["GKb"] - PNab = self._parameters["PNab"] - PCab = self._parameters["PCab"] - GpCa = self._parameters["GpCa"] - bt = self._parameters["bt"] - BSLmax = self._parameters["BSLmax"] - BSRmax = self._parameters["BSRmax"] - KmBSL = self._parameters["KmBSL"] - KmBSR = self._parameters["KmBSR"] - cmdnmax = self._parameters["cmdnmax"] - csqnmax = self._parameters["csqnmax"] - kmcmdn = self._parameters["kmcmdn"] - kmcsqn = self._parameters["kmcsqn"] - trpnmax = self._parameters["trpnmax"] - Beta1 = self._parameters["Beta1"] - Tot_A = self._parameters["Tot_A"] - Trpn50 = self._parameters["Trpn50"] - cat50_ref = self._parameters["cat50_ref"] - dLambda = self._parameters["dLambda"] - etal = self._parameters["etal"] - etas = self._parameters["etas"] - gammas = self._parameters["gammas"] - gammaw = self._parameters["gammaw"] - ktrpn = self._parameters["ktrpn"] - ku = self._parameters["ku"] - kuw = self._parameters["kuw"] - kws = self._parameters["kws"] - lmbda = self._parameters["lmbda"] - ntm = self._parameters["ntm"] - ntrpn = self._parameters["ntrpn"] - p_k = self._parameters["p_k"] - phi = self._parameters["phi"] - rs = self._parameters["rs"] - rw = self._parameters["rw"] - - # Drug factor - scale_drug_INa = self._parameters["scale_drug_INa"] - scale_drug_INaL = self._parameters["scale_drug_INaL"] - scale_drug_Ito = self._parameters["scale_drug_Ito"] - scale_drug_ICaL = self._parameters["scale_drug_ICaL"] - scale_drug_IKr = self._parameters["scale_drug_IKr"] - scale_drug_IKs = self._parameters["scale_drug_IKs"] - scale_drug_IK1 = self._parameters["scale_drug_IK1"] - scale_drug_IKb = self._parameters["scale_drug_IKb"] - scale_drug_INab = self._parameters["scale_drug_INab"] - scale_drug_ICab = self._parameters["scale_drug_ICab"] - scale_drug_IpCa = self._parameters["scale_drug_IpCa"] - scale_drug_Isacns = self._parameters["scale_drug_Isacns"] - scale_drug_Isack = self._parameters["scale_drug_Isack"] - - # Population factors - scale_popu_GNa = self._parameters["scale_popu_GNa"] - scale_popu_GCaL = self._parameters["scale_popu_GCaL"] - scale_popu_Gto = self._parameters["scale_popu_Gto"] - scale_popu_GNaL = self._parameters["scale_popu_GNaL"] - scale_popu_GKr = self._parameters["scale_popu_GKr"] - scale_popu_GKs = self._parameters["scale_popu_GKs"] - scale_popu_GK1 = self._parameters["scale_popu_GK1"] - scale_popu_GbK = self._parameters["scale_popu_GbK"] - scale_popu_KNCX = self._parameters["scale_popu_KNCX"] - scale_popu_KNaK = self._parameters["scale_popu_KNaK"] - scale_popu_GbNa = self._parameters["scale_popu_GbNa"] - scale_popu_GbCa = self._parameters["scale_popu_GbCa"] - scale_popu_KpCa = self._parameters["scale_popu_KpCa"] - scale_popu_KRyR = self._parameters["scale_popu_KRyR"] - scale_popu_KSERCA = self._parameters["scale_popu_KSERCA"] - scale_popu_Kleak = self._parameters["scale_popu_Kleak"] - scale_popu_nTm = self._parameters["scale_popu_nTm"] - scale_popu_CaT50ref = self._parameters["scale_popu_CaT50ref"] - scale_popu_kuw = self._parameters["scale_popu_kuw"] - scale_popu_kws = self._parameters["scale_popu_kws"] - scale_popu_kTRPN = self._parameters["scale_popu_kTRPN"] - scale_popu_nTRPN = self._parameters["scale_popu_nTRPN"] - scale_popu_ku = self._parameters["scale_popu_ku"] - scale_popu_TRPN50 = self._parameters["scale_popu_TRPN50"] - scale_popu_rw = self._parameters["scale_popu_rw"] - scale_popu_rs = self._parameters["scale_popu_rs"] - - # Systolic Heart Failure (HF with preserved ejection fraction) - HF_scaling_CaMKa = self._parameters["HF_scaling_CaMKa"] - HF_scaling_Jrel_inf = self._parameters["HF_scaling_Jrel_inf"] - HF_scaling_Jleak = self._parameters["HF_scaling_Jleak"] - HF_scaling_Jup = self._parameters["HF_scaling_Jup"] - HF_scaling_GNaL = self._parameters["HF_scaling_GNaL"] - HF_scaling_GK1 = self._parameters["HF_scaling_GK1"] - HF_scaling_thL = self._parameters["HF_scaling_thL"] - HF_scaling_Gto = self._parameters["HF_scaling_Gto"] - HF_scaling_Gncx = self._parameters["HF_scaling_Gncx"] - HF_scaling_Pnak = self._parameters["HF_scaling_Pnak"] - HF_scaling_cat50_ref = self._parameters["HF_scaling_cat50_ref"] - - # Init return args - F_expressions = [dolfin.Constant(0.0)] * 47 - - # Expressions for the cell geometry component - vcell = 3140.0 * L * (rad * rad) - Ageo = 6.28 * (rad * rad) + 6.28 * L * rad - Acap = 2 * Ageo - vmyo = 0.68 * vcell - vnsr = 0.0552 * vcell - vjsr = 0.0048 * vcell - vss = 0.02 * vcell - - # Expressions for the CaMKt component - CaMKb = CaMKo * (1.0 - CaMKt) / (1.0 + KmCaM / cass) - CaMKa = (CaMKb + CaMKt) * HF_scaling_CaMKa - F_expressions[0] = -bCaMK * CaMKt + aCaMK * (CaMKb + CaMKt) * CaMKb - - # Expressions for the reversal potentials component - ENa = R * T * ufl.ln(nao / nai) / F - EK = R * T * ufl.ln(ko / ki) / F - EKs = R * T * ufl.ln((ko + PKNa * nao) / (PKNa * nai + ki)) / F - vffrt = (F * F) * v / (R * T) - vfrt = F * v / (R * T) - - # Expressions for the I_Na component - mss = 1.0 / (1.0 + 0.0014599788446489682 * ufl.exp(-0.13333333333333333 * v)) - tm = 1.0 / ( - 9.454904638564724 * ufl.exp(0.02876042565429968 * v) - + 1.9314113558536928e-05 * ufl.exp(-0.16792611251049538 * v) - ) - F_expressions[1] = (-m + mss) / tm - hss = 1.0 / (1 + 302724.605401998 * ufl.exp(0.1607717041800643 * v)) - thf = 1.0 / ( - 1.183856958289087e-05 * ufl.exp(-0.15910898965791567 * v) - + 6.305549185817275 * ufl.exp(0.0493339911198816 * v) - ) - ths = 1.0 / ( - 0.005164670235381792 * ufl.exp(-0.035650623885918005 * v) - + 0.36987619372096325 * ufl.exp(0.017649135192375574 * v) - ) - Ahs = 1.0 - Ahf - F_expressions[2] = (-hf + hss) / thf - F_expressions[3] = (-hs + hss) / ths - h = Ahf * hf + Ahs * hs - jss = hss - tj = 2.038 + 1.0 / ( - 0.3131936394738773 * ufl.exp(0.02600780234070221 * v) - + 1.1315282095590072e-07 * ufl.exp(-0.12075836251660427 * v) - ) - F_expressions[4] = (-j + jss) / tj - hssp = 1.0 / (1 + 820249.0921708513 * ufl.exp(0.1607717041800643 * v)) - thsp = 3.0 * ths - F_expressions[5] = (-hsp + hssp) / thsp - hp = Ahf * hf + Ahs * hsp - tjp = 1.46 * tj - F_expressions[6] = (-jp + jss) / tjp - fINap = 1.0 / (1.0 + KmCaMK / CaMKa) - INa = ( - GNa - * scale_drug_INa - * scale_popu_GNa - * ufl.elem_pow(m, 3.0) - * (-ENa + v) - * ((1.0 - fINap) * h * j + fINap * hp * jp) - ) - # Expressions for the INaL component - mLss = 1.0 / (1.0 + 0.000291579585635531 * ufl.exp(-0.18996960486322187 * v)) - tmL = tm - F_expressions[7] = (-mL + mLss) / tmL - hLss = 1.0 / (1.0 + 120578.15595522427 * ufl.exp(0.13354700854700854 * v)) - F_expressions[8] = (-hL + hLss) / (thL * HF_scaling_thL) - hLssp = 1.0 / (1.0 + 275969.2903869871 * ufl.exp(0.13354700854700854 * v)) - thLp = 3.0 * thL * HF_scaling_thL - F_expressions[9] = (-hLp + hLssp) / thLp - GNaL = 0.0075 * scale_INaL * scale_drug_INaL * scale_popu_GNaL * HF_scaling_GNaL - fINaLp = 1.0 / (1.0 + KmCaMK / CaMKa) - INaL = (-ENa + v) * ((1.0 - fINaLp) * hL + fINaLp * hLp) * GNaL * mL - - # Expressions for the Ito component - ass = 1.0 / (1.0 + 2.6316508161673635 * ufl.exp(-0.06747638326585695 * v)) - ta = 1.0515 / ( - 1.0 / (1.2089 + 2.2621017070578837 * ufl.exp(-0.03403513787634354 * v)) - + 3.5 / (1.0 + 30.069572727397507 * ufl.exp(0.03403513787634354 * v)) - ) - F_expressions[10] = (-a + ass) / ta - iss = 1.0 / (1.0 + 2194.970764538301 * ufl.exp(0.17510068289266328 * v)) - tiF = 4.562 + delta_epi / ( - 0.14468698421272827 * ufl.exp(-0.01 * v) - + 1.6300896349780942 * ufl.exp(0.06027727546714889 * v) - ) - tiS = 23.62 + delta_epi / ( - 0.00027617763953377436 * ufl.exp(-0.01693480101608806 * v) - + 0.024208962804604526 * ufl.exp(0.12377769525931426 * v) - ) - AiF = 1.0 / (1.0 + 0.24348537187522867 * ufl.exp(0.006613756613756614 * v)) - AiS = 1.0 - AiF - F_expressions[11] = (-iF + iss) / tiF - F_expressions[12] = (-iS + iss) / tiS - i = AiF * iF + AiS * iS - assp = 1.0 / (1.0 + 5.167428462230666 * ufl.exp(-0.06747638326585695 * v)) - F_expressions[13] = (-ap + assp) / ta - dti_develop = 1.354 + 0.0001 / ( - 2.6591269045230603e-05 * ufl.exp(0.06293266205160478 * v) - + 4.5541779737128264e24 * ufl.exp(-4.642525533890436 * v) - ) - dti_recover = 1.0 - 0.5 / (1.0 + 33.11545195869231 * ufl.exp(0.05 * v)) - tiFp = dti_develop * dti_recover * tiF - tiSp = dti_develop * dti_recover * tiS - F_expressions[14] = (-iFp + iss) / tiFp - F_expressions[15] = (-iSp + iss) / tiSp - ip = AiF * iFp + AiS * iSp - fItop = 1.0 / (1.0 + KmCaMK / CaMKa) - Ito = ( - Gto - * scale_drug_Ito - * scale_popu_Gto - * HF_scaling_Gto - * (-EK + v) - * ((1.0 - fItop) * a * i + ap * fItop * ip) - ) +def forward_generalized_rush_larsen(states, t, dt, parameters): + # Assign states + hL = states[0] + a = states[1] + ap = states[2] + d = states[3] + ff = states[4] + fs = states[5] + hf = states[6] + hs = states[7] + m = states[8] + xrf = states[9] + xrs = states[10] + xs1 = states[11] + CaMKt = states[12] + xk1 = states[13] + Zetaw = states[14] + XS = states[15] + XW = states[16] + TmB = states[17] + hLp = states[18] + iF = states[19] + iS = states[20] + fcaf = states[21] + fcas = states[22] + jca = states[23] + j = states[24] + fcafp = states[25] + ffp = states[26] + hsp = states[27] + jp = states[28] + mL = states[29] + xs2 = states[30] + Zetas = states[31] + nca = states[32] + CaTrpn = states[33] + iFp = states[34] + iSp = states[35] + cajsr = states[36] + cansr = states[37] + kss = states[38] + Cd = states[39] + Jrelnp = states[40] + Jrelp = states[41] + ki = states[42] + cass = states[43] + nass = states[44] + cai = states[45] + nai = states[46] + v = states[47] - # Expressions for the ICaL ICaNa ICaK component - dss = 1.0 / (1.0 + 0.39398514226669484 * ufl.exp(-0.23640661938534277 * v)) - td = 0.6 + 1.0 / ( - 3.5254214873653824 * ufl.exp(0.09 * v) - + 0.7408182206817179 * ufl.exp(-0.05 * v) - ) - F_expressions[16] = (-d + dss) / td - fss = 1.0 / (1.0 + 199.86038496778565 * ufl.exp(0.27056277056277056 * v)) - tff = 7.0 + 1.0 / ( - 0.03325075244518792 * ufl.exp(0.1 * v) - + 0.0006090087745647571 * ufl.exp(-0.1 * v) - ) - tfs = 1000.0 + 1.0 / ( - 1.0027667890106652e-05 * ufl.exp(-0.25 * v) - + 8.053415618124885e-05 * ufl.exp(0.16666666666666666 * v) - ) - Afs = 1.0 - Aff - F_expressions[17] = (-ff + fss) / tff - F_expressions[18] = (-fs + fss) / tfs - f = Aff * ff + Afs * fs - fcass = fss - tfcaf = 7.0 + 1.0 / ( - 0.0708317980974062 * ufl.exp(-0.14285714285714285 * v) - + 0.02258872488031037 * ufl.exp(0.14285714285714285 * v) - ) - tfcas = 100.0 + 1.0 / ( - 0.00012 * ufl.exp(0.14285714285714285 * v) - + 0.00012 * ufl.exp(-0.3333333333333333 * v) - ) - Afcaf = 0.3 + 0.6 / (1.0 + 0.36787944117144233 * ufl.exp(0.1 * v)) - Afcas = 1.0 - Afcaf - F_expressions[19] = (-fcaf + fcass) / tfcaf - F_expressions[20] = (-fcas + fcass) / tfcas - fca = Afcaf * fcaf + Afcas * fcas - F_expressions[21] = (-jca + fcass) / tjca - tffp = 2.5 * tff - F_expressions[22] = (-ffp + fss) / tffp - fp = Aff * ffp + Afs * fs - tfcafp = 2.5 * tfcaf - F_expressions[23] = (-fcafp + fcass) / tfcafp - fcap = Afcaf * fcafp + Afcas * fcas - km2n = 1.0 * jca - anca = 1.0 / (ufl.elem_pow(1.0 + Kmn / cass, 4.0) + k2n / km2n) - F_expressions[24] = k2n * anca - km2n * nca - PhiCaL = ( - 4.0 - * (-0.341 * cao + cass * ufl.exp(2.0 * vfrt)) - * vffrt - / (-1.0 + ufl.exp(2.0 * vfrt)) - ) - PhiCaNa = ( - 1.0 - * (-0.75 * nao + 0.75 * ufl.exp(1.0 * vfrt) * nass) - * vffrt - / (-1.0 + ufl.exp(1.0 * vfrt)) - ) - PhiCaK = ( - 1.0 - * (-0.75 * ko + 0.75 * ufl.exp(1.0 * vfrt) * kss) - * vffrt - / (-1.0 + ufl.exp(1.0 * vfrt)) - ) - PCa = 0.0001 * scale_ICaL * scale_drug_ICaL * scale_popu_GCaL - PCap = 1.1 * PCa - PCaNa = 0.00125 * PCa - PCaK = 0.0003574 * PCa - PCaNap = 0.00125 * PCap - PCaKp = 0.0003574 * PCap - fICaLp = 1.0 / (1.0 + KmCaMK / CaMKa) - ICaL = (1.0 - fICaLp) * ( - (1.0 - nca) * f + fca * jca * nca - ) * PCa * PhiCaL * d + ( - (1.0 - nca) * fp + fcap * jca * nca - ) * PCap * PhiCaL * d * fICaLp - ICaNa = (1.0 - fICaLp) * ( - (1.0 - nca) * f + fca * jca * nca - ) * PCaNa * PhiCaNa * d + ( - (1.0 - nca) * fp + fcap * jca * nca - ) * PCaNap * PhiCaNa * d * fICaLp - ICaK = (1.0 - fICaLp) * ( - (1.0 - nca) * f + fca * jca * nca - ) * PCaK * PhiCaK * d + ( - (1.0 - nca) * fp + fcap * jca * nca - ) * PCaKp * PhiCaK * d * fICaLp - - # Expressions for the IKr component - xrss = 1.0 / (1.0 + 0.29287308872377504 * ufl.exp(-0.14729709824716453 * v)) - txrf = 12.98 + 1.0 / ( - 0.0001020239312894894 * ufl.exp(0.25846471956577927 * v) - + 0.00042992960891929087 * ufl.exp(-0.04906771344455348 * v) - ) - txrs = 1.865 + 1.0 / ( - 0.0005922420036809394 * ufl.exp(0.13596193065941536 * v) - + 3.549966111802463e-05 * ufl.exp(-0.03855050115651503 * v) - ) - Axrf = 1.0 / (1.0 + 4.197299094734718 * ufl.exp(0.02617115938236064 * v)) - Axrs = 1.0 - Axrf - F_expressions[25] = (-xrf + xrss) / txrf - F_expressions[26] = (-xrs + xrss) / txrs - xr = Axrf * xrf + Axrs * xrs - rkr = 1.0 / ( - (1.0 + 2.0820090840784555 * ufl.exp(0.013333333333333334 * v)) - * (1.0 + 0.7165313105737893 * ufl.exp(0.03333333333333333 * v)) - ) - GKr = 0.046 * scale_IKr * scale_drug_IKr * scale_popu_GKr - IKr = 0.4303314829119352 * ufl.sqrt(ko) * (-EK + v) * GKr * rkr * xr - - # Expressions for the IKs component - xs1ss = 1.0 / (1.0 + 0.27288596035656526 * ufl.exp(-0.11195700850873264 * v)) - txs1 = 817.3 + 1.0 / ( - 0.003504067763074858 * ufl.exp(0.056179775280898875 * v) - + 0.0005184809083581659 * ufl.exp(-0.004347826086956522 * v) - ) - F_expressions[27] = (-xs1 + xs1ss) / txs1 - xs2ss = xs1ss - txs2 = 1.0 / ( - 0.0022561357010639103 * ufl.exp(-0.03225806451612903 * v) - + 0.0008208499862389881 * ufl.exp(0.05 * v) - ) - F_expressions[28] = (-xs2 + xs2ss) / txs2 - KsCa = 1.0 + 0.6 / (1.0 + 6.481821026062645e-07 * ufl.elem_pow(1.0 / cai, 1.4)) - GKs = 0.0034 * scale_IKs * scale_drug_IKs * scale_popu_GKs - IKs = (-EKs + v) * GKs * KsCa * xs1 * xs2 - xk1ss = 1.0 / ( - 1.0 + ufl.exp((-144.59 - v - 2.5538 * ko) / (3.8115 + 1.5692 * ko)) - ) - txk1 = 122.2 / ( - 0.0019352007631390235 * ufl.exp(-0.049115913555992145 * v) - + 30.43364757524903 * ufl.exp(0.014423770373575654 * v) - ) - F_expressions[29] = (-xk1 + xk1ss) / txk1 - rk1 = 1.0 / ( - 1.0 - + 69220.6322106767 - * ufl.exp(0.10534077741493732 * v - 0.27388602127883704 * ko) - ) - GK1 = 0.1908 * scale_IK1 * scale_drug_IK1 * scale_popu_GK1 * HF_scaling_GK1 - IK1 = ufl.sqrt(ko) * (-EK + v) * GK1 * rk1 * xk1 - - # Expressions for the INaCa_i component - hca = ufl.exp(F * qca * v / (R * T)) - hna = ufl.exp(F * qna * v / (R * T)) - h1_i = 1.0 + (1.0 + hna) * nai / kna3 - h2_i = hna * nai / (kna3 * h1_i) - h3_i = 1.0 / h1_i - h4_i = 1.0 + (1 + nai / kna2) * nai / kna1 - h5_i = (nai * nai) / (kna1 * kna2 * h4_i) - h6_i = 1.0 / h4_i - h7_i = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 - h8_i = nao / (kna3 * h7_i * hna) - h9_i = 1.0 / h7_i - h10_i = 1.0 + kasymm + nao * (1.0 + nao / kna2) / kna1 - h11_i = (nao * nao) / (kna1 * kna2 * h10_i) - h12_i = 1.0 / h10_i - k1_i = cao * kcaon * h12_i - k2_i = kcaoff - k3p_i = wca * h9_i - k3pp_i = wnaca * h8_i - k3_i = k3p_i + k3pp_i - k4p_i = wca * h3_i / hca - k4pp_i = wnaca * h2_i - k4_i = k4p_i + k4pp_i - k5_i = kcaoff - k6_i = kcaon * cai * h6_i - k7_i = wna * h2_i * h5_i - k8_i = wna * h11_i * h8_i - x1_i = (k2_i + k3_i) * k5_i * k7_i + (k6_i + k7_i) * k2_i * k4_i - x2_i = (k1_i + k8_i) * k4_i * k6_i + (k4_i + k5_i) * k1_i * k7_i - x3_i = (k2_i + k3_i) * k6_i * k8_i + (k6_i + k7_i) * k1_i * k3_i - x4_i = (k1_i + k8_i) * k3_i * k5_i + (k4_i + k5_i) * k2_i * k8_i - E1_i = x1_i / (x1_i + x2_i + x3_i + x4_i) - E2_i = x2_i / (x1_i + x2_i + x3_i + x4_i) - E3_i = x3_i / (x1_i + x2_i + x3_i + x4_i) - E4_i = x4_i / (x1_i + x2_i + x3_i + x4_i) - allo_i = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cai, 2.0)) - zna = 1.0 - JncxNa_i = E3_i * k4pp_i - E2_i * k3pp_i + 3.0 * E4_i * k7_i - 3.0 * E1_i * k8_i - JncxCa_i = E2_i * k2_i - E1_i * k1_i - INaCa_i = ( - 0.8 - * Gncx - * scale_popu_KNCX - * HF_scaling_Gncx - * (zca * JncxCa_i + zna * JncxNa_i) - * allo_i - ) + # Assign parameters + Aff = parameters[0] + Ahf = parameters[1] + BSLmax = parameters[2] + BSRmax = parameters[3] + Beta0 = parameters[4] + Beta1 = parameters[5] + CaMKo = parameters[6] + Esac_ns = parameters[7] + F = parameters[8] + GKb = parameters[9] + GNa = parameters[10] + Gncx = parameters[11] + GpCa = parameters[12] + Gsac_k = parameters[13] + Gsac_ns = parameters[14] + Gto = parameters[15] + H = parameters[16] + Khp = parameters[17] + Kki = parameters[18] + Kko = parameters[19] + KmBSL = parameters[20] + KmBSR = parameters[21] + KmCaAct = parameters[22] + KmCaM = parameters[23] + KmCaMK = parameters[24] + Kmgatp = parameters[25] + Kmn = parameters[26] + Knai0 = parameters[27] + Knao0 = parameters[28] + Knap = parameters[29] + Kxkur = parameters[30] + L = parameters[31] + MgADP = parameters[32] + MgATP = parameters[33] + PCab = parameters[34] + PKNa = parameters[35] + PNab = parameters[36] + Pnak = parameters[37] + R = parameters[38] + T = parameters[39] + Tot_A = parameters[40] + Tref = parameters[41] + Trpn50 = parameters[42] + aCaMK = parameters[43] + amp = parameters[44] + bCaMK = parameters[45] + bt = parameters[46] + calib = parameters[47] + cao = parameters[48] + cat50_ref = parameters[49] + celltype = parameters[50] + cmdnmax = parameters[51] + csqnmax = parameters[52] + dLambda = parameters[53] + delta = parameters[54] + delta_epi = parameters[55] + duration = parameters[56] + eP = parameters[57] + emcoupling = parameters[58] + etal = parameters[59] + etas = parameters[60] + gammas = parameters[61] + gammaw = parameters[62] + isacs = parameters[63] + k1m = parameters[64] + k1p = parameters[65] + k2m = parameters[66] + k2n = parameters[67] + k2p = parameters[68] + k3m = parameters[69] + k3p = parameters[70] + k4m = parameters[71] + k4p = parameters[72] + kasymm = parameters[73] + kcaoff = parameters[74] + kcaon = parameters[75] + kmcmdn = parameters[76] + kmcsqn = parameters[77] + kmtrpn = parameters[78] + kna1 = parameters[79] + kna2 = parameters[80] + kna3 = parameters[81] + ko = parameters[82] + ktrpn = parameters[83] + ku = parameters[84] + kuw = parameters[85] + kws = parameters[86] + lambda_max = parameters[87] + lmbda = parameters[88] + mode = parameters[89] + nao = parameters[90] + ntm = parameters[91] + ntrpn = parameters[92] + p_a = parameters[93] + p_b = parameters[94] + p_k = parameters[95] + phi = parameters[96] + qca = parameters[97] + qna = parameters[98] + rad = parameters[99] + rs = parameters[100] + rw = parameters[101] + scale_HF_CaMKa = parameters[102] + scale_HF_GK1 = parameters[103] + scale_HF_GNaL = parameters[104] + scale_HF_Gncx = parameters[105] + scale_HF_Gto = parameters[106] + scale_HF_Jleak = parameters[107] + scale_HF_Jrel_inf = parameters[108] + scale_HF_Jup = parameters[109] + scale_HF_Pnak = parameters[110] + scale_HF_cat50_ref = parameters[111] + scale_HF_thL = parameters[112] + scale_ICaL = parameters[113] + scale_IK1 = parameters[114] + scale_IKr = parameters[115] + scale_IKs = parameters[116] + scale_INaL = parameters[117] + scale_drug_ICaL = parameters[118] + scale_drug_ICab = parameters[119] + scale_drug_IK1 = parameters[120] + scale_drug_IKb = parameters[121] + scale_drug_IKr = parameters[122] + scale_drug_IKs = parameters[123] + scale_drug_INa = parameters[124] + scale_drug_INaL = parameters[125] + scale_drug_INab = parameters[126] + scale_drug_IpCa = parameters[127] + scale_drug_Isack = parameters[128] + scale_drug_Isacns = parameters[129] + scale_drug_Ito = parameters[130] + thL = parameters[131] + tjca = parameters[132] + trpnmax = parameters[133] + wca = parameters[134] + wna = parameters[135] + wnaca = parameters[136] + zca = parameters[137] + zk = parameters[138] - # Expressions for the INaCa_ss component - h1 = 1.0 + (1.0 + hna) * nass / kna3 - h2 = hna * nass / (kna3 * h1) - h3 = 1.0 / h1 - h4 = 1.0 + (1 + nass / kna2) * nass / kna1 - h5 = (nass * nass) / (kna1 * kna2 * h4) - h6 = 1.0 / h4 - h7 = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 - h8 = nao / (kna3 * h7 * hna) - h9 = 1.0 / h7 - h10 = 1.0 + kasymm + nao * (1 + nao / kna2) / kna1 - h11 = (nao * nao) / (kna1 * kna2 * h10) - h12 = 1.0 / h10 - k1 = cao * kcaon * h12 - k2 = kcaoff - k3p_ss = wca * h9 - k3pp = wnaca * h8 - k3 = k3p_ss + k3pp - k4p_ss = wca * h3 / hca - k4pp = wnaca * h2 - k4 = k4p_ss + k4pp - k5 = kcaoff - k6 = kcaon * cass * h6 - k7 = wna * h2 * h5 - k8 = wna * h11 * h8 - x1_ss = (k2 + k3) * k5 * k7 + (k6 + k7) * k2 * k4 - x2_ss = (k1 + k8) * k4 * k6 + (k4 + k5) * k1 * k7 - x3_ss = (k2 + k3) * k6 * k8 + (k6 + k7) * k1 * k3 - x4_ss = (k1 + k8) * k3 * k5 + (k4 + k5) * k2 * k8 - E1_ss = x1_ss / (x1_ss + x2_ss + x3_ss + x4_ss) - E2_ss = x2_ss / (x1_ss + x2_ss + x3_ss + x4_ss) - E3_ss = x3_ss / (x1_ss + x2_ss + x3_ss + x4_ss) - E4_ss = x4_ss / (x1_ss + x2_ss + x3_ss + x4_ss) - allo_ss = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cass, 2.0)) - JncxNa_ss = E3_ss * k4pp - E2_ss * k3pp + 3.0 * E4_ss * k7 - 3.0 * E1_ss * k8 - JncxCa_ss = E2_ss * k2 - E1_ss * k1 - INaCa_ss = ( - 0.2 - * Gncx - * scale_popu_KNCX - * HF_scaling_Gncx - * (zca * JncxCa_ss + zna * JncxNa_ss) - * allo_ss + # Assign expressions + values = numpy.zeros_like(states) + zna = 1.0 + Isac_P_k = 0 + Isac_P_ns = 0 + Afcaf = 0.3 + 0.6 / (numpy.exp((v - 10.0) / 10.0) + 1.0) + AiF = 1.0 / (numpy.exp((v - 213.6) / 151.2) + 1.0) + Axrf = 1.0 / (numpy.exp((v + 54.81) / 38.21) + 1.0) + ass = 1.0 / (numpy.exp((-(v - 14.34)) / 14.82) + 1.0) + assp = 1.0 / (numpy.exp((-(v - 24.34)) / 14.82) + 1.0) + dss = 1.0 / (numpy.exp((-(v + 3.94)) / 4.23) + 1.0) + dti_develop = 1.354 + 0.0001 / ( + numpy.exp((-(v - 12.23)) / 0.2154) + numpy.exp((v - 167.4) / 15.89) + ) + dti_recover = 1.0 - 0.5 / (numpy.exp((v + 70.0) / 20.0) + 1.0) + fss = 1.0 / (numpy.exp((v + 19.58) / 3.696) + 1.0) + hLss = 1.0 / (numpy.exp((v + 87.61) / 7.488) + 1.0) + hLssp = 1.0 / (numpy.exp((v + 93.81) / 7.488) + 1.0) + hss = 1.0 / (numpy.exp((v + 78.5) / 6.22) + 1) + hssp = 1.0 / (numpy.exp(((v + 78.5) + 6.2) / 6.22) + 1) + iss = 1.0 / (numpy.exp((v + 43.94) / 5.711) + 1.0) + mLss = 1.0 / (numpy.exp((-(v + 42.85)) / 5.264) + 1.0) + mss = 1.0 / (numpy.exp((-((v + 39.57) + 9.4)) / 7.5) + 1.0) + rkr = (1.0 * (1.0 / (numpy.exp((v + 55.0) / 75.0) + 1.0))) / ( + numpy.exp((v - 10.0) / 30.0) + 1.0 + ) + ta = 1.0515 / ( + 1.0 / ((1.2089 * (numpy.exp((-(v - 18.4099)) / 29.3814) + 1.0))) + + 3.5 / (numpy.exp((v + 100.0) / 29.3814) + 1.0) + ) + td = 0.6 + 1.0 / (numpy.exp((-0.05) * (v + 6.0)) + numpy.exp(0.09 * (v + 14.0))) + tfcaf = 7.0 + 1.0 / ( + 0.04 * numpy.exp((-(v - 4.0)) / 7.0) + 0.04 * numpy.exp((v - 4.0) / 7.0) + ) + tfcas = 100.0 + 1.0 / ( + 0.00012 * numpy.exp((-v) / 3.0) + 0.00012 * numpy.exp(v / 7.0) + ) + tff = 7.0 + 1.0 / ( + 0.0045 * numpy.exp((-(v + 20.0)) / 10.0) + 0.0045 * numpy.exp((v + 20.0) / 10.0) + ) + tfs = 1000.0 + 1.0 / ( + 3.5e-05 * numpy.exp((-(v + 5.0)) / 4.0) + 3.5e-05 * numpy.exp((v + 5.0) / 6.0) + ) + thf = 1.0 / ( + 6.149 * numpy.exp((v + 0.5096) / 20.27) + + 1.432e-05 * numpy.exp((-(v + 1.196)) / 6.285) + ) + ths = 1.0 / ( + 0.009794 * numpy.exp((-(v + 17.95)) / 28.05) + + 0.3343 * numpy.exp((v + 5.73) / 56.66) + ) + tj = 2.038 + 1.0 / ( + 0.3052 * numpy.exp((v + 0.9941) / 38.45) + + 0.02136 * numpy.exp((-(v + 100.6)) / 8.281) + ) + tm = 1.0 / ( + 6.765 * numpy.exp((v + 11.64) / 34.77) + + 8.552 * numpy.exp((-(v + 77.42)) / 5.955) + ) + txk1 = 122.2 / (numpy.exp((-(v + 127.2)) / 20.36) + numpy.exp((v + 236.8) / 69.33)) + txrf = 12.98 + 1.0 / ( + 4.123e-05 * numpy.exp((-(v - 47.78)) / 20.38) + + 0.3652 * numpy.exp((v - 31.66) / 3.869) + ) + txrs = 1.865 + 1.0 / ( + 1.128e-05 * numpy.exp((-(v - 29.74)) / 25.94) + + 0.06629 * numpy.exp((v - 34.7) / 7.355) + ) + txs1 = 817.3 + 1.0 / ( + 0.0002326 * numpy.exp((v + 48.28) / 17.8) + + 0.001292 * numpy.exp((-(v + 210.0)) / 230.0) + ) + txs2 = 1.0 / ( + 0.01 * numpy.exp((v - 50.0) / 20.0) + 0.0193 * numpy.exp((-(v + 66.54)) / 31.0) + ) + xkb = 1.0 / (numpy.exp((-(v - 14.48)) / 18.34) + 1.0) + xrss = 1.0 / (numpy.exp((-(v + 8.337)) / 6.789) + 1.0) + xs1ss = 1.0 / (numpy.exp((-(v + 11.6)) / 8.932) + 1.0) + Afs = 1.0 - Aff + Ageo = L * ((2 * 3.14) * rad) + rad * ((2 * 3.14) * rad) + vcell = L * (rad * ((3.14 * 1000) * rad)) + Ahs = 1.0 - Ahf + Aw = (Tot_A * rs) / (rs + rw * (1 - rs)) + Jupnp = (0.004375 * cai) / (cai + 0.00092) + Jupp = ((0.004375 * 2.75) * cai) / ((cai + 0.00092) - 0.00017) + KsCa = 1.0 + 0.6 / ((3.8e-05 / cai) ** 1.4 + 1.0) + Bcai = 1.0 / ((cmdnmax * kmcmdn) / (cai + kmcmdn) ** 2.0 + 1.0) + Bcajsr = 1.0 / ((csqnmax * kmcsqn) / (cajsr + kmcsqn) ** 2.0 + 1.0) + Jdiff = (-cai + cass) / 0.2 + Bcass = 1.0 / ( + (BSLmax * KmBSL) / (KmBSL + cass) ** 2.0 + + ((BSRmax * KmBSR) / (KmBSR + cass) ** 2.0 + 1.0) + ) + CaMKb = (CaMKo * (1.0 - CaMKt)) / (KmCaM / cass + 1.0) + CaTrpn_max = (CaTrpn) * (CaTrpn > 0) + (0) * numpy.logical_not((CaTrpn > 0)) + vffrt = (F * (F * v)) / ((R * T)) + vfrt = (F * v) / ((R * T)) + EK = ((R * T) / F) * numpy.log(ko / ki) + rk1 = 1.0 / (numpy.exp((-2.6 * ko + (v + 105.8)) / 9.493) + 1.0) + xk1ss = 1.0 / ( + numpy.exp((-((2.5538 * ko + v) + 144.59)) / (1.5692 * ko + 3.8115)) + 1.0 + ) + ENa = ((R * T) / F) * numpy.log(nao / nai) + EKs = ((R * T) / F) * numpy.log((PKNa * nao + ko) / (PKNa * nai + ki)) + GK1 = scale_HF_GK1 * ((0.1908 * scale_IK1) * scale_drug_IK1) + GKr = (0.046 * scale_IKr) * scale_drug_IKr + GKs = (0.0034 * scale_IKs) * scale_drug_IKs + GNaL = scale_HF_GNaL * ((0.0075 * scale_INaL) * scale_drug_INaL) + km2n = 1.0 * jca + IpCa = (cai * (GpCa * scale_drug_IpCa)) / (cai + 0.0005) + Istim = (amp) * (duration >= t) + (0) * numpy.logical_not((duration >= t)) + JdiffK = (-ki + kss) / 2.0 + JdiffNa = (-nai + nass) / 2.0 + Jtr = (-cajsr + cansr) / 100.0 + Jleak = ((0.0039375 * cansr) * scale_HF_Jleak) / 15.0 + Knai = Knai0 * numpy.exp((F * (delta * v)) / (((3.0 * R) * T))) + Knao = Knao0 * numpy.exp((F * (v * (1.0 - delta))) / (((3.0 * R) * T))) + P = eP / (((H / Khp + 1.0) + nai / Knap) + ki / Kxkur) + PCa = (0.0001 * scale_ICaL) * scale_drug_ICaL + XW_max = (XW) * (XW > 0) + (0) * numpy.logical_not((XW > 0)) + XS_max = (XS) * (XS > 0) + (0) * numpy.logical_not((XS > 0)) + XU = -XW + (-XS + (1 - TmB)) + a2 = k2p + a4 = ((MgATP * k4p) / Kmgatp) / (1.0 + MgATP / Kmgatp) + a_rel = 0.5 * bt + btp = 1.25 * bt + tau_rel_tmp = bt / (1.0 + 0.0123 / cajsr) + allo_i = 1.0 / ((KmCaAct / cai) ** 2.0 + 1.0) + allo_ss = 1.0 / ((KmCaAct / cass) ** 2.0 + 1.0) + b1 = MgADP * k1m + cs = ((kws * phi) * (rw * (1 - rs))) / rs + ksu = (kws * rw) * (-1 + 1 / rs) + cw = ((kuw * phi) * ((1 - rs) * (1 - rw))) / ((rw * (1 - rs))) + kwu = kuw * (-1 + 1 / rw) - kws + gammasu = ( + gammas * Zetas * 1 * (Zetas > 0) + + 0 + * (~(Zetas > 0)) + * numpy.logical_and.reduce( + ( + numpy.logical_or((Zetas > -1), (Zetas > 0)), + numpy.logical_or((Zetas > 0), (Zetas < -1)), + numpy.logical_or.reduce( + ((Zetas >= -1), (Zetas <= 0), (Zetas > -1 / 2)), + ), + ), ) - - # Expressions for the INaK component - Knai = Knai0 * ufl.exp(0.3333333333333333 * F * delta * v / (R * T)) - Knao = Knao0 * ufl.exp(0.3333333333333333 * F * (1.0 - delta) * v / (R * T)) - P = eP / (1.0 + H / Khp + nai / Knap + ki / Kxkur) - a1 = ( - k1p - * ufl.elem_pow(nai / Knai, 3.0) - / ( - -1.0 - + ufl.elem_pow(1.0 + ki / Kki, 2.0) - + ufl.elem_pow(1.0 + nai / Knai, 3.0) + + (-Zetas - 1) * 1 * (Zetas < -1) + + 0 + * (~(Zetas < -1)) + * ( + ~numpy.logical_and.reduce( + ( + numpy.logical_or((Zetas > -1), (Zetas > 0)), + numpy.logical_or((Zetas > 0), (Zetas < -1)), + numpy.logical_or.reduce( + ((Zetas >= -1), (Zetas <= 0), (Zetas > -1 / 2)), + ), + ), ) ) - b1 = MgADP * k1m - a2 = k2p - b2 = ( - k2m - * ufl.elem_pow(nao / Knao, 3.0) + ) + gammawu = gammaw * numpy.abs(Zetaw) + h10 = (nao / kna1) * (1 + nao / kna2) + (kasymm + 1.0) + h10_i = (nao / kna1) * (1.0 + nao / kna2) + (kasymm + 1.0) + h4 = (nass / kna1) * (1 + nass / kna2) + 1.0 + h4_i = (nai / kna1) * (1 + nai / kna2) + 1.0 + hca = numpy.exp((F * (qca * v)) / ((R * T))) + hna = numpy.exp((F * (qna * v)) / ((R * T))) + k2 = kcaoff + k2_i = kcaoff + k5 = kcaoff + k5_i = kcaoff + kb = (Trpn50**ntm * ku) / (-rw * (1 - rs) + (1 - rs)) + lambda_min12 = (lmbda) * (lmbda < 1.2) + (1.2) * numpy.logical_not((lmbda < 1.2)) + thLp = scale_HF_thL * (3.0 * thL) + tiF = ( + delta_epi + * ( + 1 / ( - -1.0 - + ufl.elem_pow(1.0 + ko / Kko, 2.0) - + ufl.elem_pow(1.0 + nao / Knao, 3.0) + 0.3933 * numpy.exp((-(v + 100.0)) / 100.0) + + 0.08004 * numpy.exp((v + 50.0) / 16.59) ) ) - a3 = ( - k3p - * ufl.elem_pow(ko / Kko, 2.0) + + 4.562 + ) + tiS = ( + delta_epi + * ( + 1 / ( - -1.0 - + ufl.elem_pow(1.0 + ko / Kko, 2.0) - + ufl.elem_pow(1.0 + nao / Knao, 3.0) + 0.001416 * numpy.exp((-(v + 96.52)) / 59.05) + + 1.78e-08 * numpy.exp((v + 114.1) / 8.079) ) ) - b3 = H * k3m * P / (1.0 + MgATP / Kmgatp) - a4 = MgATP * k4p / (Kmgatp * (1.0 + MgATP / Kmgatp)) - b4 = ( - k4m - * ufl.elem_pow(ki / Kki, 2.0) - / ( - -1.0 - + ufl.elem_pow(1.0 + ki / Kki, 2.0) - + ufl.elem_pow(1.0 + nai / Knai, 3.0) + + 23.62 + ) + Afcas = 1.0 - Afcaf + AiS = 1.0 - AiF + Axrs = 1.0 - Axrf + fcass = fss + dhL_dt = (-hL + hLss) / ((scale_HF_thL * thL)) + dhL_dt_linearized = -1 / (scale_HF_thL * thL) + values[0] = ( + dhL_dt * (numpy.exp(dhL_dt_linearized * dt) - 1) / dhL_dt_linearized + hL + ) + jss = hss + da_dt = (-a + ass) / ta + da_dt_linearized = -1 / ta + values[1] = a + da_dt * (numpy.exp(da_dt_linearized * dt) - 1) / da_dt_linearized + dap_dt = (-ap + assp) / ta + dap_dt_linearized = -1 / ta + values[2] = ( + ap + dap_dt * (numpy.exp(dap_dt_linearized * dt) - 1) / dap_dt_linearized + ) + dd_dt = (-d + dss) / td + dd_dt_linearized = -1 / td + values[3] = d + dd_dt * (numpy.exp(dd_dt_linearized * dt) - 1) / dd_dt_linearized + tfcafp = 2.5 * tfcaf + tffp = 2.5 * tff + dff_dt = (-ff + fss) / tff + dff_dt_linearized = -1 / tff + values[4] = ( + dff_dt * (numpy.exp(dff_dt_linearized * dt) - 1) / dff_dt_linearized + ff + ) + dfs_dt = (-fs + fss) / tfs + dfs_dt_linearized = -1 / tfs + values[5] = ( + dfs_dt * (numpy.exp(dfs_dt_linearized * dt) - 1) / dfs_dt_linearized + fs + ) + dhf_dt = (-hf + hss) / thf + dhf_dt_linearized = -1 / thf + values[6] = ( + dhf_dt * (numpy.exp(dhf_dt_linearized * dt) - 1) / dhf_dt_linearized + hf + ) + thsp = 3.0 * ths + dhs_dt = (-hs + hss) / ths + dhs_dt_linearized = -1 / ths + values[7] = ( + dhs_dt * (numpy.exp(dhs_dt_linearized * dt) - 1) / dhs_dt_linearized + hs + ) + tjp = 1.46 * tj + tmL = tm + dm_dt = (-m + mss) / tm + dm_dt_linearized = -1 / tm + values[8] = dm_dt * (numpy.exp(dm_dt_linearized * dt) - 1) / dm_dt_linearized + m + dxrf_dt = (-xrf + xrss) / txrf + dxrf_dt_linearized = -1 / txrf + values[9] = ( + dxrf_dt * (numpy.exp(dt * dxrf_dt_linearized) - 1) / dxrf_dt_linearized + xrf + ) + dxrs_dt = (-xrs + xrss) / txrs + dxrs_dt_linearized = -1 / txrs + values[10] = ( + dxrs_dt * (numpy.exp(dt * dxrs_dt_linearized) - 1) / dxrs_dt_linearized + xrs + ) + xs2ss = xs1ss + dxs1_dt = (-xs1 + xs1ss) / txs1 + dxs1_dt_linearized = -1 / txs1 + values[11] = ( + dxs1_dt * (numpy.exp(dt * dxs1_dt_linearized) - 1) / dxs1_dt_linearized + xs1 + ) + f = Aff * ff + Afs * fs + fp = Aff * ffp + Afs * fs + Acap = 2 * Ageo + vjsr = 0.0048 * vcell + vmyo = 0.68 * vcell + vnsr = 0.0552 * vcell + vss = 0.02 * vcell + h = Ahf * hf + Ahs * hs + hp = Ahf * hf + Ahs * hsp + As = Aw + CaMKa = scale_HF_CaMKa * (CaMKb + CaMKt) + dCaMKt_dt = -CaMKt * bCaMK + (CaMKb * aCaMK) * (CaMKb + CaMKt) + dCaMKt_dt_linearized = CaMKb * aCaMK - bCaMK + values[12] = ( + CaMKt + + dCaMKt_dt + * (numpy.exp(dCaMKt_dt_linearized * dt) - 1) + / dCaMKt_dt_linearized + * (numpy.abs(dCaMKt_dt_linearized) > 1e-08) + + dCaMKt_dt * dt * (~(numpy.abs(dCaMKt_dt_linearized) > 1e-08)) + ) + ICab = ( + (vffrt * (4.0 * (PCab * scale_drug_ICab))) + * (cai * numpy.exp(2.0 * vfrt) - 0.341 * cao) + ) / (numpy.exp(2.0 * vfrt) - 1.0) + INab = ((vffrt * (PNab * scale_drug_INab)) * (nai * numpy.exp(vfrt) - nao)) / ( + numpy.exp(vfrt) - 1.0 + ) + PhiCaK = ((1.0 * vffrt) * (-0.75 * ko + (0.75 * kss) * numpy.exp(1.0 * vfrt))) / ( + numpy.exp(1.0 * vfrt) - 1.0 + ) + PhiCaL = ((4.0 * vffrt) * (-0.341 * cao + cass * numpy.exp(2.0 * vfrt))) / ( + numpy.exp(2.0 * vfrt) - 1.0 + ) + PhiCaNa = ( + (1.0 * vffrt) * (-0.75 * nao + (0.75 * nass) * numpy.exp(1.0 * vfrt)) + ) / (numpy.exp(1.0 * vfrt) - 1.0) + IKb = (xkb * (GKb * scale_drug_IKb)) * (-EK + v) + dxk1_dt = (-xk1 + xk1ss) / txk1 + dxk1_dt_linearized = -1 / txk1 + values[13] = ( + dxk1_dt * (numpy.exp(dt * dxk1_dt_linearized) - 1) / dxk1_dt_linearized + xk1 + ) + IK1 = (xk1 * (rk1 * (GK1 * math.sqrt(ko)))) * (-EK + v) + IKs = (xs2 * (xs1 * (GKs * KsCa))) * (-EKs + v) + anca = 1.0 / (k2n / km2n + (Kmn / cass + 1.0) ** 4.0) + a1 = (k1p * (nai / Knai) ** 3.0) / ( + ((1.0 + ki / Kki) ** 2.0 + (1.0 + nai / Knai) ** 3.0) - 1.0 + ) + b4 = (k4m * (ki / Kki) ** 2.0) / ( + ((1.0 + ki / Kki) ** 2.0 + (1.0 + nai / Knai) ** 3.0) - 1.0 + ) + a3 = (k3p * (ko / Kko) ** 2.0) / ( + ((1.0 + ko / Kko) ** 2.0 + (1.0 + nao / Knao) ** 3.0) - 1.0 + ) + b2 = (k2m * (nao / Knao) ** 3.0) / ( + ((1.0 + ko / Kko) ** 2.0 + (1.0 + nao / Knao) ** 3.0) - 1.0 + ) + b3 = (H * (P * k3m)) / (1.0 + MgATP / Kmgatp) + PCaK = 0.0003574 * PCa + PCaNa = 0.00125 * PCa + PCap = 1.1 * PCa + a_relp = 0.5 * btp + tau_relp_tmp = btp / (1.0 + 0.0123 / cajsr) + tau_rel = (0.001) * (tau_rel_tmp < 0.001) + (tau_rel_tmp) * numpy.logical_not( + (tau_rel_tmp < 0.001), + ) + dZetaw_dt = Aw * dLambda - Zetaw * cw + dZetaw_dt_linearized = -cw + values[14] = ( + Zetaw + + dZetaw_dt + * (numpy.exp(dZetaw_dt_linearized * dt) - 1) + / dZetaw_dt_linearized + * (numpy.abs(dZetaw_dt_linearized) > 1e-08) + + dZetaw_dt * dt * (~(numpy.abs(dZetaw_dt_linearized) > 1e-08)) + ) + dXS_dt = -XS * gammasu + (-XS * ksu + XW * kws) + dXS_dt_linearized = -gammasu - ksu + values[15] = ( + XS + + dXS_dt + * (numpy.exp(dXS_dt_linearized * dt) - 1) + / dXS_dt_linearized + * (numpy.abs(dXS_dt_linearized) > 1e-08) + + dXS_dt * dt * (~(numpy.abs(dXS_dt_linearized) > 1e-08)) + ) + dXW_dt = -XW * gammawu + (-XW * kws + (XU * kuw - XW * kwu)) + dXW_dt_linearized = -gammawu - kws - kwu + values[16] = ( + XW + + dXW_dt + * (numpy.exp(dXW_dt_linearized * dt) - 1) + / dXW_dt_linearized + * (numpy.abs(dXW_dt_linearized) > 1e-08) + + dXW_dt * dt * (~(numpy.abs(dXW_dt_linearized) > 1e-08)) + ) + h11 = (nao * nao) / ((kna2 * (h10 * kna1))) + h12 = 1.0 / h10 + h11_i = (nao * nao) / ((kna2 * (h10_i * kna1))) + h12_i = 1.0 / h10_i + h5 = (nass * nass) / ((kna2 * (h4 * kna1))) + h6 = 1.0 / h4 + h5_i = (nai * nai) / ((kna2 * (h4_i * kna1))) + h6_i = 1.0 / h4_i + h1 = (nass / kna3) * (hna + 1) + 1 + h1_i = (nai / kna3) * (hna + 1) + 1 + h7 = (nao / kna3) * (1.0 + 1.0 / hna) + 1.0 + h7_i = (nao / kna3) * (1.0 + 1.0 / hna) + 1.0 + dTmB_dt = -TmB * CaTrpn ** (ntm / 2) * ku + XU * ( + kb * CaTrpn ** ((-ntm) / 2) * (CaTrpn ** ((-ntm) / 2) < 100) + + 100 * (~(CaTrpn ** ((-ntm) / 2) < 100)) + ) + dTmB_dt_linearized = -(CaTrpn ** (ntm / 2)) * ku + values[17] = ( + TmB + + dTmB_dt + * (numpy.exp(dTmB_dt_linearized * dt) - 1) + / dTmB_dt_linearized + * (numpy.abs(dTmB_dt_linearized) > 1e-08) + + dTmB_dt * dt * (~(numpy.abs(dTmB_dt_linearized) > 1e-08)) + ) + C = lambda_min12 - 1 + cat50 = scale_HF_cat50_ref * (Beta1 * (lambda_min12 - 1) + cat50_ref) + lambda_min087 = (lambda_min12) * (lambda_min12 < 0.87) + (0.87) * numpy.logical_not( + (lambda_min12 < 0.87), + ) + dhLp_dt = (-hLp + hLssp) / thLp + dhLp_dt_linearized = -1 / thLp + values[18] = ( + dhLp_dt * (numpy.exp(dhLp_dt_linearized * dt) - 1) / dhLp_dt_linearized + hLp + ) + tiFp = tiF * (dti_develop * dti_recover) + diF_dt = (-iF + iss) / tiF + diF_dt_linearized = -1 / tiF + values[19] = ( + diF_dt * (numpy.exp(diF_dt_linearized * dt) - 1) / diF_dt_linearized + iF + ) + tiSp = tiS * (dti_develop * dti_recover) + diS_dt = (-iS + iss) / tiS + diS_dt_linearized = -1 / tiS + values[20] = ( + diS_dt * (numpy.exp(diS_dt_linearized * dt) - 1) / diS_dt_linearized + iS + ) + fca = Afcaf * fcaf + Afcas * fcas + fcap = Afcaf * fcafp + Afcas * fcas + i = AiF * iF + AiS * iS + ip = AiF * iFp + AiS * iSp + xr = Axrf * xrf + Axrs * xrs + dfcaf_dt = (-fcaf + fcass) / tfcaf + dfcaf_dt_linearized = -1 / tfcaf + values[21] = ( + dfcaf_dt * (numpy.exp(dfcaf_dt_linearized * dt) - 1) / dfcaf_dt_linearized + + fcaf + ) + dfcas_dt = (-fcas + fcass) / tfcas + dfcas_dt_linearized = -1 / tfcas + values[22] = ( + dfcas_dt * (numpy.exp(dfcas_dt_linearized * dt) - 1) / dfcas_dt_linearized + + fcas + ) + djca_dt = (fcass - jca) / tjca + djca_dt_linearized = -1 / tjca + values[23] = ( + djca_dt * (numpy.exp(djca_dt_linearized * dt) - 1) / djca_dt_linearized + jca + ) + dj_dt = (-j + jss) / tj + dj_dt_linearized = -1 / tj + values[24] = dj_dt * (numpy.exp(dj_dt_linearized * dt) - 1) / dj_dt_linearized + j + dfcafp_dt = (-fcafp + fcass) / tfcafp + dfcafp_dt_linearized = -1 / tfcafp + values[25] = ( + dfcafp_dt * (numpy.exp(dfcafp_dt_linearized * dt) - 1) / dfcafp_dt_linearized + + fcafp + ) + dffp_dt = (-ffp + fss) / tffp + dffp_dt_linearized = -1 / tffp + values[26] = ( + dffp_dt * (numpy.exp(dffp_dt_linearized * dt) - 1) / dffp_dt_linearized + ffp + ) + dhsp_dt = (-hsp + hssp) / thsp + dhsp_dt_linearized = -1 / thsp + values[27] = ( + dhsp_dt * (numpy.exp(dhsp_dt_linearized * dt) - 1) / dhsp_dt_linearized + hsp + ) + djp_dt = (-jp + jss) / tjp + djp_dt_linearized = -1 / tjp + values[28] = ( + djp_dt * (numpy.exp(djp_dt_linearized * dt) - 1) / djp_dt_linearized + jp + ) + dmL_dt = (-mL + mLss) / tmL + dmL_dt_linearized = -1 / tmL + values[29] = ( + dmL_dt * (numpy.exp(dmL_dt_linearized * dt) - 1) / dmL_dt_linearized + mL + ) + dxs2_dt = (-xs2 + xs2ss) / txs2 + dxs2_dt_linearized = -1 / txs2 + values[30] = ( + dxs2_dt * (numpy.exp(dt * dxs2_dt_linearized) - 1) / dxs2_dt_linearized + xs2 + ) + dZetas_dt = As * dLambda - Zetas * cs + dZetas_dt_linearized = -cs + values[31] = ( + Zetas + + dZetas_dt + * (numpy.exp(dZetas_dt_linearized * dt) - 1) + / dZetas_dt_linearized + * (numpy.abs(dZetas_dt_linearized) > 1e-08) + + dZetas_dt * dt * (~(numpy.abs(dZetas_dt_linearized) > 1e-08)) + ) + fICaLp = 1.0 / (1.0 + KmCaMK / CaMKa) + fINaLp = 1.0 / (1.0 + KmCaMK / CaMKa) + fINap = 1.0 / (1.0 + KmCaMK / CaMKa) + fItop = 1.0 / (1.0 + KmCaMK / CaMKa) + fJrelp = 1.0 / (1.0 + KmCaMK / CaMKa) + fJupp = 1.0 / (1.0 + KmCaMK / CaMKa) + dnca_dt = anca * k2n - km2n * nca + dnca_dt_linearized = -km2n + values[32] = ( + nca + + dnca_dt + * (numpy.exp(dnca_dt_linearized * dt) - 1) + / dnca_dt_linearized + * (numpy.abs(dnca_dt_linearized) > 1e-08) + + dnca_dt * dt * (~(numpy.abs(dnca_dt_linearized) > 1e-08)) + ) + x2 = b4 * (a2 * a3) + (b4 * (a3 * b1) + (a3 * (a1 * a2) + b4 * (b1 * b2))) + x1 = a2 * (a1 * b3) + (b3 * (a2 * b4) + (a2 * (a1 * a4) + b3 * (b2 * b4))) + x3 = b1 * (a3 * a4) + (a4 * (b1 * b2) + (a4 * (a2 * a3) + b1 * (b2 * b3))) + x4 = a1 * (b2 * b3) + (a1 * (a4 * b2) + (a1 * (a3 * a4) + b2 * (b3 * b4))) + PCaKp = 0.0003574 * PCap + PCaNap = 0.00125 * PCap + tau_relp = (0.001) * (tau_relp_tmp < 0.001) + (tau_relp_tmp) * numpy.logical_not( + (tau_relp_tmp < 0.001), + ) + k1 = kcaon * (cao * h12) + k1_i = kcaon * (cao * h12_i) + k6 = kcaon * (cass * h6) + k6_i = kcaon * (cai * h6_i) + h2 = (hna * nass) / ((h1 * kna3)) + h3 = 1.0 / h1 + h2_i = (hna * nai) / ((h1_i * kna3)) + h3_i = 1.0 / h1_i + h8 = nao / ((h7 * (hna * kna3))) + h9 = 1.0 / h7 + h8_i = nao / ((h7_i * (hna * kna3))) + h9_i = 1.0 / h7_i + F1 = numpy.exp(C * p_b) - 1 + dCd = C - Cd + dCaTrpn_dt = ktrpn * (-CaTrpn + ((1000 * cai) / cat50) ** ntrpn * (1 - CaTrpn)) + dCaTrpn_dt_linearized = ktrpn * (-(((1000 * cai) / cat50) ** ntrpn) - 1) + values[33] = ( + CaTrpn + + dCaTrpn_dt + * (numpy.exp(dCaTrpn_dt_linearized * dt) - 1) + / dCaTrpn_dt_linearized + * (numpy.abs(dCaTrpn_dt_linearized) > 1e-08) + + dCaTrpn_dt * dt * (~(numpy.abs(dCaTrpn_dt_linearized) > 1e-08)) + ) + h_lambda_prima = Beta0 * ((lambda_min087 + lambda_min12) - 1.87) + 1 + diFp_dt = (-iFp + iss) / tiFp + diFp_dt_linearized = -1 / tiFp + values[34] = ( + diFp_dt * (numpy.exp(diFp_dt_linearized * dt) - 1) / diFp_dt_linearized + iFp + ) + diSp_dt = (-iSp + iss) / tiSp + diSp_dt_linearized = -1 / tiSp + values[35] = ( + diSp_dt * (numpy.exp(diSp_dt_linearized * dt) - 1) / diSp_dt_linearized + iSp + ) + IKr = (rkr * (xr * (GKr * (0.4303314829119352 * math.sqrt(ko))))) * (-EK + v) + ICaL = (d * (PhiCaL * (PCa * (1.0 - fICaLp)))) * ( + f * (1.0 - nca) + nca * (fca * jca) + ) + (d * (PhiCaL * (PCap * fICaLp))) * (fp * (1.0 - nca) + nca * (fcap * jca)) + INaL = (mL * (GNaL * (-ENa + v))) * (fINaLp * hLp + hL * (1.0 - fINaLp)) + INa = (m**3.0 * ((GNa * scale_drug_INa) * (-ENa + v))) * ( + j * (h * (1.0 - fINap)) + jp * (fINap * hp) + ) + Ito = ((scale_HF_Gto * (Gto * scale_drug_Ito)) * (-EK + v)) * ( + i * (a * (1.0 - fItop)) + ip * (ap * fItop) + ) + Jrel = Jrelnp * (1.0 - fJrelp) + Jrelp * fJrelp + Jup = -Jleak + (Jupnp * (1.0 - fJupp) + scale_HF_Jup * (Jupp * fJupp)) + E1 = x1 / (x4 + (x3 + (x1 + x2))) + E2 = x2 / (x4 + (x3 + (x1 + x2))) + E3 = x3 / (x4 + (x3 + (x1 + x2))) + E4 = x4 / (x4 + (x3 + (x1 + x2))) + ICaK = (d * (PhiCaK * (PCaK * (1.0 - fICaLp)))) * ( + f * (1.0 - nca) + nca * (fca * jca) + ) + (d * (PhiCaK * (PCaKp * fICaLp))) * (fp * (1.0 - nca) + nca * (fcap * jca)) + ICaNa = (d * (PhiCaNa * (PCaNa * (1.0 - fICaLp)))) * ( + f * (1.0 - nca) + nca * (fca * jca) + ) + (d * (PhiCaNa * (PCaNap * fICaLp))) * (fp * (1.0 - nca) + nca * (fcap * jca)) + k4pp = h2 * wnaca + k7 = wna * (h2 * h5) + k4p_ss = (h3 * wca) / hca + k4pp_i = h2_i * wnaca + k7_i = wna * (h2_i * h5_i) + k4p_i = (h3_i * wca) / hca + k3pp = h8 * wnaca + k8 = wna * (h11 * h8) + k3p_ss = h9 * wca + k3pp_i = h8_i * wnaca + k8_i = wna * (h11_i * h8_i) + k3p_i = h9_i * wca + eta = (etas) * (dCd < 0) + (etal) * numpy.logical_not((dCd < 0)) + J_TRPN = dCaTrpn_dt * trpnmax + h_lambda = (h_lambda_prima) * (h_lambda_prima > 0) + (0) * numpy.logical_not( + (h_lambda_prima > 0), + ) + Jrel_inf = ((-ICaL) * a_rel) / (((1.5 * scale_HF_Jrel_inf) / cajsr) ** 8.0 + 1.0) + Jrel_infp = ((-ICaL) * a_relp) / (((1.5 * scale_HF_Jrel_inf) / cajsr) ** 8.0 + 1.0) + dcajsr_dt = Bcajsr * (-Jrel + Jtr) + values[36] = cajsr + dcajsr_dt * dt + dcansr_dt = Jup - (Jtr * vjsr) / vnsr + values[37] = cansr + dcansr_dt * dt + JnakNa = 3.0 * (E1 * a3 - E2 * b3) + JnakK = 2.0 * (-E3 * a1 + E4 * b1) + dkss_dt = -JdiffK + (Acap * (-ICaK)) / ((F * vss)) + values[38] = dkss_dt * dt + kss + k4 = k4p_ss + k4pp + k4_i = k4p_i + k4pp_i + k3 = k3p_ss + k3pp + k3_i = k3p_i + k3pp_i + Fd = dCd * eta + dCd_dt = (p_k * (C - Cd)) / eta + dCd_dt_linearized = -p_k / eta + values[39] = ( + Cd + + dCd_dt + * (numpy.exp(dCd_dt_linearized * dt) - 1) + / dCd_dt_linearized + * (numpy.abs(dCd_dt_linearized) > 1e-08) + + dCd_dt * dt * (~(numpy.abs(dCd_dt_linearized) > 1e-08)) + ) + Ta = (h_lambda * (Tref / rs)) * (XS * (Zetas + 1) + XW * Zetaw) + dJrelnp_dt = (Jrel_inf - Jrelnp) / tau_rel + dJrelnp_dt_linearized = -1 / tau_rel + values[40] = ( + Jrelnp + + dJrelnp_dt + * (numpy.exp(dJrelnp_dt_linearized * dt) - 1) + / dJrelnp_dt_linearized + ) + dJrelp_dt = (Jrel_infp - Jrelp) / tau_relp + dJrelp_dt_linearized = -1 / tau_relp + values[41] = ( + Jrelp + + dJrelp_dt * (numpy.exp(dJrelp_dt_linearized * dt) - 1) / dJrelp_dt_linearized + ) + INaK = (Pnak * scale_HF_Pnak) * (JnakK * zk + JnakNa * zna) + x2_ss = (k1 * k7) * (k4 + k5) + (k4 * k6) * (k1 + k8) + x2_i = (k1_i * k7_i) * (k4_i + k5_i) + (k4_i * k6_i) * (k1_i + k8_i) + x1_ss = (k2 * k4) * (k6 + k7) + (k5 * k7) * (k2 + k3) + x3_ss = (k1 * k3) * (k6 + k7) + (k6 * k8) * (k2 + k3) + x4_ss = (k2 * k8) * (k4 + k5) + (k3 * k5) * (k1 + k8) + x1_i = (k2_i * k4_i) * (k6_i + k7_i) + (k5_i * k7_i) * (k2_i + k3_i) + x3_i = (k1_i * k3_i) * (k6_i + k7_i) + (k6_i * k8_i) * (k2_i + k3_i) + x4_i = (k2_i * k8_i) * (k4_i + k5_i) + (k3_i * k5_i) * (k1_i + k8_i) + Tp = p_a * (F1 + Fd) + dki_dt = ( + Acap + * ( + -( + -2.0 * INaK + + ( + Istim + + (Isac_P_ns / 3 + (Isac_P_k + (IKb + (IK1 + (IKs + (IKr + Ito)))))) + ) ) ) - x1 = a1 * a2 * a4 + a1 * a2 * b3 + a2 * b3 * b4 + b2 * b3 * b4 - x2 = a1 * a2 * a3 + a2 * a3 * b4 + a3 * b1 * b4 + b1 * b2 * b4 - x3 = a2 * a3 * a4 + a3 * a4 * b1 + a4 * b1 * b2 + b1 * b2 * b3 - x4 = a1 * a3 * a4 + a1 * a4 * b2 + a1 * b2 * b3 + b2 * b3 * b4 - E1 = x1 / (x1 + x2 + x3 + x4) - E2 = x2 / (x1 + x2 + x3 + x4) - E3 = x3 / (x1 + x2 + x3 + x4) - E4 = x4 / (x1 + x2 + x3 + x4) - JnakNa = 3.0 * E1 * a3 - 3.0 * E2 * b3 - JnakK = 2.0 * E4 * b1 - 2.0 * E3 * a1 - INaK = Pnak * scale_popu_KNaK * HF_scaling_Pnak * (zk * JnakK + zna * JnakNa) - - # Expressions for the IKb component - xkb = 1.0 / (1.0 + 2.202363450949239 * ufl.exp(-0.05452562704471101 * v)) - IKb = GKb * scale_popu_GbK * scale_drug_IKb * (-EK + v) * xkb - - # Expressions for the INab component - INab = ( - PNab - * scale_drug_INab - * scale_popu_GbNa - * (-nao + ufl.exp(vfrt) * nai) - * vffrt - / (-1.0 + ufl.exp(vfrt)) - ) - - # Expressions for the ICab component - ICab = ( - 4.0 - * PCab - * scale_drug_ICab - * scale_popu_GbCa - * (-0.341 * cao + cai * ufl.exp(2.0 * vfrt)) - * vffrt - / (-1.0 + ufl.exp(2.0 * vfrt)) + ) / ((F * vmyo)) + (JdiffK * vss) / vmyo + values[42] = dki_dt * dt + ki + E1_ss = x1_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) + E2_ss = x2_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) + E3_ss = x3_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) + E4_ss = x4_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) + E1_i = x1_i / (x4_i + (x3_i + (x1_i + x2_i))) + E2_i = x2_i / (x4_i + (x3_i + (x1_i + x2_i))) + E3_i = x3_i / (x4_i + (x3_i + (x1_i + x2_i))) + E4_i = x4_i / (x4_i + (x3_i + (x1_i + x2_i))) + Ttot = Ta + Tp + JncxCa_ss = -E1_ss * k1 + E2_ss * k2 + JncxNa_ss = -E2_ss * k3pp + (E3_ss * k4pp + 3.0 * (-E1_ss * k8 + E4_ss * k7)) + JncxCa_i = -E1_i * k1_i + E2_i * k2_i + JncxNa_i = -E2_i * k3pp_i + (E3_i * k4pp_i + 3.0 * (-E1_i * k8_i + E4_i * k7_i)) + INaCa_ss = (allo_ss * ((0.2 * Gncx) * scale_HF_Gncx)) * ( + JncxCa_ss * zca + JncxNa_ss * zna + ) + INaCa_i = (allo_i * ((0.8 * Gncx) * scale_HF_Gncx)) * ( + JncxCa_i * zca + JncxNa_i * zna + ) + dcass_dt = Bcass * ( + -Jdiff + + ( + (Acap * (-(ICaL - 2.0 * INaCa_ss))) / (((2.0 * F) * vss)) + + (Jrel * vjsr) / vss ) - - # Expressions for the IpCa component - IpCa = GpCa * scale_drug_IpCa * scale_popu_KpCa * cai / (0.0005 + cai) - - # Expressions for the Isac (Pueyo)--> ns + k component - Gsac_ns = 0.006 * scale_drug_Isacns - Esac_ns = -10.0 - lambda_max = 1.1 - Gsac_k = (0.2882 * 800.0 / 210.0) * scale_drug_Isack # Pueyo endo - Isac_P_ns = ufl.conditional( - ufl.lt(lmbda, 1.0), - 0.0, - Gsac_ns * ((lmbda - 1.0) / (lambda_max - 1.0)) * (v - Esac_ns), + ) + values[43] = cass + dcass_dt * dt + dnass_dt = -JdiffNa + (Acap * (-(ICaNa + 3.0 * INaCa_ss))) / ((F * vss)) + values[44] = dnass_dt * dt + nass + dcai_dt = Bcai * ( + -J_TRPN + + ( + ( + (Acap * (-(Isac_P_ns / 3 + (-2.0 * INaCa_i + (ICab + IpCa))))) + / (((2.0 * F) * vmyo)) + - (Jup * vnsr) / vmyo + ) + + (Jdiff * vss) / vmyo ) - Isac_P_k = ufl.conditional( - ufl.lt(lmbda, 1.0), - 0.0, - Gsac_k - * ((lmbda - 1.0) / (lambda_max - 1.0)) - * (1.0 / (1.0 + ufl.exp((19.05 - v) / (29.98)))), + ) + values[45] = cai + dcai_dt * dt + dnai_dt = ( + Acap + * (-(Isac_P_ns / 3 + (INab + (3.0 * INaK + (3.0 * INaCa_i + (INa + INaL)))))) + ) / ((F * vmyo)) + (JdiffNa * vss) / vmyo + values[46] = dnai_dt * dt + nai + dv_dt = -( + Isac_P_k + + ( + Isac_P_ns + + ( + Istim + + ( + ICab + + ( + IpCa + + ( + IKb + + ( + INab + + ( + INaK + + ( + INaCa_ss + + ( + INaCa_i + + ( + IK1 + + ( + IKs + + ( + IKr + + ( + ICaK + + ( + ICaNa + + ( + ICaL + + ( + Ito + + (INa + INaL) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) ) + ) + values[47] = dt * dv_dt + v - # Expressions for the Istim component - Istim = 0 # amp*(ufl.le(time, duration)) + return values - # Expressions for the diffusion fluxes component - JdiffNa = 0.5 * nass - 0.5 * nai - JdiffK = 0.5 * kss - 0.5 * ki - Jdiff = 5.0 * cass - 5.0 * cai - # Expressions for the ryanodine receptor component - a_rel = 0.5 * bt - Jrel_inf = ( - -ICaL - * a_rel - / (1.0 + 25.62890625 * HF_scaling_Jrel_inf * ufl.elem_pow(1.0 / cajsr, 8.0)) - ) - tau_rel_tmp = bt / (1.0 + 0.0123 / cajsr) - tau_rel = ufl.conditional(ufl.lt(tau_rel_tmp, 0.001), 0.001, tau_rel_tmp) - F_expressions[30] = (-Jrelnp + Jrel_inf) / tau_rel - btp = 1.25 * bt - a_relp = 0.5 * btp - Jrel_infp = ( - -ICaL - * a_relp - / (1.0 + 25.62890625 * HF_scaling_Jrel_inf * ufl.elem_pow(1.0 / cajsr, 8.0)) - ) - tau_relp_tmp = btp / (1.0 + 0.0123 / cajsr) - tau_relp = ufl.conditional(ufl.lt(tau_relp_tmp, 0.001), 0.001, tau_relp_tmp) - F_expressions[31] = (-Jrelp + Jrel_infp) / tau_relp - fJrelp = 1.0 / (1.0 + KmCaMK / CaMKa) - Jrel = ((1.0 - fJrelp) * Jrelnp + Jrelp * fJrelp) * scale_popu_KRyR - - # Expressions for the calcium buffers component - Jupnp = 0.004375 * cai / (0.00092 + cai) - Jupp = 0.01203125 * cai / (0.00075 + cai) - fJupp = 1.0 / (1.0 + KmCaMK / CaMKa) - Jleak = 0.0002625 * cansr * scale_popu_Kleak * HF_scaling_Jleak - Jup = ( - -Jleak - + ((1.0 - fJupp) * Jupnp + Jupp * fJupp) - * scale_popu_KSERCA - * HF_scaling_Jup +def forward_explicit_euler(states, t, dt, parameters): + # Assign states + hL = states[0] + a = states[1] + ap = states[2] + d = states[3] + ff = states[4] + fs = states[5] + hf = states[6] + hs = states[7] + m = states[8] + xrf = states[9] + xrs = states[10] + xs1 = states[11] + CaMKt = states[12] + xk1 = states[13] + Zetaw = states[14] + XS = states[15] + XW = states[16] + TmB = states[17] + hLp = states[18] + iF = states[19] + iS = states[20] + fcaf = states[21] + fcas = states[22] + jca = states[23] + j = states[24] + fcafp = states[25] + ffp = states[26] + hsp = states[27] + jp = states[28] + mL = states[29] + xs2 = states[30] + Zetas = states[31] + nca = states[32] + CaTrpn = states[33] + iFp = states[34] + iSp = states[35] + cajsr = states[36] + cansr = states[37] + kss = states[38] + Cd = states[39] + Jrelnp = states[40] + Jrelp = states[41] + ki = states[42] + cass = states[43] + nass = states[44] + cai = states[45] + nai = states[46] + v = states[47] + + # Assign parameters + Aff = parameters[0] + Ahf = parameters[1] + BSLmax = parameters[2] + BSRmax = parameters[3] + Beta0 = parameters[4] + Beta1 = parameters[5] + CaMKo = parameters[6] + Esac_ns = parameters[7] + F = parameters[8] + GKb = parameters[9] + GNa = parameters[10] + Gncx = parameters[11] + GpCa = parameters[12] + Gsac_k = parameters[13] + Gsac_ns = parameters[14] + Gto = parameters[15] + H = parameters[16] + Khp = parameters[17] + Kki = parameters[18] + Kko = parameters[19] + KmBSL = parameters[20] + KmBSR = parameters[21] + KmCaAct = parameters[22] + KmCaM = parameters[23] + KmCaMK = parameters[24] + Kmgatp = parameters[25] + Kmn = parameters[26] + Knai0 = parameters[27] + Knao0 = parameters[28] + Knap = parameters[29] + Kxkur = parameters[30] + L = parameters[31] + MgADP = parameters[32] + MgATP = parameters[33] + PCab = parameters[34] + PKNa = parameters[35] + PNab = parameters[36] + Pnak = parameters[37] + R = parameters[38] + T = parameters[39] + Tot_A = parameters[40] + Tref = parameters[41] + Trpn50 = parameters[42] + aCaMK = parameters[43] + amp = parameters[44] + bCaMK = parameters[45] + bt = parameters[46] + calib = parameters[47] + cao = parameters[48] + cat50_ref = parameters[49] + celltype = parameters[50] + cmdnmax = parameters[51] + csqnmax = parameters[52] + dLambda = parameters[53] + delta = parameters[54] + delta_epi = parameters[55] + duration = parameters[56] + eP = parameters[57] + emcoupling = parameters[58] + etal = parameters[59] + etas = parameters[60] + gammas = parameters[61] + gammaw = parameters[62] + isacs = parameters[63] + k1m = parameters[64] + k1p = parameters[65] + k2m = parameters[66] + k2n = parameters[67] + k2p = parameters[68] + k3m = parameters[69] + k3p = parameters[70] + k4m = parameters[71] + k4p = parameters[72] + kasymm = parameters[73] + kcaoff = parameters[74] + kcaon = parameters[75] + kmcmdn = parameters[76] + kmcsqn = parameters[77] + kmtrpn = parameters[78] + kna1 = parameters[79] + kna2 = parameters[80] + kna3 = parameters[81] + ko = parameters[82] + ktrpn = parameters[83] + ku = parameters[84] + kuw = parameters[85] + kws = parameters[86] + lambda_max = parameters[87] + lmbda = parameters[88] + mode = parameters[89] + nao = parameters[90] + ntm = parameters[91] + ntrpn = parameters[92] + p_a = parameters[93] + p_b = parameters[94] + p_k = parameters[95] + phi = parameters[96] + qca = parameters[97] + qna = parameters[98] + rad = parameters[99] + rs = parameters[100] + rw = parameters[101] + scale_HF_CaMKa = parameters[102] + scale_HF_GK1 = parameters[103] + scale_HF_GNaL = parameters[104] + scale_HF_Gncx = parameters[105] + scale_HF_Gto = parameters[106] + scale_HF_Jleak = parameters[107] + scale_HF_Jrel_inf = parameters[108] + scale_HF_Jup = parameters[109] + scale_HF_Pnak = parameters[110] + scale_HF_cat50_ref = parameters[111] + scale_HF_thL = parameters[112] + scale_ICaL = parameters[113] + scale_IK1 = parameters[114] + scale_IKr = parameters[115] + scale_IKs = parameters[116] + scale_INaL = parameters[117] + scale_drug_ICaL = parameters[118] + scale_drug_ICab = parameters[119] + scale_drug_IK1 = parameters[120] + scale_drug_IKb = parameters[121] + scale_drug_IKr = parameters[122] + scale_drug_IKs = parameters[123] + scale_drug_INa = parameters[124] + scale_drug_INaL = parameters[125] + scale_drug_INab = parameters[126] + scale_drug_IpCa = parameters[127] + scale_drug_Isack = parameters[128] + scale_drug_Isacns = parameters[129] + scale_drug_Ito = parameters[130] + thL = parameters[131] + tjca = parameters[132] + trpnmax = parameters[133] + wca = parameters[134] + wna = parameters[135] + wnaca = parameters[136] + zca = parameters[137] + zk = parameters[138] + + # Assign expressions + values = numpy.zeros_like(states) + zna = 1.0 + Isac_P_k = 0 + Isac_P_ns = 0 + Afcaf = 0.3 + 0.6 / (numpy.exp((v - 10.0) / 10.0) + 1.0) + AiF = 1.0 / (numpy.exp((v - 213.6) / 151.2) + 1.0) + Axrf = 1.0 / (numpy.exp((v + 54.81) / 38.21) + 1.0) + ass = 1.0 / (numpy.exp((-(v - 14.34)) / 14.82) + 1.0) + assp = 1.0 / (numpy.exp((-(v - 24.34)) / 14.82) + 1.0) + dss = 1.0 / (numpy.exp((-(v + 3.94)) / 4.23) + 1.0) + dti_develop = 1.354 + 0.0001 / ( + numpy.exp((-(v - 12.23)) / 0.2154) + numpy.exp((v - 167.4) / 15.89) + ) + dti_recover = 1.0 - 0.5 / (numpy.exp((v + 70.0) / 20.0) + 1.0) + fss = 1.0 / (numpy.exp((v + 19.58) / 3.696) + 1.0) + hLss = 1.0 / (numpy.exp((v + 87.61) / 7.488) + 1.0) + hLssp = 1.0 / (numpy.exp((v + 93.81) / 7.488) + 1.0) + hss = 1.0 / (numpy.exp((v + 78.5) / 6.22) + 1) + hssp = 1.0 / (numpy.exp(((v + 78.5) + 6.2) / 6.22) + 1) + iss = 1.0 / (numpy.exp((v + 43.94) / 5.711) + 1.0) + mLss = 1.0 / (numpy.exp((-(v + 42.85)) / 5.264) + 1.0) + mss = 1.0 / (numpy.exp((-((v + 39.57) + 9.4)) / 7.5) + 1.0) + rkr = (1.0 * (1.0 / (numpy.exp((v + 55.0) / 75.0) + 1.0))) / ( + numpy.exp((v - 10.0) / 30.0) + 1.0 + ) + ta = 1.0515 / ( + 1.0 / ((1.2089 * (numpy.exp((-(v - 18.4099)) / 29.3814) + 1.0))) + + 3.5 / (numpy.exp((v + 100.0) / 29.3814) + 1.0) + ) + td = 0.6 + 1.0 / (numpy.exp((-0.05) * (v + 6.0)) + numpy.exp(0.09 * (v + 14.0))) + tfcaf = 7.0 + 1.0 / ( + 0.04 * numpy.exp((-(v - 4.0)) / 7.0) + 0.04 * numpy.exp((v - 4.0) / 7.0) + ) + tfcas = 100.0 + 1.0 / ( + 0.00012 * numpy.exp((-v) / 3.0) + 0.00012 * numpy.exp(v / 7.0) + ) + tff = 7.0 + 1.0 / ( + 0.0045 * numpy.exp((-(v + 20.0)) / 10.0) + 0.0045 * numpy.exp((v + 20.0) / 10.0) + ) + tfs = 1000.0 + 1.0 / ( + 3.5e-05 * numpy.exp((-(v + 5.0)) / 4.0) + 3.5e-05 * numpy.exp((v + 5.0) / 6.0) + ) + thf = 1.0 / ( + 6.149 * numpy.exp((v + 0.5096) / 20.27) + + 1.432e-05 * numpy.exp((-(v + 1.196)) / 6.285) + ) + ths = 1.0 / ( + 0.009794 * numpy.exp((-(v + 17.95)) / 28.05) + + 0.3343 * numpy.exp((v + 5.73) / 56.66) + ) + tj = 2.038 + 1.0 / ( + 0.3052 * numpy.exp((v + 0.9941) / 38.45) + + 0.02136 * numpy.exp((-(v + 100.6)) / 8.281) + ) + tm = 1.0 / ( + 6.765 * numpy.exp((v + 11.64) / 34.77) + + 8.552 * numpy.exp((-(v + 77.42)) / 5.955) + ) + txk1 = 122.2 / (numpy.exp((-(v + 127.2)) / 20.36) + numpy.exp((v + 236.8) / 69.33)) + txrf = 12.98 + 1.0 / ( + 4.123e-05 * numpy.exp((-(v - 47.78)) / 20.38) + + 0.3652 * numpy.exp((v - 31.66) / 3.869) + ) + txrs = 1.865 + 1.0 / ( + 1.128e-05 * numpy.exp((-(v - 29.74)) / 25.94) + + 0.06629 * numpy.exp((v - 34.7) / 7.355) + ) + txs1 = 817.3 + 1.0 / ( + 0.0002326 * numpy.exp((v + 48.28) / 17.8) + + 0.001292 * numpy.exp((-(v + 210.0)) / 230.0) + ) + txs2 = 1.0 / ( + 0.01 * numpy.exp((v - 50.0) / 20.0) + 0.0193 * numpy.exp((-(v + 66.54)) / 31.0) + ) + xkb = 1.0 / (numpy.exp((-(v - 14.48)) / 18.34) + 1.0) + xrss = 1.0 / (numpy.exp((-(v + 8.337)) / 6.789) + 1.0) + xs1ss = 1.0 / (numpy.exp((-(v + 11.6)) / 8.932) + 1.0) + Afs = 1.0 - Aff + Ageo = L * ((2 * 3.14) * rad) + rad * ((2 * 3.14) * rad) + vcell = L * (rad * ((3.14 * 1000) * rad)) + Ahs = 1.0 - Ahf + Aw = (Tot_A * rs) / (rs + rw * (1 - rs)) + Jupnp = (0.004375 * cai) / (cai + 0.00092) + Jupp = ((0.004375 * 2.75) * cai) / ((cai + 0.00092) - 0.00017) + KsCa = 1.0 + 0.6 / ((3.8e-05 / cai) ** 1.4 + 1.0) + Bcai = 1.0 / ((cmdnmax * kmcmdn) / (cai + kmcmdn) ** 2.0 + 1.0) + Bcajsr = 1.0 / ((csqnmax * kmcsqn) / (cajsr + kmcsqn) ** 2.0 + 1.0) + Jdiff = (-cai + cass) / 0.2 + Bcass = 1.0 / ( + (BSLmax * KmBSL) / (KmBSL + cass) ** 2.0 + + ((BSRmax * KmBSR) / (KmBSR + cass) ** 2.0 + 1.0) + ) + CaMKb = (CaMKo * (1.0 - CaMKt)) / (KmCaM / cass + 1.0) + CaTrpn_max = (CaTrpn) * (CaTrpn > 0) + (0) * numpy.logical_not((CaTrpn > 0)) + vffrt = (F * (F * v)) / ((R * T)) + vfrt = (F * v) / ((R * T)) + EK = ((R * T) / F) * numpy.log(ko / ki) + rk1 = 1.0 / (numpy.exp((-2.6 * ko + (v + 105.8)) / 9.493) + 1.0) + xk1ss = 1.0 / ( + numpy.exp((-((2.5538 * ko + v) + 144.59)) / (1.5692 * ko + 3.8115)) + 1.0 + ) + ENa = ((R * T) / F) * numpy.log(nao / nai) + EKs = ((R * T) / F) * numpy.log((PKNa * nao + ko) / (PKNa * nai + ki)) + GK1 = scale_HF_GK1 * ((0.1908 * scale_IK1) * scale_drug_IK1) + GKr = (0.046 * scale_IKr) * scale_drug_IKr + GKs = (0.0034 * scale_IKs) * scale_drug_IKs + GNaL = scale_HF_GNaL * ((0.0075 * scale_INaL) * scale_drug_INaL) + km2n = 1.0 * jca + IpCa = (cai * (GpCa * scale_drug_IpCa)) / (cai + 0.0005) + Istim = (amp) * (duration >= t) + (0) * numpy.logical_not((duration >= t)) + JdiffK = (-ki + kss) / 2.0 + JdiffNa = (-nai + nass) / 2.0 + Jtr = (-cajsr + cansr) / 100.0 + Jleak = ((0.0039375 * cansr) * scale_HF_Jleak) / 15.0 + Knai = Knai0 * numpy.exp((F * (delta * v)) / (((3.0 * R) * T))) + Knao = Knao0 * numpy.exp((F * (v * (1.0 - delta))) / (((3.0 * R) * T))) + P = eP / (((H / Khp + 1.0) + nai / Knap) + ki / Kxkur) + PCa = (0.0001 * scale_ICaL) * scale_drug_ICaL + XW_max = (XW) * (XW > 0) + (0) * numpy.logical_not((XW > 0)) + XS_max = (XS) * (XS > 0) + (0) * numpy.logical_not((XS > 0)) + XU = -XW + (-XS + (1 - TmB)) + a2 = k2p + a4 = ((MgATP * k4p) / Kmgatp) / (1.0 + MgATP / Kmgatp) + a_rel = 0.5 * bt + btp = 1.25 * bt + tau_rel_tmp = bt / (1.0 + 0.0123 / cajsr) + allo_i = 1.0 / ((KmCaAct / cai) ** 2.0 + 1.0) + allo_ss = 1.0 / ((KmCaAct / cass) ** 2.0 + 1.0) + b1 = MgADP * k1m + cs = ((kws * phi) * (rw * (1 - rs))) / rs + ksu = (kws * rw) * (-1 + 1 / rs) + cw = ((kuw * phi) * ((1 - rs) * (1 - rw))) / ((rw * (1 - rs))) + kwu = kuw * (-1 + 1 / rw) - kws + gammasu = ( + gammas * Zetas * 1 * (Zetas > 0) + + 0 + * (~(Zetas > 0)) + * numpy.logical_and.reduce( + ( + numpy.logical_or((Zetas > -1), (Zetas > 0)), + numpy.logical_or((Zetas > 0), (Zetas < -1)), + numpy.logical_or.reduce( + ((Zetas >= -1), (Zetas <= 0), (Zetas > -1 / 2)), + ), + ), ) - Jtr = 0.01 * cansr - 0.01 * cajsr - - # Expressions for the intracellular concentrations component - F_expressions[32] = JdiffNa * vss / vmyo + ( - -INa - INaL - INab - Isac_P_ns / 3.0 - 3.0 * INaCa_i - 3.0 * INaK - ) * Acap / (F * vmyo) - F_expressions[33] = -JdiffNa + (-ICaNa - 3.0 * INaCa_ss) * Acap / (F * vss) - F_expressions[34] = JdiffK * vss / vmyo + ( - -Isac_P_k - - IK1 - - IKb - - IKr - - IKs - - Istim - - Ito - - Isac_P_ns / 3.0 - + 2.0 * INaK - ) * Acap / (F * vmyo) - F_expressions[35] = -JdiffK - Acap * ICaK / (F * vss) - Bcass = 1.0 / ( - 1.0 - + BSLmax * KmBSL * ufl.elem_pow(KmBSL + cass, -2.0) - + BSRmax * KmBSR * ufl.elem_pow(KmBSR + cass, -2.0) + + (-Zetas - 1) * 1 * (Zetas < -1) + + 0 + * (~(Zetas < -1)) + * ( + ~numpy.logical_and.reduce( + ( + numpy.logical_or((Zetas > -1), (Zetas > 0)), + numpy.logical_or((Zetas > 0), (Zetas < -1)), + numpy.logical_or.reduce( + ((Zetas >= -1), (Zetas <= 0), (Zetas > -1 / 2)), + ), + ), + ) ) - F_expressions[36] = ( - -Jdiff - + Jrel * vjsr / vss - + 0.5 * (-ICaL + 2.0 * INaCa_ss) * Acap / (F * vss) - ) * Bcass - F_expressions[37] = -Jtr * vjsr / vnsr + Jup - Bcajsr = 1.0 / (1.0 + csqnmax * kmcsqn * ufl.elem_pow(kmcsqn + cajsr, -2.0)) - F_expressions[38] = (-Jrel + Jtr) * Bcajsr - - # Expressions for the mechanics component - kwu = -kws * scale_popu_kws + (kuw * scale_popu_kuw) * ( - -1.0 + 1.0 / (rw * scale_popu_rw) + ) + gammawu = gammaw * numpy.abs(Zetaw) + h10 = (nao / kna1) * (1 + nao / kna2) + (kasymm + 1.0) + h10_i = (nao / kna1) * (1.0 + nao / kna2) + (kasymm + 1.0) + h4 = (nass / kna1) * (1 + nass / kna2) + 1.0 + h4_i = (nai / kna1) * (1 + nai / kna2) + 1.0 + hca = numpy.exp((F * (qca * v)) / ((R * T))) + hna = numpy.exp((F * (qna * v)) / ((R * T))) + k2 = kcaoff + k2_i = kcaoff + k5 = kcaoff + k5_i = kcaoff + kb = (Trpn50**ntm * ku) / (-rw * (1 - rs) + (1 - rs)) + lambda_min12 = (lmbda) * (lmbda < 1.2) + (1.2) * numpy.logical_not((lmbda < 1.2)) + thLp = scale_HF_thL * (3.0 * thL) + tiF = ( + delta_epi + * ( + 1 + / ( + 0.3933 * numpy.exp((-(v + 100.0)) / 100.0) + + 0.08004 * numpy.exp((v + 50.0) / 16.59) + ) ) - ksu = ( - kws - * scale_popu_kws - * rw - * scale_popu_rw - * (-1.0 + 1.0 / (rs * scale_popu_rs)) + + 4.562 + ) + tiS = ( + delta_epi + * ( + 1 + / ( + 0.001416 * numpy.exp((-(v + 96.52)) / 59.05) + + 1.78e-08 * numpy.exp((v + 114.1) / 8.079) + ) ) - - Aw = Tot_A * rs / (rs + rw * (1 - rs)) - As = Aw - cw = kuw * phi * (1 - rw) / rw - cs = kws * phi * rw * (1 - rs) / rs - - lambda_min12 = ufl.conditional(ufl.lt(lmbda, 1.2), lmbda, 1.2) - XS = ufl.conditional(ufl.lt(XS, 0.0), 0.0, XS) - XW = ufl.conditional(ufl.lt(XW, 0.0), 0.0, XW) - - XU = 1.0 - TmB - XS - XW - gammawu = gammaw * abs(Zetaw) - # gammasu = gammas*ufl.conditional(ufl.gt(Zetas*(ufl.gt(Zetas, 0)), (-1 -\ - # Zetas)*(ufl.lt(Zetas, -1))), Zetas*(ufl.gt(Zetas, 0)), (-1 -\ - # Zetas)*(ufl.lt(Zetas, -1))) - zetas1 = Zetas * ufl.conditional(ufl.gt(Zetas, 0.0), 1.0, 0.0) - zetas2 = (-1.0 - Zetas) * ufl.conditional( - ufl.lt(Zetas, -1.0), - 1.0, - 0.0, + + 23.62 + ) + Afcas = 1.0 - Afcaf + AiS = 1.0 - AiF + Axrs = 1.0 - Axrf + fcass = fss + dhL_dt = (-hL + hLss) / ((scale_HF_thL * thL)) + values[0] = dhL_dt * dt + hL + jss = hss + da_dt = (-a + ass) / ta + values[1] = a + da_dt * dt + dap_dt = (-ap + assp) / ta + values[2] = ap + dap_dt * dt + dd_dt = (-d + dss) / td + values[3] = d + dd_dt * dt + tfcafp = 2.5 * tfcaf + tffp = 2.5 * tff + dff_dt = (-ff + fss) / tff + values[4] = dff_dt * dt + ff + dfs_dt = (-fs + fss) / tfs + values[5] = dfs_dt * dt + fs + dhf_dt = (-hf + hss) / thf + values[6] = dhf_dt * dt + hf + thsp = 3.0 * ths + dhs_dt = (-hs + hss) / ths + values[7] = dhs_dt * dt + hs + tjp = 1.46 * tj + tmL = tm + dm_dt = (-m + mss) / tm + values[8] = dm_dt * dt + m + dxrf_dt = (-xrf + xrss) / txrf + values[9] = dt * dxrf_dt + xrf + dxrs_dt = (-xrs + xrss) / txrs + values[10] = dt * dxrs_dt + xrs + xs2ss = xs1ss + dxs1_dt = (-xs1 + xs1ss) / txs1 + values[11] = dt * dxs1_dt + xs1 + f = Aff * ff + Afs * fs + fp = Aff * ffp + Afs * fs + Acap = 2 * Ageo + vjsr = 0.0048 * vcell + vmyo = 0.68 * vcell + vnsr = 0.0552 * vcell + vss = 0.02 * vcell + h = Ahf * hf + Ahs * hs + hp = Ahf * hf + Ahs * hsp + As = Aw + CaMKa = scale_HF_CaMKa * (CaMKb + CaMKt) + dCaMKt_dt = -CaMKt * bCaMK + (CaMKb * aCaMK) * (CaMKb + CaMKt) + values[12] = CaMKt + dCaMKt_dt * dt + ICab = ( + (vffrt * (4.0 * (PCab * scale_drug_ICab))) + * (cai * numpy.exp(2.0 * vfrt) - 0.341 * cao) + ) / (numpy.exp(2.0 * vfrt) - 1.0) + INab = ((vffrt * (PNab * scale_drug_INab)) * (nai * numpy.exp(vfrt) - nao)) / ( + numpy.exp(vfrt) - 1.0 + ) + PhiCaK = ((1.0 * vffrt) * (-0.75 * ko + (0.75 * kss) * numpy.exp(1.0 * vfrt))) / ( + numpy.exp(1.0 * vfrt) - 1.0 + ) + PhiCaL = ((4.0 * vffrt) * (-0.341 * cao + cass * numpy.exp(2.0 * vfrt))) / ( + numpy.exp(2.0 * vfrt) - 1.0 + ) + PhiCaNa = ( + (1.0 * vffrt) * (-0.75 * nao + (0.75 * nass) * numpy.exp(1.0 * vfrt)) + ) / (numpy.exp(1.0 * vfrt) - 1.0) + IKb = (xkb * (GKb * scale_drug_IKb)) * (-EK + v) + dxk1_dt = (-xk1 + xk1ss) / txk1 + values[13] = dt * dxk1_dt + xk1 + IK1 = (xk1 * (rk1 * (GK1 * math.sqrt(ko)))) * (-EK + v) + IKs = (xs2 * (xs1 * (GKs * KsCa))) * (-EKs + v) + anca = 1.0 / (k2n / km2n + (Kmn / cass + 1.0) ** 4.0) + a1 = (k1p * (nai / Knai) ** 3.0) / ( + ((1.0 + ki / Kki) ** 2.0 + (1.0 + nai / Knai) ** 3.0) - 1.0 + ) + b4 = (k4m * (ki / Kki) ** 2.0) / ( + ((1.0 + ki / Kki) ** 2.0 + (1.0 + nai / Knai) ** 3.0) - 1.0 + ) + a3 = (k3p * (ko / Kko) ** 2.0) / ( + ((1.0 + ko / Kko) ** 2.0 + (1.0 + nao / Knao) ** 3.0) - 1.0 + ) + b2 = (k2m * (nao / Knao) ** 3.0) / ( + ((1.0 + ko / Kko) ** 2.0 + (1.0 + nao / Knao) ** 3.0) - 1.0 + ) + b3 = (H * (P * k3m)) / (1.0 + MgATP / Kmgatp) + PCaK = 0.0003574 * PCa + PCaNa = 0.00125 * PCa + PCap = 1.1 * PCa + a_relp = 0.5 * btp + tau_relp_tmp = btp / (1.0 + 0.0123 / cajsr) + tau_rel = (0.001) * (tau_rel_tmp < 0.001) + (tau_rel_tmp) * numpy.logical_not( + (tau_rel_tmp < 0.001), + ) + dZetaw_dt = Aw * dLambda - Zetaw * cw + values[14] = Zetaw + dZetaw_dt * dt + dXS_dt = -XS * gammasu + (-XS * ksu + XW * kws) + values[15] = XS + dXS_dt * dt + dXW_dt = -XW * gammawu + (-XW * kws + (XU * kuw - XW * kwu)) + values[16] = XW + dXW_dt * dt + h11 = (nao * nao) / ((kna2 * (h10 * kna1))) + h12 = 1.0 / h10 + h11_i = (nao * nao) / ((kna2 * (h10_i * kna1))) + h12_i = 1.0 / h10_i + h5 = (nass * nass) / ((kna2 * (h4 * kna1))) + h6 = 1.0 / h4 + h5_i = (nai * nai) / ((kna2 * (h4_i * kna1))) + h6_i = 1.0 / h4_i + h1 = (nass / kna3) * (hna + 1) + 1 + h1_i = (nai / kna3) * (hna + 1) + 1 + h7 = (nao / kna3) * (1.0 + 1.0 / hna) + 1.0 + h7_i = (nao / kna3) * (1.0 + 1.0 / hna) + 1.0 + dTmB_dt = -TmB * CaTrpn ** (ntm / 2) * ku + XU * ( + kb * CaTrpn ** ((-ntm) / 2) * (CaTrpn ** ((-ntm) / 2) < 100) + + 100 * (~(CaTrpn ** ((-ntm) / 2) < 100)) + ) + values[17] = TmB + dTmB_dt * dt + C = lambda_min12 - 1 + cat50 = scale_HF_cat50_ref * (Beta1 * (lambda_min12 - 1) + cat50_ref) + lambda_min087 = (lambda_min12) * (lambda_min12 < 0.87) + (0.87) * numpy.logical_not( + (lambda_min12 < 0.87), + ) + dhLp_dt = (-hLp + hLssp) / thLp + values[18] = dhLp_dt * dt + hLp + tiFp = tiF * (dti_develop * dti_recover) + diF_dt = (-iF + iss) / tiF + values[19] = diF_dt * dt + iF + tiSp = tiS * (dti_develop * dti_recover) + diS_dt = (-iS + iss) / tiS + values[20] = diS_dt * dt + iS + fca = Afcaf * fcaf + Afcas * fcas + fcap = Afcaf * fcafp + Afcas * fcas + i = AiF * iF + AiS * iS + ip = AiF * iFp + AiS * iSp + xr = Axrf * xrf + Axrs * xrs + dfcaf_dt = (-fcaf + fcass) / tfcaf + values[21] = dfcaf_dt * dt + fcaf + dfcas_dt = (-fcas + fcass) / tfcas + values[22] = dfcas_dt * dt + fcas + djca_dt = (fcass - jca) / tjca + values[23] = djca_dt * dt + jca + dj_dt = (-j + jss) / tj + values[24] = dj_dt * dt + j + dfcafp_dt = (-fcafp + fcass) / tfcafp + values[25] = dfcafp_dt * dt + fcafp + dffp_dt = (-ffp + fss) / tffp + values[26] = dffp_dt * dt + ffp + dhsp_dt = (-hsp + hssp) / thsp + values[27] = dhsp_dt * dt + hsp + djp_dt = (-jp + jss) / tjp + values[28] = djp_dt * dt + jp + dmL_dt = (-mL + mLss) / tmL + values[29] = dmL_dt * dt + mL + dxs2_dt = (-xs2 + xs2ss) / txs2 + values[30] = dt * dxs2_dt + xs2 + dZetas_dt = As * dLambda - Zetas * cs + values[31] = Zetas + dZetas_dt * dt + fICaLp = 1.0 / (1.0 + KmCaMK / CaMKa) + fINaLp = 1.0 / (1.0 + KmCaMK / CaMKa) + fINap = 1.0 / (1.0 + KmCaMK / CaMKa) + fItop = 1.0 / (1.0 + KmCaMK / CaMKa) + fJrelp = 1.0 / (1.0 + KmCaMK / CaMKa) + fJupp = 1.0 / (1.0 + KmCaMK / CaMKa) + dnca_dt = anca * k2n - km2n * nca + values[32] = dnca_dt * dt + nca + x2 = b4 * (a2 * a3) + (b4 * (a3 * b1) + (a3 * (a1 * a2) + b4 * (b1 * b2))) + x1 = a2 * (a1 * b3) + (b3 * (a2 * b4) + (a2 * (a1 * a4) + b3 * (b2 * b4))) + x3 = b1 * (a3 * a4) + (a4 * (b1 * b2) + (a4 * (a2 * a3) + b1 * (b2 * b3))) + x4 = a1 * (b2 * b3) + (a1 * (a4 * b2) + (a1 * (a3 * a4) + b2 * (b3 * b4))) + PCaKp = 0.0003574 * PCap + PCaNap = 0.00125 * PCap + tau_relp = (0.001) * (tau_relp_tmp < 0.001) + (tau_relp_tmp) * numpy.logical_not( + (tau_relp_tmp < 0.001), + ) + k1 = kcaon * (cao * h12) + k1_i = kcaon * (cao * h12_i) + k6 = kcaon * (cass * h6) + k6_i = kcaon * (cai * h6_i) + h2 = (hna * nass) / ((h1 * kna3)) + h3 = 1.0 / h1 + h2_i = (hna * nai) / ((h1_i * kna3)) + h3_i = 1.0 / h1_i + h8 = nao / ((h7 * (hna * kna3))) + h9 = 1.0 / h7 + h8_i = nao / ((h7_i * (hna * kna3))) + h9_i = 1.0 / h7_i + F1 = numpy.exp(C * p_b) - 1 + dCd = C - Cd + dCaTrpn_dt = ktrpn * (-CaTrpn + ((1000 * cai) / cat50) ** ntrpn * (1 - CaTrpn)) + values[33] = CaTrpn + dCaTrpn_dt * dt + h_lambda_prima = Beta0 * ((lambda_min087 + lambda_min12) - 1.87) + 1 + diFp_dt = (-iFp + iss) / tiFp + values[34] = diFp_dt * dt + iFp + diSp_dt = (-iSp + iss) / tiSp + values[35] = diSp_dt * dt + iSp + IKr = (rkr * (xr * (GKr * (0.4303314829119352 * math.sqrt(ko))))) * (-EK + v) + ICaL = (d * (PhiCaL * (PCa * (1.0 - fICaLp)))) * ( + f * (1.0 - nca) + nca * (fca * jca) + ) + (d * (PhiCaL * (PCap * fICaLp))) * (fp * (1.0 - nca) + nca * (fcap * jca)) + INaL = (mL * (GNaL * (-ENa + v))) * (fINaLp * hLp + hL * (1.0 - fINaLp)) + INa = (m**3.0 * ((GNa * scale_drug_INa) * (-ENa + v))) * ( + j * (h * (1.0 - fINap)) + jp * (fINap * hp) + ) + Ito = ((scale_HF_Gto * (Gto * scale_drug_Ito)) * (-EK + v)) * ( + i * (a * (1.0 - fItop)) + ip * (ap * fItop) + ) + Jrel = Jrelnp * (1.0 - fJrelp) + Jrelp * fJrelp + Jup = -Jleak + (Jupnp * (1.0 - fJupp) + scale_HF_Jup * (Jupp * fJupp)) + E1 = x1 / (x4 + (x3 + (x1 + x2))) + E2 = x2 / (x4 + (x3 + (x1 + x2))) + E3 = x3 / (x4 + (x3 + (x1 + x2))) + E4 = x4 / (x4 + (x3 + (x1 + x2))) + ICaK = (d * (PhiCaK * (PCaK * (1.0 - fICaLp)))) * ( + f * (1.0 - nca) + nca * (fca * jca) + ) + (d * (PhiCaK * (PCaKp * fICaLp))) * (fp * (1.0 - nca) + nca * (fcap * jca)) + ICaNa = (d * (PhiCaNa * (PCaNa * (1.0 - fICaLp)))) * ( + f * (1.0 - nca) + nca * (fca * jca) + ) + (d * (PhiCaNa * (PCaNap * fICaLp))) * (fp * (1.0 - nca) + nca * (fcap * jca)) + k4pp = h2 * wnaca + k7 = wna * (h2 * h5) + k4p_ss = (h3 * wca) / hca + k4pp_i = h2_i * wnaca + k7_i = wna * (h2_i * h5_i) + k4p_i = (h3_i * wca) / hca + k3pp = h8 * wnaca + k8 = wna * (h11 * h8) + k3p_ss = h9 * wca + k3pp_i = h8_i * wnaca + k8_i = wna * (h11_i * h8_i) + k3p_i = h9_i * wca + eta = (etas) * (dCd < 0) + (etal) * numpy.logical_not((dCd < 0)) + J_TRPN = dCaTrpn_dt * trpnmax + h_lambda = (h_lambda_prima) * (h_lambda_prima > 0) + (0) * numpy.logical_not( + (h_lambda_prima > 0), + ) + Jrel_inf = ((-ICaL) * a_rel) / (((1.5 * scale_HF_Jrel_inf) / cajsr) ** 8.0 + 1.0) + Jrel_infp = ((-ICaL) * a_relp) / (((1.5 * scale_HF_Jrel_inf) / cajsr) ** 8.0 + 1.0) + dcajsr_dt = Bcajsr * (-Jrel + Jtr) + values[36] = cajsr + dcajsr_dt * dt + dcansr_dt = Jup - (Jtr * vjsr) / vnsr + values[37] = cansr + dcansr_dt * dt + JnakNa = 3.0 * (E1 * a3 - E2 * b3) + JnakK = 2.0 * (-E3 * a1 + E4 * b1) + dkss_dt = -JdiffK + (Acap * (-ICaK)) / ((F * vss)) + values[38] = dkss_dt * dt + kss + k4 = k4p_ss + k4pp + k4_i = k4p_i + k4pp_i + k3 = k3p_ss + k3pp + k3_i = k3p_i + k3pp_i + Fd = dCd * eta + dCd_dt = (p_k * (C - Cd)) / eta + values[39] = Cd + dCd_dt * dt + Ta = (h_lambda * (Tref / rs)) * (XS * (Zetas + 1) + XW * Zetaw) + dJrelnp_dt = (Jrel_inf - Jrelnp) / tau_rel + values[40] = Jrelnp + dJrelnp_dt * dt + dJrelp_dt = (Jrel_infp - Jrelp) / tau_relp + values[41] = Jrelp + dJrelp_dt * dt + INaK = (Pnak * scale_HF_Pnak) * (JnakK * zk + JnakNa * zna) + x2_ss = (k1 * k7) * (k4 + k5) + (k4 * k6) * (k1 + k8) + x2_i = (k1_i * k7_i) * (k4_i + k5_i) + (k4_i * k6_i) * (k1_i + k8_i) + x1_ss = (k2 * k4) * (k6 + k7) + (k5 * k7) * (k2 + k3) + x3_ss = (k1 * k3) * (k6 + k7) + (k6 * k8) * (k2 + k3) + x4_ss = (k2 * k8) * (k4 + k5) + (k3 * k5) * (k1 + k8) + x1_i = (k2_i * k4_i) * (k6_i + k7_i) + (k5_i * k7_i) * (k2_i + k3_i) + x3_i = (k1_i * k3_i) * (k6_i + k7_i) + (k6_i * k8_i) * (k2_i + k3_i) + x4_i = (k2_i * k8_i) * (k4_i + k5_i) + (k3_i * k5_i) * (k1_i + k8_i) + Tp = p_a * (F1 + Fd) + dki_dt = ( + Acap + * ( + -( + -2.0 * INaK + + ( + Istim + + (Isac_P_ns / 3 + (Isac_P_k + (IKb + (IK1 + (IKs + (IKr + Ito)))))) + ) + ) ) - gammasu = gammas * Max(zetas1, zetas2) - - F_expressions[39] = kws * scale_popu_kws * XW - XS * gammasu - XS * ksu - F_expressions[40] = ( - kuw * scale_popu_kuw * XU - - kws * scale_popu_kws * XW - - XW * gammawu - - XW * kwu + ) / ((F * vmyo)) + (JdiffK * vss) / vmyo + values[42] = dki_dt * dt + ki + E1_ss = x1_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) + E2_ss = x2_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) + E3_ss = x3_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) + E4_ss = x4_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) + E1_i = x1_i / (x4_i + (x3_i + (x1_i + x2_i))) + E2_i = x2_i / (x4_i + (x3_i + (x1_i + x2_i))) + E3_i = x3_i / (x4_i + (x3_i + (x1_i + x2_i))) + E4_i = x4_i / (x4_i + (x3_i + (x1_i + x2_i))) + Ttot = Ta + Tp + JncxCa_ss = -E1_ss * k1 + E2_ss * k2 + JncxNa_ss = -E2_ss * k3pp + (E3_ss * k4pp + 3.0 * (-E1_ss * k8 + E4_ss * k7)) + JncxCa_i = -E1_i * k1_i + E2_i * k2_i + JncxNa_i = -E2_i * k3pp_i + (E3_i * k4pp_i + 3.0 * (-E1_i * k8_i + E4_i * k7_i)) + INaCa_ss = (allo_ss * ((0.2 * Gncx) * scale_HF_Gncx)) * ( + JncxCa_ss * zca + JncxNa_ss * zna + ) + INaCa_i = (allo_i * ((0.8 * Gncx) * scale_HF_Gncx)) * ( + JncxCa_i * zca + JncxNa_i * zna + ) + dcass_dt = Bcass * ( + -Jdiff + + ( + (Acap * (-(ICaL - 2.0 * INaCa_ss))) / (((2.0 * F) * vss)) + + (Jrel * vjsr) / vss ) - cat50 = ( - cat50_ref * scale_popu_CaT50ref + Beta1 * (-1.0 + lambda_min12) - ) * HF_scaling_cat50_ref - CaTrpn = ufl.conditional(ufl.lt(CaTrpn, 0.0), 0.0, CaTrpn) - F_expressions[41] = ( - ktrpn - * scale_popu_kTRPN - * ( - -CaTrpn - + ufl.elem_pow(1000.0 * cai / cat50, ntrpn * scale_popu_nTRPN) - * (1.0 - CaTrpn) + ) + values[43] = cass + dcass_dt * dt + dnass_dt = -JdiffNa + (Acap * (-(ICaNa + 3.0 * INaCa_ss))) / ((F * vss)) + values[44] = dnass_dt * dt + nass + dcai_dt = Bcai * ( + -J_TRPN + + ( + ( + (Acap * (-(Isac_P_ns / 3 + (-2.0 * INaCa_i + (ICab + IpCa))))) + / (((2.0 * F) * vmyo)) + - (Jup * vnsr) / vmyo ) + + (Jdiff * vss) / vmyo ) - kb = ( - ku - * scale_popu_ku - * ufl.elem_pow(Trpn50 * scale_popu_TRPN50, (ntm * scale_popu_nTm)) - / ( - 1.0 - - (rs * scale_popu_rs) - - rw * scale_popu_rw * (1.0 - (rs * scale_popu_rs)) + ) + values[45] = cai + dcai_dt * dt + dnai_dt = ( + Acap + * (-(Isac_P_ns / 3 + (INab + (3.0 * INaK + (3.0 * INaCa_i + (INa + INaL)))))) + ) / ((F * vmyo)) + (JdiffNa * vss) / vmyo + values[46] = dnai_dt * dt + nai + dv_dt = -( + Isac_P_k + + ( + Isac_P_ns + + ( + Istim + + ( + ICab + + ( + IpCa + + ( + IKb + + ( + INab + + ( + INaK + + ( + INaCa_ss + + ( + INaCa_i + + ( + IK1 + + ( + IKs + + ( + IKr + + ( + ICaK + + ( + ICaNa + + ( + ICaL + + ( + Ito + + (INa + INaL) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) ) ) + ) + values[47] = dt * dv_dt + v - F_expressions[42] = ( - ufl.conditional( - ufl.lt(ufl.elem_pow(CaTrpn, -(ntm * scale_popu_nTm) / 2.0), 100.0), - ufl.elem_pow(CaTrpn, -(ntm * scale_popu_nTm) / 2.0), - 100.0, - ) - * XU - * kb - - ku - * scale_popu_ku - * ufl.elem_pow(CaTrpn, (ntm * scale_popu_nTm) / 2.0) - * TmB - ) + return values + + +# """This module contains a ORdmm_Land_em_coupling cardiac cell model + +# The module was autogenerated from a gotran ode file +# """ +# from collections import OrderedDict +# from typing import Dict + +# import dolfin + +# try: +# import ufl_legacy as ufl +# except ImportError: +# import ufl +# from dolfin import as_vector +# from dolfin import Constant + +# from ... import utils +# from ..cell_model import BaseCellModel + +# logger = utils.getLogger(__name__) + + +# def Max(a, b): +# return (a + b + abs(a - b)) / Constant(2.0) + + +# def Min(a, b): +# return (a + b - abs(a - b)) / Constant(2.0) + + +# class ORdmmLandPureEp(BaseCellModel): +# def __init__(self, params=None, init_conditions=None, **kwargs): +# """ +# Create cardiac cell model + +# *Arguments* +# params (dict, :py:class:`dolfin.Mesh`, optional) +# optional model parameters +# init_conditions (dict, :py:class:`dolfin.Mesh`, optional) +# optional initial conditions +# """ +# logger.debug("Initialize ORdmm Land model") + +# super().__init__(params, init_conditions) + +# @staticmethod +# def update_disease_parameters( +# params: Dict[str, float], +# disease_state: str = "healthy", +# ) -> None: +# if disease_state.lower() == "hf": +# logger.info("Update scaling parameters for heart failure model") +# params["HF_scaling_CaMKa"] = 1.50 +# params["HF_scaling_Jrel_inf"] = pow(0.8, 8.0) +# params["HF_scaling_Jleak"] = 1.3 +# params["HF_scaling_Jup"] = 0.45 +# params["HF_scaling_GNaL"] = 1.3 +# params["HF_scaling_GK1"] = 0.68 +# params["HF_scaling_thL"] = 1.8 +# params["HF_scaling_Gto"] = 0.4 +# params["HF_scaling_Gncx"] = 1.6 +# params["HF_scaling_Pnak"] = 0.7 +# params["HF_scaling_cat50_ref"] = 0.6 + +# @staticmethod +# def default_parameters() -> Dict[str, float]: +# """Set-up and return default parameters. + +# Parameters +# ---------- +# disease_state : str, optional +# String with "hf" or "healthy", by default "healthy". +# If "hf", then parameters representing heart failure +# will be used. + +# Returns +# ------- +# OrderedDict +# Dictionary with default values +# """ +# params = OrderedDict( +# [ +# ("scale_ICaL", 1.018), +# ("scale_IK1", 1.414), +# ("scale_IKr", 1.119), +# ("scale_IKs", 1.648), +# ("scale_INaL", 2.274), +# ("celltype", 0), +# ("cao", 1.8), +# ("ko", 5.4), +# ("nao", 140.0), +# ("F", 96485.0), +# ("R", 8314.0), +# ("T", 310.0), +# ("L", 0.01), +# ("rad", 0.0011), +# ("Ahf", 0.99), +# ("GNa", 31), +# ("thL", 200.0), +# ("Gto", 0.02), +# ("delta_epi", 1.0), +# ("Aff", 0.6), +# ("Kmn", 0.002), +# ("k2n", 1000.0), +# ("tjca", 75.0), +# ("zca", 2.0), +# ("bt", 4.75), +# ("Beta0", 2.3), +# ("Beta1", -2.4), +# ("Tot_A", 25), +# ("Tref", 120), +# ("Trpn50", 0.35), +# ("calib", 1), +# ("cat50_ref", 0.805), +# ("emcoupling", 1), +# ("etal", 200), +# ("etas", 20), +# ("gammas", 0.0085), +# ("gammaw", 0.615), +# ("isacs", 0), +# ("ktrpn", 0.1), +# ("ku", 0.04), +# ("kuw", 0.182), +# ("kws", 0.012), +# ("mode", 1), +# ("ntm", 2.4), +# ("ntrpn", 2.0), +# ("p_a", 2.1), +# ("p_b", 9.1), +# ("p_k", 7.0), +# ("phi", 2.23), +# ("rs", 0.25), +# ("rw", 0.5), +# ("CaMKo", 0.05), +# ("KmCaM", 0.0015), +# ("KmCaMK", 0.15), +# ("aCaMK", 0.05), +# ("bCaMK", 0.00068), +# ("PKNa", 0.01833), +# ("Gncx", 0.0008), +# ("KmCaAct", 0.00015), +# ("kasymm", 12.5), +# ("kcaoff", 5000.0), +# ("kcaon", 1500000.0), +# ("kna1", 15.0), +# ("kna2", 5.0), +# ("kna3", 88.12), +# ("qca", 0.167), +# ("qna", 0.5224), +# ("wca", 60000.0), +# ("wna", 60000.0), +# ("wnaca", 5000.0), +# ("H", 1e-07), +# ("Khp", 1.698e-07), +# ("Kki", 0.5), +# ("Kko", 0.3582), +# ("Kmgatp", 1.698e-07), +# ("Knai0", 9.073), +# ("Knao0", 27.78), +# ("Knap", 224.0), +# ("Kxkur", 292.0), +# ("MgADP", 0.05), +# ("MgATP", 9.8), +# ("Pnak", 30.0), +# ("delta", -0.155), +# ("eP", 4.2), +# ("k1m", 182.4), +# ("k1p", 949.5), +# ("k2m", 39.4), +# ("k2p", 687.2), +# ("k3m", 79300.0), +# ("k3p", 1899.0), +# ("k4m", 40.0), +# ("k4p", 639.0), +# ("zk", 1.0), +# ("GKb", 0.003), +# ("PNab", 3.75e-10), +# ("PCab", 2.5e-08), +# ("GpCa", 0.0005), +# ("Esac_ns", -10.0), +# ("Gsac_k", 1.097904761904762), +# ("Gsac_ns", 0.006), +# ("lambda_max", 1.1), +# ("amp", -80.0), +# ("duration", 0.5), +# ("BSLmax", 1.124), +# ("BSRmax", 0.047), +# ("KmBSL", 0.0087), +# ("KmBSR", 0.00087), +# ("cmdnmax", 0.05), +# ("csqnmax", 10.0), +# ("kmcmdn", 0.00238), +# ("kmcsqn", 0.8), +# ("kmtrpn", 0.0005), +# ("trpnmax", 0.07), +# ("lmbda", 1.0), +# ("dLambda", 0.0), +# # Drug factors +# ("scale_drug_INa", 1.0), +# ("scale_drug_INaL", 1.0), +# ("scale_drug_Ito", 1.0), +# ("scale_drug_ICaL", 1.0), +# ("scale_drug_IKr", 1.0), +# ("scale_drug_IKs", 1.0), +# ("scale_drug_IK1", 1.0), +# ("scale_drug_IKb", 1.0), +# ("scale_drug_INab", 1.0), +# ("scale_drug_ICab", 1.0), +# ("scale_drug_IpCa", 1.0), +# ("scale_drug_Isacns", 1.0), +# ("scale_drug_Isack", 1.0), +# # Population factors +# ("scale_popu_GNa", 1.0), +# ("scale_popu_GCaL", 1.0), +# ("scale_popu_Gto", 1.0), +# ("scale_popu_GNaL", 1.0), +# ("scale_popu_GKr", 1.0), +# ("scale_popu_GKs", 1.0), +# ("scale_popu_GK1", 1.0), +# ("scale_popu_GbK", 1.0), +# ("scale_popu_KNCX", 1.0), +# ("scale_popu_KNaK", 1.0), +# ("scale_popu_GbNa", 1.0), +# ("scale_popu_GbCa", 1.0), +# ("scale_popu_KpCa", 1.0), +# ("scale_popu_KRyR", 1.0), +# ("scale_popu_KSERCA", 1.0), +# ("scale_popu_Kleak", 1.0), +# ("scale_popu_nTm", 1.0), +# ("scale_popu_CaT50ref", 1.0), +# ("scale_popu_Tref", 1.0), +# ("scale_popu_kuw", 1.0), +# ("scale_popu_kws", 1.0), +# ("scale_popu_kTRPN", 1.0), +# ("scale_popu_nTRPN", 1.0), +# ("scale_popu_ku", 1.0), +# ("scale_popu_TRPN50", 1.0), +# ("scale_popu_rw", 1.0), +# ("scale_popu_rs", 1.0), +# # HF scaling factors +# ("HF_scaling_CaMKa", 1.0), +# ("HF_scaling_Jrel_inf", 1.0), +# ("HF_scaling_Jleak", 1.0), +# ("HF_scaling_Jup", 1.0), +# ("HF_scaling_GNaL", 1.0), +# ("HF_scaling_GK1", 1.0), +# ("HF_scaling_thL", 1.0), +# ("HF_scaling_Gto", 1.0), +# ("HF_scaling_Gncx", 1.0), +# ("HF_scaling_Pnak", 1.0), +# ("HF_scaling_cat50_ref", 1.0), +# ], +# ) + +# return params + +# @staticmethod +# def default_initial_conditions(): +# "Set-up and return default initial conditions." +# ic = OrderedDict( +# [ +# ("v", -87), +# ("CaMKt", 0), +# ("m", 0), +# ("hf", 1), +# ("hs", 1), +# ("j", 1), +# ("hsp", 1), +# ("jp", 1), +# ("mL", 0), +# ("hL", 1), +# ("hLp", 1), +# ("a", 0), +# ("iF", 1), +# ("iS", 1), +# ("ap", 0), +# ("iFp", 1), +# ("iSp", 1), +# ("d", 0), +# ("ff", 1), +# ("fs", 1), +# ("fcaf", 1), +# ("fcas", 1), +# ("jca", 1), +# ("ffp", 1), +# ("fcafp", 1), +# ("nca", 0), +# ("xrf", 0), +# ("xrs", 0), +# ("xs1", 0), +# ("xs2", 0), +# ("xk1", 1), +# ("Jrelnp", 0), +# ("Jrelp", 0), +# ("nai", 7), +# ("nass", 7), +# ("ki", 145), +# ("kss", 145), +# ("cass", 0.0001), +# ("cansr", 1.2), +# ("cajsr", 1.2), +# ("XS", 0), +# ("XW", 0), +# ("CaTrpn", 0), +# ("TmB", 1), +# ("Cd", 0), +# ("cai", 0.0001), +# ("Zetas", 0), +# ("Zetaw", 0), +# ], +# ) +# return ic + +# def _I(self, v, s, time): +# """ +# Original gotran transmembrane current dV/dt +# """ +# time = time if time else Constant(0.0) +# logger.debug("Evaluate transmembrane current") +# # Assign states +# assert len(s) == 47 +# ( +# CaMKt, +# m, +# hf, +# hs, +# j, +# hsp, +# jp, +# mL, +# hL, +# hLp, +# a, +# iF, +# iS, +# ap, +# iFp, +# iSp, +# d, +# ff, +# fs, +# fcaf, +# fcas, +# jca, +# ffp, +# fcafp, +# nca, +# xrf, +# xrs, +# xs1, +# xs2, +# xk1, +# Jrelnp, +# Jrelp, +# nai, +# nass, +# ki, +# kss, +# cass, +# cansr, +# cajsr, +# XS, +# XW, +# CaTrpn, +# TmB, +# Cd, +# cai, +# Zetas, +# Zetaw, +# ) = s + +# # Assign parameters +# scale_ICaL = self._parameters["scale_ICaL"] +# scale_IK1 = self._parameters["scale_IK1"] +# scale_IKr = self._parameters["scale_IKr"] +# scale_IKs = self._parameters["scale_IKs"] +# scale_INaL = self._parameters["scale_INaL"] +# cao = self._parameters["cao"] +# ko = self._parameters["ko"] +# nao = self._parameters["nao"] +# F = self._parameters["F"] +# R = self._parameters["R"] +# T = self._parameters["T"] +# CaMKo = self._parameters["CaMKo"] +# KmCaM = self._parameters["KmCaM"] +# KmCaMK = self._parameters["KmCaMK"] +# PKNa = self._parameters["PKNa"] +# Ahf = self._parameters["Ahf"] +# GNa = self._parameters["GNa"] +# Gto = self._parameters["Gto"] +# Aff = self._parameters["Aff"] +# zca = self._parameters["zca"] +# Gncx = self._parameters["Gncx"] +# KmCaAct = self._parameters["KmCaAct"] +# kasymm = self._parameters["kasymm"] +# kcaoff = self._parameters["kcaoff"] +# kcaon = self._parameters["kcaon"] +# kna1 = self._parameters["kna1"] +# kna2 = self._parameters["kna2"] +# kna3 = self._parameters["kna3"] +# qca = self._parameters["qca"] +# qna = self._parameters["qna"] +# wca = self._parameters["wca"] +# wna = self._parameters["wna"] +# wnaca = self._parameters["wnaca"] +# H = self._parameters["H"] +# Khp = self._parameters["Khp"] +# Kki = self._parameters["Kki"] +# Kko = self._parameters["Kko"] +# Kmgatp = self._parameters["Kmgatp"] +# Knai0 = self._parameters["Knai0"] +# Knao0 = self._parameters["Knao0"] +# Knap = self._parameters["Knap"] +# Kxkur = self._parameters["Kxkur"] +# MgADP = self._parameters["MgADP"] +# MgATP = self._parameters["MgATP"] +# Pnak = self._parameters["Pnak"] +# delta = self._parameters["delta"] +# eP = self._parameters["eP"] +# k1m = self._parameters["k1m"] +# k1p = self._parameters["k1p"] +# k2m = self._parameters["k2m"] +# k2p = self._parameters["k2p"] +# k3m = self._parameters["k3m"] +# k3p = self._parameters["k3p"] +# k4m = self._parameters["k4m"] +# k4p = self._parameters["k4p"] +# zk = self._parameters["zk"] +# GKb = self._parameters["GKb"] +# PNab = self._parameters["PNab"] +# PCab = self._parameters["PCab"] +# GpCa = self._parameters["GpCa"] +# lmbda = self._parameters["lmbda"] +# # Drug factor +# scale_drug_INa = self._parameters["scale_drug_INa"] +# scale_drug_INaL = self._parameters["scale_drug_INaL"] +# scale_drug_Ito = self._parameters["scale_drug_Ito"] +# scale_drug_ICaL = self._parameters["scale_drug_ICaL"] +# scale_drug_IKr = self._parameters["scale_drug_IKr"] +# scale_drug_IKs = self._parameters["scale_drug_IKs"] +# scale_drug_IK1 = self._parameters["scale_drug_IK1"] +# scale_drug_IKb = self._parameters["scale_drug_IKb"] +# scale_drug_INab = self._parameters["scale_drug_INab"] +# scale_drug_ICab = self._parameters["scale_drug_ICab"] +# scale_drug_IpCa = self._parameters["scale_drug_IpCa"] +# scale_drug_Isacns = self._parameters["scale_drug_Isacns"] +# scale_drug_Isack = self._parameters["scale_drug_Isack"] +# # Population factors +# scale_popu_GNa = self._parameters["scale_popu_GNa"] +# scale_popu_GCaL = self._parameters["scale_popu_GCaL"] +# scale_popu_Gto = self._parameters["scale_popu_Gto"] +# scale_popu_GNaL = self._parameters["scale_popu_GNaL"] +# scale_popu_GKr = self._parameters["scale_popu_GKr"] +# scale_popu_GKs = self._parameters["scale_popu_GKs"] +# scale_popu_GK1 = self._parameters["scale_popu_GK1"] +# scale_popu_GbK = self._parameters["scale_popu_GbK"] +# scale_popu_KNCX = self._parameters["scale_popu_KNCX"] +# scale_popu_KNaK = self._parameters["scale_popu_KNaK"] +# scale_popu_GbNa = self._parameters["scale_popu_GbNa"] +# scale_popu_GbCa = self._parameters["scale_popu_GbCa"] +# scale_popu_KpCa = self._parameters["scale_popu_KpCa"] +# # Systolic Heart Failure (HF with preserved ejection fraction) +# HF_scaling_CaMKa = self._parameters["HF_scaling_CaMKa"] +# HF_scaling_GNaL = self._parameters["HF_scaling_GNaL"] +# HF_scaling_GK1 = self._parameters["HF_scaling_GK1"] +# HF_scaling_Gto = self._parameters["HF_scaling_Gto"] +# HF_scaling_Gncx = self._parameters["HF_scaling_Gncx"] +# HF_scaling_Pnak = self._parameters["HF_scaling_Pnak"] + +# # Init return args +# current = [ufl.zero()] * 1 + +# # Expressions for the CaMKt component +# CaMKb = CaMKo * (1.0 - CaMKt) / (1.0 + KmCaM / cass) +# CaMKa = (CaMKb + CaMKt) * HF_scaling_CaMKa + +# # Expressions for the reversal potentials component +# ENa = R * T * ufl.ln(nao / nai) / F +# EK = R * T * ufl.ln(ko / ki) / F +# EKs = R * T * ufl.ln((ko + PKNa * nao) / (PKNa * nai + ki)) / F +# vffrt = (F * F) * v / (R * T) +# vfrt = F * v / (R * T) + +# # Expressions for the I_Na component +# Ahs = 1.0 - Ahf +# h = Ahf * hf + Ahs * hs +# hp = Ahf * hf + Ahs * hsp +# fINap = 1.0 / (1.0 + KmCaMK / CaMKa) +# INa = ( +# GNa +# * scale_drug_INa +# * scale_popu_GNa +# * ufl.elem_pow(m, 3.0) +# * (-ENa + v) +# * ((1.0 - fINap) * h * j + fINap * hp * jp) +# ) + +# # Expressions for the INaL component +# GNaL = 0.0075 * scale_INaL * scale_drug_INaL * scale_popu_GNaL * HF_scaling_GNaL +# fINaLp = 1.0 / (1.0 + KmCaMK / CaMKa) +# INaL = (-ENa + v) * ((1.0 - fINaLp) * hL + fINaLp * hLp) * GNaL * mL + +# # Expressions for the Ito component +# AiF = 1.0 / (1.0 + 0.24348537187522867 * ufl.exp(0.006613756613756614 * v)) +# AiS = 1.0 - AiF +# i = AiF * iF + AiS * iS +# ip = AiF * iFp + AiS * iSp +# fItop = 1.0 / (1.0 + KmCaMK / CaMKa) +# Ito = ( +# Gto +# * scale_drug_Ito +# * scale_popu_Gto +# * HF_scaling_Gto +# * (-EK + v) +# * ((1.0 - fItop) * a * i + ap * fItop * ip) +# ) + +# # Expressions for the ICaL ICaNa ICaK component +# Afs = 1.0 - Aff +# f = Aff * ff + Afs * fs +# Afcaf = 0.3 + 0.6 / (1.0 + 0.36787944117144233 * ufl.exp(0.1 * v)) +# Afcas = 1.0 - Afcaf +# fca = Afcaf * fcaf + Afcas * fcas +# fp = Aff * ffp + Afs * fs +# fcap = Afcaf * fcafp + Afcas * fcas +# PhiCaL = ( +# 4.0 +# * (-0.341 * cao + cass * ufl.exp(2.0 * vfrt)) +# * vffrt +# / (-1.0 + ufl.exp(2.0 * vfrt)) +# ) +# PhiCaNa = ( +# 1.0 +# * (-0.75 * nao + 0.75 * ufl.exp(1.0 * vfrt) * nass) +# * vffrt +# / (-1.0 + ufl.exp(1.0 * vfrt)) +# ) +# PhiCaK = ( +# 1.0 +# * (-0.75 * ko + 0.75 * ufl.exp(1.0 * vfrt) * kss) +# * vffrt +# / (-1.0 + ufl.exp(1.0 * vfrt)) +# ) +# PCa = 0.0001 * scale_ICaL * scale_drug_ICaL * scale_popu_GCaL +# PCap = 1.1 * PCa +# PCaNa = 0.00125 * PCa +# PCaK = 0.0003574 * PCa +# PCaNap = 0.00125 * PCap +# PCaKp = 0.0003574 * PCap +# fICaLp = 1.0 / (1.0 + KmCaMK / CaMKa) +# ICaL = (1.0 - fICaLp) * ( +# (1.0 - nca) * f + fca * jca * nca +# ) * PCa * PhiCaL * d + ( +# (1.0 - nca) * fp + fcap * jca * nca +# ) * PCap * PhiCaL * d * fICaLp +# ICaNa = (1.0 - fICaLp) * ( +# (1.0 - nca) * f + fca * jca * nca +# ) * PCaNa * PhiCaNa * d + ( +# (1.0 - nca) * fp + fcap * jca * nca +# ) * PCaNap * PhiCaNa * d * fICaLp +# ICaK = (1.0 - fICaLp) * ( +# (1.0 - nca) * f + fca * jca * nca +# ) * PCaK * PhiCaK * d + ( +# (1.0 - nca) * fp + fcap * jca * nca +# ) * PCaKp * PhiCaK * d * fICaLp + +# # Expressions for the IKr component +# Axrf = 1.0 / (1.0 + 4.197299094734718 * ufl.exp(0.02617115938236064 * v)) +# Axrs = 1.0 - Axrf +# xr = Axrf * xrf + Axrs * xrs +# rkr = 1.0 / ( +# (1.0 + 2.0820090840784555 * ufl.exp(0.013333333333333334 * v)) +# * (1.0 + 0.7165313105737893 * ufl.exp(0.03333333333333333 * v)) +# ) +# GKr = 0.046 * scale_IKr * scale_drug_IKr * scale_popu_GKr +# IKr = 0.4303314829119352 * ufl.sqrt(ko) * (-EK + v) * GKr * rkr * xr + +# # Expressions for the IKs component +# KsCa = 1.0 + 0.6 / (1.0 + 6.481821026062645e-07 * ufl.elem_pow(1.0 / cai, 1.4)) +# GKs = 0.0034 * scale_IKs * scale_drug_IKs * scale_popu_GKs +# IKs = (-EKs + v) * GKs * KsCa * xs1 * xs2 +# rk1 = 1.0 / ( +# 1.0 +# + 69220.6322106767 +# * ufl.exp(0.10534077741493732 * v - 0.27388602127883704 * ko) +# ) +# GK1 = 0.1908 * scale_IK1 * scale_drug_IK1 * scale_popu_GK1 * HF_scaling_GK1 +# IK1 = ufl.sqrt(ko) * (-EK + v) * GK1 * rk1 * xk1 + +# # Expressions for the INaCa_i component +# hca = ufl.exp(F * qca * v / (R * T)) +# hna = ufl.exp(F * qna * v / (R * T)) +# h1_i = 1 + (1 + hna) * nai / kna3 +# h2_i = hna * nai / (kna3 * h1_i) +# h3_i = 1.0 / h1_i +# h4_i = 1.0 + (1 + nai / kna2) * nai / kna1 +# h5_i = (nai * nai) / (kna1 * kna2 * h4_i) +# h6_i = 1.0 / h4_i +# h7_i = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 +# h8_i = nao / (kna3 * h7_i * hna) +# h9_i = 1.0 / h7_i +# h10_i = 1.0 + kasymm + nao * (1.0 + nao / kna2) / kna1 +# h11_i = (nao * nao) / (kna1 * kna2 * h10_i) +# h12_i = 1.0 / h10_i +# k1_i = cao * kcaon * h12_i +# k2_i = kcaoff +# k3p_i = wca * h9_i +# k3pp_i = wnaca * h8_i +# k3_i = k3p_i + k3pp_i +# k4p_i = wca * h3_i / hca +# k4pp_i = wnaca * h2_i +# k4_i = k4p_i + k4pp_i +# k5_i = kcaoff +# k6_i = kcaon * cai * h6_i +# k7_i = wna * h2_i * h5_i +# k8_i = wna * h11_i * h8_i +# x1_i = (k2_i + k3_i) * k5_i * k7_i + (k6_i + k7_i) * k2_i * k4_i +# x2_i = (k1_i + k8_i) * k4_i * k6_i + (k4_i + k5_i) * k1_i * k7_i +# x3_i = (k2_i + k3_i) * k6_i * k8_i + (k6_i + k7_i) * k1_i * k3_i +# x4_i = (k1_i + k8_i) * k3_i * k5_i + (k4_i + k5_i) * k2_i * k8_i +# E1_i = x1_i / (x1_i + x2_i + x3_i + x4_i) +# E2_i = x2_i / (x1_i + x2_i + x3_i + x4_i) +# E3_i = x3_i / (x1_i + x2_i + x3_i + x4_i) +# E4_i = x4_i / (x1_i + x2_i + x3_i + x4_i) +# allo_i = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cai, 2.0)) +# zna = 1.0 +# JncxNa_i = E3_i * k4pp_i - E2_i * k3pp_i + 3.0 * E4_i * k7_i - 3.0 * E1_i * k8_i +# JncxCa_i = E2_i * k2_i - E1_i * k1_i +# INaCa_i = ( +# 0.8 +# * Gncx +# * scale_popu_KNCX +# * HF_scaling_Gncx +# * (zca * JncxCa_i + zna * JncxNa_i) +# * allo_i +# ) + +# # Expressions for the INaCa_ss component +# h1 = 1.0 + (1.0 + hna) * nass / kna3 +# h2 = hna * nass / (kna3 * h1) +# h3 = 1.0 / h1 +# h4 = 1.0 + (1 + nass / kna2) * nass / kna1 +# h5 = (nass * nass) / (kna1 * kna2 * h4) +# h6 = 1.0 / h4 +# h7 = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 +# h8 = nao / (kna3 * h7 * hna) +# h9 = 1.0 / h7 +# h10 = 1.0 + kasymm + nao * (1 + nao / kna2) / kna1 +# h11 = (nao * nao) / (kna1 * kna2 * h10) +# h12 = 1.0 / h10 +# k1 = cao * kcaon * h12 +# k2 = kcaoff +# k3p_ss = wca * h9 +# k3pp = wnaca * h8 +# k3 = k3p_ss + k3pp +# k4p_ss = wca * h3 / hca +# k4pp = wnaca * h2 +# k4 = k4p_ss + k4pp +# k5 = kcaoff +# k6 = kcaon * cass * h6 +# k7 = wna * h2 * h5 +# k8 = wna * h11 * h8 +# x1_ss = (k2 + k3) * k5 * k7 + (k6 + k7) * k2 * k4 +# x2_ss = (k1 + k8) * k4 * k6 + (k4 + k5) * k1 * k7 +# x3_ss = (k2 + k3) * k6 * k8 + (k6 + k7) * k1 * k3 +# x4_ss = (k1 + k8) * k3 * k5 + (k4 + k5) * k2 * k8 +# E1_ss = x1_ss / (x1_ss + x2_ss + x3_ss + x4_ss) +# E2_ss = x2_ss / (x1_ss + x2_ss + x3_ss + x4_ss) +# E3_ss = x3_ss / (x1_ss + x2_ss + x3_ss + x4_ss) +# E4_ss = x4_ss / (x1_ss + x2_ss + x3_ss + x4_ss) +# allo_ss = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cass, 2.0)) +# JncxNa_ss = E3_ss * k4pp - E2_ss * k3pp + 3.0 * E4_ss * k7 - 3.0 * E1_ss * k8 +# JncxCa_ss = E2_ss * k2 - E1_ss * k1 +# INaCa_ss = ( +# 0.2 +# * Gncx +# * scale_popu_KNCX +# * HF_scaling_Gncx +# * (zca * JncxCa_ss + zna * JncxNa_ss) +# * allo_ss +# ) + +# # Expressions for the INaK component +# Knai = Knai0 * ufl.exp(0.3333333333333333 * F * delta * v / (R * T)) +# Knao = Knao0 * ufl.exp(0.3333333333333333 * F * (1.0 - delta) * v / (R * T)) +# P = eP / (1.0 + H / Khp + nai / Knap + ki / Kxkur) +# a1 = ( +# k1p +# * ufl.elem_pow(nai / Knai, 3.0) +# / ( +# -1.0 +# + ufl.elem_pow(1.0 + ki / Kki, 2.0) +# + ufl.elem_pow(1.0 + nai / Knai, 3.0) +# ) +# ) +# b1 = MgADP * k1m +# a2 = k2p +# b2 = ( +# k2m +# * ufl.elem_pow(nao / Knao, 3.0) +# / ( +# -1.0 +# + ufl.elem_pow(1.0 + ko / Kko, 2.0) +# + ufl.elem_pow(1.0 + nao / Knao, 3.0) +# ) +# ) +# a3 = ( +# k3p +# * ufl.elem_pow(ko / Kko, 2.0) +# / ( +# -1.0 +# + ufl.elem_pow(1.0 + ko / Kko, 2.0) +# + ufl.elem_pow(1.0 + nao / Knao, 3.0) +# ) +# ) +# b3 = H * k3m * P / (1.0 + MgATP / Kmgatp) +# a4 = MgATP * k4p / (Kmgatp * (1.0 + MgATP / Kmgatp)) +# b4 = ( +# k4m +# * ufl.elem_pow(ki / Kki, 2.0) +# / ( +# -1.0 +# + ufl.elem_pow(1.0 + ki / Kki, 2.0) +# + ufl.elem_pow(1.0 + nai / Knai, 3.0) +# ) +# ) +# x1 = a1 * a2 * a4 + a1 * a2 * b3 + a2 * b3 * b4 + b2 * b3 * b4 +# x2 = a1 * a2 * a3 + a2 * a3 * b4 + a3 * b1 * b4 + b1 * b2 * b4 +# x3 = a2 * a3 * a4 + a3 * a4 * b1 + a4 * b1 * b2 + b1 * b2 * b3 +# x4 = a1 * a3 * a4 + a1 * a4 * b2 + a1 * b2 * b3 + b2 * b3 * b4 +# E1 = x1 / (x1 + x2 + x3 + x4) +# E2 = x2 / (x1 + x2 + x3 + x4) +# E3 = x3 / (x1 + x2 + x3 + x4) +# E4 = x4 / (x1 + x2 + x3 + x4) +# JnakNa = 3.0 * E1 * a3 - 3.0 * E2 * b3 +# JnakK = 2.0 * E4 * b1 - 2.0 * E3 * a1 +# INaK = Pnak * scale_popu_KNaK * HF_scaling_Pnak * (zk * JnakK + zna * JnakNa) + +# # Expressions for the IKb component +# xkb = 1.0 / (1.0 + 2.202363450949239 * ufl.exp(-0.05452562704471101 * v)) +# IKb = GKb * scale_popu_GbK * scale_drug_IKb * (-EK + v) * xkb + +# # Expressions for the INab component +# INab = ( +# PNab +# * scale_drug_INab +# * scale_popu_GbNa +# * (-nao + ufl.exp(vfrt) * nai) +# * vffrt +# / (-1.0 + ufl.exp(vfrt)) +# ) + +# # Expressions for the ICab component +# ICab = ( +# 4.0 +# * PCab +# * scale_drug_ICab +# * scale_popu_GbCa +# * (-0.341 * cao + cai * ufl.exp(2.0 * vfrt)) +# * vffrt +# / (-1.0 + ufl.exp(2.0 * vfrt)) +# ) + +# # Expressions for the IpCa component +# IpCa = GpCa * scale_drug_IpCa * scale_popu_KpCa * cai / (0.0005 + cai) + +# # Expressions for the Isac (Pueyo)--> ns + k component +# Gsac_ns = 0.006 * scale_drug_Isacns +# Esac_ns = -10.0 +# lambda_max = 1.1 +# Gsac_k = (0.2882 * 800.0 / 210.0) * scale_drug_Isack # Pueyo endo + +# Isac_P_ns = ufl.conditional( +# ufl.lt(lmbda, 1.0), +# 0.0, +# Gsac_ns * ((lmbda - 1.0) / (lambda_max - 1.0)) * (v - Esac_ns), +# ) +# Isac_P_k = ufl.conditional( +# ufl.lt(lmbda, 1.0), +# 0.0, +# Gsac_k +# * ((lmbda - 1.0) / (lambda_max - 1.0)) +# * (1.0 / (1.0 + ufl.exp((19.05 - v) / (29.98)))), +# ) + +# # Expressions for the Istim component +# Istim = 0 # amp*(ufl.le(time, duration)) + +# # Expressions for the membrane potential component +# current[0] = ( +# -Isac_P_k +# - Isac_P_ns +# - ICaK +# - ICaL +# - ICaNa +# - ICab +# - IK1 +# - IKb +# - IKr +# - IKs +# - INa +# - INaCa_i +# - INaCa_ss +# - INaK +# - INaL +# - INab +# - IpCa +# - Istim +# - Ito +# ) + +# # Return results +# return current[0] + +# def I(self, v, s, time=None): # noqa: E741, E743 +# """ +# Transmembrane current + +# I = -dV/dt + +# """ +# return -self._I(v, s, time) + +# def F(self, v, s, time=None): +# """ +# Right hand side for ODE system +# """ +# logger.debug("Evaluate RHS") +# time = time if time else Constant(0.0) + +# # Assign states +# assert len(s) == 47 +# ( +# CaMKt, +# m, +# hf, +# hs, +# j, +# hsp, +# jp, +# mL, +# hL, +# hLp, +# a, +# iF, +# iS, +# ap, +# iFp, +# iSp, +# d, +# ff, +# fs, +# fcaf, +# fcas, +# jca, +# ffp, +# fcafp, +# nca, +# xrf, +# xrs, +# xs1, +# xs2, +# xk1, +# Jrelnp, +# Jrelp, +# nai, +# nass, +# ki, +# kss, +# cass, +# cansr, +# cajsr, +# XS, +# XW, +# CaTrpn, +# TmB, +# Cd, +# cai, +# Zetas, +# Zetaw, +# ) = s + +# # Assign parameters +# scale_ICaL = self._parameters["scale_ICaL"] +# scale_IK1 = self._parameters["scale_IK1"] +# scale_IKr = self._parameters["scale_IKr"] +# scale_IKs = self._parameters["scale_IKs"] +# scale_INaL = self._parameters["scale_INaL"] +# cao = self._parameters["cao"] +# ko = self._parameters["ko"] +# nao = self._parameters["nao"] +# F = self._parameters["F"] +# R = self._parameters["R"] +# T = self._parameters["T"] +# L = self._parameters["L"] +# rad = self._parameters["rad"] +# CaMKo = self._parameters["CaMKo"] +# KmCaM = self._parameters["KmCaM"] +# KmCaMK = self._parameters["KmCaMK"] +# aCaMK = self._parameters["aCaMK"] +# bCaMK = self._parameters["bCaMK"] +# PKNa = self._parameters["PKNa"] +# Ahf = self._parameters["Ahf"] +# GNa = self._parameters["GNa"] +# thL = self._parameters["thL"] +# Gto = self._parameters["Gto"] +# delta_epi = self._parameters["delta_epi"] +# Aff = self._parameters["Aff"] +# Kmn = self._parameters["Kmn"] +# k2n = self._parameters["k2n"] +# tjca = self._parameters["tjca"] +# zca = self._parameters["zca"] +# Gncx = self._parameters["Gncx"] +# KmCaAct = self._parameters["KmCaAct"] +# kasymm = self._parameters["kasymm"] +# kcaoff = self._parameters["kcaoff"] +# kcaon = self._parameters["kcaon"] +# kna1 = self._parameters["kna1"] +# kna2 = self._parameters["kna2"] +# kna3 = self._parameters["kna3"] +# qca = self._parameters["qca"] +# qna = self._parameters["qna"] +# wca = self._parameters["wca"] +# wna = self._parameters["wna"] +# wnaca = self._parameters["wnaca"] +# H = self._parameters["H"] +# Khp = self._parameters["Khp"] +# Kki = self._parameters["Kki"] +# Kko = self._parameters["Kko"] +# Kmgatp = self._parameters["Kmgatp"] +# Knai0 = self._parameters["Knai0"] +# Knao0 = self._parameters["Knao0"] +# Knap = self._parameters["Knap"] +# Kxkur = self._parameters["Kxkur"] +# MgADP = self._parameters["MgADP"] +# MgATP = self._parameters["MgATP"] +# Pnak = self._parameters["Pnak"] +# delta = self._parameters["delta"] +# eP = self._parameters["eP"] +# k1m = self._parameters["k1m"] +# k1p = self._parameters["k1p"] +# k2m = self._parameters["k2m"] +# k2p = self._parameters["k2p"] +# k3m = self._parameters["k3m"] +# k3p = self._parameters["k3p"] +# k4m = self._parameters["k4m"] +# k4p = self._parameters["k4p"] +# zk = self._parameters["zk"] +# GKb = self._parameters["GKb"] +# PNab = self._parameters["PNab"] +# PCab = self._parameters["PCab"] +# GpCa = self._parameters["GpCa"] +# bt = self._parameters["bt"] +# BSLmax = self._parameters["BSLmax"] +# BSRmax = self._parameters["BSRmax"] +# KmBSL = self._parameters["KmBSL"] +# KmBSR = self._parameters["KmBSR"] +# cmdnmax = self._parameters["cmdnmax"] +# csqnmax = self._parameters["csqnmax"] +# kmcmdn = self._parameters["kmcmdn"] +# kmcsqn = self._parameters["kmcsqn"] +# trpnmax = self._parameters["trpnmax"] +# Beta1 = self._parameters["Beta1"] +# Tot_A = self._parameters["Tot_A"] +# Trpn50 = self._parameters["Trpn50"] +# cat50_ref = self._parameters["cat50_ref"] +# dLambda = self._parameters["dLambda"] +# etal = self._parameters["etal"] +# etas = self._parameters["etas"] +# gammas = self._parameters["gammas"] +# gammaw = self._parameters["gammaw"] +# ktrpn = self._parameters["ktrpn"] +# ku = self._parameters["ku"] +# kuw = self._parameters["kuw"] +# kws = self._parameters["kws"] +# lmbda = self._parameters["lmbda"] +# ntm = self._parameters["ntm"] +# ntrpn = self._parameters["ntrpn"] +# p_k = self._parameters["p_k"] +# phi = self._parameters["phi"] +# rs = self._parameters["rs"] +# rw = self._parameters["rw"] + +# # Drug factor +# scale_drug_INa = self._parameters["scale_drug_INa"] +# scale_drug_INaL = self._parameters["scale_drug_INaL"] +# scale_drug_Ito = self._parameters["scale_drug_Ito"] +# scale_drug_ICaL = self._parameters["scale_drug_ICaL"] +# scale_drug_IKr = self._parameters["scale_drug_IKr"] +# scale_drug_IKs = self._parameters["scale_drug_IKs"] +# scale_drug_IK1 = self._parameters["scale_drug_IK1"] +# scale_drug_IKb = self._parameters["scale_drug_IKb"] +# scale_drug_INab = self._parameters["scale_drug_INab"] +# scale_drug_ICab = self._parameters["scale_drug_ICab"] +# scale_drug_IpCa = self._parameters["scale_drug_IpCa"] +# scale_drug_Isacns = self._parameters["scale_drug_Isacns"] +# scale_drug_Isack = self._parameters["scale_drug_Isack"] + +# # Population factors +# scale_popu_GNa = self._parameters["scale_popu_GNa"] +# scale_popu_GCaL = self._parameters["scale_popu_GCaL"] +# scale_popu_Gto = self._parameters["scale_popu_Gto"] +# scale_popu_GNaL = self._parameters["scale_popu_GNaL"] +# scale_popu_GKr = self._parameters["scale_popu_GKr"] +# scale_popu_GKs = self._parameters["scale_popu_GKs"] +# scale_popu_GK1 = self._parameters["scale_popu_GK1"] +# scale_popu_GbK = self._parameters["scale_popu_GbK"] +# scale_popu_KNCX = self._parameters["scale_popu_KNCX"] +# scale_popu_KNaK = self._parameters["scale_popu_KNaK"] +# scale_popu_GbNa = self._parameters["scale_popu_GbNa"] +# scale_popu_GbCa = self._parameters["scale_popu_GbCa"] +# scale_popu_KpCa = self._parameters["scale_popu_KpCa"] +# scale_popu_KRyR = self._parameters["scale_popu_KRyR"] +# scale_popu_KSERCA = self._parameters["scale_popu_KSERCA"] +# scale_popu_Kleak = self._parameters["scale_popu_Kleak"] +# scale_popu_nTm = self._parameters["scale_popu_nTm"] +# scale_popu_CaT50ref = self._parameters["scale_popu_CaT50ref"] +# scale_popu_kuw = self._parameters["scale_popu_kuw"] +# scale_popu_kws = self._parameters["scale_popu_kws"] +# scale_popu_kTRPN = self._parameters["scale_popu_kTRPN"] +# scale_popu_nTRPN = self._parameters["scale_popu_nTRPN"] +# scale_popu_ku = self._parameters["scale_popu_ku"] +# scale_popu_TRPN50 = self._parameters["scale_popu_TRPN50"] +# scale_popu_rw = self._parameters["scale_popu_rw"] +# scale_popu_rs = self._parameters["scale_popu_rs"] + +# # Systolic Heart Failure (HF with preserved ejection fraction) +# HF_scaling_CaMKa = self._parameters["HF_scaling_CaMKa"] +# HF_scaling_Jrel_inf = self._parameters["HF_scaling_Jrel_inf"] +# HF_scaling_Jleak = self._parameters["HF_scaling_Jleak"] +# HF_scaling_Jup = self._parameters["HF_scaling_Jup"] +# HF_scaling_GNaL = self._parameters["HF_scaling_GNaL"] +# HF_scaling_GK1 = self._parameters["HF_scaling_GK1"] +# HF_scaling_thL = self._parameters["HF_scaling_thL"] +# HF_scaling_Gto = self._parameters["HF_scaling_Gto"] +# HF_scaling_Gncx = self._parameters["HF_scaling_Gncx"] +# HF_scaling_Pnak = self._parameters["HF_scaling_Pnak"] +# HF_scaling_cat50_ref = self._parameters["HF_scaling_cat50_ref"] + +# # Init return args +# F_expressions = [dolfin.Constant(0.0)] * 47 + +# # Expressions for the cell geometry component +# vcell = 3140.0 * L * (rad * rad) +# Ageo = 6.28 * (rad * rad) + 6.28 * L * rad +# Acap = 2 * Ageo +# vmyo = 0.68 * vcell +# vnsr = 0.0552 * vcell +# vjsr = 0.0048 * vcell +# vss = 0.02 * vcell + +# # Expressions for the CaMKt component +# CaMKb = CaMKo * (1.0 - CaMKt) / (1.0 + KmCaM / cass) +# CaMKa = (CaMKb + CaMKt) * HF_scaling_CaMKa +# F_expressions[0] = -bCaMK * CaMKt + aCaMK * (CaMKb + CaMKt) * CaMKb + +# # Expressions for the reversal potentials component +# ENa = R * T * ufl.ln(nao / nai) / F +# EK = R * T * ufl.ln(ko / ki) / F +# EKs = R * T * ufl.ln((ko + PKNa * nao) / (PKNa * nai + ki)) / F +# vffrt = (F * F) * v / (R * T) +# vfrt = F * v / (R * T) + +# # Expressions for the I_Na component +# mss = 1.0 / (1.0 + 0.0014599788446489682 * ufl.exp(-0.13333333333333333 * v)) +# tm = 1.0 / ( +# 9.454904638564724 * ufl.exp(0.02876042565429968 * v) +# + 1.9314113558536928e-05 * ufl.exp(-0.16792611251049538 * v) +# ) +# F_expressions[1] = (-m + mss) / tm +# hss = 1.0 / (1 + 302724.605401998 * ufl.exp(0.1607717041800643 * v)) +# thf = 1.0 / ( +# 1.183856958289087e-05 * ufl.exp(-0.15910898965791567 * v) +# + 6.305549185817275 * ufl.exp(0.0493339911198816 * v) +# ) +# ths = 1.0 / ( +# 0.005164670235381792 * ufl.exp(-0.035650623885918005 * v) +# + 0.36987619372096325 * ufl.exp(0.017649135192375574 * v) +# ) +# Ahs = 1.0 - Ahf +# F_expressions[2] = (-hf + hss) / thf +# F_expressions[3] = (-hs + hss) / ths +# h = Ahf * hf + Ahs * hs +# jss = hss +# tj = 2.038 + 1.0 / ( +# 0.3131936394738773 * ufl.exp(0.02600780234070221 * v) +# + 1.1315282095590072e-07 * ufl.exp(-0.12075836251660427 * v) +# ) +# F_expressions[4] = (-j + jss) / tj +# hssp = 1.0 / (1 + 820249.0921708513 * ufl.exp(0.1607717041800643 * v)) +# thsp = 3.0 * ths +# F_expressions[5] = (-hsp + hssp) / thsp +# hp = Ahf * hf + Ahs * hsp +# tjp = 1.46 * tj +# F_expressions[6] = (-jp + jss) / tjp +# fINap = 1.0 / (1.0 + KmCaMK / CaMKa) +# INa = ( +# GNa +# * scale_drug_INa +# * scale_popu_GNa +# * ufl.elem_pow(m, 3.0) +# * (-ENa + v) +# * ((1.0 - fINap) * h * j + fINap * hp * jp) +# ) + +# # Expressions for the INaL component +# mLss = 1.0 / (1.0 + 0.000291579585635531 * ufl.exp(-0.18996960486322187 * v)) +# tmL = tm +# F_expressions[7] = (-mL + mLss) / tmL +# hLss = 1.0 / (1.0 + 120578.15595522427 * ufl.exp(0.13354700854700854 * v)) +# F_expressions[8] = (-hL + hLss) / (thL * HF_scaling_thL) +# hLssp = 1.0 / (1.0 + 275969.2903869871 * ufl.exp(0.13354700854700854 * v)) +# thLp = 3.0 * thL * HF_scaling_thL +# F_expressions[9] = (-hLp + hLssp) / thLp +# GNaL = 0.0075 * scale_INaL * scale_drug_INaL * scale_popu_GNaL * HF_scaling_GNaL +# fINaLp = 1.0 / (1.0 + KmCaMK / CaMKa) +# INaL = (-ENa + v) * ((1.0 - fINaLp) * hL + fINaLp * hLp) * GNaL * mL + +# # Expressions for the Ito component +# ass = 1.0 / (1.0 + 2.6316508161673635 * ufl.exp(-0.06747638326585695 * v)) +# ta = 1.0515 / ( +# 1.0 / (1.2089 + 2.2621017070578837 * ufl.exp(-0.03403513787634354 * v)) +# + 3.5 / (1.0 + 30.069572727397507 * ufl.exp(0.03403513787634354 * v)) +# ) +# F_expressions[10] = (-a + ass) / ta +# iss = 1.0 / (1.0 + 2194.970764538301 * ufl.exp(0.17510068289266328 * v)) +# tiF = 4.562 + delta_epi / ( +# 0.14468698421272827 * ufl.exp(-0.01 * v) +# + 1.6300896349780942 * ufl.exp(0.06027727546714889 * v) +# ) +# tiS = 23.62 + delta_epi / ( +# 0.00027617763953377436 * ufl.exp(-0.01693480101608806 * v) +# + 0.024208962804604526 * ufl.exp(0.12377769525931426 * v) +# ) +# AiF = 1.0 / (1.0 + 0.24348537187522867 * ufl.exp(0.006613756613756614 * v)) +# AiS = 1.0 - AiF +# F_expressions[11] = (-iF + iss) / tiF +# F_expressions[12] = (-iS + iss) / tiS +# i = AiF * iF + AiS * iS +# assp = 1.0 / (1.0 + 5.167428462230666 * ufl.exp(-0.06747638326585695 * v)) +# F_expressions[13] = (-ap + assp) / ta +# dti_develop = 1.354 + 0.0001 / ( +# 2.6591269045230603e-05 * ufl.exp(0.06293266205160478 * v) +# + 4.5541779737128264e24 * ufl.exp(-4.642525533890436 * v) +# ) +# dti_recover = 1.0 - 0.5 / (1.0 + 33.11545195869231 * ufl.exp(0.05 * v)) +# tiFp = dti_develop * dti_recover * tiF +# tiSp = dti_develop * dti_recover * tiS +# F_expressions[14] = (-iFp + iss) / tiFp +# F_expressions[15] = (-iSp + iss) / tiSp +# ip = AiF * iFp + AiS * iSp +# fItop = 1.0 / (1.0 + KmCaMK / CaMKa) +# Ito = ( +# Gto +# * scale_drug_Ito +# * scale_popu_Gto +# * HF_scaling_Gto +# * (-EK + v) +# * ((1.0 - fItop) * a * i + ap * fItop * ip) +# ) + +# # Expressions for the ICaL ICaNa ICaK component +# dss = 1.0 / (1.0 + 0.39398514226669484 * ufl.exp(-0.23640661938534277 * v)) +# td = 0.6 + 1.0 / ( +# 3.5254214873653824 * ufl.exp(0.09 * v) +# + 0.7408182206817179 * ufl.exp(-0.05 * v) +# ) +# F_expressions[16] = (-d + dss) / td +# fss = 1.0 / (1.0 + 199.86038496778565 * ufl.exp(0.27056277056277056 * v)) +# tff = 7.0 + 1.0 / ( +# 0.03325075244518792 * ufl.exp(0.1 * v) +# + 0.0006090087745647571 * ufl.exp(-0.1 * v) +# ) +# tfs = 1000.0 + 1.0 / ( +# 1.0027667890106652e-05 * ufl.exp(-0.25 * v) +# + 8.053415618124885e-05 * ufl.exp(0.16666666666666666 * v) +# ) +# Afs = 1.0 - Aff +# F_expressions[17] = (-ff + fss) / tff +# F_expressions[18] = (-fs + fss) / tfs +# f = Aff * ff + Afs * fs +# fcass = fss +# tfcaf = 7.0 + 1.0 / ( +# 0.0708317980974062 * ufl.exp(-0.14285714285714285 * v) +# + 0.02258872488031037 * ufl.exp(0.14285714285714285 * v) +# ) +# tfcas = 100.0 + 1.0 / ( +# 0.00012 * ufl.exp(0.14285714285714285 * v) +# + 0.00012 * ufl.exp(-0.3333333333333333 * v) +# ) +# Afcaf = 0.3 + 0.6 / (1.0 + 0.36787944117144233 * ufl.exp(0.1 * v)) +# Afcas = 1.0 - Afcaf +# F_expressions[19] = (-fcaf + fcass) / tfcaf +# F_expressions[20] = (-fcas + fcass) / tfcas +# fca = Afcaf * fcaf + Afcas * fcas +# F_expressions[21] = (-jca + fcass) / tjca +# tffp = 2.5 * tff +# F_expressions[22] = (-ffp + fss) / tffp +# fp = Aff * ffp + Afs * fs +# tfcafp = 2.5 * tfcaf +# F_expressions[23] = (-fcafp + fcass) / tfcafp +# fcap = Afcaf * fcafp + Afcas * fcas +# km2n = 1.0 * jca +# anca = 1.0 / (ufl.elem_pow(1.0 + Kmn / cass, 4.0) + k2n / km2n) +# F_expressions[24] = k2n * anca - km2n * nca +# PhiCaL = ( +# 4.0 +# * (-0.341 * cao + cass * ufl.exp(2.0 * vfrt)) +# * vffrt +# / (-1.0 + ufl.exp(2.0 * vfrt)) +# ) +# PhiCaNa = ( +# 1.0 +# * (-0.75 * nao + 0.75 * ufl.exp(1.0 * vfrt) * nass) +# * vffrt +# / (-1.0 + ufl.exp(1.0 * vfrt)) +# ) +# PhiCaK = ( +# 1.0 +# * (-0.75 * ko + 0.75 * ufl.exp(1.0 * vfrt) * kss) +# * vffrt +# / (-1.0 + ufl.exp(1.0 * vfrt)) +# ) +# PCa = 0.0001 * scale_ICaL * scale_drug_ICaL * scale_popu_GCaL +# PCap = 1.1 * PCa +# PCaNa = 0.00125 * PCa +# PCaK = 0.0003574 * PCa +# PCaNap = 0.00125 * PCap +# PCaKp = 0.0003574 * PCap +# fICaLp = 1.0 / (1.0 + KmCaMK / CaMKa) +# ICaL = (1.0 - fICaLp) * ( +# (1.0 - nca) * f + fca * jca * nca +# ) * PCa * PhiCaL * d + ( +# (1.0 - nca) * fp + fcap * jca * nca +# ) * PCap * PhiCaL * d * fICaLp +# ICaNa = (1.0 - fICaLp) * ( +# (1.0 - nca) * f + fca * jca * nca +# ) * PCaNa * PhiCaNa * d + ( +# (1.0 - nca) * fp + fcap * jca * nca +# ) * PCaNap * PhiCaNa * d * fICaLp +# ICaK = (1.0 - fICaLp) * ( +# (1.0 - nca) * f + fca * jca * nca +# ) * PCaK * PhiCaK * d + ( +# (1.0 - nca) * fp + fcap * jca * nca +# ) * PCaKp * PhiCaK * d * fICaLp + +# # Expressions for the IKr component +# xrss = 1.0 / (1.0 + 0.29287308872377504 * ufl.exp(-0.14729709824716453 * v)) +# txrf = 12.98 + 1.0 / ( +# 0.0001020239312894894 * ufl.exp(0.25846471956577927 * v) +# + 0.00042992960891929087 * ufl.exp(-0.04906771344455348 * v) +# ) +# txrs = 1.865 + 1.0 / ( +# 0.0005922420036809394 * ufl.exp(0.13596193065941536 * v) +# + 3.549966111802463e-05 * ufl.exp(-0.03855050115651503 * v) +# ) +# Axrf = 1.0 / (1.0 + 4.197299094734718 * ufl.exp(0.02617115938236064 * v)) +# Axrs = 1.0 - Axrf +# F_expressions[25] = (-xrf + xrss) / txrf +# F_expressions[26] = (-xrs + xrss) / txrs +# xr = Axrf * xrf + Axrs * xrs +# rkr = 1.0 / ( +# (1.0 + 2.0820090840784555 * ufl.exp(0.013333333333333334 * v)) +# * (1.0 + 0.7165313105737893 * ufl.exp(0.03333333333333333 * v)) +# ) +# GKr = 0.046 * scale_IKr * scale_drug_IKr * scale_popu_GKr +# IKr = 0.4303314829119352 * ufl.sqrt(ko) * (-EK + v) * GKr * rkr * xr + +# # Expressions for the IKs component +# xs1ss = 1.0 / (1.0 + 0.27288596035656526 * ufl.exp(-0.11195700850873264 * v)) +# txs1 = 817.3 + 1.0 / ( +# 0.003504067763074858 * ufl.exp(0.056179775280898875 * v) +# + 0.0005184809083581659 * ufl.exp(-0.004347826086956522 * v) +# ) +# F_expressions[27] = (-xs1 + xs1ss) / txs1 +# xs2ss = xs1ss +# txs2 = 1.0 / ( +# 0.0022561357010639103 * ufl.exp(-0.03225806451612903 * v) +# + 0.0008208499862389881 * ufl.exp(0.05 * v) +# ) +# F_expressions[28] = (-xs2 + xs2ss) / txs2 +# KsCa = 1.0 + 0.6 / (1.0 + 6.481821026062645e-07 * ufl.elem_pow(1.0 / cai, 1.4)) +# GKs = 0.0034 * scale_IKs * scale_drug_IKs * scale_popu_GKs +# IKs = (-EKs + v) * GKs * KsCa * xs1 * xs2 +# xk1ss = 1.0 / ( +# 1.0 + ufl.exp((-144.59 - v - 2.5538 * ko) / (3.8115 + 1.5692 * ko)) +# ) +# txk1 = 122.2 / ( +# 0.0019352007631390235 * ufl.exp(-0.049115913555992145 * v) +# + 30.43364757524903 * ufl.exp(0.014423770373575654 * v) +# ) +# F_expressions[29] = (-xk1 + xk1ss) / txk1 +# rk1 = 1.0 / ( +# 1.0 +# + 69220.6322106767 +# * ufl.exp(0.10534077741493732 * v - 0.27388602127883704 * ko) +# ) +# GK1 = 0.1908 * scale_IK1 * scale_drug_IK1 * scale_popu_GK1 * HF_scaling_GK1 +# IK1 = ufl.sqrt(ko) * (-EK + v) * GK1 * rk1 * xk1 + +# # Expressions for the INaCa_i component +# hca = ufl.exp(F * qca * v / (R * T)) +# hna = ufl.exp(F * qna * v / (R * T)) +# h1_i = 1.0 + (1.0 + hna) * nai / kna3 +# h2_i = hna * nai / (kna3 * h1_i) +# h3_i = 1.0 / h1_i +# h4_i = 1.0 + (1 + nai / kna2) * nai / kna1 +# h5_i = (nai * nai) / (kna1 * kna2 * h4_i) +# h6_i = 1.0 / h4_i +# h7_i = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 +# h8_i = nao / (kna3 * h7_i * hna) +# h9_i = 1.0 / h7_i +# h10_i = 1.0 + kasymm + nao * (1.0 + nao / kna2) / kna1 +# h11_i = (nao * nao) / (kna1 * kna2 * h10_i) +# h12_i = 1.0 / h10_i +# k1_i = cao * kcaon * h12_i +# k2_i = kcaoff +# k3p_i = wca * h9_i +# k3pp_i = wnaca * h8_i +# k3_i = k3p_i + k3pp_i +# k4p_i = wca * h3_i / hca +# k4pp_i = wnaca * h2_i +# k4_i = k4p_i + k4pp_i +# k5_i = kcaoff +# k6_i = kcaon * cai * h6_i +# k7_i = wna * h2_i * h5_i +# k8_i = wna * h11_i * h8_i +# x1_i = (k2_i + k3_i) * k5_i * k7_i + (k6_i + k7_i) * k2_i * k4_i +# x2_i = (k1_i + k8_i) * k4_i * k6_i + (k4_i + k5_i) * k1_i * k7_i +# x3_i = (k2_i + k3_i) * k6_i * k8_i + (k6_i + k7_i) * k1_i * k3_i +# x4_i = (k1_i + k8_i) * k3_i * k5_i + (k4_i + k5_i) * k2_i * k8_i +# E1_i = x1_i / (x1_i + x2_i + x3_i + x4_i) +# E2_i = x2_i / (x1_i + x2_i + x3_i + x4_i) +# E3_i = x3_i / (x1_i + x2_i + x3_i + x4_i) +# E4_i = x4_i / (x1_i + x2_i + x3_i + x4_i) +# allo_i = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cai, 2.0)) +# zna = 1.0 +# JncxNa_i = E3_i * k4pp_i - E2_i * k3pp_i + 3.0 * E4_i * k7_i - 3.0 * E1_i * k8_i +# JncxCa_i = E2_i * k2_i - E1_i * k1_i +# INaCa_i = ( +# 0.8 +# * Gncx +# * scale_popu_KNCX +# * HF_scaling_Gncx +# * (zca * JncxCa_i + zna * JncxNa_i) +# * allo_i +# ) + +# # Expressions for the INaCa_ss component +# h1 = 1.0 + (1.0 + hna) * nass / kna3 +# h2 = hna * nass / (kna3 * h1) +# h3 = 1.0 / h1 +# h4 = 1.0 + (1 + nass / kna2) * nass / kna1 +# h5 = (nass * nass) / (kna1 * kna2 * h4) +# h6 = 1.0 / h4 +# h7 = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 +# h8 = nao / (kna3 * h7 * hna) +# h9 = 1.0 / h7 +# h10 = 1.0 + kasymm + nao * (1 + nao / kna2) / kna1 +# h11 = (nao * nao) / (kna1 * kna2 * h10) +# h12 = 1.0 / h10 +# k1 = cao * kcaon * h12 +# k2 = kcaoff +# k3p_ss = wca * h9 +# k3pp = wnaca * h8 +# k3 = k3p_ss + k3pp +# k4p_ss = wca * h3 / hca +# k4pp = wnaca * h2 +# k4 = k4p_ss + k4pp +# k5 = kcaoff +# k6 = kcaon * cass * h6 +# k7 = wna * h2 * h5 +# k8 = wna * h11 * h8 +# x1_ss = (k2 + k3) * k5 * k7 + (k6 + k7) * k2 * k4 +# x2_ss = (k1 + k8) * k4 * k6 + (k4 + k5) * k1 * k7 +# x3_ss = (k2 + k3) * k6 * k8 + (k6 + k7) * k1 * k3 +# x4_ss = (k1 + k8) * k3 * k5 + (k4 + k5) * k2 * k8 +# E1_ss = x1_ss / (x1_ss + x2_ss + x3_ss + x4_ss) +# E2_ss = x2_ss / (x1_ss + x2_ss + x3_ss + x4_ss) +# E3_ss = x3_ss / (x1_ss + x2_ss + x3_ss + x4_ss) +# E4_ss = x4_ss / (x1_ss + x2_ss + x3_ss + x4_ss) +# allo_ss = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cass, 2.0)) +# JncxNa_ss = E3_ss * k4pp - E2_ss * k3pp + 3.0 * E4_ss * k7 - 3.0 * E1_ss * k8 +# JncxCa_ss = E2_ss * k2 - E1_ss * k1 +# INaCa_ss = ( +# 0.2 +# * Gncx +# * scale_popu_KNCX +# * HF_scaling_Gncx +# * (zca * JncxCa_ss + zna * JncxNa_ss) +# * allo_ss +# ) + +# # Expressions for the INaK component +# Knai = Knai0 * ufl.exp(0.3333333333333333 * F * delta * v / (R * T)) +# Knao = Knao0 * ufl.exp(0.3333333333333333 * F * (1.0 - delta) * v / (R * T)) +# P = eP / (1.0 + H / Khp + nai / Knap + ki / Kxkur) +# a1 = ( +# k1p +# * ufl.elem_pow(nai / Knai, 3.0) +# / ( +# -1.0 +# + ufl.elem_pow(1.0 + ki / Kki, 2.0) +# + ufl.elem_pow(1.0 + nai / Knai, 3.0) +# ) +# ) +# b1 = MgADP * k1m +# a2 = k2p +# b2 = ( +# k2m +# * ufl.elem_pow(nao / Knao, 3.0) +# / ( +# -1.0 +# + ufl.elem_pow(1.0 + ko / Kko, 2.0) +# + ufl.elem_pow(1.0 + nao / Knao, 3.0) +# ) +# ) +# a3 = ( +# k3p +# * ufl.elem_pow(ko / Kko, 2.0) +# / ( +# -1.0 +# + ufl.elem_pow(1.0 + ko / Kko, 2.0) +# + ufl.elem_pow(1.0 + nao / Knao, 3.0) +# ) +# ) +# b3 = H * k3m * P / (1.0 + MgATP / Kmgatp) +# a4 = MgATP * k4p / (Kmgatp * (1.0 + MgATP / Kmgatp)) +# b4 = ( +# k4m +# * ufl.elem_pow(ki / Kki, 2.0) +# / ( +# -1.0 +# + ufl.elem_pow(1.0 + ki / Kki, 2.0) +# + ufl.elem_pow(1.0 + nai / Knai, 3.0) +# ) +# ) +# x1 = a1 * a2 * a4 + a1 * a2 * b3 + a2 * b3 * b4 + b2 * b3 * b4 +# x2 = a1 * a2 * a3 + a2 * a3 * b4 + a3 * b1 * b4 + b1 * b2 * b4 +# x3 = a2 * a3 * a4 + a3 * a4 * b1 + a4 * b1 * b2 + b1 * b2 * b3 +# x4 = a1 * a3 * a4 + a1 * a4 * b2 + a1 * b2 * b3 + b2 * b3 * b4 +# E1 = x1 / (x1 + x2 + x3 + x4) +# E2 = x2 / (x1 + x2 + x3 + x4) +# E3 = x3 / (x1 + x2 + x3 + x4) +# E4 = x4 / (x1 + x2 + x3 + x4) +# JnakNa = 3.0 * E1 * a3 - 3.0 * E2 * b3 +# JnakK = 2.0 * E4 * b1 - 2.0 * E3 * a1 +# INaK = Pnak * scale_popu_KNaK * HF_scaling_Pnak * (zk * JnakK + zna * JnakNa) + +# # Expressions for the IKb component +# xkb = 1.0 / (1.0 + 2.202363450949239 * ufl.exp(-0.05452562704471101 * v)) +# IKb = GKb * scale_popu_GbK * scale_drug_IKb * (-EK + v) * xkb + +# # Expressions for the INab component +# INab = ( +# PNab +# * scale_drug_INab +# * scale_popu_GbNa +# * (-nao + ufl.exp(vfrt) * nai) +# * vffrt +# / (-1.0 + ufl.exp(vfrt)) +# ) + +# # Expressions for the ICab component +# ICab = ( +# 4.0 +# * PCab +# * scale_drug_ICab +# * scale_popu_GbCa +# * (-0.341 * cao + cai * ufl.exp(2.0 * vfrt)) +# * vffrt +# / (-1.0 + ufl.exp(2.0 * vfrt)) +# ) + +# # Expressions for the IpCa component +# IpCa = GpCa * scale_drug_IpCa * scale_popu_KpCa * cai / (0.0005 + cai) + +# # Expressions for the Isac (Pueyo)--> ns + k component +# Gsac_ns = 0.006 * scale_drug_Isacns +# Esac_ns = -10.0 +# lambda_max = 1.1 +# Gsac_k = (0.2882 * 800.0 / 210.0) * scale_drug_Isack # Pueyo endo +# Isac_P_ns = ufl.conditional( +# ufl.lt(lmbda, 1.0), +# 0.0, +# Gsac_ns * ((lmbda - 1.0) / (lambda_max - 1.0)) * (v - Esac_ns), +# ) +# Isac_P_k = ufl.conditional( +# ufl.lt(lmbda, 1.0), +# 0.0, +# Gsac_k +# * ((lmbda - 1.0) / (lambda_max - 1.0)) +# * (1.0 / (1.0 + ufl.exp((19.05 - v) / (29.98)))), +# ) + +# # Expressions for the Istim component +# Istim = 0 # amp*(ufl.le(time, duration)) + +# # Expressions for the diffusion fluxes component +# JdiffNa = 0.5 * nass - 0.5 * nai +# JdiffK = 0.5 * kss - 0.5 * ki +# Jdiff = 5.0 * cass - 5.0 * cai + +# # Expressions for the ryanodine receptor component +# a_rel = 0.5 * bt +# Jrel_inf = ( +# -ICaL +# * a_rel +# / (1.0 + 25.62890625 * HF_scaling_Jrel_inf * ufl.elem_pow(1.0 / cajsr, 8.0)) +# ) +# tau_rel_tmp = bt / (1.0 + 0.0123 / cajsr) +# tau_rel = ufl.conditional(ufl.lt(tau_rel_tmp, 0.001), 0.001, tau_rel_tmp) +# F_expressions[30] = (-Jrelnp + Jrel_inf) / tau_rel +# btp = 1.25 * bt +# a_relp = 0.5 * btp +# Jrel_infp = ( +# -ICaL +# * a_relp +# / (1.0 + 25.62890625 * HF_scaling_Jrel_inf * ufl.elem_pow(1.0 / cajsr, 8.0)) +# ) +# tau_relp_tmp = btp / (1.0 + 0.0123 / cajsr) +# tau_relp = ufl.conditional(ufl.lt(tau_relp_tmp, 0.001), 0.001, tau_relp_tmp) +# F_expressions[31] = (-Jrelp + Jrel_infp) / tau_relp +# fJrelp = 1.0 / (1.0 + KmCaMK / CaMKa) +# Jrel = ((1.0 - fJrelp) * Jrelnp + Jrelp * fJrelp) * scale_popu_KRyR + +# # Expressions for the calcium buffers component +# Jupnp = 0.004375 * cai / (0.00092 + cai) +# Jupp = 0.01203125 * cai / (0.00075 + cai) +# fJupp = 1.0 / (1.0 + KmCaMK / CaMKa) +# Jleak = 0.0002625 * cansr * scale_popu_Kleak * HF_scaling_Jleak +# Jup = ( +# -Jleak +# + ((1.0 - fJupp) * Jupnp + Jupp * fJupp) +# * scale_popu_KSERCA +# * HF_scaling_Jup +# ) +# Jtr = 0.01 * cansr - 0.01 * cajsr + +# # Expressions for the intracellular concentrations component +# F_expressions[32] = JdiffNa * vss / vmyo + ( +# -INa - INaL - INab - Isac_P_ns / 3.0 - 3.0 * INaCa_i - 3.0 * INaK +# ) * Acap / (F * vmyo) +# F_expressions[33] = -JdiffNa + (-ICaNa - 3.0 * INaCa_ss) * Acap / (F * vss) +# F_expressions[34] = JdiffK * vss / vmyo + ( +# -Isac_P_k +# - IK1 +# - IKb +# - IKr +# - IKs +# - Istim +# - Ito +# - Isac_P_ns / 3.0 +# + 2.0 * INaK +# ) * Acap / (F * vmyo) +# F_expressions[35] = -JdiffK - Acap * ICaK / (F * vss) +# Bcass = 1.0 / ( +# 1.0 +# + BSLmax * KmBSL * ufl.elem_pow(KmBSL + cass, -2.0) +# + BSRmax * KmBSR * ufl.elem_pow(KmBSR + cass, -2.0) +# ) +# F_expressions[36] = ( +# -Jdiff +# + Jrel * vjsr / vss +# + 0.5 * (-ICaL + 2.0 * INaCa_ss) * Acap / (F * vss) +# ) * Bcass +# F_expressions[37] = -Jtr * vjsr / vnsr + Jup +# Bcajsr = 1.0 / (1.0 + csqnmax * kmcsqn * ufl.elem_pow(kmcsqn + cajsr, -2.0)) +# F_expressions[38] = (-Jrel + Jtr) * Bcajsr + +# # Expressions for the mechanics component +# kwu = -kws * scale_popu_kws + (kuw * scale_popu_kuw) * ( +# -1.0 + 1.0 / (rw * scale_popu_rw) +# ) +# ksu = ( +# kws +# * scale_popu_kws +# * rw +# * scale_popu_rw +# * (-1.0 + 1.0 / (rs * scale_popu_rs)) +# ) + +# Aw = Tot_A * rs / (rs + rw * (1 - rs)) +# As = Aw +# cw = kuw * phi * (1 - rw) / rw +# cs = kws * phi * rw * (1 - rs) / rs + +# lambda_min12 = ufl.conditional(ufl.lt(lmbda, 1.2), lmbda, 1.2) +# XS = ufl.conditional(ufl.lt(XS, 0.0), 0.0, XS) +# XW = ufl.conditional(ufl.lt(XW, 0.0), 0.0, XW) + +# XU = 1.0 - TmB - XS - XW +# gammawu = gammaw * abs(Zetaw) +# # gammasu = gammas*ufl.conditional(ufl.gt(Zetas*(ufl.gt(Zetas, 0)), (-1 -\ +# # Zetas)*(ufl.lt(Zetas, -1))), Zetas*(ufl.gt(Zetas, 0)), (-1 -\ +# # Zetas)*(ufl.lt(Zetas, -1))) +# zetas1 = Zetas * ufl.conditional(ufl.gt(Zetas, 0.0), 1.0, 0.0) +# zetas2 = (-1.0 - Zetas) * ufl.conditional( +# ufl.lt(Zetas, -1.0), +# 1.0, +# 0.0, +# ) +# gammasu = gammas * Max(zetas1, zetas2) + +# F_expressions[39] = kws * scale_popu_kws * XW - XS * gammasu - XS * ksu +# F_expressions[40] = ( +# kuw * scale_popu_kuw * XU +# - kws * scale_popu_kws * XW +# - XW * gammawu +# - XW * kwu +# ) +# cat50 = ( +# cat50_ref * scale_popu_CaT50ref + Beta1 * (-1.0 + lambda_min12) +# ) * HF_scaling_cat50_ref +# CaTrpn = ufl.conditional(ufl.lt(CaTrpn, 0.0), 0.0, CaTrpn) +# F_expressions[41] = ( +# ktrpn +# * scale_popu_kTRPN +# * ( +# -CaTrpn +# + ufl.elem_pow(1000.0 * cai / cat50, ntrpn * scale_popu_nTRPN) +# * (1.0 - CaTrpn) +# ) +# ) +# kb = ( +# ku +# * scale_popu_ku +# * ufl.elem_pow(Trpn50 * scale_popu_TRPN50, (ntm * scale_popu_nTm)) +# / ( +# 1.0 +# - (rs * scale_popu_rs) +# - rw * scale_popu_rw * (1.0 - (rs * scale_popu_rs)) +# ) +# ) + +# F_expressions[42] = ( +# ufl.conditional( +# ufl.lt(ufl.elem_pow(CaTrpn, -(ntm * scale_popu_nTm) / 2.0), 100.0), +# ufl.elem_pow(CaTrpn, -(ntm * scale_popu_nTm) / 2.0), +# 100.0, +# ) +# * XU +# * kb +# - ku +# * scale_popu_ku +# * ufl.elem_pow(CaTrpn, (ntm * scale_popu_nTm) / 2.0) +# * TmB +# ) + +# C = -1.0 + lambda_min12 +# dCd = -Cd + C +# eta = ufl.conditional(ufl.lt(dCd, 0.0), etas, etal) +# F_expressions[43] = p_k * (-Cd + C) / eta +# Bcai = 1.0 / (1.0 + cmdnmax * kmcmdn * ufl.elem_pow(kmcmdn + cai, -2.0)) +# J_TRPN = trpnmax * F_expressions[41] +# F_expressions[44] = ( +# -J_TRPN +# + Jdiff * vss / vmyo +# - Jup * vnsr / vmyo +# + 0.5 * (-ICab - IpCa - Isac_P_ns / 3.0 + 2.0 * INaCa_i) * Acap / (F * vmyo) +# ) * Bcai + +# F_expressions[45] = dLambda * As - Zetas * cs +# F_expressions[46] = dLambda * Aw - Zetaw * cw +# # State 46 and 47 is lambda and dLambda respectively + +# # Return results +# return as_vector(F_expressions) + +# def num_states(self): +# return 47 - C = -1.0 + lambda_min12 - dCd = -Cd + C - eta = ufl.conditional(ufl.lt(dCd, 0.0), etas, etal) - F_expressions[43] = p_k * (-Cd + C) / eta - Bcai = 1.0 / (1.0 + cmdnmax * kmcmdn * ufl.elem_pow(kmcmdn + cai, -2.0)) - J_TRPN = trpnmax * F_expressions[41] - F_expressions[44] = ( - -J_TRPN - + Jdiff * vss / vmyo - - Jup * vnsr / vmyo - + 0.5 * (-ICab - IpCa - Isac_P_ns / 3.0 + 2.0 * INaCa_i) * Acap / (F * vmyo) - ) * Bcai - - F_expressions[45] = dLambda * As - Zetas * cs - F_expressions[46] = dLambda * Aw - Zetaw * cw - # State 46 and 47 is lambda and dLambda respectively - - # Return results - return as_vector(F_expressions) - - def num_states(self): - return 47 - - def __str__(self): - return "ORdmm_Land_em_coupling cardiac cell model" +# def __str__(self): +# return "ORdmm_Land_em_coupling cardiac cell model" diff --git a/src/simcardems/models/pureEP_ORdmm_Land/em_model.py b/src/simcardems/models/pureEP_ORdmm_Land/em_model.py index 9f8e0d41..7ce8185f 100644 --- a/src/simcardems/models/pureEP_ORdmm_Land/em_model.py +++ b/src/simcardems/models/pureEP_ORdmm_Land/em_model.py @@ -33,8 +33,8 @@ def coupling_type(self): return "pureEP_ORdmm_Land" @property - def vs(self) -> dolfin.Function: - return self.ep_solver.solution_fields()[0] + def vs(self) -> np.ndarray: + return self.ep_solver.ode.values def register_ep_model(self, solver: cbcbeat.SplittingSolver): logger.debug("Registering EP model") @@ -48,7 +48,7 @@ def __eq__(self, __o: object) -> bool: if not super().__eq__(__o): return False - if not np.allclose(self.vs.vector().get_local(), __o.vs.vector().get_local()): + if not np.allclose(self.vs, __o.vs): return False return True @@ -61,42 +61,46 @@ def assigners(self, assigners) -> None: self._assigners = assigners def setup_assigners(self) -> None: - from ...datacollector import Assigners - - self.assigners = Assigners(vs=self.vs, mech_state=None) - for name, index in [ - ("V", 0), - ("Ca", 45), - ("XS", 40), - ("XW", 41), - ("CaTrpn", 42), - ("TmB", 43), - ("Cd", 44), - ]: - self.assigners.register_subfunction( - name=name, - group="ep", - subspace_index=index, - ) + ... + # from ...datacollector import Assigners + + # self.assigners = Assigners(vs=self.vs, mech_state=None) + # for name, index in [ + # ("V", 0), + # ("Ca", 41), + # ("XS", 40), + # ("XW", 41), + # ("CaTrpn", 42), + # ("TmB", 43), + # ("Cd", 44), + # ]: + # self.assigners.register_subfunction( + # name=name, + # group="ep", + # subspace_index=index, + # ) + # pass def solve_ep(self, interval: Tuple[float, float]) -> None: self.ep_solver.step(interval) def print_ep_info(self): # Output some degrees of freedom - total_dofs = self.vs.function_space().dim() + + total_dofs = self.ep_solver.pde.V.dim() logger.info("EP model") utils.print_mesh_info(self.ep_mesh, total_dofs) def cell_params(self): - return self.ep_solver.ode_solver._model.parameters() + return self.ep_solver.ode.parameters @property def ep_mesh(self): return self.geometry.ep_mesh def update_prev_ep(self): - self.ep_solver.vs_.assign(self.ep_solver.vs) + ... + # self.ep_solver.vs_.assign(self.ep_solver.vs) def save_state( self, @@ -104,20 +108,30 @@ def save_state( config: Optional[Config] = None, ) -> None: super().save_state(path=path, config=config) - - with dolfin.HDF5File( - self.geometry.comm(), - Path(path).as_posix(), - "a", - ) as h5file: - h5file.write(self.ep_solver.vs, "/ep/vs") - - io.dict_to_h5( - self.cell_params(), - path, - "ep/cell_params", - comm=self.geometry.comm(), - ) + # breakpoint() + + # with dolfin.HDF5File( + # self.geometry.comm(), + # Path(path).as_posix(), + # "a", + # ) as h5file: + # h5file.write(self.ep_solver.vs, "/ep/vs") + with io.h5pyfile(path, "a") as h5file: + h5file["ep/vs"] = self.vs + h5file["ep/cell_params"] = self.cell_params() + + # io.dict_to_h5( + # self.vs, + # path, + # "ep/vs", + # comm=self.geometry.comm(), + # ) + # io.dict_to_h5( + # self.cell_params(), + # path, + # "ep/cell_params", + # comm=self.geometry.comm(), + # ) @classmethod def from_state( @@ -138,26 +152,28 @@ def from_state( with io.h5pyfile(path) as h5file: config = Config(**io.h5_to_dict(h5file["config"])) state_params = io.h5_to_dict(h5file["state_params"]) - cell_params = io.h5_to_dict(h5file["ep"]["cell_params"]) - vs_signature = h5file["ep"]["vs"].attrs["signature"].decode() + cell_params = h5file["ep"]["cell_params"][:] + vs = h5file["ep"]["vs"][:] + # vs_signature = h5file["ep"]["vs"].attrs["signature"].decode() config.drug_factors_file = drug_factors_file config.popu_factors_file = popu_factors_file config.disease_state = disease_state config.PCL = PCL - VS = dolfin.FunctionSpace(geo.ep_mesh, eval(vs_signature)) - vs = dolfin.Function(VS) + # VS = dolfin.FunctionSpace(geo.ep_mesh, eval(vs_signature)) + # vs = dolfin.Function(VS) logger.debug("Load functions") - with dolfin.HDF5File(geo.ep_mesh.mpi_comm(), path.as_posix(), "r") as h5file: - h5file.read(vs, "/ep/vs") + # with dolfin.HDF5File(geo.ep_mesh.mpi_comm(), path.as_posix(), "r") as h5file: + # h5file.read(vs, "/ep/vs") + # from . import cell_model as model from . import CellModel, ActiveModel - cell_inits = io.vs_functions_to_dict( - vs, - state_names=CellModel.default_initial_conditions().keys(), - ) + # cell_inits = io.vs_functions_to_dict( + # vs, + # state_names=CellModel.default_initial_conditions().keys(), + # ) return setup_EM_model( cls_EMCoupling=cls, @@ -165,7 +181,7 @@ def from_state( cls_ActiveModel=ActiveModel, geometry=geo, config=config, - cell_inits=cell_inits, + cell_inits=vs, cell_params=cell_params, state_params=state_params, ) diff --git a/src/simcardems/runner.py b/src/simcardems/runner.py index fbd58de7..bfb28ca3 100644 --- a/src/simcardems/runner.py +++ b/src/simcardems/runner.py @@ -124,7 +124,7 @@ def from_models( def store(self): # Assign u, v and Ca for postprocessing - self.coupling.assigners.assign() + # self.coupling.assigners.assign() self.collector.store(TimeStepper.ns2ms(self.t)) def _setup_datacollector(self): @@ -136,18 +136,19 @@ def _setup_datacollector(self): reset_state=self._reset, outfilename=self._config.outfilename, ) - self.coupling.register_datacollector(self.collector) + # self.coupling.register_datacollector(self.collector) def _solve_mechanics_now(self) -> bool: if self._config.mechanics_solve_strategy == "fixed": return self.coupling.dt_mechanics > self._config.dt_mech - self.coupling.assigners.assign_pre() - norm = self.coupling.assigners.compute_pre_norm() - return ( - norm >= self._config.mech_threshold - or self.coupling.dt_mechanics > self._config.dt_mech - ) + # self.coupling.assigners.assign_pre() + # norm = self.coupling.assigners.compute_pre_norm() + # return ( + # norm >= self._config.mech_threshold + # or self.coupling.dt_mechanics > self._config.dt_mech + # ) + return True def _post_mechanics_solve(self) -> None: # Update previous lmbda diff --git a/tests/test_models.py b/tests/test_models.py index ddca171b..8c597e09 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -60,4 +60,5 @@ def test_pure_ep_ORdmm_Land(geo, tmpdir): new_coupling = models.pureEP_ORdmm_Land.EMCoupling.from_state( path=runner.state_path, ) + assert new_coupling == coupling From 4e7057ce77ae4d07411369e30e5258ac664ff809 Mon Sep 17 00:00:00 2001 From: Henrik Finsberg Date: Tue, 16 Jan 2024 08:49:18 +0100 Subject: [PATCH 2/7] Make it work with explicit model --- .cspell_dict.txt | 1 + src/simcardems/datacollector.py | 38 +- src/simcardems/ep_model.py | 94 +- .../models/explicit_ORdmm_Land/__init__.py | 4 +- .../models/explicit_ORdmm_Land/cell_model.py | 4679 +++++++++++------ .../models/explicit_ORdmm_Land/em_model.py | 109 +- .../models/pureEP_ORdmm_Land/cell_model.py | 2071 +------- .../models/pureEP_ORdmm_Land/em_model.py | 37 +- src/simcardems/runner.py | 16 +- tests/test_models.py | 4 +- 10 files changed, 3455 insertions(+), 3598 deletions(-) diff --git a/.cspell_dict.txt b/.cspell_dict.txt index fbb56664..e38748b1 100644 --- a/.cspell_dict.txt +++ b/.cspell_dict.txt @@ -303,6 +303,7 @@ noninteractive ntm ntrpn numpyfy +odesolver onlylastbeat opencarp opencmiss diff --git a/src/simcardems/datacollector.py b/src/simcardems/datacollector.py index decd8f50..2cf25b8b 100644 --- a/src/simcardems/datacollector.py +++ b/src/simcardems/datacollector.py @@ -7,11 +7,9 @@ from typing import Tuple from typing import Union -import cbcbeat import dolfin import h5py import numpy as np -import pulse from dolfin import FiniteElement # noqa: F401 from dolfin import tetrahedron # noqa: F401 from dolfin import VectorElement # noqa: F401 @@ -51,17 +49,21 @@ class Assigners: def __init__( self, *, - vs: Optional[cbcbeat.SplittingSolver] = None, - mech_state: Optional[pulse.MechanicsProblem] = None, + vs: Optional[np.ndarray] = None, + mech_state: Optional[dolfin.Function] = None, + V_mech: Optional[dolfin.FunctionSpace] = None, + V_ep: Optional[dolfin.FunctionSpace] = None, ) -> None: self.vs = vs self.mech_state = mech_state + self.V_mech = V_mech + self.V_ep = V_ep self.functions: Dict[str, Dict[str, dolfin.Function]] = { "ep": {}, "mechanics": {}, } - self.assigners: Dict[str, Dict[str, dolfin.FunctionAssigner]] = { + self.assigners: Dict[str, Dict[str, Optional[dolfin.FunctionAssigner]]] = { "ep": {}, "mechanics": {}, } @@ -74,7 +76,7 @@ def __init__( "ep": {}, "mechanics": {}, } - self.pre_assigners: Dict[str, Dict[str, dolfin.FunctionAssigner]] = { + self.pre_assigners: Dict[str, Dict[str, Optional[dolfin.FunctionAssigner]]] = { "ep": {}, "mechanics": {}, } @@ -89,14 +91,14 @@ def assign(self) -> None: def assign_pre(self) -> None: self.assign_pre_mechanics() - self.assign_ep() + self.assign_pre_ep() def _get( self, is_pre: bool, ) -> Tuple[ Dict[str, Dict[str, dolfin.Function]], - Dict[str, Dict[str, dolfin.FunctionAssigner]], + Dict[str, Dict[str, Optional[dolfin.FunctionAssigner]]], Dict[str, Dict[str, int]], ]: if is_pre: @@ -142,15 +144,11 @@ def _assign_ep(self, is_pre: bool) -> None: raise RuntimeError("Unable to assign EP, no EP state registered") for name in keys: - assigner = assigners["ep"].get(name) index = subspace_indices["ep"].get(name) f = functions["ep"].get(name) - if assign_item_is_None(f, assigner, index): + if f is None or index is None: continue - - # Could ass a typeguard here: https://peps.python.org/pep-0647/ - # but this will need python3.10 - assigner.assign(f, utils.sub_function(self.vs, index)) # type: ignore + f.vector()[:] = self.vs[index] def assign_pre_ep(self) -> None: self._assign_ep(is_pre=True) @@ -182,8 +180,16 @@ def register_subfunction( subspace_index: int, is_pre: bool = False, ) -> None: - func = self.vs if group == "ep" else self.mech_state - f, assigner = utils.setup_assigner(func, subspace_index) + V = self.V_ep if group == "ep" else self.V_mech + if V is None: + raise RuntimeError( + f"Unable to register subfunction {name} in group {group}, no function space", + ) + if group == "ep": + assigner = None + f = dolfin.Function(V) + else: + f, assigner = utils.setup_assigner(self.mech_state, subspace_index) functions, assigners, subspace_indices = self._get(is_pre) functions[group][name] = f assigners[group][name] = assigner diff --git a/src/simcardems/ep_model.py b/src/simcardems/ep_model.py index 55f4a344..809f0ffc 100644 --- a/src/simcardems/ep_model.py +++ b/src/simcardems/ep_model.py @@ -6,15 +6,14 @@ from typing import Dict from typing import NamedTuple from typing import Optional -from typing import Type +from typing import Protocol from typing import TYPE_CHECKING import beat import dolfin +import numpy as np import pulse -# import cbcbeat - try: import ufl_legacy as ufl except ImportError: @@ -37,15 +36,31 @@ class CellModel(NamedTuple): parameters: Dict[str, float] | Dict[int, Dict[str, float]] v_index: int | Dict[int, int] fun: Callable | Dict[int, Callable] - markers = None @property def num_states(self): return len(self.init_states) +class CellModelType(Protocol): + def init_state_values(self) -> Dict[str, float]: + ... + + def init_parameter_values(self) -> Dict[str, float]: + ... + + def state_index(self, name: str) -> int: + ... + + def forward_generalized_rush_larsen( + self, + coupling: BaseEMCoupling, + ) -> Callable[[np.ndarray, float, float, np.ndarray], np.ndarray]: + ... + + def setup_cell_model( - model, + model: CellModelType, coupling: BaseEMCoupling, cell_params=None, cell_inits=None, @@ -61,6 +76,7 @@ def setup_cell_model( # popu_factors_file=popu_factors_file, # CellModel=cls, # ) + # FIXME: Handle case when files are passed in if cell_params is None: parameters = model.init_parameter_values() else: @@ -82,13 +98,11 @@ def setup_cell_model( # coupling=coupling, # ) - # model = beat.cellmodels.torord_dyn_chloride.mid - return CellModel( init_states=init_states, parameters=parameters, v_index=model.state_index("v"), - fun=model.forward_generalized_rush_larsen, + fun=model.forward_generalized_rush_larsen(coupling=coupling), ) @@ -269,38 +283,38 @@ def load_json(filename: str): return d -def handle_cell_params( - CellModel: Type[BaseCellModel], - cell_params: Optional[Dict[str, float]] = None, - disease_state: str = "healthy", - drug_factors_file: str = "", - popu_factors_file: str = "", -): - cell_params_tmp = CellModel.default_parameters() - # FIXME: In this case we update the parameters first, while in the - # initial condition case we do that last. We need to be consistent - # about this. - if cell_params is not None: - cell_params_tmp.update(cell_params) - - CellModel.update_disease_parameters(cell_params_tmp, disease_state=disease_state) - # Adding optional drug factors to parameters (if drug_factors_file exists) - if file_exist(drug_factors_file, ".json"): - logger.info(f"Drug scaling factors loaded from {drug_factors_file}") - cell_params_tmp.update(load_json(drug_factors_file)) - else: - if drug_factors_file != "": - logger.warning(f"Unable to load drug factors file {drug_factors_file}") - # FIXME: A problem here is that popu_factors_file will overwrite the - # drug_factors_file. Is it possible to only have one file? - if file_exist(popu_factors_file, ".json"): - logger.info(f"Population scaling factors loaded from {popu_factors_file}") - cell_params_tmp.update(load_json(popu_factors_file)) - else: - if popu_factors_file != "": - logger.warning(f"Unable to load popu factors file {popu_factors_file}") - - return cell_params_tmp +# def handle_cell_params( +# CellModel: Type[BaseCellModel], +# cell_params: Optional[Dict[str, float]] = None, +# disease_state: str = "healthy", +# drug_factors_file: str = "", +# popu_factors_file: str = "", +# ): +# cell_params_tmp = CellModel.default_parameters() +# # FIXME: In this case we update the parameters first, while in the +# # initial condition case we do that last. We need to be consistent +# # about this. +# if cell_params is not None: +# cell_params_tmp.update(cell_params) + +# CellModel.update_disease_parameters(cell_params_tmp, disease_state=disease_state) +# # Adding optional drug factors to parameters (if drug_factors_file exists) +# if file_exist(drug_factors_file, ".json"): +# logger.info(f"Drug scaling factors loaded from {drug_factors_file}") +# cell_params_tmp.update(load_json(drug_factors_file)) +# else: +# if drug_factors_file != "": +# logger.warning(f"Unable to load drug factors file {drug_factors_file}") +# # FIXME: A problem here is that popu_factors_file will overwrite the +# # drug_factors_file. Is it possible to only have one file? +# if file_exist(popu_factors_file, ".json"): +# logger.info(f"Population scaling factors loaded from {popu_factors_file}") +# cell_params_tmp.update(load_json(popu_factors_file)) +# else: +# if popu_factors_file != "": +# logger.warning(f"Unable to load popu factors file {popu_factors_file}") + +# return cell_params_tmp # def handle_cell_inits( diff --git a/src/simcardems/models/explicit_ORdmm_Land/__init__.py b/src/simcardems/models/explicit_ORdmm_Land/__init__.py index bd030885..b4d91679 100644 --- a/src/simcardems/models/explicit_ORdmm_Land/__init__.py +++ b/src/simcardems/models/explicit_ORdmm_Land/__init__.py @@ -2,10 +2,12 @@ import pulse from . import cell_model +from . import cell_model as CellModel from . import em_model -from .cell_model import ORdmmLandExplicit as CellModel from .em_model import EMCoupling +# from .cell_model import ORdmmLandExplicit as CellModel + loggers = [ "simcardems.explicit_ORdmm_Land.cell_model.logger", "simcardems.explicit_ORdmm_Land.em_model.logger", diff --git a/src/simcardems/models/explicit_ORdmm_Land/cell_model.py b/src/simcardems/models/explicit_ORdmm_Land/cell_model.py index 36ef2f7d..0dba209a 100644 --- a/src/simcardems/models/explicit_ORdmm_Land/cell_model.py +++ b/src/simcardems/models/explicit_ORdmm_Land/cell_model.py @@ -1,1679 +1,3124 @@ +# flake8: noqa: F841 """This module contains a ORdmm_Land_em_coupling cardiac cell model The module was autogenerated from a gotran ode file -""" -from collections import OrderedDict -from typing import Dict +# """ +import math -import dolfin -from dolfin import as_vector -from dolfin import Constant - -try: - import ufl_legacy as ufl -except ImportError: - import ufl +import numpy from ... import utils -from ..cell_model import BaseCellModel from .em_model import EMCoupling +# from collections import OrderedDict +# from typing import Dict +# import dolfin +# from dolfin import as_vector +# from dolfin import Constant +# try: +# import ufl_legacy as ufl +# except ImportError: +# import ufl +# from ..cell_model import BaseCellModel + logger = utils.getLogger(__name__) -def Max(a, b): - return (a + b + abs(a - b)) / Constant(2.0) - - -def Min(a, b): - return (a + b - abs(a - b)) / Constant(2.0) - - -class ORdmmLandExplicit(BaseCellModel): - def __init__( - self, - coupling: EMCoupling, - params=None, - init_conditions=None, - ): - """ - Create cardiac cell model - - *Arguments* - params (dict, :py:class:`dolfin.Mesh`, optional) - optional model parameters - init_conditions (dict, :py:class:`dolfin.Mesh`, optional) - optional initial conditions - """ - logger.debug("Initialize ORdmm Land model") - - super().__init__(params, init_conditions) - self.lmbda = coupling.lmbda_ep - self.dLambda = coupling.dLambda_ep - - @staticmethod - def update_disease_parameters( - params: Dict[str, float], - disease_state: str = "healthy", - ) -> None: - if disease_state.lower() == "hf": - logger.info("Update scaling parameters for heart failure model") - params["HF_scaling_CaMKa"] = 1.50 - params["HF_scaling_Jrel_inf"] = pow(0.8, 8.0) - params["HF_scaling_Jleak"] = 1.3 - params["HF_scaling_Jup"] = 0.45 - params["HF_scaling_GNaL"] = 1.3 - params["HF_scaling_GK1"] = 0.68 - params["HF_scaling_thL"] = 1.8 - params["HF_scaling_Gto"] = 0.4 - params["HF_scaling_Gncx"] = 1.6 - params["HF_scaling_Pnak"] = 0.7 - params["HF_scaling_cat50_ref"] = 0.6 - - @staticmethod - def default_parameters() -> Dict[str, float]: - """Set-up and return default parameters. - - Parameters - ---------- - disease_state : str, optional - String with "hf" or "healthy", by default "healthy". - If "hf", then parameters representing heart failure - will be used. - - Returns - ------- - OrderedDict - Dictionary with default values - """ - params = OrderedDict( - [ - ("scale_ICaL", 1.018), - ("scale_IK1", 1.414), - ("scale_IKr", 1.119), - ("scale_IKs", 1.648), - ("scale_INaL", 2.274), - ("celltype", 0), - ("cao", 1.8), - ("ko", 5.4), - ("nao", 140.0), - ("F", 96485.0), - ("R", 8314.0), - ("T", 310.0), - ("L", 0.01), - ("rad", 0.0011), - ("Ahf", 0.99), - ("GNa", 31), - ("thL", 200.0), - ("Gto", 0.02), - ("delta_epi", 1.0), - ("Aff", 0.6), - ("Kmn", 0.002), - ("k2n", 1000.0), - ("tjca", 75.0), - ("zca", 2.0), - ("bt", 4.75), - ("Beta0", 2.3), - ("Beta1", -2.4), - ("Tot_A", 25), - ("Tref", 120), - ("Trpn50", 0.35), - ("calib", 1), - ("cat50_ref", 0.805), - ("emcoupling", 1), - ("etal", 200), - ("etas", 20), - ("gammas", 0.0085), - ("gammaw", 0.615), - ("isacs", 0), - ("ktrpn", 0.1), - ("ku", 0.04), - ("kuw", 0.182), - ("kws", 0.012), - ("mode", 1), - ("ntm", 2.4), - ("ntrpn", 2.0), - ("p_a", 2.1), - ("p_b", 9.1), - ("p_k", 7.0), - ("phi", 2.23), - ("rs", 0.25), - ("rw", 0.5), - ("CaMKo", 0.05), - ("KmCaM", 0.0015), - ("KmCaMK", 0.15), - ("aCaMK", 0.05), - ("bCaMK", 0.00068), - ("PKNa", 0.01833), - ("Gncx", 0.0008), - ("KmCaAct", 0.00015), - ("kasymm", 12.5), - ("kcaoff", 5000.0), - ("kcaon", 1500000.0), - ("kna1", 15.0), - ("kna2", 5.0), - ("kna3", 88.12), - ("qca", 0.167), - ("qna", 0.5224), - ("wca", 60000.0), - ("wna", 60000.0), - ("wnaca", 5000.0), - ("H", 1e-07), - ("Khp", 1.698e-07), - ("Kki", 0.5), - ("Kko", 0.3582), - ("Kmgatp", 1.698e-07), - ("Knai0", 9.073), - ("Knao0", 27.78), - ("Knap", 224.0), - ("Kxkur", 292.0), - ("MgADP", 0.05), - ("MgATP", 9.8), - ("Pnak", 30.0), - ("delta", -0.155), - ("eP", 4.2), - ("k1m", 182.4), - ("k1p", 949.5), - ("k2m", 39.4), - ("k2p", 687.2), - ("k3m", 79300.0), - ("k3p", 1899.0), - ("k4m", 40.0), - ("k4p", 639.0), - ("zk", 1.0), - ("GKb", 0.003), - ("PNab", 3.75e-10), - ("PCab", 2.5e-08), - ("GpCa", 0.0005), - ("Esac_ns", -10.0), - ("Gsac_k", 1.097904761904762), - ("Gsac_ns", 0.006), - ("lambda_max", 1.1), - ("amp", -80.0), - ("duration", 0.5), - ("BSLmax", 1.124), - ("BSRmax", 0.047), - ("KmBSL", 0.0087), - ("KmBSR", 0.00087), - ("cmdnmax", 0.05), - ("csqnmax", 10.0), - ("kmcmdn", 0.00238), - ("kmcsqn", 0.8), - ("kmtrpn", 0.0005), - ("trpnmax", 0.07), - # Drug factors - ("scale_drug_INa", 1.0), - ("scale_drug_INaL", 1.0), - ("scale_drug_Ito", 1.0), - ("scale_drug_ICaL", 1.0), - ("scale_drug_IKr", 1.0), - ("scale_drug_IKs", 1.0), - ("scale_drug_IK1", 1.0), - ("scale_drug_IKb", 1.0), - ("scale_drug_INab", 1.0), - ("scale_drug_ICab", 1.0), - ("scale_drug_IpCa", 1.0), - ("scale_drug_Isacns", 1.0), - ("scale_drug_Isack", 1.0), - # Population factors - ("scale_popu_GNa", 1.0), - ("scale_popu_GCaL", 1.0), - ("scale_popu_Gto", 1.0), - ("scale_popu_GNaL", 1.0), - ("scale_popu_GKr", 1.0), - ("scale_popu_GKs", 1.0), - ("scale_popu_GK1", 1.0), - ("scale_popu_GbK", 1.0), - ("scale_popu_KNCX", 1.0), - ("scale_popu_KNaK", 1.0), - ("scale_popu_GbNa", 1.0), - ("scale_popu_GbCa", 1.0), - ("scale_popu_KpCa", 1.0), - ("scale_popu_KRyR", 1.0), - ("scale_popu_KSERCA", 1.0), - ("scale_popu_Kleak", 1.0), - ("scale_popu_nTm", 1.0), - ("scale_popu_CaT50ref", 1.0), - ("scale_popu_Tref", 1.0), - ("scale_popu_kuw", 1.0), - ("scale_popu_kws", 1.0), - ("scale_popu_kTRPN", 1.0), - ("scale_popu_nTRPN", 1.0), - ("scale_popu_ku", 1.0), - ("scale_popu_TRPN50", 1.0), - ("scale_popu_rw", 1.0), - ("scale_popu_rs", 1.0), - # HF scaling factors - ("HF_scaling_CaMKa", 1.0), - ("HF_scaling_Jrel_inf", 1.0), - ("HF_scaling_Jleak", 1.0), - ("HF_scaling_Jup", 1.0), - ("HF_scaling_GNaL", 1.0), - ("HF_scaling_GK1", 1.0), - ("HF_scaling_thL", 1.0), - ("HF_scaling_Gto", 1.0), - ("HF_scaling_Gncx", 1.0), - ("HF_scaling_Pnak", 1.0), - ("HF_scaling_cat50_ref", 1.0), - ], - ) - - return params - - @staticmethod - def default_initial_conditions(): - "Set-up and return default initial conditions." - ic = OrderedDict( - [ - ("v", -87), - ("CaMKt", 0), - ("m", 0), - ("hf", 1), - ("hs", 1), - ("j", 1), - ("hsp", 1), - ("jp", 1), - ("mL", 0), - ("hL", 1), - ("hLp", 1), - ("a", 0), - ("iF", 1), - ("iS", 1), - ("ap", 0), - ("iFp", 1), - ("iSp", 1), - ("d", 0), - ("ff", 1), - ("fs", 1), - ("fcaf", 1), - ("fcas", 1), - ("jca", 1), - ("ffp", 1), - ("fcafp", 1), - ("nca", 0), - ("xrf", 0), - ("xrs", 0), - ("xs1", 0), - ("xs2", 0), - ("xk1", 1), - ("Jrelnp", 0), - ("Jrelp", 0), - ("nai", 7), - ("nass", 7), - ("ki", 145), - ("kss", 145), - ("cass", 0.0001), - ("cansr", 1.2), - ("cajsr", 1.2), - ("XS", 0), - ("XW", 0), - ("CaTrpn", 0), - ("TmB", 1), - ("Cd", 0), - ("cai", 0.0001), - ("Zetas", 0), - ("Zetaw", 0), - ], - ) - return ic - - def _I(self, v, s, time): - """ - Original gotran transmembrane current dV/dt - """ - time = time if time else Constant(0.0) - logger.debug("Evaluate transmembrane current") +def parameter_index(name: str) -> int: + """Return the index of the parameter with the given name + + Arguments + --------- + name : str + The name of the parameter + + Returns + ------- + int + The index of the parameter + + Raises + ------ + KeyError + If the name is not a valid parameter + """ + + data = { + "Aff": 0, + "Ahf": 1, + "BSLmax": 2, + "BSRmax": 3, + "Beta0": 4, + "Beta1": 5, + "CaMKo": 6, + "Esac_ns": 7, + "F": 8, + "GKb": 9, + "GNa": 10, + "Gncx": 11, + "GpCa": 12, + "Gsac_k": 13, + "Gsac_ns": 14, + "Gto": 15, + "H": 16, + "Khp": 17, + "Kki": 18, + "Kko": 19, + "KmBSL": 20, + "KmBSR": 21, + "KmCaAct": 22, + "KmCaM": 23, + "KmCaMK": 24, + "Kmgatp": 25, + "Kmn": 26, + "Knai0": 27, + "Knao0": 28, + "Knap": 29, + "Kxkur": 30, + "L": 31, + "MgADP": 32, + "MgATP": 33, + "PCab": 34, + "PKNa": 35, + "PNab": 36, + "Pnak": 37, + "R": 38, + "T": 39, + "Tot_A": 40, + "Tref": 41, + "Trpn50": 42, + "aCaMK": 43, + "amp": 44, + "bCaMK": 45, + "bt": 46, + "calib": 47, + "cao": 48, + "cat50_ref": 49, + "celltype": 50, + "cmdnmax": 51, + "csqnmax": 52, + "dLambda": 53, + "delta": 54, + "delta_epi": 55, + "duration": 56, + "eP": 57, + "emcoupling": 58, + "etal": 59, + "etas": 60, + "gammas": 61, + "gammaw": 62, + "isacs": 63, + "k1m": 64, + "k1p": 65, + "k2m": 66, + "k2n": 67, + "k2p": 68, + "k3m": 69, + "k3p": 70, + "k4m": 71, + "k4p": 72, + "kasymm": 73, + "kcaoff": 74, + "kcaon": 75, + "kmcmdn": 76, + "kmcsqn": 77, + "kmtrpn": 78, + "kna1": 79, + "kna2": 80, + "kna3": 81, + "ko": 82, + "ktrpn": 83, + "ku": 84, + "kuw": 85, + "kws": 86, + "lambda_max": 87, + "lmbda": 88, + "mode": 89, + "nao": 90, + "ntm": 91, + "ntrpn": 92, + "p_a": 93, + "p_b": 94, + "p_k": 95, + "phi": 96, + "qca": 97, + "qna": 98, + "rad": 99, + "rs": 100, + "rw": 101, + "scale_HF_CaMKa": 102, + "scale_HF_GK1": 103, + "scale_HF_GNaL": 104, + "scale_HF_Gncx": 105, + "scale_HF_Gto": 106, + "scale_HF_Jleak": 107, + "scale_HF_Jrel_inf": 108, + "scale_HF_Jup": 109, + "scale_HF_Pnak": 110, + "scale_HF_cat50_ref": 111, + "scale_HF_thL": 112, + "scale_ICaL": 113, + "scale_IK1": 114, + "scale_IKr": 115, + "scale_IKs": 116, + "scale_INaL": 117, + "scale_drug_ICaL": 118, + "scale_drug_ICab": 119, + "scale_drug_IK1": 120, + "scale_drug_IKb": 121, + "scale_drug_IKr": 122, + "scale_drug_IKs": 123, + "scale_drug_INa": 124, + "scale_drug_INaL": 125, + "scale_drug_INab": 126, + "scale_drug_IpCa": 127, + "scale_drug_Isack": 128, + "scale_drug_Isacns": 129, + "scale_drug_Ito": 130, + "thL": 131, + "tjca": 132, + "trpnmax": 133, + "wca": 134, + "wna": 135, + "wnaca": 136, + "zca": 137, + "zk": 138, + } + return data[name] + + +def state_index(name: str) -> int: + """Return the index of the state with the given name + + Arguments + --------- + name : str + The name of the state + + Returns + ------- + int + The index of the state + + Raises + ------ + KeyError + If the name is not a valid state + """ + + data = { + "hL": 0, + "a": 1, + "ap": 2, + "d": 3, + "ff": 4, + "fs": 5, + "hf": 6, + "hs": 7, + "m": 8, + "xrf": 9, + "xrs": 10, + "xs1": 11, + "CaMKt": 12, + "xk1": 13, + "Zetaw": 14, + "XS": 15, + "XW": 16, + "TmB": 17, + "hLp": 18, + "iF": 19, + "iS": 20, + "fcaf": 21, + "fcas": 22, + "jca": 23, + "j": 24, + "fcafp": 25, + "ffp": 26, + "hsp": 27, + "jp": 28, + "mL": 29, + "xs2": 30, + "Zetas": 31, + "nca": 32, + "CaTrpn": 33, + "iFp": 34, + "iSp": 35, + "cajsr": 36, + "cansr": 37, + "kss": 38, + "Cd": 39, + "Jrelnp": 40, + "Jrelp": 41, + "ki": 42, + "cass": 43, + "nass": 44, + "cai": 45, + "nai": 46, + "v": 47, + } + return data[name] + + +def init_parameter_values(**values): + """Initialize parameter values""" + # Aff=0.6, Ahf=0.99, BSLmax=1.124, BSRmax=0.047, Beta0=2.3 + # Beta1=-2.4, CaMKo=0.05, Esac_ns=-10, F=96485.0, GKb=0.003 + # GNa=31, Gncx=0.0008, GpCa=0.0005, Gsac_k=(0.2882*800)/210 + # Gsac_ns=0.006, Gto=0.02, H=1e-07, Khp=1.698e-07, Kki=0.5 + # Kko=0.3582, KmBSL=0.0087, KmBSR=0.00087, KmCaAct=0.00015 + # KmCaM=0.0015, KmCaMK=0.15, Kmgatp=1.698e-07, Kmn=0.002 + # Knai0=9.073, Knao0=27.78, Knap=224.0, Kxkur=292.0, L=0.01 + # MgADP=0.05, MgATP=9.8, PCab=2.5e-08, PKNa=0.01833 + # PNab=3.75e-10, Pnak=30, R=8314.0, T=310.0, Tot_A=25, Tref=120 + # Trpn50=0.35, aCaMK=0.05, amp=-80.0, bCaMK=0.00068, bt=4.75 + # calib=1, cao=1.8, cat50_ref=0.805, celltype=0, cmdnmax=0.05 + # csqnmax=10.0, dLambda=0, delta=-0.155, delta_epi=1.0 + # duration=0.5, eP=4.2, emcoupling=1, etal=200, etas=20 + # gammas=0.0085, gammaw=0.615, isacs=0, k1m=182.4, k1p=949.5 + # k2m=39.4, k2n=1000.0, k2p=687.2, k3m=79300.0, k3p=1899.0 + # k4m=40.0, k4p=639.0, kasymm=12.5, kcaoff=5000.0 + # kcaon=1500000.0, kmcmdn=0.00238, kmcsqn=0.8, kmtrpn=0.0005 + # kna1=15.0, kna2=5.0, kna3=88.12, ko=5.4, ktrpn=0.1, ku=0.04 + # kuw=0.182, kws=0.012, lambda_max=1.1, lmbda=1, mode=1 + # nao=140.0, ntm=2.4, ntrpn=2, p_a=2.1, p_b=9.1, p_k=7 + # phi=2.23, qca=0.167, qna=0.5224, rad=0.0011, rs=0.25, rw=0.5 + # scale_HF_CaMKa=1.0, scale_HF_GK1=1.0, scale_HF_GNaL=1.0 + # scale_HF_Gncx=1.0, scale_HF_Gto=1.0, scale_HF_Jleak=1.0 + # scale_HF_Jrel_inf=1.0, scale_HF_Jup=1.0, scale_HF_Pnak=1.0 + # scale_HF_cat50_ref=1.0, scale_HF_thL=1.0, scale_ICaL=1.018 + # scale_IK1=1.414, scale_IKr=1.119, scale_IKs=1.648 + # scale_INaL=2.274, scale_drug_ICaL=1.0, scale_drug_ICab=1.0 + # scale_drug_IK1=1.0, scale_drug_IKb=1.0, scale_drug_IKr=1.0 + # scale_drug_IKs=1.0, scale_drug_INa=1.0, scale_drug_INaL=1.0 + # scale_drug_INab=1.0, scale_drug_IpCa=1.0 + # scale_drug_Isack=1.0, scale_drug_Isacns=1.0 + # scale_drug_Ito=1.0, thL=200.0, tjca=75.0, trpnmax=0.07 + # wca=60000.0, wna=60000.0, wnaca=5000.0, zca=2.0, zk=1.0 + + parameters = numpy.array( + [ + 0.6, + 0.99, + 1.124, + 0.047, + 2.3, + -2.4, + 0.05, + -10, + 96485.0, + 0.003, + 31, + 0.0008, + 0.0005, + (0.2882 * 800) / 210, + 0.006, + 0.02, + 1e-07, + 1.698e-07, + 0.5, + 0.3582, + 0.0087, + 0.00087, + 0.00015, + 0.0015, + 0.15, + 1.698e-07, + 0.002, + 9.073, + 27.78, + 224.0, + 292.0, + 0.01, + 0.05, + 9.8, + 2.5e-08, + 0.01833, + 3.75e-10, + 30, + 8314.0, + 310.0, + 25, + 120, + 0.35, + 0.05, + -80.0, + 0.00068, + 4.75, + 1, + 1.8, + 0.805, + 0, + 0.05, + 10.0, + 0, + -0.155, + 1.0, + 0.5, + 4.2, + 1, + 200, + 20, + 0.0085, + 0.615, + 0, + 182.4, + 949.5, + 39.4, + 1000.0, + 687.2, + 79300.0, + 1899.0, + 40.0, + 639.0, + 12.5, + 5000.0, + 1500000.0, + 0.00238, + 0.8, + 0.0005, + 15.0, + 5.0, + 88.12, + 5.4, + 0.1, + 0.04, + 0.182, + 0.012, + 1.1, + 1, + 1, + 140.0, + 2.4, + 2, + 2.1, + 9.1, + 7, + 2.23, + 0.167, + 0.5224, + 0.0011, + 0.25, + 0.5, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.018, + 1.414, + 1.119, + 1.648, + 2.274, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 200.0, + 75.0, + 0.07, + 60000.0, + 60000.0, + 5000.0, + 2.0, + 1.0, + ], + ) + + for key, value in values.items(): + parameters[parameter_index(key)] = value + + return parameters + + +def init_state_values(**values): + """Initialize state values""" + # hL=1, a=0, ap=0, d=0, ff=1, fs=1, hf=1, hs=1, m=0, xrf=0 + # xrs=0, xs1=0, CaMKt=0, xk1=1, Zetaw=0, XS=0, XW=0, TmB=1 + # hLp=1, iF=1, iS=1, fcaf=1, fcas=1, jca=1, j=1, fcafp=1, ffp=1 + # hsp=1, jp=1, mL=0, xs2=0, Zetas=0, nca=0, CaTrpn=0, iFp=1 + # iSp=1, cajsr=1.2, cansr=1.2, kss=145, Cd=0, Jrelnp=0, Jrelp=0 + # ki=145, cass=0.0001, nass=7, cai=0.0001, nai=7, v=-87 + + states = numpy.array( + [ + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1.2, + 1.2, + 145, + 0, + 0, + 0, + 145, + 0.0001, + 7, + 0.0001, + 7, + -87, + ], + ) + + for key, value in values.items(): + states[state_index(key)] = value + + return states + + +def forward_generalized_rush_larsen(coupling: EMCoupling): + def forward_generalized_rush_larsen_(states, t, dt, parameters): + lmbda = coupling.lmbda_ep.vector().get_local() + dLambda = coupling.dLambda_ep.vector().get_local() # Assign states - assert len(s) == 47 - ( - CaMKt, - m, - hf, - hs, - j, - hsp, - jp, - mL, - hL, - hLp, - a, - iF, - iS, - ap, - iFp, - iSp, - d, - ff, - fs, - fcaf, - fcas, - jca, - ffp, - fcafp, - nca, - xrf, - xrs, - xs1, - xs2, - xk1, - Jrelnp, - Jrelp, - nai, - nass, - ki, - kss, - cass, - cansr, - cajsr, - XS, - XW, - CaTrpn, - TmB, - Cd, - cai, - Zetas, - Zetaw, - ) = s + hL = states[0] + a = states[1] + ap = states[2] + d = states[3] + ff = states[4] + fs = states[5] + hf = states[6] + hs = states[7] + m = states[8] + xrf = states[9] + xrs = states[10] + xs1 = states[11] + CaMKt = states[12] + xk1 = states[13] + Zetaw = states[14] + XS = states[15] + XW = states[16] + TmB = states[17] + hLp = states[18] + iF = states[19] + iS = states[20] + fcaf = states[21] + fcas = states[22] + jca = states[23] + j = states[24] + fcafp = states[25] + ffp = states[26] + hsp = states[27] + jp = states[28] + mL = states[29] + xs2 = states[30] + Zetas = states[31] + nca = states[32] + CaTrpn = states[33] + iFp = states[34] + iSp = states[35] + cajsr = states[36] + cansr = states[37] + kss = states[38] + Cd = states[39] + Jrelnp = states[40] + Jrelp = states[41] + ki = states[42] + cass = states[43] + nass = states[44] + cai = states[45] + nai = states[46] + v = states[47] # Assign parameters - scale_ICaL = self._parameters["scale_ICaL"] - scale_IK1 = self._parameters["scale_IK1"] - scale_IKr = self._parameters["scale_IKr"] - scale_IKs = self._parameters["scale_IKs"] - scale_INaL = self._parameters["scale_INaL"] - cao = self._parameters["cao"] - ko = self._parameters["ko"] - nao = self._parameters["nao"] - F = self._parameters["F"] - R = self._parameters["R"] - T = self._parameters["T"] - CaMKo = self._parameters["CaMKo"] - KmCaM = self._parameters["KmCaM"] - KmCaMK = self._parameters["KmCaMK"] - PKNa = self._parameters["PKNa"] - Ahf = self._parameters["Ahf"] - GNa = self._parameters["GNa"] - Gto = self._parameters["Gto"] - Aff = self._parameters["Aff"] - zca = self._parameters["zca"] - Gncx = self._parameters["Gncx"] - KmCaAct = self._parameters["KmCaAct"] - kasymm = self._parameters["kasymm"] - kcaoff = self._parameters["kcaoff"] - kcaon = self._parameters["kcaon"] - kna1 = self._parameters["kna1"] - kna2 = self._parameters["kna2"] - kna3 = self._parameters["kna3"] - qca = self._parameters["qca"] - qna = self._parameters["qna"] - wca = self._parameters["wca"] - wna = self._parameters["wna"] - wnaca = self._parameters["wnaca"] - H = self._parameters["H"] - Khp = self._parameters["Khp"] - Kki = self._parameters["Kki"] - Kko = self._parameters["Kko"] - Kmgatp = self._parameters["Kmgatp"] - Knai0 = self._parameters["Knai0"] - Knao0 = self._parameters["Knao0"] - Knap = self._parameters["Knap"] - Kxkur = self._parameters["Kxkur"] - MgADP = self._parameters["MgADP"] - MgATP = self._parameters["MgATP"] - Pnak = self._parameters["Pnak"] - delta = self._parameters["delta"] - eP = self._parameters["eP"] - k1m = self._parameters["k1m"] - k1p = self._parameters["k1p"] - k2m = self._parameters["k2m"] - k2p = self._parameters["k2p"] - k3m = self._parameters["k3m"] - k3p = self._parameters["k3p"] - k4m = self._parameters["k4m"] - k4p = self._parameters["k4p"] - zk = self._parameters["zk"] - GKb = self._parameters["GKb"] - PNab = self._parameters["PNab"] - PCab = self._parameters["PCab"] - GpCa = self._parameters["GpCa"] - # Drug factor - scale_drug_INa = self._parameters["scale_drug_INa"] - scale_drug_INaL = self._parameters["scale_drug_INaL"] - scale_drug_Ito = self._parameters["scale_drug_Ito"] - scale_drug_ICaL = self._parameters["scale_drug_ICaL"] - scale_drug_IKr = self._parameters["scale_drug_IKr"] - scale_drug_IKs = self._parameters["scale_drug_IKs"] - scale_drug_IK1 = self._parameters["scale_drug_IK1"] - scale_drug_IKb = self._parameters["scale_drug_IKb"] - scale_drug_INab = self._parameters["scale_drug_INab"] - scale_drug_ICab = self._parameters["scale_drug_ICab"] - scale_drug_IpCa = self._parameters["scale_drug_IpCa"] - scale_drug_Isacns = self._parameters["scale_drug_Isacns"] - scale_drug_Isack = self._parameters["scale_drug_Isack"] - # Population factors - scale_popu_GNa = self._parameters["scale_popu_GNa"] - scale_popu_GCaL = self._parameters["scale_popu_GCaL"] - scale_popu_Gto = self._parameters["scale_popu_Gto"] - scale_popu_GNaL = self._parameters["scale_popu_GNaL"] - scale_popu_GKr = self._parameters["scale_popu_GKr"] - scale_popu_GKs = self._parameters["scale_popu_GKs"] - scale_popu_GK1 = self._parameters["scale_popu_GK1"] - scale_popu_GbK = self._parameters["scale_popu_GbK"] - scale_popu_KNCX = self._parameters["scale_popu_KNCX"] - scale_popu_KNaK = self._parameters["scale_popu_KNaK"] - scale_popu_GbNa = self._parameters["scale_popu_GbNa"] - scale_popu_GbCa = self._parameters["scale_popu_GbCa"] - scale_popu_KpCa = self._parameters["scale_popu_KpCa"] - # Systolic Heart Failure (HF with preserved ejection fraction) - HF_scaling_CaMKa = self._parameters["HF_scaling_CaMKa"] - HF_scaling_GNaL = self._parameters["HF_scaling_GNaL"] - HF_scaling_GK1 = self._parameters["HF_scaling_GK1"] - HF_scaling_Gto = self._parameters["HF_scaling_Gto"] - HF_scaling_Gncx = self._parameters["HF_scaling_Gncx"] - HF_scaling_Pnak = self._parameters["HF_scaling_Pnak"] - - # Init return args - current = [ufl.zero()] * 1 - - # Expressions for the CaMKt component - CaMKb = CaMKo * (1.0 - CaMKt) / (1.0 + KmCaM / cass) - CaMKa = (CaMKb + CaMKt) * HF_scaling_CaMKa - - # Expressions for the reversal potentials component - ENa = R * T * ufl.ln(nao / nai) / F - EK = R * T * ufl.ln(ko / ki) / F - EKs = R * T * ufl.ln((ko + PKNa * nao) / (PKNa * nai + ki)) / F - vffrt = (F * F) * v / (R * T) - vfrt = F * v / (R * T) - - # Expressions for the I_Na component - Ahs = 1.0 - Ahf - h = Ahf * hf + Ahs * hs - hp = Ahf * hf + Ahs * hsp - fINap = 1.0 / (1.0 + KmCaMK / CaMKa) - INa = ( - GNa - * scale_drug_INa - * scale_popu_GNa - * ufl.elem_pow(m, 3.0) - * (-ENa + v) - * ((1.0 - fINap) * h * j + fINap * hp * jp) + Aff = parameters[0] + Ahf = parameters[1] + BSLmax = parameters[2] + BSRmax = parameters[3] + Beta0 = parameters[4] + Beta1 = parameters[5] + CaMKo = parameters[6] + F = parameters[8] + GKb = parameters[9] + GNa = parameters[10] + Gncx = parameters[11] + GpCa = parameters[12] + Gto = parameters[15] + H = parameters[16] + Khp = parameters[17] + Kki = parameters[18] + Kko = parameters[19] + KmBSL = parameters[20] + KmBSR = parameters[21] + KmCaAct = parameters[22] + KmCaM = parameters[23] + KmCaMK = parameters[24] + Kmgatp = parameters[25] + Kmn = parameters[26] + Knai0 = parameters[27] + Knao0 = parameters[28] + Knap = parameters[29] + Kxkur = parameters[30] + L = parameters[31] + MgADP = parameters[32] + MgATP = parameters[33] + PCab = parameters[34] + PKNa = parameters[35] + PNab = parameters[36] + Pnak = parameters[37] + R = parameters[38] + T = parameters[39] + Tot_A = parameters[40] + Tref = parameters[41] + Trpn50 = parameters[42] + aCaMK = parameters[43] + amp = parameters[44] + bCaMK = parameters[45] + bt = parameters[46] + cao = parameters[48] + cat50_ref = parameters[49] + cmdnmax = parameters[51] + csqnmax = parameters[52] + # dLambda = parameters[53] + delta = parameters[54] + delta_epi = parameters[55] + duration = parameters[56] + eP = parameters[57] + etal = parameters[59] + etas = parameters[60] + gammas = parameters[61] + gammaw = parameters[62] + k1m = parameters[64] + k1p = parameters[65] + k2m = parameters[66] + k2n = parameters[67] + k2p = parameters[68] + k3m = parameters[69] + k3p = parameters[70] + k4m = parameters[71] + k4p = parameters[72] + kasymm = parameters[73] + kcaoff = parameters[74] + kcaon = parameters[75] + kmcmdn = parameters[76] + kmcsqn = parameters[77] + kna1 = parameters[79] + kna2 = parameters[80] + kna3 = parameters[81] + ko = parameters[82] + ktrpn = parameters[83] + ku = parameters[84] + kuw = parameters[85] + kws = parameters[86] + # lmbda = parameters[88] + nao = parameters[90] + ntm = parameters[91] + ntrpn = parameters[92] + p_a = parameters[93] + p_b = parameters[94] + p_k = parameters[95] + phi = parameters[96] + qca = parameters[97] + qna = parameters[98] + rad = parameters[99] + rs = parameters[100] + rw = parameters[101] + scale_HF_CaMKa = parameters[102] + scale_HF_GK1 = parameters[103] + scale_HF_GNaL = parameters[104] + scale_HF_Gncx = parameters[105] + scale_HF_Gto = parameters[106] + scale_HF_Jleak = parameters[107] + scale_HF_Jrel_inf = parameters[108] + scale_HF_Jup = parameters[109] + scale_HF_Pnak = parameters[110] + scale_HF_cat50_ref = parameters[111] + scale_HF_thL = parameters[112] + scale_ICaL = parameters[113] + scale_IK1 = parameters[114] + scale_IKr = parameters[115] + scale_IKs = parameters[116] + scale_INaL = parameters[117] + scale_drug_ICaL = parameters[118] + scale_drug_ICab = parameters[119] + scale_drug_IK1 = parameters[120] + scale_drug_IKb = parameters[121] + scale_drug_IKr = parameters[122] + scale_drug_IKs = parameters[123] + scale_drug_INa = parameters[124] + scale_drug_INaL = parameters[125] + scale_drug_INab = parameters[126] + scale_drug_IpCa = parameters[127] + scale_drug_Ito = parameters[130] + thL = parameters[131] + tjca = parameters[132] + trpnmax = parameters[133] + wca = parameters[134] + wna = parameters[135] + wnaca = parameters[136] + zca = parameters[137] + zk = parameters[138] + + # Assign expressions + values = numpy.zeros_like(states) + zna = 1.0 + Isac_P_k = 0 + Isac_P_ns = 0 + Afcaf = 0.3 + 0.6 / (numpy.exp((v - 10.0) / 10.0) + 1.0) + AiF = 1.0 / (numpy.exp((v - 213.6) / 151.2) + 1.0) + Axrf = 1.0 / (numpy.exp((v + 54.81) / 38.21) + 1.0) + ass = 1.0 / (numpy.exp((-(v - 14.34)) / 14.82) + 1.0) + assp = 1.0 / (numpy.exp((-(v - 24.34)) / 14.82) + 1.0) + dss = 1.0 / (numpy.exp((-(v + 3.94)) / 4.23) + 1.0) + dti_develop = 1.354 + 0.0001 / ( + numpy.exp((-(v - 12.23)) / 0.2154) + numpy.exp((v - 167.4) / 15.89) + ) + dti_recover = 1.0 - 0.5 / (numpy.exp((v + 70.0) / 20.0) + 1.0) + fss = 1.0 / (numpy.exp((v + 19.58) / 3.696) + 1.0) + hLss = 1.0 / (numpy.exp((v + 87.61) / 7.488) + 1.0) + hLssp = 1.0 / (numpy.exp((v + 93.81) / 7.488) + 1.0) + hss = 1.0 / (numpy.exp((v + 78.5) / 6.22) + 1) + hssp = 1.0 / (numpy.exp(((v + 78.5) + 6.2) / 6.22) + 1) + iss = 1.0 / (numpy.exp((v + 43.94) / 5.711) + 1.0) + mLss = 1.0 / (numpy.exp((-(v + 42.85)) / 5.264) + 1.0) + mss = 1.0 / (numpy.exp((-((v + 39.57) + 9.4)) / 7.5) + 1.0) + rkr = (1.0 * (1.0 / (numpy.exp((v + 55.0) / 75.0) + 1.0))) / ( + numpy.exp((v - 10.0) / 30.0) + 1.0 ) - - # Expressions for the INaL component - GNaL = 0.0075 * scale_INaL * scale_drug_INaL * scale_popu_GNaL * HF_scaling_GNaL - fINaLp = 1.0 / (1.0 + KmCaMK / CaMKa) - INaL = (-ENa + v) * ((1.0 - fINaLp) * hL + fINaLp * hLp) * GNaL * mL - - # Expressions for the Ito component - AiF = 1.0 / (1.0 + 0.24348537187522867 * ufl.exp(0.006613756613756614 * v)) - AiS = 1.0 - AiF - i = AiF * iF + AiS * iS - ip = AiF * iFp + AiS * iSp - fItop = 1.0 / (1.0 + KmCaMK / CaMKa) - Ito = ( - Gto - * scale_drug_Ito - * scale_popu_Gto - * HF_scaling_Gto - * (-EK + v) - * ((1.0 - fItop) * a * i + ap * fItop * ip) + ta = 1.0515 / ( + 1.0 / ((1.2089 * (numpy.exp((-(v - 18.4099)) / 29.3814) + 1.0))) + + 3.5 / (numpy.exp((v + 100.0) / 29.3814) + 1.0) ) - - # Expressions for the ICaL ICaNa ICaK component - Afs = 1.0 - Aff - f = Aff * ff + Afs * fs - Afcaf = 0.3 + 0.6 / (1.0 + 0.36787944117144233 * ufl.exp(0.1 * v)) - Afcas = 1.0 - Afcaf - fca = Afcaf * fcaf + Afcas * fcas - fp = Aff * ffp + Afs * fs - fcap = Afcaf * fcafp + Afcas * fcas - PhiCaL = ( - 4.0 - * (-0.341 * cao + cass * ufl.exp(2.0 * vfrt)) - * vffrt - / (-1.0 + ufl.exp(2.0 * vfrt)) + td = 0.6 + 1.0 / (numpy.exp((-0.05) * (v + 6.0)) + numpy.exp(0.09 * (v + 14.0))) + tfcaf = 7.0 + 1.0 / ( + 0.04 * numpy.exp((-(v - 4.0)) / 7.0) + 0.04 * numpy.exp((v - 4.0) / 7.0) ) - PhiCaNa = ( - 1.0 - * (-0.75 * nao + 0.75 * ufl.exp(1.0 * vfrt) * nass) - * vffrt - / (-1.0 + ufl.exp(1.0 * vfrt)) + tfcas = 100.0 + 1.0 / ( + 0.00012 * numpy.exp((-v) / 3.0) + 0.00012 * numpy.exp(v / 7.0) ) - PhiCaK = ( - 1.0 - * (-0.75 * ko + 0.75 * ufl.exp(1.0 * vfrt) * kss) - * vffrt - / (-1.0 + ufl.exp(1.0 * vfrt)) + tff = 7.0 + 1.0 / ( + 0.0045 * numpy.exp((-(v + 20.0)) / 10.0) + + 0.0045 * numpy.exp((v + 20.0) / 10.0) ) - PCa = 0.0001 * scale_ICaL * scale_drug_ICaL * scale_popu_GCaL - PCap = 1.1 * PCa - PCaNa = 0.00125 * PCa - PCaK = 0.0003574 * PCa - PCaNap = 0.00125 * PCap - PCaKp = 0.0003574 * PCap - fICaLp = 1.0 / (1.0 + KmCaMK / CaMKa) - ICaL = (1.0 - fICaLp) * ( - (1.0 - nca) * f + fca * jca * nca - ) * PCa * PhiCaL * d + ( - (1.0 - nca) * fp + fcap * jca * nca - ) * PCap * PhiCaL * d * fICaLp - ICaNa = (1.0 - fICaLp) * ( - (1.0 - nca) * f + fca * jca * nca - ) * PCaNa * PhiCaNa * d + ( - (1.0 - nca) * fp + fcap * jca * nca - ) * PCaNap * PhiCaNa * d * fICaLp - ICaK = (1.0 - fICaLp) * ( - (1.0 - nca) * f + fca * jca * nca - ) * PCaK * PhiCaK * d + ( - (1.0 - nca) * fp + fcap * jca * nca - ) * PCaKp * PhiCaK * d * fICaLp - - # Expressions for the IKr component - Axrf = 1.0 / (1.0 + 4.197299094734718 * ufl.exp(0.02617115938236064 * v)) - Axrs = 1.0 - Axrf - xr = Axrf * xrf + Axrs * xrs - rkr = 1.0 / ( - (1.0 + 2.0820090840784555 * ufl.exp(0.013333333333333334 * v)) - * (1.0 + 0.7165313105737893 * ufl.exp(0.03333333333333333 * v)) - ) - GKr = 0.046 * scale_IKr * scale_drug_IKr * scale_popu_GKr - IKr = 0.4303314829119352 * ufl.sqrt(ko) * (-EK + v) * GKr * rkr * xr - - # Expressions for the IKs component - KsCa = 1.0 + 0.6 / (1.0 + 6.481821026062645e-07 * ufl.elem_pow(1.0 / cai, 1.4)) - GKs = 0.0034 * scale_IKs * scale_drug_IKs * scale_popu_GKs - IKs = (-EKs + v) * GKs * KsCa * xs1 * xs2 - rk1 = 1.0 / ( - 1.0 - + 69220.6322106767 - * ufl.exp(0.10534077741493732 * v - 0.27388602127883704 * ko) - ) - GK1 = 0.1908 * scale_IK1 * scale_drug_IK1 * scale_popu_GK1 * HF_scaling_GK1 - IK1 = ufl.sqrt(ko) * (-EK + v) * GK1 * rk1 * xk1 - - # Expressions for the INaCa_i component - hca = ufl.exp(F * qca * v / (R * T)) - hna = ufl.exp(F * qna * v / (R * T)) - h1_i = 1 + (1 + hna) * nai / kna3 - h2_i = hna * nai / (kna3 * h1_i) - h3_i = 1.0 / h1_i - h4_i = 1.0 + (1 + nai / kna2) * nai / kna1 - h5_i = (nai * nai) / (kna1 * kna2 * h4_i) - h6_i = 1.0 / h4_i - h7_i = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 - h8_i = nao / (kna3 * h7_i * hna) - h9_i = 1.0 / h7_i - h10_i = 1.0 + kasymm + nao * (1.0 + nao / kna2) / kna1 - h11_i = (nao * nao) / (kna1 * kna2 * h10_i) - h12_i = 1.0 / h10_i - k1_i = cao * kcaon * h12_i - k2_i = kcaoff - k3p_i = wca * h9_i - k3pp_i = wnaca * h8_i - k3_i = k3p_i + k3pp_i - k4p_i = wca * h3_i / hca - k4pp_i = wnaca * h2_i - k4_i = k4p_i + k4pp_i - k5_i = kcaoff - k6_i = kcaon * cai * h6_i - k7_i = wna * h2_i * h5_i - k8_i = wna * h11_i * h8_i - x1_i = (k2_i + k3_i) * k5_i * k7_i + (k6_i + k7_i) * k2_i * k4_i - x2_i = (k1_i + k8_i) * k4_i * k6_i + (k4_i + k5_i) * k1_i * k7_i - x3_i = (k2_i + k3_i) * k6_i * k8_i + (k6_i + k7_i) * k1_i * k3_i - x4_i = (k1_i + k8_i) * k3_i * k5_i + (k4_i + k5_i) * k2_i * k8_i - E1_i = x1_i / (x1_i + x2_i + x3_i + x4_i) - E2_i = x2_i / (x1_i + x2_i + x3_i + x4_i) - E3_i = x3_i / (x1_i + x2_i + x3_i + x4_i) - E4_i = x4_i / (x1_i + x2_i + x3_i + x4_i) - allo_i = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cai, 2.0)) - zna = 1.0 - JncxNa_i = E3_i * k4pp_i - E2_i * k3pp_i + 3.0 * E4_i * k7_i - 3.0 * E1_i * k8_i - JncxCa_i = E2_i * k2_i - E1_i * k1_i - INaCa_i = ( - 0.8 - * Gncx - * scale_popu_KNCX - * HF_scaling_Gncx - * (zca * JncxCa_i + zna * JncxNa_i) - * allo_i - ) - - # Expressions for the INaCa_ss component - h1 = 1.0 + (1.0 + hna) * nass / kna3 - h2 = hna * nass / (kna3 * h1) - h3 = 1.0 / h1 - h4 = 1.0 + (1 + nass / kna2) * nass / kna1 - h5 = (nass * nass) / (kna1 * kna2 * h4) - h6 = 1.0 / h4 - h7 = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 - h8 = nao / (kna3 * h7 * hna) - h9 = 1.0 / h7 - h10 = 1.0 + kasymm + nao * (1 + nao / kna2) / kna1 - h11 = (nao * nao) / (kna1 * kna2 * h10) - h12 = 1.0 / h10 - k1 = cao * kcaon * h12 - k2 = kcaoff - k3p_ss = wca * h9 - k3pp = wnaca * h8 - k3 = k3p_ss + k3pp - k4p_ss = wca * h3 / hca - k4pp = wnaca * h2 - k4 = k4p_ss + k4pp - k5 = kcaoff - k6 = kcaon * cass * h6 - k7 = wna * h2 * h5 - k8 = wna * h11 * h8 - x1_ss = (k2 + k3) * k5 * k7 + (k6 + k7) * k2 * k4 - x2_ss = (k1 + k8) * k4 * k6 + (k4 + k5) * k1 * k7 - x3_ss = (k2 + k3) * k6 * k8 + (k6 + k7) * k1 * k3 - x4_ss = (k1 + k8) * k3 * k5 + (k4 + k5) * k2 * k8 - E1_ss = x1_ss / (x1_ss + x2_ss + x3_ss + x4_ss) - E2_ss = x2_ss / (x1_ss + x2_ss + x3_ss + x4_ss) - E3_ss = x3_ss / (x1_ss + x2_ss + x3_ss + x4_ss) - E4_ss = x4_ss / (x1_ss + x2_ss + x3_ss + x4_ss) - allo_ss = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cass, 2.0)) - JncxNa_ss = E3_ss * k4pp - E2_ss * k3pp + 3.0 * E4_ss * k7 - 3.0 * E1_ss * k8 - JncxCa_ss = E2_ss * k2 - E1_ss * k1 - INaCa_ss = ( - 0.2 - * Gncx - * scale_popu_KNCX - * HF_scaling_Gncx - * (zca * JncxCa_ss + zna * JncxNa_ss) - * allo_ss - ) - - # Expressions for the INaK component - Knai = Knai0 * ufl.exp(0.3333333333333333 * F * delta * v / (R * T)) - Knao = Knao0 * ufl.exp(0.3333333333333333 * F * (1.0 - delta) * v / (R * T)) - P = eP / (1.0 + H / Khp + nai / Knap + ki / Kxkur) - a1 = ( - k1p - * ufl.elem_pow(nai / Knai, 3.0) - / ( - -1.0 - + ufl.elem_pow(1.0 + ki / Kki, 2.0) - + ufl.elem_pow(1.0 + nai / Knai, 3.0) - ) + tfs = 1000.0 + 1.0 / ( + 3.5e-05 * numpy.exp((-(v + 5.0)) / 4.0) + + 3.5e-05 * numpy.exp((v + 5.0) / 6.0) ) - b1 = MgADP * k1m - a2 = k2p - b2 = ( - k2m - * ufl.elem_pow(nao / Knao, 3.0) - / ( - -1.0 - + ufl.elem_pow(1.0 + ko / Kko, 2.0) - + ufl.elem_pow(1.0 + nao / Knao, 3.0) - ) + thf = 1.0 / ( + 6.149 * numpy.exp((v + 0.5096) / 20.27) + + 1.432e-05 * numpy.exp((-(v + 1.196)) / 6.285) ) - a3 = ( - k3p - * ufl.elem_pow(ko / Kko, 2.0) - / ( - -1.0 - + ufl.elem_pow(1.0 + ko / Kko, 2.0) - + ufl.elem_pow(1.0 + nao / Knao, 3.0) - ) + ths = 1.0 / ( + 0.009794 * numpy.exp((-(v + 17.95)) / 28.05) + + 0.3343 * numpy.exp((v + 5.73) / 56.66) ) - b3 = H * k3m * P / (1.0 + MgATP / Kmgatp) - a4 = MgATP * k4p / (Kmgatp * (1.0 + MgATP / Kmgatp)) - b4 = ( - k4m - * ufl.elem_pow(ki / Kki, 2.0) - / ( - -1.0 - + ufl.elem_pow(1.0 + ki / Kki, 2.0) - + ufl.elem_pow(1.0 + nai / Knai, 3.0) - ) + tj = 2.038 + 1.0 / ( + 0.3052 * numpy.exp((v + 0.9941) / 38.45) + + 0.02136 * numpy.exp((-(v + 100.6)) / 8.281) ) - x1 = a1 * a2 * a4 + a1 * a2 * b3 + a2 * b3 * b4 + b2 * b3 * b4 - x2 = a1 * a2 * a3 + a2 * a3 * b4 + a3 * b1 * b4 + b1 * b2 * b4 - x3 = a2 * a3 * a4 + a3 * a4 * b1 + a4 * b1 * b2 + b1 * b2 * b3 - x4 = a1 * a3 * a4 + a1 * a4 * b2 + a1 * b2 * b3 + b2 * b3 * b4 - E1 = x1 / (x1 + x2 + x3 + x4) - E2 = x2 / (x1 + x2 + x3 + x4) - E3 = x3 / (x1 + x2 + x3 + x4) - E4 = x4 / (x1 + x2 + x3 + x4) - JnakNa = 3.0 * E1 * a3 - 3.0 * E2 * b3 - JnakK = 2.0 * E4 * b1 - 2.0 * E3 * a1 - INaK = Pnak * scale_popu_KNaK * HF_scaling_Pnak * (zk * JnakK + zna * JnakNa) - - # Expressions for the IKb component - xkb = 1.0 / (1.0 + 2.202363450949239 * ufl.exp(-0.05452562704471101 * v)) - IKb = GKb * scale_popu_GbK * scale_drug_IKb * (-EK + v) * xkb - - # Expressions for the INab component - INab = ( - PNab - * scale_drug_INab - * scale_popu_GbNa - * (-nao + ufl.exp(vfrt) * nai) - * vffrt - / (-1.0 + ufl.exp(vfrt)) - ) - - # Expressions for the ICab component - ICab = ( - 4.0 - * PCab - * scale_drug_ICab - * scale_popu_GbCa - * (-0.341 * cao + cai * ufl.exp(2.0 * vfrt)) - * vffrt - / (-1.0 + ufl.exp(2.0 * vfrt)) - ) - - # Expressions for the IpCa component - IpCa = GpCa * scale_drug_IpCa * scale_popu_KpCa * cai / (0.0005 + cai) - - # Expressions for the Isac (Pueyo)--> ns + k component - Gsac_ns = 0.006 * scale_drug_Isacns - Esac_ns = -10.0 - lambda_max = 1.1 - Gsac_k = (0.2882 * 800.0 / 210.0) * scale_drug_Isack # Pueyo endo - - Isac_P_ns = ufl.conditional( - ufl.lt(self.lmbda, 1.0), - 0.0, - Gsac_ns * ((self.lmbda - 1.0) / (lambda_max - 1.0)) * (v - Esac_ns), - ) - Isac_P_k = ufl.conditional( - ufl.lt(self.lmbda, 1.0), - 0.0, - Gsac_k - * ((self.lmbda - 1.0) / (lambda_max - 1.0)) - * (1.0 / (1.0 + ufl.exp((19.05 - v) / (29.98)))), - ) - - # Expressions for the Istim component - Istim = 0 # amp*(ufl.le(time, duration)) - - # Expressions for the membrane potential component - current[0] = ( - -Isac_P_k - - Isac_P_ns - - ICaK - - ICaL - - ICaNa - - ICab - - IK1 - - IKb - - IKr - - IKs - - INa - - INaCa_i - - INaCa_ss - - INaK - - INaL - - INab - - IpCa - - Istim - - Ito - ) - - # Return results - return current[0] - - def I(self, v, s, time=None): # noqa: E741, E743 - """ - Transmembrane current - - I = -dV/dt - - """ - return -self._I(v, s, time) - - def F(self, v, s, time=None): - """ - Right hand side for ODE system - """ - logger.debug("Evaluate RHS") - time = time if time else Constant(0.0) - - # Assign states - assert len(s) == 47 - ( - CaMKt, - m, - hf, - hs, - j, - hsp, - jp, - mL, - hL, - hLp, - a, - iF, - iS, - ap, - iFp, - iSp, - d, - ff, - fs, - fcaf, - fcas, - jca, - ffp, - fcafp, - nca, - xrf, - xrs, - xs1, - xs2, - xk1, - Jrelnp, - Jrelp, - nai, - nass, - ki, - kss, - cass, - cansr, - cajsr, - XS, - XW, - CaTrpn, - TmB, - Cd, - cai, - Zetas, - Zetaw, - ) = s - - # Assign parameters - scale_ICaL = self._parameters["scale_ICaL"] - scale_IK1 = self._parameters["scale_IK1"] - scale_IKr = self._parameters["scale_IKr"] - scale_IKs = self._parameters["scale_IKs"] - scale_INaL = self._parameters["scale_INaL"] - cao = self._parameters["cao"] - ko = self._parameters["ko"] - nao = self._parameters["nao"] - F = self._parameters["F"] - R = self._parameters["R"] - T = self._parameters["T"] - L = self._parameters["L"] - rad = self._parameters["rad"] - CaMKo = self._parameters["CaMKo"] - KmCaM = self._parameters["KmCaM"] - KmCaMK = self._parameters["KmCaMK"] - aCaMK = self._parameters["aCaMK"] - bCaMK = self._parameters["bCaMK"] - PKNa = self._parameters["PKNa"] - Ahf = self._parameters["Ahf"] - GNa = self._parameters["GNa"] - thL = self._parameters["thL"] - Gto = self._parameters["Gto"] - delta_epi = self._parameters["delta_epi"] - Aff = self._parameters["Aff"] - Kmn = self._parameters["Kmn"] - k2n = self._parameters["k2n"] - tjca = self._parameters["tjca"] - zca = self._parameters["zca"] - Gncx = self._parameters["Gncx"] - KmCaAct = self._parameters["KmCaAct"] - kasymm = self._parameters["kasymm"] - kcaoff = self._parameters["kcaoff"] - kcaon = self._parameters["kcaon"] - kna1 = self._parameters["kna1"] - kna2 = self._parameters["kna2"] - kna3 = self._parameters["kna3"] - qca = self._parameters["qca"] - qna = self._parameters["qna"] - wca = self._parameters["wca"] - wna = self._parameters["wna"] - wnaca = self._parameters["wnaca"] - H = self._parameters["H"] - Khp = self._parameters["Khp"] - Kki = self._parameters["Kki"] - Kko = self._parameters["Kko"] - Kmgatp = self._parameters["Kmgatp"] - Knai0 = self._parameters["Knai0"] - Knao0 = self._parameters["Knao0"] - Knap = self._parameters["Knap"] - Kxkur = self._parameters["Kxkur"] - MgADP = self._parameters["MgADP"] - MgATP = self._parameters["MgATP"] - Pnak = self._parameters["Pnak"] - delta = self._parameters["delta"] - eP = self._parameters["eP"] - k1m = self._parameters["k1m"] - k1p = self._parameters["k1p"] - k2m = self._parameters["k2m"] - k2p = self._parameters["k2p"] - k3m = self._parameters["k3m"] - k3p = self._parameters["k3p"] - k4m = self._parameters["k4m"] - k4p = self._parameters["k4p"] - zk = self._parameters["zk"] - GKb = self._parameters["GKb"] - PNab = self._parameters["PNab"] - PCab = self._parameters["PCab"] - GpCa = self._parameters["GpCa"] - bt = self._parameters["bt"] - BSLmax = self._parameters["BSLmax"] - BSRmax = self._parameters["BSRmax"] - KmBSL = self._parameters["KmBSL"] - KmBSR = self._parameters["KmBSR"] - cmdnmax = self._parameters["cmdnmax"] - csqnmax = self._parameters["csqnmax"] - kmcmdn = self._parameters["kmcmdn"] - kmcsqn = self._parameters["kmcsqn"] - trpnmax = self._parameters["trpnmax"] - Beta1 = self._parameters["Beta1"] - Tot_A = self._parameters["Tot_A"] - Trpn50 = self._parameters["Trpn50"] - cat50_ref = self._parameters["cat50_ref"] - # dLambda = self._parameters["dLambda"] - etal = self._parameters["etal"] - etas = self._parameters["etas"] - gammas = self._parameters["gammas"] - gammaw = self._parameters["gammaw"] - ktrpn = self._parameters["ktrpn"] - ku = self._parameters["ku"] - kuw = self._parameters["kuw"] - kws = self._parameters["kws"] - # lmbda = self._parameters["lmbda"] - ntm = self._parameters["ntm"] - ntrpn = self._parameters["ntrpn"] - p_k = self._parameters["p_k"] - phi = self._parameters["phi"] - rs = self._parameters["rs"] - rw = self._parameters["rw"] - - # Drug factor - scale_drug_INa = self._parameters["scale_drug_INa"] - scale_drug_INaL = self._parameters["scale_drug_INaL"] - scale_drug_Ito = self._parameters["scale_drug_Ito"] - scale_drug_ICaL = self._parameters["scale_drug_ICaL"] - scale_drug_IKr = self._parameters["scale_drug_IKr"] - scale_drug_IKs = self._parameters["scale_drug_IKs"] - scale_drug_IK1 = self._parameters["scale_drug_IK1"] - scale_drug_IKb = self._parameters["scale_drug_IKb"] - scale_drug_INab = self._parameters["scale_drug_INab"] - scale_drug_ICab = self._parameters["scale_drug_ICab"] - scale_drug_IpCa = self._parameters["scale_drug_IpCa"] - scale_drug_Isacns = self._parameters["scale_drug_Isacns"] - scale_drug_Isack = self._parameters["scale_drug_Isack"] - - # Population factors - scale_popu_GNa = self._parameters["scale_popu_GNa"] - scale_popu_GCaL = self._parameters["scale_popu_GCaL"] - scale_popu_Gto = self._parameters["scale_popu_Gto"] - scale_popu_GNaL = self._parameters["scale_popu_GNaL"] - scale_popu_GKr = self._parameters["scale_popu_GKr"] - scale_popu_GKs = self._parameters["scale_popu_GKs"] - scale_popu_GK1 = self._parameters["scale_popu_GK1"] - scale_popu_GbK = self._parameters["scale_popu_GbK"] - scale_popu_KNCX = self._parameters["scale_popu_KNCX"] - scale_popu_KNaK = self._parameters["scale_popu_KNaK"] - scale_popu_GbNa = self._parameters["scale_popu_GbNa"] - scale_popu_GbCa = self._parameters["scale_popu_GbCa"] - scale_popu_KpCa = self._parameters["scale_popu_KpCa"] - scale_popu_KRyR = self._parameters["scale_popu_KRyR"] - scale_popu_KSERCA = self._parameters["scale_popu_KSERCA"] - scale_popu_Kleak = self._parameters["scale_popu_Kleak"] - scale_popu_nTm = self._parameters["scale_popu_nTm"] - scale_popu_CaT50ref = self._parameters["scale_popu_CaT50ref"] - scale_popu_kuw = self._parameters["scale_popu_kuw"] - scale_popu_kws = self._parameters["scale_popu_kws"] - scale_popu_kTRPN = self._parameters["scale_popu_kTRPN"] - scale_popu_nTRPN = self._parameters["scale_popu_nTRPN"] - scale_popu_ku = self._parameters["scale_popu_ku"] - scale_popu_TRPN50 = self._parameters["scale_popu_TRPN50"] - scale_popu_rw = self._parameters["scale_popu_rw"] - scale_popu_rs = self._parameters["scale_popu_rs"] - - # Systolic Heart Failure (HF with preserved ejection fraction) - HF_scaling_CaMKa = self._parameters["HF_scaling_CaMKa"] - HF_scaling_Jrel_inf = self._parameters["HF_scaling_Jrel_inf"] - HF_scaling_Jleak = self._parameters["HF_scaling_Jleak"] - HF_scaling_Jup = self._parameters["HF_scaling_Jup"] - HF_scaling_GNaL = self._parameters["HF_scaling_GNaL"] - HF_scaling_GK1 = self._parameters["HF_scaling_GK1"] - HF_scaling_thL = self._parameters["HF_scaling_thL"] - HF_scaling_Gto = self._parameters["HF_scaling_Gto"] - HF_scaling_Gncx = self._parameters["HF_scaling_Gncx"] - HF_scaling_Pnak = self._parameters["HF_scaling_Pnak"] - HF_scaling_cat50_ref = self._parameters["HF_scaling_cat50_ref"] - - # Init return args - F_expressions = [dolfin.Constant(0.0)] * 47 - - # Expressions for the cell geometry component - vcell = 3140.0 * L * (rad * rad) - Ageo = 6.28 * (rad * rad) + 6.28 * L * rad - Acap = 2 * Ageo - vmyo = 0.68 * vcell - vnsr = 0.0552 * vcell - vjsr = 0.0048 * vcell - vss = 0.02 * vcell - - # Expressions for the CaMKt component - CaMKb = CaMKo * (1.0 - CaMKt) / (1.0 + KmCaM / cass) - CaMKa = (CaMKb + CaMKt) * HF_scaling_CaMKa - F_expressions[0] = -bCaMK * CaMKt + aCaMK * (CaMKb + CaMKt) * CaMKb - - # Expressions for the reversal potentials component - ENa = R * T * ufl.ln(nao / nai) / F - EK = R * T * ufl.ln(ko / ki) / F - EKs = R * T * ufl.ln((ko + PKNa * nao) / (PKNa * nai + ki)) / F - vffrt = (F * F) * v / (R * T) - vfrt = F * v / (R * T) - - # Expressions for the I_Na component - mss = 1.0 / (1.0 + 0.0014599788446489682 * ufl.exp(-0.13333333333333333 * v)) tm = 1.0 / ( - 9.454904638564724 * ufl.exp(0.02876042565429968 * v) - + 1.9314113558536928e-05 * ufl.exp(-0.16792611251049538 * v) + 6.765 * numpy.exp((v + 11.64) / 34.77) + + 8.552 * numpy.exp((-(v + 77.42)) / 5.955) ) - F_expressions[1] = (-m + mss) / tm - hss = 1.0 / (1 + 302724.605401998 * ufl.exp(0.1607717041800643 * v)) - thf = 1.0 / ( - 1.183856958289087e-05 * ufl.exp(-0.15910898965791567 * v) - + 6.305549185817275 * ufl.exp(0.0493339911198816 * v) + txk1 = 122.2 / ( + numpy.exp((-(v + 127.2)) / 20.36) + numpy.exp((v + 236.8) / 69.33) ) - ths = 1.0 / ( - 0.005164670235381792 * ufl.exp(-0.035650623885918005 * v) - + 0.36987619372096325 * ufl.exp(0.017649135192375574 * v) + txrf = 12.98 + 1.0 / ( + 4.123e-05 * numpy.exp((-(v - 47.78)) / 20.38) + + 0.3652 * numpy.exp((v - 31.66) / 3.869) ) - Ahs = 1.0 - Ahf - F_expressions[2] = (-hf + hss) / thf - F_expressions[3] = (-hs + hss) / ths - h = Ahf * hf + Ahs * hs - jss = hss - tj = 2.038 + 1.0 / ( - 0.3131936394738773 * ufl.exp(0.02600780234070221 * v) - + 1.1315282095590072e-07 * ufl.exp(-0.12075836251660427 * v) + txrs = 1.865 + 1.0 / ( + 1.128e-05 * numpy.exp((-(v - 29.74)) / 25.94) + + 0.06629 * numpy.exp((v - 34.7) / 7.355) ) - F_expressions[4] = (-j + jss) / tj - hssp = 1.0 / (1 + 820249.0921708513 * ufl.exp(0.1607717041800643 * v)) - thsp = 3.0 * ths - F_expressions[5] = (-hsp + hssp) / thsp - hp = Ahf * hf + Ahs * hsp - tjp = 1.46 * tj - F_expressions[6] = (-jp + jss) / tjp - fINap = 1.0 / (1.0 + KmCaMK / CaMKa) - INa = ( - GNa - * scale_drug_INa - * scale_popu_GNa - * ufl.elem_pow(m, 3.0) - * (-ENa + v) - * ((1.0 - fINap) * h * j + fINap * hp * jp) + txs1 = 817.3 + 1.0 / ( + 0.0002326 * numpy.exp((v + 48.28) / 17.8) + + 0.001292 * numpy.exp((-(v + 210.0)) / 230.0) ) - - # Expressions for the INaL component - mLss = 1.0 / (1.0 + 0.000291579585635531 * ufl.exp(-0.18996960486322187 * v)) - tmL = tm - F_expressions[7] = (-mL + mLss) / tmL - hLss = 1.0 / (1.0 + 120578.15595522427 * ufl.exp(0.13354700854700854 * v)) - F_expressions[8] = (-hL + hLss) / (thL * HF_scaling_thL) - hLssp = 1.0 / (1.0 + 275969.2903869871 * ufl.exp(0.13354700854700854 * v)) - thLp = 3.0 * thL * HF_scaling_thL - F_expressions[9] = (-hLp + hLssp) / thLp - GNaL = 0.0075 * scale_INaL * scale_drug_INaL * scale_popu_GNaL * HF_scaling_GNaL - fINaLp = 1.0 / (1.0 + KmCaMK / CaMKa) - INaL = (-ENa + v) * ((1.0 - fINaLp) * hL + fINaLp * hLp) * GNaL * mL - - # Expressions for the Ito component - ass = 1.0 / (1.0 + 2.6316508161673635 * ufl.exp(-0.06747638326585695 * v)) - ta = 1.0515 / ( - 1.0 / (1.2089 + 2.2621017070578837 * ufl.exp(-0.03403513787634354 * v)) - + 3.5 / (1.0 + 30.069572727397507 * ufl.exp(0.03403513787634354 * v)) + txs2 = 1.0 / ( + 0.01 * numpy.exp((v - 50.0) / 20.0) + + 0.0193 * numpy.exp((-(v + 66.54)) / 31.0) ) - F_expressions[10] = (-a + ass) / ta - iss = 1.0 / (1.0 + 2194.970764538301 * ufl.exp(0.17510068289266328 * v)) - tiF = 4.562 + delta_epi / ( - 0.14468698421272827 * ufl.exp(-0.01 * v) - + 1.6300896349780942 * ufl.exp(0.06027727546714889 * v) + xkb = 1.0 / (numpy.exp((-(v - 14.48)) / 18.34) + 1.0) + xrss = 1.0 / (numpy.exp((-(v + 8.337)) / 6.789) + 1.0) + xs1ss = 1.0 / (numpy.exp((-(v + 11.6)) / 8.932) + 1.0) + Afs = 1.0 - Aff + Ageo = L * ((2 * 3.14) * rad) + rad * ((2 * 3.14) * rad) + vcell = L * (rad * ((3.14 * 1000) * rad)) + Ahs = 1.0 - Ahf + Aw = (Tot_A * rs) / (rs + rw * (1 - rs)) + Jupnp = (0.004375 * cai) / (cai + 0.00092) + Jupp = ((0.004375 * 2.75) * cai) / ((cai + 0.00092) - 0.00017) + KsCa = 1.0 + 0.6 / ((3.8e-05 / cai) ** 1.4 + 1.0) + Bcai = 1.0 / ((cmdnmax * kmcmdn) / (cai + kmcmdn) ** 2.0 + 1.0) + Bcajsr = 1.0 / ((csqnmax * kmcsqn) / (cajsr + kmcsqn) ** 2.0 + 1.0) + Bcass = 1.0 / ( + (BSLmax * KmBSL) / (KmBSL + cass) ** 2.0 + + ((BSRmax * KmBSR) / (KmBSR + cass) ** 2.0 + 1.0) ) - tiS = 23.62 + delta_epi / ( - 0.00027617763953377436 * ufl.exp(-0.01693480101608806 * v) - + 0.024208962804604526 * ufl.exp(0.12377769525931426 * v) + Jdiff = (-cai + cass) / 0.2 + CaMKb = (CaMKo * (1.0 - CaMKt)) / (KmCaM / cass + 1.0) + rk1 = 1.0 / (numpy.exp((-2.6 * ko + (v + 105.8)) / 9.493) + 1.0) + xk1ss = 1.0 / ( + numpy.exp((-((2.5538 * ko + v) + 144.59)) / (1.5692 * ko + 3.8115)) + 1.0 + ) + EK = ((R * T) / F) * numpy.log(ko / ki) + vffrt = (F * (F * v)) / ((R * T)) + vfrt = (F * v) / ((R * T)) + EKs = ((R * T) / F) * numpy.log((PKNa * nao + ko) / (PKNa * nai + ki)) + ENa = ((R * T) / F) * numpy.log(nao / nai) + GK1 = scale_HF_GK1 * ((0.1908 * scale_IK1) * scale_drug_IK1) + GKr = (0.046 * scale_IKr) * scale_drug_IKr + GKs = (0.0034 * scale_IKs) * scale_drug_IKs + GNaL = scale_HF_GNaL * ((0.0075 * scale_INaL) * scale_drug_INaL) + km2n = 1.0 * jca + IpCa = (cai * (GpCa * scale_drug_IpCa)) / (cai + 0.0005) + Istim = 0 # (amp) * (duration >= t) + (0) * numpy.logical_not((duration >= t)) + JdiffK = (-ki + kss) / 2.0 + JdiffNa = (-nai + nass) / 2.0 + Jleak = ((0.0039375 * cansr) * scale_HF_Jleak) / 15.0 + Jtr = (-cajsr + cansr) / 100.0 + Knai = Knai0 * numpy.exp((F * (delta * v)) / (((3.0 * R) * T))) + Knao = Knao0 * numpy.exp((F * (v * (1.0 - delta))) / (((3.0 * R) * T))) + P = eP / (((H / Khp + 1.0) + nai / Knap) + ki / Kxkur) + PCa = (0.0001 * scale_ICaL) * scale_drug_ICaL + XU = -XW + (-XS + (1 - TmB)) + a2 = k2p + a4 = ((MgATP * k4p) / Kmgatp) / (1.0 + MgATP / Kmgatp) + a_rel = 0.5 * bt + btp = 1.25 * bt + tau_rel_tmp = bt / (1.0 + 0.0123 / cajsr) + allo_i = 1.0 / ((KmCaAct / cai) ** 2.0 + 1.0) + allo_ss = 1.0 / ((KmCaAct / cass) ** 2.0 + 1.0) + b1 = MgADP * k1m + ksu = (kws * rw) * (-1 + 1 / rs) + cs = ((kws * phi) * (rw * (1 - rs))) / rs + cw = ((kuw * phi) * ((1 - rs) * (1 - rw))) / ((rw * (1 - rs))) + kwu = kuw * (-1 + 1 / rw) - kws + gammasu = gammas * numpy.where( + Zetas * (Zetas > 0) > (-1 - Zetas) * (Zetas < -1), + Zetas * (Zetas > 0), + (-1 - Zetas) * (Zetas < -1), + ) + gammawu = gammaw * numpy.abs(Zetaw) + h4 = (nass / kna1) * (1 + nass / kna2) + 1.0 + h4_i = (nai / kna1) * (1 + nai / kna2) + 1.0 + h10 = (nao / kna1) * (1 + nao / kna2) + (kasymm + 1.0) + h10_i = (nao / kna1) * (1.0 + nao / kna2) + (kasymm + 1.0) + hca = numpy.exp((F * (qca * v)) / ((R * T))) + hna = numpy.exp((F * (qna * v)) / ((R * T))) + k2 = kcaoff + k2_i = kcaoff + k5 = kcaoff + k5_i = kcaoff + kb = (Trpn50**ntm * ku) / (-rw * (1 - rs) + (1 - rs)) + lambda_min12 = (lmbda) * (lmbda < 1.2) + (1.2) * numpy.logical_not( + (lmbda < 1.2), ) - AiF = 1.0 / (1.0 + 0.24348537187522867 * ufl.exp(0.006613756613756614 * v)) - AiS = 1.0 - AiF - F_expressions[11] = (-iF + iss) / tiF - F_expressions[12] = (-iS + iss) / tiS - i = AiF * iF + AiS * iS - assp = 1.0 / (1.0 + 5.167428462230666 * ufl.exp(-0.06747638326585695 * v)) - F_expressions[13] = (-ap + assp) / ta - dti_develop = 1.354 + 0.0001 / ( - 2.6591269045230603e-05 * ufl.exp(0.06293266205160478 * v) - + 4.5541779737128264e24 * ufl.exp(-4.642525533890436 * v) - ) - dti_recover = 1.0 - 0.5 / (1.0 + 33.11545195869231 * ufl.exp(0.05 * v)) - tiFp = dti_develop * dti_recover * tiF - tiSp = dti_develop * dti_recover * tiS - F_expressions[14] = (-iFp + iss) / tiFp - F_expressions[15] = (-iSp + iss) / tiSp - ip = AiF * iFp + AiS * iSp - fItop = 1.0 / (1.0 + KmCaMK / CaMKa) - Ito = ( - Gto - * scale_drug_Ito - * scale_popu_Gto - * HF_scaling_Gto - * (-EK + v) - * ((1.0 - fItop) * a * i + ap * fItop * ip) - ) - - # Expressions for the ICaL ICaNa ICaK component - dss = 1.0 / (1.0 + 0.39398514226669484 * ufl.exp(-0.23640661938534277 * v)) - td = 0.6 + 1.0 / ( - 3.5254214873653824 * ufl.exp(0.09 * v) - + 0.7408182206817179 * ufl.exp(-0.05 * v) - ) - F_expressions[16] = (-d + dss) / td - fss = 1.0 / (1.0 + 199.86038496778565 * ufl.exp(0.27056277056277056 * v)) - tff = 7.0 + 1.0 / ( - 0.03325075244518792 * ufl.exp(0.1 * v) - + 0.0006090087745647571 * ufl.exp(-0.1 * v) + thLp = scale_HF_thL * (3.0 * thL) + tiF = ( + delta_epi + * ( + 1 + / ( + 0.3933 * numpy.exp((-(v + 100.0)) / 100.0) + + 0.08004 * numpy.exp((v + 50.0) / 16.59) + ) + ) + + 4.562 ) - tfs = 1000.0 + 1.0 / ( - 1.0027667890106652e-05 * ufl.exp(-0.25 * v) - + 8.053415618124885e-05 * ufl.exp(0.16666666666666666 * v) + tiS = ( + delta_epi + * ( + 1 + / ( + 0.001416 * numpy.exp((-(v + 96.52)) / 59.05) + + 1.78e-08 * numpy.exp((v + 114.1) / 8.079) + ) + ) + + 23.62 ) - Afs = 1.0 - Aff - F_expressions[17] = (-ff + fss) / tff - F_expressions[18] = (-fs + fss) / tfs - f = Aff * ff + Afs * fs + Afcas = 1.0 - Afcaf + AiS = 1.0 - AiF + Axrs = 1.0 - Axrf fcass = fss - tfcaf = 7.0 + 1.0 / ( - 0.0708317980974062 * ufl.exp(-0.14285714285714285 * v) - + 0.02258872488031037 * ufl.exp(0.14285714285714285 * v) + dhL_dt = (-hL + hLss) / ((scale_HF_thL * thL)) + dhL_dt_linearized = -1 / (scale_HF_thL * thL) + values[0] = ( + dhL_dt * (numpy.exp(dhL_dt_linearized * dt) - 1) / dhL_dt_linearized + hL ) - tfcas = 100.0 + 1.0 / ( - 0.00012 * ufl.exp(0.14285714285714285 * v) - + 0.00012 * ufl.exp(-0.3333333333333333 * v) + jss = hss + da_dt = (-a + ass) / ta + da_dt_linearized = -1 / ta + values[1] = ( + a + da_dt * (numpy.exp(da_dt_linearized * dt) - 1) / da_dt_linearized ) - Afcaf = 0.3 + 0.6 / (1.0 + 0.36787944117144233 * ufl.exp(0.1 * v)) - Afcas = 1.0 - Afcaf - F_expressions[19] = (-fcaf + fcass) / tfcaf - F_expressions[20] = (-fcas + fcass) / tfcas - fca = Afcaf * fcaf + Afcas * fcas - F_expressions[21] = (-jca + fcass) / tjca - tffp = 2.5 * tff - F_expressions[22] = (-ffp + fss) / tffp - fp = Aff * ffp + Afs * fs - tfcafp = 2.5 * tfcaf - F_expressions[23] = (-fcafp + fcass) / tfcafp - fcap = Afcaf * fcafp + Afcas * fcas - km2n = 1.0 * jca - anca = 1.0 / (ufl.elem_pow(1.0 + Kmn / cass, 4.0) + k2n / km2n) - F_expressions[24] = k2n * anca - km2n * nca - PhiCaL = ( - 4.0 - * (-0.341 * cao + cass * ufl.exp(2.0 * vfrt)) - * vffrt - / (-1.0 + ufl.exp(2.0 * vfrt)) + dap_dt = (-ap + assp) / ta + dap_dt_linearized = -1 / ta + values[2] = ( + ap + dap_dt * (numpy.exp(dap_dt_linearized * dt) - 1) / dap_dt_linearized ) - PhiCaNa = ( - 1.0 - * (-0.75 * nao + 0.75 * ufl.exp(1.0 * vfrt) * nass) - * vffrt - / (-1.0 + ufl.exp(1.0 * vfrt)) + dd_dt = (-d + dss) / td + dd_dt_linearized = -1 / td + values[3] = ( + d + dd_dt * (numpy.exp(dd_dt_linearized * dt) - 1) / dd_dt_linearized ) - PhiCaK = ( - 1.0 - * (-0.75 * ko + 0.75 * ufl.exp(1.0 * vfrt) * kss) - * vffrt - / (-1.0 + ufl.exp(1.0 * vfrt)) + tfcafp = 2.5 * tfcaf + tffp = 2.5 * tff + dff_dt = (-ff + fss) / tff + dff_dt_linearized = -1 / tff + values[4] = ( + dff_dt * (numpy.exp(dff_dt_linearized * dt) - 1) / dff_dt_linearized + ff ) - PCa = 0.0001 * scale_ICaL * scale_drug_ICaL * scale_popu_GCaL - PCap = 1.1 * PCa - PCaNa = 0.00125 * PCa - PCaK = 0.0003574 * PCa - PCaNap = 0.00125 * PCap - PCaKp = 0.0003574 * PCap - fICaLp = 1.0 / (1.0 + KmCaMK / CaMKa) - ICaL = (1.0 - fICaLp) * ( - (1.0 - nca) * f + fca * jca * nca - ) * PCa * PhiCaL * d + ( - (1.0 - nca) * fp + fcap * jca * nca - ) * PCap * PhiCaL * d * fICaLp - ICaNa = (1.0 - fICaLp) * ( - (1.0 - nca) * f + fca * jca * nca - ) * PCaNa * PhiCaNa * d + ( - (1.0 - nca) * fp + fcap * jca * nca - ) * PCaNap * PhiCaNa * d * fICaLp - ICaK = (1.0 - fICaLp) * ( - (1.0 - nca) * f + fca * jca * nca - ) * PCaK * PhiCaK * d + ( - (1.0 - nca) * fp + fcap * jca * nca - ) * PCaKp * PhiCaK * d * fICaLp - - # Expressions for the IKr component - xrss = 1.0 / (1.0 + 0.29287308872377504 * ufl.exp(-0.14729709824716453 * v)) - txrf = 12.98 + 1.0 / ( - 0.0001020239312894894 * ufl.exp(0.25846471956577927 * v) - + 0.00042992960891929087 * ufl.exp(-0.04906771344455348 * v) + dfs_dt = (-fs + fss) / tfs + dfs_dt_linearized = -1 / tfs + values[5] = ( + dfs_dt * (numpy.exp(dfs_dt_linearized * dt) - 1) / dfs_dt_linearized + fs ) - txrs = 1.865 + 1.0 / ( - 0.0005922420036809394 * ufl.exp(0.13596193065941536 * v) - + 3.549966111802463e-05 * ufl.exp(-0.03855050115651503 * v) + dhf_dt = (-hf + hss) / thf + dhf_dt_linearized = -1 / thf + values[6] = ( + dhf_dt * (numpy.exp(dhf_dt_linearized * dt) - 1) / dhf_dt_linearized + hf ) - Axrf = 1.0 / (1.0 + 4.197299094734718 * ufl.exp(0.02617115938236064 * v)) - Axrs = 1.0 - Axrf - F_expressions[25] = (-xrf + xrss) / txrf - F_expressions[26] = (-xrs + xrss) / txrs - xr = Axrf * xrf + Axrs * xrs - rkr = 1.0 / ( - (1.0 + 2.0820090840784555 * ufl.exp(0.013333333333333334 * v)) - * (1.0 + 0.7165313105737893 * ufl.exp(0.03333333333333333 * v)) + thsp = 3.0 * ths + dhs_dt = (-hs + hss) / ths + dhs_dt_linearized = -1 / ths + values[7] = ( + dhs_dt * (numpy.exp(dhs_dt_linearized * dt) - 1) / dhs_dt_linearized + hs ) - GKr = 0.046 * scale_IKr * scale_drug_IKr * scale_popu_GKr - IKr = 0.4303314829119352 * ufl.sqrt(ko) * (-EK + v) * GKr * rkr * xr - - # Expressions for the IKs component - xs1ss = 1.0 / (1.0 + 0.27288596035656526 * ufl.exp(-0.11195700850873264 * v)) - txs1 = 817.3 + 1.0 / ( - 0.003504067763074858 * ufl.exp(0.056179775280898875 * v) - + 0.0005184809083581659 * ufl.exp(-0.004347826086956522 * v) + tjp = 1.46 * tj + tmL = tm + dm_dt = (-m + mss) / tm + dm_dt_linearized = -1 / tm + values[8] = ( + dm_dt * (numpy.exp(dm_dt_linearized * dt) - 1) / dm_dt_linearized + m + ) + dxrf_dt = (-xrf + xrss) / txrf + dxrf_dt_linearized = -1 / txrf + values[9] = ( + dxrf_dt * (numpy.exp(dt * dxrf_dt_linearized) - 1) / dxrf_dt_linearized + + xrf + ) + dxrs_dt = (-xrs + xrss) / txrs + dxrs_dt_linearized = -1 / txrs + values[10] = ( + dxrs_dt * (numpy.exp(dt * dxrs_dt_linearized) - 1) / dxrs_dt_linearized + + xrs ) - F_expressions[27] = (-xs1 + xs1ss) / txs1 xs2ss = xs1ss - txs2 = 1.0 / ( - 0.0022561357010639103 * ufl.exp(-0.03225806451612903 * v) - + 0.0008208499862389881 * ufl.exp(0.05 * v) + dxs1_dt = (-xs1 + xs1ss) / txs1 + dxs1_dt_linearized = -1 / txs1 + values[11] = ( + dxs1_dt * (numpy.exp(dt * dxs1_dt_linearized) - 1) / dxs1_dt_linearized + + xs1 ) - F_expressions[28] = (-xs2 + xs2ss) / txs2 - KsCa = 1.0 + 0.6 / (1.0 + 6.481821026062645e-07 * ufl.elem_pow(1.0 / cai, 1.4)) - GKs = 0.0034 * scale_IKs * scale_drug_IKs * scale_popu_GKs - IKs = (-EKs + v) * GKs * KsCa * xs1 * xs2 - xk1ss = 1.0 / ( - 1.0 + ufl.exp((-144.59 - v - 2.5538 * ko) / (3.8115 + 1.5692 * ko)) + f = Aff * ff + Afs * fs + fp = Aff * ffp + Afs * fs + Acap = 2 * Ageo + vjsr = 0.0048 * vcell + vmyo = 0.68 * vcell + vnsr = 0.0552 * vcell + vss = 0.02 * vcell + h = Ahf * hf + Ahs * hs + hp = Ahf * hf + Ahs * hsp + As = Aw + CaMKa = scale_HF_CaMKa * (CaMKb + CaMKt) + dCaMKt_dt = -CaMKt * bCaMK + (CaMKb * aCaMK) * (CaMKb + CaMKt) + dCaMKt_dt_linearized = CaMKb * aCaMK - bCaMK + values[12] = ( + CaMKt + + dCaMKt_dt + * (numpy.exp(dCaMKt_dt_linearized * dt) - 1) + / dCaMKt_dt_linearized + * (numpy.abs(dCaMKt_dt_linearized) > 1e-08) + + dCaMKt_dt * dt * (~(numpy.abs(dCaMKt_dt_linearized) > 1e-08)) + ) + dxk1_dt = (-xk1 + xk1ss) / txk1 + dxk1_dt_linearized = -1 / txk1 + values[13] = ( + dxk1_dt * (numpy.exp(dt * dxk1_dt_linearized) - 1) / dxk1_dt_linearized + + xk1 + ) + IKb = (xkb * (GKb * scale_drug_IKb)) * (-EK + v) + ICab = ( + (vffrt * (4.0 * (PCab * scale_drug_ICab))) + * (cai * numpy.exp(2.0 * vfrt) - 0.341 * cao) + ) / (numpy.exp(2.0 * vfrt) - 1.0) + INab = ((vffrt * (PNab * scale_drug_INab)) * (nai * numpy.exp(vfrt) - nao)) / ( + numpy.exp(vfrt) - 1.0 ) - txk1 = 122.2 / ( - 0.0019352007631390235 * ufl.exp(-0.049115913555992145 * v) - + 30.43364757524903 * ufl.exp(0.014423770373575654 * v) - ) - F_expressions[29] = (-xk1 + xk1ss) / txk1 - rk1 = 1.0 / ( - 1.0 - + 69220.6322106767 - * ufl.exp(0.10534077741493732 * v - 0.27388602127883704 * ko) - ) - GK1 = 0.1908 * scale_IK1 * scale_drug_IK1 * scale_popu_GK1 * HF_scaling_GK1 - IK1 = ufl.sqrt(ko) * (-EK + v) * GK1 * rk1 * xk1 - - # Expressions for the INaCa_i component - hca = ufl.exp(F * qca * v / (R * T)) - hna = ufl.exp(F * qna * v / (R * T)) - h1_i = 1.0 + (1.0 + hna) * nai / kna3 - h2_i = hna * nai / (kna3 * h1_i) - h3_i = 1.0 / h1_i - h4_i = 1.0 + (1 + nai / kna2) * nai / kna1 - h5_i = (nai * nai) / (kna1 * kna2 * h4_i) - h6_i = 1.0 / h4_i - h7_i = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 - h8_i = nao / (kna3 * h7_i * hna) - h9_i = 1.0 / h7_i - h10_i = 1.0 + kasymm + nao * (1.0 + nao / kna2) / kna1 - h11_i = (nao * nao) / (kna1 * kna2 * h10_i) - h12_i = 1.0 / h10_i - k1_i = cao * kcaon * h12_i - k2_i = kcaoff - k3p_i = wca * h9_i - k3pp_i = wnaca * h8_i - k3_i = k3p_i + k3pp_i - k4p_i = wca * h3_i / hca - k4pp_i = wnaca * h2_i - k4_i = k4p_i + k4pp_i - k5_i = kcaoff - k6_i = kcaon * cai * h6_i - k7_i = wna * h2_i * h5_i - k8_i = wna * h11_i * h8_i - x1_i = (k2_i + k3_i) * k5_i * k7_i + (k6_i + k7_i) * k2_i * k4_i - x2_i = (k1_i + k8_i) * k4_i * k6_i + (k4_i + k5_i) * k1_i * k7_i - x3_i = (k2_i + k3_i) * k6_i * k8_i + (k6_i + k7_i) * k1_i * k3_i - x4_i = (k1_i + k8_i) * k3_i * k5_i + (k4_i + k5_i) * k2_i * k8_i - E1_i = x1_i / (x1_i + x2_i + x3_i + x4_i) - E2_i = x2_i / (x1_i + x2_i + x3_i + x4_i) - E3_i = x3_i / (x1_i + x2_i + x3_i + x4_i) - E4_i = x4_i / (x1_i + x2_i + x3_i + x4_i) - allo_i = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cai, 2.0)) - zna = 1.0 - JncxNa_i = E3_i * k4pp_i - E2_i * k3pp_i + 3.0 * E4_i * k7_i - 3.0 * E1_i * k8_i - JncxCa_i = E2_i * k2_i - E1_i * k1_i - INaCa_i = ( - 0.8 - * Gncx - * scale_popu_KNCX - * HF_scaling_Gncx - * (zca * JncxCa_i + zna * JncxNa_i) - * allo_i - ) - - # Expressions for the INaCa_ss component - h1 = 1.0 + (1.0 + hna) * nass / kna3 - h2 = hna * nass / (kna3 * h1) - h3 = 1.0 / h1 - h4 = 1.0 + (1 + nass / kna2) * nass / kna1 - h5 = (nass * nass) / (kna1 * kna2 * h4) - h6 = 1.0 / h4 - h7 = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 - h8 = nao / (kna3 * h7 * hna) - h9 = 1.0 / h7 - h10 = 1.0 + kasymm + nao * (1 + nao / kna2) / kna1 - h11 = (nao * nao) / (kna1 * kna2 * h10) - h12 = 1.0 / h10 - k1 = cao * kcaon * h12 - k2 = kcaoff - k3p_ss = wca * h9 - k3pp = wnaca * h8 - k3 = k3p_ss + k3pp - k4p_ss = wca * h3 / hca - k4pp = wnaca * h2 - k4 = k4p_ss + k4pp - k5 = kcaoff - k6 = kcaon * cass * h6 - k7 = wna * h2 * h5 - k8 = wna * h11 * h8 - x1_ss = (k2 + k3) * k5 * k7 + (k6 + k7) * k2 * k4 - x2_ss = (k1 + k8) * k4 * k6 + (k4 + k5) * k1 * k7 - x3_ss = (k2 + k3) * k6 * k8 + (k6 + k7) * k1 * k3 - x4_ss = (k1 + k8) * k3 * k5 + (k4 + k5) * k2 * k8 - E1_ss = x1_ss / (x1_ss + x2_ss + x3_ss + x4_ss) - E2_ss = x2_ss / (x1_ss + x2_ss + x3_ss + x4_ss) - E3_ss = x3_ss / (x1_ss + x2_ss + x3_ss + x4_ss) - E4_ss = x4_ss / (x1_ss + x2_ss + x3_ss + x4_ss) - allo_ss = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cass, 2.0)) - JncxNa_ss = E3_ss * k4pp - E2_ss * k3pp + 3.0 * E4_ss * k7 - 3.0 * E1_ss * k8 - JncxCa_ss = E2_ss * k2 - E1_ss * k1 - INaCa_ss = ( - 0.2 - * Gncx - * scale_popu_KNCX - * HF_scaling_Gncx - * (zca * JncxCa_ss + zna * JncxNa_ss) - * allo_ss - ) - - # Expressions for the INaK component - Knai = Knai0 * ufl.exp(0.3333333333333333 * F * delta * v / (R * T)) - Knao = Knao0 * ufl.exp(0.3333333333333333 * F * (1.0 - delta) * v / (R * T)) - P = eP / (1.0 + H / Khp + nai / Knap + ki / Kxkur) - a1 = ( - k1p - * ufl.elem_pow(nai / Knai, 3.0) - / ( - -1.0 - + ufl.elem_pow(1.0 + ki / Kki, 2.0) - + ufl.elem_pow(1.0 + nai / Knai, 3.0) - ) + PhiCaK = ( + (1.0 * vffrt) * (-0.75 * ko + (0.75 * kss) * numpy.exp(1.0 * vfrt)) + ) / (numpy.exp(1.0 * vfrt) - 1.0) + PhiCaL = ((4.0 * vffrt) * (-0.341 * cao + cass * numpy.exp(2.0 * vfrt))) / ( + numpy.exp(2.0 * vfrt) - 1.0 ) - b1 = MgADP * k1m - a2 = k2p - b2 = ( - k2m - * ufl.elem_pow(nao / Knao, 3.0) - / ( - -1.0 - + ufl.elem_pow(1.0 + ko / Kko, 2.0) - + ufl.elem_pow(1.0 + nao / Knao, 3.0) - ) + PhiCaNa = ( + (1.0 * vffrt) * (-0.75 * nao + (0.75 * nass) * numpy.exp(1.0 * vfrt)) + ) / (numpy.exp(1.0 * vfrt) - 1.0) + IK1 = (xk1 * (rk1 * (GK1 * math.sqrt(ko)))) * (-EK + v) + IKs = (xs2 * (xs1 * (GKs * KsCa))) * (-EKs + v) + anca = 1.0 / (k2n / km2n + (Kmn / cass + 1.0) ** 4.0) + a1 = (k1p * (nai / Knai) ** 3.0) / ( + ((1.0 + ki / Kki) ** 2.0 + (1.0 + nai / Knai) ** 3.0) - 1.0 ) - a3 = ( - k3p - * ufl.elem_pow(ko / Kko, 2.0) - / ( - -1.0 - + ufl.elem_pow(1.0 + ko / Kko, 2.0) - + ufl.elem_pow(1.0 + nao / Knao, 3.0) - ) + b4 = (k4m * (ki / Kki) ** 2.0) / ( + ((1.0 + ki / Kki) ** 2.0 + (1.0 + nai / Knai) ** 3.0) - 1.0 ) - b3 = H * k3m * P / (1.0 + MgATP / Kmgatp) - a4 = MgATP * k4p / (Kmgatp * (1.0 + MgATP / Kmgatp)) - b4 = ( - k4m - * ufl.elem_pow(ki / Kki, 2.0) - / ( - -1.0 - + ufl.elem_pow(1.0 + ki / Kki, 2.0) - + ufl.elem_pow(1.0 + nai / Knai, 3.0) - ) + a3 = (k3p * (ko / Kko) ** 2.0) / ( + ((1.0 + ko / Kko) ** 2.0 + (1.0 + nao / Knao) ** 3.0) - 1.0 ) - x1 = a1 * a2 * a4 + a1 * a2 * b3 + a2 * b3 * b4 + b2 * b3 * b4 - x2 = a1 * a2 * a3 + a2 * a3 * b4 + a3 * b1 * b4 + b1 * b2 * b4 - x3 = a2 * a3 * a4 + a3 * a4 * b1 + a4 * b1 * b2 + b1 * b2 * b3 - x4 = a1 * a3 * a4 + a1 * a4 * b2 + a1 * b2 * b3 + b2 * b3 * b4 - E1 = x1 / (x1 + x2 + x3 + x4) - E2 = x2 / (x1 + x2 + x3 + x4) - E3 = x3 / (x1 + x2 + x3 + x4) - E4 = x4 / (x1 + x2 + x3 + x4) - JnakNa = 3.0 * E1 * a3 - 3.0 * E2 * b3 - JnakK = 2.0 * E4 * b1 - 2.0 * E3 * a1 - INaK = Pnak * scale_popu_KNaK * HF_scaling_Pnak * (zk * JnakK + zna * JnakNa) - - # Expressions for the IKb component - xkb = 1.0 / (1.0 + 2.202363450949239 * ufl.exp(-0.05452562704471101 * v)) - IKb = GKb * scale_popu_GbK * scale_drug_IKb * (-EK + v) * xkb - - # Expressions for the INab component - INab = ( - PNab - * scale_drug_INab - * scale_popu_GbNa - * (-nao + ufl.exp(vfrt) * nai) - * vffrt - / (-1.0 + ufl.exp(vfrt)) - ) - - # Expressions for the ICab component - ICab = ( - 4.0 - * PCab - * scale_drug_ICab - * scale_popu_GbCa - * (-0.341 * cao + cai * ufl.exp(2.0 * vfrt)) - * vffrt - / (-1.0 + ufl.exp(2.0 * vfrt)) - ) - - # Expressions for the IpCa component - IpCa = GpCa * scale_drug_IpCa * scale_popu_KpCa * cai / (0.0005 + cai) - - # Expressions for the Isac (Pueyo)--> ns + k component - Gsac_ns = 0.006 * scale_drug_Isacns - Esac_ns = -10.0 - lambda_max = 1.1 - Gsac_k = (0.2882 * 800.0 / 210.0) * scale_drug_Isack # Pueyo endo - Isac_P_ns = ufl.conditional( - ufl.lt(self.lmbda, 1.0), - 0.0, - Gsac_ns * ((self.lmbda - 1.0) / (lambda_max - 1.0)) * (v - Esac_ns), - ) - Isac_P_k = ufl.conditional( - ufl.lt(self.lmbda, 1.0), - 0.0, - Gsac_k - * ((self.lmbda - 1.0) / (lambda_max - 1.0)) - * (1.0 / (1.0 + ufl.exp((19.05 - v) / (29.98)))), - ) - - # Expressions for the Istim component - Istim = 0 # amp*(ufl.le(time, duration)) - - # Expressions for the diffusion fluxes component - JdiffNa = 0.5 * nass - 0.5 * nai - JdiffK = 0.5 * kss - 0.5 * ki - Jdiff = 5.0 * cass - 5.0 * cai - - # Expressions for the ryanodine receptor component - a_rel = 0.5 * bt - Jrel_inf = ( - -ICaL - * a_rel - / (1.0 + 25.62890625 * HF_scaling_Jrel_inf * ufl.elem_pow(1.0 / cajsr, 8.0)) + b2 = (k2m * (nao / Knao) ** 3.0) / ( + ((1.0 + ko / Kko) ** 2.0 + (1.0 + nao / Knao) ** 3.0) - 1.0 ) - tau_rel_tmp = bt / (1.0 + 0.0123 / cajsr) - tau_rel = ufl.conditional(ufl.lt(tau_rel_tmp, 0.001), 0.001, tau_rel_tmp) - F_expressions[30] = (-Jrelnp + Jrel_inf) / tau_rel - btp = 1.25 * bt + b3 = (H * (P * k3m)) / (1.0 + MgATP / Kmgatp) + PCaK = 0.0003574 * PCa + PCaNa = 0.00125 * PCa + PCap = 1.1 * PCa a_relp = 0.5 * btp - Jrel_infp = ( - -ICaL - * a_relp - / (1.0 + 25.62890625 * HF_scaling_Jrel_inf * ufl.elem_pow(1.0 / cajsr, 8.0)) - ) tau_relp_tmp = btp / (1.0 + 0.0123 / cajsr) - tau_relp = ufl.conditional(ufl.lt(tau_relp_tmp, 0.001), 0.001, tau_relp_tmp) - F_expressions[31] = (-Jrelp + Jrel_infp) / tau_relp + tau_rel = (0.001) * (tau_rel_tmp < 0.001) + (tau_rel_tmp) * numpy.logical_not( + (tau_rel_tmp < 0.001), + ) + dZetaw_dt = Aw * dLambda - Zetaw * cw + dZetaw_dt_linearized = -cw + values[14] = ( + Zetaw + + dZetaw_dt + * (numpy.exp(dZetaw_dt_linearized * dt) - 1) + / dZetaw_dt_linearized + * (numpy.abs(dZetaw_dt_linearized) > 1e-08) + + dZetaw_dt * dt * (~(numpy.abs(dZetaw_dt_linearized) > 1e-08)) + ) + dXS_dt = -XS * gammasu + (-XS * ksu + XW * kws) + dXS_dt_linearized = -gammasu - ksu + values[15] = ( + XS + + dXS_dt + * (numpy.exp(dXS_dt_linearized * dt) - 1) + / dXS_dt_linearized + * (numpy.abs(dXS_dt_linearized) > 1e-08) + + dXS_dt * dt * (~(numpy.abs(dXS_dt_linearized) > 1e-08)) + ) + dXW_dt = -XW * gammawu + (-XW * kws + (XU * kuw - XW * kwu)) + dXW_dt_linearized = -gammawu - kws - kwu + values[16] = ( + XW + + dXW_dt + * (numpy.exp(dXW_dt_linearized * dt) - 1) + / dXW_dt_linearized + * (numpy.abs(dXW_dt_linearized) > 1e-08) + + dXW_dt * dt * (~(numpy.abs(dXW_dt_linearized) > 1e-08)) + ) + h5 = (nass * nass) / ((kna2 * (h4 * kna1))) + h6 = 1.0 / h4 + h5_i = (nai * nai) / ((kna2 * (h4_i * kna1))) + h6_i = 1.0 / h4_i + h11 = (nao * nao) / ((kna2 * (h10 * kna1))) + h12 = 1.0 / h10 + h11_i = (nao * nao) / ((kna2 * (h10_i * kna1))) + h12_i = 1.0 / h10_i + h1 = (nass / kna3) * (hna + 1) + 1 + h1_i = (nai / kna3) * (hna + 1) + 1 + h7 = (nao / kna3) * (1.0 + 1.0 / hna) + 1.0 + h7_i = (nao / kna3) * (1.0 + 1.0 / hna) + 1.0 + dTmB_dt = -TmB * CaTrpn ** (ntm / 2) * ku + XU * ( + kb + * numpy.where( + (CaTrpn ** (-1 / 2 * ntm) < 100), + CaTrpn ** (-1 / 2 * ntm), + 100, + ) + ) + dTmB_dt_linearized = numpy.where( + numpy.isclose(CaTrpn, 0), + 0, + -(CaTrpn ** (ntm / 2)) * ku, + ) + values[17] = ( + TmB + + dTmB_dt + * (numpy.exp(dTmB_dt_linearized * dt) - 1) + / dTmB_dt_linearized + * (numpy.abs(dTmB_dt_linearized) > 1e-08) + + dTmB_dt * dt * (~(numpy.abs(dTmB_dt_linearized) > 1e-08)) + ) + C = lambda_min12 - 1 + cat50 = scale_HF_cat50_ref * (Beta1 * (lambda_min12 - 1) + cat50_ref) + lambda_min087 = (lambda_min12) * (lambda_min12 < 0.87) + ( + 0.87 + ) * numpy.logical_not((lambda_min12 < 0.87)) + dhLp_dt = (-hLp + hLssp) / thLp + dhLp_dt_linearized = -1 / thLp + values[18] = ( + dhLp_dt * (numpy.exp(dhLp_dt_linearized * dt) - 1) / dhLp_dt_linearized + + hLp + ) + tiFp = tiF * (dti_develop * dti_recover) + diF_dt = (-iF + iss) / tiF + diF_dt_linearized = -1 / tiF + values[19] = ( + diF_dt * (numpy.exp(diF_dt_linearized * dt) - 1) / diF_dt_linearized + iF + ) + tiSp = tiS * (dti_develop * dti_recover) + diS_dt = (-iS + iss) / tiS + diS_dt_linearized = -1 / tiS + values[20] = ( + diS_dt * (numpy.exp(diS_dt_linearized * dt) - 1) / diS_dt_linearized + iS + ) + fca = Afcaf * fcaf + Afcas * fcas + fcap = Afcaf * fcafp + Afcas * fcas + i = AiF * iF + AiS * iS + ip = AiF * iFp + AiS * iSp + xr = Axrf * xrf + Axrs * xrs + dfcaf_dt = (-fcaf + fcass) / tfcaf + dfcaf_dt_linearized = -1 / tfcaf + values[21] = ( + dfcaf_dt * (numpy.exp(dfcaf_dt_linearized * dt) - 1) / dfcaf_dt_linearized + + fcaf + ) + dfcas_dt = (-fcas + fcass) / tfcas + dfcas_dt_linearized = -1 / tfcas + values[22] = ( + dfcas_dt * (numpy.exp(dfcas_dt_linearized * dt) - 1) / dfcas_dt_linearized + + fcas + ) + djca_dt = (fcass - jca) / tjca + djca_dt_linearized = -1 / tjca + values[23] = ( + djca_dt * (numpy.exp(djca_dt_linearized * dt) - 1) / djca_dt_linearized + + jca + ) + dj_dt = (-j + jss) / tj + dj_dt_linearized = -1 / tj + values[24] = ( + dj_dt * (numpy.exp(dj_dt_linearized * dt) - 1) / dj_dt_linearized + j + ) + dfcafp_dt = (-fcafp + fcass) / tfcafp + dfcafp_dt_linearized = -1 / tfcafp + values[25] = ( + dfcafp_dt + * (numpy.exp(dfcafp_dt_linearized * dt) - 1) + / dfcafp_dt_linearized + + fcafp + ) + dffp_dt = (-ffp + fss) / tffp + dffp_dt_linearized = -1 / tffp + values[26] = ( + dffp_dt * (numpy.exp(dffp_dt_linearized * dt) - 1) / dffp_dt_linearized + + ffp + ) + dhsp_dt = (-hsp + hssp) / thsp + dhsp_dt_linearized = -1 / thsp + values[27] = ( + dhsp_dt * (numpy.exp(dhsp_dt_linearized * dt) - 1) / dhsp_dt_linearized + + hsp + ) + djp_dt = (-jp + jss) / tjp + djp_dt_linearized = -1 / tjp + values[28] = ( + djp_dt * (numpy.exp(djp_dt_linearized * dt) - 1) / djp_dt_linearized + jp + ) + dmL_dt = (-mL + mLss) / tmL + dmL_dt_linearized = -1 / tmL + values[29] = ( + dmL_dt * (numpy.exp(dmL_dt_linearized * dt) - 1) / dmL_dt_linearized + mL + ) + dxs2_dt = (-xs2 + xs2ss) / txs2 + dxs2_dt_linearized = -1 / txs2 + values[30] = ( + dxs2_dt * (numpy.exp(dt * dxs2_dt_linearized) - 1) / dxs2_dt_linearized + + xs2 + ) + dZetas_dt = As * dLambda - Zetas * cs + dZetas_dt_linearized = -cs + values[31] = ( + Zetas + + dZetas_dt + * (numpy.exp(dZetas_dt_linearized * dt) - 1) + / dZetas_dt_linearized + * (numpy.abs(dZetas_dt_linearized) > 1e-08) + + dZetas_dt * dt * (~(numpy.abs(dZetas_dt_linearized) > 1e-08)) + ) + fICaLp = 1.0 / (1.0 + KmCaMK / CaMKa) + fINaLp = 1.0 / (1.0 + KmCaMK / CaMKa) + fINap = 1.0 / (1.0 + KmCaMK / CaMKa) + fItop = 1.0 / (1.0 + KmCaMK / CaMKa) fJrelp = 1.0 / (1.0 + KmCaMK / CaMKa) - Jrel = ((1.0 - fJrelp) * Jrelnp + Jrelp * fJrelp) * scale_popu_KRyR - - # Expressions for the calcium buffers component - Jupnp = 0.004375 * cai / (0.00092 + cai) - Jupp = 0.01203125 * cai / (0.00075 + cai) fJupp = 1.0 / (1.0 + KmCaMK / CaMKa) - Jleak = 0.0002625 * cansr * scale_popu_Kleak * HF_scaling_Jleak - Jup = ( - -Jleak - + ((1.0 - fJupp) * Jupnp + Jupp * fJupp) - * scale_popu_KSERCA - * HF_scaling_Jup - ) - Jtr = 0.01 * cansr - 0.01 * cajsr - - # Expressions for the intracellular concentrations component - F_expressions[32] = JdiffNa * vss / vmyo + ( - -INa - INaL - INab - Isac_P_ns / 3.0 - 3.0 * INaCa_i - 3.0 * INaK - ) * Acap / (F * vmyo) - F_expressions[33] = -JdiffNa + (-ICaNa - 3.0 * INaCa_ss) * Acap / (F * vss) - F_expressions[34] = JdiffK * vss / vmyo + ( - -Isac_P_k - - IK1 - - IKb - - IKr - - IKs - - Istim - - Ito - - Isac_P_ns / 3.0 - + 2.0 * INaK - ) * Acap / (F * vmyo) - F_expressions[35] = -JdiffK - Acap * ICaK / (F * vss) - Bcass = 1.0 / ( - 1.0 - + BSLmax * KmBSL * ufl.elem_pow(KmBSL + cass, -2.0) - + BSRmax * KmBSR * ufl.elem_pow(KmBSR + cass, -2.0) - ) - F_expressions[36] = ( - -Jdiff - + Jrel * vjsr / vss - + 0.5 * (-ICaL + 2.0 * INaCa_ss) * Acap / (F * vss) - ) * Bcass - F_expressions[37] = -Jtr * vjsr / vnsr + Jup - Bcajsr = 1.0 / (1.0 + csqnmax * kmcsqn * ufl.elem_pow(kmcsqn + cajsr, -2.0)) - F_expressions[38] = (-Jrel + Jtr) * Bcajsr - - # Expressions for the mechanics component - kwu = -kws * scale_popu_kws + (kuw * scale_popu_kuw) * ( - -1.0 + 1.0 / (rw * scale_popu_rw) - ) - ksu = ( - kws - * scale_popu_kws - * rw - * scale_popu_rw - * (-1.0 + 1.0 / (rs * scale_popu_rs)) - ) - - Aw = Tot_A * rs / (rs + rw * (1 - rs)) - As = Aw - cw = kuw * phi * (1 - rw) / rw - cs = kws * phi * rw * (1 - rs) / rs - - lambda_min12 = ufl.conditional(ufl.lt(self.lmbda, 1.2), self.lmbda, 1.2) - XS = ufl.conditional(ufl.lt(XS, 0.0), 0.0, XS) - XW = ufl.conditional(ufl.lt(XW, 0.0), 0.0, XW) - - XU = 1.0 - TmB - XS - XW - gammawu = gammaw * abs(Zetaw) - # gammasu = gammas*ufl.conditional(ufl.gt(Zetas*(ufl.gt(Zetas, 0)), (-1 -\ - # Zetas)*(ufl.lt(Zetas, -1))), Zetas*(ufl.gt(Zetas, 0)), (-1 -\ - # Zetas)*(ufl.lt(Zetas, -1))) - zetas1 = Zetas * ufl.conditional(ufl.gt(Zetas, 0.0), 1.0, 0.0) - zetas2 = (-1.0 - Zetas) * ufl.conditional( - ufl.lt(Zetas, -1.0), - 1.0, - 0.0, - ) - gammasu = gammas * Max(zetas1, zetas2) - - F_expressions[39] = kws * scale_popu_kws * XW - XS * gammasu - XS * ksu - F_expressions[40] = ( - kuw * scale_popu_kuw * XU - - kws * scale_popu_kws * XW - - XW * gammawu - - XW * kwu - ) - cat50 = ( - cat50_ref * scale_popu_CaT50ref + Beta1 * (-1.0 + lambda_min12) - ) * HF_scaling_cat50_ref - CaTrpn = ufl.conditional(ufl.lt(CaTrpn, 0.0), 0.0, CaTrpn) - F_expressions[41] = ( - ktrpn - * scale_popu_kTRPN + dnca_dt = anca * k2n - km2n * nca + dnca_dt_linearized = -km2n + values[32] = ( + nca + + dnca_dt + * (numpy.exp(dnca_dt_linearized * dt) - 1) + / dnca_dt_linearized + * (numpy.abs(dnca_dt_linearized) > 1e-08) + + dnca_dt * dt * (~(numpy.abs(dnca_dt_linearized) > 1e-08)) + ) + x2 = b4 * (a2 * a3) + (b4 * (a3 * b1) + (a3 * (a1 * a2) + b4 * (b1 * b2))) + x1 = a2 * (a1 * b3) + (b3 * (a2 * b4) + (a2 * (a1 * a4) + b3 * (b2 * b4))) + x3 = b1 * (a3 * a4) + (a4 * (b1 * b2) + (a4 * (a2 * a3) + b1 * (b2 * b3))) + x4 = a1 * (b2 * b3) + (a1 * (a4 * b2) + (a1 * (a3 * a4) + b2 * (b3 * b4))) + PCaKp = 0.0003574 * PCap + PCaNap = 0.00125 * PCap + tau_relp = (0.001) * (tau_relp_tmp < 0.001) + ( + tau_relp_tmp + ) * numpy.logical_not((tau_relp_tmp < 0.001)) + k6 = kcaon * (cass * h6) + k6_i = kcaon * (cai * h6_i) + k1 = kcaon * (cao * h12) + k1_i = kcaon * (cao * h12_i) + h2 = (hna * nass) / ((h1 * kna3)) + h3 = 1.0 / h1 + h2_i = (hna * nai) / ((h1_i * kna3)) + h3_i = 1.0 / h1_i + h8 = nao / ((h7 * (hna * kna3))) + h9 = 1.0 / h7 + h8_i = nao / ((h7_i * (hna * kna3))) + h9_i = 1.0 / h7_i + # F1 = numpy.exp(C * p_b) - 1 + dCd = C - Cd + + dCaTrpn_dt = ktrpn * (-CaTrpn + ((1000 * cai) / cat50) ** ntrpn * (1 - CaTrpn)) + dCaTrpn_dt_linearized = ktrpn * (-(((1000 * cai) / cat50) ** ntrpn) - 1) + values[33] = ( + CaTrpn + + dCaTrpn_dt + * (numpy.exp(dCaTrpn_dt_linearized * dt) - 1) + / dCaTrpn_dt_linearized + * (numpy.abs(dCaTrpn_dt_linearized) > 1e-08) + + dCaTrpn_dt * dt * (~(numpy.abs(dCaTrpn_dt_linearized) > 1e-08)) + ) + # h_lambda_prima = Beta0 * ((lambda_min087 + lambda_min12) - 1.87) + 1 + diFp_dt = (-iFp + iss) / tiFp + diFp_dt_linearized = -1 / tiFp + values[34] = ( + diFp_dt * (numpy.exp(diFp_dt_linearized * dt) - 1) / diFp_dt_linearized + + iFp + ) + diSp_dt = (-iSp + iss) / tiSp + diSp_dt_linearized = -1 / tiSp + values[35] = ( + diSp_dt * (numpy.exp(diSp_dt_linearized * dt) - 1) / diSp_dt_linearized + + iSp + ) + IKr = (rkr * (xr * (GKr * (0.4303314829119352 * math.sqrt(ko))))) * (-EK + v) + ICaL = (d * (PhiCaL * (PCa * (1.0 - fICaLp)))) * ( + f * (1.0 - nca) + nca * (fca * jca) + ) + (d * (PhiCaL * (PCap * fICaLp))) * (fp * (1.0 - nca) + nca * (fcap * jca)) + INaL = (mL * (GNaL * (-ENa + v))) * (fINaLp * hLp + hL * (1.0 - fINaLp)) + INa = (m**3.0 * ((GNa * scale_drug_INa) * (-ENa + v))) * ( + j * (h * (1.0 - fINap)) + jp * (fINap * hp) + ) + Ito = ((scale_HF_Gto * (Gto * scale_drug_Ito)) * (-EK + v)) * ( + i * (a * (1.0 - fItop)) + ip * (ap * fItop) + ) + Jrel = Jrelnp * (1.0 - fJrelp) + Jrelp * fJrelp + Jup = -Jleak + (Jupnp * (1.0 - fJupp) + scale_HF_Jup * (Jupp * fJupp)) + E1 = x1 / (x4 + (x3 + (x1 + x2))) + E2 = x2 / (x4 + (x3 + (x1 + x2))) + E3 = x3 / (x4 + (x3 + (x1 + x2))) + E4 = x4 / (x4 + (x3 + (x1 + x2))) + ICaK = (d * (PhiCaK * (PCaK * (1.0 - fICaLp)))) * ( + f * (1.0 - nca) + nca * (fca * jca) + ) + (d * (PhiCaK * (PCaKp * fICaLp))) * (fp * (1.0 - nca) + nca * (fcap * jca)) + ICaNa = (d * (PhiCaNa * (PCaNa * (1.0 - fICaLp)))) * ( + f * (1.0 - nca) + nca * (fca * jca) + ) + (d * (PhiCaNa * (PCaNap * fICaLp))) * ( + fp * (1.0 - nca) + nca * (fcap * jca) + ) + k4pp = h2 * wnaca + k7 = wna * (h2 * h5) + k4p_ss = (h3 * wca) / hca + k4pp_i = h2_i * wnaca + k7_i = wna * (h2_i * h5_i) + k4p_i = (h3_i * wca) / hca + k3pp = h8 * wnaca + k8 = wna * (h11 * h8) + k3p_ss = h9 * wca + k3pp_i = h8_i * wnaca + k8_i = wna * (h11_i * h8_i) + k3p_i = h9_i * wca + eta = (etas) * (dCd < 0) + (etal) * numpy.logical_not((dCd < 0)) + J_TRPN = dCaTrpn_dt * trpnmax + # h_lambda = (h_lambda_prima) * (h_lambda_prima > 0) + (0) * numpy.logical_not( + # (h_lambda_prima > 0), + # ) + Jrel_inf = ((-ICaL) * a_rel) / ( + ((1.5 * scale_HF_Jrel_inf) / cajsr) ** 8.0 + 1.0 + ) + Jrel_infp = ((-ICaL) * a_relp) / ( + ((1.5 * scale_HF_Jrel_inf) / cajsr) ** 8.0 + 1.0 + ) + dcajsr_dt = Bcajsr * (-Jrel + Jtr) + values[36] = cajsr + dcajsr_dt * dt + dcansr_dt = Jup - (Jtr * vjsr) / vnsr + values[37] = cansr + dcansr_dt * dt + JnakNa = 3.0 * (E1 * a3 - E2 * b3) + JnakK = 2.0 * (-E3 * a1 + E4 * b1) + dkss_dt = -JdiffK + (Acap * (-ICaK)) / ((F * vss)) + values[38] = dkss_dt * dt + kss + k4 = k4p_ss + k4pp + k4_i = k4p_i + k4pp_i + k3 = k3p_ss + k3pp + k3_i = k3p_i + k3pp_i + # Fd = dCd * eta + dCd_dt = (p_k * (C - Cd)) / eta + dCd_dt_linearized = -p_k / eta + values[39] = ( + Cd + + dCd_dt + * (numpy.exp(dCd_dt_linearized * dt) - 1) + / dCd_dt_linearized + * (numpy.abs(dCd_dt_linearized) > 1e-08) + + dCd_dt * dt * (~(numpy.abs(dCd_dt_linearized) > 1e-08)) + ) + # Ta = (h_lambda * (Tref / rs)) * (XS * (Zetas + 1) + XW * Zetaw) + dJrelnp_dt = (Jrel_inf - Jrelnp) / tau_rel + dJrelnp_dt_linearized = -1 / tau_rel + values[40] = ( + Jrelnp + + dJrelnp_dt + * (numpy.exp(dJrelnp_dt_linearized * dt) - 1) + / dJrelnp_dt_linearized + ) + dJrelp_dt = (Jrel_infp - Jrelp) / tau_relp + dJrelp_dt_linearized = -1 / tau_relp + values[41] = ( + Jrelp + + dJrelp_dt + * (numpy.exp(dJrelp_dt_linearized * dt) - 1) + / dJrelp_dt_linearized + ) + INaK = (Pnak * scale_HF_Pnak) * (JnakK * zk + JnakNa * zna) + x2_ss = (k1 * k7) * (k4 + k5) + (k4 * k6) * (k1 + k8) + x2_i = (k1_i * k7_i) * (k4_i + k5_i) + (k4_i * k6_i) * (k1_i + k8_i) + x1_ss = (k2 * k4) * (k6 + k7) + (k5 * k7) * (k2 + k3) + x3_ss = (k1 * k3) * (k6 + k7) + (k6 * k8) * (k2 + k3) + x4_ss = (k2 * k8) * (k4 + k5) + (k3 * k5) * (k1 + k8) + x1_i = (k2_i * k4_i) * (k6_i + k7_i) + (k5_i * k7_i) * (k2_i + k3_i) + x3_i = (k1_i * k3_i) * (k6_i + k7_i) + (k6_i * k8_i) * (k2_i + k3_i) + x4_i = (k2_i * k8_i) * (k4_i + k5_i) + (k3_i * k5_i) * (k1_i + k8_i) + # Tp = p_a * (F1 + Fd) + dki_dt = ( + Acap * ( - -CaTrpn - + ufl.elem_pow(1000.0 * cai / cat50, ntrpn * scale_popu_nTRPN) - * (1.0 - CaTrpn) + -( + -2.0 * INaK + + ( + Istim + + ( + Isac_P_ns / 3 + + (Isac_P_k + (IKb + (IK1 + (IKs + (IKr + Ito))))) + ) + ) + ) + ) + ) / ((F * vmyo)) + (JdiffK * vss) / vmyo + values[42] = dki_dt * dt + ki + E1_ss = x1_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) + E2_ss = x2_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) + E3_ss = x3_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) + E4_ss = x4_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) + E1_i = x1_i / (x4_i + (x3_i + (x1_i + x2_i))) + E2_i = x2_i / (x4_i + (x3_i + (x1_i + x2_i))) + E3_i = x3_i / (x4_i + (x3_i + (x1_i + x2_i))) + E4_i = x4_i / (x4_i + (x3_i + (x1_i + x2_i))) + JncxCa_ss = -E1_ss * k1 + E2_ss * k2 + JncxNa_ss = -E2_ss * k3pp + (E3_ss * k4pp + 3.0 * (-E1_ss * k8 + E4_ss * k7)) + JncxCa_i = -E1_i * k1_i + E2_i * k2_i + JncxNa_i = -E2_i * k3pp_i + (E3_i * k4pp_i + 3.0 * (-E1_i * k8_i + E4_i * k7_i)) + INaCa_ss = (allo_ss * ((0.2 * Gncx) * scale_HF_Gncx)) * ( + JncxCa_ss * zca + JncxNa_ss * zna + ) + INaCa_i = (allo_i * ((0.8 * Gncx) * scale_HF_Gncx)) * ( + JncxCa_i * zca + JncxNa_i * zna + ) + dcass_dt = Bcass * ( + -Jdiff + + ( + (Acap * (-(ICaL - 2.0 * INaCa_ss))) / (((2.0 * F) * vss)) + + (Jrel * vjsr) / vss ) ) - kb = ( - ku - * scale_popu_ku - * ufl.elem_pow(Trpn50 * scale_popu_TRPN50, (ntm * scale_popu_nTm)) - / ( - 1.0 - - (rs * scale_popu_rs) - - rw * scale_popu_rw * (1.0 - (rs * scale_popu_rs)) + values[43] = cass + dcass_dt * dt + dnass_dt = -JdiffNa + (Acap * (-(ICaNa + 3.0 * INaCa_ss))) / ((F * vss)) + values[44] = dnass_dt * dt + nass + dcai_dt = Bcai * ( + -J_TRPN + + ( + ( + (Acap * (-(Isac_P_ns / 3 + (-2.0 * INaCa_i + (ICab + IpCa))))) + / (((2.0 * F) * vmyo)) + - (Jup * vnsr) / vmyo + ) + + (Jdiff * vss) / vmyo ) ) - - F_expressions[42] = ( - ufl.conditional( - ufl.lt(ufl.elem_pow(CaTrpn, -(ntm * scale_popu_nTm) / 2.0), 100.0), - ufl.elem_pow(CaTrpn, -(ntm * scale_popu_nTm) / 2.0), - 100.0, + values[45] = cai + dcai_dt * dt + dnai_dt = ( + Acap + * ( + -( + Isac_P_ns / 3 + + (INab + (3.0 * INaK + (3.0 * INaCa_i + (INa + INaL)))) + ) ) - * XU - * kb - - ku - * scale_popu_ku - * ufl.elem_pow(CaTrpn, (ntm * scale_popu_nTm) / 2.0) - * TmB - ) - - C = -1.0 + lambda_min12 - dCd = -Cd + C - eta = ufl.conditional(ufl.lt(dCd, 0.0), etas, etal) - F_expressions[43] = p_k * (-Cd + C) / eta - Bcai = 1.0 / (1.0 + cmdnmax * kmcmdn * ufl.elem_pow(kmcmdn + cai, -2.0)) - J_TRPN = trpnmax * F_expressions[41] - F_expressions[44] = ( - -J_TRPN - + Jdiff * vss / vmyo - - Jup * vnsr / vmyo - + 0.5 * (-ICab - IpCa - Isac_P_ns / 3.0 + 2.0 * INaCa_i) * Acap / (F * vmyo) - ) * Bcai - - F_expressions[45] = self.dLambda * As - Zetas * cs - F_expressions[46] = self.dLambda * Aw - Zetaw * cw - # State 46 and 47 is lambda and dLambda respectively - - # Return results - return as_vector(F_expressions) - - def num_states(self): - return 47 - - def __str__(self): - return "ORdmm_Land_em_coupling cardiac cell model" + ) / ((F * vmyo)) + (JdiffNa * vss) / vmyo + values[46] = dnai_dt * dt + nai + dv_dt = -( + Isac_P_k + + ( + Isac_P_ns + + ( + Istim + + ( + ICab + + ( + IpCa + + ( + IKb + + ( + INab + + ( + INaK + + ( + INaCa_ss + + ( + INaCa_i + + ( + IK1 + + ( + IKs + + ( + IKr + + ( + ICaK + + ( + ICaNa + + ( + ICaL + + ( + Ito + + ( + INa + + INaL + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + values[47] = dt * dv_dt + v + + return numpy.nan_to_num(values, nan=0.0) + + return forward_generalized_rush_larsen_ + + +# def Max(a, b): +# return (a + b + abs(a - b)) / Constant(2.0) + + +# def Min(a, b): +# return (a + b - abs(a - b)) / Constant(2.0) + + +# class ORdmmLandExplicit(BaseCellModel): +# def __init__( +# self, +# coupling: EMCoupling, +# params=None, +# init_conditions=None, +# ): +# """ +# Create cardiac cell model + +# *Arguments* +# params (dict, :py:class:`dolfin.Mesh`, optional) +# optional model parameters +# init_conditions (dict, :py:class:`dolfin.Mesh`, optional) +# optional initial conditions +# """ +# logger.debug("Initialize ORdmm Land model") + +# super().__init__(params, init_conditions) +# self.lmbda = coupling.lmbda_ep +# self.dLambda = coupling.dLambda_ep + +# @staticmethod +# def update_disease_parameters( +# params: Dict[str, float], +# disease_state: str = "healthy", +# ) -> None: +# if disease_state.lower() == "hf": +# logger.info("Update scaling parameters for heart failure model") +# params["HF_scaling_CaMKa"] = 1.50 +# params["HF_scaling_Jrel_inf"] = pow(0.8, 8.0) +# params["HF_scaling_Jleak"] = 1.3 +# params["HF_scaling_Jup"] = 0.45 +# params["HF_scaling_GNaL"] = 1.3 +# params["HF_scaling_GK1"] = 0.68 +# params["HF_scaling_thL"] = 1.8 +# params["HF_scaling_Gto"] = 0.4 +# params["HF_scaling_Gncx"] = 1.6 +# params["HF_scaling_Pnak"] = 0.7 +# params["HF_scaling_cat50_ref"] = 0.6 + +# @staticmethod +# def default_parameters() -> Dict[str, float]: +# """Set-up and return default parameters. + +# Parameters +# ---------- +# disease_state : str, optional +# String with "hf" or "healthy", by default "healthy". +# If "hf", then parameters representing heart failure +# will be used. + +# Returns +# ------- +# OrderedDict +# Dictionary with default values +# """ +# params = OrderedDict( +# [ +# ("scale_ICaL", 1.018), +# ("scale_IK1", 1.414), +# ("scale_IKr", 1.119), +# ("scale_IKs", 1.648), +# ("scale_INaL", 2.274), +# ("celltype", 0), +# ("cao", 1.8), +# ("ko", 5.4), +# ("nao", 140.0), +# ("F", 96485.0), +# ("R", 8314.0), +# ("T", 310.0), +# ("L", 0.01), +# ("rad", 0.0011), +# ("Ahf", 0.99), +# ("GNa", 31), +# ("thL", 200.0), +# ("Gto", 0.02), +# ("delta_epi", 1.0), +# ("Aff", 0.6), +# ("Kmn", 0.002), +# ("k2n", 1000.0), +# ("tjca", 75.0), +# ("zca", 2.0), +# ("bt", 4.75), +# ("Beta0", 2.3), +# ("Beta1", -2.4), +# ("Tot_A", 25), +# ("Tref", 120), +# ("Trpn50", 0.35), +# ("calib", 1), +# ("cat50_ref", 0.805), +# ("emcoupling", 1), +# ("etal", 200), +# ("etas", 20), +# ("gammas", 0.0085), +# ("gammaw", 0.615), +# ("isacs", 0), +# ("ktrpn", 0.1), +# ("ku", 0.04), +# ("kuw", 0.182), +# ("kws", 0.012), +# ("mode", 1), +# ("ntm", 2.4), +# ("ntrpn", 2.0), +# ("p_a", 2.1), +# ("p_b", 9.1), +# ("p_k", 7.0), +# ("phi", 2.23), +# ("rs", 0.25), +# ("rw", 0.5), +# ("CaMKo", 0.05), +# ("KmCaM", 0.0015), +# ("KmCaMK", 0.15), +# ("aCaMK", 0.05), +# ("bCaMK", 0.00068), +# ("PKNa", 0.01833), +# ("Gncx", 0.0008), +# ("KmCaAct", 0.00015), +# ("kasymm", 12.5), +# ("kcaoff", 5000.0), +# ("kcaon", 1500000.0), +# ("kna1", 15.0), +# ("kna2", 5.0), +# ("kna3", 88.12), +# ("qca", 0.167), +# ("qna", 0.5224), +# ("wca", 60000.0), +# ("wna", 60000.0), +# ("wnaca", 5000.0), +# ("H", 1e-07), +# ("Khp", 1.698e-07), +# ("Kki", 0.5), +# ("Kko", 0.3582), +# ("Kmgatp", 1.698e-07), +# ("Knai0", 9.073), +# ("Knao0", 27.78), +# ("Knap", 224.0), +# ("Kxkur", 292.0), +# ("MgADP", 0.05), +# ("MgATP", 9.8), +# ("Pnak", 30.0), +# ("delta", -0.155), +# ("eP", 4.2), +# ("k1m", 182.4), +# ("k1p", 949.5), +# ("k2m", 39.4), +# ("k2p", 687.2), +# ("k3m", 79300.0), +# ("k3p", 1899.0), +# ("k4m", 40.0), +# ("k4p", 639.0), +# ("zk", 1.0), +# ("GKb", 0.003), +# ("PNab", 3.75e-10), +# ("PCab", 2.5e-08), +# ("GpCa", 0.0005), +# ("Esac_ns", -10.0), +# ("Gsac_k", 1.097904761904762), +# ("Gsac_ns", 0.006), +# ("lambda_max", 1.1), +# ("amp", -80.0), +# ("duration", 0.5), +# ("BSLmax", 1.124), +# ("BSRmax", 0.047), +# ("KmBSL", 0.0087), +# ("KmBSR", 0.00087), +# ("cmdnmax", 0.05), +# ("csqnmax", 10.0), +# ("kmcmdn", 0.00238), +# ("kmcsqn", 0.8), +# ("kmtrpn", 0.0005), +# ("trpnmax", 0.07), +# # Drug factors +# ("scale_drug_INa", 1.0), +# ("scale_drug_INaL", 1.0), +# ("scale_drug_Ito", 1.0), +# ("scale_drug_ICaL", 1.0), +# ("scale_drug_IKr", 1.0), +# ("scale_drug_IKs", 1.0), +# ("scale_drug_IK1", 1.0), +# ("scale_drug_IKb", 1.0), +# ("scale_drug_INab", 1.0), +# ("scale_drug_ICab", 1.0), +# ("scale_drug_IpCa", 1.0), +# ("scale_drug_Isacns", 1.0), +# ("scale_drug_Isack", 1.0), +# # Population factors +# ("scale_popu_GNa", 1.0), +# ("scale_popu_GCaL", 1.0), +# ("scale_popu_Gto", 1.0), +# ("scale_popu_GNaL", 1.0), +# ("scale_popu_GKr", 1.0), +# ("scale_popu_GKs", 1.0), +# ("scale_popu_GK1", 1.0), +# ("scale_popu_GbK", 1.0), +# ("scale_popu_KNCX", 1.0), +# ("scale_popu_KNaK", 1.0), +# ("scale_popu_GbNa", 1.0), +# ("scale_popu_GbCa", 1.0), +# ("scale_popu_KpCa", 1.0), +# ("scale_popu_KRyR", 1.0), +# ("scale_popu_KSERCA", 1.0), +# ("scale_popu_Kleak", 1.0), +# ("scale_popu_nTm", 1.0), +# ("scale_popu_CaT50ref", 1.0), +# ("scale_popu_Tref", 1.0), +# ("scale_popu_kuw", 1.0), +# ("scale_popu_kws", 1.0), +# ("scale_popu_kTRPN", 1.0), +# ("scale_popu_nTRPN", 1.0), +# ("scale_popu_ku", 1.0), +# ("scale_popu_TRPN50", 1.0), +# ("scale_popu_rw", 1.0), +# ("scale_popu_rs", 1.0), +# # HF scaling factors +# ("HF_scaling_CaMKa", 1.0), +# ("HF_scaling_Jrel_inf", 1.0), +# ("HF_scaling_Jleak", 1.0), +# ("HF_scaling_Jup", 1.0), +# ("HF_scaling_GNaL", 1.0), +# ("HF_scaling_GK1", 1.0), +# ("HF_scaling_thL", 1.0), +# ("HF_scaling_Gto", 1.0), +# ("HF_scaling_Gncx", 1.0), +# ("HF_scaling_Pnak", 1.0), +# ("HF_scaling_cat50_ref", 1.0), +# ], +# ) + +# return params + +# @staticmethod +# def default_initial_conditions(): +# "Set-up and return default initial conditions." +# ic = OrderedDict( +# [ +# ("v", -87), +# ("CaMKt", 0), +# ("m", 0), +# ("hf", 1), +# ("hs", 1), +# ("j", 1), +# ("hsp", 1), +# ("jp", 1), +# ("mL", 0), +# ("hL", 1), +# ("hLp", 1), +# ("a", 0), +# ("iF", 1), +# ("iS", 1), +# ("ap", 0), +# ("iFp", 1), +# ("iSp", 1), +# ("d", 0), +# ("ff", 1), +# ("fs", 1), +# ("fcaf", 1), +# ("fcas", 1), +# ("jca", 1), +# ("ffp", 1), +# ("fcafp", 1), +# ("nca", 0), +# ("xrf", 0), +# ("xrs", 0), +# ("xs1", 0), +# ("xs2", 0), +# ("xk1", 1), +# ("Jrelnp", 0), +# ("Jrelp", 0), +# ("nai", 7), +# ("nass", 7), +# ("ki", 145), +# ("kss", 145), +# ("cass", 0.0001), +# ("cansr", 1.2), +# ("cajsr", 1.2), +# ("XS", 0), +# ("XW", 0), +# ("CaTrpn", 0), +# ("TmB", 1), +# ("Cd", 0), +# ("cai", 0.0001), +# ("Zetas", 0), +# ("Zetaw", 0), +# ], +# ) +# return ic + +# def _I(self, v, s, time): +# """ +# Original gotran transmembrane current dV/dt +# """ +# time = time if time else Constant(0.0) +# logger.debug("Evaluate transmembrane current") +# # Assign states +# assert len(s) == 47 +# ( +# CaMKt, +# m, +# hf, +# hs, +# j, +# hsp, +# jp, +# mL, +# hL, +# hLp, +# a, +# iF, +# iS, +# ap, +# iFp, +# iSp, +# d, +# ff, +# fs, +# fcaf, +# fcas, +# jca, +# ffp, +# fcafp, +# nca, +# xrf, +# xrs, +# xs1, +# xs2, +# xk1, +# Jrelnp, +# Jrelp, +# nai, +# nass, +# ki, +# kss, +# cass, +# cansr, +# cajsr, +# XS, +# XW, +# CaTrpn, +# TmB, +# Cd, +# cai, +# Zetas, +# Zetaw, +# ) = s + +# # Assign parameters +# scale_ICaL = self._parameters["scale_ICaL"] +# scale_IK1 = self._parameters["scale_IK1"] +# scale_IKr = self._parameters["scale_IKr"] +# scale_IKs = self._parameters["scale_IKs"] +# scale_INaL = self._parameters["scale_INaL"] +# cao = self._parameters["cao"] +# ko = self._parameters["ko"] +# nao = self._parameters["nao"] +# F = self._parameters["F"] +# R = self._parameters["R"] +# T = self._parameters["T"] +# CaMKo = self._parameters["CaMKo"] +# KmCaM = self._parameters["KmCaM"] +# KmCaMK = self._parameters["KmCaMK"] +# PKNa = self._parameters["PKNa"] +# Ahf = self._parameters["Ahf"] +# GNa = self._parameters["GNa"] +# Gto = self._parameters["Gto"] +# Aff = self._parameters["Aff"] +# zca = self._parameters["zca"] +# Gncx = self._parameters["Gncx"] +# KmCaAct = self._parameters["KmCaAct"] +# kasymm = self._parameters["kasymm"] +# kcaoff = self._parameters["kcaoff"] +# kcaon = self._parameters["kcaon"] +# kna1 = self._parameters["kna1"] +# kna2 = self._parameters["kna2"] +# kna3 = self._parameters["kna3"] +# qca = self._parameters["qca"] +# qna = self._parameters["qna"] +# wca = self._parameters["wca"] +# wna = self._parameters["wna"] +# wnaca = self._parameters["wnaca"] +# H = self._parameters["H"] +# Khp = self._parameters["Khp"] +# Kki = self._parameters["Kki"] +# Kko = self._parameters["Kko"] +# Kmgatp = self._parameters["Kmgatp"] +# Knai0 = self._parameters["Knai0"] +# Knao0 = self._parameters["Knao0"] +# Knap = self._parameters["Knap"] +# Kxkur = self._parameters["Kxkur"] +# MgADP = self._parameters["MgADP"] +# MgATP = self._parameters["MgATP"] +# Pnak = self._parameters["Pnak"] +# delta = self._parameters["delta"] +# eP = self._parameters["eP"] +# k1m = self._parameters["k1m"] +# k1p = self._parameters["k1p"] +# k2m = self._parameters["k2m"] +# k2p = self._parameters["k2p"] +# k3m = self._parameters["k3m"] +# k3p = self._parameters["k3p"] +# k4m = self._parameters["k4m"] +# k4p = self._parameters["k4p"] +# zk = self._parameters["zk"] +# GKb = self._parameters["GKb"] +# PNab = self._parameters["PNab"] +# PCab = self._parameters["PCab"] +# GpCa = self._parameters["GpCa"] +# # Drug factor +# scale_drug_INa = self._parameters["scale_drug_INa"] +# scale_drug_INaL = self._parameters["scale_drug_INaL"] +# scale_drug_Ito = self._parameters["scale_drug_Ito"] +# scale_drug_ICaL = self._parameters["scale_drug_ICaL"] +# scale_drug_IKr = self._parameters["scale_drug_IKr"] +# scale_drug_IKs = self._parameters["scale_drug_IKs"] +# scale_drug_IK1 = self._parameters["scale_drug_IK1"] +# scale_drug_IKb = self._parameters["scale_drug_IKb"] +# scale_drug_INab = self._parameters["scale_drug_INab"] +# scale_drug_ICab = self._parameters["scale_drug_ICab"] +# scale_drug_IpCa = self._parameters["scale_drug_IpCa"] +# scale_drug_Isacns = self._parameters["scale_drug_Isacns"] +# scale_drug_Isack = self._parameters["scale_drug_Isack"] +# # Population factors +# scale_popu_GNa = self._parameters["scale_popu_GNa"] +# scale_popu_GCaL = self._parameters["scale_popu_GCaL"] +# scale_popu_Gto = self._parameters["scale_popu_Gto"] +# scale_popu_GNaL = self._parameters["scale_popu_GNaL"] +# scale_popu_GKr = self._parameters["scale_popu_GKr"] +# scale_popu_GKs = self._parameters["scale_popu_GKs"] +# scale_popu_GK1 = self._parameters["scale_popu_GK1"] +# scale_popu_GbK = self._parameters["scale_popu_GbK"] +# scale_popu_KNCX = self._parameters["scale_popu_KNCX"] +# scale_popu_KNaK = self._parameters["scale_popu_KNaK"] +# scale_popu_GbNa = self._parameters["scale_popu_GbNa"] +# scale_popu_GbCa = self._parameters["scale_popu_GbCa"] +# scale_popu_KpCa = self._parameters["scale_popu_KpCa"] +# # Systolic Heart Failure (HF with preserved ejection fraction) +# HF_scaling_CaMKa = self._parameters["HF_scaling_CaMKa"] +# HF_scaling_GNaL = self._parameters["HF_scaling_GNaL"] +# HF_scaling_GK1 = self._parameters["HF_scaling_GK1"] +# HF_scaling_Gto = self._parameters["HF_scaling_Gto"] +# HF_scaling_Gncx = self._parameters["HF_scaling_Gncx"] +# HF_scaling_Pnak = self._parameters["HF_scaling_Pnak"] + +# # Init return args +# current = [ufl.zero()] * 1 + +# # Expressions for the CaMKt component +# CaMKb = CaMKo * (1.0 - CaMKt) / (1.0 + KmCaM / cass) +# CaMKa = (CaMKb + CaMKt) * HF_scaling_CaMKa + +# # Expressions for the reversal potentials component +# ENa = R * T * ufl.ln(nao / nai) / F +# EK = R * T * ufl.ln(ko / ki) / F +# EKs = R * T * ufl.ln((ko + PKNa * nao) / (PKNa * nai + ki)) / F +# vffrt = (F * F) * v / (R * T) +# vfrt = F * v / (R * T) + +# # Expressions for the I_Na component +# Ahs = 1.0 - Ahf +# h = Ahf * hf + Ahs * hs +# hp = Ahf * hf + Ahs * hsp +# fINap = 1.0 / (1.0 + KmCaMK / CaMKa) +# INa = ( +# GNa +# * scale_drug_INa +# * scale_popu_GNa +# * ufl.elem_pow(m, 3.0) +# * (-ENa + v) +# * ((1.0 - fINap) * h * j + fINap * hp * jp) +# ) + +# # Expressions for the INaL component +# GNaL = 0.0075 * scale_INaL * scale_drug_INaL * scale_popu_GNaL * HF_scaling_GNaL +# fINaLp = 1.0 / (1.0 + KmCaMK / CaMKa) +# INaL = (-ENa + v) * ((1.0 - fINaLp) * hL + fINaLp * hLp) * GNaL * mL + +# # Expressions for the Ito component +# AiF = 1.0 / (1.0 + 0.24348537187522867 * ufl.exp(0.006613756613756614 * v)) +# AiS = 1.0 - AiF +# i = AiF * iF + AiS * iS +# ip = AiF * iFp + AiS * iSp +# fItop = 1.0 / (1.0 + KmCaMK / CaMKa) +# Ito = ( +# Gto +# * scale_drug_Ito +# * scale_popu_Gto +# * HF_scaling_Gto +# * (-EK + v) +# * ((1.0 - fItop) * a * i + ap * fItop * ip) +# ) + +# # Expressions for the ICaL ICaNa ICaK component +# Afs = 1.0 - Aff +# f = Aff * ff + Afs * fs +# Afcaf = 0.3 + 0.6 / (1.0 + 0.36787944117144233 * ufl.exp(0.1 * v)) +# Afcas = 1.0 - Afcaf +# fca = Afcaf * fcaf + Afcas * fcas +# fp = Aff * ffp + Afs * fs +# fcap = Afcaf * fcafp + Afcas * fcas +# PhiCaL = ( +# 4.0 +# * (-0.341 * cao + cass * ufl.exp(2.0 * vfrt)) +# * vffrt +# / (-1.0 + ufl.exp(2.0 * vfrt)) +# ) +# PhiCaNa = ( +# 1.0 +# * (-0.75 * nao + 0.75 * ufl.exp(1.0 * vfrt) * nass) +# * vffrt +# / (-1.0 + ufl.exp(1.0 * vfrt)) +# ) +# PhiCaK = ( +# 1.0 +# * (-0.75 * ko + 0.75 * ufl.exp(1.0 * vfrt) * kss) +# * vffrt +# / (-1.0 + ufl.exp(1.0 * vfrt)) +# ) +# PCa = 0.0001 * scale_ICaL * scale_drug_ICaL * scale_popu_GCaL +# PCap = 1.1 * PCa +# PCaNa = 0.00125 * PCa +# PCaK = 0.0003574 * PCa +# PCaNap = 0.00125 * PCap +# PCaKp = 0.0003574 * PCap +# fICaLp = 1.0 / (1.0 + KmCaMK / CaMKa) +# ICaL = (1.0 - fICaLp) * ( +# (1.0 - nca) * f + fca * jca * nca +# ) * PCa * PhiCaL * d + ( +# (1.0 - nca) * fp + fcap * jca * nca +# ) * PCap * PhiCaL * d * fICaLp +# ICaNa = (1.0 - fICaLp) * ( +# (1.0 - nca) * f + fca * jca * nca +# ) * PCaNa * PhiCaNa * d + ( +# (1.0 - nca) * fp + fcap * jca * nca +# ) * PCaNap * PhiCaNa * d * fICaLp +# ICaK = (1.0 - fICaLp) * ( +# (1.0 - nca) * f + fca * jca * nca +# ) * PCaK * PhiCaK * d + ( +# (1.0 - nca) * fp + fcap * jca * nca +# ) * PCaKp * PhiCaK * d * fICaLp + +# # Expressions for the IKr component +# Axrf = 1.0 / (1.0 + 4.197299094734718 * ufl.exp(0.02617115938236064 * v)) +# Axrs = 1.0 - Axrf +# xr = Axrf * xrf + Axrs * xrs +# rkr = 1.0 / ( +# (1.0 + 2.0820090840784555 * ufl.exp(0.013333333333333334 * v)) +# * (1.0 + 0.7165313105737893 * ufl.exp(0.03333333333333333 * v)) +# ) +# GKr = 0.046 * scale_IKr * scale_drug_IKr * scale_popu_GKr +# IKr = 0.4303314829119352 * ufl.sqrt(ko) * (-EK + v) * GKr * rkr * xr + +# # Expressions for the IKs component +# KsCa = 1.0 + 0.6 / (1.0 + 6.481821026062645e-07 * ufl.elem_pow(1.0 / cai, 1.4)) +# GKs = 0.0034 * scale_IKs * scale_drug_IKs * scale_popu_GKs +# IKs = (-EKs + v) * GKs * KsCa * xs1 * xs2 +# rk1 = 1.0 / ( +# 1.0 +# + 69220.6322106767 +# * ufl.exp(0.10534077741493732 * v - 0.27388602127883704 * ko) +# ) +# GK1 = 0.1908 * scale_IK1 * scale_drug_IK1 * scale_popu_GK1 * HF_scaling_GK1 +# IK1 = ufl.sqrt(ko) * (-EK + v) * GK1 * rk1 * xk1 + +# # Expressions for the INaCa_i component +# hca = ufl.exp(F * qca * v / (R * T)) +# hna = ufl.exp(F * qna * v / (R * T)) +# h1_i = 1 + (1 + hna) * nai / kna3 +# h2_i = hna * nai / (kna3 * h1_i) +# h3_i = 1.0 / h1_i +# h4_i = 1.0 + (1 + nai / kna2) * nai / kna1 +# h5_i = (nai * nai) / (kna1 * kna2 * h4_i) +# h6_i = 1.0 / h4_i +# h7_i = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 +# h8_i = nao / (kna3 * h7_i * hna) +# h9_i = 1.0 / h7_i +# h10_i = 1.0 + kasymm + nao * (1.0 + nao / kna2) / kna1 +# h11_i = (nao * nao) / (kna1 * kna2 * h10_i) +# h12_i = 1.0 / h10_i +# k1_i = cao * kcaon * h12_i +# k2_i = kcaoff +# k3p_i = wca * h9_i +# k3pp_i = wnaca * h8_i +# k3_i = k3p_i + k3pp_i +# k4p_i = wca * h3_i / hca +# k4pp_i = wnaca * h2_i +# k4_i = k4p_i + k4pp_i +# k5_i = kcaoff +# k6_i = kcaon * cai * h6_i +# k7_i = wna * h2_i * h5_i +# k8_i = wna * h11_i * h8_i +# x1_i = (k2_i + k3_i) * k5_i * k7_i + (k6_i + k7_i) * k2_i * k4_i +# x2_i = (k1_i + k8_i) * k4_i * k6_i + (k4_i + k5_i) * k1_i * k7_i +# x3_i = (k2_i + k3_i) * k6_i * k8_i + (k6_i + k7_i) * k1_i * k3_i +# x4_i = (k1_i + k8_i) * k3_i * k5_i + (k4_i + k5_i) * k2_i * k8_i +# E1_i = x1_i / (x1_i + x2_i + x3_i + x4_i) +# E2_i = x2_i / (x1_i + x2_i + x3_i + x4_i) +# E3_i = x3_i / (x1_i + x2_i + x3_i + x4_i) +# E4_i = x4_i / (x1_i + x2_i + x3_i + x4_i) +# allo_i = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cai, 2.0)) +# zna = 1.0 +# JncxNa_i = E3_i * k4pp_i - E2_i * k3pp_i + 3.0 * E4_i * k7_i - 3.0 * E1_i * k8_i +# JncxCa_i = E2_i * k2_i - E1_i * k1_i +# INaCa_i = ( +# 0.8 +# * Gncx +# * scale_popu_KNCX +# * HF_scaling_Gncx +# * (zca * JncxCa_i + zna * JncxNa_i) +# * allo_i +# ) + +# # Expressions for the INaCa_ss component +# h1 = 1.0 + (1.0 + hna) * nass / kna3 +# h2 = hna * nass / (kna3 * h1) +# h3 = 1.0 / h1 +# h4 = 1.0 + (1 + nass / kna2) * nass / kna1 +# h5 = (nass * nass) / (kna1 * kna2 * h4) +# h6 = 1.0 / h4 +# h7 = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 +# h8 = nao / (kna3 * h7 * hna) +# h9 = 1.0 / h7 +# h10 = 1.0 + kasymm + nao * (1 + nao / kna2) / kna1 +# h11 = (nao * nao) / (kna1 * kna2 * h10) +# h12 = 1.0 / h10 +# k1 = cao * kcaon * h12 +# k2 = kcaoff +# k3p_ss = wca * h9 +# k3pp = wnaca * h8 +# k3 = k3p_ss + k3pp +# k4p_ss = wca * h3 / hca +# k4pp = wnaca * h2 +# k4 = k4p_ss + k4pp +# k5 = kcaoff +# k6 = kcaon * cass * h6 +# k7 = wna * h2 * h5 +# k8 = wna * h11 * h8 +# x1_ss = (k2 + k3) * k5 * k7 + (k6 + k7) * k2 * k4 +# x2_ss = (k1 + k8) * k4 * k6 + (k4 + k5) * k1 * k7 +# x3_ss = (k2 + k3) * k6 * k8 + (k6 + k7) * k1 * k3 +# x4_ss = (k1 + k8) * k3 * k5 + (k4 + k5) * k2 * k8 +# E1_ss = x1_ss / (x1_ss + x2_ss + x3_ss + x4_ss) +# E2_ss = x2_ss / (x1_ss + x2_ss + x3_ss + x4_ss) +# E3_ss = x3_ss / (x1_ss + x2_ss + x3_ss + x4_ss) +# E4_ss = x4_ss / (x1_ss + x2_ss + x3_ss + x4_ss) +# allo_ss = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cass, 2.0)) +# JncxNa_ss = E3_ss * k4pp - E2_ss * k3pp + 3.0 * E4_ss * k7 - 3.0 * E1_ss * k8 +# JncxCa_ss = E2_ss * k2 - E1_ss * k1 +# INaCa_ss = ( +# 0.2 +# * Gncx +# * scale_popu_KNCX +# * HF_scaling_Gncx +# * (zca * JncxCa_ss + zna * JncxNa_ss) +# * allo_ss +# ) + +# # Expressions for the INaK component +# Knai = Knai0 * ufl.exp(0.3333333333333333 * F * delta * v / (R * T)) +# Knao = Knao0 * ufl.exp(0.3333333333333333 * F * (1.0 - delta) * v / (R * T)) +# P = eP / (1.0 + H / Khp + nai / Knap + ki / Kxkur) +# a1 = ( +# k1p +# * ufl.elem_pow(nai / Knai, 3.0) +# / ( +# -1.0 +# + ufl.elem_pow(1.0 + ki / Kki, 2.0) +# + ufl.elem_pow(1.0 + nai / Knai, 3.0) +# ) +# ) +# b1 = MgADP * k1m +# a2 = k2p +# b2 = ( +# k2m +# * ufl.elem_pow(nao / Knao, 3.0) +# / ( +# -1.0 +# + ufl.elem_pow(1.0 + ko / Kko, 2.0) +# + ufl.elem_pow(1.0 + nao / Knao, 3.0) +# ) +# ) +# a3 = ( +# k3p +# * ufl.elem_pow(ko / Kko, 2.0) +# / ( +# -1.0 +# + ufl.elem_pow(1.0 + ko / Kko, 2.0) +# + ufl.elem_pow(1.0 + nao / Knao, 3.0) +# ) +# ) +# b3 = H * k3m * P / (1.0 + MgATP / Kmgatp) +# a4 = MgATP * k4p / (Kmgatp * (1.0 + MgATP / Kmgatp)) +# b4 = ( +# k4m +# * ufl.elem_pow(ki / Kki, 2.0) +# / ( +# -1.0 +# + ufl.elem_pow(1.0 + ki / Kki, 2.0) +# + ufl.elem_pow(1.0 + nai / Knai, 3.0) +# ) +# ) +# x1 = a1 * a2 * a4 + a1 * a2 * b3 + a2 * b3 * b4 + b2 * b3 * b4 +# x2 = a1 * a2 * a3 + a2 * a3 * b4 + a3 * b1 * b4 + b1 * b2 * b4 +# x3 = a2 * a3 * a4 + a3 * a4 * b1 + a4 * b1 * b2 + b1 * b2 * b3 +# x4 = a1 * a3 * a4 + a1 * a4 * b2 + a1 * b2 * b3 + b2 * b3 * b4 +# E1 = x1 / (x1 + x2 + x3 + x4) +# E2 = x2 / (x1 + x2 + x3 + x4) +# E3 = x3 / (x1 + x2 + x3 + x4) +# E4 = x4 / (x1 + x2 + x3 + x4) +# JnakNa = 3.0 * E1 * a3 - 3.0 * E2 * b3 +# JnakK = 2.0 * E4 * b1 - 2.0 * E3 * a1 +# INaK = Pnak * scale_popu_KNaK * HF_scaling_Pnak * (zk * JnakK + zna * JnakNa) + +# # Expressions for the IKb component +# xkb = 1.0 / (1.0 + 2.202363450949239 * ufl.exp(-0.05452562704471101 * v)) +# IKb = GKb * scale_popu_GbK * scale_drug_IKb * (-EK + v) * xkb + +# # Expressions for the INab component +# INab = ( +# PNab +# * scale_drug_INab +# * scale_popu_GbNa +# * (-nao + ufl.exp(vfrt) * nai) +# * vffrt +# / (-1.0 + ufl.exp(vfrt)) +# ) + +# # Expressions for the ICab component +# ICab = ( +# 4.0 +# * PCab +# * scale_drug_ICab +# * scale_popu_GbCa +# * (-0.341 * cao + cai * ufl.exp(2.0 * vfrt)) +# * vffrt +# / (-1.0 + ufl.exp(2.0 * vfrt)) +# ) + +# # Expressions for the IpCa component +# IpCa = GpCa * scale_drug_IpCa * scale_popu_KpCa * cai / (0.0005 + cai) + +# # Expressions for the Isac (Pueyo)--> ns + k component +# Gsac_ns = 0.006 * scale_drug_Isacns +# Esac_ns = -10.0 +# lambda_max = 1.1 +# Gsac_k = (0.2882 * 800.0 / 210.0) * scale_drug_Isack # Pueyo endo + +# Isac_P_ns = ufl.conditional( +# ufl.lt(self.lmbda, 1.0), +# 0.0, +# Gsac_ns * ((self.lmbda - 1.0) / (lambda_max - 1.0)) * (v - Esac_ns), +# ) +# Isac_P_k = ufl.conditional( +# ufl.lt(self.lmbda, 1.0), +# 0.0, +# Gsac_k +# * ((self.lmbda - 1.0) / (lambda_max - 1.0)) +# * (1.0 / (1.0 + ufl.exp((19.05 - v) / (29.98)))), +# ) + +# # Expressions for the Istim component +# Istim = 0 #0 # amp*(ufl.le(time, duration)) + +# # Expressions for the membrane potential component +# current[0] = ( +# -Isac_P_k +# - Isac_P_ns +# - ICaK +# - ICaL +# - ICaNa +# - ICab +# - IK1 +# - IKb +# - IKr +# - IKs +# - INa +# - INaCa_i +# - INaCa_ss +# - INaK +# - INaL +# - INab +# - IpCa +# - Istim +# - Ito +# ) + +# # Return results +# return current[0] + +# def I(self, v, s, time=None): # noqa: E741, E743 +# """ +# Transmembrane current + +# I = -dV/dt + +# """ +# return -self._I(v, s, time) + +# def F(self, v, s, time=None): +# """ +# Right hand side for ODE system +# """ +# logger.debug("Evaluate RHS") +# time = time if time else Constant(0.0) + +# # Assign states +# assert len(s) == 47 +# ( +# CaMKt, +# m, +# hf, +# hs, +# j, +# hsp, +# jp, +# mL, +# hL, +# hLp, +# a, +# iF, +# iS, +# ap, +# iFp, +# iSp, +# d, +# ff, +# fs, +# fcaf, +# fcas, +# jca, +# ffp, +# fcafp, +# nca, +# xrf, +# xrs, +# xs1, +# xs2, +# xk1, +# Jrelnp, +# Jrelp, +# nai, +# nass, +# ki, +# kss, +# cass, +# cansr, +# cajsr, +# XS, +# XW, +# CaTrpn, +# TmB, +# Cd, +# cai, +# Zetas, +# Zetaw, +# ) = s + +# # Assign parameters +# scale_ICaL = self._parameters["scale_ICaL"] +# scale_IK1 = self._parameters["scale_IK1"] +# scale_IKr = self._parameters["scale_IKr"] +# scale_IKs = self._parameters["scale_IKs"] +# scale_INaL = self._parameters["scale_INaL"] +# cao = self._parameters["cao"] +# ko = self._parameters["ko"] +# nao = self._parameters["nao"] +# F = self._parameters["F"] +# R = self._parameters["R"] +# T = self._parameters["T"] +# L = self._parameters["L"] +# rad = self._parameters["rad"] +# CaMKo = self._parameters["CaMKo"] +# KmCaM = self._parameters["KmCaM"] +# KmCaMK = self._parameters["KmCaMK"] +# aCaMK = self._parameters["aCaMK"] +# bCaMK = self._parameters["bCaMK"] +# PKNa = self._parameters["PKNa"] +# Ahf = self._parameters["Ahf"] +# GNa = self._parameters["GNa"] +# thL = self._parameters["thL"] +# Gto = self._parameters["Gto"] +# delta_epi = self._parameters["delta_epi"] +# Aff = self._parameters["Aff"] +# Kmn = self._parameters["Kmn"] +# k2n = self._parameters["k2n"] +# tjca = self._parameters["tjca"] +# zca = self._parameters["zca"] +# Gncx = self._parameters["Gncx"] +# KmCaAct = self._parameters["KmCaAct"] +# kasymm = self._parameters["kasymm"] +# kcaoff = self._parameters["kcaoff"] +# kcaon = self._parameters["kcaon"] +# kna1 = self._parameters["kna1"] +# kna2 = self._parameters["kna2"] +# kna3 = self._parameters["kna3"] +# qca = self._parameters["qca"] +# qna = self._parameters["qna"] +# wca = self._parameters["wca"] +# wna = self._parameters["wna"] +# wnaca = self._parameters["wnaca"] +# H = self._parameters["H"] +# Khp = self._parameters["Khp"] +# Kki = self._parameters["Kki"] +# Kko = self._parameters["Kko"] +# Kmgatp = self._parameters["Kmgatp"] +# Knai0 = self._parameters["Knai0"] +# Knao0 = self._parameters["Knao0"] +# Knap = self._parameters["Knap"] +# Kxkur = self._parameters["Kxkur"] +# MgADP = self._parameters["MgADP"] +# MgATP = self._parameters["MgATP"] +# Pnak = self._parameters["Pnak"] +# delta = self._parameters["delta"] +# eP = self._parameters["eP"] +# k1m = self._parameters["k1m"] +# k1p = self._parameters["k1p"] +# k2m = self._parameters["k2m"] +# k2p = self._parameters["k2p"] +# k3m = self._parameters["k3m"] +# k3p = self._parameters["k3p"] +# k4m = self._parameters["k4m"] +# k4p = self._parameters["k4p"] +# zk = self._parameters["zk"] +# GKb = self._parameters["GKb"] +# PNab = self._parameters["PNab"] +# PCab = self._parameters["PCab"] +# GpCa = self._parameters["GpCa"] +# bt = self._parameters["bt"] +# BSLmax = self._parameters["BSLmax"] +# BSRmax = self._parameters["BSRmax"] +# KmBSL = self._parameters["KmBSL"] +# KmBSR = self._parameters["KmBSR"] +# cmdnmax = self._parameters["cmdnmax"] +# csqnmax = self._parameters["csqnmax"] +# kmcmdn = self._parameters["kmcmdn"] +# kmcsqn = self._parameters["kmcsqn"] +# trpnmax = self._parameters["trpnmax"] +# Beta1 = self._parameters["Beta1"] +# Tot_A = self._parameters["Tot_A"] +# Trpn50 = self._parameters["Trpn50"] +# cat50_ref = self._parameters["cat50_ref"] +# # dLambda = self._parameters["dLambda"] +# etal = self._parameters["etal"] +# etas = self._parameters["etas"] +# gammas = self._parameters["gammas"] +# gammaw = self._parameters["gammaw"] +# ktrpn = self._parameters["ktrpn"] +# ku = self._parameters["ku"] +# kuw = self._parameters["kuw"] +# kws = self._parameters["kws"] +# # lmbda = self._parameters["lmbda"] +# ntm = self._parameters["ntm"] +# ntrpn = self._parameters["ntrpn"] +# p_k = self._parameters["p_k"] +# phi = self._parameters["phi"] +# rs = self._parameters["rs"] +# rw = self._parameters["rw"] + +# # Drug factor +# scale_drug_INa = self._parameters["scale_drug_INa"] +# scale_drug_INaL = self._parameters["scale_drug_INaL"] +# scale_drug_Ito = self._parameters["scale_drug_Ito"] +# scale_drug_ICaL = self._parameters["scale_drug_ICaL"] +# scale_drug_IKr = self._parameters["scale_drug_IKr"] +# scale_drug_IKs = self._parameters["scale_drug_IKs"] +# scale_drug_IK1 = self._parameters["scale_drug_IK1"] +# scale_drug_IKb = self._parameters["scale_drug_IKb"] +# scale_drug_INab = self._parameters["scale_drug_INab"] +# scale_drug_ICab = self._parameters["scale_drug_ICab"] +# scale_drug_IpCa = self._parameters["scale_drug_IpCa"] +# scale_drug_Isacns = self._parameters["scale_drug_Isacns"] +# scale_drug_Isack = self._parameters["scale_drug_Isack"] + +# # Population factors +# scale_popu_GNa = self._parameters["scale_popu_GNa"] +# scale_popu_GCaL = self._parameters["scale_popu_GCaL"] +# scale_popu_Gto = self._parameters["scale_popu_Gto"] +# scale_popu_GNaL = self._parameters["scale_popu_GNaL"] +# scale_popu_GKr = self._parameters["scale_popu_GKr"] +# scale_popu_GKs = self._parameters["scale_popu_GKs"] +# scale_popu_GK1 = self._parameters["scale_popu_GK1"] +# scale_popu_GbK = self._parameters["scale_popu_GbK"] +# scale_popu_KNCX = self._parameters["scale_popu_KNCX"] +# scale_popu_KNaK = self._parameters["scale_popu_KNaK"] +# scale_popu_GbNa = self._parameters["scale_popu_GbNa"] +# scale_popu_GbCa = self._parameters["scale_popu_GbCa"] +# scale_popu_KpCa = self._parameters["scale_popu_KpCa"] +# scale_popu_KRyR = self._parameters["scale_popu_KRyR"] +# scale_popu_KSERCA = self._parameters["scale_popu_KSERCA"] +# scale_popu_Kleak = self._parameters["scale_popu_Kleak"] +# scale_popu_nTm = self._parameters["scale_popu_nTm"] +# scale_popu_CaT50ref = self._parameters["scale_popu_CaT50ref"] +# scale_popu_kuw = self._parameters["scale_popu_kuw"] +# scale_popu_kws = self._parameters["scale_popu_kws"] +# scale_popu_kTRPN = self._parameters["scale_popu_kTRPN"] +# scale_popu_nTRPN = self._parameters["scale_popu_nTRPN"] +# scale_popu_ku = self._parameters["scale_popu_ku"] +# scale_popu_TRPN50 = self._parameters["scale_popu_TRPN50"] +# scale_popu_rw = self._parameters["scale_popu_rw"] +# scale_popu_rs = self._parameters["scale_popu_rs"] + +# # Systolic Heart Failure (HF with preserved ejection fraction) +# HF_scaling_CaMKa = self._parameters["HF_scaling_CaMKa"] +# HF_scaling_Jrel_inf = self._parameters["HF_scaling_Jrel_inf"] +# HF_scaling_Jleak = self._parameters["HF_scaling_Jleak"] +# HF_scaling_Jup = self._parameters["HF_scaling_Jup"] +# HF_scaling_GNaL = self._parameters["HF_scaling_GNaL"] +# HF_scaling_GK1 = self._parameters["HF_scaling_GK1"] +# HF_scaling_thL = self._parameters["HF_scaling_thL"] +# HF_scaling_Gto = self._parameters["HF_scaling_Gto"] +# HF_scaling_Gncx = self._parameters["HF_scaling_Gncx"] +# HF_scaling_Pnak = self._parameters["HF_scaling_Pnak"] +# HF_scaling_cat50_ref = self._parameters["HF_scaling_cat50_ref"] + +# # Init return args +# F_expressions = [dolfin.Constant(0.0)] * 47 + +# # Expressions for the cell geometry component +# vcell = 3140.0 * L * (rad * rad) +# Ageo = 6.28 * (rad * rad) + 6.28 * L * rad +# Acap = 2 * Ageo +# vmyo = 0.68 * vcell +# vnsr = 0.0552 * vcell +# vjsr = 0.0048 * vcell +# vss = 0.02 * vcell + +# # Expressions for the CaMKt component +# CaMKb = CaMKo * (1.0 - CaMKt) / (1.0 + KmCaM / cass) +# CaMKa = (CaMKb + CaMKt) * HF_scaling_CaMKa +# F_expressions[0] = -bCaMK * CaMKt + aCaMK * (CaMKb + CaMKt) * CaMKb + +# # Expressions for the reversal potentials component +# ENa = R * T * ufl.ln(nao / nai) / F +# EK = R * T * ufl.ln(ko / ki) / F +# EKs = R * T * ufl.ln((ko + PKNa * nao) / (PKNa * nai + ki)) / F +# vffrt = (F * F) * v / (R * T) +# vfrt = F * v / (R * T) + +# # Expressions for the I_Na component +# mss = 1.0 / (1.0 + 0.0014599788446489682 * ufl.exp(-0.13333333333333333 * v)) +# tm = 1.0 / ( +# 9.454904638564724 * ufl.exp(0.02876042565429968 * v) +# + 1.9314113558536928e-05 * ufl.exp(-0.16792611251049538 * v) +# ) +# F_expressions[1] = (-m + mss) / tm +# hss = 1.0 / (1 + 302724.605401998 * ufl.exp(0.1607717041800643 * v)) +# thf = 1.0 / ( +# 1.183856958289087e-05 * ufl.exp(-0.15910898965791567 * v) +# + 6.305549185817275 * ufl.exp(0.0493339911198816 * v) +# ) +# ths = 1.0 / ( +# 0.005164670235381792 * ufl.exp(-0.035650623885918005 * v) +# + 0.36987619372096325 * ufl.exp(0.017649135192375574 * v) +# ) +# Ahs = 1.0 - Ahf +# F_expressions[2] = (-hf + hss) / thf +# F_expressions[3] = (-hs + hss) / ths +# h = Ahf * hf + Ahs * hs +# jss = hss +# tj = 2.038 + 1.0 / ( +# 0.3131936394738773 * ufl.exp(0.02600780234070221 * v) +# + 1.1315282095590072e-07 * ufl.exp(-0.12075836251660427 * v) +# ) +# F_expressions[4] = (-j + jss) / tj +# hssp = 1.0 / (1 + 820249.0921708513 * ufl.exp(0.1607717041800643 * v)) +# thsp = 3.0 * ths +# F_expressions[5] = (-hsp + hssp) / thsp +# hp = Ahf * hf + Ahs * hsp +# tjp = 1.46 * tj +# F_expressions[6] = (-jp + jss) / tjp +# fINap = 1.0 / (1.0 + KmCaMK / CaMKa) +# INa = ( +# GNa +# * scale_drug_INa +# * scale_popu_GNa +# * ufl.elem_pow(m, 3.0) +# * (-ENa + v) +# * ((1.0 - fINap) * h * j + fINap * hp * jp) +# ) + +# # Expressions for the INaL component +# mLss = 1.0 / (1.0 + 0.000291579585635531 * ufl.exp(-0.18996960486322187 * v)) +# tmL = tm +# F_expressions[7] = (-mL + mLss) / tmL +# hLss = 1.0 / (1.0 + 120578.15595522427 * ufl.exp(0.13354700854700854 * v)) +# F_expressions[8] = (-hL + hLss) / (thL * HF_scaling_thL) +# hLssp = 1.0 / (1.0 + 275969.2903869871 * ufl.exp(0.13354700854700854 * v)) +# thLp = 3.0 * thL * HF_scaling_thL +# F_expressions[9] = (-hLp + hLssp) / thLp +# GNaL = 0.0075 * scale_INaL * scale_drug_INaL * scale_popu_GNaL * HF_scaling_GNaL +# fINaLp = 1.0 / (1.0 + KmCaMK / CaMKa) +# INaL = (-ENa + v) * ((1.0 - fINaLp) * hL + fINaLp * hLp) * GNaL * mL + +# # Expressions for the Ito component +# ass = 1.0 / (1.0 + 2.6316508161673635 * ufl.exp(-0.06747638326585695 * v)) +# ta = 1.0515 / ( +# 1.0 / (1.2089 + 2.2621017070578837 * ufl.exp(-0.03403513787634354 * v)) +# + 3.5 / (1.0 + 30.069572727397507 * ufl.exp(0.03403513787634354 * v)) +# ) +# F_expressions[10] = (-a + ass) / ta +# iss = 1.0 / (1.0 + 2194.970764538301 * ufl.exp(0.17510068289266328 * v)) +# tiF = 4.562 + delta_epi / ( +# 0.14468698421272827 * ufl.exp(-0.01 * v) +# + 1.6300896349780942 * ufl.exp(0.06027727546714889 * v) +# ) +# tiS = 23.62 + delta_epi / ( +# 0.00027617763953377436 * ufl.exp(-0.01693480101608806 * v) +# + 0.024208962804604526 * ufl.exp(0.12377769525931426 * v) +# ) +# AiF = 1.0 / (1.0 + 0.24348537187522867 * ufl.exp(0.006613756613756614 * v)) +# AiS = 1.0 - AiF +# F_expressions[11] = (-iF + iss) / tiF +# F_expressions[12] = (-iS + iss) / tiS +# i = AiF * iF + AiS * iS +# assp = 1.0 / (1.0 + 5.167428462230666 * ufl.exp(-0.06747638326585695 * v)) +# F_expressions[13] = (-ap + assp) / ta +# dti_develop = 1.354 + 0.0001 / ( +# 2.6591269045230603e-05 * ufl.exp(0.06293266205160478 * v) +# + 4.5541779737128264e24 * ufl.exp(-4.642525533890436 * v) +# ) +# dti_recover = 1.0 - 0.5 / (1.0 + 33.11545195869231 * ufl.exp(0.05 * v)) +# tiFp = dti_develop * dti_recover * tiF +# tiSp = dti_develop * dti_recover * tiS +# F_expressions[14] = (-iFp + iss) / tiFp +# F_expressions[15] = (-iSp + iss) / tiSp +# ip = AiF * iFp + AiS * iSp +# fItop = 1.0 / (1.0 + KmCaMK / CaMKa) +# Ito = ( +# Gto +# * scale_drug_Ito +# * scale_popu_Gto +# * HF_scaling_Gto +# * (-EK + v) +# * ((1.0 - fItop) * a * i + ap * fItop * ip) +# ) + +# # Expressions for the ICaL ICaNa ICaK component +# dss = 1.0 / (1.0 + 0.39398514226669484 * ufl.exp(-0.23640661938534277 * v)) +# td = 0.6 + 1.0 / ( +# 3.5254214873653824 * ufl.exp(0.09 * v) +# + 0.7408182206817179 * ufl.exp(-0.05 * v) +# ) +# F_expressions[16] = (-d + dss) / td +# fss = 1.0 / (1.0 + 199.86038496778565 * ufl.exp(0.27056277056277056 * v)) +# tff = 7.0 + 1.0 / ( +# 0.03325075244518792 * ufl.exp(0.1 * v) +# + 0.0006090087745647571 * ufl.exp(-0.1 * v) +# ) +# tfs = 1000.0 + 1.0 / ( +# 1.0027667890106652e-05 * ufl.exp(-0.25 * v) +# + 8.053415618124885e-05 * ufl.exp(0.16666666666666666 * v) +# ) +# Afs = 1.0 - Aff +# F_expressions[17] = (-ff + fss) / tff +# F_expressions[18] = (-fs + fss) / tfs +# f = Aff * ff + Afs * fs +# fcass = fss +# tfcaf = 7.0 + 1.0 / ( +# 0.0708317980974062 * ufl.exp(-0.14285714285714285 * v) +# + 0.02258872488031037 * ufl.exp(0.14285714285714285 * v) +# ) +# tfcas = 100.0 + 1.0 / ( +# 0.00012 * ufl.exp(0.14285714285714285 * v) +# + 0.00012 * ufl.exp(-0.3333333333333333 * v) +# ) +# Afcaf = 0.3 + 0.6 / (1.0 + 0.36787944117144233 * ufl.exp(0.1 * v)) +# Afcas = 1.0 - Afcaf +# F_expressions[19] = (-fcaf + fcass) / tfcaf +# F_expressions[20] = (-fcas + fcass) / tfcas +# fca = Afcaf * fcaf + Afcas * fcas +# F_expressions[21] = (-jca + fcass) / tjca +# tffp = 2.5 * tff +# F_expressions[22] = (-ffp + fss) / tffp +# fp = Aff * ffp + Afs * fs +# tfcafp = 2.5 * tfcaf +# F_expressions[23] = (-fcafp + fcass) / tfcafp +# fcap = Afcaf * fcafp + Afcas * fcas +# km2n = 1.0 * jca +# anca = 1.0 / (ufl.elem_pow(1.0 + Kmn / cass, 4.0) + k2n / km2n) +# F_expressions[24] = k2n * anca - km2n * nca +# PhiCaL = ( +# 4.0 +# * (-0.341 * cao + cass * ufl.exp(2.0 * vfrt)) +# * vffrt +# / (-1.0 + ufl.exp(2.0 * vfrt)) +# ) +# PhiCaNa = ( +# 1.0 +# * (-0.75 * nao + 0.75 * ufl.exp(1.0 * vfrt) * nass) +# * vffrt +# / (-1.0 + ufl.exp(1.0 * vfrt)) +# ) +# PhiCaK = ( +# 1.0 +# * (-0.75 * ko + 0.75 * ufl.exp(1.0 * vfrt) * kss) +# * vffrt +# / (-1.0 + ufl.exp(1.0 * vfrt)) +# ) +# PCa = 0.0001 * scale_ICaL * scale_drug_ICaL * scale_popu_GCaL +# PCap = 1.1 * PCa +# PCaNa = 0.00125 * PCa +# PCaK = 0.0003574 * PCa +# PCaNap = 0.00125 * PCap +# PCaKp = 0.0003574 * PCap +# fICaLp = 1.0 / (1.0 + KmCaMK / CaMKa) +# ICaL = (1.0 - fICaLp) * ( +# (1.0 - nca) * f + fca * jca * nca +# ) * PCa * PhiCaL * d + ( +# (1.0 - nca) * fp + fcap * jca * nca +# ) * PCap * PhiCaL * d * fICaLp +# ICaNa = (1.0 - fICaLp) * ( +# (1.0 - nca) * f + fca * jca * nca +# ) * PCaNa * PhiCaNa * d + ( +# (1.0 - nca) * fp + fcap * jca * nca +# ) * PCaNap * PhiCaNa * d * fICaLp +# ICaK = (1.0 - fICaLp) * ( +# (1.0 - nca) * f + fca * jca * nca +# ) * PCaK * PhiCaK * d + ( +# (1.0 - nca) * fp + fcap * jca * nca +# ) * PCaKp * PhiCaK * d * fICaLp + +# # Expressions for the IKr component +# xrss = 1.0 / (1.0 + 0.29287308872377504 * ufl.exp(-0.14729709824716453 * v)) +# txrf = 12.98 + 1.0 / ( +# 0.0001020239312894894 * ufl.exp(0.25846471956577927 * v) +# + 0.00042992960891929087 * ufl.exp(-0.04906771344455348 * v) +# ) +# txrs = 1.865 + 1.0 / ( +# 0.0005922420036809394 * ufl.exp(0.13596193065941536 * v) +# + 3.549966111802463e-05 * ufl.exp(-0.03855050115651503 * v) +# ) +# Axrf = 1.0 / (1.0 + 4.197299094734718 * ufl.exp(0.02617115938236064 * v)) +# Axrs = 1.0 - Axrf +# F_expressions[25] = (-xrf + xrss) / txrf +# F_expressions[26] = (-xrs + xrss) / txrs +# xr = Axrf * xrf + Axrs * xrs +# rkr = 1.0 / ( +# (1.0 + 2.0820090840784555 * ufl.exp(0.013333333333333334 * v)) +# * (1.0 + 0.7165313105737893 * ufl.exp(0.03333333333333333 * v)) +# ) +# GKr = 0.046 * scale_IKr * scale_drug_IKr * scale_popu_GKr +# IKr = 0.4303314829119352 * ufl.sqrt(ko) * (-EK + v) * GKr * rkr * xr + +# # Expressions for the IKs component +# xs1ss = 1.0 / (1.0 + 0.27288596035656526 * ufl.exp(-0.11195700850873264 * v)) +# txs1 = 817.3 + 1.0 / ( +# 0.003504067763074858 * ufl.exp(0.056179775280898875 * v) +# + 0.0005184809083581659 * ufl.exp(-0.004347826086956522 * v) +# ) +# F_expressions[27] = (-xs1 + xs1ss) / txs1 +# xs2ss = xs1ss +# txs2 = 1.0 / ( +# 0.0022561357010639103 * ufl.exp(-0.03225806451612903 * v) +# + 0.0008208499862389881 * ufl.exp(0.05 * v) +# ) +# F_expressions[28] = (-xs2 + xs2ss) / txs2 +# KsCa = 1.0 + 0.6 / (1.0 + 6.481821026062645e-07 * ufl.elem_pow(1.0 / cai, 1.4)) +# GKs = 0.0034 * scale_IKs * scale_drug_IKs * scale_popu_GKs +# IKs = (-EKs + v) * GKs * KsCa * xs1 * xs2 +# xk1ss = 1.0 / ( +# 1.0 + ufl.exp((-144.59 - v - 2.5538 * ko) / (3.8115 + 1.5692 * ko)) +# ) +# txk1 = 122.2 / ( +# 0.0019352007631390235 * ufl.exp(-0.049115913555992145 * v) +# + 30.43364757524903 * ufl.exp(0.014423770373575654 * v) +# ) +# F_expressions[29] = (-xk1 + xk1ss) / txk1 +# rk1 = 1.0 / ( +# 1.0 +# + 69220.6322106767 +# * ufl.exp(0.10534077741493732 * v - 0.27388602127883704 * ko) +# ) +# GK1 = 0.1908 * scale_IK1 * scale_drug_IK1 * scale_popu_GK1 * HF_scaling_GK1 +# IK1 = ufl.sqrt(ko) * (-EK + v) * GK1 * rk1 * xk1 + +# # Expressions for the INaCa_i component +# hca = ufl.exp(F * qca * v / (R * T)) +# hna = ufl.exp(F * qna * v / (R * T)) +# h1_i = 1.0 + (1.0 + hna) * nai / kna3 +# h2_i = hna * nai / (kna3 * h1_i) +# h3_i = 1.0 / h1_i +# h4_i = 1.0 + (1 + nai / kna2) * nai / kna1 +# h5_i = (nai * nai) / (kna1 * kna2 * h4_i) +# h6_i = 1.0 / h4_i +# h7_i = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 +# h8_i = nao / (kna3 * h7_i * hna) +# h9_i = 1.0 / h7_i +# h10_i = 1.0 + kasymm + nao * (1.0 + nao / kna2) / kna1 +# h11_i = (nao * nao) / (kna1 * kna2 * h10_i) +# h12_i = 1.0 / h10_i +# k1_i = cao * kcaon * h12_i +# k2_i = kcaoff +# k3p_i = wca * h9_i +# k3pp_i = wnaca * h8_i +# k3_i = k3p_i + k3pp_i +# k4p_i = wca * h3_i / hca +# k4pp_i = wnaca * h2_i +# k4_i = k4p_i + k4pp_i +# k5_i = kcaoff +# k6_i = kcaon * cai * h6_i +# k7_i = wna * h2_i * h5_i +# k8_i = wna * h11_i * h8_i +# x1_i = (k2_i + k3_i) * k5_i * k7_i + (k6_i + k7_i) * k2_i * k4_i +# x2_i = (k1_i + k8_i) * k4_i * k6_i + (k4_i + k5_i) * k1_i * k7_i +# x3_i = (k2_i + k3_i) * k6_i * k8_i + (k6_i + k7_i) * k1_i * k3_i +# x4_i = (k1_i + k8_i) * k3_i * k5_i + (k4_i + k5_i) * k2_i * k8_i +# E1_i = x1_i / (x1_i + x2_i + x3_i + x4_i) +# E2_i = x2_i / (x1_i + x2_i + x3_i + x4_i) +# E3_i = x3_i / (x1_i + x2_i + x3_i + x4_i) +# E4_i = x4_i / (x1_i + x2_i + x3_i + x4_i) +# allo_i = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cai, 2.0)) +# zna = 1.0 +# JncxNa_i = E3_i * k4pp_i - E2_i * k3pp_i + 3.0 * E4_i * k7_i - 3.0 * E1_i * k8_i +# JncxCa_i = E2_i * k2_i - E1_i * k1_i +# INaCa_i = ( +# 0.8 +# * Gncx +# * scale_popu_KNCX +# * HF_scaling_Gncx +# * (zca * JncxCa_i + zna * JncxNa_i) +# * allo_i +# ) + +# # Expressions for the INaCa_ss component +# h1 = 1.0 + (1.0 + hna) * nass / kna3 +# h2 = hna * nass / (kna3 * h1) +# h3 = 1.0 / h1 +# h4 = 1.0 + (1 + nass / kna2) * nass / kna1 +# h5 = (nass * nass) / (kna1 * kna2 * h4) +# h6 = 1.0 / h4 +# h7 = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 +# h8 = nao / (kna3 * h7 * hna) +# h9 = 1.0 / h7 +# h10 = 1.0 + kasymm + nao * (1 + nao / kna2) / kna1 +# h11 = (nao * nao) / (kna1 * kna2 * h10) +# h12 = 1.0 / h10 +# k1 = cao * kcaon * h12 +# k2 = kcaoff +# k3p_ss = wca * h9 +# k3pp = wnaca * h8 +# k3 = k3p_ss + k3pp +# k4p_ss = wca * h3 / hca +# k4pp = wnaca * h2 +# k4 = k4p_ss + k4pp +# k5 = kcaoff +# k6 = kcaon * cass * h6 +# k7 = wna * h2 * h5 +# k8 = wna * h11 * h8 +# x1_ss = (k2 + k3) * k5 * k7 + (k6 + k7) * k2 * k4 +# x2_ss = (k1 + k8) * k4 * k6 + (k4 + k5) * k1 * k7 +# x3_ss = (k2 + k3) * k6 * k8 + (k6 + k7) * k1 * k3 +# x4_ss = (k1 + k8) * k3 * k5 + (k4 + k5) * k2 * k8 +# E1_ss = x1_ss / (x1_ss + x2_ss + x3_ss + x4_ss) +# E2_ss = x2_ss / (x1_ss + x2_ss + x3_ss + x4_ss) +# E3_ss = x3_ss / (x1_ss + x2_ss + x3_ss + x4_ss) +# E4_ss = x4_ss / (x1_ss + x2_ss + x3_ss + x4_ss) +# allo_ss = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cass, 2.0)) +# JncxNa_ss = E3_ss * k4pp - E2_ss * k3pp + 3.0 * E4_ss * k7 - 3.0 * E1_ss * k8 +# JncxCa_ss = E2_ss * k2 - E1_ss * k1 +# INaCa_ss = ( +# 0.2 +# * Gncx +# * scale_popu_KNCX +# * HF_scaling_Gncx +# * (zca * JncxCa_ss + zna * JncxNa_ss) +# * allo_ss +# ) + +# # Expressions for the INaK component +# Knai = Knai0 * ufl.exp(0.3333333333333333 * F * delta * v / (R * T)) +# Knao = Knao0 * ufl.exp(0.3333333333333333 * F * (1.0 - delta) * v / (R * T)) +# P = eP / (1.0 + H / Khp + nai / Knap + ki / Kxkur) +# a1 = ( +# k1p +# * ufl.elem_pow(nai / Knai, 3.0) +# / ( +# -1.0 +# + ufl.elem_pow(1.0 + ki / Kki, 2.0) +# + ufl.elem_pow(1.0 + nai / Knai, 3.0) +# ) +# ) +# b1 = MgADP * k1m +# a2 = k2p +# b2 = ( +# k2m +# * ufl.elem_pow(nao / Knao, 3.0) +# / ( +# -1.0 +# + ufl.elem_pow(1.0 + ko / Kko, 2.0) +# + ufl.elem_pow(1.0 + nao / Knao, 3.0) +# ) +# ) +# a3 = ( +# k3p +# * ufl.elem_pow(ko / Kko, 2.0) +# / ( +# -1.0 +# + ufl.elem_pow(1.0 + ko / Kko, 2.0) +# + ufl.elem_pow(1.0 + nao / Knao, 3.0) +# ) +# ) +# b3 = H * k3m * P / (1.0 + MgATP / Kmgatp) +# a4 = MgATP * k4p / (Kmgatp * (1.0 + MgATP / Kmgatp)) +# b4 = ( +# k4m +# * ufl.elem_pow(ki / Kki, 2.0) +# / ( +# -1.0 +# + ufl.elem_pow(1.0 + ki / Kki, 2.0) +# + ufl.elem_pow(1.0 + nai / Knai, 3.0) +# ) +# ) +# x1 = a1 * a2 * a4 + a1 * a2 * b3 + a2 * b3 * b4 + b2 * b3 * b4 +# x2 = a1 * a2 * a3 + a2 * a3 * b4 + a3 * b1 * b4 + b1 * b2 * b4 +# x3 = a2 * a3 * a4 + a3 * a4 * b1 + a4 * b1 * b2 + b1 * b2 * b3 +# x4 = a1 * a3 * a4 + a1 * a4 * b2 + a1 * b2 * b3 + b2 * b3 * b4 +# E1 = x1 / (x1 + x2 + x3 + x4) +# E2 = x2 / (x1 + x2 + x3 + x4) +# E3 = x3 / (x1 + x2 + x3 + x4) +# E4 = x4 / (x1 + x2 + x3 + x4) +# JnakNa = 3.0 * E1 * a3 - 3.0 * E2 * b3 +# JnakK = 2.0 * E4 * b1 - 2.0 * E3 * a1 +# INaK = Pnak * scale_popu_KNaK * HF_scaling_Pnak * (zk * JnakK + zna * JnakNa) + +# # Expressions for the IKb component +# xkb = 1.0 / (1.0 + 2.202363450949239 * ufl.exp(-0.05452562704471101 * v)) +# IKb = GKb * scale_popu_GbK * scale_drug_IKb * (-EK + v) * xkb + +# # Expressions for the INab component +# INab = ( +# PNab +# * scale_drug_INab +# * scale_popu_GbNa +# * (-nao + ufl.exp(vfrt) * nai) +# * vffrt +# / (-1.0 + ufl.exp(vfrt)) +# ) + +# # Expressions for the ICab component +# ICab = ( +# 4.0 +# * PCab +# * scale_drug_ICab +# * scale_popu_GbCa +# * (-0.341 * cao + cai * ufl.exp(2.0 * vfrt)) +# * vffrt +# / (-1.0 + ufl.exp(2.0 * vfrt)) +# ) + +# # Expressions for the IpCa component +# IpCa = GpCa * scale_drug_IpCa * scale_popu_KpCa * cai / (0.0005 + cai) + +# # Expressions for the Isac (Pueyo)--> ns + k component +# Gsac_ns = 0.006 * scale_drug_Isacns +# Esac_ns = -10.0 +# lambda_max = 1.1 +# Gsac_k = (0.2882 * 800.0 / 210.0) * scale_drug_Isack # Pueyo endo +# Isac_P_ns = ufl.conditional( +# ufl.lt(self.lmbda, 1.0), +# 0.0, +# Gsac_ns * ((self.lmbda - 1.0) / (lambda_max - 1.0)) * (v - Esac_ns), +# ) +# Isac_P_k = ufl.conditional( +# ufl.lt(self.lmbda, 1.0), +# 0.0, +# Gsac_k +# * ((self.lmbda - 1.0) / (lambda_max - 1.0)) +# * (1.0 / (1.0 + ufl.exp((19.05 - v) / (29.98)))), +# ) + +# # Expressions for the Istim component +# Istim = 0 #0 # amp*(ufl.le(time, duration)) + +# # Expressions for the diffusion fluxes component +# JdiffNa = 0.5 * nass - 0.5 * nai +# JdiffK = 0.5 * kss - 0.5 * ki +# Jdiff = 5.0 * cass - 5.0 * cai + +# # Expressions for the ryanodine receptor component +# a_rel = 0.5 * bt +# Jrel_inf = ( +# -ICaL +# * a_rel +# / (1.0 + 25.62890625 * HF_scaling_Jrel_inf * ufl.elem_pow(1.0 / cajsr, 8.0)) +# ) +# tau_rel_tmp = bt / (1.0 + 0.0123 / cajsr) +# tau_rel = ufl.conditional(ufl.lt(tau_rel_tmp, 0.001), 0.001, tau_rel_tmp) +# F_expressions[30] = (-Jrelnp + Jrel_inf) / tau_rel +# btp = 1.25 * bt +# a_relp = 0.5 * btp +# Jrel_infp = ( +# -ICaL +# * a_relp +# / (1.0 + 25.62890625 * HF_scaling_Jrel_inf * ufl.elem_pow(1.0 / cajsr, 8.0)) +# ) +# tau_relp_tmp = btp / (1.0 + 0.0123 / cajsr) +# tau_relp = ufl.conditional(ufl.lt(tau_relp_tmp, 0.001), 0.001, tau_relp_tmp) +# F_expressions[31] = (-Jrelp + Jrel_infp) / tau_relp +# fJrelp = 1.0 / (1.0 + KmCaMK / CaMKa) +# Jrel = ((1.0 - fJrelp) * Jrelnp + Jrelp * fJrelp) * scale_popu_KRyR + +# # Expressions for the calcium buffers component +# Jupnp = 0.004375 * cai / (0.00092 + cai) +# Jupp = 0.01203125 * cai / (0.00075 + cai) +# fJupp = 1.0 / (1.0 + KmCaMK / CaMKa) +# Jleak = 0.0002625 * cansr * scale_popu_Kleak * HF_scaling_Jleak +# Jup = ( +# -Jleak +# + ((1.0 - fJupp) * Jupnp + Jupp * fJupp) +# * scale_popu_KSERCA +# * HF_scaling_Jup +# ) +# Jtr = 0.01 * cansr - 0.01 * cajsr + +# # Expressions for the intracellular concentrations component +# F_expressions[32] = JdiffNa * vss / vmyo + ( +# -INa - INaL - INab - Isac_P_ns / 3.0 - 3.0 * INaCa_i - 3.0 * INaK +# ) * Acap / (F * vmyo) +# F_expressions[33] = -JdiffNa + (-ICaNa - 3.0 * INaCa_ss) * Acap / (F * vss) +# F_expressions[34] = JdiffK * vss / vmyo + ( +# -Isac_P_k +# - IK1 +# - IKb +# - IKr +# - IKs +# - Istim +# - Ito +# - Isac_P_ns / 3.0 +# + 2.0 * INaK +# ) * Acap / (F * vmyo) +# F_expressions[35] = -JdiffK - Acap * ICaK / (F * vss) +# Bcass = 1.0 / ( +# 1.0 +# + BSLmax * KmBSL * ufl.elem_pow(KmBSL + cass, -2.0) +# + BSRmax * KmBSR * ufl.elem_pow(KmBSR + cass, -2.0) +# ) +# F_expressions[36] = ( +# -Jdiff +# + Jrel * vjsr / vss +# + 0.5 * (-ICaL + 2.0 * INaCa_ss) * Acap / (F * vss) +# ) * Bcass +# F_expressions[37] = -Jtr * vjsr / vnsr + Jup +# Bcajsr = 1.0 / (1.0 + csqnmax * kmcsqn * ufl.elem_pow(kmcsqn + cajsr, -2.0)) +# F_expressions[38] = (-Jrel + Jtr) * Bcajsr + +# # Expressions for the mechanics component +# kwu = -kws * scale_popu_kws + (kuw * scale_popu_kuw) * ( +# -1.0 + 1.0 / (rw * scale_popu_rw) +# ) +# ksu = ( +# kws +# * scale_popu_kws +# * rw +# * scale_popu_rw +# * (-1.0 + 1.0 / (rs * scale_popu_rs)) +# ) + +# Aw = Tot_A * rs / (rs + rw * (1 - rs)) +# As = Aw +# cw = kuw * phi * (1 - rw) / rw +# cs = kws * phi * rw * (1 - rs) / rs + +# lambda_min12 = ufl.conditional(ufl.lt(self.lmbda, 1.2), self.lmbda, 1.2) +# XS = ufl.conditional(ufl.lt(XS, 0.0), 0.0, XS) +# XW = ufl.conditional(ufl.lt(XW, 0.0), 0.0, XW) + +# XU = 1.0 - TmB - XS - XW +# gammawu = gammaw * abs(Zetaw) +# # gammasu = gammas*ufl.conditional(ufl.gt(Zetas*(ufl.gt(Zetas, 0)), (-1 -\ +# # Zetas)*(ufl.lt(Zetas, -1))), Zetas*(ufl.gt(Zetas, 0)), (-1 -\ +# # Zetas)*(ufl.lt(Zetas, -1))) +# zetas1 = Zetas * ufl.conditional(ufl.gt(Zetas, 0.0), 1.0, 0.0) +# zetas2 = (-1.0 - Zetas) * ufl.conditional( +# ufl.lt(Zetas, -1.0), +# 1.0, +# 0.0, +# ) +# gammasu = gammas * Max(zetas1, zetas2) + +# F_expressions[39] = kws * scale_popu_kws * XW - XS * gammasu - XS * ksu +# F_expressions[40] = ( +# kuw * scale_popu_kuw * XU +# - kws * scale_popu_kws * XW +# - XW * gammawu +# - XW * kwu +# ) +# cat50 = ( +# cat50_ref * scale_popu_CaT50ref + Beta1 * (-1.0 + lambda_min12) +# ) * HF_scaling_cat50_ref +# CaTrpn = ufl.conditional(ufl.lt(CaTrpn, 0.0), 0.0, CaTrpn) +# F_expressions[41] = ( +# ktrpn +# * scale_popu_kTRPN +# * ( +# -CaTrpn +# + ufl.elem_pow(1000.0 * cai / cat50, ntrpn * scale_popu_nTRPN) +# * (1.0 - CaTrpn) +# ) +# ) +# kb = ( +# ku +# * scale_popu_ku +# * ufl.elem_pow(Trpn50 * scale_popu_TRPN50, (ntm * scale_popu_nTm)) +# / ( +# 1.0 +# - (rs * scale_popu_rs) +# - rw * scale_popu_rw * (1.0 - (rs * scale_popu_rs)) +# ) +# ) + +# F_expressions[42] = ( +# ufl.conditional( +# ufl.lt(ufl.elem_pow(CaTrpn, -(ntm * scale_popu_nTm) / 2.0), 100.0), +# ufl.elem_pow(CaTrpn, -(ntm * scale_popu_nTm) / 2.0), +# 100.0, +# ) +# * XU +# * kb +# - ku +# * scale_popu_ku +# * ufl.elem_pow(CaTrpn, (ntm * scale_popu_nTm) / 2.0) +# * TmB +# ) + +# C = -1.0 + lambda_min12 +# dCd = -Cd + C +# eta = ufl.conditional(ufl.lt(dCd, 0.0), etas, etal) +# F_expressions[43] = p_k * (-Cd + C) / eta +# Bcai = 1.0 / (1.0 + cmdnmax * kmcmdn * ufl.elem_pow(kmcmdn + cai, -2.0)) +# J_TRPN = trpnmax * F_expressions[41] +# F_expressions[44] = ( +# -J_TRPN +# + Jdiff * vss / vmyo +# - Jup * vnsr / vmyo +# + 0.5 * (-ICab - IpCa - Isac_P_ns / 3.0 + 2.0 * INaCa_i) * Acap / (F * vmyo) +# ) * Bcai + +# F_expressions[45] = self.dLambda * As - Zetas * cs +# F_expressions[46] = self.dLambda * Aw - Zetaw * cw +# # State 46 and 47 is lambda and dLambda respectively + +# # Return results +# return as_vector(F_expressions) + +# def num_states(self): +# return 47 + +# def __str__(self): +# return "ORdmm_Land_em_coupling cardiac cell model" diff --git a/src/simcardems/models/explicit_ORdmm_Land/em_model.py b/src/simcardems/models/explicit_ORdmm_Land/em_model.py index efd36a80..f271b53e 100644 --- a/src/simcardems/models/explicit_ORdmm_Land/em_model.py +++ b/src/simcardems/models/explicit_ORdmm_Land/em_model.py @@ -7,7 +7,7 @@ from typing import TYPE_CHECKING from typing import Union -import cbcbeat +import beat import dolfin import numpy as np @@ -115,7 +115,6 @@ def __eq__(self, __o: object) -> bool: return False for attr in [ - "vs", "mech_state", "lmbda_mech_func", "Zetas_mech", @@ -123,12 +122,12 @@ def __eq__(self, __o: object) -> bool: "lmbda_ep", "lmbda_ep_prev", "dLambda_ep", + "XS_mech", + "XW_mech", "Zetas_ep", "Zetaw_ep", "XS_ep", "XW_ep", - "XS_mech", - "XW_mech", ]: if not np.allclose( getattr(self, attr).vector().get_local(), @@ -136,6 +135,12 @@ def __eq__(self, __o: object) -> bool: ): logger.info(f"{attr} differs in equality") return False + for attr in [ + "vs", + ]: + if not np.allclose(getattr(self, attr), getattr(__o, attr)): + logger.info(f"{attr} differs in equality") + return False return True @@ -153,21 +158,19 @@ def assigners(self, assigners) -> None: def setup_assigners(self) -> None: from ...datacollector import Assigners + from . import cell_model - self.assigners = Assigners(vs=self.vs, mech_state=self.mech_state) - for name, index in [ - ("V", 0), - ("Ca", 45), - ("XS", 40), - ("XW", 41), - ("CaTrpn", 42), - ("TmB", 43), - ("Cd", 44), - ]: + self.assigners = Assigners( + vs=self.vs, + mech_state=self.mech_state, + V_mech=self.V_mech, + V_ep=self.V_ep, + ) + for name in ["v", "cai", "XS", "XW", "CaTrpn", "TmB", "Cd"]: self.assigners.register_subfunction( name=name, group="ep", - subspace_index=index, + subspace_index=cell_model.state_index(name), ) self.assigners.register_subfunction( @@ -183,9 +186,10 @@ def setup_assigners(self) -> None: self.assigners.register_subfunction( name=name, group="ep", - subspace_index=index, + subspace_index=cell_model.state_index(name), is_pre=True, ) + pass @property def mech_mesh(self): @@ -200,8 +204,8 @@ def mech_state(self): return self.mech_solver.state @property - def vs(self) -> dolfin.Function: - return self.ep_solver.solution_fields()[0] + def vs(self) -> np.ndarray: + return self.ep_solver.ode.values @property def dLambda_ep(self): @@ -225,25 +229,26 @@ def update_prev_mechanics(self): self.lmbda_ep_prev.vector()[:] = self.lmbda_ep.vector() def update_prev_ep(self): - self.ep_solver.vs_.assign(self.ep_solver.vs) + pass + # self.ep_solver.vs_.assign(self.ep_solver.vs) # def _project_lmbda(self): # F = dolfin.grad(self.u_ep) + dolfin.Identity(3) # f = F * self.geometry.f0_ep # self._projector_V_ep(self.lmbda_ep, dolfin.project(dolfin.sqrt(f**2))) - def register_ep_model(self, solver: cbcbeat.SplittingSolver): + def register_ep_model(self, solver: beat.MonodomainSplittingSolver): logger.debug("Registering EP model") + self.ep_solver = solver - self.XS_ep, self.XS_ep_assigner = utils.setup_assigner(self.vs, 40) - self.XW_ep, self.XW_ep_assigner = utils.setup_assigner(self.vs, 41) - self.Zetas_ep, self.Zetas_ep_assigner = utils.setup_assigner(self.vs, 46) - self.Zetaw_ep, self.Zetaw_ep_assigner = utils.setup_assigner(self.vs, 47) + from . import cell_model + + params = self.ep_solver.ode.parameters - params = self.ep_solver.ode_solver._model.parameters() - self._Tref = params["Tref"] - self._rs = params["rs"] - self._Beta0 = params["Beta0"] + self._Tref = params[cell_model.parameter_index("Tref")] + self._rs = params[cell_model.parameter_index("rs")] + self._Beta0 = params[cell_model.parameter_index("Beta0")] + self.ep_to_coupling() if hasattr(self, "mech_solver"): self.mechanics_to_coupling() @@ -277,10 +282,12 @@ def register_datacollector(self, collector: datacollector.DataCollector) -> None def ep_to_coupling(self): logger.debug("Transfer variables from EP to coupling") - self.XS_ep_assigner.assign(self.XS_ep, utils.sub_function(self.vs, 40)) - self.XW_ep_assigner.assign(self.XW_ep, utils.sub_function(self.vs, 41)) - self.Zetas_ep_assigner.assign(self.Zetas_ep, utils.sub_function(self.vs, 46)) - self.Zetaw_ep_assigner.assign(self.Zetaw_ep, utils.sub_function(self.vs, 47)) + from . import cell_model + + self.XS_ep.vector()[:] = self.vs[cell_model.state_index("XS")] + self.XW_ep.vector()[:] = self.vs[cell_model.state_index("XW")] + self.Zetas_ep.vector()[:] = self.vs[cell_model.state_index("Zetas")] + self.Zetaw_ep.vector()[:] = self.vs[cell_model.state_index("Zetaw")] logger.debug("Done transferring variables from EP to coupling") @@ -303,6 +310,7 @@ def coupling_to_mechanics(self): Beta0=self._Beta0, ), ) + logger.debug("Done transferring variables from coupling to mechanics") def mechanics_to_coupling(self): @@ -332,12 +340,12 @@ def print_mechanics_info(self): def print_ep_info(self): # Output some degrees of freedom - total_dofs = self.vs.function_space().dim() + total_dofs = self.ep_solver.pde.V.dim() logger.info("EP model") utils.print_mesh_info(self.ep_mesh, total_dofs) def cell_params(self): - return self.ep_solver.ode_solver._model.parameters() + return self.ep_solver.ode.parameters def save_state( self, @@ -352,15 +360,13 @@ def save_state( "a", ) as h5file: h5file.write(self.lmbda_ep_prev, "/em/lmbda_prev") - h5file.write(self.ep_solver.vs, "/ep/vs") + h5file.write(self.Zetas_mech, "/em/Zetas_prev") + h5file.write(self.Zetaw_mech, "/em/Zetaw_prev") h5file.write(self.mech_solver.state, "/mechanics/state") - io.dict_to_h5( - self.cell_params(), - path, - "ep/cell_params", - comm=self.geometry.comm(), - ) + with io.h5pyfile(path, "a") as h5file: + h5file["ep/vs"] = self.vs + h5file["ep/cell_params"] = self.cell_params() @classmethod def from_state( @@ -381,37 +387,28 @@ def from_state( with io.h5pyfile(path) as h5file: config = Config(**io.h5_to_dict(h5file["config"])) state_params = io.h5_to_dict(h5file["state_params"]) - cell_params = io.h5_to_dict(h5file["ep"]["cell_params"]) - vs_signature = h5file["ep"]["vs"].attrs["signature"].decode() mech_signature = h5file["mechanics"]["state"].attrs["signature"].decode() + cell_params = h5file["ep"]["cell_params"][:] + vs = h5file["ep"]["vs"][:] config.drug_factors_file = drug_factors_file config.popu_factors_file = popu_factors_file config.disease_state = disease_state config.PCL = PCL - VS = dolfin.FunctionSpace(geo.ep_mesh, eval(vs_signature)) - vs = dolfin.Function(VS) - W = dolfin.FunctionSpace(geo.mechanics_mesh, eval(mech_signature)) mech_state = dolfin.Function(W) V = dolfin.FunctionSpace(geo.ep_mesh, "CG", 1) - lmbda = dolfin.Function(V, name="lambda") + lmbda_prev = dolfin.Function(V, name="lambda") logger.debug("Load functions") with dolfin.HDF5File(geo.ep_mesh.mpi_comm(), path.as_posix(), "r") as h5file: - h5file.read(vs, "/ep/vs") h5file.read(mech_state, "/mechanics/state") - h5file.read(lmbda, "/em/lmbda_prev") + h5file.read(lmbda_prev, "/em/lmbda_prev") from . import CellModel, ActiveModel - cell_inits = io.vs_functions_to_dict( - vs, - state_names=CellModel.default_initial_conditions().keys(), - ) - - cls_EMCoupling = partial(cls, lmbda=lmbda) + cls_EMCoupling = partial(cls, lmbda=lmbda_prev) return em_model.setup_EM_model( cls_EMCoupling=cls_EMCoupling, @@ -419,7 +416,7 @@ def from_state( cls_ActiveModel=ActiveModel, geometry=geo, config=config, - cell_inits=cell_inits, + cell_inits=vs, cell_params=cell_params, mech_state_init=mech_state, state_params=state_params, diff --git a/src/simcardems/models/pureEP_ORdmm_Land/cell_model.py b/src/simcardems/models/pureEP_ORdmm_Land/cell_model.py index 90f5f4ff..5b8e4138 100644 --- a/src/simcardems/models/pureEP_ORdmm_Land/cell_model.py +++ b/src/simcardems/models/pureEP_ORdmm_Land/cell_model.py @@ -1,12 +1,9 @@ +# flake8: noqa: F841 import math import numpy -class ORdmmLandPureEp: - pass - - def parameter_index(name: str) -> float: """Return the index of the parameter with the given name @@ -496,7 +493,11 @@ def init_state_values(**values): return states -def rhs(t, states, parameters): +def forward_generalized_rush_larsen(coupling): + return forward_generalized_rush_larsen_ + + +def forward_generalized_rush_larsen_(states, t, dt, parameters): # Assign states hL = states[0] a = states[1] @@ -555,14 +556,11 @@ def rhs(t, states, parameters): Beta0 = parameters[4] Beta1 = parameters[5] CaMKo = parameters[6] - Esac_ns = parameters[7] F = parameters[8] GKb = parameters[9] GNa = parameters[10] Gncx = parameters[11] GpCa = parameters[12] - Gsac_k = parameters[13] - Gsac_ns = parameters[14] Gto = parameters[15] H = parameters[16] Khp = parameters[17] @@ -595,10 +593,8 @@ def rhs(t, states, parameters): amp = parameters[44] bCaMK = parameters[45] bt = parameters[46] - calib = parameters[47] cao = parameters[48] cat50_ref = parameters[49] - celltype = parameters[50] cmdnmax = parameters[51] csqnmax = parameters[52] dLambda = parameters[53] @@ -606,12 +602,10 @@ def rhs(t, states, parameters): delta_epi = parameters[55] duration = parameters[56] eP = parameters[57] - emcoupling = parameters[58] etal = parameters[59] etas = parameters[60] gammas = parameters[61] gammaw = parameters[62] - isacs = parameters[63] k1m = parameters[64] k1p = parameters[65] k2m = parameters[66] @@ -626,7 +620,6 @@ def rhs(t, states, parameters): kcaon = parameters[75] kmcmdn = parameters[76] kmcsqn = parameters[77] - kmtrpn = parameters[78] kna1 = parameters[79] kna2 = parameters[80] kna3 = parameters[81] @@ -635,9 +628,7 @@ def rhs(t, states, parameters): ku = parameters[84] kuw = parameters[85] kws = parameters[86] - lambda_max = parameters[87] lmbda = parameters[88] - mode = parameters[89] nao = parameters[90] ntm = parameters[91] ntrpn = parameters[92] @@ -676,8 +667,6 @@ def rhs(t, states, parameters): scale_drug_INaL = parameters[125] scale_drug_INab = parameters[126] scale_drug_IpCa = parameters[127] - scale_drug_Isack = parameters[128] - scale_drug_Isacns = parameters[129] scale_drug_Ito = parameters[130] thL = parameters[131] tjca = parameters[132] @@ -776,39 +765,36 @@ def rhs(t, states, parameters): KsCa = 1.0 + 0.6 / ((3.8e-05 / cai) ** 1.4 + 1.0) Bcai = 1.0 / ((cmdnmax * kmcmdn) / (cai + kmcmdn) ** 2.0 + 1.0) Bcajsr = 1.0 / ((csqnmax * kmcsqn) / (cajsr + kmcsqn) ** 2.0 + 1.0) - Jdiff = (-cai + cass) / 0.2 Bcass = 1.0 / ( (BSLmax * KmBSL) / (KmBSL + cass) ** 2.0 + ((BSRmax * KmBSR) / (KmBSR + cass) ** 2.0 + 1.0) ) + Jdiff = (-cai + cass) / 0.2 CaMKb = (CaMKo * (1.0 - CaMKt)) / (KmCaM / cass + 1.0) - CaTrpn_max = (CaTrpn) * (CaTrpn > 0) + (0) * numpy.logical_not((CaTrpn > 0)) - vffrt = (F * (F * v)) / ((R * T)) - vfrt = (F * v) / ((R * T)) - EK = ((R * T) / F) * numpy.log(ko / ki) rk1 = 1.0 / (numpy.exp((-2.6 * ko + (v + 105.8)) / 9.493) + 1.0) xk1ss = 1.0 / ( numpy.exp((-((2.5538 * ko + v) + 144.59)) / (1.5692 * ko + 3.8115)) + 1.0 ) - ENa = ((R * T) / F) * numpy.log(nao / nai) + EK = ((R * T) / F) * numpy.log(ko / ki) + vffrt = (F * (F * v)) / ((R * T)) + vfrt = (F * v) / ((R * T)) EKs = ((R * T) / F) * numpy.log((PKNa * nao + ko) / (PKNa * nai + ki)) + ENa = ((R * T) / F) * numpy.log(nao / nai) GK1 = scale_HF_GK1 * ((0.1908 * scale_IK1) * scale_drug_IK1) GKr = (0.046 * scale_IKr) * scale_drug_IKr GKs = (0.0034 * scale_IKs) * scale_drug_IKs GNaL = scale_HF_GNaL * ((0.0075 * scale_INaL) * scale_drug_INaL) km2n = 1.0 * jca IpCa = (cai * (GpCa * scale_drug_IpCa)) / (cai + 0.0005) - Istim = (amp) * (duration >= t) + (0) * numpy.logical_not((duration >= t)) + Istim = 0 # (amp) * (duration >= t) + (0) * numpy.logical_not((duration >= t)) JdiffK = (-ki + kss) / 2.0 JdiffNa = (-nai + nass) / 2.0 - Jtr = (-cajsr + cansr) / 100.0 Jleak = ((0.0039375 * cansr) * scale_HF_Jleak) / 15.0 + Jtr = (-cajsr + cansr) / 100.0 Knai = Knai0 * numpy.exp((F * (delta * v)) / (((3.0 * R) * T))) Knao = Knao0 * numpy.exp((F * (v * (1.0 - delta))) / (((3.0 * R) * T))) P = eP / (((H / Khp + 1.0) + nai / Knap) + ki / Kxkur) PCa = (0.0001 * scale_ICaL) * scale_drug_ICaL - XW_max = (XW) * (XW > 0) + (0) * numpy.logical_not((XW > 0)) - XS_max = (XS) * (XS > 0) + (0) * numpy.logical_not((XS > 0)) XU = -XW + (-XS + (1 - TmB)) a2 = k2p a4 = ((MgATP * k4p) / Kmgatp) / (1.0 + MgATP / Kmgatp) @@ -818,43 +804,20 @@ def rhs(t, states, parameters): allo_i = 1.0 / ((KmCaAct / cai) ** 2.0 + 1.0) allo_ss = 1.0 / ((KmCaAct / cass) ** 2.0 + 1.0) b1 = MgADP * k1m - cs = ((kws * phi) * (rw * (1 - rs))) / rs ksu = (kws * rw) * (-1 + 1 / rs) + cs = ((kws * phi) * (rw * (1 - rs))) / rs cw = ((kuw * phi) * ((1 - rs) * (1 - rw))) / ((rw * (1 - rs))) kwu = kuw * (-1 + 1 / rw) - kws - gammasu = ( - gammas * Zetas * 1 * (Zetas > 0) - + 0 - * (~(Zetas > 0)) - * numpy.logical_and.reduce( - ( - numpy.logical_or((Zetas > -1), (Zetas > 0)), - numpy.logical_or((Zetas > 0), (Zetas < -1)), - numpy.logical_or.reduce( - ((Zetas >= -1), (Zetas <= 0), (Zetas > -1 / 2)), - ), - ), - ) - + (-Zetas - 1) * 1 * (Zetas < -1) - + 0 - * (~(Zetas < -1)) - * ( - ~numpy.logical_and.reduce( - ( - numpy.logical_or((Zetas > -1), (Zetas > 0)), - numpy.logical_or((Zetas > 0), (Zetas < -1)), - numpy.logical_or.reduce( - ((Zetas >= -1), (Zetas <= 0), (Zetas > -1 / 2)), - ), - ), - ) - ) + gammasu = gammas * numpy.where( + Zetas * (Zetas > 0) > (-1 - Zetas) * (Zetas < -1), + Zetas * (Zetas > 0), + (-1 - Zetas) * (Zetas < -1), ) gammawu = gammaw * numpy.abs(Zetaw) - h10 = (nao / kna1) * (1 + nao / kna2) + (kasymm + 1.0) - h10_i = (nao / kna1) * (1.0 + nao / kna2) + (kasymm + 1.0) h4 = (nass / kna1) * (1 + nass / kna2) + 1.0 h4_i = (nai / kna1) * (1 + nai / kna2) + 1.0 + h10 = (nao / kna1) * (1 + nao / kna2) + (kasymm + 1.0) + h10_i = (nao / kna1) * (1.0 + nao / kna2) + (kasymm + 1.0) hca = numpy.exp((F * (qca * v)) / ((R * T))) hna = numpy.exp((F * (qna * v)) / ((R * T))) k2 = kcaoff @@ -891,36 +854,66 @@ def rhs(t, states, parameters): Axrs = 1.0 - Axrf fcass = fss dhL_dt = (-hL + hLss) / ((scale_HF_thL * thL)) - values[0] = dhL_dt + dhL_dt_linearized = -1 / (scale_HF_thL * thL) + values[0] = ( + dhL_dt * (numpy.exp(dhL_dt_linearized * dt) - 1) / dhL_dt_linearized + hL + ) jss = hss da_dt = (-a + ass) / ta - values[1] = da_dt + da_dt_linearized = -1 / ta + values[1] = a + da_dt * (numpy.exp(da_dt_linearized * dt) - 1) / da_dt_linearized dap_dt = (-ap + assp) / ta - values[2] = dap_dt + dap_dt_linearized = -1 / ta + values[2] = ( + ap + dap_dt * (numpy.exp(dap_dt_linearized * dt) - 1) / dap_dt_linearized + ) dd_dt = (-d + dss) / td - values[3] = dd_dt + dd_dt_linearized = -1 / td + values[3] = d + dd_dt * (numpy.exp(dd_dt_linearized * dt) - 1) / dd_dt_linearized tfcafp = 2.5 * tfcaf tffp = 2.5 * tff dff_dt = (-ff + fss) / tff - values[4] = dff_dt + dff_dt_linearized = -1 / tff + values[4] = ( + dff_dt * (numpy.exp(dff_dt_linearized * dt) - 1) / dff_dt_linearized + ff + ) dfs_dt = (-fs + fss) / tfs - values[5] = dfs_dt + dfs_dt_linearized = -1 / tfs + values[5] = ( + dfs_dt * (numpy.exp(dfs_dt_linearized * dt) - 1) / dfs_dt_linearized + fs + ) dhf_dt = (-hf + hss) / thf - values[6] = dhf_dt + dhf_dt_linearized = -1 / thf + values[6] = ( + dhf_dt * (numpy.exp(dhf_dt_linearized * dt) - 1) / dhf_dt_linearized + hf + ) thsp = 3.0 * ths dhs_dt = (-hs + hss) / ths - values[7] = dhs_dt + dhs_dt_linearized = -1 / ths + values[7] = ( + dhs_dt * (numpy.exp(dhs_dt_linearized * dt) - 1) / dhs_dt_linearized + hs + ) tjp = 1.46 * tj tmL = tm dm_dt = (-m + mss) / tm - values[8] = dm_dt + dm_dt_linearized = -1 / tm + values[8] = dm_dt * (numpy.exp(dm_dt_linearized * dt) - 1) / dm_dt_linearized + m dxrf_dt = (-xrf + xrss) / txrf - values[9] = dxrf_dt + dxrf_dt_linearized = -1 / txrf + values[9] = ( + dxrf_dt * (numpy.exp(dt * dxrf_dt_linearized) - 1) / dxrf_dt_linearized + xrf + ) dxrs_dt = (-xrs + xrss) / txrs - values[10] = dxrs_dt + dxrs_dt_linearized = -1 / txrs + values[10] = ( + dxrs_dt * (numpy.exp(dt * dxrs_dt_linearized) - 1) / dxrs_dt_linearized + xrs + ) xs2ss = xs1ss dxs1_dt = (-xs1 + xs1ss) / txs1 - values[11] = dxs1_dt + dxs1_dt_linearized = -1 / txs1 + values[11] = ( + dxs1_dt * (numpy.exp(dt * dxs1_dt_linearized) - 1) / dxs1_dt_linearized + xs1 + ) f = Aff * ff + Afs * fs fp = Aff * ffp + Afs * fs Acap = 2 * Ageo @@ -933,7 +926,21 @@ def rhs(t, states, parameters): As = Aw CaMKa = scale_HF_CaMKa * (CaMKb + CaMKt) dCaMKt_dt = -CaMKt * bCaMK + (CaMKb * aCaMK) * (CaMKb + CaMKt) - values[12] = dCaMKt_dt + dCaMKt_dt_linearized = CaMKb * aCaMK - bCaMK + values[12] = ( + CaMKt + + dCaMKt_dt + * (numpy.exp(dCaMKt_dt_linearized * dt) - 1) + / dCaMKt_dt_linearized + * (numpy.abs(dCaMKt_dt_linearized) > 1e-08) + + dCaMKt_dt * dt * (~(numpy.abs(dCaMKt_dt_linearized) > 1e-08)) + ) + dxk1_dt = (-xk1 + xk1ss) / txk1 + dxk1_dt_linearized = -1 / txk1 + values[13] = ( + dxk1_dt * (numpy.exp(dt * dxk1_dt_linearized) - 1) / dxk1_dt_linearized + xk1 + ) + IKb = (xkb * (GKb * scale_drug_IKb)) * (-EK + v) ICab = ( (vffrt * (4.0 * (PCab * scale_drug_ICab))) * (cai * numpy.exp(2.0 * vfrt) - 0.341 * cao) @@ -950,9 +957,6 @@ def rhs(t, states, parameters): PhiCaNa = ( (1.0 * vffrt) * (-0.75 * nao + (0.75 * nass) * numpy.exp(1.0 * vfrt)) ) / (numpy.exp(1.0 * vfrt) - 1.0) - IKb = (xkb * (GKb * scale_drug_IKb)) * (-EK + v) - dxk1_dt = (-xk1 + xk1ss) / txk1 - values[13] = dxk1_dt IK1 = (xk1 * (rk1 * (GK1 * math.sqrt(ko)))) * (-EK + v) IKs = (xs2 * (xs1 * (GKs * KsCa))) * (-EKs + v) anca = 1.0 / (k2n / km2n + (Kmn / cass + 1.0) ** 4.0) @@ -978,70 +982,153 @@ def rhs(t, states, parameters): (tau_rel_tmp < 0.001), ) dZetaw_dt = Aw * dLambda - Zetaw * cw - values[14] = dZetaw_dt + dZetaw_dt_linearized = -cw + values[14] = ( + Zetaw + + dZetaw_dt + * (numpy.exp(dZetaw_dt_linearized * dt) - 1) + / dZetaw_dt_linearized + * (numpy.abs(dZetaw_dt_linearized) > 1e-08) + + dZetaw_dt * dt * (~(numpy.abs(dZetaw_dt_linearized) > 1e-08)) + ) dXS_dt = -XS * gammasu + (-XS * ksu + XW * kws) - values[15] = dXS_dt + dXS_dt_linearized = -gammasu - ksu + values[15] = ( + XS + + dXS_dt + * (numpy.exp(dXS_dt_linearized * dt) - 1) + / dXS_dt_linearized + * (numpy.abs(dXS_dt_linearized) > 1e-08) + + dXS_dt * dt * (~(numpy.abs(dXS_dt_linearized) > 1e-08)) + ) + dXW_dt = -XW * gammawu + (-XW * kws + (XU * kuw - XW * kwu)) - values[16] = dXW_dt - h11 = (nao * nao) / ((kna2 * (h10 * kna1))) - h12 = 1.0 / h10 - h11_i = (nao * nao) / ((kna2 * (h10_i * kna1))) - h12_i = 1.0 / h10_i + dXW_dt_linearized = -gammawu - kws - kwu + values[16] = ( + XW + + dXW_dt + * (numpy.exp(dXW_dt_linearized * dt) - 1) + / dXW_dt_linearized + * (numpy.abs(dXW_dt_linearized) > 1e-08) + + dXW_dt * dt * (~(numpy.abs(dXW_dt_linearized) > 1e-08)) + ) h5 = (nass * nass) / ((kna2 * (h4 * kna1))) h6 = 1.0 / h4 h5_i = (nai * nai) / ((kna2 * (h4_i * kna1))) h6_i = 1.0 / h4_i + h11 = (nao * nao) / ((kna2 * (h10 * kna1))) + h12 = 1.0 / h10 + h11_i = (nao * nao) / ((kna2 * (h10_i * kna1))) + h12_i = 1.0 / h10_i h1 = (nass / kna3) * (hna + 1) + 1 h1_i = (nai / kna3) * (hna + 1) + 1 h7 = (nao / kna3) * (1.0 + 1.0 / hna) + 1.0 h7_i = (nao / kna3) * (1.0 + 1.0 / hna) + 1.0 dTmB_dt = -TmB * CaTrpn ** (ntm / 2) * ku + XU * ( - kb * CaTrpn ** ((-ntm) / 2) * (CaTrpn ** ((-ntm) / 2) < 100) - + 100 * (~(CaTrpn ** ((-ntm) / 2) < 100)) + kb + * numpy.where((CaTrpn ** (-1 / 2 * ntm) < 100), CaTrpn ** (-1 / 2 * ntm), 100) + ) + dTmB_dt_linearized = numpy.where( + numpy.isclose(CaTrpn, 0), + 0, + -(CaTrpn ** (ntm / 2)) * ku, + ) + values[17] = ( + TmB + + dTmB_dt + * (numpy.exp(dTmB_dt_linearized * dt) - 1) + / dTmB_dt_linearized + * (numpy.abs(dTmB_dt_linearized) > 1e-08) + + dTmB_dt * dt * (~(numpy.abs(dTmB_dt_linearized) > 1e-08)) ) - if numpy.isnan(dTmB_dt): - dTmB_dt = 0 - values[17] = dTmB_dt C = lambda_min12 - 1 cat50 = scale_HF_cat50_ref * (Beta1 * (lambda_min12 - 1) + cat50_ref) lambda_min087 = (lambda_min12) * (lambda_min12 < 0.87) + (0.87) * numpy.logical_not( (lambda_min12 < 0.87), ) dhLp_dt = (-hLp + hLssp) / thLp - values[18] = dhLp_dt + dhLp_dt_linearized = -1 / thLp + values[18] = ( + dhLp_dt * (numpy.exp(dhLp_dt_linearized * dt) - 1) / dhLp_dt_linearized + hLp + ) tiFp = tiF * (dti_develop * dti_recover) diF_dt = (-iF + iss) / tiF - values[19] = diF_dt + diF_dt_linearized = -1 / tiF + values[19] = ( + diF_dt * (numpy.exp(diF_dt_linearized * dt) - 1) / diF_dt_linearized + iF + ) tiSp = tiS * (dti_develop * dti_recover) diS_dt = (-iS + iss) / tiS - values[20] = diS_dt + diS_dt_linearized = -1 / tiS + values[20] = ( + diS_dt * (numpy.exp(diS_dt_linearized * dt) - 1) / diS_dt_linearized + iS + ) fca = Afcaf * fcaf + Afcas * fcas fcap = Afcaf * fcafp + Afcas * fcas i = AiF * iF + AiS * iS ip = AiF * iFp + AiS * iSp xr = Axrf * xrf + Axrs * xrs dfcaf_dt = (-fcaf + fcass) / tfcaf - values[21] = dfcaf_dt + dfcaf_dt_linearized = -1 / tfcaf + values[21] = ( + dfcaf_dt * (numpy.exp(dfcaf_dt_linearized * dt) - 1) / dfcaf_dt_linearized + + fcaf + ) dfcas_dt = (-fcas + fcass) / tfcas - values[22] = dfcas_dt + dfcas_dt_linearized = -1 / tfcas + values[22] = ( + dfcas_dt * (numpy.exp(dfcas_dt_linearized * dt) - 1) / dfcas_dt_linearized + + fcas + ) djca_dt = (fcass - jca) / tjca - values[23] = djca_dt + djca_dt_linearized = -1 / tjca + values[23] = ( + djca_dt * (numpy.exp(djca_dt_linearized * dt) - 1) / djca_dt_linearized + jca + ) dj_dt = (-j + jss) / tj - values[24] = dj_dt + dj_dt_linearized = -1 / tj + values[24] = dj_dt * (numpy.exp(dj_dt_linearized * dt) - 1) / dj_dt_linearized + j dfcafp_dt = (-fcafp + fcass) / tfcafp - values[25] = dfcafp_dt + dfcafp_dt_linearized = -1 / tfcafp + values[25] = ( + dfcafp_dt * (numpy.exp(dfcafp_dt_linearized * dt) - 1) / dfcafp_dt_linearized + + fcafp + ) dffp_dt = (-ffp + fss) / tffp - values[26] = dffp_dt + dffp_dt_linearized = -1 / tffp + values[26] = ( + dffp_dt * (numpy.exp(dffp_dt_linearized * dt) - 1) / dffp_dt_linearized + ffp + ) dhsp_dt = (-hsp + hssp) / thsp - values[27] = dhsp_dt + dhsp_dt_linearized = -1 / thsp + values[27] = ( + dhsp_dt * (numpy.exp(dhsp_dt_linearized * dt) - 1) / dhsp_dt_linearized + hsp + ) djp_dt = (-jp + jss) / tjp - values[28] = djp_dt + djp_dt_linearized = -1 / tjp + values[28] = ( + djp_dt * (numpy.exp(djp_dt_linearized * dt) - 1) / djp_dt_linearized + jp + ) dmL_dt = (-mL + mLss) / tmL - values[29] = dmL_dt + dmL_dt_linearized = -1 / tmL + values[29] = ( + dmL_dt * (numpy.exp(dmL_dt_linearized * dt) - 1) / dmL_dt_linearized + mL + ) dxs2_dt = (-xs2 + xs2ss) / txs2 - values[30] = dxs2_dt + dxs2_dt_linearized = -1 / txs2 + values[30] = ( + dxs2_dt * (numpy.exp(dt * dxs2_dt_linearized) - 1) / dxs2_dt_linearized + xs2 + ) dZetas_dt = As * dLambda - Zetas * cs - values[31] = dZetas_dt + dZetas_dt_linearized = -cs + values[31] = ( + Zetas + + dZetas_dt + * (numpy.exp(dZetas_dt_linearized * dt) - 1) + / dZetas_dt_linearized + * (numpy.abs(dZetas_dt_linearized) > 1e-08) + + dZetas_dt * dt * (~(numpy.abs(dZetas_dt_linearized) > 1e-08)) + ) fICaLp = 1.0 / (1.0 + KmCaMK / CaMKa) fINaLp = 1.0 / (1.0 + KmCaMK / CaMKa) fINap = 1.0 / (1.0 + KmCaMK / CaMKa) @@ -1049,7 +1136,15 @@ def rhs(t, states, parameters): fJrelp = 1.0 / (1.0 + KmCaMK / CaMKa) fJupp = 1.0 / (1.0 + KmCaMK / CaMKa) dnca_dt = anca * k2n - km2n * nca - values[32] = dnca_dt + dnca_dt_linearized = -km2n + values[32] = ( + nca + + dnca_dt + * (numpy.exp(dnca_dt_linearized * dt) - 1) + / dnca_dt_linearized + * (numpy.abs(dnca_dt_linearized) > 1e-08) + + dnca_dt * dt * (~(numpy.abs(dnca_dt_linearized) > 1e-08)) + ) x2 = b4 * (a2 * a3) + (b4 * (a3 * b1) + (a3 * (a1 * a2) + b4 * (b1 * b2))) x1 = a2 * (a1 * b3) + (b3 * (a2 * b4) + (a2 * (a1 * a4) + b3 * (b2 * b4))) x3 = b1 * (a3 * a4) + (a4 * (b1 * b2) + (a4 * (a2 * a3) + b1 * (b2 * b3))) @@ -1059,10 +1154,10 @@ def rhs(t, states, parameters): tau_relp = (0.001) * (tau_relp_tmp < 0.001) + (tau_relp_tmp) * numpy.logical_not( (tau_relp_tmp < 0.001), ) - k1 = kcaon * (cao * h12) - k1_i = kcaon * (cao * h12_i) k6 = kcaon * (cass * h6) k6_i = kcaon * (cai * h6_i) + k1 = kcaon * (cao * h12) + k1_i = kcaon * (cao * h12_i) h2 = (hna * nass) / ((h1 * kna3)) h3 = 1.0 / h1 h2_i = (hna * nai) / ((h1_i * kna3)) @@ -1071,15 +1166,29 @@ def rhs(t, states, parameters): h9 = 1.0 / h7 h8_i = nao / ((h7_i * (hna * kna3))) h9_i = 1.0 / h7_i - F1 = numpy.exp(C * p_b) - 1 + # F1 = numpy.exp(C * p_b) - 1 dCd = C - Cd dCaTrpn_dt = ktrpn * (-CaTrpn + ((1000 * cai) / cat50) ** ntrpn * (1 - CaTrpn)) - values[33] = dCaTrpn_dt - h_lambda_prima = Beta0 * ((lambda_min087 + lambda_min12) - 1.87) + 1 + dCaTrpn_dt_linearized = ktrpn * (-(((1000 * cai) / cat50) ** ntrpn) - 1) + values[33] = ( + CaTrpn + + dCaTrpn_dt + * (numpy.exp(dCaTrpn_dt_linearized * dt) - 1) + / dCaTrpn_dt_linearized + * (numpy.abs(dCaTrpn_dt_linearized) > 1e-08) + + dCaTrpn_dt * dt * (~(numpy.abs(dCaTrpn_dt_linearized) > 1e-08)) + ) + # h_lambda_prima = Beta0 * ((lambda_min087 + lambda_min12) - 1.87) + 1 diFp_dt = (-iFp + iss) / tiFp - values[34] = diFp_dt + diFp_dt_linearized = -1 / tiFp + values[34] = ( + diFp_dt * (numpy.exp(diFp_dt_linearized * dt) - 1) / diFp_dt_linearized + iFp + ) diSp_dt = (-iSp + iss) / tiSp - values[35] = diSp_dt + diSp_dt_linearized = -1 / tiSp + values[35] = ( + diSp_dt * (numpy.exp(diSp_dt_linearized * dt) - 1) / diSp_dt_linearized + iSp + ) IKr = (rkr * (xr * (GKr * (0.4303314829119352 * math.sqrt(ko))))) * (-EK + v) ICaL = (d * (PhiCaL * (PCa * (1.0 - fICaLp)))) * ( f * (1.0 - nca) + nca * (fca * jca) @@ -1117,1732 +1226,49 @@ def rhs(t, states, parameters): k3p_i = h9_i * wca eta = (etas) * (dCd < 0) + (etal) * numpy.logical_not((dCd < 0)) J_TRPN = dCaTrpn_dt * trpnmax - h_lambda = (h_lambda_prima) * (h_lambda_prima > 0) + (0) * numpy.logical_not( - (h_lambda_prima > 0), - ) + # h_lambda = (h_lambda_prima) * (h_lambda_prima > 0) + (0) * numpy.logical_not( + # (h_lambda_prima > 0), + # ) Jrel_inf = ((-ICaL) * a_rel) / (((1.5 * scale_HF_Jrel_inf) / cajsr) ** 8.0 + 1.0) Jrel_infp = ((-ICaL) * a_relp) / (((1.5 * scale_HF_Jrel_inf) / cajsr) ** 8.0 + 1.0) dcajsr_dt = Bcajsr * (-Jrel + Jtr) - values[36] = dcajsr_dt + values[36] = cajsr + dcajsr_dt * dt dcansr_dt = Jup - (Jtr * vjsr) / vnsr - values[37] = dcansr_dt + values[37] = cansr + dcansr_dt * dt JnakNa = 3.0 * (E1 * a3 - E2 * b3) JnakK = 2.0 * (-E3 * a1 + E4 * b1) dkss_dt = -JdiffK + (Acap * (-ICaK)) / ((F * vss)) - values[38] = dkss_dt + values[38] = dkss_dt * dt + kss k4 = k4p_ss + k4pp k4_i = k4p_i + k4pp_i k3 = k3p_ss + k3pp k3_i = k3p_i + k3pp_i - Fd = dCd * eta + # Fd = dCd * eta dCd_dt = (p_k * (C - Cd)) / eta - values[39] = dCd_dt - Ta = (h_lambda * (Tref / rs)) * (XS * (Zetas + 1) + XW * Zetaw) + dCd_dt_linearized = -p_k / eta + values[39] = ( + Cd + + dCd_dt + * (numpy.exp(dCd_dt_linearized * dt) - 1) + / dCd_dt_linearized + * (numpy.abs(dCd_dt_linearized) > 1e-08) + + dCd_dt * dt * (~(numpy.abs(dCd_dt_linearized) > 1e-08)) + ) + # Ta = (h_lambda * (Tref / rs)) * (XS * (Zetas + 1) + XW * Zetaw) dJrelnp_dt = (Jrel_inf - Jrelnp) / tau_rel - values[40] = dJrelnp_dt + dJrelnp_dt_linearized = -1 / tau_rel + values[40] = ( + Jrelnp + + dJrelnp_dt + * (numpy.exp(dJrelnp_dt_linearized * dt) - 1) + / dJrelnp_dt_linearized + ) dJrelp_dt = (Jrel_infp - Jrelp) / tau_relp - values[41] = dJrelp_dt - INaK = (Pnak * scale_HF_Pnak) * (JnakK * zk + JnakNa * zna) - x2_ss = (k1 * k7) * (k4 + k5) + (k4 * k6) * (k1 + k8) - x2_i = (k1_i * k7_i) * (k4_i + k5_i) + (k4_i * k6_i) * (k1_i + k8_i) - x1_ss = (k2 * k4) * (k6 + k7) + (k5 * k7) * (k2 + k3) - x3_ss = (k1 * k3) * (k6 + k7) + (k6 * k8) * (k2 + k3) - x4_ss = (k2 * k8) * (k4 + k5) + (k3 * k5) * (k1 + k8) - x1_i = (k2_i * k4_i) * (k6_i + k7_i) + (k5_i * k7_i) * (k2_i + k3_i) - x3_i = (k1_i * k3_i) * (k6_i + k7_i) + (k6_i * k8_i) * (k2_i + k3_i) - x4_i = (k2_i * k8_i) * (k4_i + k5_i) + (k3_i * k5_i) * (k1_i + k8_i) - Tp = p_a * (F1 + Fd) - dki_dt = ( - Acap - * ( - -( - -2.0 * INaK - + ( - Istim - + (Isac_P_ns / 3 + (Isac_P_k + (IKb + (IK1 + (IKs + (IKr + Ito)))))) - ) - ) - ) - ) / ((F * vmyo)) + (JdiffK * vss) / vmyo - values[42] = dki_dt - E1_ss = x1_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) - E2_ss = x2_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) - E3_ss = x3_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) - E4_ss = x4_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) - E1_i = x1_i / (x4_i + (x3_i + (x1_i + x2_i))) - E2_i = x2_i / (x4_i + (x3_i + (x1_i + x2_i))) - E3_i = x3_i / (x4_i + (x3_i + (x1_i + x2_i))) - E4_i = x4_i / (x4_i + (x3_i + (x1_i + x2_i))) - Ttot = Ta + Tp - JncxCa_ss = -E1_ss * k1 + E2_ss * k2 - JncxNa_ss = -E2_ss * k3pp + (E3_ss * k4pp + 3.0 * (-E1_ss * k8 + E4_ss * k7)) - JncxCa_i = -E1_i * k1_i + E2_i * k2_i - JncxNa_i = -E2_i * k3pp_i + (E3_i * k4pp_i + 3.0 * (-E1_i * k8_i + E4_i * k7_i)) - INaCa_ss = (allo_ss * ((0.2 * Gncx) * scale_HF_Gncx)) * ( - JncxCa_ss * zca + JncxNa_ss * zna - ) - INaCa_i = (allo_i * ((0.8 * Gncx) * scale_HF_Gncx)) * ( - JncxCa_i * zca + JncxNa_i * zna - ) - dcass_dt = Bcass * ( - -Jdiff - + ( - (Acap * (-(ICaL - 2.0 * INaCa_ss))) / (((2.0 * F) * vss)) - + (Jrel * vjsr) / vss - ) - ) - values[43] = dcass_dt - dnass_dt = -JdiffNa + (Acap * (-(ICaNa + 3.0 * INaCa_ss))) / ((F * vss)) - values[44] = dnass_dt - dcai_dt = Bcai * ( - -J_TRPN - + ( - ( - (Acap * (-(Isac_P_ns / 3 + (-2.0 * INaCa_i + (ICab + IpCa))))) - / (((2.0 * F) * vmyo)) - - (Jup * vnsr) / vmyo - ) - + (Jdiff * vss) / vmyo - ) - ) - values[45] = dcai_dt - dnai_dt = ( - Acap - * (-(Isac_P_ns / 3 + (INab + (3.0 * INaK + (3.0 * INaCa_i + (INa + INaL)))))) - ) / ((F * vmyo)) + (JdiffNa * vss) / vmyo - values[46] = dnai_dt - dv_dt = -( - Isac_P_k - + ( - Isac_P_ns - + ( - Istim - + ( - ICab - + ( - IpCa - + ( - IKb - + ( - INab - + ( - INaK - + ( - INaCa_ss - + ( - INaCa_i - + ( - IK1 - + ( - IKs - + ( - IKr - + ( - ICaK - + ( - ICaNa - + ( - ICaL - + ( - Ito - + (INa + INaL) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - values[47] = dv_dt - - return values - - -def forward_generalized_rush_larsen(states, t, dt, parameters): - # Assign states - hL = states[0] - a = states[1] - ap = states[2] - d = states[3] - ff = states[4] - fs = states[5] - hf = states[6] - hs = states[7] - m = states[8] - xrf = states[9] - xrs = states[10] - xs1 = states[11] - CaMKt = states[12] - xk1 = states[13] - Zetaw = states[14] - XS = states[15] - XW = states[16] - TmB = states[17] - hLp = states[18] - iF = states[19] - iS = states[20] - fcaf = states[21] - fcas = states[22] - jca = states[23] - j = states[24] - fcafp = states[25] - ffp = states[26] - hsp = states[27] - jp = states[28] - mL = states[29] - xs2 = states[30] - Zetas = states[31] - nca = states[32] - CaTrpn = states[33] - iFp = states[34] - iSp = states[35] - cajsr = states[36] - cansr = states[37] - kss = states[38] - Cd = states[39] - Jrelnp = states[40] - Jrelp = states[41] - ki = states[42] - cass = states[43] - nass = states[44] - cai = states[45] - nai = states[46] - v = states[47] - - # Assign parameters - Aff = parameters[0] - Ahf = parameters[1] - BSLmax = parameters[2] - BSRmax = parameters[3] - Beta0 = parameters[4] - Beta1 = parameters[5] - CaMKo = parameters[6] - Esac_ns = parameters[7] - F = parameters[8] - GKb = parameters[9] - GNa = parameters[10] - Gncx = parameters[11] - GpCa = parameters[12] - Gsac_k = parameters[13] - Gsac_ns = parameters[14] - Gto = parameters[15] - H = parameters[16] - Khp = parameters[17] - Kki = parameters[18] - Kko = parameters[19] - KmBSL = parameters[20] - KmBSR = parameters[21] - KmCaAct = parameters[22] - KmCaM = parameters[23] - KmCaMK = parameters[24] - Kmgatp = parameters[25] - Kmn = parameters[26] - Knai0 = parameters[27] - Knao0 = parameters[28] - Knap = parameters[29] - Kxkur = parameters[30] - L = parameters[31] - MgADP = parameters[32] - MgATP = parameters[33] - PCab = parameters[34] - PKNa = parameters[35] - PNab = parameters[36] - Pnak = parameters[37] - R = parameters[38] - T = parameters[39] - Tot_A = parameters[40] - Tref = parameters[41] - Trpn50 = parameters[42] - aCaMK = parameters[43] - amp = parameters[44] - bCaMK = parameters[45] - bt = parameters[46] - calib = parameters[47] - cao = parameters[48] - cat50_ref = parameters[49] - celltype = parameters[50] - cmdnmax = parameters[51] - csqnmax = parameters[52] - dLambda = parameters[53] - delta = parameters[54] - delta_epi = parameters[55] - duration = parameters[56] - eP = parameters[57] - emcoupling = parameters[58] - etal = parameters[59] - etas = parameters[60] - gammas = parameters[61] - gammaw = parameters[62] - isacs = parameters[63] - k1m = parameters[64] - k1p = parameters[65] - k2m = parameters[66] - k2n = parameters[67] - k2p = parameters[68] - k3m = parameters[69] - k3p = parameters[70] - k4m = parameters[71] - k4p = parameters[72] - kasymm = parameters[73] - kcaoff = parameters[74] - kcaon = parameters[75] - kmcmdn = parameters[76] - kmcsqn = parameters[77] - kmtrpn = parameters[78] - kna1 = parameters[79] - kna2 = parameters[80] - kna3 = parameters[81] - ko = parameters[82] - ktrpn = parameters[83] - ku = parameters[84] - kuw = parameters[85] - kws = parameters[86] - lambda_max = parameters[87] - lmbda = parameters[88] - mode = parameters[89] - nao = parameters[90] - ntm = parameters[91] - ntrpn = parameters[92] - p_a = parameters[93] - p_b = parameters[94] - p_k = parameters[95] - phi = parameters[96] - qca = parameters[97] - qna = parameters[98] - rad = parameters[99] - rs = parameters[100] - rw = parameters[101] - scale_HF_CaMKa = parameters[102] - scale_HF_GK1 = parameters[103] - scale_HF_GNaL = parameters[104] - scale_HF_Gncx = parameters[105] - scale_HF_Gto = parameters[106] - scale_HF_Jleak = parameters[107] - scale_HF_Jrel_inf = parameters[108] - scale_HF_Jup = parameters[109] - scale_HF_Pnak = parameters[110] - scale_HF_cat50_ref = parameters[111] - scale_HF_thL = parameters[112] - scale_ICaL = parameters[113] - scale_IK1 = parameters[114] - scale_IKr = parameters[115] - scale_IKs = parameters[116] - scale_INaL = parameters[117] - scale_drug_ICaL = parameters[118] - scale_drug_ICab = parameters[119] - scale_drug_IK1 = parameters[120] - scale_drug_IKb = parameters[121] - scale_drug_IKr = parameters[122] - scale_drug_IKs = parameters[123] - scale_drug_INa = parameters[124] - scale_drug_INaL = parameters[125] - scale_drug_INab = parameters[126] - scale_drug_IpCa = parameters[127] - scale_drug_Isack = parameters[128] - scale_drug_Isacns = parameters[129] - scale_drug_Ito = parameters[130] - thL = parameters[131] - tjca = parameters[132] - trpnmax = parameters[133] - wca = parameters[134] - wna = parameters[135] - wnaca = parameters[136] - zca = parameters[137] - zk = parameters[138] - - # Assign expressions - values = numpy.zeros_like(states) - zna = 1.0 - Isac_P_k = 0 - Isac_P_ns = 0 - Afcaf = 0.3 + 0.6 / (numpy.exp((v - 10.0) / 10.0) + 1.0) - AiF = 1.0 / (numpy.exp((v - 213.6) / 151.2) + 1.0) - Axrf = 1.0 / (numpy.exp((v + 54.81) / 38.21) + 1.0) - ass = 1.0 / (numpy.exp((-(v - 14.34)) / 14.82) + 1.0) - assp = 1.0 / (numpy.exp((-(v - 24.34)) / 14.82) + 1.0) - dss = 1.0 / (numpy.exp((-(v + 3.94)) / 4.23) + 1.0) - dti_develop = 1.354 + 0.0001 / ( - numpy.exp((-(v - 12.23)) / 0.2154) + numpy.exp((v - 167.4) / 15.89) - ) - dti_recover = 1.0 - 0.5 / (numpy.exp((v + 70.0) / 20.0) + 1.0) - fss = 1.0 / (numpy.exp((v + 19.58) / 3.696) + 1.0) - hLss = 1.0 / (numpy.exp((v + 87.61) / 7.488) + 1.0) - hLssp = 1.0 / (numpy.exp((v + 93.81) / 7.488) + 1.0) - hss = 1.0 / (numpy.exp((v + 78.5) / 6.22) + 1) - hssp = 1.0 / (numpy.exp(((v + 78.5) + 6.2) / 6.22) + 1) - iss = 1.0 / (numpy.exp((v + 43.94) / 5.711) + 1.0) - mLss = 1.0 / (numpy.exp((-(v + 42.85)) / 5.264) + 1.0) - mss = 1.0 / (numpy.exp((-((v + 39.57) + 9.4)) / 7.5) + 1.0) - rkr = (1.0 * (1.0 / (numpy.exp((v + 55.0) / 75.0) + 1.0))) / ( - numpy.exp((v - 10.0) / 30.0) + 1.0 - ) - ta = 1.0515 / ( - 1.0 / ((1.2089 * (numpy.exp((-(v - 18.4099)) / 29.3814) + 1.0))) - + 3.5 / (numpy.exp((v + 100.0) / 29.3814) + 1.0) - ) - td = 0.6 + 1.0 / (numpy.exp((-0.05) * (v + 6.0)) + numpy.exp(0.09 * (v + 14.0))) - tfcaf = 7.0 + 1.0 / ( - 0.04 * numpy.exp((-(v - 4.0)) / 7.0) + 0.04 * numpy.exp((v - 4.0) / 7.0) - ) - tfcas = 100.0 + 1.0 / ( - 0.00012 * numpy.exp((-v) / 3.0) + 0.00012 * numpy.exp(v / 7.0) - ) - tff = 7.0 + 1.0 / ( - 0.0045 * numpy.exp((-(v + 20.0)) / 10.0) + 0.0045 * numpy.exp((v + 20.0) / 10.0) - ) - tfs = 1000.0 + 1.0 / ( - 3.5e-05 * numpy.exp((-(v + 5.0)) / 4.0) + 3.5e-05 * numpy.exp((v + 5.0) / 6.0) - ) - thf = 1.0 / ( - 6.149 * numpy.exp((v + 0.5096) / 20.27) - + 1.432e-05 * numpy.exp((-(v + 1.196)) / 6.285) - ) - ths = 1.0 / ( - 0.009794 * numpy.exp((-(v + 17.95)) / 28.05) - + 0.3343 * numpy.exp((v + 5.73) / 56.66) - ) - tj = 2.038 + 1.0 / ( - 0.3052 * numpy.exp((v + 0.9941) / 38.45) - + 0.02136 * numpy.exp((-(v + 100.6)) / 8.281) - ) - tm = 1.0 / ( - 6.765 * numpy.exp((v + 11.64) / 34.77) - + 8.552 * numpy.exp((-(v + 77.42)) / 5.955) - ) - txk1 = 122.2 / (numpy.exp((-(v + 127.2)) / 20.36) + numpy.exp((v + 236.8) / 69.33)) - txrf = 12.98 + 1.0 / ( - 4.123e-05 * numpy.exp((-(v - 47.78)) / 20.38) - + 0.3652 * numpy.exp((v - 31.66) / 3.869) - ) - txrs = 1.865 + 1.0 / ( - 1.128e-05 * numpy.exp((-(v - 29.74)) / 25.94) - + 0.06629 * numpy.exp((v - 34.7) / 7.355) - ) - txs1 = 817.3 + 1.0 / ( - 0.0002326 * numpy.exp((v + 48.28) / 17.8) - + 0.001292 * numpy.exp((-(v + 210.0)) / 230.0) - ) - txs2 = 1.0 / ( - 0.01 * numpy.exp((v - 50.0) / 20.0) + 0.0193 * numpy.exp((-(v + 66.54)) / 31.0) - ) - xkb = 1.0 / (numpy.exp((-(v - 14.48)) / 18.34) + 1.0) - xrss = 1.0 / (numpy.exp((-(v + 8.337)) / 6.789) + 1.0) - xs1ss = 1.0 / (numpy.exp((-(v + 11.6)) / 8.932) + 1.0) - Afs = 1.0 - Aff - Ageo = L * ((2 * 3.14) * rad) + rad * ((2 * 3.14) * rad) - vcell = L * (rad * ((3.14 * 1000) * rad)) - Ahs = 1.0 - Ahf - Aw = (Tot_A * rs) / (rs + rw * (1 - rs)) - Jupnp = (0.004375 * cai) / (cai + 0.00092) - Jupp = ((0.004375 * 2.75) * cai) / ((cai + 0.00092) - 0.00017) - KsCa = 1.0 + 0.6 / ((3.8e-05 / cai) ** 1.4 + 1.0) - Bcai = 1.0 / ((cmdnmax * kmcmdn) / (cai + kmcmdn) ** 2.0 + 1.0) - Bcajsr = 1.0 / ((csqnmax * kmcsqn) / (cajsr + kmcsqn) ** 2.0 + 1.0) - Jdiff = (-cai + cass) / 0.2 - Bcass = 1.0 / ( - (BSLmax * KmBSL) / (KmBSL + cass) ** 2.0 - + ((BSRmax * KmBSR) / (KmBSR + cass) ** 2.0 + 1.0) - ) - CaMKb = (CaMKo * (1.0 - CaMKt)) / (KmCaM / cass + 1.0) - CaTrpn_max = (CaTrpn) * (CaTrpn > 0) + (0) * numpy.logical_not((CaTrpn > 0)) - vffrt = (F * (F * v)) / ((R * T)) - vfrt = (F * v) / ((R * T)) - EK = ((R * T) / F) * numpy.log(ko / ki) - rk1 = 1.0 / (numpy.exp((-2.6 * ko + (v + 105.8)) / 9.493) + 1.0) - xk1ss = 1.0 / ( - numpy.exp((-((2.5538 * ko + v) + 144.59)) / (1.5692 * ko + 3.8115)) + 1.0 - ) - ENa = ((R * T) / F) * numpy.log(nao / nai) - EKs = ((R * T) / F) * numpy.log((PKNa * nao + ko) / (PKNa * nai + ki)) - GK1 = scale_HF_GK1 * ((0.1908 * scale_IK1) * scale_drug_IK1) - GKr = (0.046 * scale_IKr) * scale_drug_IKr - GKs = (0.0034 * scale_IKs) * scale_drug_IKs - GNaL = scale_HF_GNaL * ((0.0075 * scale_INaL) * scale_drug_INaL) - km2n = 1.0 * jca - IpCa = (cai * (GpCa * scale_drug_IpCa)) / (cai + 0.0005) - Istim = (amp) * (duration >= t) + (0) * numpy.logical_not((duration >= t)) - JdiffK = (-ki + kss) / 2.0 - JdiffNa = (-nai + nass) / 2.0 - Jtr = (-cajsr + cansr) / 100.0 - Jleak = ((0.0039375 * cansr) * scale_HF_Jleak) / 15.0 - Knai = Knai0 * numpy.exp((F * (delta * v)) / (((3.0 * R) * T))) - Knao = Knao0 * numpy.exp((F * (v * (1.0 - delta))) / (((3.0 * R) * T))) - P = eP / (((H / Khp + 1.0) + nai / Knap) + ki / Kxkur) - PCa = (0.0001 * scale_ICaL) * scale_drug_ICaL - XW_max = (XW) * (XW > 0) + (0) * numpy.logical_not((XW > 0)) - XS_max = (XS) * (XS > 0) + (0) * numpy.logical_not((XS > 0)) - XU = -XW + (-XS + (1 - TmB)) - a2 = k2p - a4 = ((MgATP * k4p) / Kmgatp) / (1.0 + MgATP / Kmgatp) - a_rel = 0.5 * bt - btp = 1.25 * bt - tau_rel_tmp = bt / (1.0 + 0.0123 / cajsr) - allo_i = 1.0 / ((KmCaAct / cai) ** 2.0 + 1.0) - allo_ss = 1.0 / ((KmCaAct / cass) ** 2.0 + 1.0) - b1 = MgADP * k1m - cs = ((kws * phi) * (rw * (1 - rs))) / rs - ksu = (kws * rw) * (-1 + 1 / rs) - cw = ((kuw * phi) * ((1 - rs) * (1 - rw))) / ((rw * (1 - rs))) - kwu = kuw * (-1 + 1 / rw) - kws - gammasu = ( - gammas * Zetas * 1 * (Zetas > 0) - + 0 - * (~(Zetas > 0)) - * numpy.logical_and.reduce( - ( - numpy.logical_or((Zetas > -1), (Zetas > 0)), - numpy.logical_or((Zetas > 0), (Zetas < -1)), - numpy.logical_or.reduce( - ((Zetas >= -1), (Zetas <= 0), (Zetas > -1 / 2)), - ), - ), - ) - + (-Zetas - 1) * 1 * (Zetas < -1) - + 0 - * (~(Zetas < -1)) - * ( - ~numpy.logical_and.reduce( - ( - numpy.logical_or((Zetas > -1), (Zetas > 0)), - numpy.logical_or((Zetas > 0), (Zetas < -1)), - numpy.logical_or.reduce( - ((Zetas >= -1), (Zetas <= 0), (Zetas > -1 / 2)), - ), - ), - ) - ) - ) - gammawu = gammaw * numpy.abs(Zetaw) - h10 = (nao / kna1) * (1 + nao / kna2) + (kasymm + 1.0) - h10_i = (nao / kna1) * (1.0 + nao / kna2) + (kasymm + 1.0) - h4 = (nass / kna1) * (1 + nass / kna2) + 1.0 - h4_i = (nai / kna1) * (1 + nai / kna2) + 1.0 - hca = numpy.exp((F * (qca * v)) / ((R * T))) - hna = numpy.exp((F * (qna * v)) / ((R * T))) - k2 = kcaoff - k2_i = kcaoff - k5 = kcaoff - k5_i = kcaoff - kb = (Trpn50**ntm * ku) / (-rw * (1 - rs) + (1 - rs)) - lambda_min12 = (lmbda) * (lmbda < 1.2) + (1.2) * numpy.logical_not((lmbda < 1.2)) - thLp = scale_HF_thL * (3.0 * thL) - tiF = ( - delta_epi - * ( - 1 - / ( - 0.3933 * numpy.exp((-(v + 100.0)) / 100.0) - + 0.08004 * numpy.exp((v + 50.0) / 16.59) - ) - ) - + 4.562 - ) - tiS = ( - delta_epi - * ( - 1 - / ( - 0.001416 * numpy.exp((-(v + 96.52)) / 59.05) - + 1.78e-08 * numpy.exp((v + 114.1) / 8.079) - ) - ) - + 23.62 - ) - Afcas = 1.0 - Afcaf - AiS = 1.0 - AiF - Axrs = 1.0 - Axrf - fcass = fss - dhL_dt = (-hL + hLss) / ((scale_HF_thL * thL)) - dhL_dt_linearized = -1 / (scale_HF_thL * thL) - values[0] = ( - dhL_dt * (numpy.exp(dhL_dt_linearized * dt) - 1) / dhL_dt_linearized + hL - ) - jss = hss - da_dt = (-a + ass) / ta - da_dt_linearized = -1 / ta - values[1] = a + da_dt * (numpy.exp(da_dt_linearized * dt) - 1) / da_dt_linearized - dap_dt = (-ap + assp) / ta - dap_dt_linearized = -1 / ta - values[2] = ( - ap + dap_dt * (numpy.exp(dap_dt_linearized * dt) - 1) / dap_dt_linearized - ) - dd_dt = (-d + dss) / td - dd_dt_linearized = -1 / td - values[3] = d + dd_dt * (numpy.exp(dd_dt_linearized * dt) - 1) / dd_dt_linearized - tfcafp = 2.5 * tfcaf - tffp = 2.5 * tff - dff_dt = (-ff + fss) / tff - dff_dt_linearized = -1 / tff - values[4] = ( - dff_dt * (numpy.exp(dff_dt_linearized * dt) - 1) / dff_dt_linearized + ff - ) - dfs_dt = (-fs + fss) / tfs - dfs_dt_linearized = -1 / tfs - values[5] = ( - dfs_dt * (numpy.exp(dfs_dt_linearized * dt) - 1) / dfs_dt_linearized + fs - ) - dhf_dt = (-hf + hss) / thf - dhf_dt_linearized = -1 / thf - values[6] = ( - dhf_dt * (numpy.exp(dhf_dt_linearized * dt) - 1) / dhf_dt_linearized + hf - ) - thsp = 3.0 * ths - dhs_dt = (-hs + hss) / ths - dhs_dt_linearized = -1 / ths - values[7] = ( - dhs_dt * (numpy.exp(dhs_dt_linearized * dt) - 1) / dhs_dt_linearized + hs - ) - tjp = 1.46 * tj - tmL = tm - dm_dt = (-m + mss) / tm - dm_dt_linearized = -1 / tm - values[8] = dm_dt * (numpy.exp(dm_dt_linearized * dt) - 1) / dm_dt_linearized + m - dxrf_dt = (-xrf + xrss) / txrf - dxrf_dt_linearized = -1 / txrf - values[9] = ( - dxrf_dt * (numpy.exp(dt * dxrf_dt_linearized) - 1) / dxrf_dt_linearized + xrf - ) - dxrs_dt = (-xrs + xrss) / txrs - dxrs_dt_linearized = -1 / txrs - values[10] = ( - dxrs_dt * (numpy.exp(dt * dxrs_dt_linearized) - 1) / dxrs_dt_linearized + xrs - ) - xs2ss = xs1ss - dxs1_dt = (-xs1 + xs1ss) / txs1 - dxs1_dt_linearized = -1 / txs1 - values[11] = ( - dxs1_dt * (numpy.exp(dt * dxs1_dt_linearized) - 1) / dxs1_dt_linearized + xs1 - ) - f = Aff * ff + Afs * fs - fp = Aff * ffp + Afs * fs - Acap = 2 * Ageo - vjsr = 0.0048 * vcell - vmyo = 0.68 * vcell - vnsr = 0.0552 * vcell - vss = 0.02 * vcell - h = Ahf * hf + Ahs * hs - hp = Ahf * hf + Ahs * hsp - As = Aw - CaMKa = scale_HF_CaMKa * (CaMKb + CaMKt) - dCaMKt_dt = -CaMKt * bCaMK + (CaMKb * aCaMK) * (CaMKb + CaMKt) - dCaMKt_dt_linearized = CaMKb * aCaMK - bCaMK - values[12] = ( - CaMKt - + dCaMKt_dt - * (numpy.exp(dCaMKt_dt_linearized * dt) - 1) - / dCaMKt_dt_linearized - * (numpy.abs(dCaMKt_dt_linearized) > 1e-08) - + dCaMKt_dt * dt * (~(numpy.abs(dCaMKt_dt_linearized) > 1e-08)) - ) - ICab = ( - (vffrt * (4.0 * (PCab * scale_drug_ICab))) - * (cai * numpy.exp(2.0 * vfrt) - 0.341 * cao) - ) / (numpy.exp(2.0 * vfrt) - 1.0) - INab = ((vffrt * (PNab * scale_drug_INab)) * (nai * numpy.exp(vfrt) - nao)) / ( - numpy.exp(vfrt) - 1.0 - ) - PhiCaK = ((1.0 * vffrt) * (-0.75 * ko + (0.75 * kss) * numpy.exp(1.0 * vfrt))) / ( - numpy.exp(1.0 * vfrt) - 1.0 - ) - PhiCaL = ((4.0 * vffrt) * (-0.341 * cao + cass * numpy.exp(2.0 * vfrt))) / ( - numpy.exp(2.0 * vfrt) - 1.0 - ) - PhiCaNa = ( - (1.0 * vffrt) * (-0.75 * nao + (0.75 * nass) * numpy.exp(1.0 * vfrt)) - ) / (numpy.exp(1.0 * vfrt) - 1.0) - IKb = (xkb * (GKb * scale_drug_IKb)) * (-EK + v) - dxk1_dt = (-xk1 + xk1ss) / txk1 - dxk1_dt_linearized = -1 / txk1 - values[13] = ( - dxk1_dt * (numpy.exp(dt * dxk1_dt_linearized) - 1) / dxk1_dt_linearized + xk1 - ) - IK1 = (xk1 * (rk1 * (GK1 * math.sqrt(ko)))) * (-EK + v) - IKs = (xs2 * (xs1 * (GKs * KsCa))) * (-EKs + v) - anca = 1.0 / (k2n / km2n + (Kmn / cass + 1.0) ** 4.0) - a1 = (k1p * (nai / Knai) ** 3.0) / ( - ((1.0 + ki / Kki) ** 2.0 + (1.0 + nai / Knai) ** 3.0) - 1.0 - ) - b4 = (k4m * (ki / Kki) ** 2.0) / ( - ((1.0 + ki / Kki) ** 2.0 + (1.0 + nai / Knai) ** 3.0) - 1.0 - ) - a3 = (k3p * (ko / Kko) ** 2.0) / ( - ((1.0 + ko / Kko) ** 2.0 + (1.0 + nao / Knao) ** 3.0) - 1.0 - ) - b2 = (k2m * (nao / Knao) ** 3.0) / ( - ((1.0 + ko / Kko) ** 2.0 + (1.0 + nao / Knao) ** 3.0) - 1.0 - ) - b3 = (H * (P * k3m)) / (1.0 + MgATP / Kmgatp) - PCaK = 0.0003574 * PCa - PCaNa = 0.00125 * PCa - PCap = 1.1 * PCa - a_relp = 0.5 * btp - tau_relp_tmp = btp / (1.0 + 0.0123 / cajsr) - tau_rel = (0.001) * (tau_rel_tmp < 0.001) + (tau_rel_tmp) * numpy.logical_not( - (tau_rel_tmp < 0.001), - ) - dZetaw_dt = Aw * dLambda - Zetaw * cw - dZetaw_dt_linearized = -cw - values[14] = ( - Zetaw - + dZetaw_dt - * (numpy.exp(dZetaw_dt_linearized * dt) - 1) - / dZetaw_dt_linearized - * (numpy.abs(dZetaw_dt_linearized) > 1e-08) - + dZetaw_dt * dt * (~(numpy.abs(dZetaw_dt_linearized) > 1e-08)) - ) - dXS_dt = -XS * gammasu + (-XS * ksu + XW * kws) - dXS_dt_linearized = -gammasu - ksu - values[15] = ( - XS - + dXS_dt - * (numpy.exp(dXS_dt_linearized * dt) - 1) - / dXS_dt_linearized - * (numpy.abs(dXS_dt_linearized) > 1e-08) - + dXS_dt * dt * (~(numpy.abs(dXS_dt_linearized) > 1e-08)) - ) - dXW_dt = -XW * gammawu + (-XW * kws + (XU * kuw - XW * kwu)) - dXW_dt_linearized = -gammawu - kws - kwu - values[16] = ( - XW - + dXW_dt - * (numpy.exp(dXW_dt_linearized * dt) - 1) - / dXW_dt_linearized - * (numpy.abs(dXW_dt_linearized) > 1e-08) - + dXW_dt * dt * (~(numpy.abs(dXW_dt_linearized) > 1e-08)) - ) - h11 = (nao * nao) / ((kna2 * (h10 * kna1))) - h12 = 1.0 / h10 - h11_i = (nao * nao) / ((kna2 * (h10_i * kna1))) - h12_i = 1.0 / h10_i - h5 = (nass * nass) / ((kna2 * (h4 * kna1))) - h6 = 1.0 / h4 - h5_i = (nai * nai) / ((kna2 * (h4_i * kna1))) - h6_i = 1.0 / h4_i - h1 = (nass / kna3) * (hna + 1) + 1 - h1_i = (nai / kna3) * (hna + 1) + 1 - h7 = (nao / kna3) * (1.0 + 1.0 / hna) + 1.0 - h7_i = (nao / kna3) * (1.0 + 1.0 / hna) + 1.0 - dTmB_dt = -TmB * CaTrpn ** (ntm / 2) * ku + XU * ( - kb * CaTrpn ** ((-ntm) / 2) * (CaTrpn ** ((-ntm) / 2) < 100) - + 100 * (~(CaTrpn ** ((-ntm) / 2) < 100)) - ) - dTmB_dt_linearized = -(CaTrpn ** (ntm / 2)) * ku - values[17] = ( - TmB - + dTmB_dt - * (numpy.exp(dTmB_dt_linearized * dt) - 1) - / dTmB_dt_linearized - * (numpy.abs(dTmB_dt_linearized) > 1e-08) - + dTmB_dt * dt * (~(numpy.abs(dTmB_dt_linearized) > 1e-08)) - ) - C = lambda_min12 - 1 - cat50 = scale_HF_cat50_ref * (Beta1 * (lambda_min12 - 1) + cat50_ref) - lambda_min087 = (lambda_min12) * (lambda_min12 < 0.87) + (0.87) * numpy.logical_not( - (lambda_min12 < 0.87), - ) - dhLp_dt = (-hLp + hLssp) / thLp - dhLp_dt_linearized = -1 / thLp - values[18] = ( - dhLp_dt * (numpy.exp(dhLp_dt_linearized * dt) - 1) / dhLp_dt_linearized + hLp - ) - tiFp = tiF * (dti_develop * dti_recover) - diF_dt = (-iF + iss) / tiF - diF_dt_linearized = -1 / tiF - values[19] = ( - diF_dt * (numpy.exp(diF_dt_linearized * dt) - 1) / diF_dt_linearized + iF - ) - tiSp = tiS * (dti_develop * dti_recover) - diS_dt = (-iS + iss) / tiS - diS_dt_linearized = -1 / tiS - values[20] = ( - diS_dt * (numpy.exp(diS_dt_linearized * dt) - 1) / diS_dt_linearized + iS - ) - fca = Afcaf * fcaf + Afcas * fcas - fcap = Afcaf * fcafp + Afcas * fcas - i = AiF * iF + AiS * iS - ip = AiF * iFp + AiS * iSp - xr = Axrf * xrf + Axrs * xrs - dfcaf_dt = (-fcaf + fcass) / tfcaf - dfcaf_dt_linearized = -1 / tfcaf - values[21] = ( - dfcaf_dt * (numpy.exp(dfcaf_dt_linearized * dt) - 1) / dfcaf_dt_linearized - + fcaf - ) - dfcas_dt = (-fcas + fcass) / tfcas - dfcas_dt_linearized = -1 / tfcas - values[22] = ( - dfcas_dt * (numpy.exp(dfcas_dt_linearized * dt) - 1) / dfcas_dt_linearized - + fcas - ) - djca_dt = (fcass - jca) / tjca - djca_dt_linearized = -1 / tjca - values[23] = ( - djca_dt * (numpy.exp(djca_dt_linearized * dt) - 1) / djca_dt_linearized + jca - ) - dj_dt = (-j + jss) / tj - dj_dt_linearized = -1 / tj - values[24] = dj_dt * (numpy.exp(dj_dt_linearized * dt) - 1) / dj_dt_linearized + j - dfcafp_dt = (-fcafp + fcass) / tfcafp - dfcafp_dt_linearized = -1 / tfcafp - values[25] = ( - dfcafp_dt * (numpy.exp(dfcafp_dt_linearized * dt) - 1) / dfcafp_dt_linearized - + fcafp - ) - dffp_dt = (-ffp + fss) / tffp - dffp_dt_linearized = -1 / tffp - values[26] = ( - dffp_dt * (numpy.exp(dffp_dt_linearized * dt) - 1) / dffp_dt_linearized + ffp - ) - dhsp_dt = (-hsp + hssp) / thsp - dhsp_dt_linearized = -1 / thsp - values[27] = ( - dhsp_dt * (numpy.exp(dhsp_dt_linearized * dt) - 1) / dhsp_dt_linearized + hsp - ) - djp_dt = (-jp + jss) / tjp - djp_dt_linearized = -1 / tjp - values[28] = ( - djp_dt * (numpy.exp(djp_dt_linearized * dt) - 1) / djp_dt_linearized + jp - ) - dmL_dt = (-mL + mLss) / tmL - dmL_dt_linearized = -1 / tmL - values[29] = ( - dmL_dt * (numpy.exp(dmL_dt_linearized * dt) - 1) / dmL_dt_linearized + mL - ) - dxs2_dt = (-xs2 + xs2ss) / txs2 - dxs2_dt_linearized = -1 / txs2 - values[30] = ( - dxs2_dt * (numpy.exp(dt * dxs2_dt_linearized) - 1) / dxs2_dt_linearized + xs2 - ) - dZetas_dt = As * dLambda - Zetas * cs - dZetas_dt_linearized = -cs - values[31] = ( - Zetas - + dZetas_dt - * (numpy.exp(dZetas_dt_linearized * dt) - 1) - / dZetas_dt_linearized - * (numpy.abs(dZetas_dt_linearized) > 1e-08) - + dZetas_dt * dt * (~(numpy.abs(dZetas_dt_linearized) > 1e-08)) - ) - fICaLp = 1.0 / (1.0 + KmCaMK / CaMKa) - fINaLp = 1.0 / (1.0 + KmCaMK / CaMKa) - fINap = 1.0 / (1.0 + KmCaMK / CaMKa) - fItop = 1.0 / (1.0 + KmCaMK / CaMKa) - fJrelp = 1.0 / (1.0 + KmCaMK / CaMKa) - fJupp = 1.0 / (1.0 + KmCaMK / CaMKa) - dnca_dt = anca * k2n - km2n * nca - dnca_dt_linearized = -km2n - values[32] = ( - nca - + dnca_dt - * (numpy.exp(dnca_dt_linearized * dt) - 1) - / dnca_dt_linearized - * (numpy.abs(dnca_dt_linearized) > 1e-08) - + dnca_dt * dt * (~(numpy.abs(dnca_dt_linearized) > 1e-08)) - ) - x2 = b4 * (a2 * a3) + (b4 * (a3 * b1) + (a3 * (a1 * a2) + b4 * (b1 * b2))) - x1 = a2 * (a1 * b3) + (b3 * (a2 * b4) + (a2 * (a1 * a4) + b3 * (b2 * b4))) - x3 = b1 * (a3 * a4) + (a4 * (b1 * b2) + (a4 * (a2 * a3) + b1 * (b2 * b3))) - x4 = a1 * (b2 * b3) + (a1 * (a4 * b2) + (a1 * (a3 * a4) + b2 * (b3 * b4))) - PCaKp = 0.0003574 * PCap - PCaNap = 0.00125 * PCap - tau_relp = (0.001) * (tau_relp_tmp < 0.001) + (tau_relp_tmp) * numpy.logical_not( - (tau_relp_tmp < 0.001), - ) - k1 = kcaon * (cao * h12) - k1_i = kcaon * (cao * h12_i) - k6 = kcaon * (cass * h6) - k6_i = kcaon * (cai * h6_i) - h2 = (hna * nass) / ((h1 * kna3)) - h3 = 1.0 / h1 - h2_i = (hna * nai) / ((h1_i * kna3)) - h3_i = 1.0 / h1_i - h8 = nao / ((h7 * (hna * kna3))) - h9 = 1.0 / h7 - h8_i = nao / ((h7_i * (hna * kna3))) - h9_i = 1.0 / h7_i - F1 = numpy.exp(C * p_b) - 1 - dCd = C - Cd - dCaTrpn_dt = ktrpn * (-CaTrpn + ((1000 * cai) / cat50) ** ntrpn * (1 - CaTrpn)) - dCaTrpn_dt_linearized = ktrpn * (-(((1000 * cai) / cat50) ** ntrpn) - 1) - values[33] = ( - CaTrpn - + dCaTrpn_dt - * (numpy.exp(dCaTrpn_dt_linearized * dt) - 1) - / dCaTrpn_dt_linearized - * (numpy.abs(dCaTrpn_dt_linearized) > 1e-08) - + dCaTrpn_dt * dt * (~(numpy.abs(dCaTrpn_dt_linearized) > 1e-08)) - ) - h_lambda_prima = Beta0 * ((lambda_min087 + lambda_min12) - 1.87) + 1 - diFp_dt = (-iFp + iss) / tiFp - diFp_dt_linearized = -1 / tiFp - values[34] = ( - diFp_dt * (numpy.exp(diFp_dt_linearized * dt) - 1) / diFp_dt_linearized + iFp - ) - diSp_dt = (-iSp + iss) / tiSp - diSp_dt_linearized = -1 / tiSp - values[35] = ( - diSp_dt * (numpy.exp(diSp_dt_linearized * dt) - 1) / diSp_dt_linearized + iSp - ) - IKr = (rkr * (xr * (GKr * (0.4303314829119352 * math.sqrt(ko))))) * (-EK + v) - ICaL = (d * (PhiCaL * (PCa * (1.0 - fICaLp)))) * ( - f * (1.0 - nca) + nca * (fca * jca) - ) + (d * (PhiCaL * (PCap * fICaLp))) * (fp * (1.0 - nca) + nca * (fcap * jca)) - INaL = (mL * (GNaL * (-ENa + v))) * (fINaLp * hLp + hL * (1.0 - fINaLp)) - INa = (m**3.0 * ((GNa * scale_drug_INa) * (-ENa + v))) * ( - j * (h * (1.0 - fINap)) + jp * (fINap * hp) - ) - Ito = ((scale_HF_Gto * (Gto * scale_drug_Ito)) * (-EK + v)) * ( - i * (a * (1.0 - fItop)) + ip * (ap * fItop) - ) - Jrel = Jrelnp * (1.0 - fJrelp) + Jrelp * fJrelp - Jup = -Jleak + (Jupnp * (1.0 - fJupp) + scale_HF_Jup * (Jupp * fJupp)) - E1 = x1 / (x4 + (x3 + (x1 + x2))) - E2 = x2 / (x4 + (x3 + (x1 + x2))) - E3 = x3 / (x4 + (x3 + (x1 + x2))) - E4 = x4 / (x4 + (x3 + (x1 + x2))) - ICaK = (d * (PhiCaK * (PCaK * (1.0 - fICaLp)))) * ( - f * (1.0 - nca) + nca * (fca * jca) - ) + (d * (PhiCaK * (PCaKp * fICaLp))) * (fp * (1.0 - nca) + nca * (fcap * jca)) - ICaNa = (d * (PhiCaNa * (PCaNa * (1.0 - fICaLp)))) * ( - f * (1.0 - nca) + nca * (fca * jca) - ) + (d * (PhiCaNa * (PCaNap * fICaLp))) * (fp * (1.0 - nca) + nca * (fcap * jca)) - k4pp = h2 * wnaca - k7 = wna * (h2 * h5) - k4p_ss = (h3 * wca) / hca - k4pp_i = h2_i * wnaca - k7_i = wna * (h2_i * h5_i) - k4p_i = (h3_i * wca) / hca - k3pp = h8 * wnaca - k8 = wna * (h11 * h8) - k3p_ss = h9 * wca - k3pp_i = h8_i * wnaca - k8_i = wna * (h11_i * h8_i) - k3p_i = h9_i * wca - eta = (etas) * (dCd < 0) + (etal) * numpy.logical_not((dCd < 0)) - J_TRPN = dCaTrpn_dt * trpnmax - h_lambda = (h_lambda_prima) * (h_lambda_prima > 0) + (0) * numpy.logical_not( - (h_lambda_prima > 0), - ) - Jrel_inf = ((-ICaL) * a_rel) / (((1.5 * scale_HF_Jrel_inf) / cajsr) ** 8.0 + 1.0) - Jrel_infp = ((-ICaL) * a_relp) / (((1.5 * scale_HF_Jrel_inf) / cajsr) ** 8.0 + 1.0) - dcajsr_dt = Bcajsr * (-Jrel + Jtr) - values[36] = cajsr + dcajsr_dt * dt - dcansr_dt = Jup - (Jtr * vjsr) / vnsr - values[37] = cansr + dcansr_dt * dt - JnakNa = 3.0 * (E1 * a3 - E2 * b3) - JnakK = 2.0 * (-E3 * a1 + E4 * b1) - dkss_dt = -JdiffK + (Acap * (-ICaK)) / ((F * vss)) - values[38] = dkss_dt * dt + kss - k4 = k4p_ss + k4pp - k4_i = k4p_i + k4pp_i - k3 = k3p_ss + k3pp - k3_i = k3p_i + k3pp_i - Fd = dCd * eta - dCd_dt = (p_k * (C - Cd)) / eta - dCd_dt_linearized = -p_k / eta - values[39] = ( - Cd - + dCd_dt - * (numpy.exp(dCd_dt_linearized * dt) - 1) - / dCd_dt_linearized - * (numpy.abs(dCd_dt_linearized) > 1e-08) - + dCd_dt * dt * (~(numpy.abs(dCd_dt_linearized) > 1e-08)) - ) - Ta = (h_lambda * (Tref / rs)) * (XS * (Zetas + 1) + XW * Zetaw) - dJrelnp_dt = (Jrel_inf - Jrelnp) / tau_rel - dJrelnp_dt_linearized = -1 / tau_rel - values[40] = ( - Jrelnp - + dJrelnp_dt - * (numpy.exp(dJrelnp_dt_linearized * dt) - 1) - / dJrelnp_dt_linearized - ) - dJrelp_dt = (Jrel_infp - Jrelp) / tau_relp - dJrelp_dt_linearized = -1 / tau_relp - values[41] = ( - Jrelp - + dJrelp_dt * (numpy.exp(dJrelp_dt_linearized * dt) - 1) / dJrelp_dt_linearized - ) - INaK = (Pnak * scale_HF_Pnak) * (JnakK * zk + JnakNa * zna) - x2_ss = (k1 * k7) * (k4 + k5) + (k4 * k6) * (k1 + k8) - x2_i = (k1_i * k7_i) * (k4_i + k5_i) + (k4_i * k6_i) * (k1_i + k8_i) - x1_ss = (k2 * k4) * (k6 + k7) + (k5 * k7) * (k2 + k3) - x3_ss = (k1 * k3) * (k6 + k7) + (k6 * k8) * (k2 + k3) - x4_ss = (k2 * k8) * (k4 + k5) + (k3 * k5) * (k1 + k8) - x1_i = (k2_i * k4_i) * (k6_i + k7_i) + (k5_i * k7_i) * (k2_i + k3_i) - x3_i = (k1_i * k3_i) * (k6_i + k7_i) + (k6_i * k8_i) * (k2_i + k3_i) - x4_i = (k2_i * k8_i) * (k4_i + k5_i) + (k3_i * k5_i) * (k1_i + k8_i) - Tp = p_a * (F1 + Fd) - dki_dt = ( - Acap - * ( - -( - -2.0 * INaK - + ( - Istim - + (Isac_P_ns / 3 + (Isac_P_k + (IKb + (IK1 + (IKs + (IKr + Ito)))))) - ) - ) - ) - ) / ((F * vmyo)) + (JdiffK * vss) / vmyo - values[42] = dki_dt * dt + ki - E1_ss = x1_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) - E2_ss = x2_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) - E3_ss = x3_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) - E4_ss = x4_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) - E1_i = x1_i / (x4_i + (x3_i + (x1_i + x2_i))) - E2_i = x2_i / (x4_i + (x3_i + (x1_i + x2_i))) - E3_i = x3_i / (x4_i + (x3_i + (x1_i + x2_i))) - E4_i = x4_i / (x4_i + (x3_i + (x1_i + x2_i))) - Ttot = Ta + Tp - JncxCa_ss = -E1_ss * k1 + E2_ss * k2 - JncxNa_ss = -E2_ss * k3pp + (E3_ss * k4pp + 3.0 * (-E1_ss * k8 + E4_ss * k7)) - JncxCa_i = -E1_i * k1_i + E2_i * k2_i - JncxNa_i = -E2_i * k3pp_i + (E3_i * k4pp_i + 3.0 * (-E1_i * k8_i + E4_i * k7_i)) - INaCa_ss = (allo_ss * ((0.2 * Gncx) * scale_HF_Gncx)) * ( - JncxCa_ss * zca + JncxNa_ss * zna - ) - INaCa_i = (allo_i * ((0.8 * Gncx) * scale_HF_Gncx)) * ( - JncxCa_i * zca + JncxNa_i * zna - ) - dcass_dt = Bcass * ( - -Jdiff - + ( - (Acap * (-(ICaL - 2.0 * INaCa_ss))) / (((2.0 * F) * vss)) - + (Jrel * vjsr) / vss - ) - ) - values[43] = cass + dcass_dt * dt - dnass_dt = -JdiffNa + (Acap * (-(ICaNa + 3.0 * INaCa_ss))) / ((F * vss)) - values[44] = dnass_dt * dt + nass - dcai_dt = Bcai * ( - -J_TRPN - + ( - ( - (Acap * (-(Isac_P_ns / 3 + (-2.0 * INaCa_i + (ICab + IpCa))))) - / (((2.0 * F) * vmyo)) - - (Jup * vnsr) / vmyo - ) - + (Jdiff * vss) / vmyo - ) - ) - values[45] = cai + dcai_dt * dt - dnai_dt = ( - Acap - * (-(Isac_P_ns / 3 + (INab + (3.0 * INaK + (3.0 * INaCa_i + (INa + INaL)))))) - ) / ((F * vmyo)) + (JdiffNa * vss) / vmyo - values[46] = dnai_dt * dt + nai - dv_dt = -( - Isac_P_k - + ( - Isac_P_ns - + ( - Istim - + ( - ICab - + ( - IpCa - + ( - IKb - + ( - INab - + ( - INaK - + ( - INaCa_ss - + ( - INaCa_i - + ( - IK1 - + ( - IKs - + ( - IKr - + ( - ICaK - + ( - ICaNa - + ( - ICaL - + ( - Ito - + (INa + INaL) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - values[47] = dt * dv_dt + v - - return values - - -def forward_explicit_euler(states, t, dt, parameters): - # Assign states - hL = states[0] - a = states[1] - ap = states[2] - d = states[3] - ff = states[4] - fs = states[5] - hf = states[6] - hs = states[7] - m = states[8] - xrf = states[9] - xrs = states[10] - xs1 = states[11] - CaMKt = states[12] - xk1 = states[13] - Zetaw = states[14] - XS = states[15] - XW = states[16] - TmB = states[17] - hLp = states[18] - iF = states[19] - iS = states[20] - fcaf = states[21] - fcas = states[22] - jca = states[23] - j = states[24] - fcafp = states[25] - ffp = states[26] - hsp = states[27] - jp = states[28] - mL = states[29] - xs2 = states[30] - Zetas = states[31] - nca = states[32] - CaTrpn = states[33] - iFp = states[34] - iSp = states[35] - cajsr = states[36] - cansr = states[37] - kss = states[38] - Cd = states[39] - Jrelnp = states[40] - Jrelp = states[41] - ki = states[42] - cass = states[43] - nass = states[44] - cai = states[45] - nai = states[46] - v = states[47] - - # Assign parameters - Aff = parameters[0] - Ahf = parameters[1] - BSLmax = parameters[2] - BSRmax = parameters[3] - Beta0 = parameters[4] - Beta1 = parameters[5] - CaMKo = parameters[6] - Esac_ns = parameters[7] - F = parameters[8] - GKb = parameters[9] - GNa = parameters[10] - Gncx = parameters[11] - GpCa = parameters[12] - Gsac_k = parameters[13] - Gsac_ns = parameters[14] - Gto = parameters[15] - H = parameters[16] - Khp = parameters[17] - Kki = parameters[18] - Kko = parameters[19] - KmBSL = parameters[20] - KmBSR = parameters[21] - KmCaAct = parameters[22] - KmCaM = parameters[23] - KmCaMK = parameters[24] - Kmgatp = parameters[25] - Kmn = parameters[26] - Knai0 = parameters[27] - Knao0 = parameters[28] - Knap = parameters[29] - Kxkur = parameters[30] - L = parameters[31] - MgADP = parameters[32] - MgATP = parameters[33] - PCab = parameters[34] - PKNa = parameters[35] - PNab = parameters[36] - Pnak = parameters[37] - R = parameters[38] - T = parameters[39] - Tot_A = parameters[40] - Tref = parameters[41] - Trpn50 = parameters[42] - aCaMK = parameters[43] - amp = parameters[44] - bCaMK = parameters[45] - bt = parameters[46] - calib = parameters[47] - cao = parameters[48] - cat50_ref = parameters[49] - celltype = parameters[50] - cmdnmax = parameters[51] - csqnmax = parameters[52] - dLambda = parameters[53] - delta = parameters[54] - delta_epi = parameters[55] - duration = parameters[56] - eP = parameters[57] - emcoupling = parameters[58] - etal = parameters[59] - etas = parameters[60] - gammas = parameters[61] - gammaw = parameters[62] - isacs = parameters[63] - k1m = parameters[64] - k1p = parameters[65] - k2m = parameters[66] - k2n = parameters[67] - k2p = parameters[68] - k3m = parameters[69] - k3p = parameters[70] - k4m = parameters[71] - k4p = parameters[72] - kasymm = parameters[73] - kcaoff = parameters[74] - kcaon = parameters[75] - kmcmdn = parameters[76] - kmcsqn = parameters[77] - kmtrpn = parameters[78] - kna1 = parameters[79] - kna2 = parameters[80] - kna3 = parameters[81] - ko = parameters[82] - ktrpn = parameters[83] - ku = parameters[84] - kuw = parameters[85] - kws = parameters[86] - lambda_max = parameters[87] - lmbda = parameters[88] - mode = parameters[89] - nao = parameters[90] - ntm = parameters[91] - ntrpn = parameters[92] - p_a = parameters[93] - p_b = parameters[94] - p_k = parameters[95] - phi = parameters[96] - qca = parameters[97] - qna = parameters[98] - rad = parameters[99] - rs = parameters[100] - rw = parameters[101] - scale_HF_CaMKa = parameters[102] - scale_HF_GK1 = parameters[103] - scale_HF_GNaL = parameters[104] - scale_HF_Gncx = parameters[105] - scale_HF_Gto = parameters[106] - scale_HF_Jleak = parameters[107] - scale_HF_Jrel_inf = parameters[108] - scale_HF_Jup = parameters[109] - scale_HF_Pnak = parameters[110] - scale_HF_cat50_ref = parameters[111] - scale_HF_thL = parameters[112] - scale_ICaL = parameters[113] - scale_IK1 = parameters[114] - scale_IKr = parameters[115] - scale_IKs = parameters[116] - scale_INaL = parameters[117] - scale_drug_ICaL = parameters[118] - scale_drug_ICab = parameters[119] - scale_drug_IK1 = parameters[120] - scale_drug_IKb = parameters[121] - scale_drug_IKr = parameters[122] - scale_drug_IKs = parameters[123] - scale_drug_INa = parameters[124] - scale_drug_INaL = parameters[125] - scale_drug_INab = parameters[126] - scale_drug_IpCa = parameters[127] - scale_drug_Isack = parameters[128] - scale_drug_Isacns = parameters[129] - scale_drug_Ito = parameters[130] - thL = parameters[131] - tjca = parameters[132] - trpnmax = parameters[133] - wca = parameters[134] - wna = parameters[135] - wnaca = parameters[136] - zca = parameters[137] - zk = parameters[138] - - # Assign expressions - values = numpy.zeros_like(states) - zna = 1.0 - Isac_P_k = 0 - Isac_P_ns = 0 - Afcaf = 0.3 + 0.6 / (numpy.exp((v - 10.0) / 10.0) + 1.0) - AiF = 1.0 / (numpy.exp((v - 213.6) / 151.2) + 1.0) - Axrf = 1.0 / (numpy.exp((v + 54.81) / 38.21) + 1.0) - ass = 1.0 / (numpy.exp((-(v - 14.34)) / 14.82) + 1.0) - assp = 1.0 / (numpy.exp((-(v - 24.34)) / 14.82) + 1.0) - dss = 1.0 / (numpy.exp((-(v + 3.94)) / 4.23) + 1.0) - dti_develop = 1.354 + 0.0001 / ( - numpy.exp((-(v - 12.23)) / 0.2154) + numpy.exp((v - 167.4) / 15.89) - ) - dti_recover = 1.0 - 0.5 / (numpy.exp((v + 70.0) / 20.0) + 1.0) - fss = 1.0 / (numpy.exp((v + 19.58) / 3.696) + 1.0) - hLss = 1.0 / (numpy.exp((v + 87.61) / 7.488) + 1.0) - hLssp = 1.0 / (numpy.exp((v + 93.81) / 7.488) + 1.0) - hss = 1.0 / (numpy.exp((v + 78.5) / 6.22) + 1) - hssp = 1.0 / (numpy.exp(((v + 78.5) + 6.2) / 6.22) + 1) - iss = 1.0 / (numpy.exp((v + 43.94) / 5.711) + 1.0) - mLss = 1.0 / (numpy.exp((-(v + 42.85)) / 5.264) + 1.0) - mss = 1.0 / (numpy.exp((-((v + 39.57) + 9.4)) / 7.5) + 1.0) - rkr = (1.0 * (1.0 / (numpy.exp((v + 55.0) / 75.0) + 1.0))) / ( - numpy.exp((v - 10.0) / 30.0) + 1.0 - ) - ta = 1.0515 / ( - 1.0 / ((1.2089 * (numpy.exp((-(v - 18.4099)) / 29.3814) + 1.0))) - + 3.5 / (numpy.exp((v + 100.0) / 29.3814) + 1.0) - ) - td = 0.6 + 1.0 / (numpy.exp((-0.05) * (v + 6.0)) + numpy.exp(0.09 * (v + 14.0))) - tfcaf = 7.0 + 1.0 / ( - 0.04 * numpy.exp((-(v - 4.0)) / 7.0) + 0.04 * numpy.exp((v - 4.0) / 7.0) - ) - tfcas = 100.0 + 1.0 / ( - 0.00012 * numpy.exp((-v) / 3.0) + 0.00012 * numpy.exp(v / 7.0) - ) - tff = 7.0 + 1.0 / ( - 0.0045 * numpy.exp((-(v + 20.0)) / 10.0) + 0.0045 * numpy.exp((v + 20.0) / 10.0) - ) - tfs = 1000.0 + 1.0 / ( - 3.5e-05 * numpy.exp((-(v + 5.0)) / 4.0) + 3.5e-05 * numpy.exp((v + 5.0) / 6.0) - ) - thf = 1.0 / ( - 6.149 * numpy.exp((v + 0.5096) / 20.27) - + 1.432e-05 * numpy.exp((-(v + 1.196)) / 6.285) - ) - ths = 1.0 / ( - 0.009794 * numpy.exp((-(v + 17.95)) / 28.05) - + 0.3343 * numpy.exp((v + 5.73) / 56.66) - ) - tj = 2.038 + 1.0 / ( - 0.3052 * numpy.exp((v + 0.9941) / 38.45) - + 0.02136 * numpy.exp((-(v + 100.6)) / 8.281) - ) - tm = 1.0 / ( - 6.765 * numpy.exp((v + 11.64) / 34.77) - + 8.552 * numpy.exp((-(v + 77.42)) / 5.955) - ) - txk1 = 122.2 / (numpy.exp((-(v + 127.2)) / 20.36) + numpy.exp((v + 236.8) / 69.33)) - txrf = 12.98 + 1.0 / ( - 4.123e-05 * numpy.exp((-(v - 47.78)) / 20.38) - + 0.3652 * numpy.exp((v - 31.66) / 3.869) - ) - txrs = 1.865 + 1.0 / ( - 1.128e-05 * numpy.exp((-(v - 29.74)) / 25.94) - + 0.06629 * numpy.exp((v - 34.7) / 7.355) - ) - txs1 = 817.3 + 1.0 / ( - 0.0002326 * numpy.exp((v + 48.28) / 17.8) - + 0.001292 * numpy.exp((-(v + 210.0)) / 230.0) - ) - txs2 = 1.0 / ( - 0.01 * numpy.exp((v - 50.0) / 20.0) + 0.0193 * numpy.exp((-(v + 66.54)) / 31.0) - ) - xkb = 1.0 / (numpy.exp((-(v - 14.48)) / 18.34) + 1.0) - xrss = 1.0 / (numpy.exp((-(v + 8.337)) / 6.789) + 1.0) - xs1ss = 1.0 / (numpy.exp((-(v + 11.6)) / 8.932) + 1.0) - Afs = 1.0 - Aff - Ageo = L * ((2 * 3.14) * rad) + rad * ((2 * 3.14) * rad) - vcell = L * (rad * ((3.14 * 1000) * rad)) - Ahs = 1.0 - Ahf - Aw = (Tot_A * rs) / (rs + rw * (1 - rs)) - Jupnp = (0.004375 * cai) / (cai + 0.00092) - Jupp = ((0.004375 * 2.75) * cai) / ((cai + 0.00092) - 0.00017) - KsCa = 1.0 + 0.6 / ((3.8e-05 / cai) ** 1.4 + 1.0) - Bcai = 1.0 / ((cmdnmax * kmcmdn) / (cai + kmcmdn) ** 2.0 + 1.0) - Bcajsr = 1.0 / ((csqnmax * kmcsqn) / (cajsr + kmcsqn) ** 2.0 + 1.0) - Jdiff = (-cai + cass) / 0.2 - Bcass = 1.0 / ( - (BSLmax * KmBSL) / (KmBSL + cass) ** 2.0 - + ((BSRmax * KmBSR) / (KmBSR + cass) ** 2.0 + 1.0) - ) - CaMKb = (CaMKo * (1.0 - CaMKt)) / (KmCaM / cass + 1.0) - CaTrpn_max = (CaTrpn) * (CaTrpn > 0) + (0) * numpy.logical_not((CaTrpn > 0)) - vffrt = (F * (F * v)) / ((R * T)) - vfrt = (F * v) / ((R * T)) - EK = ((R * T) / F) * numpy.log(ko / ki) - rk1 = 1.0 / (numpy.exp((-2.6 * ko + (v + 105.8)) / 9.493) + 1.0) - xk1ss = 1.0 / ( - numpy.exp((-((2.5538 * ko + v) + 144.59)) / (1.5692 * ko + 3.8115)) + 1.0 - ) - ENa = ((R * T) / F) * numpy.log(nao / nai) - EKs = ((R * T) / F) * numpy.log((PKNa * nao + ko) / (PKNa * nai + ki)) - GK1 = scale_HF_GK1 * ((0.1908 * scale_IK1) * scale_drug_IK1) - GKr = (0.046 * scale_IKr) * scale_drug_IKr - GKs = (0.0034 * scale_IKs) * scale_drug_IKs - GNaL = scale_HF_GNaL * ((0.0075 * scale_INaL) * scale_drug_INaL) - km2n = 1.0 * jca - IpCa = (cai * (GpCa * scale_drug_IpCa)) / (cai + 0.0005) - Istim = (amp) * (duration >= t) + (0) * numpy.logical_not((duration >= t)) - JdiffK = (-ki + kss) / 2.0 - JdiffNa = (-nai + nass) / 2.0 - Jtr = (-cajsr + cansr) / 100.0 - Jleak = ((0.0039375 * cansr) * scale_HF_Jleak) / 15.0 - Knai = Knai0 * numpy.exp((F * (delta * v)) / (((3.0 * R) * T))) - Knao = Knao0 * numpy.exp((F * (v * (1.0 - delta))) / (((3.0 * R) * T))) - P = eP / (((H / Khp + 1.0) + nai / Knap) + ki / Kxkur) - PCa = (0.0001 * scale_ICaL) * scale_drug_ICaL - XW_max = (XW) * (XW > 0) + (0) * numpy.logical_not((XW > 0)) - XS_max = (XS) * (XS > 0) + (0) * numpy.logical_not((XS > 0)) - XU = -XW + (-XS + (1 - TmB)) - a2 = k2p - a4 = ((MgATP * k4p) / Kmgatp) / (1.0 + MgATP / Kmgatp) - a_rel = 0.5 * bt - btp = 1.25 * bt - tau_rel_tmp = bt / (1.0 + 0.0123 / cajsr) - allo_i = 1.0 / ((KmCaAct / cai) ** 2.0 + 1.0) - allo_ss = 1.0 / ((KmCaAct / cass) ** 2.0 + 1.0) - b1 = MgADP * k1m - cs = ((kws * phi) * (rw * (1 - rs))) / rs - ksu = (kws * rw) * (-1 + 1 / rs) - cw = ((kuw * phi) * ((1 - rs) * (1 - rw))) / ((rw * (1 - rs))) - kwu = kuw * (-1 + 1 / rw) - kws - gammasu = ( - gammas * Zetas * 1 * (Zetas > 0) - + 0 - * (~(Zetas > 0)) - * numpy.logical_and.reduce( - ( - numpy.logical_or((Zetas > -1), (Zetas > 0)), - numpy.logical_or((Zetas > 0), (Zetas < -1)), - numpy.logical_or.reduce( - ((Zetas >= -1), (Zetas <= 0), (Zetas > -1 / 2)), - ), - ), - ) - + (-Zetas - 1) * 1 * (Zetas < -1) - + 0 - * (~(Zetas < -1)) - * ( - ~numpy.logical_and.reduce( - ( - numpy.logical_or((Zetas > -1), (Zetas > 0)), - numpy.logical_or((Zetas > 0), (Zetas < -1)), - numpy.logical_or.reduce( - ((Zetas >= -1), (Zetas <= 0), (Zetas > -1 / 2)), - ), - ), - ) - ) - ) - gammawu = gammaw * numpy.abs(Zetaw) - h10 = (nao / kna1) * (1 + nao / kna2) + (kasymm + 1.0) - h10_i = (nao / kna1) * (1.0 + nao / kna2) + (kasymm + 1.0) - h4 = (nass / kna1) * (1 + nass / kna2) + 1.0 - h4_i = (nai / kna1) * (1 + nai / kna2) + 1.0 - hca = numpy.exp((F * (qca * v)) / ((R * T))) - hna = numpy.exp((F * (qna * v)) / ((R * T))) - k2 = kcaoff - k2_i = kcaoff - k5 = kcaoff - k5_i = kcaoff - kb = (Trpn50**ntm * ku) / (-rw * (1 - rs) + (1 - rs)) - lambda_min12 = (lmbda) * (lmbda < 1.2) + (1.2) * numpy.logical_not((lmbda < 1.2)) - thLp = scale_HF_thL * (3.0 * thL) - tiF = ( - delta_epi - * ( - 1 - / ( - 0.3933 * numpy.exp((-(v + 100.0)) / 100.0) - + 0.08004 * numpy.exp((v + 50.0) / 16.59) - ) - ) - + 4.562 - ) - tiS = ( - delta_epi - * ( - 1 - / ( - 0.001416 * numpy.exp((-(v + 96.52)) / 59.05) - + 1.78e-08 * numpy.exp((v + 114.1) / 8.079) - ) - ) - + 23.62 - ) - Afcas = 1.0 - Afcaf - AiS = 1.0 - AiF - Axrs = 1.0 - Axrf - fcass = fss - dhL_dt = (-hL + hLss) / ((scale_HF_thL * thL)) - values[0] = dhL_dt * dt + hL - jss = hss - da_dt = (-a + ass) / ta - values[1] = a + da_dt * dt - dap_dt = (-ap + assp) / ta - values[2] = ap + dap_dt * dt - dd_dt = (-d + dss) / td - values[3] = d + dd_dt * dt - tfcafp = 2.5 * tfcaf - tffp = 2.5 * tff - dff_dt = (-ff + fss) / tff - values[4] = dff_dt * dt + ff - dfs_dt = (-fs + fss) / tfs - values[5] = dfs_dt * dt + fs - dhf_dt = (-hf + hss) / thf - values[6] = dhf_dt * dt + hf - thsp = 3.0 * ths - dhs_dt = (-hs + hss) / ths - values[7] = dhs_dt * dt + hs - tjp = 1.46 * tj - tmL = tm - dm_dt = (-m + mss) / tm - values[8] = dm_dt * dt + m - dxrf_dt = (-xrf + xrss) / txrf - values[9] = dt * dxrf_dt + xrf - dxrs_dt = (-xrs + xrss) / txrs - values[10] = dt * dxrs_dt + xrs - xs2ss = xs1ss - dxs1_dt = (-xs1 + xs1ss) / txs1 - values[11] = dt * dxs1_dt + xs1 - f = Aff * ff + Afs * fs - fp = Aff * ffp + Afs * fs - Acap = 2 * Ageo - vjsr = 0.0048 * vcell - vmyo = 0.68 * vcell - vnsr = 0.0552 * vcell - vss = 0.02 * vcell - h = Ahf * hf + Ahs * hs - hp = Ahf * hf + Ahs * hsp - As = Aw - CaMKa = scale_HF_CaMKa * (CaMKb + CaMKt) - dCaMKt_dt = -CaMKt * bCaMK + (CaMKb * aCaMK) * (CaMKb + CaMKt) - values[12] = CaMKt + dCaMKt_dt * dt - ICab = ( - (vffrt * (4.0 * (PCab * scale_drug_ICab))) - * (cai * numpy.exp(2.0 * vfrt) - 0.341 * cao) - ) / (numpy.exp(2.0 * vfrt) - 1.0) - INab = ((vffrt * (PNab * scale_drug_INab)) * (nai * numpy.exp(vfrt) - nao)) / ( - numpy.exp(vfrt) - 1.0 - ) - PhiCaK = ((1.0 * vffrt) * (-0.75 * ko + (0.75 * kss) * numpy.exp(1.0 * vfrt))) / ( - numpy.exp(1.0 * vfrt) - 1.0 - ) - PhiCaL = ((4.0 * vffrt) * (-0.341 * cao + cass * numpy.exp(2.0 * vfrt))) / ( - numpy.exp(2.0 * vfrt) - 1.0 - ) - PhiCaNa = ( - (1.0 * vffrt) * (-0.75 * nao + (0.75 * nass) * numpy.exp(1.0 * vfrt)) - ) / (numpy.exp(1.0 * vfrt) - 1.0) - IKb = (xkb * (GKb * scale_drug_IKb)) * (-EK + v) - dxk1_dt = (-xk1 + xk1ss) / txk1 - values[13] = dt * dxk1_dt + xk1 - IK1 = (xk1 * (rk1 * (GK1 * math.sqrt(ko)))) * (-EK + v) - IKs = (xs2 * (xs1 * (GKs * KsCa))) * (-EKs + v) - anca = 1.0 / (k2n / km2n + (Kmn / cass + 1.0) ** 4.0) - a1 = (k1p * (nai / Knai) ** 3.0) / ( - ((1.0 + ki / Kki) ** 2.0 + (1.0 + nai / Knai) ** 3.0) - 1.0 - ) - b4 = (k4m * (ki / Kki) ** 2.0) / ( - ((1.0 + ki / Kki) ** 2.0 + (1.0 + nai / Knai) ** 3.0) - 1.0 - ) - a3 = (k3p * (ko / Kko) ** 2.0) / ( - ((1.0 + ko / Kko) ** 2.0 + (1.0 + nao / Knao) ** 3.0) - 1.0 - ) - b2 = (k2m * (nao / Knao) ** 3.0) / ( - ((1.0 + ko / Kko) ** 2.0 + (1.0 + nao / Knao) ** 3.0) - 1.0 - ) - b3 = (H * (P * k3m)) / (1.0 + MgATP / Kmgatp) - PCaK = 0.0003574 * PCa - PCaNa = 0.00125 * PCa - PCap = 1.1 * PCa - a_relp = 0.5 * btp - tau_relp_tmp = btp / (1.0 + 0.0123 / cajsr) - tau_rel = (0.001) * (tau_rel_tmp < 0.001) + (tau_rel_tmp) * numpy.logical_not( - (tau_rel_tmp < 0.001), - ) - dZetaw_dt = Aw * dLambda - Zetaw * cw - values[14] = Zetaw + dZetaw_dt * dt - dXS_dt = -XS * gammasu + (-XS * ksu + XW * kws) - values[15] = XS + dXS_dt * dt - dXW_dt = -XW * gammawu + (-XW * kws + (XU * kuw - XW * kwu)) - values[16] = XW + dXW_dt * dt - h11 = (nao * nao) / ((kna2 * (h10 * kna1))) - h12 = 1.0 / h10 - h11_i = (nao * nao) / ((kna2 * (h10_i * kna1))) - h12_i = 1.0 / h10_i - h5 = (nass * nass) / ((kna2 * (h4 * kna1))) - h6 = 1.0 / h4 - h5_i = (nai * nai) / ((kna2 * (h4_i * kna1))) - h6_i = 1.0 / h4_i - h1 = (nass / kna3) * (hna + 1) + 1 - h1_i = (nai / kna3) * (hna + 1) + 1 - h7 = (nao / kna3) * (1.0 + 1.0 / hna) + 1.0 - h7_i = (nao / kna3) * (1.0 + 1.0 / hna) + 1.0 - dTmB_dt = -TmB * CaTrpn ** (ntm / 2) * ku + XU * ( - kb * CaTrpn ** ((-ntm) / 2) * (CaTrpn ** ((-ntm) / 2) < 100) - + 100 * (~(CaTrpn ** ((-ntm) / 2) < 100)) - ) - values[17] = TmB + dTmB_dt * dt - C = lambda_min12 - 1 - cat50 = scale_HF_cat50_ref * (Beta1 * (lambda_min12 - 1) + cat50_ref) - lambda_min087 = (lambda_min12) * (lambda_min12 < 0.87) + (0.87) * numpy.logical_not( - (lambda_min12 < 0.87), - ) - dhLp_dt = (-hLp + hLssp) / thLp - values[18] = dhLp_dt * dt + hLp - tiFp = tiF * (dti_develop * dti_recover) - diF_dt = (-iF + iss) / tiF - values[19] = diF_dt * dt + iF - tiSp = tiS * (dti_develop * dti_recover) - diS_dt = (-iS + iss) / tiS - values[20] = diS_dt * dt + iS - fca = Afcaf * fcaf + Afcas * fcas - fcap = Afcaf * fcafp + Afcas * fcas - i = AiF * iF + AiS * iS - ip = AiF * iFp + AiS * iSp - xr = Axrf * xrf + Axrs * xrs - dfcaf_dt = (-fcaf + fcass) / tfcaf - values[21] = dfcaf_dt * dt + fcaf - dfcas_dt = (-fcas + fcass) / tfcas - values[22] = dfcas_dt * dt + fcas - djca_dt = (fcass - jca) / tjca - values[23] = djca_dt * dt + jca - dj_dt = (-j + jss) / tj - values[24] = dj_dt * dt + j - dfcafp_dt = (-fcafp + fcass) / tfcafp - values[25] = dfcafp_dt * dt + fcafp - dffp_dt = (-ffp + fss) / tffp - values[26] = dffp_dt * dt + ffp - dhsp_dt = (-hsp + hssp) / thsp - values[27] = dhsp_dt * dt + hsp - djp_dt = (-jp + jss) / tjp - values[28] = djp_dt * dt + jp - dmL_dt = (-mL + mLss) / tmL - values[29] = dmL_dt * dt + mL - dxs2_dt = (-xs2 + xs2ss) / txs2 - values[30] = dt * dxs2_dt + xs2 - dZetas_dt = As * dLambda - Zetas * cs - values[31] = Zetas + dZetas_dt * dt - fICaLp = 1.0 / (1.0 + KmCaMK / CaMKa) - fINaLp = 1.0 / (1.0 + KmCaMK / CaMKa) - fINap = 1.0 / (1.0 + KmCaMK / CaMKa) - fItop = 1.0 / (1.0 + KmCaMK / CaMKa) - fJrelp = 1.0 / (1.0 + KmCaMK / CaMKa) - fJupp = 1.0 / (1.0 + KmCaMK / CaMKa) - dnca_dt = anca * k2n - km2n * nca - values[32] = dnca_dt * dt + nca - x2 = b4 * (a2 * a3) + (b4 * (a3 * b1) + (a3 * (a1 * a2) + b4 * (b1 * b2))) - x1 = a2 * (a1 * b3) + (b3 * (a2 * b4) + (a2 * (a1 * a4) + b3 * (b2 * b4))) - x3 = b1 * (a3 * a4) + (a4 * (b1 * b2) + (a4 * (a2 * a3) + b1 * (b2 * b3))) - x4 = a1 * (b2 * b3) + (a1 * (a4 * b2) + (a1 * (a3 * a4) + b2 * (b3 * b4))) - PCaKp = 0.0003574 * PCap - PCaNap = 0.00125 * PCap - tau_relp = (0.001) * (tau_relp_tmp < 0.001) + (tau_relp_tmp) * numpy.logical_not( - (tau_relp_tmp < 0.001), - ) - k1 = kcaon * (cao * h12) - k1_i = kcaon * (cao * h12_i) - k6 = kcaon * (cass * h6) - k6_i = kcaon * (cai * h6_i) - h2 = (hna * nass) / ((h1 * kna3)) - h3 = 1.0 / h1 - h2_i = (hna * nai) / ((h1_i * kna3)) - h3_i = 1.0 / h1_i - h8 = nao / ((h7 * (hna * kna3))) - h9 = 1.0 / h7 - h8_i = nao / ((h7_i * (hna * kna3))) - h9_i = 1.0 / h7_i - F1 = numpy.exp(C * p_b) - 1 - dCd = C - Cd - dCaTrpn_dt = ktrpn * (-CaTrpn + ((1000 * cai) / cat50) ** ntrpn * (1 - CaTrpn)) - values[33] = CaTrpn + dCaTrpn_dt * dt - h_lambda_prima = Beta0 * ((lambda_min087 + lambda_min12) - 1.87) + 1 - diFp_dt = (-iFp + iss) / tiFp - values[34] = diFp_dt * dt + iFp - diSp_dt = (-iSp + iss) / tiSp - values[35] = diSp_dt * dt + iSp - IKr = (rkr * (xr * (GKr * (0.4303314829119352 * math.sqrt(ko))))) * (-EK + v) - ICaL = (d * (PhiCaL * (PCa * (1.0 - fICaLp)))) * ( - f * (1.0 - nca) + nca * (fca * jca) - ) + (d * (PhiCaL * (PCap * fICaLp))) * (fp * (1.0 - nca) + nca * (fcap * jca)) - INaL = (mL * (GNaL * (-ENa + v))) * (fINaLp * hLp + hL * (1.0 - fINaLp)) - INa = (m**3.0 * ((GNa * scale_drug_INa) * (-ENa + v))) * ( - j * (h * (1.0 - fINap)) + jp * (fINap * hp) - ) - Ito = ((scale_HF_Gto * (Gto * scale_drug_Ito)) * (-EK + v)) * ( - i * (a * (1.0 - fItop)) + ip * (ap * fItop) - ) - Jrel = Jrelnp * (1.0 - fJrelp) + Jrelp * fJrelp - Jup = -Jleak + (Jupnp * (1.0 - fJupp) + scale_HF_Jup * (Jupp * fJupp)) - E1 = x1 / (x4 + (x3 + (x1 + x2))) - E2 = x2 / (x4 + (x3 + (x1 + x2))) - E3 = x3 / (x4 + (x3 + (x1 + x2))) - E4 = x4 / (x4 + (x3 + (x1 + x2))) - ICaK = (d * (PhiCaK * (PCaK * (1.0 - fICaLp)))) * ( - f * (1.0 - nca) + nca * (fca * jca) - ) + (d * (PhiCaK * (PCaKp * fICaLp))) * (fp * (1.0 - nca) + nca * (fcap * jca)) - ICaNa = (d * (PhiCaNa * (PCaNa * (1.0 - fICaLp)))) * ( - f * (1.0 - nca) + nca * (fca * jca) - ) + (d * (PhiCaNa * (PCaNap * fICaLp))) * (fp * (1.0 - nca) + nca * (fcap * jca)) - k4pp = h2 * wnaca - k7 = wna * (h2 * h5) - k4p_ss = (h3 * wca) / hca - k4pp_i = h2_i * wnaca - k7_i = wna * (h2_i * h5_i) - k4p_i = (h3_i * wca) / hca - k3pp = h8 * wnaca - k8 = wna * (h11 * h8) - k3p_ss = h9 * wca - k3pp_i = h8_i * wnaca - k8_i = wna * (h11_i * h8_i) - k3p_i = h9_i * wca - eta = (etas) * (dCd < 0) + (etal) * numpy.logical_not((dCd < 0)) - J_TRPN = dCaTrpn_dt * trpnmax - h_lambda = (h_lambda_prima) * (h_lambda_prima > 0) + (0) * numpy.logical_not( - (h_lambda_prima > 0), + dJrelp_dt_linearized = -1 / tau_relp + values[41] = ( + Jrelp + + dJrelp_dt * (numpy.exp(dJrelp_dt_linearized * dt) - 1) / dJrelp_dt_linearized ) - Jrel_inf = ((-ICaL) * a_rel) / (((1.5 * scale_HF_Jrel_inf) / cajsr) ** 8.0 + 1.0) - Jrel_infp = ((-ICaL) * a_relp) / (((1.5 * scale_HF_Jrel_inf) / cajsr) ** 8.0 + 1.0) - dcajsr_dt = Bcajsr * (-Jrel + Jtr) - values[36] = cajsr + dcajsr_dt * dt - dcansr_dt = Jup - (Jtr * vjsr) / vnsr - values[37] = cansr + dcansr_dt * dt - JnakNa = 3.0 * (E1 * a3 - E2 * b3) - JnakK = 2.0 * (-E3 * a1 + E4 * b1) - dkss_dt = -JdiffK + (Acap * (-ICaK)) / ((F * vss)) - values[38] = dkss_dt * dt + kss - k4 = k4p_ss + k4pp - k4_i = k4p_i + k4pp_i - k3 = k3p_ss + k3pp - k3_i = k3p_i + k3pp_i - Fd = dCd * eta - dCd_dt = (p_k * (C - Cd)) / eta - values[39] = Cd + dCd_dt * dt - Ta = (h_lambda * (Tref / rs)) * (XS * (Zetas + 1) + XW * Zetaw) - dJrelnp_dt = (Jrel_inf - Jrelnp) / tau_rel - values[40] = Jrelnp + dJrelnp_dt * dt - dJrelp_dt = (Jrel_infp - Jrelp) / tau_relp - values[41] = Jrelp + dJrelp_dt * dt INaK = (Pnak * scale_HF_Pnak) * (JnakK * zk + JnakNa * zna) x2_ss = (k1 * k7) * (k4 + k5) + (k4 * k6) * (k1 + k8) x2_i = (k1_i * k7_i) * (k4_i + k5_i) + (k4_i * k6_i) * (k1_i + k8_i) @@ -2852,7 +1278,7 @@ def forward_explicit_euler(states, t, dt, parameters): x1_i = (k2_i * k4_i) * (k6_i + k7_i) + (k5_i * k7_i) * (k2_i + k3_i) x3_i = (k1_i * k3_i) * (k6_i + k7_i) + (k6_i * k8_i) * (k2_i + k3_i) x4_i = (k2_i * k8_i) * (k4_i + k5_i) + (k3_i * k5_i) * (k1_i + k8_i) - Tp = p_a * (F1 + Fd) + # Tp = p_a * (F1 + Fd) dki_dt = ( Acap * ( @@ -2874,7 +1300,6 @@ def forward_explicit_euler(states, t, dt, parameters): E2_i = x2_i / (x4_i + (x3_i + (x1_i + x2_i))) E3_i = x3_i / (x4_i + (x3_i + (x1_i + x2_i))) E4_i = x4_i / (x4_i + (x3_i + (x1_i + x2_i))) - Ttot = Ta + Tp JncxCa_ss = -E1_ss * k1 + E2_ss * k2 JncxNa_ss = -E2_ss * k3pp + (E3_ss * k4pp + 3.0 * (-E1_ss * k8 + E4_ss * k7)) JncxCa_i = -E1_i * k1_i + E2_i * k2_i @@ -2966,7 +1391,7 @@ def forward_explicit_euler(states, t, dt, parameters): ) values[47] = dt * dv_dt + v - return values + return numpy.nan_to_num(values, nan=0.0) # """This module contains a ORdmm_Land_em_coupling cardiac cell model @@ -3755,7 +2180,7 @@ def forward_explicit_euler(states, t, dt, parameters): # ) # # Expressions for the Istim component -# Istim = 0 # amp*(ufl.le(time, duration)) +# Istim = 0 # 0 # amp*(ufl.le(time, duration)) # # Expressions for the membrane potential component # current[0] = ( @@ -4465,7 +2890,7 @@ def forward_explicit_euler(states, t, dt, parameters): # ) # # Expressions for the Istim component -# Istim = 0 # amp*(ufl.le(time, duration)) +# Istim = 0 # 0 # amp*(ufl.le(time, duration)) # # Expressions for the diffusion fluxes component # JdiffNa = 0.5 * nass - 0.5 * nai diff --git a/src/simcardems/models/pureEP_ORdmm_Land/em_model.py b/src/simcardems/models/pureEP_ORdmm_Land/em_model.py index 7ce8185f..fe2c3ed2 100644 --- a/src/simcardems/models/pureEP_ORdmm_Land/em_model.py +++ b/src/simcardems/models/pureEP_ORdmm_Land/em_model.py @@ -6,8 +6,7 @@ from typing import TYPE_CHECKING from typing import Union -import cbcbeat -import dolfin +import beat import numpy as np from dolfin import FiniteElement # noqa: F401 from dolfin import MixedElement # noqa: F401 @@ -36,7 +35,7 @@ def coupling_type(self): def vs(self) -> np.ndarray: return self.ep_solver.ode.values - def register_ep_model(self, solver: cbcbeat.SplittingSolver): + def register_ep_model(self, solver: beat.MonodomainSplittingSolver): logger.debug("Registering EP model") self.ep_solver = solver logger.debug("Done registering EP model") @@ -108,31 +107,10 @@ def save_state( config: Optional[Config] = None, ) -> None: super().save_state(path=path, config=config) - # breakpoint() - - # with dolfin.HDF5File( - # self.geometry.comm(), - # Path(path).as_posix(), - # "a", - # ) as h5file: - # h5file.write(self.ep_solver.vs, "/ep/vs") with io.h5pyfile(path, "a") as h5file: h5file["ep/vs"] = self.vs h5file["ep/cell_params"] = self.cell_params() - # io.dict_to_h5( - # self.vs, - # path, - # "ep/vs", - # comm=self.geometry.comm(), - # ) - # io.dict_to_h5( - # self.cell_params(), - # path, - # "ep/cell_params", - # comm=self.geometry.comm(), - # ) - @classmethod def from_state( cls, @@ -154,27 +132,16 @@ def from_state( state_params = io.h5_to_dict(h5file["state_params"]) cell_params = h5file["ep"]["cell_params"][:] vs = h5file["ep"]["vs"][:] - # vs_signature = h5file["ep"]["vs"].attrs["signature"].decode() config.drug_factors_file = drug_factors_file config.popu_factors_file = popu_factors_file config.disease_state = disease_state config.PCL = PCL - # VS = dolfin.FunctionSpace(geo.ep_mesh, eval(vs_signature)) - # vs = dolfin.Function(VS) logger.debug("Load functions") - # with dolfin.HDF5File(geo.ep_mesh.mpi_comm(), path.as_posix(), "r") as h5file: - # h5file.read(vs, "/ep/vs") - # from . import cell_model as model from . import CellModel, ActiveModel - # cell_inits = io.vs_functions_to_dict( - # vs, - # state_names=CellModel.default_initial_conditions().keys(), - # ) - return setup_EM_model( cls_EMCoupling=cls, cls_CellModel=CellModel, diff --git a/src/simcardems/runner.py b/src/simcardems/runner.py index bfb28ca3..e4524c1e 100644 --- a/src/simcardems/runner.py +++ b/src/simcardems/runner.py @@ -124,7 +124,7 @@ def from_models( def store(self): # Assign u, v and Ca for postprocessing - # self.coupling.assigners.assign() + self.coupling.assigners.assign() self.collector.store(TimeStepper.ns2ms(self.t)) def _setup_datacollector(self): @@ -136,18 +136,18 @@ def _setup_datacollector(self): reset_state=self._reset, outfilename=self._config.outfilename, ) - # self.coupling.register_datacollector(self.collector) + self.coupling.register_datacollector(self.collector) def _solve_mechanics_now(self) -> bool: if self._config.mechanics_solve_strategy == "fixed": return self.coupling.dt_mechanics > self._config.dt_mech - # self.coupling.assigners.assign_pre() - # norm = self.coupling.assigners.compute_pre_norm() - # return ( - # norm >= self._config.mech_threshold - # or self.coupling.dt_mechanics > self._config.dt_mech - # ) + self.coupling.assigners.assign_pre() + norm = self.coupling.assigners.compute_pre_norm() + return ( + norm >= self._config.mech_threshold + or self.coupling.dt_mechanics > self._config.dt_mech + ) return True def _post_mechanics_solve(self) -> None: diff --git a/tests/test_models.py b/tests/test_models.py index 8c597e09..28262df3 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -15,7 +15,7 @@ def test_explicit_ORdmm_Land(geo, tmpdir): ) config = simcardems.Config(outdir=Path(tmpdir), coupling_type="explicit_ORdmm_Land") runner = simcardems.Runner.from_models(coupling=coupling, config=config) - runner.solve(1.0) + runner.solve(10.0) assert runner.state_path.is_file() new_coupling = models.explicit_ORdmm_Land.EMCoupling.from_state( path=runner.state_path, @@ -55,7 +55,7 @@ def test_pure_ep_ORdmm_Land(geo, tmpdir): ) runner = simcardems.Runner.from_models(coupling=coupling, config=config) - runner.solve(1.0) + runner.solve(10.0) assert runner.state_path.is_file() new_coupling = models.pureEP_ORdmm_Land.EMCoupling.from_state( path=runner.state_path, From 24704108525c69778965d42a5557fb9c57d976ae Mon Sep 17 00:00:00 2001 From: Henrik Finsberg Date: Tue, 16 Jan 2024 13:39:19 +0100 Subject: [PATCH 3/7] Start working on fully coupled model --- demos/simple_demo.py | 4 +- .../models/explicit_ORdmm_Land/em_model.py | 1 - .../fully_coupled_ORdmm_Land/__init__.py | 2 +- .../fully_coupled_ORdmm_Land/active_model.py | 82 +- .../fully_coupled_ORdmm_Land/cell_model.py | 4668 +++++++++++------ .../fully_coupled_ORdmm_Land/em_model.py | 66 +- .../models/pureEP_ORdmm_Land/em_model.py | 36 +- 7 files changed, 3162 insertions(+), 1697 deletions(-) diff --git a/demos/simple_demo.py b/demos/simple_demo.py index 99c083e4..661100b2 100644 --- a/demos/simple_demo.py +++ b/demos/simple_demo.py @@ -27,6 +27,8 @@ geometry_schema_path=geometry_schema_path, loglevel=10, coupling_type="fully_coupled_ORdmm_Land", + # coupling_type="explicit_ORdmm_Land", + # mechanics_solve_strategy="fixed", T=20, ) @@ -63,7 +65,7 @@ # We can also save the output to xdmf-files that can be viewed in Paraview # -# simcardems.postprocess.make_xdmffiles(outdir.joinpath("results.h5")) +simcardems.postprocess.make_xdmffiles(outdir.joinpath("results.h5")) # The `xdmf` files are can be opened in [Paraview](https://www.paraview.org/download/) to visualize the different variables such as in {numref}`Figure {number} `. # diff --git a/src/simcardems/models/explicit_ORdmm_Land/em_model.py b/src/simcardems/models/explicit_ORdmm_Land/em_model.py index f271b53e..09146bc5 100644 --- a/src/simcardems/models/explicit_ORdmm_Land/em_model.py +++ b/src/simcardems/models/explicit_ORdmm_Land/em_model.py @@ -189,7 +189,6 @@ def setup_assigners(self) -> None: subspace_index=cell_model.state_index(name), is_pre=True, ) - pass @property def mech_mesh(self): diff --git a/src/simcardems/models/fully_coupled_ORdmm_Land/__init__.py b/src/simcardems/models/fully_coupled_ORdmm_Land/__init__.py index 8afb9d45..226d7265 100644 --- a/src/simcardems/models/fully_coupled_ORdmm_Land/__init__.py +++ b/src/simcardems/models/fully_coupled_ORdmm_Land/__init__.py @@ -1,8 +1,8 @@ from . import active_model from . import cell_model +from . import cell_model as CellModel from . import em_model from .active_model import LandModel as ActiveModel -from .cell_model import ORdmmLandFull as CellModel from .em_model import EMCoupling loggers = [ diff --git a/src/simcardems/models/fully_coupled_ORdmm_Land/active_model.py b/src/simcardems/models/fully_coupled_ORdmm_Land/active_model.py index f69889c5..12c4ee0b 100644 --- a/src/simcardems/models/fully_coupled_ORdmm_Land/active_model.py +++ b/src/simcardems/models/fully_coupled_ORdmm_Land/active_model.py @@ -13,8 +13,8 @@ from ... import utils from ...time_stepper import TimeStepper -from .cell_model import ORdmmLandFull from .em_model import EMCoupling +from .cell_model import init_parameter_values, parameter_index logger = utils.getLogger(__name__) @@ -27,15 +27,21 @@ class Scheme(str, Enum): def _Zeta(Zeta_prev, A, c, dLambda, dt, scheme: Scheme): - if scheme == Scheme.analytic: - return Zeta_prev * dolfin.exp(-c * dt) + (A * dLambda / c * dt) * ( - 1.0 - dolfin.exp(-c * dt) - ) - - elif scheme == Scheme.bd: - return Zeta_prev + A * dLambda / (1.0 + c * dt) - else: - return Zeta_prev * (1.0 - c * dt) + A * dLambda + dZeta_dt = A * dLambda - Zeta_prev * c + dZeta_dt_linearized = -c + return ( + Zeta_prev + + dZeta_dt * (dolfin.exp(dZeta_dt_linearized * dt) - 1) / dZeta_dt_linearized + ) + # if scheme == Scheme.analytic: + # return Zeta_prev * dolfin.exp(-c * dt) + (A * dLambda / c * dt) * ( + # 1.0 - dolfin.exp(-c * dt) + # ) + + # elif scheme == Scheme.bd: + # return Zeta_prev + A * dLambda / (1.0 + c * dt) + # else: + # return Zeta_prev * (1.0 - c * dt) + A * dLambda class LandModel(pulse.ActiveModel): @@ -64,7 +70,7 @@ def __init__( self.XS = coupling.XS_mech self.XW = coupling.XW_mech if parameters is None: - parameters = ORdmmLandFull.default_parameters() + parameters = init_parameter_values() self._parameters = parameters @@ -103,11 +109,11 @@ def dLambda(self): @property def Aw(self): - Tot_A = self._parameters["Tot_A"] - rs = self._parameters["rs"] - rw = self._parameters["rw"] - scale_popu_rw = self._parameters["scale_popu_rw"] - scale_popu_rs = self._parameters["scale_popu_rs"] + Tot_A = self._parameters[parameter_index("Tot_A")] + rs = self._parameters[parameter_index("rs")] + rw = self._parameters[parameter_index("rw")] + scale_popu_rw = 1.0 # self._parameters[parameter_index("scale_popu_rw")] + scale_popu_rs = 1.0 # self._parameters[parameter_index("scale_popu_rs")] return ( Tot_A * rs @@ -121,12 +127,12 @@ def As(self): @property def cw(self): - phi = self._parameters["phi"] - kuw = self._parameters["kuw"] - rw = self._parameters["rw"] + phi = self._parameters[parameter_index("phi")] + kuw = self._parameters[parameter_index("kuw")] + rw = self._parameters[parameter_index("rw")] - scale_popu_kuw = self._parameters["scale_popu_kuw"] - scale_popu_rw = self._parameters["scale_popu_rw"] + scale_popu_kuw = 1.0 # self._parameters[parameter_index("scale_popu_kuw")] + scale_popu_rw = 1.0 # self._parameters[parameter_index("scale_popu_rw")] return ( kuw * scale_popu_kuw @@ -137,13 +143,13 @@ def cw(self): @property def cs(self): - phi = self._parameters["phi"] - kws = self._parameters["kws"] - rs = self._parameters["rs"] - rw = self._parameters["rw"] - scale_popu_kws = self._parameters["scale_popu_kws"] - scale_popu_rw = self._parameters["scale_popu_rw"] - scale_popu_rs = self._parameters["scale_popu_rs"] + phi = self._parameters[parameter_index("phi")] + kws = self._parameters[parameter_index("kws")] + rs = self._parameters[parameter_index("rs")] + rw = self._parameters[parameter_index("rw")] + scale_popu_kws = 1.0 # self._parameters[parameter_index("scale_popu_kws")] + scale_popu_rw = 1.0 # self._parameters[parameter_index("scale_popu_rw")] + scale_popu_rs = 1.0 # self._parameters[parameter_index("scale_popu_rs")] return ( kws * scale_popu_kws @@ -209,11 +215,11 @@ def update_prev(self): @property def Ta(self): logger.debug("Evaluate Ta") - Tref = self._parameters["Tref"] - rs = self._parameters["rs"] - scale_popu_Tref = self._parameters["scale_popu_Tref"] - scale_popu_rs = self._parameters["scale_popu_rs"] - Beta0 = self._parameters["Beta0"] + Tref = self._parameters[parameter_index("Tref")] + rs = self._parameters[parameter_index("rs")] + scale_popu_Tref = 1.0 # self._parameters[parameter_index("scale_popu_Tref")] + scale_popu_rs = 1.0 # self._parameters[parameter_index("scale_popu_rs")] + Beta0 = self._parameters[parameter_index("Beta0")] _min = ufl.min_value _max = ufl.max_value @@ -224,11 +230,19 @@ def Ta(self): h_lambda_prima = 1.0 + Beta0 * (lmbda + _min(lmbda, 0.87) - 1.87) h_lambda = _max(0, h_lambda_prima) - return ( + Ta = ( h_lambda * (Tref * scale_popu_Tref / (rs * scale_popu_rs)) * (self.XS * (self.Zetas + 1.0) + self.XW * self.Zetaw) ) + print("Ta", self.Ta_current.vector().get_local()) + print("Zetas", self.Zetas.vector().get_local()) + print("Zetaw", self.Zetaw.vector().get_local()) + print("XS", self.XS.vector().get_local()) + print("XW", self.XW.vector().get_local()) + print("dLambda", self.dLambda.vector().get_local()) + + return Ta def Wactive(self, F, **kwargs): """Active stress energy""" diff --git a/src/simcardems/models/fully_coupled_ORdmm_Land/cell_model.py b/src/simcardems/models/fully_coupled_ORdmm_Land/cell_model.py index 3f04fdd5..5413ba84 100644 --- a/src/simcardems/models/fully_coupled_ORdmm_Land/cell_model.py +++ b/src/simcardems/models/fully_coupled_ORdmm_Land/cell_model.py @@ -1,1664 +1,3126 @@ +# """This module contains a ORdmm_Land_em_coupling cardiac cell model +# The module was autogenerated from a gotran ode file +# """ +# from __future__ import division +# from ... import utils +# from .em_model import EMCoupling +# # from collections import OrderedDict +# # from typing import Dict +# # import dolfin +# # try: +# # import ufl_legacy as ufl +# # except ImportError: +# # import ufl +# # from dolfin import as_vector +# # from dolfin import Constant +# # from ..cell_model import BaseCellModel +# logger = utils.getLogger(__name__) +# flake8: noqa: F841 """This module contains a ORdmm_Land_em_coupling cardiac cell model -The module was autogenerated from a gotran ode file -""" -from __future__ import division - -from collections import OrderedDict -from typing import Dict -import dolfin +The module was autogenerated from a gotran ode file +# """ +import math -try: - import ufl_legacy as ufl -except ImportError: - import ufl -from dolfin import as_vector -from dolfin import Constant +import numpy from ... import utils -from ..cell_model import BaseCellModel from .em_model import EMCoupling +# from collections import OrderedDict +# from typing import Dict +# import dolfin +# from dolfin import as_vector +# from dolfin import Constant +# try: +# import ufl_legacy as ufl +# except ImportError: +# import ufl +# from ..cell_model import BaseCellModel + logger = utils.getLogger(__name__) -def Max(a, b): - return (a + b + abs(a - b)) / Constant(2.0) - - -def Min(a, b): - return (a + b - abs(a - b)) / Constant(2.0) - - -class ORdmmLandFull(BaseCellModel): - def __init__( - self, - coupling: EMCoupling, - params=None, - init_conditions=None, - ): - """ - Create cardiac cell model - *Arguments* - params (dict, :py:class:`dolfin.Mesh`, optional) - optional model parameters - init_conditions (dict, :py:class:`dolfin.Mesh`, optional) - optional initial conditions - """ - logger.debug("Initialize ORdmm Land model") - - super().__init__(params, init_conditions) - self.lmbda = coupling.lmbda_ep - self.Zetas = coupling.Zetas_ep - self.Zetaw = coupling.Zetaw_ep - - @staticmethod - def update_disease_parameters( - params: Dict[str, float], - disease_state: str = "healthy", - ) -> None: - if disease_state.lower() == "hf": - logger.info("Update scaling parameters for heart failure model") - params["HF_scaling_CaMKa"] = 1.50 - params["HF_scaling_Jrel_inf"] = pow(0.8, 8.0) - params["HF_scaling_Jleak"] = 1.3 - params["HF_scaling_Jup"] = 0.45 - params["HF_scaling_GNaL"] = 1.3 - params["HF_scaling_GK1"] = 0.68 - params["HF_scaling_thL"] = 1.8 - params["HF_scaling_Gto"] = 0.4 - params["HF_scaling_Gncx"] = 1.6 - params["HF_scaling_Pnak"] = 0.7 - params["HF_scaling_cat50_ref"] = 0.6 - - @staticmethod - def default_parameters() -> Dict[str, float]: - """Set-up and return default parameters. - Parameters - ---------- - disease_state : str, optional - String with "hf" or "healthy", by default "healthy". - If "hf", then parameters representing heart failure - will be used. - Returns - ------- - OrderedDict - Dictionary with default values - """ - params = OrderedDict( - [ - ("scale_ICaL", 1.018), - ("scale_IK1", 1.414), - ("scale_IKr", 1.119), - ("scale_IKs", 1.648), - ("scale_INaL", 2.274), - ("celltype", 0), - ("cao", 1.8), - ("ko", 5.4), - ("nao", 140.0), - ("F", 96485.0), - ("R", 8314.0), - ("T", 310.0), - ("L", 0.01), - ("rad", 0.0011), - ("Ahf", 0.99), - ("GNa", 31), - ("thL", 200.0), - ("Gto", 0.02), - ("delta_epi", 1.0), - ("Aff", 0.6), - ("Kmn", 0.002), - ("k2n", 1000.0), - ("tjca", 75.0), - ("zca", 2.0), - ("bt", 4.75), - ("Beta0", 2.3), - ("Beta1", -2.4), - ("Tot_A", 25), - ("Tref", 120), - ("Trpn50", 0.35), - ("calib", 1), - ("cat50_ref", 0.805), - ("emcoupling", 1), - ("etal", 200), - ("etas", 20), - ("gammas", 0.0085), - ("gammaw", 0.615), - ("isacs", 0), - ("ktrpn", 0.1), - ("ku", 0.04), - ("kuw", 0.182), - ("kws", 0.012), - ("mode", 1), - ("ntm", 2.4), - ("ntrpn", 2.0), - ("p_a", 2.1), - ("p_b", 9.1), - ("p_k", 7.0), - ("phi", 2.23), - ("rs", 0.25), - ("rw", 0.5), - ("CaMKo", 0.05), - ("KmCaM", 0.0015), - ("KmCaMK", 0.15), - ("aCaMK", 0.05), - ("bCaMK", 0.00068), - ("PKNa", 0.01833), - ("Gncx", 0.0008), - ("KmCaAct", 0.00015), - ("kasymm", 12.5), - ("kcaoff", 5000.0), - ("kcaon", 1500000.0), - ("kna1", 15.0), - ("kna2", 5.0), - ("kna3", 88.12), - ("qca", 0.167), - ("qna", 0.5224), - ("wca", 60000.0), - ("wna", 60000.0), - ("wnaca", 5000.0), - ("H", 1e-07), - ("Khp", 1.698e-07), - ("Kki", 0.5), - ("Kko", 0.3582), - ("Kmgatp", 1.698e-07), - ("Knai0", 9.073), - ("Knao0", 27.78), - ("Knap", 224.0), - ("Kxkur", 292.0), - ("MgADP", 0.05), - ("MgATP", 9.8), - ("Pnak", 30.0), - ("delta", -0.155), - ("eP", 4.2), - ("k1m", 182.4), - ("k1p", 949.5), - ("k2m", 39.4), - ("k2p", 687.2), - ("k3m", 79300.0), - ("k3p", 1899.0), - ("k4m", 40.0), - ("k4p", 639.0), - ("zk", 1.0), - ("GKb", 0.003), - ("PNab", 3.75e-10), - ("PCab", 2.5e-08), - ("GpCa", 0.0005), - ("Esac_ns", -10.0), - ("Gsac_k", 1.097904761904762), - ("Gsac_ns", 0.006), - ("lambda_max", 1.1), - ("amp", -80.0), - ("duration", 0.5), - ("BSLmax", 1.124), - ("BSRmax", 0.047), - ("KmBSL", 0.0087), - ("KmBSR", 0.00087), - ("cmdnmax", 0.05), - ("csqnmax", 10.0), - ("kmcmdn", 0.00238), - ("kmcsqn", 0.8), - ("kmtrpn", 0.0005), - ("trpnmax", 0.07), - # Drug factors - ("scale_drug_INa", 1.0), - ("scale_drug_INaL", 1.0), - ("scale_drug_Ito", 1.0), - ("scale_drug_ICaL", 1.0), - ("scale_drug_IKr", 1.0), - ("scale_drug_IKs", 1.0), - ("scale_drug_IK1", 1.0), - ("scale_drug_IKb", 1.0), - ("scale_drug_INab", 1.0), - ("scale_drug_ICab", 1.0), - ("scale_drug_IpCa", 1.0), - ("scale_drug_Isacns", 1.0), - ("scale_drug_Isack", 1.0), - # Population factors - ("scale_popu_GNa", 1.0), - ("scale_popu_GCaL", 1.0), - ("scale_popu_Gto", 1.0), - ("scale_popu_GNaL", 1.0), - ("scale_popu_GKr", 1.0), - ("scale_popu_GKs", 1.0), - ("scale_popu_GK1", 1.0), - ("scale_popu_GbK", 1.0), - ("scale_popu_KNCX", 1.0), - ("scale_popu_KNaK", 1.0), - ("scale_popu_GbNa", 1.0), - ("scale_popu_GbCa", 1.0), - ("scale_popu_KpCa", 1.0), - ("scale_popu_KRyR", 1.0), - ("scale_popu_KSERCA", 1.0), - ("scale_popu_Kleak", 1.0), - ("scale_popu_nTm", 1.0), - ("scale_popu_CaT50ref", 1.0), - ("scale_popu_Tref", 1.0), - ("scale_popu_kuw", 1.0), - ("scale_popu_kws", 1.0), - ("scale_popu_kTRPN", 1.0), - ("scale_popu_nTRPN", 1.0), - ("scale_popu_ku", 1.0), - ("scale_popu_TRPN50", 1.0), - ("scale_popu_rw", 1.0), - ("scale_popu_rs", 1.0), - # HF scaling factors - ("HF_scaling_CaMKa", 1.0), - ("HF_scaling_Jrel_inf", 1.0), - ("HF_scaling_Jleak", 1.0), - ("HF_scaling_Jup", 1.0), - ("HF_scaling_GNaL", 1.0), - ("HF_scaling_GK1", 1.0), - ("HF_scaling_thL", 1.0), - ("HF_scaling_Gto", 1.0), - ("HF_scaling_Gncx", 1.0), - ("HF_scaling_Pnak", 1.0), - ("HF_scaling_cat50_ref", 1.0), - ], - ) - - return params - - @staticmethod - def default_initial_conditions(): - "Set-up and return default initial conditions." - ic = OrderedDict( - [ - ("v", -87), - ("CaMKt", 0), - ("m", 0), - ("hf", 1), - ("hs", 1), - ("j", 1), - ("hsp", 1), - ("jp", 1), - ("mL", 0), - ("hL", 1), - ("hLp", 1), - ("a", 0), - ("iF", 1), - ("iS", 1), - ("ap", 0), - ("iFp", 1), - ("iSp", 1), - ("d", 0), - ("ff", 1), - ("fs", 1), - ("fcaf", 1), - ("fcas", 1), - ("jca", 1), - ("ffp", 1), - ("fcafp", 1), - ("nca", 0), - ("xrf", 0), - ("xrs", 0), - ("xs1", 0), - ("xs2", 0), - ("xk1", 1), - ("Jrelnp", 0), - ("Jrelp", 0), - ("nai", 7), - ("nass", 7), - ("ki", 145), - ("kss", 145), - ("cass", 0.0001), - ("cansr", 1.2), - ("cajsr", 1.2), - ("XS", 0), - ("XW", 0), - ("CaTrpn", 0), - ("TmB", 1), - ("Cd", 0), - ("cai", 0.0001), - ], - ) - return ic - - def _I(self, v, s, time): - """ - Original gotran transmembrane current dV/dt - """ - time = time if time else Constant(0.0) - logger.debug("Evaluate transmembrane current") +def parameter_index(name: str) -> int: + """Return the index of the parameter with the given name + + Arguments + --------- + name : str + The name of the parameter + + Returns + ------- + int + The index of the parameter + + Raises + ------ + KeyError + If the name is not a valid parameter + """ + + data = { + "Aff": 0, + "Ahf": 1, + "BSLmax": 2, + "BSRmax": 3, + "Beta0": 4, + "Beta1": 5, + "CaMKo": 6, + "Esac_ns": 7, + "F": 8, + "GKb": 9, + "GNa": 10, + "Gncx": 11, + "GpCa": 12, + "Gsac_k": 13, + "Gsac_ns": 14, + "Gto": 15, + "H": 16, + "Khp": 17, + "Kki": 18, + "Kko": 19, + "KmBSL": 20, + "KmBSR": 21, + "KmCaAct": 22, + "KmCaM": 23, + "KmCaMK": 24, + "Kmgatp": 25, + "Kmn": 26, + "Knai0": 27, + "Knao0": 28, + "Knap": 29, + "Kxkur": 30, + "L": 31, + "MgADP": 32, + "MgATP": 33, + "PCab": 34, + "PKNa": 35, + "PNab": 36, + "Pnak": 37, + "R": 38, + "T": 39, + "Tot_A": 40, + "Tref": 41, + "Trpn50": 42, + "aCaMK": 43, + "amp": 44, + "bCaMK": 45, + "bt": 46, + "calib": 47, + "cao": 48, + "cat50_ref": 49, + "celltype": 50, + "cmdnmax": 51, + "csqnmax": 52, + "dLambda": 53, + "delta": 54, + "delta_epi": 55, + "duration": 56, + "eP": 57, + "emcoupling": 58, + "etal": 59, + "etas": 60, + "gammas": 61, + "gammaw": 62, + "isacs": 63, + "k1m": 64, + "k1p": 65, + "k2m": 66, + "k2n": 67, + "k2p": 68, + "k3m": 69, + "k3p": 70, + "k4m": 71, + "k4p": 72, + "kasymm": 73, + "kcaoff": 74, + "kcaon": 75, + "kmcmdn": 76, + "kmcsqn": 77, + "kmtrpn": 78, + "kna1": 79, + "kna2": 80, + "kna3": 81, + "ko": 82, + "ktrpn": 83, + "ku": 84, + "kuw": 85, + "kws": 86, + "lambda_max": 87, + "lmbda": 88, + "mode": 89, + "nao": 90, + "ntm": 91, + "ntrpn": 92, + "p_a": 93, + "p_b": 94, + "p_k": 95, + "phi": 96, + "qca": 97, + "qna": 98, + "rad": 99, + "rs": 100, + "rw": 101, + "scale_HF_CaMKa": 102, + "scale_HF_GK1": 103, + "scale_HF_GNaL": 104, + "scale_HF_Gncx": 105, + "scale_HF_Gto": 106, + "scale_HF_Jleak": 107, + "scale_HF_Jrel_inf": 108, + "scale_HF_Jup": 109, + "scale_HF_Pnak": 110, + "scale_HF_cat50_ref": 111, + "scale_HF_thL": 112, + "scale_ICaL": 113, + "scale_IK1": 114, + "scale_IKr": 115, + "scale_IKs": 116, + "scale_INaL": 117, + "scale_drug_ICaL": 118, + "scale_drug_ICab": 119, + "scale_drug_IK1": 120, + "scale_drug_IKb": 121, + "scale_drug_IKr": 122, + "scale_drug_IKs": 123, + "scale_drug_INa": 124, + "scale_drug_INaL": 125, + "scale_drug_INab": 126, + "scale_drug_IpCa": 127, + "scale_drug_Isack": 128, + "scale_drug_Isacns": 129, + "scale_drug_Ito": 130, + "thL": 131, + "tjca": 132, + "trpnmax": 133, + "wca": 134, + "wna": 135, + "wnaca": 136, + "zca": 137, + "zk": 138, + } + return data[name] + + +def state_index(name: str) -> int: + """Return the index of the state with the given name + + Arguments + --------- + name : str + The name of the state + + Returns + ------- + int + The index of the state + + Raises + ------ + KeyError + If the name is not a valid state + """ + + data = { + "hL": 0, + "a": 1, + "ap": 2, + "d": 3, + "ff": 4, + "fs": 5, + "hf": 6, + "hs": 7, + "m": 8, + "xrf": 9, + "xrs": 10, + "xs1": 11, + "CaMKt": 12, + "xk1": 13, + "Zetaw": 14, + "XS": 15, + "XW": 16, + "TmB": 17, + "hLp": 18, + "iF": 19, + "iS": 20, + "fcaf": 21, + "fcas": 22, + "jca": 23, + "j": 24, + "fcafp": 25, + "ffp": 26, + "hsp": 27, + "jp": 28, + "mL": 29, + "xs2": 30, + "Zetas": 31, + "nca": 32, + "CaTrpn": 33, + "iFp": 34, + "iSp": 35, + "cajsr": 36, + "cansr": 37, + "kss": 38, + "Cd": 39, + "Jrelnp": 40, + "Jrelp": 41, + "ki": 42, + "cass": 43, + "nass": 44, + "cai": 45, + "nai": 46, + "v": 47, + } + return data[name] + + +def init_parameter_values(**values): + """Initialize parameter values""" + # Aff=0.6, Ahf=0.99, BSLmax=1.124, BSRmax=0.047, Beta0=2.3 + # Beta1=-2.4, CaMKo=0.05, Esac_ns=-10, F=96485.0, GKb=0.003 + # GNa=31, Gncx=0.0008, GpCa=0.0005, Gsac_k=(0.2882*800)/210 + # Gsac_ns=0.006, Gto=0.02, H=1e-07, Khp=1.698e-07, Kki=0.5 + # Kko=0.3582, KmBSL=0.0087, KmBSR=0.00087, KmCaAct=0.00015 + # KmCaM=0.0015, KmCaMK=0.15, Kmgatp=1.698e-07, Kmn=0.002 + # Knai0=9.073, Knao0=27.78, Knap=224.0, Kxkur=292.0, L=0.01 + # MgADP=0.05, MgATP=9.8, PCab=2.5e-08, PKNa=0.01833 + # PNab=3.75e-10, Pnak=30, R=8314.0, T=310.0, Tot_A=25, Tref=120 + # Trpn50=0.35, aCaMK=0.05, amp=-80.0, bCaMK=0.00068, bt=4.75 + # calib=1, cao=1.8, cat50_ref=0.805, celltype=0, cmdnmax=0.05 + # csqnmax=10.0, dLambda=0, delta=-0.155, delta_epi=1.0 + # duration=0.5, eP=4.2, emcoupling=1, etal=200, etas=20 + # gammas=0.0085, gammaw=0.615, isacs=0, k1m=182.4, k1p=949.5 + # k2m=39.4, k2n=1000.0, k2p=687.2, k3m=79300.0, k3p=1899.0 + # k4m=40.0, k4p=639.0, kasymm=12.5, kcaoff=5000.0 + # kcaon=1500000.0, kmcmdn=0.00238, kmcsqn=0.8, kmtrpn=0.0005 + # kna1=15.0, kna2=5.0, kna3=88.12, ko=5.4, ktrpn=0.1, ku=0.04 + # kuw=0.182, kws=0.012, lambda_max=1.1, lmbda=1, mode=1 + # nao=140.0, ntm=2.4, ntrpn=2, p_a=2.1, p_b=9.1, p_k=7 + # phi=2.23, qca=0.167, qna=0.5224, rad=0.0011, rs=0.25, rw=0.5 + # scale_HF_CaMKa=1.0, scale_HF_GK1=1.0, scale_HF_GNaL=1.0 + # scale_HF_Gncx=1.0, scale_HF_Gto=1.0, scale_HF_Jleak=1.0 + # scale_HF_Jrel_inf=1.0, scale_HF_Jup=1.0, scale_HF_Pnak=1.0 + # scale_HF_cat50_ref=1.0, scale_HF_thL=1.0, scale_ICaL=1.018 + # scale_IK1=1.414, scale_IKr=1.119, scale_IKs=1.648 + # scale_INaL=2.274, scale_drug_ICaL=1.0, scale_drug_ICab=1.0 + # scale_drug_IK1=1.0, scale_drug_IKb=1.0, scale_drug_IKr=1.0 + # scale_drug_IKs=1.0, scale_drug_INa=1.0, scale_drug_INaL=1.0 + # scale_drug_INab=1.0, scale_drug_IpCa=1.0 + # scale_drug_Isack=1.0, scale_drug_Isacns=1.0 + # scale_drug_Ito=1.0, thL=200.0, tjca=75.0, trpnmax=0.07 + # wca=60000.0, wna=60000.0, wnaca=5000.0, zca=2.0, zk=1.0 + + parameters = numpy.array( + [ + 0.6, + 0.99, + 1.124, + 0.047, + 2.3, + -2.4, + 0.05, + -10, + 96485.0, + 0.003, + 31, + 0.0008, + 0.0005, + (0.2882 * 800) / 210, + 0.006, + 0.02, + 1e-07, + 1.698e-07, + 0.5, + 0.3582, + 0.0087, + 0.00087, + 0.00015, + 0.0015, + 0.15, + 1.698e-07, + 0.002, + 9.073, + 27.78, + 224.0, + 292.0, + 0.01, + 0.05, + 9.8, + 2.5e-08, + 0.01833, + 3.75e-10, + 30, + 8314.0, + 310.0, + 25, + 120, + 0.35, + 0.05, + -80.0, + 0.00068, + 4.75, + 1, + 1.8, + 0.805, + 0, + 0.05, + 10.0, + 0, + -0.155, + 1.0, + 0.5, + 4.2, + 1, + 200, + 20, + 0.0085, + 0.615, + 0, + 182.4, + 949.5, + 39.4, + 1000.0, + 687.2, + 79300.0, + 1899.0, + 40.0, + 639.0, + 12.5, + 5000.0, + 1500000.0, + 0.00238, + 0.8, + 0.0005, + 15.0, + 5.0, + 88.12, + 5.4, + 0.1, + 0.04, + 0.182, + 0.012, + 1.1, + 1, + 1, + 140.0, + 2.4, + 2, + 2.1, + 9.1, + 7, + 2.23, + 0.167, + 0.5224, + 0.0011, + 0.25, + 0.5, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.018, + 1.414, + 1.119, + 1.648, + 2.274, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 200.0, + 75.0, + 0.07, + 60000.0, + 60000.0, + 5000.0, + 2.0, + 1.0, + ], + ) + + for key, value in values.items(): + parameters[parameter_index(key)] = value + + return parameters + + +def init_state_values(**values): + """Initialize state values""" + # hL=1, a=0, ap=0, d=0, ff=1, fs=1, hf=1, hs=1, m=0, xrf=0 + # xrs=0, xs1=0, CaMKt=0, xk1=1, Zetaw=0, XS=0, XW=0, TmB=1 + # hLp=1, iF=1, iS=1, fcaf=1, fcas=1, jca=1, j=1, fcafp=1, ffp=1 + # hsp=1, jp=1, mL=0, xs2=0, Zetas=0, nca=0, CaTrpn=0, iFp=1 + # iSp=1, cajsr=1.2, cansr=1.2, kss=145, Cd=0, Jrelnp=0, Jrelp=0 + # ki=145, cass=0.0001, nass=7, cai=0.0001, nai=7, v=-87 + + states = numpy.array( + [ + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1.2, + 1.2, + 145, + 0, + 0, + 0, + 145, + 0.0001, + 7, + 0.0001, + 7, + -87, + ], + ) + + for key, value in values.items(): + states[state_index(key)] = value + + return states + + +def forward_generalized_rush_larsen(coupling: EMCoupling): + def forward_generalized_rush_larsen_(states, t, dt, parameters): + lmbda = coupling.lmbda_ep.vector().get_local() + Zetas = coupling.Zetas_ep.vector().get_local() + Zetaw = coupling.Zetaw_ep.vector().get_local() # Assign states - assert len(s) == 45 - ( - CaMKt, - m, - hf, - hs, - j, - hsp, - jp, - mL, - hL, - hLp, - a, - iF, - iS, - ap, - iFp, - iSp, - d, - ff, - fs, - fcaf, - fcas, - jca, - ffp, - fcafp, - nca, - xrf, - xrs, - xs1, - xs2, - xk1, - Jrelnp, - Jrelp, - nai, - nass, - ki, - kss, - cass, - cansr, - cajsr, - XS, - XW, - CaTrpn, - TmB, - Cd, - cai, - ) = s + hL = states[0] + a = states[1] + ap = states[2] + d = states[3] + ff = states[4] + fs = states[5] + hf = states[6] + hs = states[7] + m = states[8] + xrf = states[9] + xrs = states[10] + xs1 = states[11] + CaMKt = states[12] + xk1 = states[13] + Zetaw = states[14] + XS = states[15] + XW = states[16] + TmB = states[17] + hLp = states[18] + iF = states[19] + iS = states[20] + fcaf = states[21] + fcas = states[22] + jca = states[23] + j = states[24] + fcafp = states[25] + ffp = states[26] + hsp = states[27] + jp = states[28] + mL = states[29] + xs2 = states[30] + Zetas = states[31] + nca = states[32] + CaTrpn = states[33] + iFp = states[34] + iSp = states[35] + cajsr = states[36] + cansr = states[37] + kss = states[38] + Cd = states[39] + Jrelnp = states[40] + Jrelp = states[41] + ki = states[42] + cass = states[43] + nass = states[44] + cai = states[45] + nai = states[46] + v = states[47] # Assign parameters - scale_ICaL = self._parameters["scale_ICaL"] - scale_IK1 = self._parameters["scale_IK1"] - scale_IKr = self._parameters["scale_IKr"] - scale_IKs = self._parameters["scale_IKs"] - scale_INaL = self._parameters["scale_INaL"] - cao = self._parameters["cao"] - ko = self._parameters["ko"] - nao = self._parameters["nao"] - F = self._parameters["F"] - R = self._parameters["R"] - T = self._parameters["T"] - CaMKo = self._parameters["CaMKo"] - KmCaM = self._parameters["KmCaM"] - KmCaMK = self._parameters["KmCaMK"] - PKNa = self._parameters["PKNa"] - Ahf = self._parameters["Ahf"] - GNa = self._parameters["GNa"] - Gto = self._parameters["Gto"] - Aff = self._parameters["Aff"] - zca = self._parameters["zca"] - Gncx = self._parameters["Gncx"] - KmCaAct = self._parameters["KmCaAct"] - kasymm = self._parameters["kasymm"] - kcaoff = self._parameters["kcaoff"] - kcaon = self._parameters["kcaon"] - kna1 = self._parameters["kna1"] - kna2 = self._parameters["kna2"] - kna3 = self._parameters["kna3"] - qca = self._parameters["qca"] - qna = self._parameters["qna"] - wca = self._parameters["wca"] - wna = self._parameters["wna"] - wnaca = self._parameters["wnaca"] - H = self._parameters["H"] - Khp = self._parameters["Khp"] - Kki = self._parameters["Kki"] - Kko = self._parameters["Kko"] - Kmgatp = self._parameters["Kmgatp"] - Knai0 = self._parameters["Knai0"] - Knao0 = self._parameters["Knao0"] - Knap = self._parameters["Knap"] - Kxkur = self._parameters["Kxkur"] - MgADP = self._parameters["MgADP"] - MgATP = self._parameters["MgATP"] - Pnak = self._parameters["Pnak"] - delta = self._parameters["delta"] - eP = self._parameters["eP"] - k1m = self._parameters["k1m"] - k1p = self._parameters["k1p"] - k2m = self._parameters["k2m"] - k2p = self._parameters["k2p"] - k3m = self._parameters["k3m"] - k3p = self._parameters["k3p"] - k4m = self._parameters["k4m"] - k4p = self._parameters["k4p"] - zk = self._parameters["zk"] - GKb = self._parameters["GKb"] - PNab = self._parameters["PNab"] - PCab = self._parameters["PCab"] - GpCa = self._parameters["GpCa"] - # Drug factor - scale_drug_INa = self._parameters["scale_drug_INa"] - scale_drug_INaL = self._parameters["scale_drug_INaL"] - scale_drug_Ito = self._parameters["scale_drug_Ito"] - scale_drug_ICaL = self._parameters["scale_drug_ICaL"] - scale_drug_IKr = self._parameters["scale_drug_IKr"] - scale_drug_IKs = self._parameters["scale_drug_IKs"] - scale_drug_IK1 = self._parameters["scale_drug_IK1"] - scale_drug_IKb = self._parameters["scale_drug_IKb"] - scale_drug_INab = self._parameters["scale_drug_INab"] - scale_drug_ICab = self._parameters["scale_drug_ICab"] - scale_drug_IpCa = self._parameters["scale_drug_IpCa"] - scale_drug_Isacns = self._parameters["scale_drug_Isacns"] - scale_drug_Isack = self._parameters["scale_drug_Isack"] - # Population factors - scale_popu_GNa = self._parameters["scale_popu_GNa"] - scale_popu_GCaL = self._parameters["scale_popu_GCaL"] - scale_popu_Gto = self._parameters["scale_popu_Gto"] - scale_popu_GNaL = self._parameters["scale_popu_GNaL"] - scale_popu_GKr = self._parameters["scale_popu_GKr"] - scale_popu_GKs = self._parameters["scale_popu_GKs"] - scale_popu_GK1 = self._parameters["scale_popu_GK1"] - scale_popu_GbK = self._parameters["scale_popu_GbK"] - scale_popu_KNCX = self._parameters["scale_popu_KNCX"] - scale_popu_KNaK = self._parameters["scale_popu_KNaK"] - scale_popu_GbNa = self._parameters["scale_popu_GbNa"] - scale_popu_GbCa = self._parameters["scale_popu_GbCa"] - scale_popu_KpCa = self._parameters["scale_popu_KpCa"] - # Systolic Heart Failure (HF with preserved ejection fraction) - HF_scaling_CaMKa = self._parameters["HF_scaling_CaMKa"] - HF_scaling_GNaL = self._parameters["HF_scaling_GNaL"] - HF_scaling_GK1 = self._parameters["HF_scaling_GK1"] - HF_scaling_Gto = self._parameters["HF_scaling_Gto"] - HF_scaling_Gncx = self._parameters["HF_scaling_Gncx"] - HF_scaling_Pnak = self._parameters["HF_scaling_Pnak"] - - # Init return args - current = [ufl.zero()] * 1 - - # Expressions for the CaMKt component - CaMKb = CaMKo * (1.0 - CaMKt) / (1.0 + KmCaM / cass) - CaMKa = (CaMKb + CaMKt) * HF_scaling_CaMKa - - # Expressions for the reversal potentials component - ENa = R * T * ufl.ln(nao / nai) / F - EK = R * T * ufl.ln(ko / ki) / F - EKs = R * T * ufl.ln((ko + PKNa * nao) / (PKNa * nai + ki)) / F - vffrt = (F * F) * v / (R * T) - vfrt = F * v / (R * T) - - # Expressions for the I_Na component - Ahs = 1.0 - Ahf - h = Ahf * hf + Ahs * hs - hp = Ahf * hf + Ahs * hsp - fINap = 1.0 / (1.0 + KmCaMK / CaMKa) - INa = ( - GNa - * scale_drug_INa - * scale_popu_GNa - * ufl.elem_pow(m, 3.0) - * (-ENa + v) - * ((1.0 - fINap) * h * j + fINap * hp * jp) + Aff = parameters[0] + Ahf = parameters[1] + BSLmax = parameters[2] + BSRmax = parameters[3] + Beta0 = parameters[4] + Beta1 = parameters[5] + CaMKo = parameters[6] + F = parameters[8] + GKb = parameters[9] + GNa = parameters[10] + Gncx = parameters[11] + GpCa = parameters[12] + Gto = parameters[15] + H = parameters[16] + Khp = parameters[17] + Kki = parameters[18] + Kko = parameters[19] + KmBSL = parameters[20] + KmBSR = parameters[21] + KmCaAct = parameters[22] + KmCaM = parameters[23] + KmCaMK = parameters[24] + Kmgatp = parameters[25] + Kmn = parameters[26] + Knai0 = parameters[27] + Knao0 = parameters[28] + Knap = parameters[29] + Kxkur = parameters[30] + L = parameters[31] + MgADP = parameters[32] + MgATP = parameters[33] + PCab = parameters[34] + PKNa = parameters[35] + PNab = parameters[36] + Pnak = parameters[37] + R = parameters[38] + T = parameters[39] + Tot_A = parameters[40] + Tref = parameters[41] + Trpn50 = parameters[42] + aCaMK = parameters[43] + amp = parameters[44] + bCaMK = parameters[45] + bt = parameters[46] + cao = parameters[48] + cat50_ref = parameters[49] + cmdnmax = parameters[51] + csqnmax = parameters[52] + # dLambda = parameters[53] + delta = parameters[54] + delta_epi = parameters[55] + duration = parameters[56] + eP = parameters[57] + etal = parameters[59] + etas = parameters[60] + gammas = parameters[61] + gammaw = parameters[62] + k1m = parameters[64] + k1p = parameters[65] + k2m = parameters[66] + k2n = parameters[67] + k2p = parameters[68] + k3m = parameters[69] + k3p = parameters[70] + k4m = parameters[71] + k4p = parameters[72] + kasymm = parameters[73] + kcaoff = parameters[74] + kcaon = parameters[75] + kmcmdn = parameters[76] + kmcsqn = parameters[77] + kna1 = parameters[79] + kna2 = parameters[80] + kna3 = parameters[81] + ko = parameters[82] + ktrpn = parameters[83] + ku = parameters[84] + kuw = parameters[85] + kws = parameters[86] + # lmbda = parameters[88] + nao = parameters[90] + ntm = parameters[91] + ntrpn = parameters[92] + p_a = parameters[93] + p_b = parameters[94] + p_k = parameters[95] + phi = parameters[96] + qca = parameters[97] + qna = parameters[98] + rad = parameters[99] + rs = parameters[100] + rw = parameters[101] + scale_HF_CaMKa = parameters[102] + scale_HF_GK1 = parameters[103] + scale_HF_GNaL = parameters[104] + scale_HF_Gncx = parameters[105] + scale_HF_Gto = parameters[106] + scale_HF_Jleak = parameters[107] + scale_HF_Jrel_inf = parameters[108] + scale_HF_Jup = parameters[109] + scale_HF_Pnak = parameters[110] + scale_HF_cat50_ref = parameters[111] + scale_HF_thL = parameters[112] + scale_ICaL = parameters[113] + scale_IK1 = parameters[114] + scale_IKr = parameters[115] + scale_IKs = parameters[116] + scale_INaL = parameters[117] + scale_drug_ICaL = parameters[118] + scale_drug_ICab = parameters[119] + scale_drug_IK1 = parameters[120] + scale_drug_IKb = parameters[121] + scale_drug_IKr = parameters[122] + scale_drug_IKs = parameters[123] + scale_drug_INa = parameters[124] + scale_drug_INaL = parameters[125] + scale_drug_INab = parameters[126] + scale_drug_IpCa = parameters[127] + scale_drug_Ito = parameters[130] + thL = parameters[131] + tjca = parameters[132] + trpnmax = parameters[133] + wca = parameters[134] + wna = parameters[135] + wnaca = parameters[136] + zca = parameters[137] + zk = parameters[138] + + # Assign expressions + values = numpy.zeros_like(states) + zna = 1.0 + Isac_P_k = 0 + Isac_P_ns = 0 + Afcaf = 0.3 + 0.6 / (numpy.exp((v - 10.0) / 10.0) + 1.0) + AiF = 1.0 / (numpy.exp((v - 213.6) / 151.2) + 1.0) + Axrf = 1.0 / (numpy.exp((v + 54.81) / 38.21) + 1.0) + ass = 1.0 / (numpy.exp((-(v - 14.34)) / 14.82) + 1.0) + assp = 1.0 / (numpy.exp((-(v - 24.34)) / 14.82) + 1.0) + dss = 1.0 / (numpy.exp((-(v + 3.94)) / 4.23) + 1.0) + dti_develop = 1.354 + 0.0001 / ( + numpy.exp((-(v - 12.23)) / 0.2154) + numpy.exp((v - 167.4) / 15.89) + ) + dti_recover = 1.0 - 0.5 / (numpy.exp((v + 70.0) / 20.0) + 1.0) + fss = 1.0 / (numpy.exp((v + 19.58) / 3.696) + 1.0) + hLss = 1.0 / (numpy.exp((v + 87.61) / 7.488) + 1.0) + hLssp = 1.0 / (numpy.exp((v + 93.81) / 7.488) + 1.0) + hss = 1.0 / (numpy.exp((v + 78.5) / 6.22) + 1) + hssp = 1.0 / (numpy.exp(((v + 78.5) + 6.2) / 6.22) + 1) + iss = 1.0 / (numpy.exp((v + 43.94) / 5.711) + 1.0) + mLss = 1.0 / (numpy.exp((-(v + 42.85)) / 5.264) + 1.0) + mss = 1.0 / (numpy.exp((-((v + 39.57) + 9.4)) / 7.5) + 1.0) + rkr = (1.0 * (1.0 / (numpy.exp((v + 55.0) / 75.0) + 1.0))) / ( + numpy.exp((v - 10.0) / 30.0) + 1.0 ) - - # Expressions for the INaL component - GNaL = 0.0075 * scale_INaL * scale_drug_INaL * scale_popu_GNaL * HF_scaling_GNaL - fINaLp = 1.0 / (1.0 + KmCaMK / CaMKa) - INaL = (-ENa + v) * ((1.0 - fINaLp) * hL + fINaLp * hLp) * GNaL * mL - - # Expressions for the Ito component - AiF = 1.0 / (1.0 + 0.24348537187522867 * ufl.exp(0.006613756613756614 * v)) - AiS = 1.0 - AiF - i = AiF * iF + AiS * iS - ip = AiF * iFp + AiS * iSp - fItop = 1.0 / (1.0 + KmCaMK / CaMKa) - Ito = ( - Gto - * scale_drug_Ito - * scale_popu_Gto - * HF_scaling_Gto - * (-EK + v) - * ((1.0 - fItop) * a * i + ap * fItop * ip) + ta = 1.0515 / ( + 1.0 / ((1.2089 * (numpy.exp((-(v - 18.4099)) / 29.3814) + 1.0))) + + 3.5 / (numpy.exp((v + 100.0) / 29.3814) + 1.0) ) - - # Expressions for the ICaL ICaNa ICaK component - Afs = 1.0 - Aff - f = Aff * ff + Afs * fs - Afcaf = 0.3 + 0.6 / (1.0 + 0.36787944117144233 * ufl.exp(0.1 * v)) - Afcas = 1.0 - Afcaf - fca = Afcaf * fcaf + Afcas * fcas - fp = Aff * ffp + Afs * fs - fcap = Afcaf * fcafp + Afcas * fcas - PhiCaL = ( - 4.0 - * (-0.341 * cao + cass * ufl.exp(2.0 * vfrt)) - * vffrt - / (-1.0 + ufl.exp(2.0 * vfrt)) + td = 0.6 + 1.0 / (numpy.exp((-0.05) * (v + 6.0)) + numpy.exp(0.09 * (v + 14.0))) + tfcaf = 7.0 + 1.0 / ( + 0.04 * numpy.exp((-(v - 4.0)) / 7.0) + 0.04 * numpy.exp((v - 4.0) / 7.0) ) - PhiCaNa = ( - 1.0 - * (-0.75 * nao + 0.75 * ufl.exp(1.0 * vfrt) * nass) - * vffrt - / (-1.0 + ufl.exp(1.0 * vfrt)) + tfcas = 100.0 + 1.0 / ( + 0.00012 * numpy.exp((-v) / 3.0) + 0.00012 * numpy.exp(v / 7.0) ) - PhiCaK = ( - 1.0 - * (-0.75 * ko + 0.75 * ufl.exp(1.0 * vfrt) * kss) - * vffrt - / (-1.0 + ufl.exp(1.0 * vfrt)) + tff = 7.0 + 1.0 / ( + 0.0045 * numpy.exp((-(v + 20.0)) / 10.0) + + 0.0045 * numpy.exp((v + 20.0) / 10.0) ) - PCa = 0.0001 * scale_ICaL * scale_drug_ICaL * scale_popu_GCaL - PCap = 1.1 * PCa - PCaNa = 0.00125 * PCa - PCaK = 0.0003574 * PCa - PCaNap = 0.00125 * PCap - PCaKp = 0.0003574 * PCap - fICaLp = 1.0 / (1.0 + KmCaMK / CaMKa) - ICaL = (1.0 - fICaLp) * ( - (1.0 - nca) * f + fca * jca * nca - ) * PCa * PhiCaL * d + ( - (1.0 - nca) * fp + fcap * jca * nca - ) * PCap * PhiCaL * d * fICaLp - ICaNa = (1.0 - fICaLp) * ( - (1.0 - nca) * f + fca * jca * nca - ) * PCaNa * PhiCaNa * d + ( - (1.0 - nca) * fp + fcap * jca * nca - ) * PCaNap * PhiCaNa * d * fICaLp - ICaK = (1.0 - fICaLp) * ( - (1.0 - nca) * f + fca * jca * nca - ) * PCaK * PhiCaK * d + ( - (1.0 - nca) * fp + fcap * jca * nca - ) * PCaKp * PhiCaK * d * fICaLp - - # Expressions for the IKr component - Axrf = 1.0 / (1.0 + 4.197299094734718 * ufl.exp(0.02617115938236064 * v)) - Axrs = 1.0 - Axrf - xr = Axrf * xrf + Axrs * xrs - rkr = 1.0 / ( - (1.0 + 2.0820090840784555 * ufl.exp(0.013333333333333334 * v)) - * (1.0 + 0.7165313105737893 * ufl.exp(0.03333333333333333 * v)) - ) - GKr = 0.046 * scale_IKr * scale_drug_IKr * scale_popu_GKr - IKr = 0.4303314829119352 * ufl.sqrt(ko) * (-EK + v) * GKr * rkr * xr - - # Expressions for the IKs component - KsCa = 1.0 + 0.6 / (1.0 + 6.481821026062645e-07 * ufl.elem_pow(1.0 / cai, 1.4)) - GKs = 0.0034 * scale_IKs * scale_drug_IKs * scale_popu_GKs - IKs = (-EKs + v) * GKs * KsCa * xs1 * xs2 - rk1 = 1.0 / ( - 1.0 - + 69220.6322106767 - * ufl.exp(0.10534077741493732 * v - 0.27388602127883704 * ko) - ) - GK1 = 0.1908 * scale_IK1 * scale_drug_IK1 * scale_popu_GK1 * HF_scaling_GK1 - IK1 = ufl.sqrt(ko) * (-EK + v) * GK1 * rk1 * xk1 - - # Expressions for the INaCa_i component - hca = ufl.exp(F * qca * v / (R * T)) - hna = ufl.exp(F * qna * v / (R * T)) - h1_i = 1 + (1 + hna) * nai / kna3 - h2_i = hna * nai / (kna3 * h1_i) - h3_i = 1.0 / h1_i - h4_i = 1.0 + (1 + nai / kna2) * nai / kna1 - h5_i = (nai * nai) / (kna1 * kna2 * h4_i) - h6_i = 1.0 / h4_i - h7_i = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 - h8_i = nao / (kna3 * h7_i * hna) - h9_i = 1.0 / h7_i - h10_i = 1.0 + kasymm + nao * (1.0 + nao / kna2) / kna1 - h11_i = (nao * nao) / (kna1 * kna2 * h10_i) - h12_i = 1.0 / h10_i - k1_i = cao * kcaon * h12_i - k2_i = kcaoff - k3p_i = wca * h9_i - k3pp_i = wnaca * h8_i - k3_i = k3p_i + k3pp_i - k4p_i = wca * h3_i / hca - k4pp_i = wnaca * h2_i - k4_i = k4p_i + k4pp_i - k5_i = kcaoff - k6_i = kcaon * cai * h6_i - k7_i = wna * h2_i * h5_i - k8_i = wna * h11_i * h8_i - x1_i = (k2_i + k3_i) * k5_i * k7_i + (k6_i + k7_i) * k2_i * k4_i - x2_i = (k1_i + k8_i) * k4_i * k6_i + (k4_i + k5_i) * k1_i * k7_i - x3_i = (k2_i + k3_i) * k6_i * k8_i + (k6_i + k7_i) * k1_i * k3_i - x4_i = (k1_i + k8_i) * k3_i * k5_i + (k4_i + k5_i) * k2_i * k8_i - E1_i = x1_i / (x1_i + x2_i + x3_i + x4_i) - E2_i = x2_i / (x1_i + x2_i + x3_i + x4_i) - E3_i = x3_i / (x1_i + x2_i + x3_i + x4_i) - E4_i = x4_i / (x1_i + x2_i + x3_i + x4_i) - allo_i = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cai, 2.0)) - zna = 1.0 - JncxNa_i = E3_i * k4pp_i - E2_i * k3pp_i + 3.0 * E4_i * k7_i - 3.0 * E1_i * k8_i - JncxCa_i = E2_i * k2_i - E1_i * k1_i - INaCa_i = ( - 0.8 - * Gncx - * scale_popu_KNCX - * HF_scaling_Gncx - * (zca * JncxCa_i + zna * JncxNa_i) - * allo_i - ) - - # Expressions for the INaCa_ss component - h1 = 1.0 + (1.0 + hna) * nass / kna3 - h2 = hna * nass / (kna3 * h1) - h3 = 1.0 / h1 - h4 = 1.0 + (1 + nass / kna2) * nass / kna1 - h5 = (nass * nass) / (kna1 * kna2 * h4) - h6 = 1.0 / h4 - h7 = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 - h8 = nao / (kna3 * h7 * hna) - h9 = 1.0 / h7 - h10 = 1.0 + kasymm + nao * (1 + nao / kna2) / kna1 - h11 = (nao * nao) / (kna1 * kna2 * h10) - h12 = 1.0 / h10 - k1 = cao * kcaon * h12 - k2 = kcaoff - k3p_ss = wca * h9 - k3pp = wnaca * h8 - k3 = k3p_ss + k3pp - k4p_ss = wca * h3 / hca - k4pp = wnaca * h2 - k4 = k4p_ss + k4pp - k5 = kcaoff - k6 = kcaon * cass * h6 - k7 = wna * h2 * h5 - k8 = wna * h11 * h8 - x1_ss = (k2 + k3) * k5 * k7 + (k6 + k7) * k2 * k4 - x2_ss = (k1 + k8) * k4 * k6 + (k4 + k5) * k1 * k7 - x3_ss = (k2 + k3) * k6 * k8 + (k6 + k7) * k1 * k3 - x4_ss = (k1 + k8) * k3 * k5 + (k4 + k5) * k2 * k8 - E1_ss = x1_ss / (x1_ss + x2_ss + x3_ss + x4_ss) - E2_ss = x2_ss / (x1_ss + x2_ss + x3_ss + x4_ss) - E3_ss = x3_ss / (x1_ss + x2_ss + x3_ss + x4_ss) - E4_ss = x4_ss / (x1_ss + x2_ss + x3_ss + x4_ss) - allo_ss = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cass, 2.0)) - JncxNa_ss = E3_ss * k4pp - E2_ss * k3pp + 3.0 * E4_ss * k7 - 3.0 * E1_ss * k8 - JncxCa_ss = E2_ss * k2 - E1_ss * k1 - INaCa_ss = ( - 0.2 - * Gncx - * scale_popu_KNCX - * HF_scaling_Gncx - * (zca * JncxCa_ss + zna * JncxNa_ss) - * allo_ss - ) - - # Expressions for the INaK component - Knai = Knai0 * ufl.exp(0.3333333333333333 * F * delta * v / (R * T)) - Knao = Knao0 * ufl.exp(0.3333333333333333 * F * (1.0 - delta) * v / (R * T)) - P = eP / (1.0 + H / Khp + nai / Knap + ki / Kxkur) - a1 = ( - k1p - * ufl.elem_pow(nai / Knai, 3.0) - / ( - -1.0 - + ufl.elem_pow(1.0 + ki / Kki, 2.0) - + ufl.elem_pow(1.0 + nai / Knai, 3.0) - ) + tfs = 1000.0 + 1.0 / ( + 3.5e-05 * numpy.exp((-(v + 5.0)) / 4.0) + + 3.5e-05 * numpy.exp((v + 5.0) / 6.0) ) - b1 = MgADP * k1m - a2 = k2p - b2 = ( - k2m - * ufl.elem_pow(nao / Knao, 3.0) - / ( - -1.0 - + ufl.elem_pow(1.0 + ko / Kko, 2.0) - + ufl.elem_pow(1.0 + nao / Knao, 3.0) - ) + thf = 1.0 / ( + 6.149 * numpy.exp((v + 0.5096) / 20.27) + + 1.432e-05 * numpy.exp((-(v + 1.196)) / 6.285) ) - a3 = ( - k3p - * ufl.elem_pow(ko / Kko, 2.0) - / ( - -1.0 - + ufl.elem_pow(1.0 + ko / Kko, 2.0) - + ufl.elem_pow(1.0 + nao / Knao, 3.0) - ) + ths = 1.0 / ( + 0.009794 * numpy.exp((-(v + 17.95)) / 28.05) + + 0.3343 * numpy.exp((v + 5.73) / 56.66) ) - b3 = H * k3m * P / (1.0 + MgATP / Kmgatp) - a4 = MgATP * k4p / (Kmgatp * (1.0 + MgATP / Kmgatp)) - b4 = ( - k4m - * ufl.elem_pow(ki / Kki, 2.0) - / ( - -1.0 - + ufl.elem_pow(1.0 + ki / Kki, 2.0) - + ufl.elem_pow(1.0 + nai / Knai, 3.0) - ) + tj = 2.038 + 1.0 / ( + 0.3052 * numpy.exp((v + 0.9941) / 38.45) + + 0.02136 * numpy.exp((-(v + 100.6)) / 8.281) ) - x1 = a1 * a2 * a4 + a1 * a2 * b3 + a2 * b3 * b4 + b2 * b3 * b4 - x2 = a1 * a2 * a3 + a2 * a3 * b4 + a3 * b1 * b4 + b1 * b2 * b4 - x3 = a2 * a3 * a4 + a3 * a4 * b1 + a4 * b1 * b2 + b1 * b2 * b3 - x4 = a1 * a3 * a4 + a1 * a4 * b2 + a1 * b2 * b3 + b2 * b3 * b4 - E1 = x1 / (x1 + x2 + x3 + x4) - E2 = x2 / (x1 + x2 + x3 + x4) - E3 = x3 / (x1 + x2 + x3 + x4) - E4 = x4 / (x1 + x2 + x3 + x4) - JnakNa = 3.0 * E1 * a3 - 3.0 * E2 * b3 - JnakK = 2.0 * E4 * b1 - 2.0 * E3 * a1 - INaK = Pnak * scale_popu_KNaK * HF_scaling_Pnak * (zk * JnakK + zna * JnakNa) - - # Expressions for the IKb component - xkb = 1.0 / (1.0 + 2.202363450949239 * ufl.exp(-0.05452562704471101 * v)) - IKb = GKb * scale_popu_GbK * scale_drug_IKb * (-EK + v) * xkb - - # Expressions for the INab component - INab = ( - PNab - * scale_drug_INab - * scale_popu_GbNa - * (-nao + ufl.exp(vfrt) * nai) - * vffrt - / (-1.0 + ufl.exp(vfrt)) - ) - - # Expressions for the ICab component - ICab = ( - 4.0 - * PCab - * scale_drug_ICab - * scale_popu_GbCa - * (-0.341 * cao + cai * ufl.exp(2.0 * vfrt)) - * vffrt - / (-1.0 + ufl.exp(2.0 * vfrt)) - ) - - # Expressions for the IpCa component - IpCa = GpCa * scale_drug_IpCa * scale_popu_KpCa * cai / (0.0005 + cai) - - # Expressions for the Isac (Pueyo)--> ns + k component - Gsac_ns = 0.006 * scale_drug_Isacns - Esac_ns = -10.0 - lambda_max = 1.1 - Gsac_k = (0.2882 * 800.0 / 210.0) * scale_drug_Isack # Pueyo endo - - Isac_P_ns = ufl.conditional( - ufl.lt(self.lmbda, 1.0), - 0.0, - Gsac_ns * ((self.lmbda - 1.0) / (lambda_max - 1.0)) * (v - Esac_ns), - ) - Isac_P_k = ufl.conditional( - ufl.lt(self.lmbda, 1.0), - 0.0, - Gsac_k - * ((self.lmbda - 1.0) / (lambda_max - 1.0)) - * (1.0 / (1.0 + ufl.exp((19.05 - v) / (29.98)))), - ) - - # Expressions for the Istim component - Istim = 0 # amp*(ufl.le(time, duration)) - - # Expressions for the membrane potential component - current[0] = ( - -Isac_P_k - - Isac_P_ns - - ICaK - - ICaL - - ICaNa - - ICab - - IK1 - - IKb - - IKr - - IKs - - INa - - INaCa_i - - INaCa_ss - - INaK - - INaL - - INab - - IpCa - - Istim - - Ito - ) - - # Return results - return current[0] - - def I(self, v, s, time=None): # noqa: E741, E743 - """ - Transmembrane current - I = -dV/dt - """ - return -self._I(v, s, time) - - def F(self, v, s, time=None): - """ - Right hand side for ODE system - """ - logger.debug("Evaluate RHS") - time = time if time else Constant(0.0) - - # Assign states - assert len(s) == 45 - ( - CaMKt, - m, - hf, - hs, - j, - hsp, - jp, - mL, - hL, - hLp, - a, - iF, - iS, - ap, - iFp, - iSp, - d, - ff, - fs, - fcaf, - fcas, - jca, - ffp, - fcafp, - nca, - xrf, - xrs, - xs1, - xs2, - xk1, - Jrelnp, - Jrelp, - nai, - nass, - ki, - kss, - cass, - cansr, - cajsr, - XS, - XW, - CaTrpn, - TmB, - Cd, - cai, - ) = s - - # Assign parameters - scale_ICaL = self._parameters["scale_ICaL"] - scale_IK1 = self._parameters["scale_IK1"] - scale_IKr = self._parameters["scale_IKr"] - scale_IKs = self._parameters["scale_IKs"] - scale_INaL = self._parameters["scale_INaL"] - cao = self._parameters["cao"] - ko = self._parameters["ko"] - nao = self._parameters["nao"] - F = self._parameters["F"] - R = self._parameters["R"] - T = self._parameters["T"] - L = self._parameters["L"] - rad = self._parameters["rad"] - CaMKo = self._parameters["CaMKo"] - KmCaM = self._parameters["KmCaM"] - KmCaMK = self._parameters["KmCaMK"] - aCaMK = self._parameters["aCaMK"] - bCaMK = self._parameters["bCaMK"] - PKNa = self._parameters["PKNa"] - Ahf = self._parameters["Ahf"] - GNa = self._parameters["GNa"] - thL = self._parameters["thL"] - Gto = self._parameters["Gto"] - delta_epi = self._parameters["delta_epi"] - Aff = self._parameters["Aff"] - Kmn = self._parameters["Kmn"] - k2n = self._parameters["k2n"] - tjca = self._parameters["tjca"] - zca = self._parameters["zca"] - Gncx = self._parameters["Gncx"] - KmCaAct = self._parameters["KmCaAct"] - kasymm = self._parameters["kasymm"] - kcaoff = self._parameters["kcaoff"] - kcaon = self._parameters["kcaon"] - kna1 = self._parameters["kna1"] - kna2 = self._parameters["kna2"] - kna3 = self._parameters["kna3"] - qca = self._parameters["qca"] - qna = self._parameters["qna"] - wca = self._parameters["wca"] - wna = self._parameters["wna"] - wnaca = self._parameters["wnaca"] - H = self._parameters["H"] - Khp = self._parameters["Khp"] - Kki = self._parameters["Kki"] - Kko = self._parameters["Kko"] - Kmgatp = self._parameters["Kmgatp"] - Knai0 = self._parameters["Knai0"] - Knao0 = self._parameters["Knao0"] - Knap = self._parameters["Knap"] - Kxkur = self._parameters["Kxkur"] - MgADP = self._parameters["MgADP"] - MgATP = self._parameters["MgATP"] - Pnak = self._parameters["Pnak"] - delta = self._parameters["delta"] - eP = self._parameters["eP"] - k1m = self._parameters["k1m"] - k1p = self._parameters["k1p"] - k2m = self._parameters["k2m"] - k2p = self._parameters["k2p"] - k3m = self._parameters["k3m"] - k3p = self._parameters["k3p"] - k4m = self._parameters["k4m"] - k4p = self._parameters["k4p"] - zk = self._parameters["zk"] - GKb = self._parameters["GKb"] - PNab = self._parameters["PNab"] - PCab = self._parameters["PCab"] - GpCa = self._parameters["GpCa"] - bt = self._parameters["bt"] - BSLmax = self._parameters["BSLmax"] - BSRmax = self._parameters["BSRmax"] - KmBSL = self._parameters["KmBSL"] - KmBSR = self._parameters["KmBSR"] - cmdnmax = self._parameters["cmdnmax"] - csqnmax = self._parameters["csqnmax"] - kmcmdn = self._parameters["kmcmdn"] - kmcsqn = self._parameters["kmcsqn"] - trpnmax = self._parameters["trpnmax"] - Beta1 = self._parameters["Beta1"] - - Trpn50 = self._parameters["Trpn50"] - cat50_ref = self._parameters["cat50_ref"] - - etal = self._parameters["etal"] - etas = self._parameters["etas"] - gammas = self._parameters["gammas"] - gammaw = self._parameters["gammaw"] - ktrpn = self._parameters["ktrpn"] - ku = self._parameters["ku"] - kuw = self._parameters["kuw"] - kws = self._parameters["kws"] - # lmbda = self._parameters["lmbda"] - ntm = self._parameters["ntm"] - ntrpn = self._parameters["ntrpn"] - p_k = self._parameters["p_k"] - - rs = self._parameters["rs"] - rw = self._parameters["rw"] - - # Zetas = self._parameters["Zetas"] - # Zetaw = self._parameters["Zetaw"] - - # Drug factor - scale_drug_INa = self._parameters["scale_drug_INa"] - scale_drug_INaL = self._parameters["scale_drug_INaL"] - scale_drug_Ito = self._parameters["scale_drug_Ito"] - scale_drug_ICaL = self._parameters["scale_drug_ICaL"] - scale_drug_IKr = self._parameters["scale_drug_IKr"] - scale_drug_IKs = self._parameters["scale_drug_IKs"] - scale_drug_IK1 = self._parameters["scale_drug_IK1"] - scale_drug_IKb = self._parameters["scale_drug_IKb"] - scale_drug_INab = self._parameters["scale_drug_INab"] - scale_drug_ICab = self._parameters["scale_drug_ICab"] - scale_drug_IpCa = self._parameters["scale_drug_IpCa"] - scale_drug_Isacns = self._parameters["scale_drug_Isacns"] - scale_drug_Isack = self._parameters["scale_drug_Isack"] - - # Population factors - scale_popu_GNa = self._parameters["scale_popu_GNa"] - scale_popu_GCaL = self._parameters["scale_popu_GCaL"] - scale_popu_Gto = self._parameters["scale_popu_Gto"] - scale_popu_GNaL = self._parameters["scale_popu_GNaL"] - scale_popu_GKr = self._parameters["scale_popu_GKr"] - scale_popu_GKs = self._parameters["scale_popu_GKs"] - scale_popu_GK1 = self._parameters["scale_popu_GK1"] - scale_popu_GbK = self._parameters["scale_popu_GbK"] - scale_popu_KNCX = self._parameters["scale_popu_KNCX"] - scale_popu_KNaK = self._parameters["scale_popu_KNaK"] - scale_popu_GbNa = self._parameters["scale_popu_GbNa"] - scale_popu_GbCa = self._parameters["scale_popu_GbCa"] - scale_popu_KpCa = self._parameters["scale_popu_KpCa"] - scale_popu_KRyR = self._parameters["scale_popu_KRyR"] - scale_popu_KSERCA = self._parameters["scale_popu_KSERCA"] - scale_popu_Kleak = self._parameters["scale_popu_Kleak"] - scale_popu_nTm = self._parameters["scale_popu_nTm"] - scale_popu_CaT50ref = self._parameters["scale_popu_CaT50ref"] - scale_popu_kuw = self._parameters["scale_popu_kuw"] - scale_popu_kws = self._parameters["scale_popu_kws"] - scale_popu_kTRPN = self._parameters["scale_popu_kTRPN"] - scale_popu_nTRPN = self._parameters["scale_popu_nTRPN"] - scale_popu_ku = self._parameters["scale_popu_ku"] - scale_popu_TRPN50 = self._parameters["scale_popu_TRPN50"] - scale_popu_rw = self._parameters["scale_popu_rw"] - scale_popu_rs = self._parameters["scale_popu_rs"] - - # Systolic Heart Failure (HF with preserved ejection fraction) - HF_scaling_CaMKa = self._parameters["HF_scaling_CaMKa"] - HF_scaling_Jrel_inf = self._parameters["HF_scaling_Jrel_inf"] - HF_scaling_Jleak = self._parameters["HF_scaling_Jleak"] - HF_scaling_Jup = self._parameters["HF_scaling_Jup"] - HF_scaling_GNaL = self._parameters["HF_scaling_GNaL"] - HF_scaling_GK1 = self._parameters["HF_scaling_GK1"] - HF_scaling_thL = self._parameters["HF_scaling_thL"] - HF_scaling_Gto = self._parameters["HF_scaling_Gto"] - HF_scaling_Gncx = self._parameters["HF_scaling_Gncx"] - HF_scaling_Pnak = self._parameters["HF_scaling_Pnak"] - HF_scaling_cat50_ref = self._parameters["HF_scaling_cat50_ref"] - - # Init return args - F_expressions = [dolfin.Constant(0.0)] * 45 - - # Expressions for the cell geometry component - vcell = 3140.0 * L * (rad * rad) - Ageo = 6.28 * (rad * rad) + 6.28 * L * rad - Acap = 2 * Ageo - vmyo = 0.68 * vcell - vnsr = 0.0552 * vcell - vjsr = 0.0048 * vcell - vss = 0.02 * vcell - - # Expressions for the CaMKt component - CaMKb = CaMKo * (1.0 - CaMKt) / (1.0 + KmCaM / cass) - CaMKa = (CaMKb + CaMKt) * HF_scaling_CaMKa - F_expressions[0] = -bCaMK * CaMKt + aCaMK * (CaMKb + CaMKt) * CaMKb - - # Expressions for the reversal potentials component - ENa = R * T * ufl.ln(nao / nai) / F - EK = R * T * ufl.ln(ko / ki) / F - EKs = R * T * ufl.ln((ko + PKNa * nao) / (PKNa * nai + ki)) / F - vffrt = (F * F) * v / (R * T) - vfrt = F * v / (R * T) - - # Expressions for the I_Na component - mss = 1.0 / (1.0 + 0.0014599788446489682 * ufl.exp(-0.13333333333333333 * v)) tm = 1.0 / ( - 9.454904638564724 * ufl.exp(0.02876042565429968 * v) - + 1.9314113558536928e-05 * ufl.exp(-0.16792611251049538 * v) + 6.765 * numpy.exp((v + 11.64) / 34.77) + + 8.552 * numpy.exp((-(v + 77.42)) / 5.955) ) - F_expressions[1] = (-m + mss) / tm - hss = 1.0 / (1 + 302724.605401998 * ufl.exp(0.1607717041800643 * v)) - thf = 1.0 / ( - 1.183856958289087e-05 * ufl.exp(-0.15910898965791567 * v) - + 6.305549185817275 * ufl.exp(0.0493339911198816 * v) + txk1 = 122.2 / ( + numpy.exp((-(v + 127.2)) / 20.36) + numpy.exp((v + 236.8) / 69.33) ) - ths = 1.0 / ( - 0.005164670235381792 * ufl.exp(-0.035650623885918005 * v) - + 0.36987619372096325 * ufl.exp(0.017649135192375574 * v) + txrf = 12.98 + 1.0 / ( + 4.123e-05 * numpy.exp((-(v - 47.78)) / 20.38) + + 0.3652 * numpy.exp((v - 31.66) / 3.869) ) - Ahs = 1.0 - Ahf - F_expressions[2] = (-hf + hss) / thf - F_expressions[3] = (-hs + hss) / ths - h = Ahf * hf + Ahs * hs - jss = hss - tj = 2.038 + 1.0 / ( - 0.3131936394738773 * ufl.exp(0.02600780234070221 * v) - + 1.1315282095590072e-07 * ufl.exp(-0.12075836251660427 * v) + txrs = 1.865 + 1.0 / ( + 1.128e-05 * numpy.exp((-(v - 29.74)) / 25.94) + + 0.06629 * numpy.exp((v - 34.7) / 7.355) ) - F_expressions[4] = (-j + jss) / tj - hssp = 1.0 / (1 + 820249.0921708513 * ufl.exp(0.1607717041800643 * v)) - thsp = 3.0 * ths - F_expressions[5] = (-hsp + hssp) / thsp - hp = Ahf * hf + Ahs * hsp - tjp = 1.46 * tj - F_expressions[6] = (-jp + jss) / tjp - fINap = 1.0 / (1.0 + KmCaMK / CaMKa) - INa = ( - GNa - * scale_drug_INa - * scale_popu_GNa - * ufl.elem_pow(m, 3.0) - * (-ENa + v) - * ((1.0 - fINap) * h * j + fINap * hp * jp) + txs1 = 817.3 + 1.0 / ( + 0.0002326 * numpy.exp((v + 48.28) / 17.8) + + 0.001292 * numpy.exp((-(v + 210.0)) / 230.0) ) - - # Expressions for the INaL component - mLss = 1.0 / (1.0 + 0.000291579585635531 * ufl.exp(-0.18996960486322187 * v)) - tmL = tm - F_expressions[7] = (-mL + mLss) / tmL - hLss = 1.0 / (1.0 + 120578.15595522427 * ufl.exp(0.13354700854700854 * v)) - F_expressions[8] = (-hL + hLss) / (thL * HF_scaling_thL) - hLssp = 1.0 / (1.0 + 275969.2903869871 * ufl.exp(0.13354700854700854 * v)) - thLp = 3.0 * thL * HF_scaling_thL - F_expressions[9] = (-hLp + hLssp) / thLp - GNaL = 0.0075 * scale_INaL * scale_drug_INaL * scale_popu_GNaL * HF_scaling_GNaL - fINaLp = 1.0 / (1.0 + KmCaMK / CaMKa) - INaL = (-ENa + v) * ((1.0 - fINaLp) * hL + fINaLp * hLp) * GNaL * mL - - # Expressions for the Ito component - ass = 1.0 / (1.0 + 2.6316508161673635 * ufl.exp(-0.06747638326585695 * v)) - ta = 1.0515 / ( - 1.0 / (1.2089 + 2.2621017070578837 * ufl.exp(-0.03403513787634354 * v)) - + 3.5 / (1.0 + 30.069572727397507 * ufl.exp(0.03403513787634354 * v)) + txs2 = 1.0 / ( + 0.01 * numpy.exp((v - 50.0) / 20.0) + + 0.0193 * numpy.exp((-(v + 66.54)) / 31.0) ) - F_expressions[10] = (-a + ass) / ta - iss = 1.0 / (1.0 + 2194.970764538301 * ufl.exp(0.17510068289266328 * v)) - tiF = 4.562 + delta_epi / ( - 0.14468698421272827 * ufl.exp(-0.01 * v) - + 1.6300896349780942 * ufl.exp(0.06027727546714889 * v) + xkb = 1.0 / (numpy.exp((-(v - 14.48)) / 18.34) + 1.0) + xrss = 1.0 / (numpy.exp((-(v + 8.337)) / 6.789) + 1.0) + xs1ss = 1.0 / (numpy.exp((-(v + 11.6)) / 8.932) + 1.0) + Afs = 1.0 - Aff + Ageo = L * ((2 * 3.14) * rad) + rad * ((2 * 3.14) * rad) + vcell = L * (rad * ((3.14 * 1000) * rad)) + Ahs = 1.0 - Ahf + Aw = (Tot_A * rs) / (rs + rw * (1 - rs)) + Jupnp = (0.004375 * cai) / (cai + 0.00092) + Jupp = ((0.004375 * 2.75) * cai) / ((cai + 0.00092) - 0.00017) + KsCa = 1.0 + 0.6 / ((3.8e-05 / cai) ** 1.4 + 1.0) + Bcai = 1.0 / ((cmdnmax * kmcmdn) / (cai + kmcmdn) ** 2.0 + 1.0) + Bcajsr = 1.0 / ((csqnmax * kmcsqn) / (cajsr + kmcsqn) ** 2.0 + 1.0) + Bcass = 1.0 / ( + (BSLmax * KmBSL) / (KmBSL + cass) ** 2.0 + + ((BSRmax * KmBSR) / (KmBSR + cass) ** 2.0 + 1.0) ) - tiS = 23.62 + delta_epi / ( - 0.00027617763953377436 * ufl.exp(-0.01693480101608806 * v) - + 0.024208962804604526 * ufl.exp(0.12377769525931426 * v) + Jdiff = (-cai + cass) / 0.2 + CaMKb = (CaMKo * (1.0 - CaMKt)) / (KmCaM / cass + 1.0) + rk1 = 1.0 / (numpy.exp((-2.6 * ko + (v + 105.8)) / 9.493) + 1.0) + xk1ss = 1.0 / ( + numpy.exp((-((2.5538 * ko + v) + 144.59)) / (1.5692 * ko + 3.8115)) + 1.0 + ) + EK = ((R * T) / F) * numpy.log(ko / ki) + vffrt = (F * (F * v)) / ((R * T)) + vfrt = (F * v) / ((R * T)) + EKs = ((R * T) / F) * numpy.log((PKNa * nao + ko) / (PKNa * nai + ki)) + ENa = ((R * T) / F) * numpy.log(nao / nai) + GK1 = scale_HF_GK1 * ((0.1908 * scale_IK1) * scale_drug_IK1) + GKr = (0.046 * scale_IKr) * scale_drug_IKr + GKs = (0.0034 * scale_IKs) * scale_drug_IKs + GNaL = scale_HF_GNaL * ((0.0075 * scale_INaL) * scale_drug_INaL) + km2n = 1.0 * jca + IpCa = (cai * (GpCa * scale_drug_IpCa)) / (cai + 0.0005) + Istim = 0 # (amp) * (duration >= t) + (0) * numpy.logical_not((duration >= t)) + JdiffK = (-ki + kss) / 2.0 + JdiffNa = (-nai + nass) / 2.0 + Jleak = ((0.0039375 * cansr) * scale_HF_Jleak) / 15.0 + Jtr = (-cajsr + cansr) / 100.0 + Knai = Knai0 * numpy.exp((F * (delta * v)) / (((3.0 * R) * T))) + Knao = Knao0 * numpy.exp((F * (v * (1.0 - delta))) / (((3.0 * R) * T))) + P = eP / (((H / Khp + 1.0) + nai / Knap) + ki / Kxkur) + PCa = (0.0001 * scale_ICaL) * scale_drug_ICaL + XU = -XW + (-XS + (1 - TmB)) + a2 = k2p + a4 = ((MgATP * k4p) / Kmgatp) / (1.0 + MgATP / Kmgatp) + a_rel = 0.5 * bt + btp = 1.25 * bt + tau_rel_tmp = bt / (1.0 + 0.0123 / cajsr) + allo_i = 1.0 / ((KmCaAct / cai) ** 2.0 + 1.0) + allo_ss = 1.0 / ((KmCaAct / cass) ** 2.0 + 1.0) + b1 = MgADP * k1m + ksu = (kws * rw) * (-1 + 1 / rs) + cs = ((kws * phi) * (rw * (1 - rs))) / rs + cw = ((kuw * phi) * ((1 - rs) * (1 - rw))) / ((rw * (1 - rs))) + kwu = kuw * (-1 + 1 / rw) - kws + gammasu = gammas * numpy.where( + Zetas * (Zetas > 0) > (-1 - Zetas) * (Zetas < -1), + Zetas * (Zetas > 0), + (-1 - Zetas) * (Zetas < -1), + ) + gammawu = gammaw * numpy.abs(Zetaw) + h4 = (nass / kna1) * (1 + nass / kna2) + 1.0 + h4_i = (nai / kna1) * (1 + nai / kna2) + 1.0 + h10 = (nao / kna1) * (1 + nao / kna2) + (kasymm + 1.0) + h10_i = (nao / kna1) * (1.0 + nao / kna2) + (kasymm + 1.0) + hca = numpy.exp((F * (qca * v)) / ((R * T))) + hna = numpy.exp((F * (qna * v)) / ((R * T))) + k2 = kcaoff + k2_i = kcaoff + k5 = kcaoff + k5_i = kcaoff + kb = (Trpn50**ntm * ku) / (-rw * (1 - rs) + (1 - rs)) + lambda_min12 = (lmbda) * (lmbda < 1.2) + (1.2) * numpy.logical_not( + (lmbda < 1.2), ) - AiF = 1.0 / (1.0 + 0.24348537187522867 * ufl.exp(0.006613756613756614 * v)) - AiS = 1.0 - AiF - F_expressions[11] = (-iF + iss) / tiF - F_expressions[12] = (-iS + iss) / tiS - i = AiF * iF + AiS * iS - assp = 1.0 / (1.0 + 5.167428462230666 * ufl.exp(-0.06747638326585695 * v)) - F_expressions[13] = (-ap + assp) / ta - dti_develop = 1.354 + 0.0001 / ( - 2.6591269045230603e-05 * ufl.exp(0.06293266205160478 * v) - + 4.5541779737128264e24 * ufl.exp(-4.642525533890436 * v) - ) - dti_recover = 1.0 - 0.5 / (1.0 + 33.11545195869231 * ufl.exp(0.05 * v)) - tiFp = dti_develop * dti_recover * tiF - tiSp = dti_develop * dti_recover * tiS - F_expressions[14] = (-iFp + iss) / tiFp - F_expressions[15] = (-iSp + iss) / tiSp - ip = AiF * iFp + AiS * iSp - fItop = 1.0 / (1.0 + KmCaMK / CaMKa) - Ito = ( - Gto - * scale_drug_Ito - * scale_popu_Gto - * HF_scaling_Gto - * (-EK + v) - * ((1.0 - fItop) * a * i + ap * fItop * ip) - ) - - # Expressions for the ICaL ICaNa ICaK component - dss = 1.0 / (1.0 + 0.39398514226669484 * ufl.exp(-0.23640661938534277 * v)) - td = 0.6 + 1.0 / ( - 3.5254214873653824 * ufl.exp(0.09 * v) - + 0.7408182206817179 * ufl.exp(-0.05 * v) - ) - F_expressions[16] = (-d + dss) / td - fss = 1.0 / (1.0 + 199.86038496778565 * ufl.exp(0.27056277056277056 * v)) - tff = 7.0 + 1.0 / ( - 0.03325075244518792 * ufl.exp(0.1 * v) - + 0.0006090087745647571 * ufl.exp(-0.1 * v) + thLp = scale_HF_thL * (3.0 * thL) + tiF = ( + delta_epi + * ( + 1 + / ( + 0.3933 * numpy.exp((-(v + 100.0)) / 100.0) + + 0.08004 * numpy.exp((v + 50.0) / 16.59) + ) + ) + + 4.562 ) - tfs = 1000.0 + 1.0 / ( - 1.0027667890106652e-05 * ufl.exp(-0.25 * v) - + 8.053415618124885e-05 * ufl.exp(0.16666666666666666 * v) + tiS = ( + delta_epi + * ( + 1 + / ( + 0.001416 * numpy.exp((-(v + 96.52)) / 59.05) + + 1.78e-08 * numpy.exp((v + 114.1) / 8.079) + ) + ) + + 23.62 ) - Afs = 1.0 - Aff - F_expressions[17] = (-ff + fss) / tff - F_expressions[18] = (-fs + fss) / tfs - f = Aff * ff + Afs * fs + Afcas = 1.0 - Afcaf + AiS = 1.0 - AiF + Axrs = 1.0 - Axrf fcass = fss - tfcaf = 7.0 + 1.0 / ( - 0.0708317980974062 * ufl.exp(-0.14285714285714285 * v) - + 0.02258872488031037 * ufl.exp(0.14285714285714285 * v) + dhL_dt = (-hL + hLss) / ((scale_HF_thL * thL)) + dhL_dt_linearized = -1 / (scale_HF_thL * thL) + values[0] = ( + dhL_dt * (numpy.exp(dhL_dt_linearized * dt) - 1) / dhL_dt_linearized + hL ) - tfcas = 100.0 + 1.0 / ( - 0.00012 * ufl.exp(0.14285714285714285 * v) - + 0.00012 * ufl.exp(-0.3333333333333333 * v) + jss = hss + da_dt = (-a + ass) / ta + da_dt_linearized = -1 / ta + values[1] = ( + a + da_dt * (numpy.exp(da_dt_linearized * dt) - 1) / da_dt_linearized ) - Afcaf = 0.3 + 0.6 / (1.0 + 0.36787944117144233 * ufl.exp(0.1 * v)) - Afcas = 1.0 - Afcaf - F_expressions[19] = (-fcaf + fcass) / tfcaf - F_expressions[20] = (-fcas + fcass) / tfcas - fca = Afcaf * fcaf + Afcas * fcas - F_expressions[21] = (-jca + fcass) / tjca - tffp = 2.5 * tff - F_expressions[22] = (-ffp + fss) / tffp - fp = Aff * ffp + Afs * fs - tfcafp = 2.5 * tfcaf - F_expressions[23] = (-fcafp + fcass) / tfcafp - fcap = Afcaf * fcafp + Afcas * fcas - km2n = 1.0 * jca - anca = 1.0 / (ufl.elem_pow(1.0 + Kmn / cass, 4.0) + k2n / km2n) - F_expressions[24] = k2n * anca - km2n * nca - PhiCaL = ( - 4.0 - * (-0.341 * cao + cass * ufl.exp(2.0 * vfrt)) - * vffrt - / (-1.0 + ufl.exp(2.0 * vfrt)) + dap_dt = (-ap + assp) / ta + dap_dt_linearized = -1 / ta + values[2] = ( + ap + dap_dt * (numpy.exp(dap_dt_linearized * dt) - 1) / dap_dt_linearized ) - PhiCaNa = ( - 1.0 - * (-0.75 * nao + 0.75 * ufl.exp(1.0 * vfrt) * nass) - * vffrt - / (-1.0 + ufl.exp(1.0 * vfrt)) + dd_dt = (-d + dss) / td + dd_dt_linearized = -1 / td + values[3] = ( + d + dd_dt * (numpy.exp(dd_dt_linearized * dt) - 1) / dd_dt_linearized ) - PhiCaK = ( - 1.0 - * (-0.75 * ko + 0.75 * ufl.exp(1.0 * vfrt) * kss) - * vffrt - / (-1.0 + ufl.exp(1.0 * vfrt)) + tfcafp = 2.5 * tfcaf + tffp = 2.5 * tff + dff_dt = (-ff + fss) / tff + dff_dt_linearized = -1 / tff + values[4] = ( + dff_dt * (numpy.exp(dff_dt_linearized * dt) - 1) / dff_dt_linearized + ff ) - PCa = 0.0001 * scale_ICaL * scale_drug_ICaL * scale_popu_GCaL - PCap = 1.1 * PCa - PCaNa = 0.00125 * PCa - PCaK = 0.0003574 * PCa - PCaNap = 0.00125 * PCap - PCaKp = 0.0003574 * PCap - fICaLp = 1.0 / (1.0 + KmCaMK / CaMKa) - ICaL = (1.0 - fICaLp) * ( - (1.0 - nca) * f + fca * jca * nca - ) * PCa * PhiCaL * d + ( - (1.0 - nca) * fp + fcap * jca * nca - ) * PCap * PhiCaL * d * fICaLp - ICaNa = (1.0 - fICaLp) * ( - (1.0 - nca) * f + fca * jca * nca - ) * PCaNa * PhiCaNa * d + ( - (1.0 - nca) * fp + fcap * jca * nca - ) * PCaNap * PhiCaNa * d * fICaLp - ICaK = (1.0 - fICaLp) * ( - (1.0 - nca) * f + fca * jca * nca - ) * PCaK * PhiCaK * d + ( - (1.0 - nca) * fp + fcap * jca * nca - ) * PCaKp * PhiCaK * d * fICaLp - - # Expressions for the IKr component - xrss = 1.0 / (1.0 + 0.29287308872377504 * ufl.exp(-0.14729709824716453 * v)) - txrf = 12.98 + 1.0 / ( - 0.0001020239312894894 * ufl.exp(0.25846471956577927 * v) - + 0.00042992960891929087 * ufl.exp(-0.04906771344455348 * v) + dfs_dt = (-fs + fss) / tfs + dfs_dt_linearized = -1 / tfs + values[5] = ( + dfs_dt * (numpy.exp(dfs_dt_linearized * dt) - 1) / dfs_dt_linearized + fs ) - txrs = 1.865 + 1.0 / ( - 0.0005922420036809394 * ufl.exp(0.13596193065941536 * v) - + 3.549966111802463e-05 * ufl.exp(-0.03855050115651503 * v) + dhf_dt = (-hf + hss) / thf + dhf_dt_linearized = -1 / thf + values[6] = ( + dhf_dt * (numpy.exp(dhf_dt_linearized * dt) - 1) / dhf_dt_linearized + hf ) - Axrf = 1.0 / (1.0 + 4.197299094734718 * ufl.exp(0.02617115938236064 * v)) - Axrs = 1.0 - Axrf - F_expressions[25] = (-xrf + xrss) / txrf - F_expressions[26] = (-xrs + xrss) / txrs - xr = Axrf * xrf + Axrs * xrs - rkr = 1.0 / ( - (1.0 + 2.0820090840784555 * ufl.exp(0.013333333333333334 * v)) - * (1.0 + 0.7165313105737893 * ufl.exp(0.03333333333333333 * v)) + thsp = 3.0 * ths + dhs_dt = (-hs + hss) / ths + dhs_dt_linearized = -1 / ths + values[7] = ( + dhs_dt * (numpy.exp(dhs_dt_linearized * dt) - 1) / dhs_dt_linearized + hs ) - GKr = 0.046 * scale_IKr * scale_drug_IKr * scale_popu_GKr - IKr = 0.4303314829119352 * ufl.sqrt(ko) * (-EK + v) * GKr * rkr * xr - - # Expressions for the IKs component - xs1ss = 1.0 / (1.0 + 0.27288596035656526 * ufl.exp(-0.11195700850873264 * v)) - txs1 = 817.3 + 1.0 / ( - 0.003504067763074858 * ufl.exp(0.056179775280898875 * v) - + 0.0005184809083581659 * ufl.exp(-0.004347826086956522 * v) + tjp = 1.46 * tj + tmL = tm + dm_dt = (-m + mss) / tm + dm_dt_linearized = -1 / tm + values[8] = ( + dm_dt * (numpy.exp(dm_dt_linearized * dt) - 1) / dm_dt_linearized + m + ) + dxrf_dt = (-xrf + xrss) / txrf + dxrf_dt_linearized = -1 / txrf + values[9] = ( + dxrf_dt * (numpy.exp(dt * dxrf_dt_linearized) - 1) / dxrf_dt_linearized + + xrf + ) + dxrs_dt = (-xrs + xrss) / txrs + dxrs_dt_linearized = -1 / txrs + values[10] = ( + dxrs_dt * (numpy.exp(dt * dxrs_dt_linearized) - 1) / dxrs_dt_linearized + + xrs ) - F_expressions[27] = (-xs1 + xs1ss) / txs1 xs2ss = xs1ss - txs2 = 1.0 / ( - 0.0022561357010639103 * ufl.exp(-0.03225806451612903 * v) - + 0.0008208499862389881 * ufl.exp(0.05 * v) + dxs1_dt = (-xs1 + xs1ss) / txs1 + dxs1_dt_linearized = -1 / txs1 + values[11] = ( + dxs1_dt * (numpy.exp(dt * dxs1_dt_linearized) - 1) / dxs1_dt_linearized + + xs1 ) - F_expressions[28] = (-xs2 + xs2ss) / txs2 - KsCa = 1.0 + 0.6 / (1.0 + 6.481821026062645e-07 * ufl.elem_pow(1.0 / cai, 1.4)) - GKs = 0.0034 * scale_IKs * scale_drug_IKs * scale_popu_GKs - IKs = (-EKs + v) * GKs * KsCa * xs1 * xs2 - xk1ss = 1.0 / ( - 1.0 + ufl.exp((-144.59 - v - 2.5538 * ko) / (3.8115 + 1.5692 * ko)) + f = Aff * ff + Afs * fs + fp = Aff * ffp + Afs * fs + Acap = 2 * Ageo + vjsr = 0.0048 * vcell + vmyo = 0.68 * vcell + vnsr = 0.0552 * vcell + vss = 0.02 * vcell + h = Ahf * hf + Ahs * hs + hp = Ahf * hf + Ahs * hsp + As = Aw + CaMKa = scale_HF_CaMKa * (CaMKb + CaMKt) + dCaMKt_dt = -CaMKt * bCaMK + (CaMKb * aCaMK) * (CaMKb + CaMKt) + dCaMKt_dt_linearized = CaMKb * aCaMK - bCaMK + values[12] = ( + CaMKt + + dCaMKt_dt + * (numpy.exp(dCaMKt_dt_linearized * dt) - 1) + / dCaMKt_dt_linearized + * (numpy.abs(dCaMKt_dt_linearized) > 1e-08) + + dCaMKt_dt * dt * (~(numpy.abs(dCaMKt_dt_linearized) > 1e-08)) + ) + dxk1_dt = (-xk1 + xk1ss) / txk1 + dxk1_dt_linearized = -1 / txk1 + values[13] = ( + dxk1_dt * (numpy.exp(dt * dxk1_dt_linearized) - 1) / dxk1_dt_linearized + + xk1 + ) + IKb = (xkb * (GKb * scale_drug_IKb)) * (-EK + v) + ICab = ( + (vffrt * (4.0 * (PCab * scale_drug_ICab))) + * (cai * numpy.exp(2.0 * vfrt) - 0.341 * cao) + ) / (numpy.exp(2.0 * vfrt) - 1.0) + INab = ((vffrt * (PNab * scale_drug_INab)) * (nai * numpy.exp(vfrt) - nao)) / ( + numpy.exp(vfrt) - 1.0 ) - txk1 = 122.2 / ( - 0.0019352007631390235 * ufl.exp(-0.049115913555992145 * v) - + 30.43364757524903 * ufl.exp(0.014423770373575654 * v) - ) - F_expressions[29] = (-xk1 + xk1ss) / txk1 - rk1 = 1.0 / ( - 1.0 - + 69220.6322106767 - * ufl.exp(0.10534077741493732 * v - 0.27388602127883704 * ko) - ) - GK1 = 0.1908 * scale_IK1 * scale_drug_IK1 * scale_popu_GK1 * HF_scaling_GK1 - IK1 = ufl.sqrt(ko) * (-EK + v) * GK1 * rk1 * xk1 - - # Expressions for the INaCa_i component - hca = ufl.exp(F * qca * v / (R * T)) - hna = ufl.exp(F * qna * v / (R * T)) - h1_i = 1.0 + (1.0 + hna) * nai / kna3 - h2_i = hna * nai / (kna3 * h1_i) - h3_i = 1.0 / h1_i - h4_i = 1.0 + (1 + nai / kna2) * nai / kna1 - h5_i = (nai * nai) / (kna1 * kna2 * h4_i) - h6_i = 1.0 / h4_i - h7_i = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 - h8_i = nao / (kna3 * h7_i * hna) - h9_i = 1.0 / h7_i - h10_i = 1.0 + kasymm + nao * (1.0 + nao / kna2) / kna1 - h11_i = (nao * nao) / (kna1 * kna2 * h10_i) - h12_i = 1.0 / h10_i - k1_i = cao * kcaon * h12_i - k2_i = kcaoff - k3p_i = wca * h9_i - k3pp_i = wnaca * h8_i - k3_i = k3p_i + k3pp_i - k4p_i = wca * h3_i / hca - k4pp_i = wnaca * h2_i - k4_i = k4p_i + k4pp_i - k5_i = kcaoff - k6_i = kcaon * cai * h6_i - k7_i = wna * h2_i * h5_i - k8_i = wna * h11_i * h8_i - x1_i = (k2_i + k3_i) * k5_i * k7_i + (k6_i + k7_i) * k2_i * k4_i - x2_i = (k1_i + k8_i) * k4_i * k6_i + (k4_i + k5_i) * k1_i * k7_i - x3_i = (k2_i + k3_i) * k6_i * k8_i + (k6_i + k7_i) * k1_i * k3_i - x4_i = (k1_i + k8_i) * k3_i * k5_i + (k4_i + k5_i) * k2_i * k8_i - E1_i = x1_i / (x1_i + x2_i + x3_i + x4_i) - E2_i = x2_i / (x1_i + x2_i + x3_i + x4_i) - E3_i = x3_i / (x1_i + x2_i + x3_i + x4_i) - E4_i = x4_i / (x1_i + x2_i + x3_i + x4_i) - allo_i = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cai, 2.0)) - zna = 1.0 - JncxNa_i = E3_i * k4pp_i - E2_i * k3pp_i + 3.0 * E4_i * k7_i - 3.0 * E1_i * k8_i - JncxCa_i = E2_i * k2_i - E1_i * k1_i - INaCa_i = ( - 0.8 - * Gncx - * scale_popu_KNCX - * HF_scaling_Gncx - * (zca * JncxCa_i + zna * JncxNa_i) - * allo_i - ) - - # Expressions for the INaCa_ss component - h1 = 1.0 + (1.0 + hna) * nass / kna3 - h2 = hna * nass / (kna3 * h1) - h3 = 1.0 / h1 - h4 = 1.0 + (1 + nass / kna2) * nass / kna1 - h5 = (nass * nass) / (kna1 * kna2 * h4) - h6 = 1.0 / h4 - h7 = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 - h8 = nao / (kna3 * h7 * hna) - h9 = 1.0 / h7 - h10 = 1.0 + kasymm + nao * (1 + nao / kna2) / kna1 - h11 = (nao * nao) / (kna1 * kna2 * h10) - h12 = 1.0 / h10 - k1 = cao * kcaon * h12 - k2 = kcaoff - k3p_ss = wca * h9 - k3pp = wnaca * h8 - k3 = k3p_ss + k3pp - k4p_ss = wca * h3 / hca - k4pp = wnaca * h2 - k4 = k4p_ss + k4pp - k5 = kcaoff - k6 = kcaon * cass * h6 - k7 = wna * h2 * h5 - k8 = wna * h11 * h8 - x1_ss = (k2 + k3) * k5 * k7 + (k6 + k7) * k2 * k4 - x2_ss = (k1 + k8) * k4 * k6 + (k4 + k5) * k1 * k7 - x3_ss = (k2 + k3) * k6 * k8 + (k6 + k7) * k1 * k3 - x4_ss = (k1 + k8) * k3 * k5 + (k4 + k5) * k2 * k8 - E1_ss = x1_ss / (x1_ss + x2_ss + x3_ss + x4_ss) - E2_ss = x2_ss / (x1_ss + x2_ss + x3_ss + x4_ss) - E3_ss = x3_ss / (x1_ss + x2_ss + x3_ss + x4_ss) - E4_ss = x4_ss / (x1_ss + x2_ss + x3_ss + x4_ss) - allo_ss = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cass, 2.0)) - JncxNa_ss = E3_ss * k4pp - E2_ss * k3pp + 3.0 * E4_ss * k7 - 3.0 * E1_ss * k8 - JncxCa_ss = E2_ss * k2 - E1_ss * k1 - INaCa_ss = ( - 0.2 - * Gncx - * scale_popu_KNCX - * HF_scaling_Gncx - * (zca * JncxCa_ss + zna * JncxNa_ss) - * allo_ss - ) - - # Expressions for the INaK component - Knai = Knai0 * ufl.exp(0.3333333333333333 * F * delta * v / (R * T)) - Knao = Knao0 * ufl.exp(0.3333333333333333 * F * (1.0 - delta) * v / (R * T)) - P = eP / (1.0 + H / Khp + nai / Knap + ki / Kxkur) - a1 = ( - k1p - * ufl.elem_pow(nai / Knai, 3.0) - / ( - -1.0 - + ufl.elem_pow(1.0 + ki / Kki, 2.0) - + ufl.elem_pow(1.0 + nai / Knai, 3.0) - ) + PhiCaK = ( + (1.0 * vffrt) * (-0.75 * ko + (0.75 * kss) * numpy.exp(1.0 * vfrt)) + ) / (numpy.exp(1.0 * vfrt) - 1.0) + PhiCaL = ((4.0 * vffrt) * (-0.341 * cao + cass * numpy.exp(2.0 * vfrt))) / ( + numpy.exp(2.0 * vfrt) - 1.0 ) - b1 = MgADP * k1m - a2 = k2p - b2 = ( - k2m - * ufl.elem_pow(nao / Knao, 3.0) - / ( - -1.0 - + ufl.elem_pow(1.0 + ko / Kko, 2.0) - + ufl.elem_pow(1.0 + nao / Knao, 3.0) - ) + PhiCaNa = ( + (1.0 * vffrt) * (-0.75 * nao + (0.75 * nass) * numpy.exp(1.0 * vfrt)) + ) / (numpy.exp(1.0 * vfrt) - 1.0) + IK1 = (xk1 * (rk1 * (GK1 * math.sqrt(ko)))) * (-EK + v) + IKs = (xs2 * (xs1 * (GKs * KsCa))) * (-EKs + v) + anca = 1.0 / (k2n / km2n + (Kmn / cass + 1.0) ** 4.0) + a1 = (k1p * (nai / Knai) ** 3.0) / ( + ((1.0 + ki / Kki) ** 2.0 + (1.0 + nai / Knai) ** 3.0) - 1.0 ) - a3 = ( - k3p - * ufl.elem_pow(ko / Kko, 2.0) - / ( - -1.0 - + ufl.elem_pow(1.0 + ko / Kko, 2.0) - + ufl.elem_pow(1.0 + nao / Knao, 3.0) - ) + b4 = (k4m * (ki / Kki) ** 2.0) / ( + ((1.0 + ki / Kki) ** 2.0 + (1.0 + nai / Knai) ** 3.0) - 1.0 ) - b3 = H * k3m * P / (1.0 + MgATP / Kmgatp) - a4 = MgATP * k4p / (Kmgatp * (1.0 + MgATP / Kmgatp)) - b4 = ( - k4m - * ufl.elem_pow(ki / Kki, 2.0) - / ( - -1.0 - + ufl.elem_pow(1.0 + ki / Kki, 2.0) - + ufl.elem_pow(1.0 + nai / Knai, 3.0) - ) + a3 = (k3p * (ko / Kko) ** 2.0) / ( + ((1.0 + ko / Kko) ** 2.0 + (1.0 + nao / Knao) ** 3.0) - 1.0 ) - x1 = a1 * a2 * a4 + a1 * a2 * b3 + a2 * b3 * b4 + b2 * b3 * b4 - x2 = a1 * a2 * a3 + a2 * a3 * b4 + a3 * b1 * b4 + b1 * b2 * b4 - x3 = a2 * a3 * a4 + a3 * a4 * b1 + a4 * b1 * b2 + b1 * b2 * b3 - x4 = a1 * a3 * a4 + a1 * a4 * b2 + a1 * b2 * b3 + b2 * b3 * b4 - E1 = x1 / (x1 + x2 + x3 + x4) - E2 = x2 / (x1 + x2 + x3 + x4) - E3 = x3 / (x1 + x2 + x3 + x4) - E4 = x4 / (x1 + x2 + x3 + x4) - JnakNa = 3.0 * E1 * a3 - 3.0 * E2 * b3 - JnakK = 2.0 * E4 * b1 - 2.0 * E3 * a1 - INaK = Pnak * scale_popu_KNaK * HF_scaling_Pnak * (zk * JnakK + zna * JnakNa) - - # Expressions for the IKb component - xkb = 1.0 / (1.0 + 2.202363450949239 * ufl.exp(-0.05452562704471101 * v)) - IKb = GKb * scale_popu_GbK * scale_drug_IKb * (-EK + v) * xkb - - # Expressions for the INab component - INab = ( - PNab - * scale_drug_INab - * scale_popu_GbNa - * (-nao + ufl.exp(vfrt) * nai) - * vffrt - / (-1.0 + ufl.exp(vfrt)) - ) - - # Expressions for the ICab component - ICab = ( - 4.0 - * PCab - * scale_drug_ICab - * scale_popu_GbCa - * (-0.341 * cao + cai * ufl.exp(2.0 * vfrt)) - * vffrt - / (-1.0 + ufl.exp(2.0 * vfrt)) - ) - - # Expressions for the IpCa component - IpCa = GpCa * scale_drug_IpCa * scale_popu_KpCa * cai / (0.0005 + cai) - - # Expressions for the Isac (Pueyo)--> ns + k component - Gsac_ns = 0.006 * scale_drug_Isacns - Esac_ns = -10.0 - lambda_max = 1.1 - Gsac_k = (0.2882 * 800.0 / 210.0) * scale_drug_Isack # Pueyo endo - Isac_P_ns = ufl.conditional( - ufl.lt(self.lmbda, 1.0), - 0.0, - Gsac_ns * ((self.lmbda - 1.0) / (lambda_max - 1.0)) * (v - Esac_ns), - ) - Isac_P_k = ufl.conditional( - ufl.lt(self.lmbda, 1.0), - 0.0, - Gsac_k - * ((self.lmbda - 1.0) / (lambda_max - 1.0)) - * (1.0 / (1.0 + ufl.exp((19.05 - v) / (29.98)))), - ) - - # Expressions for the Istim component - Istim = 0 # amp*(ufl.le(time, duration)) - - # Expressions for the diffusion fluxes component - JdiffNa = 0.5 * nass - 0.5 * nai - JdiffK = 0.5 * kss - 0.5 * ki - Jdiff = 5.0 * cass - 5.0 * cai - - # Expressions for the ryanodine receptor component - a_rel = 0.5 * bt - Jrel_inf = ( - -ICaL - * a_rel - / (1.0 + 25.62890625 * HF_scaling_Jrel_inf * ufl.elem_pow(1.0 / cajsr, 8.0)) + b2 = (k2m * (nao / Knao) ** 3.0) / ( + ((1.0 + ko / Kko) ** 2.0 + (1.0 + nao / Knao) ** 3.0) - 1.0 ) - tau_rel_tmp = bt / (1.0 + 0.0123 / cajsr) - tau_rel = ufl.conditional(ufl.lt(tau_rel_tmp, 0.001), 0.001, tau_rel_tmp) - F_expressions[30] = (-Jrelnp + Jrel_inf) / tau_rel - btp = 1.25 * bt + b3 = (H * (P * k3m)) / (1.0 + MgATP / Kmgatp) + PCaK = 0.0003574 * PCa + PCaNa = 0.00125 * PCa + PCap = 1.1 * PCa a_relp = 0.5 * btp - Jrel_infp = ( - -ICaL - * a_relp - / (1.0 + 25.62890625 * HF_scaling_Jrel_inf * ufl.elem_pow(1.0 / cajsr, 8.0)) - ) tau_relp_tmp = btp / (1.0 + 0.0123 / cajsr) - tau_relp = ufl.conditional(ufl.lt(tau_relp_tmp, 0.001), 0.001, tau_relp_tmp) - F_expressions[31] = (-Jrelp + Jrel_infp) / tau_relp + tau_rel = (0.001) * (tau_rel_tmp < 0.001) + (tau_rel_tmp) * numpy.logical_not( + (tau_rel_tmp < 0.001), + ) + # dZetaw_dt = Aw * dLambda - Zetaw * cw + # dZetaw_dt_linearized = -cw + # values[14] = ( + # Zetaw + # + dZetaw_dt + # * (numpy.exp(dZetaw_dt_linearized * dt) - 1) + # / dZetaw_dt_linearized + # * (numpy.abs(dZetaw_dt_linearized) > 1e-08) + # + dZetaw_dt * dt * (~(numpy.abs(dZetaw_dt_linearized) > 1e-08)) + # ) + dXS_dt = -XS * gammasu + (-XS * ksu + XW * kws) + dXS_dt_linearized = -gammasu - ksu + values[15] = ( + XS + + dXS_dt + * (numpy.exp(dXS_dt_linearized * dt) - 1) + / dXS_dt_linearized + * (numpy.abs(dXS_dt_linearized) > 1e-08) + + dXS_dt * dt * (~(numpy.abs(dXS_dt_linearized) > 1e-08)) + ) + dXW_dt = -XW * gammawu + (-XW * kws + (XU * kuw - XW * kwu)) + dXW_dt_linearized = -gammawu - kws - kwu + values[16] = ( + XW + + dXW_dt + * (numpy.exp(dXW_dt_linearized * dt) - 1) + / dXW_dt_linearized + * (numpy.abs(dXW_dt_linearized) > 1e-08) + + dXW_dt * dt * (~(numpy.abs(dXW_dt_linearized) > 1e-08)) + ) + h5 = (nass * nass) / ((kna2 * (h4 * kna1))) + h6 = 1.0 / h4 + h5_i = (nai * nai) / ((kna2 * (h4_i * kna1))) + h6_i = 1.0 / h4_i + h11 = (nao * nao) / ((kna2 * (h10 * kna1))) + h12 = 1.0 / h10 + h11_i = (nao * nao) / ((kna2 * (h10_i * kna1))) + h12_i = 1.0 / h10_i + h1 = (nass / kna3) * (hna + 1) + 1 + h1_i = (nai / kna3) * (hna + 1) + 1 + h7 = (nao / kna3) * (1.0 + 1.0 / hna) + 1.0 + h7_i = (nao / kna3) * (1.0 + 1.0 / hna) + 1.0 + dTmB_dt = -TmB * CaTrpn ** (ntm / 2) * ku + XU * ( + kb + * numpy.where( + (CaTrpn ** (-1 / 2 * ntm) < 100), + CaTrpn ** (-1 / 2 * ntm), + 100, + ) + ) + dTmB_dt_linearized = numpy.where( + numpy.isclose(CaTrpn, 0), + 0, + -(CaTrpn ** (ntm / 2)) * ku, + ) + values[17] = ( + TmB + + dTmB_dt + * (numpy.exp(dTmB_dt_linearized * dt) - 1) + / dTmB_dt_linearized + * (numpy.abs(dTmB_dt_linearized) > 1e-08) + + dTmB_dt * dt * (~(numpy.abs(dTmB_dt_linearized) > 1e-08)) + ) + C = lambda_min12 - 1 + cat50 = scale_HF_cat50_ref * (Beta1 * (lambda_min12 - 1) + cat50_ref) + lambda_min087 = (lambda_min12) * (lambda_min12 < 0.87) + ( + 0.87 + ) * numpy.logical_not((lambda_min12 < 0.87)) + dhLp_dt = (-hLp + hLssp) / thLp + dhLp_dt_linearized = -1 / thLp + values[18] = ( + dhLp_dt * (numpy.exp(dhLp_dt_linearized * dt) - 1) / dhLp_dt_linearized + + hLp + ) + tiFp = tiF * (dti_develop * dti_recover) + diF_dt = (-iF + iss) / tiF + diF_dt_linearized = -1 / tiF + values[19] = ( + diF_dt * (numpy.exp(diF_dt_linearized * dt) - 1) / diF_dt_linearized + iF + ) + tiSp = tiS * (dti_develop * dti_recover) + diS_dt = (-iS + iss) / tiS + diS_dt_linearized = -1 / tiS + values[20] = ( + diS_dt * (numpy.exp(diS_dt_linearized * dt) - 1) / diS_dt_linearized + iS + ) + fca = Afcaf * fcaf + Afcas * fcas + fcap = Afcaf * fcafp + Afcas * fcas + i = AiF * iF + AiS * iS + ip = AiF * iFp + AiS * iSp + xr = Axrf * xrf + Axrs * xrs + dfcaf_dt = (-fcaf + fcass) / tfcaf + dfcaf_dt_linearized = -1 / tfcaf + values[21] = ( + dfcaf_dt * (numpy.exp(dfcaf_dt_linearized * dt) - 1) / dfcaf_dt_linearized + + fcaf + ) + dfcas_dt = (-fcas + fcass) / tfcas + dfcas_dt_linearized = -1 / tfcas + values[22] = ( + dfcas_dt * (numpy.exp(dfcas_dt_linearized * dt) - 1) / dfcas_dt_linearized + + fcas + ) + djca_dt = (fcass - jca) / tjca + djca_dt_linearized = -1 / tjca + values[23] = ( + djca_dt * (numpy.exp(djca_dt_linearized * dt) - 1) / djca_dt_linearized + + jca + ) + dj_dt = (-j + jss) / tj + dj_dt_linearized = -1 / tj + values[24] = ( + dj_dt * (numpy.exp(dj_dt_linearized * dt) - 1) / dj_dt_linearized + j + ) + dfcafp_dt = (-fcafp + fcass) / tfcafp + dfcafp_dt_linearized = -1 / tfcafp + values[25] = ( + dfcafp_dt + * (numpy.exp(dfcafp_dt_linearized * dt) - 1) + / dfcafp_dt_linearized + + fcafp + ) + dffp_dt = (-ffp + fss) / tffp + dffp_dt_linearized = -1 / tffp + values[26] = ( + dffp_dt * (numpy.exp(dffp_dt_linearized * dt) - 1) / dffp_dt_linearized + + ffp + ) + dhsp_dt = (-hsp + hssp) / thsp + dhsp_dt_linearized = -1 / thsp + values[27] = ( + dhsp_dt * (numpy.exp(dhsp_dt_linearized * dt) - 1) / dhsp_dt_linearized + + hsp + ) + djp_dt = (-jp + jss) / tjp + djp_dt_linearized = -1 / tjp + values[28] = ( + djp_dt * (numpy.exp(djp_dt_linearized * dt) - 1) / djp_dt_linearized + jp + ) + dmL_dt = (-mL + mLss) / tmL + dmL_dt_linearized = -1 / tmL + values[29] = ( + dmL_dt * (numpy.exp(dmL_dt_linearized * dt) - 1) / dmL_dt_linearized + mL + ) + dxs2_dt = (-xs2 + xs2ss) / txs2 + dxs2_dt_linearized = -1 / txs2 + values[30] = ( + dxs2_dt * (numpy.exp(dt * dxs2_dt_linearized) - 1) / dxs2_dt_linearized + + xs2 + ) + # dZetas_dt = As * dLambda - Zetas * cs + # dZetas_dt_linearized = -cs + # values[31] = ( + # Zetas + # + dZetas_dt + # * (numpy.exp(dZetas_dt_linearized * dt) - 1) + # / dZetas_dt_linearized + # * (numpy.abs(dZetas_dt_linearized) > 1e-08) + # + dZetas_dt * dt * (~(numpy.abs(dZetas_dt_linearized) > 1e-08)) + # ) + fICaLp = 1.0 / (1.0 + KmCaMK / CaMKa) + fINaLp = 1.0 / (1.0 + KmCaMK / CaMKa) + fINap = 1.0 / (1.0 + KmCaMK / CaMKa) + fItop = 1.0 / (1.0 + KmCaMK / CaMKa) fJrelp = 1.0 / (1.0 + KmCaMK / CaMKa) - Jrel = ((1.0 - fJrelp) * Jrelnp + Jrelp * fJrelp) * scale_popu_KRyR - - # Expressions for the calcium buffers component - Jupnp = 0.004375 * cai / (0.00092 + cai) - Jupp = 0.01203125 * cai / (0.00075 + cai) fJupp = 1.0 / (1.0 + KmCaMK / CaMKa) - Jleak = 0.0002625 * cansr * scale_popu_Kleak * HF_scaling_Jleak - Jup = ( - -Jleak - + ((1.0 - fJupp) * Jupnp + Jupp * fJupp) - * scale_popu_KSERCA - * HF_scaling_Jup - ) - Jtr = 0.01 * cansr - 0.01 * cajsr - - # Expressions for the intracellular concentrations component - F_expressions[32] = JdiffNa * vss / vmyo + ( - -INa - INaL - INab - Isac_P_ns / 3.0 - 3.0 * INaCa_i - 3.0 * INaK - ) * Acap / (F * vmyo) - F_expressions[33] = -JdiffNa + (-ICaNa - 3.0 * INaCa_ss) * Acap / (F * vss) - F_expressions[34] = JdiffK * vss / vmyo + ( - -Isac_P_k - - IK1 - - IKb - - IKr - - IKs - - Istim - - Ito - - Isac_P_ns / 3.0 - + 2.0 * INaK - ) * Acap / (F * vmyo) - F_expressions[35] = -JdiffK - Acap * ICaK / (F * vss) - Bcass = 1.0 / ( - 1.0 - + BSLmax * KmBSL * ufl.elem_pow(KmBSL + cass, -2.0) - + BSRmax * KmBSR * ufl.elem_pow(KmBSR + cass, -2.0) - ) - F_expressions[36] = ( - -Jdiff - + Jrel * vjsr / vss - + 0.5 * (-ICaL + 2.0 * INaCa_ss) * Acap / (F * vss) - ) * Bcass - F_expressions[37] = -Jtr * vjsr / vnsr + Jup - Bcajsr = 1.0 / (1.0 + csqnmax * kmcsqn * ufl.elem_pow(kmcsqn + cajsr, -2.0)) - F_expressions[38] = (-Jrel + Jtr) * Bcajsr - - # Expressions for the mechanics component - kwu = -kws * scale_popu_kws + (kuw * scale_popu_kuw) * ( - -1.0 + 1.0 / (rw * scale_popu_rw) - ) - ksu = ( - kws - * scale_popu_kws - * rw - * scale_popu_rw - * (-1.0 + 1.0 / (rs * scale_popu_rs)) - ) - - lambda_min12 = ufl.conditional(ufl.lt(self.lmbda, 1.2), self.lmbda, 1.2) - XS = ufl.conditional(ufl.lt(XS, 0.0), 0.0, XS) - XW = ufl.conditional(ufl.lt(XW, 0.0), 0.0, XW) - - XU = 1.0 - TmB - XS - XW - gammawu = gammaw * abs(self.Zetaw) - # gammasu = gammas*ufl.conditional(ufl.gt(Zetas*(ufl.gt(Zetas, 0)), (-1 -\ - # Zetas)*(ufl.lt(Zetas, -1))), Zetas*(ufl.gt(Zetas, 0)), (-1 -\ - # Zetas)*(ufl.lt(Zetas, -1))) - zetas1 = self.Zetas * ufl.conditional(ufl.gt(self.Zetas, 0.0), 1.0, 0.0) - zetas2 = (-1.0 - self.Zetas) * ufl.conditional( - ufl.lt(self.Zetas, -1.0), - 1.0, - 0.0, - ) - gammasu = gammas * Max(zetas1, zetas2) - - F_expressions[39] = kws * scale_popu_kws * XW - XS * gammasu - XS * ksu - F_expressions[40] = ( - kuw * scale_popu_kuw * XU - - kws * scale_popu_kws * XW - - XW * gammawu - - XW * kwu - ) - cat50 = ( - cat50_ref * scale_popu_CaT50ref + Beta1 * (-1.0 + lambda_min12) - ) * HF_scaling_cat50_ref - CaTrpn = ufl.conditional(ufl.lt(CaTrpn, 0.0), 0.0, CaTrpn) - F_expressions[41] = ( - ktrpn - * scale_popu_kTRPN + dnca_dt = anca * k2n - km2n * nca + dnca_dt_linearized = -km2n + values[32] = ( + nca + + dnca_dt + * (numpy.exp(dnca_dt_linearized * dt) - 1) + / dnca_dt_linearized + * (numpy.abs(dnca_dt_linearized) > 1e-08) + + dnca_dt * dt * (~(numpy.abs(dnca_dt_linearized) > 1e-08)) + ) + x2 = b4 * (a2 * a3) + (b4 * (a3 * b1) + (a3 * (a1 * a2) + b4 * (b1 * b2))) + x1 = a2 * (a1 * b3) + (b3 * (a2 * b4) + (a2 * (a1 * a4) + b3 * (b2 * b4))) + x3 = b1 * (a3 * a4) + (a4 * (b1 * b2) + (a4 * (a2 * a3) + b1 * (b2 * b3))) + x4 = a1 * (b2 * b3) + (a1 * (a4 * b2) + (a1 * (a3 * a4) + b2 * (b3 * b4))) + PCaKp = 0.0003574 * PCap + PCaNap = 0.00125 * PCap + tau_relp = (0.001) * (tau_relp_tmp < 0.001) + ( + tau_relp_tmp + ) * numpy.logical_not((tau_relp_tmp < 0.001)) + k6 = kcaon * (cass * h6) + k6_i = kcaon * (cai * h6_i) + k1 = kcaon * (cao * h12) + k1_i = kcaon * (cao * h12_i) + h2 = (hna * nass) / ((h1 * kna3)) + h3 = 1.0 / h1 + h2_i = (hna * nai) / ((h1_i * kna3)) + h3_i = 1.0 / h1_i + h8 = nao / ((h7 * (hna * kna3))) + h9 = 1.0 / h7 + h8_i = nao / ((h7_i * (hna * kna3))) + h9_i = 1.0 / h7_i + # F1 = numpy.exp(C * p_b) - 1 + dCd = C - Cd + + dCaTrpn_dt = ktrpn * (-CaTrpn + ((1000 * cai) / cat50) ** ntrpn * (1 - CaTrpn)) + dCaTrpn_dt_linearized = ktrpn * (-(((1000 * cai) / cat50) ** ntrpn) - 1) + values[33] = ( + CaTrpn + + dCaTrpn_dt + * (numpy.exp(dCaTrpn_dt_linearized * dt) - 1) + / dCaTrpn_dt_linearized + * (numpy.abs(dCaTrpn_dt_linearized) > 1e-08) + + dCaTrpn_dt * dt * (~(numpy.abs(dCaTrpn_dt_linearized) > 1e-08)) + ) + # h_lambda_prima = Beta0 * ((lambda_min087 + lambda_min12) - 1.87) + 1 + diFp_dt = (-iFp + iss) / tiFp + diFp_dt_linearized = -1 / tiFp + values[34] = ( + diFp_dt * (numpy.exp(diFp_dt_linearized * dt) - 1) / diFp_dt_linearized + + iFp + ) + diSp_dt = (-iSp + iss) / tiSp + diSp_dt_linearized = -1 / tiSp + values[35] = ( + diSp_dt * (numpy.exp(diSp_dt_linearized * dt) - 1) / diSp_dt_linearized + + iSp + ) + IKr = (rkr * (xr * (GKr * (0.4303314829119352 * math.sqrt(ko))))) * (-EK + v) + ICaL = (d * (PhiCaL * (PCa * (1.0 - fICaLp)))) * ( + f * (1.0 - nca) + nca * (fca * jca) + ) + (d * (PhiCaL * (PCap * fICaLp))) * (fp * (1.0 - nca) + nca * (fcap * jca)) + INaL = (mL * (GNaL * (-ENa + v))) * (fINaLp * hLp + hL * (1.0 - fINaLp)) + INa = (m**3.0 * ((GNa * scale_drug_INa) * (-ENa + v))) * ( + j * (h * (1.0 - fINap)) + jp * (fINap * hp) + ) + Ito = ((scale_HF_Gto * (Gto * scale_drug_Ito)) * (-EK + v)) * ( + i * (a * (1.0 - fItop)) + ip * (ap * fItop) + ) + Jrel = Jrelnp * (1.0 - fJrelp) + Jrelp * fJrelp + Jup = -Jleak + (Jupnp * (1.0 - fJupp) + scale_HF_Jup * (Jupp * fJupp)) + E1 = x1 / (x4 + (x3 + (x1 + x2))) + E2 = x2 / (x4 + (x3 + (x1 + x2))) + E3 = x3 / (x4 + (x3 + (x1 + x2))) + E4 = x4 / (x4 + (x3 + (x1 + x2))) + ICaK = (d * (PhiCaK * (PCaK * (1.0 - fICaLp)))) * ( + f * (1.0 - nca) + nca * (fca * jca) + ) + (d * (PhiCaK * (PCaKp * fICaLp))) * (fp * (1.0 - nca) + nca * (fcap * jca)) + ICaNa = (d * (PhiCaNa * (PCaNa * (1.0 - fICaLp)))) * ( + f * (1.0 - nca) + nca * (fca * jca) + ) + (d * (PhiCaNa * (PCaNap * fICaLp))) * ( + fp * (1.0 - nca) + nca * (fcap * jca) + ) + k4pp = h2 * wnaca + k7 = wna * (h2 * h5) + k4p_ss = (h3 * wca) / hca + k4pp_i = h2_i * wnaca + k7_i = wna * (h2_i * h5_i) + k4p_i = (h3_i * wca) / hca + k3pp = h8 * wnaca + k8 = wna * (h11 * h8) + k3p_ss = h9 * wca + k3pp_i = h8_i * wnaca + k8_i = wna * (h11_i * h8_i) + k3p_i = h9_i * wca + eta = (etas) * (dCd < 0) + (etal) * numpy.logical_not((dCd < 0)) + J_TRPN = dCaTrpn_dt * trpnmax + # h_lambda = (h_lambda_prima) * (h_lambda_prima > 0) + (0) * numpy.logical_not( + # (h_lambda_prima > 0), + # ) + Jrel_inf = ((-ICaL) * a_rel) / ( + ((1.5 * scale_HF_Jrel_inf) / cajsr) ** 8.0 + 1.0 + ) + Jrel_infp = ((-ICaL) * a_relp) / ( + ((1.5 * scale_HF_Jrel_inf) / cajsr) ** 8.0 + 1.0 + ) + dcajsr_dt = Bcajsr * (-Jrel + Jtr) + values[36] = cajsr + dcajsr_dt * dt + dcansr_dt = Jup - (Jtr * vjsr) / vnsr + values[37] = cansr + dcansr_dt * dt + JnakNa = 3.0 * (E1 * a3 - E2 * b3) + JnakK = 2.0 * (-E3 * a1 + E4 * b1) + dkss_dt = -JdiffK + (Acap * (-ICaK)) / ((F * vss)) + values[38] = dkss_dt * dt + kss + k4 = k4p_ss + k4pp + k4_i = k4p_i + k4pp_i + k3 = k3p_ss + k3pp + k3_i = k3p_i + k3pp_i + # Fd = dCd * eta + dCd_dt = (p_k * (C - Cd)) / eta + dCd_dt_linearized = -p_k / eta + values[39] = ( + Cd + + dCd_dt + * (numpy.exp(dCd_dt_linearized * dt) - 1) + / dCd_dt_linearized + * (numpy.abs(dCd_dt_linearized) > 1e-08) + + dCd_dt * dt * (~(numpy.abs(dCd_dt_linearized) > 1e-08)) + ) + # Ta = (h_lambda * (Tref / rs)) * (XS * (Zetas + 1) + XW * Zetaw) + dJrelnp_dt = (Jrel_inf - Jrelnp) / tau_rel + dJrelnp_dt_linearized = -1 / tau_rel + values[40] = ( + Jrelnp + + dJrelnp_dt + * (numpy.exp(dJrelnp_dt_linearized * dt) - 1) + / dJrelnp_dt_linearized + ) + dJrelp_dt = (Jrel_infp - Jrelp) / tau_relp + dJrelp_dt_linearized = -1 / tau_relp + values[41] = ( + Jrelp + + dJrelp_dt + * (numpy.exp(dJrelp_dt_linearized * dt) - 1) + / dJrelp_dt_linearized + ) + INaK = (Pnak * scale_HF_Pnak) * (JnakK * zk + JnakNa * zna) + x2_ss = (k1 * k7) * (k4 + k5) + (k4 * k6) * (k1 + k8) + x2_i = (k1_i * k7_i) * (k4_i + k5_i) + (k4_i * k6_i) * (k1_i + k8_i) + x1_ss = (k2 * k4) * (k6 + k7) + (k5 * k7) * (k2 + k3) + x3_ss = (k1 * k3) * (k6 + k7) + (k6 * k8) * (k2 + k3) + x4_ss = (k2 * k8) * (k4 + k5) + (k3 * k5) * (k1 + k8) + x1_i = (k2_i * k4_i) * (k6_i + k7_i) + (k5_i * k7_i) * (k2_i + k3_i) + x3_i = (k1_i * k3_i) * (k6_i + k7_i) + (k6_i * k8_i) * (k2_i + k3_i) + x4_i = (k2_i * k8_i) * (k4_i + k5_i) + (k3_i * k5_i) * (k1_i + k8_i) + # Tp = p_a * (F1 + Fd) + dki_dt = ( + Acap * ( - -CaTrpn - + ufl.elem_pow(1000.0 * cai / cat50, ntrpn * scale_popu_nTRPN) - * (1.0 - CaTrpn) + -( + -2.0 * INaK + + ( + Istim + + ( + Isac_P_ns / 3 + + (Isac_P_k + (IKb + (IK1 + (IKs + (IKr + Ito))))) + ) + ) + ) + ) + ) / ((F * vmyo)) + (JdiffK * vss) / vmyo + values[42] = dki_dt * dt + ki + E1_ss = x1_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) + E2_ss = x2_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) + E3_ss = x3_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) + E4_ss = x4_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) + E1_i = x1_i / (x4_i + (x3_i + (x1_i + x2_i))) + E2_i = x2_i / (x4_i + (x3_i + (x1_i + x2_i))) + E3_i = x3_i / (x4_i + (x3_i + (x1_i + x2_i))) + E4_i = x4_i / (x4_i + (x3_i + (x1_i + x2_i))) + JncxCa_ss = -E1_ss * k1 + E2_ss * k2 + JncxNa_ss = -E2_ss * k3pp + (E3_ss * k4pp + 3.0 * (-E1_ss * k8 + E4_ss * k7)) + JncxCa_i = -E1_i * k1_i + E2_i * k2_i + JncxNa_i = -E2_i * k3pp_i + (E3_i * k4pp_i + 3.0 * (-E1_i * k8_i + E4_i * k7_i)) + INaCa_ss = (allo_ss * ((0.2 * Gncx) * scale_HF_Gncx)) * ( + JncxCa_ss * zca + JncxNa_ss * zna + ) + INaCa_i = (allo_i * ((0.8 * Gncx) * scale_HF_Gncx)) * ( + JncxCa_i * zca + JncxNa_i * zna + ) + dcass_dt = Bcass * ( + -Jdiff + + ( + (Acap * (-(ICaL - 2.0 * INaCa_ss))) / (((2.0 * F) * vss)) + + (Jrel * vjsr) / vss ) ) - kb = ( - ku - * scale_popu_ku - * ufl.elem_pow(Trpn50 * scale_popu_TRPN50, (ntm * scale_popu_nTm)) - / ( - 1.0 - - (rs * scale_popu_rs) - - rw * scale_popu_rw * (1.0 - (rs * scale_popu_rs)) + values[43] = cass + dcass_dt * dt + dnass_dt = -JdiffNa + (Acap * (-(ICaNa + 3.0 * INaCa_ss))) / ((F * vss)) + values[44] = dnass_dt * dt + nass + dcai_dt = Bcai * ( + -J_TRPN + + ( + ( + (Acap * (-(Isac_P_ns / 3 + (-2.0 * INaCa_i + (ICab + IpCa))))) + / (((2.0 * F) * vmyo)) + - (Jup * vnsr) / vmyo + ) + + (Jdiff * vss) / vmyo ) ) - - F_expressions[42] = ( - ufl.conditional( - ufl.lt(ufl.elem_pow(CaTrpn, -(ntm * scale_popu_nTm) / 2.0), 100.0), - ufl.elem_pow(CaTrpn, -(ntm * scale_popu_nTm) / 2.0), - 100.0, + values[45] = cai + dcai_dt * dt + dnai_dt = ( + Acap + * ( + -( + Isac_P_ns / 3 + + (INab + (3.0 * INaK + (3.0 * INaCa_i + (INa + INaL)))) + ) ) - * XU - * kb - - ku - * scale_popu_ku - * ufl.elem_pow(CaTrpn, (ntm * scale_popu_nTm) / 2.0) - * TmB - ) - - C = -1.0 + lambda_min12 - dCd = -Cd + C - eta = ufl.conditional(ufl.lt(dCd, 0.0), etas, etal) - F_expressions[43] = p_k * (-Cd + C) / eta - Bcai = 1.0 / (1.0 + cmdnmax * kmcmdn * ufl.elem_pow(kmcmdn + cai, -2.0)) - J_TRPN = trpnmax * F_expressions[41] - F_expressions[44] = ( - -J_TRPN - + Jdiff * vss / vmyo - - Jup * vnsr / vmyo - + 0.5 * (-ICab - IpCa - Isac_P_ns / 3.0 + 2.0 * INaCa_i) * Acap / (F * vmyo) - ) * Bcai - - # Return results - return as_vector(F_expressions) - - def num_states(self): - return 45 - - def __str__(self): - return "ORdmm_Land_em_coupling cardiac cell model" + ) / ((F * vmyo)) + (JdiffNa * vss) / vmyo + values[46] = dnai_dt * dt + nai + dv_dt = -( + Isac_P_k + + ( + Isac_P_ns + + ( + Istim + + ( + ICab + + ( + IpCa + + ( + IKb + + ( + INab + + ( + INaK + + ( + INaCa_ss + + ( + INaCa_i + + ( + IK1 + + ( + IKs + + ( + IKr + + ( + ICaK + + ( + ICaNa + + ( + ICaL + + ( + Ito + + ( + INa + + INaL + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + values[47] = dt * dv_dt + v + + return numpy.nan_to_num(values, nan=0.0) + + return forward_generalized_rush_larsen_ + + +# def Max(a, b): +# return (a + b + abs(a - b)) / Constant(2.0) + + +# def Min(a, b): +# return (a + b - abs(a - b)) / Constant(2.0) + + +# class ORdmmLandFull(BaseCellModel): +# def __init__( +# self, +# coupling: EMCoupling, +# params=None, +# init_conditions=None, +# ): +# """ +# Create cardiac cell model +# *Arguments* +# params (dict, :py:class:`dolfin.Mesh`, optional) +# optional model parameters +# init_conditions (dict, :py:class:`dolfin.Mesh`, optional) +# optional initial conditions +# """ +# logger.debug("Initialize ORdmm Land model") + +# super().__init__(params, init_conditions) +# self.lmbda = coupling.lmbda_ep +# self.Zetas = coupling.Zetas_ep +# self.Zetaw = coupling.Zetaw_ep + +# @staticmethod +# def update_disease_parameters( +# params: Dict[str, float], +# disease_state: str = "healthy", +# ) -> None: +# if disease_state.lower() == "hf": +# logger.info("Update scaling parameters for heart failure model") +# params["HF_scaling_CaMKa"] = 1.50 +# params["HF_scaling_Jrel_inf"] = pow(0.8, 8.0) +# params["HF_scaling_Jleak"] = 1.3 +# params["HF_scaling_Jup"] = 0.45 +# params["HF_scaling_GNaL"] = 1.3 +# params["HF_scaling_GK1"] = 0.68 +# params["HF_scaling_thL"] = 1.8 +# params["HF_scaling_Gto"] = 0.4 +# params["HF_scaling_Gncx"] = 1.6 +# params["HF_scaling_Pnak"] = 0.7 +# params["HF_scaling_cat50_ref"] = 0.6 + +# @staticmethod +# def default_parameters() -> Dict[str, float]: +# """Set-up and return default parameters. +# Parameters +# ---------- +# disease_state : str, optional +# String with "hf" or "healthy", by default "healthy". +# If "hf", then parameters representing heart failure +# will be used. +# Returns +# ------- +# OrderedDict +# Dictionary with default values +# """ +# params = OrderedDict( +# [ +# ("scale_ICaL", 1.018), +# ("scale_IK1", 1.414), +# ("scale_IKr", 1.119), +# ("scale_IKs", 1.648), +# ("scale_INaL", 2.274), +# ("celltype", 0), +# ("cao", 1.8), +# ("ko", 5.4), +# ("nao", 140.0), +# ("F", 96485.0), +# ("R", 8314.0), +# ("T", 310.0), +# ("L", 0.01), +# ("rad", 0.0011), +# ("Ahf", 0.99), +# ("GNa", 31), +# ("thL", 200.0), +# ("Gto", 0.02), +# ("delta_epi", 1.0), +# ("Aff", 0.6), +# ("Kmn", 0.002), +# ("k2n", 1000.0), +# ("tjca", 75.0), +# ("zca", 2.0), +# ("bt", 4.75), +# ("Beta0", 2.3), +# ("Beta1", -2.4), +# ("Tot_A", 25), +# ("Tref", 120), +# ("Trpn50", 0.35), +# ("calib", 1), +# ("cat50_ref", 0.805), +# ("emcoupling", 1), +# ("etal", 200), +# ("etas", 20), +# ("gammas", 0.0085), +# ("gammaw", 0.615), +# ("isacs", 0), +# ("ktrpn", 0.1), +# ("ku", 0.04), +# ("kuw", 0.182), +# ("kws", 0.012), +# ("mode", 1), +# ("ntm", 2.4), +# ("ntrpn", 2.0), +# ("p_a", 2.1), +# ("p_b", 9.1), +# ("p_k", 7.0), +# ("phi", 2.23), +# ("rs", 0.25), +# ("rw", 0.5), +# ("CaMKo", 0.05), +# ("KmCaM", 0.0015), +# ("KmCaMK", 0.15), +# ("aCaMK", 0.05), +# ("bCaMK", 0.00068), +# ("PKNa", 0.01833), +# ("Gncx", 0.0008), +# ("KmCaAct", 0.00015), +# ("kasymm", 12.5), +# ("kcaoff", 5000.0), +# ("kcaon", 1500000.0), +# ("kna1", 15.0), +# ("kna2", 5.0), +# ("kna3", 88.12), +# ("qca", 0.167), +# ("qna", 0.5224), +# ("wca", 60000.0), +# ("wna", 60000.0), +# ("wnaca", 5000.0), +# ("H", 1e-07), +# ("Khp", 1.698e-07), +# ("Kki", 0.5), +# ("Kko", 0.3582), +# ("Kmgatp", 1.698e-07), +# ("Knai0", 9.073), +# ("Knao0", 27.78), +# ("Knap", 224.0), +# ("Kxkur", 292.0), +# ("MgADP", 0.05), +# ("MgATP", 9.8), +# ("Pnak", 30.0), +# ("delta", -0.155), +# ("eP", 4.2), +# ("k1m", 182.4), +# ("k1p", 949.5), +# ("k2m", 39.4), +# ("k2p", 687.2), +# ("k3m", 79300.0), +# ("k3p", 1899.0), +# ("k4m", 40.0), +# ("k4p", 639.0), +# ("zk", 1.0), +# ("GKb", 0.003), +# ("PNab", 3.75e-10), +# ("PCab", 2.5e-08), +# ("GpCa", 0.0005), +# ("Esac_ns", -10.0), +# ("Gsac_k", 1.097904761904762), +# ("Gsac_ns", 0.006), +# ("lambda_max", 1.1), +# ("amp", -80.0), +# ("duration", 0.5), +# ("BSLmax", 1.124), +# ("BSRmax", 0.047), +# ("KmBSL", 0.0087), +# ("KmBSR", 0.00087), +# ("cmdnmax", 0.05), +# ("csqnmax", 10.0), +# ("kmcmdn", 0.00238), +# ("kmcsqn", 0.8), +# ("kmtrpn", 0.0005), +# ("trpnmax", 0.07), +# # Drug factors +# ("scale_drug_INa", 1.0), +# ("scale_drug_INaL", 1.0), +# ("scale_drug_Ito", 1.0), +# ("scale_drug_ICaL", 1.0), +# ("scale_drug_IKr", 1.0), +# ("scale_drug_IKs", 1.0), +# ("scale_drug_IK1", 1.0), +# ("scale_drug_IKb", 1.0), +# ("scale_drug_INab", 1.0), +# ("scale_drug_ICab", 1.0), +# ("scale_drug_IpCa", 1.0), +# ("scale_drug_Isacns", 1.0), +# ("scale_drug_Isack", 1.0), +# # Population factors +# ("scale_popu_GNa", 1.0), +# ("scale_popu_GCaL", 1.0), +# ("scale_popu_Gto", 1.0), +# ("scale_popu_GNaL", 1.0), +# ("scale_popu_GKr", 1.0), +# ("scale_popu_GKs", 1.0), +# ("scale_popu_GK1", 1.0), +# ("scale_popu_GbK", 1.0), +# ("scale_popu_KNCX", 1.0), +# ("scale_popu_KNaK", 1.0), +# ("scale_popu_GbNa", 1.0), +# ("scale_popu_GbCa", 1.0), +# ("scale_popu_KpCa", 1.0), +# ("scale_popu_KRyR", 1.0), +# ("scale_popu_KSERCA", 1.0), +# ("scale_popu_Kleak", 1.0), +# ("scale_popu_nTm", 1.0), +# ("scale_popu_CaT50ref", 1.0), +# ("scale_popu_Tref", 1.0), +# ("scale_popu_kuw", 1.0), +# ("scale_popu_kws", 1.0), +# ("scale_popu_kTRPN", 1.0), +# ("scale_popu_nTRPN", 1.0), +# ("scale_popu_ku", 1.0), +# ("scale_popu_TRPN50", 1.0), +# ("scale_popu_rw", 1.0), +# ("scale_popu_rs", 1.0), +# # HF scaling factors +# ("HF_scaling_CaMKa", 1.0), +# ("HF_scaling_Jrel_inf", 1.0), +# ("HF_scaling_Jleak", 1.0), +# ("HF_scaling_Jup", 1.0), +# ("HF_scaling_GNaL", 1.0), +# ("HF_scaling_GK1", 1.0), +# ("HF_scaling_thL", 1.0), +# ("HF_scaling_Gto", 1.0), +# ("HF_scaling_Gncx", 1.0), +# ("HF_scaling_Pnak", 1.0), +# ("HF_scaling_cat50_ref", 1.0), +# ], +# ) + +# return params + +# @staticmethod +# def default_initial_conditions(): +# "Set-up and return default initial conditions." +# ic = OrderedDict( +# [ +# ("v", -87), +# ("CaMKt", 0), +# ("m", 0), +# ("hf", 1), +# ("hs", 1), +# ("j", 1), +# ("hsp", 1), +# ("jp", 1), +# ("mL", 0), +# ("hL", 1), +# ("hLp", 1), +# ("a", 0), +# ("iF", 1), +# ("iS", 1), +# ("ap", 0), +# ("iFp", 1), +# ("iSp", 1), +# ("d", 0), +# ("ff", 1), +# ("fs", 1), +# ("fcaf", 1), +# ("fcas", 1), +# ("jca", 1), +# ("ffp", 1), +# ("fcafp", 1), +# ("nca", 0), +# ("xrf", 0), +# ("xrs", 0), +# ("xs1", 0), +# ("xs2", 0), +# ("xk1", 1), +# ("Jrelnp", 0), +# ("Jrelp", 0), +# ("nai", 7), +# ("nass", 7), +# ("ki", 145), +# ("kss", 145), +# ("cass", 0.0001), +# ("cansr", 1.2), +# ("cajsr", 1.2), +# ("XS", 0), +# ("XW", 0), +# ("CaTrpn", 0), +# ("TmB", 1), +# ("Cd", 0), +# ("cai", 0.0001), +# ], +# ) +# return ic + +# def _I(self, v, s, time): +# """ +# Original gotran transmembrane current dV/dt +# """ +# time = time if time else Constant(0.0) +# logger.debug("Evaluate transmembrane current") +# # Assign states +# assert len(s) == 45 +# ( +# CaMKt, +# m, +# hf, +# hs, +# j, +# hsp, +# jp, +# mL, +# hL, +# hLp, +# a, +# iF, +# iS, +# ap, +# iFp, +# iSp, +# d, +# ff, +# fs, +# fcaf, +# fcas, +# jca, +# ffp, +# fcafp, +# nca, +# xrf, +# xrs, +# xs1, +# xs2, +# xk1, +# Jrelnp, +# Jrelp, +# nai, +# nass, +# ki, +# kss, +# cass, +# cansr, +# cajsr, +# XS, +# XW, +# CaTrpn, +# TmB, +# Cd, +# cai, +# ) = s + +# # Assign parameters +# scale_ICaL = self._parameters["scale_ICaL"] +# scale_IK1 = self._parameters["scale_IK1"] +# scale_IKr = self._parameters["scale_IKr"] +# scale_IKs = self._parameters["scale_IKs"] +# scale_INaL = self._parameters["scale_INaL"] +# cao = self._parameters["cao"] +# ko = self._parameters["ko"] +# nao = self._parameters["nao"] +# F = self._parameters["F"] +# R = self._parameters["R"] +# T = self._parameters["T"] +# CaMKo = self._parameters["CaMKo"] +# KmCaM = self._parameters["KmCaM"] +# KmCaMK = self._parameters["KmCaMK"] +# PKNa = self._parameters["PKNa"] +# Ahf = self._parameters["Ahf"] +# GNa = self._parameters["GNa"] +# Gto = self._parameters["Gto"] +# Aff = self._parameters["Aff"] +# zca = self._parameters["zca"] +# Gncx = self._parameters["Gncx"] +# KmCaAct = self._parameters["KmCaAct"] +# kasymm = self._parameters["kasymm"] +# kcaoff = self._parameters["kcaoff"] +# kcaon = self._parameters["kcaon"] +# kna1 = self._parameters["kna1"] +# kna2 = self._parameters["kna2"] +# kna3 = self._parameters["kna3"] +# qca = self._parameters["qca"] +# qna = self._parameters["qna"] +# wca = self._parameters["wca"] +# wna = self._parameters["wna"] +# wnaca = self._parameters["wnaca"] +# H = self._parameters["H"] +# Khp = self._parameters["Khp"] +# Kki = self._parameters["Kki"] +# Kko = self._parameters["Kko"] +# Kmgatp = self._parameters["Kmgatp"] +# Knai0 = self._parameters["Knai0"] +# Knao0 = self._parameters["Knao0"] +# Knap = self._parameters["Knap"] +# Kxkur = self._parameters["Kxkur"] +# MgADP = self._parameters["MgADP"] +# MgATP = self._parameters["MgATP"] +# Pnak = self._parameters["Pnak"] +# delta = self._parameters["delta"] +# eP = self._parameters["eP"] +# k1m = self._parameters["k1m"] +# k1p = self._parameters["k1p"] +# k2m = self._parameters["k2m"] +# k2p = self._parameters["k2p"] +# k3m = self._parameters["k3m"] +# k3p = self._parameters["k3p"] +# k4m = self._parameters["k4m"] +# k4p = self._parameters["k4p"] +# zk = self._parameters["zk"] +# GKb = self._parameters["GKb"] +# PNab = self._parameters["PNab"] +# PCab = self._parameters["PCab"] +# GpCa = self._parameters["GpCa"] +# # Drug factor +# scale_drug_INa = self._parameters["scale_drug_INa"] +# scale_drug_INaL = self._parameters["scale_drug_INaL"] +# scale_drug_Ito = self._parameters["scale_drug_Ito"] +# scale_drug_ICaL = self._parameters["scale_drug_ICaL"] +# scale_drug_IKr = self._parameters["scale_drug_IKr"] +# scale_drug_IKs = self._parameters["scale_drug_IKs"] +# scale_drug_IK1 = self._parameters["scale_drug_IK1"] +# scale_drug_IKb = self._parameters["scale_drug_IKb"] +# scale_drug_INab = self._parameters["scale_drug_INab"] +# scale_drug_ICab = self._parameters["scale_drug_ICab"] +# scale_drug_IpCa = self._parameters["scale_drug_IpCa"] +# scale_drug_Isacns = self._parameters["scale_drug_Isacns"] +# scale_drug_Isack = self._parameters["scale_drug_Isack"] +# # Population factors +# scale_popu_GNa = self._parameters["scale_popu_GNa"] +# scale_popu_GCaL = self._parameters["scale_popu_GCaL"] +# scale_popu_Gto = self._parameters["scale_popu_Gto"] +# scale_popu_GNaL = self._parameters["scale_popu_GNaL"] +# scale_popu_GKr = self._parameters["scale_popu_GKr"] +# scale_popu_GKs = self._parameters["scale_popu_GKs"] +# scale_popu_GK1 = self._parameters["scale_popu_GK1"] +# scale_popu_GbK = self._parameters["scale_popu_GbK"] +# scale_popu_KNCX = self._parameters["scale_popu_KNCX"] +# scale_popu_KNaK = self._parameters["scale_popu_KNaK"] +# scale_popu_GbNa = self._parameters["scale_popu_GbNa"] +# scale_popu_GbCa = self._parameters["scale_popu_GbCa"] +# scale_popu_KpCa = self._parameters["scale_popu_KpCa"] +# # Systolic Heart Failure (HF with preserved ejection fraction) +# HF_scaling_CaMKa = self._parameters["HF_scaling_CaMKa"] +# HF_scaling_GNaL = self._parameters["HF_scaling_GNaL"] +# HF_scaling_GK1 = self._parameters["HF_scaling_GK1"] +# HF_scaling_Gto = self._parameters["HF_scaling_Gto"] +# HF_scaling_Gncx = self._parameters["HF_scaling_Gncx"] +# HF_scaling_Pnak = self._parameters["HF_scaling_Pnak"] + +# # Init return args +# current = [ufl.zero()] * 1 + +# # Expressions for the CaMKt component +# CaMKb = CaMKo * (1.0 - CaMKt) / (1.0 + KmCaM / cass) +# CaMKa = (CaMKb + CaMKt) * HF_scaling_CaMKa + +# # Expressions for the reversal potentials component +# ENa = R * T * ufl.ln(nao / nai) / F +# EK = R * T * ufl.ln(ko / ki) / F +# EKs = R * T * ufl.ln((ko + PKNa * nao) / (PKNa * nai + ki)) / F +# vffrt = (F * F) * v / (R * T) +# vfrt = F * v / (R * T) + +# # Expressions for the I_Na component +# Ahs = 1.0 - Ahf +# h = Ahf * hf + Ahs * hs +# hp = Ahf * hf + Ahs * hsp +# fINap = 1.0 / (1.0 + KmCaMK / CaMKa) +# INa = ( +# GNa +# * scale_drug_INa +# * scale_popu_GNa +# * ufl.elem_pow(m, 3.0) +# * (-ENa + v) +# * ((1.0 - fINap) * h * j + fINap * hp * jp) +# ) + +# # Expressions for the INaL component +# GNaL = 0.0075 * scale_INaL * scale_drug_INaL * scale_popu_GNaL * HF_scaling_GNaL +# fINaLp = 1.0 / (1.0 + KmCaMK / CaMKa) +# INaL = (-ENa + v) * ((1.0 - fINaLp) * hL + fINaLp * hLp) * GNaL * mL + +# # Expressions for the Ito component +# AiF = 1.0 / (1.0 + 0.24348537187522867 * ufl.exp(0.006613756613756614 * v)) +# AiS = 1.0 - AiF +# i = AiF * iF + AiS * iS +# ip = AiF * iFp + AiS * iSp +# fItop = 1.0 / (1.0 + KmCaMK / CaMKa) +# Ito = ( +# Gto +# * scale_drug_Ito +# * scale_popu_Gto +# * HF_scaling_Gto +# * (-EK + v) +# * ((1.0 - fItop) * a * i + ap * fItop * ip) +# ) + +# # Expressions for the ICaL ICaNa ICaK component +# Afs = 1.0 - Aff +# f = Aff * ff + Afs * fs +# Afcaf = 0.3 + 0.6 / (1.0 + 0.36787944117144233 * ufl.exp(0.1 * v)) +# Afcas = 1.0 - Afcaf +# fca = Afcaf * fcaf + Afcas * fcas +# fp = Aff * ffp + Afs * fs +# fcap = Afcaf * fcafp + Afcas * fcas +# PhiCaL = ( +# 4.0 +# * (-0.341 * cao + cass * ufl.exp(2.0 * vfrt)) +# * vffrt +# / (-1.0 + ufl.exp(2.0 * vfrt)) +# ) +# PhiCaNa = ( +# 1.0 +# * (-0.75 * nao + 0.75 * ufl.exp(1.0 * vfrt) * nass) +# * vffrt +# / (-1.0 + ufl.exp(1.0 * vfrt)) +# ) +# PhiCaK = ( +# 1.0 +# * (-0.75 * ko + 0.75 * ufl.exp(1.0 * vfrt) * kss) +# * vffrt +# / (-1.0 + ufl.exp(1.0 * vfrt)) +# ) +# PCa = 0.0001 * scale_ICaL * scale_drug_ICaL * scale_popu_GCaL +# PCap = 1.1 * PCa +# PCaNa = 0.00125 * PCa +# PCaK = 0.0003574 * PCa +# PCaNap = 0.00125 * PCap +# PCaKp = 0.0003574 * PCap +# fICaLp = 1.0 / (1.0 + KmCaMK / CaMKa) +# ICaL = (1.0 - fICaLp) * ( +# (1.0 - nca) * f + fca * jca * nca +# ) * PCa * PhiCaL * d + ( +# (1.0 - nca) * fp + fcap * jca * nca +# ) * PCap * PhiCaL * d * fICaLp +# ICaNa = (1.0 - fICaLp) * ( +# (1.0 - nca) * f + fca * jca * nca +# ) * PCaNa * PhiCaNa * d + ( +# (1.0 - nca) * fp + fcap * jca * nca +# ) * PCaNap * PhiCaNa * d * fICaLp +# ICaK = (1.0 - fICaLp) * ( +# (1.0 - nca) * f + fca * jca * nca +# ) * PCaK * PhiCaK * d + ( +# (1.0 - nca) * fp + fcap * jca * nca +# ) * PCaKp * PhiCaK * d * fICaLp + +# # Expressions for the IKr component +# Axrf = 1.0 / (1.0 + 4.197299094734718 * ufl.exp(0.02617115938236064 * v)) +# Axrs = 1.0 - Axrf +# xr = Axrf * xrf + Axrs * xrs +# rkr = 1.0 / ( +# (1.0 + 2.0820090840784555 * ufl.exp(0.013333333333333334 * v)) +# * (1.0 + 0.7165313105737893 * ufl.exp(0.03333333333333333 * v)) +# ) +# GKr = 0.046 * scale_IKr * scale_drug_IKr * scale_popu_GKr +# IKr = 0.4303314829119352 * ufl.sqrt(ko) * (-EK + v) * GKr * rkr * xr + +# # Expressions for the IKs component +# KsCa = 1.0 + 0.6 / (1.0 + 6.481821026062645e-07 * ufl.elem_pow(1.0 / cai, 1.4)) +# GKs = 0.0034 * scale_IKs * scale_drug_IKs * scale_popu_GKs +# IKs = (-EKs + v) * GKs * KsCa * xs1 * xs2 +# rk1 = 1.0 / ( +# 1.0 +# + 69220.6322106767 +# * ufl.exp(0.10534077741493732 * v - 0.27388602127883704 * ko) +# ) +# GK1 = 0.1908 * scale_IK1 * scale_drug_IK1 * scale_popu_GK1 * HF_scaling_GK1 +# IK1 = ufl.sqrt(ko) * (-EK + v) * GK1 * rk1 * xk1 + +# # Expressions for the INaCa_i component +# hca = ufl.exp(F * qca * v / (R * T)) +# hna = ufl.exp(F * qna * v / (R * T)) +# h1_i = 1 + (1 + hna) * nai / kna3 +# h2_i = hna * nai / (kna3 * h1_i) +# h3_i = 1.0 / h1_i +# h4_i = 1.0 + (1 + nai / kna2) * nai / kna1 +# h5_i = (nai * nai) / (kna1 * kna2 * h4_i) +# h6_i = 1.0 / h4_i +# h7_i = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 +# h8_i = nao / (kna3 * h7_i * hna) +# h9_i = 1.0 / h7_i +# h10_i = 1.0 + kasymm + nao * (1.0 + nao / kna2) / kna1 +# h11_i = (nao * nao) / (kna1 * kna2 * h10_i) +# h12_i = 1.0 / h10_i +# k1_i = cao * kcaon * h12_i +# k2_i = kcaoff +# k3p_i = wca * h9_i +# k3pp_i = wnaca * h8_i +# k3_i = k3p_i + k3pp_i +# k4p_i = wca * h3_i / hca +# k4pp_i = wnaca * h2_i +# k4_i = k4p_i + k4pp_i +# k5_i = kcaoff +# k6_i = kcaon * cai * h6_i +# k7_i = wna * h2_i * h5_i +# k8_i = wna * h11_i * h8_i +# x1_i = (k2_i + k3_i) * k5_i * k7_i + (k6_i + k7_i) * k2_i * k4_i +# x2_i = (k1_i + k8_i) * k4_i * k6_i + (k4_i + k5_i) * k1_i * k7_i +# x3_i = (k2_i + k3_i) * k6_i * k8_i + (k6_i + k7_i) * k1_i * k3_i +# x4_i = (k1_i + k8_i) * k3_i * k5_i + (k4_i + k5_i) * k2_i * k8_i +# E1_i = x1_i / (x1_i + x2_i + x3_i + x4_i) +# E2_i = x2_i / (x1_i + x2_i + x3_i + x4_i) +# E3_i = x3_i / (x1_i + x2_i + x3_i + x4_i) +# E4_i = x4_i / (x1_i + x2_i + x3_i + x4_i) +# allo_i = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cai, 2.0)) +# zna = 1.0 +# JncxNa_i = E3_i * k4pp_i - E2_i * k3pp_i + 3.0 * E4_i * k7_i - 3.0 * E1_i * k8_i +# JncxCa_i = E2_i * k2_i - E1_i * k1_i +# INaCa_i = ( +# 0.8 +# * Gncx +# * scale_popu_KNCX +# * HF_scaling_Gncx +# * (zca * JncxCa_i + zna * JncxNa_i) +# * allo_i +# ) + +# # Expressions for the INaCa_ss component +# h1 = 1.0 + (1.0 + hna) * nass / kna3 +# h2 = hna * nass / (kna3 * h1) +# h3 = 1.0 / h1 +# h4 = 1.0 + (1 + nass / kna2) * nass / kna1 +# h5 = (nass * nass) / (kna1 * kna2 * h4) +# h6 = 1.0 / h4 +# h7 = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 +# h8 = nao / (kna3 * h7 * hna) +# h9 = 1.0 / h7 +# h10 = 1.0 + kasymm + nao * (1 + nao / kna2) / kna1 +# h11 = (nao * nao) / (kna1 * kna2 * h10) +# h12 = 1.0 / h10 +# k1 = cao * kcaon * h12 +# k2 = kcaoff +# k3p_ss = wca * h9 +# k3pp = wnaca * h8 +# k3 = k3p_ss + k3pp +# k4p_ss = wca * h3 / hca +# k4pp = wnaca * h2 +# k4 = k4p_ss + k4pp +# k5 = kcaoff +# k6 = kcaon * cass * h6 +# k7 = wna * h2 * h5 +# k8 = wna * h11 * h8 +# x1_ss = (k2 + k3) * k5 * k7 + (k6 + k7) * k2 * k4 +# x2_ss = (k1 + k8) * k4 * k6 + (k4 + k5) * k1 * k7 +# x3_ss = (k2 + k3) * k6 * k8 + (k6 + k7) * k1 * k3 +# x4_ss = (k1 + k8) * k3 * k5 + (k4 + k5) * k2 * k8 +# E1_ss = x1_ss / (x1_ss + x2_ss + x3_ss + x4_ss) +# E2_ss = x2_ss / (x1_ss + x2_ss + x3_ss + x4_ss) +# E3_ss = x3_ss / (x1_ss + x2_ss + x3_ss + x4_ss) +# E4_ss = x4_ss / (x1_ss + x2_ss + x3_ss + x4_ss) +# allo_ss = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cass, 2.0)) +# JncxNa_ss = E3_ss * k4pp - E2_ss * k3pp + 3.0 * E4_ss * k7 - 3.0 * E1_ss * k8 +# JncxCa_ss = E2_ss * k2 - E1_ss * k1 +# INaCa_ss = ( +# 0.2 +# * Gncx +# * scale_popu_KNCX +# * HF_scaling_Gncx +# * (zca * JncxCa_ss + zna * JncxNa_ss) +# * allo_ss +# ) + +# # Expressions for the INaK component +# Knai = Knai0 * ufl.exp(0.3333333333333333 * F * delta * v / (R * T)) +# Knao = Knao0 * ufl.exp(0.3333333333333333 * F * (1.0 - delta) * v / (R * T)) +# P = eP / (1.0 + H / Khp + nai / Knap + ki / Kxkur) +# a1 = ( +# k1p +# * ufl.elem_pow(nai / Knai, 3.0) +# / ( +# -1.0 +# + ufl.elem_pow(1.0 + ki / Kki, 2.0) +# + ufl.elem_pow(1.0 + nai / Knai, 3.0) +# ) +# ) +# b1 = MgADP * k1m +# a2 = k2p +# b2 = ( +# k2m +# * ufl.elem_pow(nao / Knao, 3.0) +# / ( +# -1.0 +# + ufl.elem_pow(1.0 + ko / Kko, 2.0) +# + ufl.elem_pow(1.0 + nao / Knao, 3.0) +# ) +# ) +# a3 = ( +# k3p +# * ufl.elem_pow(ko / Kko, 2.0) +# / ( +# -1.0 +# + ufl.elem_pow(1.0 + ko / Kko, 2.0) +# + ufl.elem_pow(1.0 + nao / Knao, 3.0) +# ) +# ) +# b3 = H * k3m * P / (1.0 + MgATP / Kmgatp) +# a4 = MgATP * k4p / (Kmgatp * (1.0 + MgATP / Kmgatp)) +# b4 = ( +# k4m +# * ufl.elem_pow(ki / Kki, 2.0) +# / ( +# -1.0 +# + ufl.elem_pow(1.0 + ki / Kki, 2.0) +# + ufl.elem_pow(1.0 + nai / Knai, 3.0) +# ) +# ) +# x1 = a1 * a2 * a4 + a1 * a2 * b3 + a2 * b3 * b4 + b2 * b3 * b4 +# x2 = a1 * a2 * a3 + a2 * a3 * b4 + a3 * b1 * b4 + b1 * b2 * b4 +# x3 = a2 * a3 * a4 + a3 * a4 * b1 + a4 * b1 * b2 + b1 * b2 * b3 +# x4 = a1 * a3 * a4 + a1 * a4 * b2 + a1 * b2 * b3 + b2 * b3 * b4 +# E1 = x1 / (x1 + x2 + x3 + x4) +# E2 = x2 / (x1 + x2 + x3 + x4) +# E3 = x3 / (x1 + x2 + x3 + x4) +# E4 = x4 / (x1 + x2 + x3 + x4) +# JnakNa = 3.0 * E1 * a3 - 3.0 * E2 * b3 +# JnakK = 2.0 * E4 * b1 - 2.0 * E3 * a1 +# INaK = Pnak * scale_popu_KNaK * HF_scaling_Pnak * (zk * JnakK + zna * JnakNa) + +# # Expressions for the IKb component +# xkb = 1.0 / (1.0 + 2.202363450949239 * ufl.exp(-0.05452562704471101 * v)) +# IKb = GKb * scale_popu_GbK * scale_drug_IKb * (-EK + v) * xkb + +# # Expressions for the INab component +# INab = ( +# PNab +# * scale_drug_INab +# * scale_popu_GbNa +# * (-nao + ufl.exp(vfrt) * nai) +# * vffrt +# / (-1.0 + ufl.exp(vfrt)) +# ) + +# # Expressions for the ICab component +# ICab = ( +# 4.0 +# * PCab +# * scale_drug_ICab +# * scale_popu_GbCa +# * (-0.341 * cao + cai * ufl.exp(2.0 * vfrt)) +# * vffrt +# / (-1.0 + ufl.exp(2.0 * vfrt)) +# ) + +# # Expressions for the IpCa component +# IpCa = GpCa * scale_drug_IpCa * scale_popu_KpCa * cai / (0.0005 + cai) + +# # Expressions for the Isac (Pueyo)--> ns + k component +# Gsac_ns = 0.006 * scale_drug_Isacns +# Esac_ns = -10.0 +# lambda_max = 1.1 +# Gsac_k = (0.2882 * 800.0 / 210.0) * scale_drug_Isack # Pueyo endo + +# Isac_P_ns = ufl.conditional( +# ufl.lt(self.lmbda, 1.0), +# 0.0, +# Gsac_ns * ((self.lmbda - 1.0) / (lambda_max - 1.0)) * (v - Esac_ns), +# ) +# Isac_P_k = ufl.conditional( +# ufl.lt(self.lmbda, 1.0), +# 0.0, +# Gsac_k +# * ((self.lmbda - 1.0) / (lambda_max - 1.0)) +# * (1.0 / (1.0 + ufl.exp((19.05 - v) / (29.98)))), +# ) + +# # Expressions for the Istim component +# Istim = 0 # amp*(ufl.le(time, duration)) + +# # Expressions for the membrane potential component +# current[0] = ( +# -Isac_P_k +# - Isac_P_ns +# - ICaK +# - ICaL +# - ICaNa +# - ICab +# - IK1 +# - IKb +# - IKr +# - IKs +# - INa +# - INaCa_i +# - INaCa_ss +# - INaK +# - INaL +# - INab +# - IpCa +# - Istim +# - Ito +# ) + +# # Return results +# return current[0] + +# def I(self, v, s, time=None): # noqa: E741, E743 +# """ +# Transmembrane current +# I = -dV/dt +# """ +# return -self._I(v, s, time) + +# def F(self, v, s, time=None): +# """ +# Right hand side for ODE system +# """ +# logger.debug("Evaluate RHS") +# time = time if time else Constant(0.0) + +# # Assign states +# assert len(s) == 45 +# ( +# CaMKt, +# m, +# hf, +# hs, +# j, +# hsp, +# jp, +# mL, +# hL, +# hLp, +# a, +# iF, +# iS, +# ap, +# iFp, +# iSp, +# d, +# ff, +# fs, +# fcaf, +# fcas, +# jca, +# ffp, +# fcafp, +# nca, +# xrf, +# xrs, +# xs1, +# xs2, +# xk1, +# Jrelnp, +# Jrelp, +# nai, +# nass, +# ki, +# kss, +# cass, +# cansr, +# cajsr, +# XS, +# XW, +# CaTrpn, +# TmB, +# Cd, +# cai, +# ) = s + +# # Assign parameters +# scale_ICaL = self._parameters["scale_ICaL"] +# scale_IK1 = self._parameters["scale_IK1"] +# scale_IKr = self._parameters["scale_IKr"] +# scale_IKs = self._parameters["scale_IKs"] +# scale_INaL = self._parameters["scale_INaL"] +# cao = self._parameters["cao"] +# ko = self._parameters["ko"] +# nao = self._parameters["nao"] +# F = self._parameters["F"] +# R = self._parameters["R"] +# T = self._parameters["T"] +# L = self._parameters["L"] +# rad = self._parameters["rad"] +# CaMKo = self._parameters["CaMKo"] +# KmCaM = self._parameters["KmCaM"] +# KmCaMK = self._parameters["KmCaMK"] +# aCaMK = self._parameters["aCaMK"] +# bCaMK = self._parameters["bCaMK"] +# PKNa = self._parameters["PKNa"] +# Ahf = self._parameters["Ahf"] +# GNa = self._parameters["GNa"] +# thL = self._parameters["thL"] +# Gto = self._parameters["Gto"] +# delta_epi = self._parameters["delta_epi"] +# Aff = self._parameters["Aff"] +# Kmn = self._parameters["Kmn"] +# k2n = self._parameters["k2n"] +# tjca = self._parameters["tjca"] +# zca = self._parameters["zca"] +# Gncx = self._parameters["Gncx"] +# KmCaAct = self._parameters["KmCaAct"] +# kasymm = self._parameters["kasymm"] +# kcaoff = self._parameters["kcaoff"] +# kcaon = self._parameters["kcaon"] +# kna1 = self._parameters["kna1"] +# kna2 = self._parameters["kna2"] +# kna3 = self._parameters["kna3"] +# qca = self._parameters["qca"] +# qna = self._parameters["qna"] +# wca = self._parameters["wca"] +# wna = self._parameters["wna"] +# wnaca = self._parameters["wnaca"] +# H = self._parameters["H"] +# Khp = self._parameters["Khp"] +# Kki = self._parameters["Kki"] +# Kko = self._parameters["Kko"] +# Kmgatp = self._parameters["Kmgatp"] +# Knai0 = self._parameters["Knai0"] +# Knao0 = self._parameters["Knao0"] +# Knap = self._parameters["Knap"] +# Kxkur = self._parameters["Kxkur"] +# MgADP = self._parameters["MgADP"] +# MgATP = self._parameters["MgATP"] +# Pnak = self._parameters["Pnak"] +# delta = self._parameters["delta"] +# eP = self._parameters["eP"] +# k1m = self._parameters["k1m"] +# k1p = self._parameters["k1p"] +# k2m = self._parameters["k2m"] +# k2p = self._parameters["k2p"] +# k3m = self._parameters["k3m"] +# k3p = self._parameters["k3p"] +# k4m = self._parameters["k4m"] +# k4p = self._parameters["k4p"] +# zk = self._parameters["zk"] +# GKb = self._parameters["GKb"] +# PNab = self._parameters["PNab"] +# PCab = self._parameters["PCab"] +# GpCa = self._parameters["GpCa"] +# bt = self._parameters["bt"] +# BSLmax = self._parameters["BSLmax"] +# BSRmax = self._parameters["BSRmax"] +# KmBSL = self._parameters["KmBSL"] +# KmBSR = self._parameters["KmBSR"] +# cmdnmax = self._parameters["cmdnmax"] +# csqnmax = self._parameters["csqnmax"] +# kmcmdn = self._parameters["kmcmdn"] +# kmcsqn = self._parameters["kmcsqn"] +# trpnmax = self._parameters["trpnmax"] +# Beta1 = self._parameters["Beta1"] + +# Trpn50 = self._parameters["Trpn50"] +# cat50_ref = self._parameters["cat50_ref"] + +# etal = self._parameters["etal"] +# etas = self._parameters["etas"] +# gammas = self._parameters["gammas"] +# gammaw = self._parameters["gammaw"] +# ktrpn = self._parameters["ktrpn"] +# ku = self._parameters["ku"] +# kuw = self._parameters["kuw"] +# kws = self._parameters["kws"] +# # lmbda = self._parameters["lmbda"] +# ntm = self._parameters["ntm"] +# ntrpn = self._parameters["ntrpn"] +# p_k = self._parameters["p_k"] + +# rs = self._parameters["rs"] +# rw = self._parameters["rw"] + +# # Zetas = self._parameters["Zetas"] +# # Zetaw = self._parameters["Zetaw"] + +# # Drug factor +# scale_drug_INa = self._parameters["scale_drug_INa"] +# scale_drug_INaL = self._parameters["scale_drug_INaL"] +# scale_drug_Ito = self._parameters["scale_drug_Ito"] +# scale_drug_ICaL = self._parameters["scale_drug_ICaL"] +# scale_drug_IKr = self._parameters["scale_drug_IKr"] +# scale_drug_IKs = self._parameters["scale_drug_IKs"] +# scale_drug_IK1 = self._parameters["scale_drug_IK1"] +# scale_drug_IKb = self._parameters["scale_drug_IKb"] +# scale_drug_INab = self._parameters["scale_drug_INab"] +# scale_drug_ICab = self._parameters["scale_drug_ICab"] +# scale_drug_IpCa = self._parameters["scale_drug_IpCa"] +# scale_drug_Isacns = self._parameters["scale_drug_Isacns"] +# scale_drug_Isack = self._parameters["scale_drug_Isack"] + +# # Population factors +# scale_popu_GNa = self._parameters["scale_popu_GNa"] +# scale_popu_GCaL = self._parameters["scale_popu_GCaL"] +# scale_popu_Gto = self._parameters["scale_popu_Gto"] +# scale_popu_GNaL = self._parameters["scale_popu_GNaL"] +# scale_popu_GKr = self._parameters["scale_popu_GKr"] +# scale_popu_GKs = self._parameters["scale_popu_GKs"] +# scale_popu_GK1 = self._parameters["scale_popu_GK1"] +# scale_popu_GbK = self._parameters["scale_popu_GbK"] +# scale_popu_KNCX = self._parameters["scale_popu_KNCX"] +# scale_popu_KNaK = self._parameters["scale_popu_KNaK"] +# scale_popu_GbNa = self._parameters["scale_popu_GbNa"] +# scale_popu_GbCa = self._parameters["scale_popu_GbCa"] +# scale_popu_KpCa = self._parameters["scale_popu_KpCa"] +# scale_popu_KRyR = self._parameters["scale_popu_KRyR"] +# scale_popu_KSERCA = self._parameters["scale_popu_KSERCA"] +# scale_popu_Kleak = self._parameters["scale_popu_Kleak"] +# scale_popu_nTm = self._parameters["scale_popu_nTm"] +# scale_popu_CaT50ref = self._parameters["scale_popu_CaT50ref"] +# scale_popu_kuw = self._parameters["scale_popu_kuw"] +# scale_popu_kws = self._parameters["scale_popu_kws"] +# scale_popu_kTRPN = self._parameters["scale_popu_kTRPN"] +# scale_popu_nTRPN = self._parameters["scale_popu_nTRPN"] +# scale_popu_ku = self._parameters["scale_popu_ku"] +# scale_popu_TRPN50 = self._parameters["scale_popu_TRPN50"] +# scale_popu_rw = self._parameters["scale_popu_rw"] +# scale_popu_rs = self._parameters["scale_popu_rs"] + +# # Systolic Heart Failure (HF with preserved ejection fraction) +# HF_scaling_CaMKa = self._parameters["HF_scaling_CaMKa"] +# HF_scaling_Jrel_inf = self._parameters["HF_scaling_Jrel_inf"] +# HF_scaling_Jleak = self._parameters["HF_scaling_Jleak"] +# HF_scaling_Jup = self._parameters["HF_scaling_Jup"] +# HF_scaling_GNaL = self._parameters["HF_scaling_GNaL"] +# HF_scaling_GK1 = self._parameters["HF_scaling_GK1"] +# HF_scaling_thL = self._parameters["HF_scaling_thL"] +# HF_scaling_Gto = self._parameters["HF_scaling_Gto"] +# HF_scaling_Gncx = self._parameters["HF_scaling_Gncx"] +# HF_scaling_Pnak = self._parameters["HF_scaling_Pnak"] +# HF_scaling_cat50_ref = self._parameters["HF_scaling_cat50_ref"] + +# # Init return args +# F_expressions = [dolfin.Constant(0.0)] * 45 + +# # Expressions for the cell geometry component +# vcell = 3140.0 * L * (rad * rad) +# Ageo = 6.28 * (rad * rad) + 6.28 * L * rad +# Acap = 2 * Ageo +# vmyo = 0.68 * vcell +# vnsr = 0.0552 * vcell +# vjsr = 0.0048 * vcell +# vss = 0.02 * vcell + +# # Expressions for the CaMKt component +# CaMKb = CaMKo * (1.0 - CaMKt) / (1.0 + KmCaM / cass) +# CaMKa = (CaMKb + CaMKt) * HF_scaling_CaMKa +# F_expressions[0] = -bCaMK * CaMKt + aCaMK * (CaMKb + CaMKt) * CaMKb + +# # Expressions for the reversal potentials component +# ENa = R * T * ufl.ln(nao / nai) / F +# EK = R * T * ufl.ln(ko / ki) / F +# EKs = R * T * ufl.ln((ko + PKNa * nao) / (PKNa * nai + ki)) / F +# vffrt = (F * F) * v / (R * T) +# vfrt = F * v / (R * T) + +# # Expressions for the I_Na component +# mss = 1.0 / (1.0 + 0.0014599788446489682 * ufl.exp(-0.13333333333333333 * v)) +# tm = 1.0 / ( +# 9.454904638564724 * ufl.exp(0.02876042565429968 * v) +# + 1.9314113558536928e-05 * ufl.exp(-0.16792611251049538 * v) +# ) +# F_expressions[1] = (-m + mss) / tm +# hss = 1.0 / (1 + 302724.605401998 * ufl.exp(0.1607717041800643 * v)) +# thf = 1.0 / ( +# 1.183856958289087e-05 * ufl.exp(-0.15910898965791567 * v) +# + 6.305549185817275 * ufl.exp(0.0493339911198816 * v) +# ) +# ths = 1.0 / ( +# 0.005164670235381792 * ufl.exp(-0.035650623885918005 * v) +# + 0.36987619372096325 * ufl.exp(0.017649135192375574 * v) +# ) +# Ahs = 1.0 - Ahf +# F_expressions[2] = (-hf + hss) / thf +# F_expressions[3] = (-hs + hss) / ths +# h = Ahf * hf + Ahs * hs +# jss = hss +# tj = 2.038 + 1.0 / ( +# 0.3131936394738773 * ufl.exp(0.02600780234070221 * v) +# + 1.1315282095590072e-07 * ufl.exp(-0.12075836251660427 * v) +# ) +# F_expressions[4] = (-j + jss) / tj +# hssp = 1.0 / (1 + 820249.0921708513 * ufl.exp(0.1607717041800643 * v)) +# thsp = 3.0 * ths +# F_expressions[5] = (-hsp + hssp) / thsp +# hp = Ahf * hf + Ahs * hsp +# tjp = 1.46 * tj +# F_expressions[6] = (-jp + jss) / tjp +# fINap = 1.0 / (1.0 + KmCaMK / CaMKa) +# INa = ( +# GNa +# * scale_drug_INa +# * scale_popu_GNa +# * ufl.elem_pow(m, 3.0) +# * (-ENa + v) +# * ((1.0 - fINap) * h * j + fINap * hp * jp) +# ) + +# # Expressions for the INaL component +# mLss = 1.0 / (1.0 + 0.000291579585635531 * ufl.exp(-0.18996960486322187 * v)) +# tmL = tm +# F_expressions[7] = (-mL + mLss) / tmL +# hLss = 1.0 / (1.0 + 120578.15595522427 * ufl.exp(0.13354700854700854 * v)) +# F_expressions[8] = (-hL + hLss) / (thL * HF_scaling_thL) +# hLssp = 1.0 / (1.0 + 275969.2903869871 * ufl.exp(0.13354700854700854 * v)) +# thLp = 3.0 * thL * HF_scaling_thL +# F_expressions[9] = (-hLp + hLssp) / thLp +# GNaL = 0.0075 * scale_INaL * scale_drug_INaL * scale_popu_GNaL * HF_scaling_GNaL +# fINaLp = 1.0 / (1.0 + KmCaMK / CaMKa) +# INaL = (-ENa + v) * ((1.0 - fINaLp) * hL + fINaLp * hLp) * GNaL * mL + +# # Expressions for the Ito component +# ass = 1.0 / (1.0 + 2.6316508161673635 * ufl.exp(-0.06747638326585695 * v)) +# ta = 1.0515 / ( +# 1.0 / (1.2089 + 2.2621017070578837 * ufl.exp(-0.03403513787634354 * v)) +# + 3.5 / (1.0 + 30.069572727397507 * ufl.exp(0.03403513787634354 * v)) +# ) +# F_expressions[10] = (-a + ass) / ta +# iss = 1.0 / (1.0 + 2194.970764538301 * ufl.exp(0.17510068289266328 * v)) +# tiF = 4.562 + delta_epi / ( +# 0.14468698421272827 * ufl.exp(-0.01 * v) +# + 1.6300896349780942 * ufl.exp(0.06027727546714889 * v) +# ) +# tiS = 23.62 + delta_epi / ( +# 0.00027617763953377436 * ufl.exp(-0.01693480101608806 * v) +# + 0.024208962804604526 * ufl.exp(0.12377769525931426 * v) +# ) +# AiF = 1.0 / (1.0 + 0.24348537187522867 * ufl.exp(0.006613756613756614 * v)) +# AiS = 1.0 - AiF +# F_expressions[11] = (-iF + iss) / tiF +# F_expressions[12] = (-iS + iss) / tiS +# i = AiF * iF + AiS * iS +# assp = 1.0 / (1.0 + 5.167428462230666 * ufl.exp(-0.06747638326585695 * v)) +# F_expressions[13] = (-ap + assp) / ta +# dti_develop = 1.354 + 0.0001 / ( +# 2.6591269045230603e-05 * ufl.exp(0.06293266205160478 * v) +# + 4.5541779737128264e24 * ufl.exp(-4.642525533890436 * v) +# ) +# dti_recover = 1.0 - 0.5 / (1.0 + 33.11545195869231 * ufl.exp(0.05 * v)) +# tiFp = dti_develop * dti_recover * tiF +# tiSp = dti_develop * dti_recover * tiS +# F_expressions[14] = (-iFp + iss) / tiFp +# F_expressions[15] = (-iSp + iss) / tiSp +# ip = AiF * iFp + AiS * iSp +# fItop = 1.0 / (1.0 + KmCaMK / CaMKa) +# Ito = ( +# Gto +# * scale_drug_Ito +# * scale_popu_Gto +# * HF_scaling_Gto +# * (-EK + v) +# * ((1.0 - fItop) * a * i + ap * fItop * ip) +# ) + +# # Expressions for the ICaL ICaNa ICaK component +# dss = 1.0 / (1.0 + 0.39398514226669484 * ufl.exp(-0.23640661938534277 * v)) +# td = 0.6 + 1.0 / ( +# 3.5254214873653824 * ufl.exp(0.09 * v) +# + 0.7408182206817179 * ufl.exp(-0.05 * v) +# ) +# F_expressions[16] = (-d + dss) / td +# fss = 1.0 / (1.0 + 199.86038496778565 * ufl.exp(0.27056277056277056 * v)) +# tff = 7.0 + 1.0 / ( +# 0.03325075244518792 * ufl.exp(0.1 * v) +# + 0.0006090087745647571 * ufl.exp(-0.1 * v) +# ) +# tfs = 1000.0 + 1.0 / ( +# 1.0027667890106652e-05 * ufl.exp(-0.25 * v) +# + 8.053415618124885e-05 * ufl.exp(0.16666666666666666 * v) +# ) +# Afs = 1.0 - Aff +# F_expressions[17] = (-ff + fss) / tff +# F_expressions[18] = (-fs + fss) / tfs +# f = Aff * ff + Afs * fs +# fcass = fss +# tfcaf = 7.0 + 1.0 / ( +# 0.0708317980974062 * ufl.exp(-0.14285714285714285 * v) +# + 0.02258872488031037 * ufl.exp(0.14285714285714285 * v) +# ) +# tfcas = 100.0 + 1.0 / ( +# 0.00012 * ufl.exp(0.14285714285714285 * v) +# + 0.00012 * ufl.exp(-0.3333333333333333 * v) +# ) +# Afcaf = 0.3 + 0.6 / (1.0 + 0.36787944117144233 * ufl.exp(0.1 * v)) +# Afcas = 1.0 - Afcaf +# F_expressions[19] = (-fcaf + fcass) / tfcaf +# F_expressions[20] = (-fcas + fcass) / tfcas +# fca = Afcaf * fcaf + Afcas * fcas +# F_expressions[21] = (-jca + fcass) / tjca +# tffp = 2.5 * tff +# F_expressions[22] = (-ffp + fss) / tffp +# fp = Aff * ffp + Afs * fs +# tfcafp = 2.5 * tfcaf +# F_expressions[23] = (-fcafp + fcass) / tfcafp +# fcap = Afcaf * fcafp + Afcas * fcas +# km2n = 1.0 * jca +# anca = 1.0 / (ufl.elem_pow(1.0 + Kmn / cass, 4.0) + k2n / km2n) +# F_expressions[24] = k2n * anca - km2n * nca +# PhiCaL = ( +# 4.0 +# * (-0.341 * cao + cass * ufl.exp(2.0 * vfrt)) +# * vffrt +# / (-1.0 + ufl.exp(2.0 * vfrt)) +# ) +# PhiCaNa = ( +# 1.0 +# * (-0.75 * nao + 0.75 * ufl.exp(1.0 * vfrt) * nass) +# * vffrt +# / (-1.0 + ufl.exp(1.0 * vfrt)) +# ) +# PhiCaK = ( +# 1.0 +# * (-0.75 * ko + 0.75 * ufl.exp(1.0 * vfrt) * kss) +# * vffrt +# / (-1.0 + ufl.exp(1.0 * vfrt)) +# ) +# PCa = 0.0001 * scale_ICaL * scale_drug_ICaL * scale_popu_GCaL +# PCap = 1.1 * PCa +# PCaNa = 0.00125 * PCa +# PCaK = 0.0003574 * PCa +# PCaNap = 0.00125 * PCap +# PCaKp = 0.0003574 * PCap +# fICaLp = 1.0 / (1.0 + KmCaMK / CaMKa) +# ICaL = (1.0 - fICaLp) * ( +# (1.0 - nca) * f + fca * jca * nca +# ) * PCa * PhiCaL * d + ( +# (1.0 - nca) * fp + fcap * jca * nca +# ) * PCap * PhiCaL * d * fICaLp +# ICaNa = (1.0 - fICaLp) * ( +# (1.0 - nca) * f + fca * jca * nca +# ) * PCaNa * PhiCaNa * d + ( +# (1.0 - nca) * fp + fcap * jca * nca +# ) * PCaNap * PhiCaNa * d * fICaLp +# ICaK = (1.0 - fICaLp) * ( +# (1.0 - nca) * f + fca * jca * nca +# ) * PCaK * PhiCaK * d + ( +# (1.0 - nca) * fp + fcap * jca * nca +# ) * PCaKp * PhiCaK * d * fICaLp + +# # Expressions for the IKr component +# xrss = 1.0 / (1.0 + 0.29287308872377504 * ufl.exp(-0.14729709824716453 * v)) +# txrf = 12.98 + 1.0 / ( +# 0.0001020239312894894 * ufl.exp(0.25846471956577927 * v) +# + 0.00042992960891929087 * ufl.exp(-0.04906771344455348 * v) +# ) +# txrs = 1.865 + 1.0 / ( +# 0.0005922420036809394 * ufl.exp(0.13596193065941536 * v) +# + 3.549966111802463e-05 * ufl.exp(-0.03855050115651503 * v) +# ) +# Axrf = 1.0 / (1.0 + 4.197299094734718 * ufl.exp(0.02617115938236064 * v)) +# Axrs = 1.0 - Axrf +# F_expressions[25] = (-xrf + xrss) / txrf +# F_expressions[26] = (-xrs + xrss) / txrs +# xr = Axrf * xrf + Axrs * xrs +# rkr = 1.0 / ( +# (1.0 + 2.0820090840784555 * ufl.exp(0.013333333333333334 * v)) +# * (1.0 + 0.7165313105737893 * ufl.exp(0.03333333333333333 * v)) +# ) +# GKr = 0.046 * scale_IKr * scale_drug_IKr * scale_popu_GKr +# IKr = 0.4303314829119352 * ufl.sqrt(ko) * (-EK + v) * GKr * rkr * xr + +# # Expressions for the IKs component +# xs1ss = 1.0 / (1.0 + 0.27288596035656526 * ufl.exp(-0.11195700850873264 * v)) +# txs1 = 817.3 + 1.0 / ( +# 0.003504067763074858 * ufl.exp(0.056179775280898875 * v) +# + 0.0005184809083581659 * ufl.exp(-0.004347826086956522 * v) +# ) +# F_expressions[27] = (-xs1 + xs1ss) / txs1 +# xs2ss = xs1ss +# txs2 = 1.0 / ( +# 0.0022561357010639103 * ufl.exp(-0.03225806451612903 * v) +# + 0.0008208499862389881 * ufl.exp(0.05 * v) +# ) +# F_expressions[28] = (-xs2 + xs2ss) / txs2 +# KsCa = 1.0 + 0.6 / (1.0 + 6.481821026062645e-07 * ufl.elem_pow(1.0 / cai, 1.4)) +# GKs = 0.0034 * scale_IKs * scale_drug_IKs * scale_popu_GKs +# IKs = (-EKs + v) * GKs * KsCa * xs1 * xs2 +# xk1ss = 1.0 / ( +# 1.0 + ufl.exp((-144.59 - v - 2.5538 * ko) / (3.8115 + 1.5692 * ko)) +# ) +# txk1 = 122.2 / ( +# 0.0019352007631390235 * ufl.exp(-0.049115913555992145 * v) +# + 30.43364757524903 * ufl.exp(0.014423770373575654 * v) +# ) +# F_expressions[29] = (-xk1 + xk1ss) / txk1 +# rk1 = 1.0 / ( +# 1.0 +# + 69220.6322106767 +# * ufl.exp(0.10534077741493732 * v - 0.27388602127883704 * ko) +# ) +# GK1 = 0.1908 * scale_IK1 * scale_drug_IK1 * scale_popu_GK1 * HF_scaling_GK1 +# IK1 = ufl.sqrt(ko) * (-EK + v) * GK1 * rk1 * xk1 + +# # Expressions for the INaCa_i component +# hca = ufl.exp(F * qca * v / (R * T)) +# hna = ufl.exp(F * qna * v / (R * T)) +# h1_i = 1.0 + (1.0 + hna) * nai / kna3 +# h2_i = hna * nai / (kna3 * h1_i) +# h3_i = 1.0 / h1_i +# h4_i = 1.0 + (1 + nai / kna2) * nai / kna1 +# h5_i = (nai * nai) / (kna1 * kna2 * h4_i) +# h6_i = 1.0 / h4_i +# h7_i = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 +# h8_i = nao / (kna3 * h7_i * hna) +# h9_i = 1.0 / h7_i +# h10_i = 1.0 + kasymm + nao * (1.0 + nao / kna2) / kna1 +# h11_i = (nao * nao) / (kna1 * kna2 * h10_i) +# h12_i = 1.0 / h10_i +# k1_i = cao * kcaon * h12_i +# k2_i = kcaoff +# k3p_i = wca * h9_i +# k3pp_i = wnaca * h8_i +# k3_i = k3p_i + k3pp_i +# k4p_i = wca * h3_i / hca +# k4pp_i = wnaca * h2_i +# k4_i = k4p_i + k4pp_i +# k5_i = kcaoff +# k6_i = kcaon * cai * h6_i +# k7_i = wna * h2_i * h5_i +# k8_i = wna * h11_i * h8_i +# x1_i = (k2_i + k3_i) * k5_i * k7_i + (k6_i + k7_i) * k2_i * k4_i +# x2_i = (k1_i + k8_i) * k4_i * k6_i + (k4_i + k5_i) * k1_i * k7_i +# x3_i = (k2_i + k3_i) * k6_i * k8_i + (k6_i + k7_i) * k1_i * k3_i +# x4_i = (k1_i + k8_i) * k3_i * k5_i + (k4_i + k5_i) * k2_i * k8_i +# E1_i = x1_i / (x1_i + x2_i + x3_i + x4_i) +# E2_i = x2_i / (x1_i + x2_i + x3_i + x4_i) +# E3_i = x3_i / (x1_i + x2_i + x3_i + x4_i) +# E4_i = x4_i / (x1_i + x2_i + x3_i + x4_i) +# allo_i = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cai, 2.0)) +# zna = 1.0 +# JncxNa_i = E3_i * k4pp_i - E2_i * k3pp_i + 3.0 * E4_i * k7_i - 3.0 * E1_i * k8_i +# JncxCa_i = E2_i * k2_i - E1_i * k1_i +# INaCa_i = ( +# 0.8 +# * Gncx +# * scale_popu_KNCX +# * HF_scaling_Gncx +# * (zca * JncxCa_i + zna * JncxNa_i) +# * allo_i +# ) + +# # Expressions for the INaCa_ss component +# h1 = 1.0 + (1.0 + hna) * nass / kna3 +# h2 = hna * nass / (kna3 * h1) +# h3 = 1.0 / h1 +# h4 = 1.0 + (1 + nass / kna2) * nass / kna1 +# h5 = (nass * nass) / (kna1 * kna2 * h4) +# h6 = 1.0 / h4 +# h7 = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 +# h8 = nao / (kna3 * h7 * hna) +# h9 = 1.0 / h7 +# h10 = 1.0 + kasymm + nao * (1 + nao / kna2) / kna1 +# h11 = (nao * nao) / (kna1 * kna2 * h10) +# h12 = 1.0 / h10 +# k1 = cao * kcaon * h12 +# k2 = kcaoff +# k3p_ss = wca * h9 +# k3pp = wnaca * h8 +# k3 = k3p_ss + k3pp +# k4p_ss = wca * h3 / hca +# k4pp = wnaca * h2 +# k4 = k4p_ss + k4pp +# k5 = kcaoff +# k6 = kcaon * cass * h6 +# k7 = wna * h2 * h5 +# k8 = wna * h11 * h8 +# x1_ss = (k2 + k3) * k5 * k7 + (k6 + k7) * k2 * k4 +# x2_ss = (k1 + k8) * k4 * k6 + (k4 + k5) * k1 * k7 +# x3_ss = (k2 + k3) * k6 * k8 + (k6 + k7) * k1 * k3 +# x4_ss = (k1 + k8) * k3 * k5 + (k4 + k5) * k2 * k8 +# E1_ss = x1_ss / (x1_ss + x2_ss + x3_ss + x4_ss) +# E2_ss = x2_ss / (x1_ss + x2_ss + x3_ss + x4_ss) +# E3_ss = x3_ss / (x1_ss + x2_ss + x3_ss + x4_ss) +# E4_ss = x4_ss / (x1_ss + x2_ss + x3_ss + x4_ss) +# allo_ss = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cass, 2.0)) +# JncxNa_ss = E3_ss * k4pp - E2_ss * k3pp + 3.0 * E4_ss * k7 - 3.0 * E1_ss * k8 +# JncxCa_ss = E2_ss * k2 - E1_ss * k1 +# INaCa_ss = ( +# 0.2 +# * Gncx +# * scale_popu_KNCX +# * HF_scaling_Gncx +# * (zca * JncxCa_ss + zna * JncxNa_ss) +# * allo_ss +# ) + +# # Expressions for the INaK component +# Knai = Knai0 * ufl.exp(0.3333333333333333 * F * delta * v / (R * T)) +# Knao = Knao0 * ufl.exp(0.3333333333333333 * F * (1.0 - delta) * v / (R * T)) +# P = eP / (1.0 + H / Khp + nai / Knap + ki / Kxkur) +# a1 = ( +# k1p +# * ufl.elem_pow(nai / Knai, 3.0) +# / ( +# -1.0 +# + ufl.elem_pow(1.0 + ki / Kki, 2.0) +# + ufl.elem_pow(1.0 + nai / Knai, 3.0) +# ) +# ) +# b1 = MgADP * k1m +# a2 = k2p +# b2 = ( +# k2m +# * ufl.elem_pow(nao / Knao, 3.0) +# / ( +# -1.0 +# + ufl.elem_pow(1.0 + ko / Kko, 2.0) +# + ufl.elem_pow(1.0 + nao / Knao, 3.0) +# ) +# ) +# a3 = ( +# k3p +# * ufl.elem_pow(ko / Kko, 2.0) +# / ( +# -1.0 +# + ufl.elem_pow(1.0 + ko / Kko, 2.0) +# + ufl.elem_pow(1.0 + nao / Knao, 3.0) +# ) +# ) +# b3 = H * k3m * P / (1.0 + MgATP / Kmgatp) +# a4 = MgATP * k4p / (Kmgatp * (1.0 + MgATP / Kmgatp)) +# b4 = ( +# k4m +# * ufl.elem_pow(ki / Kki, 2.0) +# / ( +# -1.0 +# + ufl.elem_pow(1.0 + ki / Kki, 2.0) +# + ufl.elem_pow(1.0 + nai / Knai, 3.0) +# ) +# ) +# x1 = a1 * a2 * a4 + a1 * a2 * b3 + a2 * b3 * b4 + b2 * b3 * b4 +# x2 = a1 * a2 * a3 + a2 * a3 * b4 + a3 * b1 * b4 + b1 * b2 * b4 +# x3 = a2 * a3 * a4 + a3 * a4 * b1 + a4 * b1 * b2 + b1 * b2 * b3 +# x4 = a1 * a3 * a4 + a1 * a4 * b2 + a1 * b2 * b3 + b2 * b3 * b4 +# E1 = x1 / (x1 + x2 + x3 + x4) +# E2 = x2 / (x1 + x2 + x3 + x4) +# E3 = x3 / (x1 + x2 + x3 + x4) +# E4 = x4 / (x1 + x2 + x3 + x4) +# JnakNa = 3.0 * E1 * a3 - 3.0 * E2 * b3 +# JnakK = 2.0 * E4 * b1 - 2.0 * E3 * a1 +# INaK = Pnak * scale_popu_KNaK * HF_scaling_Pnak * (zk * JnakK + zna * JnakNa) + +# # Expressions for the IKb component +# xkb = 1.0 / (1.0 + 2.202363450949239 * ufl.exp(-0.05452562704471101 * v)) +# IKb = GKb * scale_popu_GbK * scale_drug_IKb * (-EK + v) * xkb + +# # Expressions for the INab component +# INab = ( +# PNab +# * scale_drug_INab +# * scale_popu_GbNa +# * (-nao + ufl.exp(vfrt) * nai) +# * vffrt +# / (-1.0 + ufl.exp(vfrt)) +# ) + +# # Expressions for the ICab component +# ICab = ( +# 4.0 +# * PCab +# * scale_drug_ICab +# * scale_popu_GbCa +# * (-0.341 * cao + cai * ufl.exp(2.0 * vfrt)) +# * vffrt +# / (-1.0 + ufl.exp(2.0 * vfrt)) +# ) + +# # Expressions for the IpCa component +# IpCa = GpCa * scale_drug_IpCa * scale_popu_KpCa * cai / (0.0005 + cai) + +# # Expressions for the Isac (Pueyo)--> ns + k component +# Gsac_ns = 0.006 * scale_drug_Isacns +# Esac_ns = -10.0 +# lambda_max = 1.1 +# Gsac_k = (0.2882 * 800.0 / 210.0) * scale_drug_Isack # Pueyo endo +# Isac_P_ns = ufl.conditional( +# ufl.lt(self.lmbda, 1.0), +# 0.0, +# Gsac_ns * ((self.lmbda - 1.0) / (lambda_max - 1.0)) * (v - Esac_ns), +# ) +# Isac_P_k = ufl.conditional( +# ufl.lt(self.lmbda, 1.0), +# 0.0, +# Gsac_k +# * ((self.lmbda - 1.0) / (lambda_max - 1.0)) +# * (1.0 / (1.0 + ufl.exp((19.05 - v) / (29.98)))), +# ) + +# # Expressions for the Istim component +# Istim = 0 # amp*(ufl.le(time, duration)) + +# # Expressions for the diffusion fluxes component +# JdiffNa = 0.5 * nass - 0.5 * nai +# JdiffK = 0.5 * kss - 0.5 * ki +# Jdiff = 5.0 * cass - 5.0 * cai + +# # Expressions for the ryanodine receptor component +# a_rel = 0.5 * bt +# Jrel_inf = ( +# -ICaL +# * a_rel +# / (1.0 + 25.62890625 * HF_scaling_Jrel_inf * ufl.elem_pow(1.0 / cajsr, 8.0)) +# ) +# tau_rel_tmp = bt / (1.0 + 0.0123 / cajsr) +# tau_rel = ufl.conditional(ufl.lt(tau_rel_tmp, 0.001), 0.001, tau_rel_tmp) +# F_expressions[30] = (-Jrelnp + Jrel_inf) / tau_rel +# btp = 1.25 * bt +# a_relp = 0.5 * btp +# Jrel_infp = ( +# -ICaL +# * a_relp +# / (1.0 + 25.62890625 * HF_scaling_Jrel_inf * ufl.elem_pow(1.0 / cajsr, 8.0)) +# ) +# tau_relp_tmp = btp / (1.0 + 0.0123 / cajsr) +# tau_relp = ufl.conditional(ufl.lt(tau_relp_tmp, 0.001), 0.001, tau_relp_tmp) +# F_expressions[31] = (-Jrelp + Jrel_infp) / tau_relp +# fJrelp = 1.0 / (1.0 + KmCaMK / CaMKa) +# Jrel = ((1.0 - fJrelp) * Jrelnp + Jrelp * fJrelp) * scale_popu_KRyR + +# # Expressions for the calcium buffers component +# Jupnp = 0.004375 * cai / (0.00092 + cai) +# Jupp = 0.01203125 * cai / (0.00075 + cai) +# fJupp = 1.0 / (1.0 + KmCaMK / CaMKa) +# Jleak = 0.0002625 * cansr * scale_popu_Kleak * HF_scaling_Jleak +# Jup = ( +# -Jleak +# + ((1.0 - fJupp) * Jupnp + Jupp * fJupp) +# * scale_popu_KSERCA +# * HF_scaling_Jup +# ) +# Jtr = 0.01 * cansr - 0.01 * cajsr + +# # Expressions for the intracellular concentrations component +# F_expressions[32] = JdiffNa * vss / vmyo + ( +# -INa - INaL - INab - Isac_P_ns / 3.0 - 3.0 * INaCa_i - 3.0 * INaK +# ) * Acap / (F * vmyo) +# F_expressions[33] = -JdiffNa + (-ICaNa - 3.0 * INaCa_ss) * Acap / (F * vss) +# F_expressions[34] = JdiffK * vss / vmyo + ( +# -Isac_P_k +# - IK1 +# - IKb +# - IKr +# - IKs +# - Istim +# - Ito +# - Isac_P_ns / 3.0 +# + 2.0 * INaK +# ) * Acap / (F * vmyo) +# F_expressions[35] = -JdiffK - Acap * ICaK / (F * vss) +# Bcass = 1.0 / ( +# 1.0 +# + BSLmax * KmBSL * ufl.elem_pow(KmBSL + cass, -2.0) +# + BSRmax * KmBSR * ufl.elem_pow(KmBSR + cass, -2.0) +# ) +# F_expressions[36] = ( +# -Jdiff +# + Jrel * vjsr / vss +# + 0.5 * (-ICaL + 2.0 * INaCa_ss) * Acap / (F * vss) +# ) * Bcass +# F_expressions[37] = -Jtr * vjsr / vnsr + Jup +# Bcajsr = 1.0 / (1.0 + csqnmax * kmcsqn * ufl.elem_pow(kmcsqn + cajsr, -2.0)) +# F_expressions[38] = (-Jrel + Jtr) * Bcajsr + +# # Expressions for the mechanics component +# kwu = -kws * scale_popu_kws + (kuw * scale_popu_kuw) * ( +# -1.0 + 1.0 / (rw * scale_popu_rw) +# ) +# ksu = ( +# kws +# * scale_popu_kws +# * rw +# * scale_popu_rw +# * (-1.0 + 1.0 / (rs * scale_popu_rs)) +# ) + +# lambda_min12 = ufl.conditional(ufl.lt(self.lmbda, 1.2), self.lmbda, 1.2) +# XS = ufl.conditional(ufl.lt(XS, 0.0), 0.0, XS) +# XW = ufl.conditional(ufl.lt(XW, 0.0), 0.0, XW) + +# XU = 1.0 - TmB - XS - XW +# gammawu = gammaw * abs(self.Zetaw) +# # gammasu = gammas*ufl.conditional(ufl.gt(Zetas*(ufl.gt(Zetas, 0)), (-1 -\ +# # Zetas)*(ufl.lt(Zetas, -1))), Zetas*(ufl.gt(Zetas, 0)), (-1 -\ +# # Zetas)*(ufl.lt(Zetas, -1))) +# zetas1 = self.Zetas * ufl.conditional(ufl.gt(self.Zetas, 0.0), 1.0, 0.0) +# zetas2 = (-1.0 - self.Zetas) * ufl.conditional( +# ufl.lt(self.Zetas, -1.0), +# 1.0, +# 0.0, +# ) +# gammasu = gammas * Max(zetas1, zetas2) + +# F_expressions[39] = kws * scale_popu_kws * XW - XS * gammasu - XS * ksu +# F_expressions[40] = ( +# kuw * scale_popu_kuw * XU +# - kws * scale_popu_kws * XW +# - XW * gammawu +# - XW * kwu +# ) +# cat50 = ( +# cat50_ref * scale_popu_CaT50ref + Beta1 * (-1.0 + lambda_min12) +# ) * HF_scaling_cat50_ref +# CaTrpn = ufl.conditional(ufl.lt(CaTrpn, 0.0), 0.0, CaTrpn) +# F_expressions[41] = ( +# ktrpn +# * scale_popu_kTRPN +# * ( +# -CaTrpn +# + ufl.elem_pow(1000.0 * cai / cat50, ntrpn * scale_popu_nTRPN) +# * (1.0 - CaTrpn) +# ) +# ) +# kb = ( +# ku +# * scale_popu_ku +# * ufl.elem_pow(Trpn50 * scale_popu_TRPN50, (ntm * scale_popu_nTm)) +# / ( +# 1.0 +# - (rs * scale_popu_rs) +# - rw * scale_popu_rw * (1.0 - (rs * scale_popu_rs)) +# ) +# ) + +# F_expressions[42] = ( +# ufl.conditional( +# ufl.lt(ufl.elem_pow(CaTrpn, -(ntm * scale_popu_nTm) / 2.0), 100.0), +# ufl.elem_pow(CaTrpn, -(ntm * scale_popu_nTm) / 2.0), +# 100.0, +# ) +# * XU +# * kb +# - ku +# * scale_popu_ku +# * ufl.elem_pow(CaTrpn, (ntm * scale_popu_nTm) / 2.0) +# * TmB +# ) + +# C = -1.0 + lambda_min12 +# dCd = -Cd + C +# eta = ufl.conditional(ufl.lt(dCd, 0.0), etas, etal) +# F_expressions[43] = p_k * (-Cd + C) / eta +# Bcai = 1.0 / (1.0 + cmdnmax * kmcmdn * ufl.elem_pow(kmcmdn + cai, -2.0)) +# J_TRPN = trpnmax * F_expressions[41] +# F_expressions[44] = ( +# -J_TRPN +# + Jdiff * vss / vmyo +# - Jup * vnsr / vmyo +# + 0.5 * (-ICab - IpCa - Isac_P_ns / 3.0 + 2.0 * INaCa_i) * Acap / (F * vmyo) +# ) * Bcai + +# # Return results +# return as_vector(F_expressions) + +# def num_states(self): +# return 45 + +# def __str__(self): +# return "ORdmm_Land_em_coupling cardiac cell model" diff --git a/src/simcardems/models/fully_coupled_ORdmm_Land/em_model.py b/src/simcardems/models/fully_coupled_ORdmm_Land/em_model.py index 89f8c0db..80617474 100644 --- a/src/simcardems/models/fully_coupled_ORdmm_Land/em_model.py +++ b/src/simcardems/models/fully_coupled_ORdmm_Land/em_model.py @@ -83,7 +83,6 @@ def __eq__(self, __o: object) -> bool: return False for attr in [ - "vs", "mech_state", "lmbda_mech", "Zetas_mech", @@ -100,6 +99,12 @@ def __eq__(self, __o: object) -> bool: ): logger.info(f"{attr} differs in equality") return False + for attr in [ + "vs", + ]: + if not np.allclose(getattr(self, attr), getattr(__o, attr)): + logger.info(f"{attr} differs in equality") + return False return True @@ -124,8 +129,8 @@ def mech_state(self) -> dolfin.Function: return self.mech_solver.state @property - def vs(self) -> dolfin.Function: - return self.ep_solver.solution_fields()[0] + def vs(self) -> np.ndarray: + return self.ep_solver.ode.values @property def assigners(self) -> datacollector.Assigners: @@ -137,21 +142,19 @@ def assigners(self, assigners) -> None: def setup_assigners(self) -> None: from ...datacollector import Assigners + from . import cell_model - self.assigners = Assigners(vs=self.vs, mech_state=self.mech_state) - for name, index in [ - ("V", 0), - ("Ca", 45), - ("CaTrpn", 42), - ("TmB", 43), - ("Cd", 44), - ("XS", 40), - ("XW", 41), - ]: + self.assigners = Assigners( + vs=self.vs, + mech_state=self.mech_state, + V_mech=self.V_mech, + V_ep=self.V_ep, + ) + for name in ["v", "cai", "XS", "XW", "CaTrpn", "TmB", "Cd"]: self.assigners.register_subfunction( name=name, group="ep", - subspace_index=index, + subspace_index=cell_model.state_index(name), ) self.assigners.register_subfunction( @@ -167,10 +170,9 @@ def setup_assigners(self) -> None: self.assigners.register_subfunction( name=name, group="ep", - subspace_index=index, + subspace_index=cell_model.state_index(name), is_pre=True, ) - self.coupling_to_mechanics() def register_ep_model(self, solver): @@ -204,7 +206,8 @@ def update_prev_mechanics(self): self.mech_solver.material.active.update_prev() def update_prev_ep(self): - self.ep_solver.vs_.assign(self.ep_solver.vs) + pass + # self.ep_solver.vs_.assign(self.ep_solver.vs) def ep_to_coupling(self): logger.debug("Update mechanics") @@ -244,12 +247,12 @@ def print_mechanics_info(self): def print_ep_info(self): # Output some degrees of freedom - total_dofs = self.vs.function_space().dim() + total_dofs = self.ep_solver.pde.V.dim() logger.info("EP model") utils.print_mesh_info(self.ep_mesh, total_dofs) def cell_params(self): - return self.ep_solver.ode_solver._model.parameters() + return self.ep_solver.ode.parameters def register_datacollector(self, collector: datacollector.DataCollector) -> None: super().register_datacollector(collector=collector) @@ -284,15 +287,11 @@ def save_state( h5file.write(self.lmbda_mech, "/em/lmbda_prev") h5file.write(self.Zetas_mech, "/em/Zetas_prev") h5file.write(self.Zetaw_mech, "/em/Zetaw_prev") - h5file.write(self.ep_solver.vs, "/ep/vs") h5file.write(self.mech_solver.state, "/mechanics/state") - io.dict_to_h5( - self.cell_params(), - path, - "ep/cell_params", - comm=self.geometry.comm(), - ) + with io.h5pyfile(path, "a") as h5file: + h5file["ep/vs"] = self.vs + h5file["ep/cell_params"] = self.cell_params() @classmethod def from_state( @@ -313,18 +312,15 @@ def from_state( with io.h5pyfile(path) as h5file: config = Config(**io.h5_to_dict(h5file["config"])) state_params = io.h5_to_dict(h5file["state_params"]) - cell_params = io.h5_to_dict(h5file["ep"]["cell_params"]) - vs_signature = h5file["ep"]["vs"].attrs["signature"].decode() mech_signature = h5file["mechanics"]["state"].attrs["signature"].decode() + cell_params = h5file["ep"]["cell_params"][:] + vs = h5file["ep"]["vs"][:] config.drug_factors_file = drug_factors_file config.popu_factors_file = popu_factors_file config.disease_state = disease_state config.PCL = PCL - VS = dolfin.FunctionSpace(geo.ep_mesh, eval(vs_signature)) - vs = dolfin.Function(VS) - W = dolfin.FunctionSpace(geo.mechanics_mesh, eval(mech_signature)) mech_state = dolfin.Function(W) @@ -335,7 +331,6 @@ def from_state( Zetaw_prev = dolfin.Function(V, name="Zetaw") logger.debug("Load functions") with dolfin.HDF5File(geo.ep_mesh.mpi_comm(), path.as_posix(), "r") as h5file: - h5file.read(vs, "/ep/vs") h5file.read(mech_state, "/mechanics/state") h5file.read(lmbda_prev, "/em/lmbda_prev") h5file.read(Zetas_prev, "/em/Zetas_prev") @@ -343,11 +338,6 @@ def from_state( from . import CellModel, ActiveModel - cell_inits = io.vs_functions_to_dict( - vs, - state_names=CellModel.default_initial_conditions().keys(), - ) - cls_ActiveModel = partial( ActiveModel, Zetas=Zetas_prev, @@ -361,7 +351,7 @@ def from_state( cls_ActiveModel=cls_ActiveModel, geometry=geo, config=config, - cell_inits=cell_inits, + cell_inits=vs, cell_params=cell_params, mech_state_init=mech_state, state_params=state_params, diff --git a/src/simcardems/models/pureEP_ORdmm_Land/em_model.py b/src/simcardems/models/pureEP_ORdmm_Land/em_model.py index fe2c3ed2..37f429d5 100644 --- a/src/simcardems/models/pureEP_ORdmm_Land/em_model.py +++ b/src/simcardems/models/pureEP_ORdmm_Land/em_model.py @@ -60,25 +60,23 @@ def assigners(self, assigners) -> None: self._assigners = assigners def setup_assigners(self) -> None: - ... - # from ...datacollector import Assigners - - # self.assigners = Assigners(vs=self.vs, mech_state=None) - # for name, index in [ - # ("V", 0), - # ("Ca", 41), - # ("XS", 40), - # ("XW", 41), - # ("CaTrpn", 42), - # ("TmB", 43), - # ("Cd", 44), - # ]: - # self.assigners.register_subfunction( - # name=name, - # group="ep", - # subspace_index=index, - # ) - # pass + from ...datacollector import Assigners + + self.assigners = Assigners(vs=self.vs, V_ep=self.ep_solver.pde.V) + for name, index in [ + ("V", 0), + ("Ca", 45), + ("CaTrpn", 42), + ("TmB", 43), + ("Cd", 44), + ("XS", 40), + ("XW", 41), + ]: + self.assigners.register_subfunction( + name=name, + group="ep", + subspace_index=index, + ) def solve_ep(self, interval: Tuple[float, float]) -> None: self.ep_solver.step(interval) From 5fd19694c420714475308f0f0da042a47e49f2a9 Mon Sep 17 00:00:00 2001 From: Henrik Finsberg Date: Wed, 17 Jan 2024 13:26:25 +0100 Subject: [PATCH 4/7] Fully coupled is now working --- demos/simple_demo.py | 6 +- src/simcardems/__init__.py | 2 +- .../fully_coupled_ORdmm_Land/active_model.py | 12 +- .../fully_coupled_ORdmm_Land/cell_model.py | 1126 ++++++++++++++--- src/simcardems/postprocess.py | 2 +- src/simcardems/runner.py | 12 +- 6 files changed, 956 insertions(+), 204 deletions(-) diff --git a/demos/simple_demo.py b/demos/simple_demo.py index 661100b2..7b491229 100644 --- a/demos/simple_demo.py +++ b/demos/simple_demo.py @@ -25,11 +25,9 @@ outdir=outdir, geometry_path=geometry_path, geometry_schema_path=geometry_schema_path, - loglevel=10, + # loglevel=10, coupling_type="fully_coupled_ORdmm_Land", - # coupling_type="explicit_ORdmm_Land", - # mechanics_solve_strategy="fixed", - T=20, + T=200, ) # To see all different configuration options you can visit https://computationalphysiology.github.io/simcardems/api.html#module-simcardems.config diff --git a/src/simcardems/__init__.py b/src/simcardems/__init__.py index bde6e46d..571873c6 100644 --- a/src/simcardems/__init__.py +++ b/src/simcardems/__init__.py @@ -59,7 +59,7 @@ def set_log_level(level): set_log_level(_logging.INFO) _dolfin.set_log_level(_logging.WARNING) -for module in ["matplotlib", "h5py", "FFC", "UFL", "UFL_LEGACY"]: +for module in ["matplotlib", "h5py", "FFC", "UFL", "UFL_LEGACY", "beat"]: _logger = _logging.getLogger(module) _logger.setLevel(_logging.WARNING) diff --git a/src/simcardems/models/fully_coupled_ORdmm_Land/active_model.py b/src/simcardems/models/fully_coupled_ORdmm_Land/active_model.py index 12c4ee0b..ed47bef2 100644 --- a/src/simcardems/models/fully_coupled_ORdmm_Land/active_model.py +++ b/src/simcardems/models/fully_coupled_ORdmm_Land/active_model.py @@ -235,12 +235,12 @@ def Ta(self): * (Tref * scale_popu_Tref / (rs * scale_popu_rs)) * (self.XS * (self.Zetas + 1.0) + self.XW * self.Zetaw) ) - print("Ta", self.Ta_current.vector().get_local()) - print("Zetas", self.Zetas.vector().get_local()) - print("Zetaw", self.Zetaw.vector().get_local()) - print("XS", self.XS.vector().get_local()) - print("XW", self.XW.vector().get_local()) - print("dLambda", self.dLambda.vector().get_local()) + # print("Ta", self.Ta_current.vector().get_local()) + # print("Zetas", self.Zetas.vector().get_local()) + # print("Zetaw", self.Zetaw.vector().get_local()) + # print("XS", self.XS.vector().get_local()) + # print("XW", self.XW.vector().get_local()) + # print("dLambda", self.dLambda.vector().get_local()) return Ta diff --git a/src/simcardems/models/fully_coupled_ORdmm_Land/cell_model.py b/src/simcardems/models/fully_coupled_ORdmm_Land/cell_model.py index 5413ba84..3fc9a31c 100644 --- a/src/simcardems/models/fully_coupled_ORdmm_Land/cell_model.py +++ b/src/simcardems/models/fully_coupled_ORdmm_Land/cell_model.py @@ -40,6 +40,9 @@ logger = utils.getLogger(__name__) +import math +import numpy + def parameter_index(name: str) -> int: """Return the index of the parameter with the given name @@ -239,31 +242,31 @@ def state_index(name: str) -> int: "CaMKt": 12, "xk1": 13, "Zetaw": 14, - "XS": 15, - "XW": 16, - "TmB": 17, - "hLp": 18, - "iF": 19, - "iS": 20, - "fcaf": 21, - "fcas": 22, - "jca": 23, - "j": 24, - "fcafp": 25, - "ffp": 26, - "hsp": 27, - "jp": 28, - "mL": 29, - "xs2": 30, - "Zetas": 31, - "nca": 32, - "CaTrpn": 33, + "XW": 15, + "TmB": 16, + "hLp": 17, + "iF": 18, + "iS": 19, + "fcaf": 20, + "fcas": 21, + "jca": 22, + "j": 23, + "fcafp": 24, + "ffp": 25, + "hsp": 26, + "jp": 27, + "mL": 28, + "xs2": 29, + "Zetas": 30, + "nca": 31, + "CaTrpn": 32, + "XS": 33, "iFp": 34, "iSp": 35, "cajsr": 36, "cansr": 37, - "kss": 38, - "Cd": 39, + "Cd": 38, + "kss": 39, "Jrelnp": 40, "Jrelp": 41, "ki": 42, @@ -465,10 +468,10 @@ def init_parameter_values(**values): def init_state_values(**values): """Initialize state values""" # hL=1, a=0, ap=0, d=0, ff=1, fs=1, hf=1, hs=1, m=0, xrf=0 - # xrs=0, xs1=0, CaMKt=0, xk1=1, Zetaw=0, XS=0, XW=0, TmB=1 - # hLp=1, iF=1, iS=1, fcaf=1, fcas=1, jca=1, j=1, fcafp=1, ffp=1 - # hsp=1, jp=1, mL=0, xs2=0, Zetas=0, nca=0, CaTrpn=0, iFp=1 - # iSp=1, cajsr=1.2, cansr=1.2, kss=145, Cd=0, Jrelnp=0, Jrelp=0 + # xrs=0, xs1=0, CaMKt=0, xk1=1, Zetaw=0, XW=0, TmB=1, hLp=1 + # iF=1, iS=1, fcaf=1, fcas=1, jca=1, j=1, fcafp=1, ffp=1, hsp=1 + # jp=1, mL=0, xs2=0, Zetas=0, nca=0, CaTrpn=0, XS=0, iFp=1 + # iSp=1, cajsr=1.2, cansr=1.2, Cd=0, kss=145, Jrelnp=0, Jrelp=0 # ki=145, cass=0.0001, nass=7, cai=0.0001, nai=7, v=-87 states = numpy.array( @@ -489,7 +492,6 @@ def init_state_values(**values): 1, 0, 0, - 0, 1, 1, 1, @@ -507,12 +509,13 @@ def init_state_values(**values): 0, 0, 0, + 0, 1, 1, 1.2, 1.2, - 145, 0, + 145, 0, 0, 145, @@ -530,6 +533,752 @@ def init_state_values(**values): return states +def rhs(t, states, parameters): + # Assign states + hL = states[0] + a = states[1] + ap = states[2] + d = states[3] + ff = states[4] + fs = states[5] + hf = states[6] + hs = states[7] + m = states[8] + xrf = states[9] + xrs = states[10] + xs1 = states[11] + CaMKt = states[12] + xk1 = states[13] + Zetaw = states[14] + XW = states[15] + TmB = states[16] + hLp = states[17] + iF = states[18] + iS = states[19] + fcaf = states[20] + fcas = states[21] + jca = states[22] + j = states[23] + fcafp = states[24] + ffp = states[25] + hsp = states[26] + jp = states[27] + mL = states[28] + xs2 = states[29] + Zetas = states[30] + nca = states[31] + CaTrpn = states[32] + XS = states[33] + iFp = states[34] + iSp = states[35] + cajsr = states[36] + cansr = states[37] + Cd = states[38] + kss = states[39] + Jrelnp = states[40] + Jrelp = states[41] + ki = states[42] + cass = states[43] + nass = states[44] + cai = states[45] + nai = states[46] + v = states[47] + + # Assign parameters + Aff = parameters[0] + Ahf = parameters[1] + BSLmax = parameters[2] + BSRmax = parameters[3] + Beta0 = parameters[4] + Beta1 = parameters[5] + CaMKo = parameters[6] + Esac_ns = parameters[7] + F = parameters[8] + GKb = parameters[9] + GNa = parameters[10] + Gncx = parameters[11] + GpCa = parameters[12] + Gsac_k = parameters[13] + Gsac_ns = parameters[14] + Gto = parameters[15] + H = parameters[16] + Khp = parameters[17] + Kki = parameters[18] + Kko = parameters[19] + KmBSL = parameters[20] + KmBSR = parameters[21] + KmCaAct = parameters[22] + KmCaM = parameters[23] + KmCaMK = parameters[24] + Kmgatp = parameters[25] + Kmn = parameters[26] + Knai0 = parameters[27] + Knao0 = parameters[28] + Knap = parameters[29] + Kxkur = parameters[30] + L = parameters[31] + MgADP = parameters[32] + MgATP = parameters[33] + PCab = parameters[34] + PKNa = parameters[35] + PNab = parameters[36] + Pnak = parameters[37] + R = parameters[38] + T = parameters[39] + Tot_A = parameters[40] + Tref = parameters[41] + Trpn50 = parameters[42] + aCaMK = parameters[43] + amp = parameters[44] + bCaMK = parameters[45] + bt = parameters[46] + calib = parameters[47] + cao = parameters[48] + cat50_ref = parameters[49] + celltype = parameters[50] + cmdnmax = parameters[51] + csqnmax = parameters[52] + dLambda = parameters[53] + delta = parameters[54] + delta_epi = parameters[55] + duration = parameters[56] + eP = parameters[57] + emcoupling = parameters[58] + etal = parameters[59] + etas = parameters[60] + gammas = parameters[61] + gammaw = parameters[62] + isacs = parameters[63] + k1m = parameters[64] + k1p = parameters[65] + k2m = parameters[66] + k2n = parameters[67] + k2p = parameters[68] + k3m = parameters[69] + k3p = parameters[70] + k4m = parameters[71] + k4p = parameters[72] + kasymm = parameters[73] + kcaoff = parameters[74] + kcaon = parameters[75] + kmcmdn = parameters[76] + kmcsqn = parameters[77] + kmtrpn = parameters[78] + kna1 = parameters[79] + kna2 = parameters[80] + kna3 = parameters[81] + ko = parameters[82] + ktrpn = parameters[83] + ku = parameters[84] + kuw = parameters[85] + kws = parameters[86] + lambda_max = parameters[87] + lmbda = parameters[88] + mode = parameters[89] + nao = parameters[90] + ntm = parameters[91] + ntrpn = parameters[92] + p_a = parameters[93] + p_b = parameters[94] + p_k = parameters[95] + phi = parameters[96] + qca = parameters[97] + qna = parameters[98] + rad = parameters[99] + rs = parameters[100] + rw = parameters[101] + scale_HF_CaMKa = parameters[102] + scale_HF_GK1 = parameters[103] + scale_HF_GNaL = parameters[104] + scale_HF_Gncx = parameters[105] + scale_HF_Gto = parameters[106] + scale_HF_Jleak = parameters[107] + scale_HF_Jrel_inf = parameters[108] + scale_HF_Jup = parameters[109] + scale_HF_Pnak = parameters[110] + scale_HF_cat50_ref = parameters[111] + scale_HF_thL = parameters[112] + scale_ICaL = parameters[113] + scale_IK1 = parameters[114] + scale_IKr = parameters[115] + scale_IKs = parameters[116] + scale_INaL = parameters[117] + scale_drug_ICaL = parameters[118] + scale_drug_ICab = parameters[119] + scale_drug_IK1 = parameters[120] + scale_drug_IKb = parameters[121] + scale_drug_IKr = parameters[122] + scale_drug_IKs = parameters[123] + scale_drug_INa = parameters[124] + scale_drug_INaL = parameters[125] + scale_drug_INab = parameters[126] + scale_drug_IpCa = parameters[127] + scale_drug_Isack = parameters[128] + scale_drug_Isacns = parameters[129] + scale_drug_Ito = parameters[130] + thL = parameters[131] + tjca = parameters[132] + trpnmax = parameters[133] + wca = parameters[134] + wna = parameters[135] + wnaca = parameters[136] + zca = parameters[137] + zk = parameters[138] + + # Assign expressions + values = numpy.zeros_like(states) + zna = 1.0 + Afcaf = 0.3 + 0.6 / (numpy.exp((v - 10.0) / 10.0) + 1.0) + AiF = 1.0 / (numpy.exp((v - 213.6) / 151.2) + 1.0) + Axrf = 1.0 / (numpy.exp((v + 54.81) / 38.21) + 1.0) + ass = 1.0 / (numpy.exp((-(v - 14.34)) / 14.82) + 1.0) + assp = 1.0 / (numpy.exp((-(v - 24.34)) / 14.82) + 1.0) + dss = 1.0 / (numpy.exp((-(v + 3.94)) / 4.23) + 1.0) + dti_develop = 1.354 + 0.0001 / ( + numpy.exp((-(v - 12.23)) / 0.2154) + numpy.exp((v - 167.4) / 15.89) + ) + dti_recover = 1.0 - 0.5 / (numpy.exp((v + 70.0) / 20.0) + 1.0) + fss = 1.0 / (numpy.exp((v + 19.58) / 3.696) + 1.0) + hLss = 1.0 / (numpy.exp((v + 87.61) / 7.488) + 1.0) + hLssp = 1.0 / (numpy.exp((v + 93.81) / 7.488) + 1.0) + hss = 1.0 / (numpy.exp((v + 78.5) / 6.22) + 1) + hssp = 1.0 / (numpy.exp(((v + 78.5) + 6.2) / 6.22) + 1) + iss = 1.0 / (numpy.exp((v + 43.94) / 5.711) + 1.0) + mLss = 1.0 / (numpy.exp((-(v + 42.85)) / 5.264) + 1.0) + mss = 1.0 / (numpy.exp((-((v + 39.57) + 9.4)) / 7.5) + 1.0) + rkr = (1.0 * (1.0 / (numpy.exp((v + 55.0) / 75.0) + 1.0))) / ( + numpy.exp((v - 10.0) / 30.0) + 1.0 + ) + ta = 1.0515 / ( + 1.0 / ((1.2089 * (numpy.exp((-(v - 18.4099)) / 29.3814) + 1.0))) + + 3.5 / (numpy.exp((v + 100.0) / 29.3814) + 1.0) + ) + td = 0.6 + 1.0 / (numpy.exp((-0.05) * (v + 6.0)) + numpy.exp(0.09 * (v + 14.0))) + tfcaf = 7.0 + 1.0 / ( + 0.04 * numpy.exp((-(v - 4.0)) / 7.0) + 0.04 * numpy.exp((v - 4.0) / 7.0) + ) + tfcas = 100.0 + 1.0 / ( + 0.00012 * numpy.exp((-v) / 3.0) + 0.00012 * numpy.exp(v / 7.0) + ) + tff = 7.0 + 1.0 / ( + 0.0045 * numpy.exp((-(v + 20.0)) / 10.0) + 0.0045 * numpy.exp((v + 20.0) / 10.0) + ) + tfs = 1000.0 + 1.0 / ( + 3.5e-05 * numpy.exp((-(v + 5.0)) / 4.0) + 3.5e-05 * numpy.exp((v + 5.0) / 6.0) + ) + thf = 1.0 / ( + 6.149 * numpy.exp((v + 0.5096) / 20.27) + + 1.432e-05 * numpy.exp((-(v + 1.196)) / 6.285) + ) + ths = 1.0 / ( + 0.009794 * numpy.exp((-(v + 17.95)) / 28.05) + + 0.3343 * numpy.exp((v + 5.73) / 56.66) + ) + tj = 2.038 + 1.0 / ( + 0.3052 * numpy.exp((v + 0.9941) / 38.45) + + 0.02136 * numpy.exp((-(v + 100.6)) / 8.281) + ) + tm = 1.0 / ( + 6.765 * numpy.exp((v + 11.64) / 34.77) + + 8.552 * numpy.exp((-(v + 77.42)) / 5.955) + ) + txk1 = 122.2 / (numpy.exp((-(v + 127.2)) / 20.36) + numpy.exp((v + 236.8) / 69.33)) + txrf = 12.98 + 1.0 / ( + 4.123e-05 * numpy.exp((-(v - 47.78)) / 20.38) + + 0.3652 * numpy.exp((v - 31.66) / 3.869) + ) + txrs = 1.865 + 1.0 / ( + 1.128e-05 * numpy.exp((-(v - 29.74)) / 25.94) + + 0.06629 * numpy.exp((v - 34.7) / 7.355) + ) + txs1 = 817.3 + 1.0 / ( + 0.0002326 * numpy.exp((v + 48.28) / 17.8) + + 0.001292 * numpy.exp((-(v + 210.0)) / 230.0) + ) + txs2 = 1.0 / ( + 0.01 * numpy.exp((v - 50.0) / 20.0) + 0.0193 * numpy.exp((-(v + 66.54)) / 31.0) + ) + xkb = 1.0 / (numpy.exp((-(v - 14.48)) / 18.34) + 1.0) + xrss = 1.0 / (numpy.exp((-(v + 8.337)) / 6.789) + 1.0) + xs1ss = 1.0 / (numpy.exp((-(v + 11.6)) / 8.932) + 1.0) + Afs = 1.0 - Aff + Ageo = L * ((2 * 3.14) * rad) + rad * ((2 * 3.14) * rad) + vcell = L * (rad * ((3.14 * 1000) * rad)) + Ahs = 1.0 - Ahf + Aw = (Tot_A * rs) / (rs + rw * (1 - rs)) + Bcai = 1.0 / ((cmdnmax * kmcmdn) / (cai + kmcmdn) ** 2.0 + 1.0) + Jupnp = (0.004375 * cai) / (cai + 0.00092) + Jupp = ((0.004375 * 2.75) * cai) / ((cai + 0.00092) - 0.00017) + KsCa = 1.0 + 0.6 / ((3.8e-05 / cai) ** 1.4 + 1.0) + Bcajsr = 1.0 / ((csqnmax * kmcsqn) / (cajsr + kmcsqn) ** 2.0 + 1.0) + Bcass = 1.0 / ( + (BSLmax * KmBSL) / (KmBSL + cass) ** 2.0 + + ((BSRmax * KmBSR) / (KmBSR + cass) ** 2.0 + 1.0) + ) + Jdiff = (-cai + cass) / 0.2 + CaMKb = (CaMKo * (1.0 - CaMKt)) / (KmCaM / cass + 1.0) + CaTrpn_max = numpy.where((CaTrpn > 0), CaTrpn, 0) + rk1 = 1.0 / (numpy.exp((-2.6 * ko + (v + 105.8)) / 9.493) + 1.0) + xk1ss = 1.0 / ( + numpy.exp((-((2.5538 * ko + v) + 144.59)) / (1.5692 * ko + 3.8115)) + 1.0 + ) + vffrt = (F * (F * v)) / ((R * T)) + vfrt = (F * v) / ((R * T)) + EK = ((R * T) / F) * numpy.log(ko / ki) + EKs = ((R * T) / F) * numpy.log((PKNa * nao + ko) / (PKNa * nai + ki)) + ENa = ((R * T) / F) * numpy.log(nao / nai) + GK1 = scale_HF_GK1 * ((0.1908 * scale_IK1) * scale_drug_IK1) + GKr = (0.046 * scale_IKr) * scale_drug_IKr + GKs = (0.0034 * scale_IKs) * scale_drug_IKs + GNaL = scale_HF_GNaL * ((0.0075 * scale_INaL) * scale_drug_INaL) + km2n = 1.0 * jca + IpCa = (cai * (GpCa * scale_drug_IpCa)) / (cai + 0.0005) + lambda_min12 = numpy.where((lmbda < 1.2), lmbda, 1.2) + Isac_P_k = numpy.where( + (lmbda < 1.0), + 0.0, + (Gsac_k * ((lmbda - 1.0) / (lambda_max - 1.0))) + * (1.0 / (numpy.exp((19.05 - v) / 29.98) + 1.0)), + ) + Isac_P_ns = numpy.where( + (lmbda < 1.0), + 0.0, + (Gsac_ns * ((lmbda - 1.0) / (lambda_max - 1.0))) * (-Esac_ns + v), + ) + Istim = 0 # numpy.where((duration >= t), amp, 0) + JdiffK = (-ki + kss) / 2.0 + JdiffNa = (-nai + nass) / 2.0 + Jtr = (-cajsr + cansr) / 100.0 + Jleak = ((0.0039375 * cansr) * scale_HF_Jleak) / 15.0 + Knai = Knai0 * numpy.exp((F * (delta * v)) / (((3.0 * R) * T))) + Knao = Knao0 * numpy.exp((F * (v * (1.0 - delta))) / (((3.0 * R) * T))) + P = eP / (((H / Khp + 1.0) + nai / Knap) + ki / Kxkur) + PCa = (0.0001 * scale_ICaL) * scale_drug_ICaL + XS_max = numpy.where((XS > 0), XS, 0) + zetas1 = Zetas * numpy.where((Zetas > 0), 1.0, 0.0) + zetas2 = (-Zetas - 1.0) * numpy.where((Zetas < -1.0), 1.0, 0.0) + XW_max = numpy.where((XW > 0), XW, 0) + XU = -XW + (-XS + (1 - TmB)) + a2 = k2p + a4 = ((MgATP * k4p) / Kmgatp) / (1.0 + MgATP / Kmgatp) + a_rel = 0.5 * bt + btp = 1.25 * bt + tau_rel_tmp = bt / (1.0 + 0.0123 / cajsr) + allo_i = 1.0 / ((KmCaAct / cai) ** 2.0 + 1.0) + allo_ss = 1.0 / ((KmCaAct / cass) ** 2.0 + 1.0) + b1 = MgADP * k1m + cs = ((kws * phi) * (rw * (1 - rs))) / rs + ksu = (kws * rw) * (-1 + 1 / rs) + cw = ((kuw * phi) * ((1 - rs) * (1 - rw))) / ((rw * (1 - rs))) + kwu = kuw * (-1 + 1 / rw) - kws + gammawu = gammaw * numpy.abs(Zetaw) + h10 = (nao / kna1) * (1 + nao / kna2) + (kasymm + 1.0) + h10_i = (nao / kna1) * (1.0 + nao / kna2) + (kasymm + 1.0) + h4 = (nass / kna1) * (1 + nass / kna2) + 1.0 + h4_i = (nai / kna1) * (1 + nai / kna2) + 1.0 + hca = numpy.exp((F * (qca * v)) / ((R * T))) + hna = numpy.exp((F * (qna * v)) / ((R * T))) + k2 = kcaoff + k2_i = kcaoff + k5 = kcaoff + k5_i = kcaoff + kb = (Trpn50**ntm * ku) / (-rw * (1 - rs) + (1 - rs)) + thLp = scale_HF_thL * (3.0 * thL) + tiF = ( + delta_epi + * ( + 1 + / ( + 0.3933 * numpy.exp((-(v + 100.0)) / 100.0) + + 0.08004 * numpy.exp((v + 50.0) / 16.59) + ) + ) + + 4.562 + ) + tiS = ( + delta_epi + * ( + 1 + / ( + 0.001416 * numpy.exp((-(v + 96.52)) / 59.05) + + 1.78e-08 * numpy.exp((v + 114.1) / 8.079) + ) + ) + + 23.62 + ) + Afcas = 1.0 - Afcaf + AiS = 1.0 - AiF + Axrs = 1.0 - Axrf + fcass = fss + dhL_dt = (-hL + hLss) / ((scale_HF_thL * thL)) + values[0] = dhL_dt + jss = hss + da_dt = (-a + ass) / ta + values[1] = da_dt + dap_dt = (-ap + assp) / ta + values[2] = dap_dt + dd_dt = (-d + dss) / td + values[3] = dd_dt + tfcafp = 2.5 * tfcaf + tffp = 2.5 * tff + dff_dt = (-ff + fss) / tff + values[4] = dff_dt + dfs_dt = (-fs + fss) / tfs + values[5] = dfs_dt + dhf_dt = (-hf + hss) / thf + values[6] = dhf_dt + thsp = 3.0 * ths + dhs_dt = (-hs + hss) / ths + values[7] = dhs_dt + tjp = 1.46 * tj + tmL = tm + dm_dt = (-m + mss) / tm + values[8] = dm_dt + dxrf_dt = (-xrf + xrss) / txrf + values[9] = dxrf_dt + dxrs_dt = (-xrs + xrss) / txrs + values[10] = dxrs_dt + xs2ss = xs1ss + dxs1_dt = (-xs1 + xs1ss) / txs1 + values[11] = dxs1_dt + f = Aff * ff + Afs * fs + fp = Aff * ffp + Afs * fs + Acap = 2 * Ageo + vjsr = 0.0048 * vcell + vmyo = 0.68 * vcell + vnsr = 0.0552 * vcell + vss = 0.02 * vcell + h = Ahf * hf + Ahs * hs + hp = Ahf * hf + Ahs * hsp + As = Aw + CaMKa = scale_HF_CaMKa * (CaMKb + CaMKt) + dCaMKt_dt = -CaMKt * bCaMK + (CaMKb * aCaMK) * (CaMKb + CaMKt) + values[12] = dCaMKt_dt + dxk1_dt = (-xk1 + xk1ss) / txk1 + values[13] = dxk1_dt + ICab = ( + (vffrt * (4.0 * (PCab * scale_drug_ICab))) + * (cai * numpy.exp(2.0 * vfrt) - 0.341 * cao) + ) / (numpy.exp(2.0 * vfrt) - 1.0) + INab = ((vffrt * (PNab * scale_drug_INab)) * (nai * numpy.exp(vfrt) - nao)) / ( + numpy.exp(vfrt) - 1.0 + ) + PhiCaK = ((1.0 * vffrt) * (-0.75 * ko + (0.75 * kss) * numpy.exp(1.0 * vfrt))) / ( + numpy.exp(1.0 * vfrt) - 1.0 + ) + PhiCaL = ((4.0 * vffrt) * (-0.341 * cao + cass * numpy.exp(2.0 * vfrt))) / ( + numpy.exp(2.0 * vfrt) - 1.0 + ) + PhiCaNa = ( + (1.0 * vffrt) * (-0.75 * nao + (0.75 * nass) * numpy.exp(1.0 * vfrt)) + ) / (numpy.exp(1.0 * vfrt) - 1.0) + IKb = (xkb * (GKb * scale_drug_IKb)) * (-EK + v) + IK1 = (xk1 * (rk1 * (GK1 * math.sqrt(ko)))) * (-EK + v) + IKs = (xs2 * (xs1 * (GKs * KsCa))) * (-EKs + v) + anca = 1.0 / (k2n / km2n + (Kmn / cass + 1.0) ** 4.0) + C = lambda_min12 - 1 + cat50 = scale_HF_cat50_ref * (Beta1 * (lambda_min12 - 1) + cat50_ref) + lambda_min087 = numpy.where((lambda_min12 < 0.87), lambda_min12, 0.87) + a1 = (k1p * (nai / Knai) ** 3.0) / ( + ((1.0 + ki / Kki) ** 2.0 + (1.0 + nai / Knai) ** 3.0) - 1.0 + ) + b4 = (k4m * (ki / Kki) ** 2.0) / ( + ((1.0 + ki / Kki) ** 2.0 + (1.0 + nai / Knai) ** 3.0) - 1.0 + ) + a3 = (k3p * (ko / Kko) ** 2.0) / ( + ((1.0 + ko / Kko) ** 2.0 + (1.0 + nao / Knao) ** 3.0) - 1.0 + ) + b2 = (k2m * (nao / Knao) ** 3.0) / ( + ((1.0 + ko / Kko) ** 2.0 + (1.0 + nao / Knao) ** 3.0) - 1.0 + ) + b3 = (H * (P * k3m)) / (1.0 + MgATP / Kmgatp) + PCaK = 0.0003574 * PCa + PCaNa = 0.00125 * PCa + PCap = 1.1 * PCa + gammasu = gammas * numpy.where((zetas1 > zetas2), zetas1, zetas2) + a_relp = 0.5 * btp + tau_relp_tmp = btp / (1.0 + 0.0123 / cajsr) + tau_rel = numpy.where((tau_rel_tmp < 0.001), 0.001, tau_rel_tmp) + dZetaw_dt = Aw * dLambda - Zetaw * cw + values[14] = dZetaw_dt + dXW_dt = -XW * gammawu + (-XW * kws + (XU * kuw - XW * kwu)) + values[15] = dXW_dt + h11 = (nao * nao) / ((kna2 * (h10 * kna1))) + h12 = 1.0 / h10 + h11_i = (nao * nao) / ((kna2 * (h10_i * kna1))) + h12_i = 1.0 / h10_i + h5 = (nass * nass) / ((kna2 * (h4 * kna1))) + h6 = 1.0 / h4 + h5_i = (nai * nai) / ((kna2 * (h4_i * kna1))) + h6_i = 1.0 / h4_i + h1 = (nass / kna3) * (hna + 1) + 1 + h1_i = (nai / kna3) * (hna + 1) + 1 + h7 = (nao / kna3) * (1.0 + 1.0 / hna) + 1.0 + h7_i = (nao / kna3) * (1.0 + 1.0 / hna) + 1.0 + dTmB_dt = -TmB * CaTrpn ** (ntm / 2) * ku + XU * ( + kb + * numpy.where((CaTrpn ** (-1 / 2 * ntm) < 100), CaTrpn ** (-1 / 2 * ntm), 100) + ) + values[16] = dTmB_dt + dhLp_dt = (-hLp + hLssp) / thLp + values[17] = dhLp_dt + tiFp = tiF * (dti_develop * dti_recover) + diF_dt = (-iF + iss) / tiF + values[18] = diF_dt + tiSp = tiS * (dti_develop * dti_recover) + diS_dt = (-iS + iss) / tiS + values[19] = diS_dt + fca = Afcaf * fcaf + Afcas * fcas + fcap = Afcaf * fcafp + Afcas * fcas + i = AiF * iF + AiS * iS + ip = AiF * iFp + AiS * iSp + xr = Axrf * xrf + Axrs * xrs + dfcaf_dt = (-fcaf + fcass) / tfcaf + values[20] = dfcaf_dt + dfcas_dt = (-fcas + fcass) / tfcas + values[21] = dfcas_dt + djca_dt = (fcass - jca) / tjca + values[22] = djca_dt + dj_dt = (-j + jss) / tj + values[23] = dj_dt + dfcafp_dt = (-fcafp + fcass) / tfcafp + values[24] = dfcafp_dt + dffp_dt = (-ffp + fss) / tffp + values[25] = dffp_dt + dhsp_dt = (-hsp + hssp) / thsp + values[26] = dhsp_dt + djp_dt = (-jp + jss) / tjp + values[27] = djp_dt + dmL_dt = (-mL + mLss) / tmL + values[28] = dmL_dt + dxs2_dt = (-xs2 + xs2ss) / txs2 + values[29] = dxs2_dt + dZetas_dt = As * dLambda - Zetas * cs + values[30] = dZetas_dt + fICaLp = 1.0 / (1.0 + KmCaMK / CaMKa) + fINaLp = 1.0 / (1.0 + KmCaMK / CaMKa) + fINap = 1.0 / (1.0 + KmCaMK / CaMKa) + fItop = 1.0 / (1.0 + KmCaMK / CaMKa) + fJrelp = 1.0 / (1.0 + KmCaMK / CaMKa) + fJupp = 1.0 / (1.0 + KmCaMK / CaMKa) + dnca_dt = anca * k2n - km2n * nca + values[31] = dnca_dt + F1 = numpy.exp(C * p_b) - 1 + dCd = C - Cd + dCaTrpn_dt = ktrpn * (-CaTrpn + ((1000 * cai) / cat50) ** ntrpn * (1 - CaTrpn)) + values[32] = dCaTrpn_dt + h_lambda_prima = Beta0 * ((lambda_min087 + lambda_min12) - 1.87) + 1 + x2 = b4 * (a2 * a3) + (b4 * (a3 * b1) + (a3 * (a1 * a2) + b4 * (b1 * b2))) + x1 = a2 * (a1 * b3) + (b3 * (a2 * b4) + (a2 * (a1 * a4) + b3 * (b2 * b4))) + x3 = b1 * (a3 * a4) + (a4 * (b1 * b2) + (a4 * (a2 * a3) + b1 * (b2 * b3))) + x4 = a1 * (b2 * b3) + (a1 * (a4 * b2) + (a1 * (a3 * a4) + b2 * (b3 * b4))) + PCaKp = 0.0003574 * PCap + PCaNap = 0.00125 * PCap + dXS_dt = -XS * gammasu + (-XS * ksu + XW * kws) + values[33] = dXS_dt + tau_relp = numpy.where((tau_relp_tmp < 0.001), 0.001, tau_relp_tmp) + k1 = kcaon * (cao * h12) + k1_i = kcaon * (cao * h12_i) + k6 = kcaon * (cass * h6) + k6_i = kcaon * (cai * h6_i) + h2 = (hna * nass) / ((h1 * kna3)) + h3 = 1.0 / h1 + h2_i = (hna * nai) / ((h1_i * kna3)) + h3_i = 1.0 / h1_i + h8 = nao / ((h7 * (hna * kna3))) + h9 = 1.0 / h7 + h8_i = nao / ((h7_i * (hna * kna3))) + h9_i = 1.0 / h7_i + diFp_dt = (-iFp + iss) / tiFp + values[34] = diFp_dt + diSp_dt = (-iSp + iss) / tiSp + values[35] = diSp_dt + IKr = (rkr * (xr * (GKr * (0.4303314829119352 * math.sqrt(ko))))) * (-EK + v) + ICaL = (d * (PhiCaL * (PCa * (1.0 - fICaLp)))) * ( + f * (1.0 - nca) + nca * (fca * jca) + ) + (d * (PhiCaL * (PCap * fICaLp))) * (fp * (1.0 - nca) + nca * (fcap * jca)) + INaL = (mL * (GNaL * (-ENa + v))) * (fINaLp * hLp + hL * (1.0 - fINaLp)) + INa = (m**3.0 * ((GNa * scale_drug_INa) * (-ENa + v))) * ( + j * (h * (1.0 - fINap)) + jp * (fINap * hp) + ) + Ito = ((scale_HF_Gto * (Gto * scale_drug_Ito)) * (-EK + v)) * ( + i * (a * (1.0 - fItop)) + ip * (ap * fItop) + ) + Jrel = Jrelnp * (1.0 - fJrelp) + Jrelp * fJrelp + Jup = -Jleak + (Jupnp * (1.0 - fJupp) + scale_HF_Jup * (Jupp * fJupp)) + eta = numpy.where((dCd < 0), etas, etal) + J_TRPN = dCaTrpn_dt * trpnmax + h_lambda = numpy.where((h_lambda_prima > 0), h_lambda_prima, 0) + E1 = x1 / (x4 + (x3 + (x1 + x2))) + E2 = x2 / (x4 + (x3 + (x1 + x2))) + E3 = x3 / (x4 + (x3 + (x1 + x2))) + E4 = x4 / (x4 + (x3 + (x1 + x2))) + ICaK = (d * (PhiCaK * (PCaK * (1.0 - fICaLp)))) * ( + f * (1.0 - nca) + nca * (fca * jca) + ) + (d * (PhiCaK * (PCaKp * fICaLp))) * (fp * (1.0 - nca) + nca * (fcap * jca)) + ICaNa = (d * (PhiCaNa * (PCaNa * (1.0 - fICaLp)))) * ( + f * (1.0 - nca) + nca * (fca * jca) + ) + (d * (PhiCaNa * (PCaNap * fICaLp))) * (fp * (1.0 - nca) + nca * (fcap * jca)) + k4pp = h2 * wnaca + k7 = wna * (h2 * h5) + k4p_ss = (h3 * wca) / hca + k4pp_i = h2_i * wnaca + k7_i = wna * (h2_i * h5_i) + k4p_i = (h3_i * wca) / hca + k3pp = h8 * wnaca + k8 = wna * (h11 * h8) + k3p_ss = h9 * wca + k3pp_i = h8_i * wnaca + k8_i = wna * (h11_i * h8_i) + k3p_i = h9_i * wca + Jrel_inf = ((-ICaL) * a_rel) / (((1.5 * scale_HF_Jrel_inf) / cajsr) ** 8.0 + 1.0) + Jrel_infp = ((-ICaL) * a_relp) / (((1.5 * scale_HF_Jrel_inf) / cajsr) ** 8.0 + 1.0) + dcajsr_dt = Bcajsr * (-Jrel + Jtr) + values[36] = dcajsr_dt + dcansr_dt = Jup - (Jtr * vjsr) / vnsr + values[37] = dcansr_dt + Fd = dCd * eta + dCd_dt = (p_k * (C - Cd)) / eta + values[38] = dCd_dt + Ta = (h_lambda * (Tref / rs)) * (XS * (Zetas + 1) + XW * Zetaw) + JnakNa = 3.0 * (E1 * a3 - E2 * b3) + JnakK = 2.0 * (-E3 * a1 + E4 * b1) + dkss_dt = -JdiffK + (Acap * (-ICaK)) / ((F * vss)) + values[39] = dkss_dt + k4 = k4p_ss + k4pp + k4_i = k4p_i + k4pp_i + k3 = k3p_ss + k3pp + k3_i = k3p_i + k3pp_i + dJrelnp_dt = (Jrel_inf - Jrelnp) / tau_rel + values[40] = dJrelnp_dt + dJrelp_dt = (Jrel_infp - Jrelp) / tau_relp + values[41] = dJrelp_dt + Tp = p_a * (F1 + Fd) + INaK = (Pnak * scale_HF_Pnak) * (JnakK * zk + JnakNa * zna) + x2_ss = (k1 * k7) * (k4 + k5) + (k4 * k6) * (k1 + k8) + x2_i = (k1_i * k7_i) * (k4_i + k5_i) + (k4_i * k6_i) * (k1_i + k8_i) + x1_ss = (k2 * k4) * (k6 + k7) + (k5 * k7) * (k2 + k3) + x3_ss = (k1 * k3) * (k6 + k7) + (k6 * k8) * (k2 + k3) + x4_ss = (k2 * k8) * (k4 + k5) + (k3 * k5) * (k1 + k8) + x1_i = (k2_i * k4_i) * (k6_i + k7_i) + (k5_i * k7_i) * (k2_i + k3_i) + x3_i = (k1_i * k3_i) * (k6_i + k7_i) + (k6_i * k8_i) * (k2_i + k3_i) + x4_i = (k2_i * k8_i) * (k4_i + k5_i) + (k3_i * k5_i) * (k1_i + k8_i) + Ttot = Ta + Tp + dki_dt = ( + Acap + * ( + -( + -2.0 * INaK + + ( + Istim + + (Isac_P_ns / 3 + (Isac_P_k + (IKb + (IK1 + (IKs + (IKr + Ito)))))) + ) + ) + ) + ) / ((F * vmyo)) + (JdiffK * vss) / vmyo + values[42] = dki_dt + E1_ss = x1_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) + E2_ss = x2_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) + E3_ss = x3_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) + E4_ss = x4_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) + E1_i = x1_i / (x4_i + (x3_i + (x1_i + x2_i))) + E2_i = x2_i / (x4_i + (x3_i + (x1_i + x2_i))) + E3_i = x3_i / (x4_i + (x3_i + (x1_i + x2_i))) + E4_i = x4_i / (x4_i + (x3_i + (x1_i + x2_i))) + JncxCa_ss = -E1_ss * k1 + E2_ss * k2 + JncxNa_ss = -E2_ss * k3pp + (E3_ss * k4pp + 3.0 * (-E1_ss * k8 + E4_ss * k7)) + JncxCa_i = -E1_i * k1_i + E2_i * k2_i + JncxNa_i = -E2_i * k3pp_i + (E3_i * k4pp_i + 3.0 * (-E1_i * k8_i + E4_i * k7_i)) + INaCa_ss = (allo_ss * ((0.2 * Gncx) * scale_HF_Gncx)) * ( + JncxCa_ss * zca + JncxNa_ss * zna + ) + INaCa_i = (allo_i * ((0.8 * Gncx) * scale_HF_Gncx)) * ( + JncxCa_i * zca + JncxNa_i * zna + ) + dcass_dt = Bcass * ( + -Jdiff + + ( + (Acap * (-(ICaL - 2.0 * INaCa_ss))) / (((2.0 * F) * vss)) + + (Jrel * vjsr) / vss + ) + ) + values[43] = dcass_dt + dnass_dt = -JdiffNa + (Acap * (-(ICaNa + 3.0 * INaCa_ss))) / ((F * vss)) + values[44] = dnass_dt + dcai_dt = Bcai * ( + -J_TRPN + + ( + ( + (Acap * (-(Isac_P_ns / 3 + (-2.0 * INaCa_i + (ICab + IpCa))))) + / (((2.0 * F) * vmyo)) + - (Jup * vnsr) / vmyo + ) + + (Jdiff * vss) / vmyo + ) + ) + values[45] = dcai_dt + dnai_dt = ( + Acap + * (-(Isac_P_ns / 3 + (INab + (3.0 * INaK + (3.0 * INaCa_i + (INa + INaL)))))) + ) / ((F * vmyo)) + (JdiffNa * vss) / vmyo + values[46] = dnai_dt + dv_dt = -( + Isac_P_k + + ( + Isac_P_ns + + ( + Istim + + ( + ICab + + ( + IpCa + + ( + IKb + + ( + INab + + ( + INaK + + ( + INaCa_ss + + ( + INaCa_i + + ( + IK1 + + ( + IKs + + ( + IKr + + ( + ICaK + + ( + ICaNa + + ( + ICaL + + ( + Ito + + (INa + INaL) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + values[47] = dv_dt + + return values + + def forward_generalized_rush_larsen(coupling: EMCoupling): def forward_generalized_rush_larsen_(states, t, dt, parameters): lmbda = coupling.lmbda_ep.vector().get_local() @@ -550,32 +1299,32 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): xs1 = states[11] CaMKt = states[12] xk1 = states[13] - Zetaw = states[14] - XS = states[15] - XW = states[16] - TmB = states[17] - hLp = states[18] - iF = states[19] - iS = states[20] - fcaf = states[21] - fcas = states[22] - jca = states[23] - j = states[24] - fcafp = states[25] - ffp = states[26] - hsp = states[27] - jp = states[28] - mL = states[29] - xs2 = states[30] - Zetas = states[31] - nca = states[32] - CaTrpn = states[33] + # Zetaw = states[14] + XW = states[15] + TmB = states[16] + hLp = states[17] + iF = states[18] + iS = states[19] + fcaf = states[20] + fcas = states[21] + jca = states[22] + j = states[23] + fcafp = states[24] + ffp = states[25] + hsp = states[26] + jp = states[27] + mL = states[28] + xs2 = states[29] + # Zetas = states[30] + nca = states[31] + CaTrpn = states[32] + XS = states[33] iFp = states[34] iSp = states[35] cajsr = states[36] cansr = states[37] - kss = states[38] - Cd = states[39] + Cd = states[38] + kss = states[39] Jrelnp = states[40] Jrelp = states[41] ki = states[42] @@ -593,11 +1342,14 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): Beta0 = parameters[4] Beta1 = parameters[5] CaMKo = parameters[6] + Esac_ns = parameters[7] F = parameters[8] GKb = parameters[9] GNa = parameters[10] Gncx = parameters[11] GpCa = parameters[12] + Gsac_k = parameters[13] + Gsac_ns = parameters[14] Gto = parameters[15] H = parameters[16] Khp = parameters[17] @@ -630,19 +1382,23 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): amp = parameters[44] bCaMK = parameters[45] bt = parameters[46] + calib = parameters[47] cao = parameters[48] cat50_ref = parameters[49] + celltype = parameters[50] cmdnmax = parameters[51] csqnmax = parameters[52] - # dLambda = parameters[53] + dLambda = parameters[53] delta = parameters[54] delta_epi = parameters[55] duration = parameters[56] eP = parameters[57] + emcoupling = parameters[58] etal = parameters[59] etas = parameters[60] gammas = parameters[61] gammaw = parameters[62] + isacs = parameters[63] k1m = parameters[64] k1p = parameters[65] k2m = parameters[66] @@ -657,6 +1413,7 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): kcaon = parameters[75] kmcmdn = parameters[76] kmcsqn = parameters[77] + kmtrpn = parameters[78] kna1 = parameters[79] kna2 = parameters[80] kna3 = parameters[81] @@ -665,7 +1422,9 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): ku = parameters[84] kuw = parameters[85] kws = parameters[86] + lambda_max = parameters[87] # lmbda = parameters[88] + mode = parameters[89] nao = parameters[90] ntm = parameters[91] ntrpn = parameters[92] @@ -704,6 +1463,8 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): scale_drug_INaL = parameters[125] scale_drug_INab = parameters[126] scale_drug_IpCa = parameters[127] + scale_drug_Isack = parameters[128] + scale_drug_Isacns = parameters[129] scale_drug_Ito = parameters[130] thL = parameters[131] tjca = parameters[132] @@ -717,8 +1478,6 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): # Assign expressions values = numpy.zeros_like(states) zna = 1.0 - Isac_P_k = 0 - Isac_P_ns = 0 Afcaf = 0.3 + 0.6 / (numpy.exp((v - 10.0) / 10.0) + 1.0) AiF = 1.0 / (numpy.exp((v - 213.6) / 151.2) + 1.0) Axrf = 1.0 / (numpy.exp((v + 54.81) / 38.21) + 1.0) @@ -802,10 +1561,10 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): vcell = L * (rad * ((3.14 * 1000) * rad)) Ahs = 1.0 - Ahf Aw = (Tot_A * rs) / (rs + rw * (1 - rs)) + Bcai = 1.0 / ((cmdnmax * kmcmdn) / (cai + kmcmdn) ** 2.0 + 1.0) Jupnp = (0.004375 * cai) / (cai + 0.00092) Jupp = ((0.004375 * 2.75) * cai) / ((cai + 0.00092) - 0.00017) KsCa = 1.0 + 0.6 / ((3.8e-05 / cai) ** 1.4 + 1.0) - Bcai = 1.0 / ((cmdnmax * kmcmdn) / (cai + kmcmdn) ** 2.0 + 1.0) Bcajsr = 1.0 / ((csqnmax * kmcsqn) / (cajsr + kmcsqn) ** 2.0 + 1.0) Bcass = 1.0 / ( (BSLmax * KmBSL) / (KmBSL + cass) ** 2.0 @@ -813,13 +1572,14 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): ) Jdiff = (-cai + cass) / 0.2 CaMKb = (CaMKo * (1.0 - CaMKt)) / (KmCaM / cass + 1.0) + CaTrpn_max = numpy.where((CaTrpn > 0), CaTrpn, 0) rk1 = 1.0 / (numpy.exp((-2.6 * ko + (v + 105.8)) / 9.493) + 1.0) xk1ss = 1.0 / ( numpy.exp((-((2.5538 * ko + v) + 144.59)) / (1.5692 * ko + 3.8115)) + 1.0 ) - EK = ((R * T) / F) * numpy.log(ko / ki) vffrt = (F * (F * v)) / ((R * T)) vfrt = (F * v) / ((R * T)) + EK = ((R * T) / F) * numpy.log(ko / ki) EKs = ((R * T) / F) * numpy.log((PKNa * nao + ko) / (PKNa * nai + ki)) ENa = ((R * T) / F) * numpy.log(nao / nai) GK1 = scale_HF_GK1 * ((0.1908 * scale_IK1) * scale_drug_IK1) @@ -828,15 +1588,31 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): GNaL = scale_HF_GNaL * ((0.0075 * scale_INaL) * scale_drug_INaL) km2n = 1.0 * jca IpCa = (cai * (GpCa * scale_drug_IpCa)) / (cai + 0.0005) - Istim = 0 # (amp) * (duration >= t) + (0) * numpy.logical_not((duration >= t)) + lambda_min12 = numpy.where((lmbda < 1.2), lmbda, 1.2) + Isac_P_k = numpy.where( + (lmbda < 1.0), + 0.0, + (Gsac_k * ((lmbda - 1.0) / (lambda_max - 1.0))) + * (1.0 / (numpy.exp((19.05 - v) / 29.98) + 1.0)), + ) + Isac_P_ns = numpy.where( + (lmbda < 1.0), + 0.0, + (Gsac_ns * ((lmbda - 1.0) / (lambda_max - 1.0))) * (-Esac_ns + v), + ) + Istim = numpy.where((duration >= t), amp, 0) JdiffK = (-ki + kss) / 2.0 JdiffNa = (-nai + nass) / 2.0 - Jleak = ((0.0039375 * cansr) * scale_HF_Jleak) / 15.0 Jtr = (-cajsr + cansr) / 100.0 + Jleak = ((0.0039375 * cansr) * scale_HF_Jleak) / 15.0 Knai = Knai0 * numpy.exp((F * (delta * v)) / (((3.0 * R) * T))) Knao = Knao0 * numpy.exp((F * (v * (1.0 - delta))) / (((3.0 * R) * T))) P = eP / (((H / Khp + 1.0) + nai / Knap) + ki / Kxkur) PCa = (0.0001 * scale_ICaL) * scale_drug_ICaL + XS_max = numpy.where((XS > 0), XS, 0) + zetas1 = Zetas * numpy.where((Zetas > 0), 1.0, 0.0) + zetas2 = (-Zetas - 1.0) * numpy.where((Zetas < -1.0), 1.0, 0.0) + XW_max = numpy.where((XW > 0), XW, 0) XU = -XW + (-XS + (1 - TmB)) a2 = k2p a4 = ((MgATP * k4p) / Kmgatp) / (1.0 + MgATP / Kmgatp) @@ -846,20 +1622,15 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): allo_i = 1.0 / ((KmCaAct / cai) ** 2.0 + 1.0) allo_ss = 1.0 / ((KmCaAct / cass) ** 2.0 + 1.0) b1 = MgADP * k1m - ksu = (kws * rw) * (-1 + 1 / rs) cs = ((kws * phi) * (rw * (1 - rs))) / rs + ksu = (kws * rw) * (-1 + 1 / rs) cw = ((kuw * phi) * ((1 - rs) * (1 - rw))) / ((rw * (1 - rs))) kwu = kuw * (-1 + 1 / rw) - kws - gammasu = gammas * numpy.where( - Zetas * (Zetas > 0) > (-1 - Zetas) * (Zetas < -1), - Zetas * (Zetas > 0), - (-1 - Zetas) * (Zetas < -1), - ) gammawu = gammaw * numpy.abs(Zetaw) - h4 = (nass / kna1) * (1 + nass / kna2) + 1.0 - h4_i = (nai / kna1) * (1 + nai / kna2) + 1.0 h10 = (nao / kna1) * (1 + nao / kna2) + (kasymm + 1.0) h10_i = (nao / kna1) * (1.0 + nao / kna2) + (kasymm + 1.0) + h4 = (nass / kna1) * (1 + nass / kna2) + 1.0 + h4_i = (nai / kna1) * (1 + nai / kna2) + 1.0 hca = numpy.exp((F * (qca * v)) / ((R * T))) hna = numpy.exp((F * (qna * v)) / ((R * T))) k2 = kcaoff @@ -867,9 +1638,6 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): k5 = kcaoff k5_i = kcaoff kb = (Trpn50**ntm * ku) / (-rw * (1 - rs) + (1 - rs)) - lambda_min12 = (lmbda) * (lmbda < 1.2) + (1.2) * numpy.logical_not( - (lmbda < 1.2), - ) thLp = scale_HF_thL * (3.0 * thL) tiF = ( delta_epi @@ -980,13 +1748,15 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): CaMKa = scale_HF_CaMKa * (CaMKb + CaMKt) dCaMKt_dt = -CaMKt * bCaMK + (CaMKb * aCaMK) * (CaMKb + CaMKt) dCaMKt_dt_linearized = CaMKb * aCaMK - bCaMK - values[12] = ( - CaMKt - + dCaMKt_dt + values[12] = CaMKt + numpy.where( + numpy.logical_or( + (dCaMKt_dt_linearized > 1e-08), + (dCaMKt_dt_linearized < -1e-08), + ), + dCaMKt_dt * (numpy.exp(dCaMKt_dt_linearized * dt) - 1) - / dCaMKt_dt_linearized - * (numpy.abs(dCaMKt_dt_linearized) > 1e-08) - + dCaMKt_dt * dt * (~(numpy.abs(dCaMKt_dt_linearized) > 1e-08)) + / dCaMKt_dt_linearized, + dCaMKt_dt * dt, ) dxk1_dt = (-xk1 + xk1ss) / txk1 dxk1_dt_linearized = -1 / txk1 @@ -994,7 +1764,6 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): dxk1_dt * (numpy.exp(dt * dxk1_dt_linearized) - 1) / dxk1_dt_linearized + xk1 ) - IKb = (xkb * (GKb * scale_drug_IKb)) * (-EK + v) ICab = ( (vffrt * (4.0 * (PCab * scale_drug_ICab))) * (cai * numpy.exp(2.0 * vfrt) - 0.341 * cao) @@ -1011,9 +1780,13 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): PhiCaNa = ( (1.0 * vffrt) * (-0.75 * nao + (0.75 * nass) * numpy.exp(1.0 * vfrt)) ) / (numpy.exp(1.0 * vfrt) - 1.0) + IKb = (xkb * (GKb * scale_drug_IKb)) * (-EK + v) IK1 = (xk1 * (rk1 * (GK1 * math.sqrt(ko)))) * (-EK + v) IKs = (xs2 * (xs1 * (GKs * KsCa))) * (-EKs + v) anca = 1.0 / (k2n / km2n + (Kmn / cass + 1.0) ** 4.0) + C = lambda_min12 - 1 + cat50 = scale_HF_cat50_ref * (Beta1 * (lambda_min12 - 1) + cat50_ref) + lambda_min087 = numpy.where((lambda_min12 < 0.87), lambda_min12, 0.87) a1 = (k1p * (nai / Knai) ** 3.0) / ( ((1.0 + ki / Kki) ** 2.0 + (1.0 + nai / Knai) ** 3.0) - 1.0 ) @@ -1030,49 +1803,36 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): PCaK = 0.0003574 * PCa PCaNa = 0.00125 * PCa PCap = 1.1 * PCa + gammasu = gammas * numpy.where((zetas1 > zetas2), zetas1, zetas2) a_relp = 0.5 * btp tau_relp_tmp = btp / (1.0 + 0.0123 / cajsr) - tau_rel = (0.001) * (tau_rel_tmp < 0.001) + (tau_rel_tmp) * numpy.logical_not( - (tau_rel_tmp < 0.001), - ) + tau_rel = numpy.where((tau_rel_tmp < 0.001), 0.001, tau_rel_tmp) # dZetaw_dt = Aw * dLambda - Zetaw * cw # dZetaw_dt_linearized = -cw - # values[14] = ( - # Zetaw - # + dZetaw_dt + # values[14] = Zetaw + numpy.where( + # numpy.logical_or( + # (dZetaw_dt_linearized > 1e-08), (dZetaw_dt_linearized < -1e-08) + # ), + # dZetaw_dt # * (numpy.exp(dZetaw_dt_linearized * dt) - 1) - # / dZetaw_dt_linearized - # * (numpy.abs(dZetaw_dt_linearized) > 1e-08) - # + dZetaw_dt * dt * (~(numpy.abs(dZetaw_dt_linearized) > 1e-08)) + # / dZetaw_dt_linearized, + # dZetaw_dt * dt, # ) - dXS_dt = -XS * gammasu + (-XS * ksu + XW * kws) - dXS_dt_linearized = -gammasu - ksu - values[15] = ( - XS - + dXS_dt - * (numpy.exp(dXS_dt_linearized * dt) - 1) - / dXS_dt_linearized - * (numpy.abs(dXS_dt_linearized) > 1e-08) - + dXS_dt * dt * (~(numpy.abs(dXS_dt_linearized) > 1e-08)) - ) dXW_dt = -XW * gammawu + (-XW * kws + (XU * kuw - XW * kwu)) dXW_dt_linearized = -gammawu - kws - kwu - values[16] = ( - XW - + dXW_dt - * (numpy.exp(dXW_dt_linearized * dt) - 1) - / dXW_dt_linearized - * (numpy.abs(dXW_dt_linearized) > 1e-08) - + dXW_dt * dt * (~(numpy.abs(dXW_dt_linearized) > 1e-08)) + values[15] = XW + numpy.where( + numpy.logical_or((dXW_dt_linearized > 1e-08), (dXW_dt_linearized < -1e-08)), + dXW_dt * (numpy.exp(dXW_dt_linearized * dt) - 1) / dXW_dt_linearized, + dXW_dt * dt, ) - h5 = (nass * nass) / ((kna2 * (h4 * kna1))) - h6 = 1.0 / h4 - h5_i = (nai * nai) / ((kna2 * (h4_i * kna1))) - h6_i = 1.0 / h4_i h11 = (nao * nao) / ((kna2 * (h10 * kna1))) h12 = 1.0 / h10 h11_i = (nao * nao) / ((kna2 * (h10_i * kna1))) h12_i = 1.0 / h10_i + h5 = (nass * nass) / ((kna2 * (h4 * kna1))) + h6 = 1.0 / h4 + h5_i = (nai * nai) / ((kna2 * (h4_i * kna1))) + h6_i = 1.0 / h4_i h1 = (nass / kna3) * (hna + 1) + 1 h1_i = (nai / kna3) * (hna + 1) + 1 h7 = (nao / kna3) * (1.0 + 1.0 / hna) + 1.0 @@ -1085,40 +1845,31 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): 100, ) ) - dTmB_dt_linearized = numpy.where( - numpy.isclose(CaTrpn, 0), - 0, - -(CaTrpn ** (ntm / 2)) * ku, - ) - values[17] = ( - TmB - + dTmB_dt - * (numpy.exp(dTmB_dt_linearized * dt) - 1) - / dTmB_dt_linearized - * (numpy.abs(dTmB_dt_linearized) > 1e-08) - + dTmB_dt * dt * (~(numpy.abs(dTmB_dt_linearized) > 1e-08)) + dTmB_dt_linearized = -(CaTrpn ** (ntm / 2)) * ku + values[16] = TmB + numpy.where( + numpy.logical_or( + (dTmB_dt_linearized > 1e-08), + (dTmB_dt_linearized < -1e-08), + ), + dTmB_dt * (numpy.exp(dTmB_dt_linearized * dt) - 1) / dTmB_dt_linearized, + dTmB_dt * dt, ) - C = lambda_min12 - 1 - cat50 = scale_HF_cat50_ref * (Beta1 * (lambda_min12 - 1) + cat50_ref) - lambda_min087 = (lambda_min12) * (lambda_min12 < 0.87) + ( - 0.87 - ) * numpy.logical_not((lambda_min12 < 0.87)) dhLp_dt = (-hLp + hLssp) / thLp dhLp_dt_linearized = -1 / thLp - values[18] = ( + values[17] = ( dhLp_dt * (numpy.exp(dhLp_dt_linearized * dt) - 1) / dhLp_dt_linearized + hLp ) tiFp = tiF * (dti_develop * dti_recover) diF_dt = (-iF + iss) / tiF diF_dt_linearized = -1 / tiF - values[19] = ( + values[18] = ( diF_dt * (numpy.exp(diF_dt_linearized * dt) - 1) / diF_dt_linearized + iF ) tiSp = tiS * (dti_develop * dti_recover) diS_dt = (-iS + iss) / tiS diS_dt_linearized = -1 / tiS - values[20] = ( + values[19] = ( diS_dt * (numpy.exp(diS_dt_linearized * dt) - 1) / diS_dt_linearized + iS ) fca = Afcaf * fcaf + Afcas * fcas @@ -1128,30 +1879,30 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): xr = Axrf * xrf + Axrs * xrs dfcaf_dt = (-fcaf + fcass) / tfcaf dfcaf_dt_linearized = -1 / tfcaf - values[21] = ( + values[20] = ( dfcaf_dt * (numpy.exp(dfcaf_dt_linearized * dt) - 1) / dfcaf_dt_linearized + fcaf ) dfcas_dt = (-fcas + fcass) / tfcas dfcas_dt_linearized = -1 / tfcas - values[22] = ( + values[21] = ( dfcas_dt * (numpy.exp(dfcas_dt_linearized * dt) - 1) / dfcas_dt_linearized + fcas ) djca_dt = (fcass - jca) / tjca djca_dt_linearized = -1 / tjca - values[23] = ( + values[22] = ( djca_dt * (numpy.exp(djca_dt_linearized * dt) - 1) / djca_dt_linearized + jca ) dj_dt = (-j + jss) / tj dj_dt_linearized = -1 / tj - values[24] = ( + values[23] = ( dj_dt * (numpy.exp(dj_dt_linearized * dt) - 1) / dj_dt_linearized + j ) dfcafp_dt = (-fcafp + fcass) / tfcafp dfcafp_dt_linearized = -1 / tfcafp - values[25] = ( + values[24] = ( dfcafp_dt * (numpy.exp(dfcafp_dt_linearized * dt) - 1) / dfcafp_dt_linearized @@ -1159,41 +1910,42 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): ) dffp_dt = (-ffp + fss) / tffp dffp_dt_linearized = -1 / tffp - values[26] = ( + values[25] = ( dffp_dt * (numpy.exp(dffp_dt_linearized * dt) - 1) / dffp_dt_linearized + ffp ) dhsp_dt = (-hsp + hssp) / thsp dhsp_dt_linearized = -1 / thsp - values[27] = ( + values[26] = ( dhsp_dt * (numpy.exp(dhsp_dt_linearized * dt) - 1) / dhsp_dt_linearized + hsp ) djp_dt = (-jp + jss) / tjp djp_dt_linearized = -1 / tjp - values[28] = ( + values[27] = ( djp_dt * (numpy.exp(djp_dt_linearized * dt) - 1) / djp_dt_linearized + jp ) dmL_dt = (-mL + mLss) / tmL dmL_dt_linearized = -1 / tmL - values[29] = ( + values[28] = ( dmL_dt * (numpy.exp(dmL_dt_linearized * dt) - 1) / dmL_dt_linearized + mL ) dxs2_dt = (-xs2 + xs2ss) / txs2 dxs2_dt_linearized = -1 / txs2 - values[30] = ( + values[29] = ( dxs2_dt * (numpy.exp(dt * dxs2_dt_linearized) - 1) / dxs2_dt_linearized + xs2 ) # dZetas_dt = As * dLambda - Zetas * cs # dZetas_dt_linearized = -cs - # values[31] = ( - # Zetas - # + dZetas_dt + # values[30] = Zetas + numpy.where( + # numpy.logical_or( + # (dZetas_dt_linearized > 1e-08), (dZetas_dt_linearized < -1e-08) + # ), + # dZetas_dt # * (numpy.exp(dZetas_dt_linearized * dt) - 1) - # / dZetas_dt_linearized - # * (numpy.abs(dZetas_dt_linearized) > 1e-08) - # + dZetas_dt * dt * (~(numpy.abs(dZetas_dt_linearized) > 1e-08)) + # / dZetas_dt_linearized, + # dZetas_dt * dt, # ) fICaLp = 1.0 / (1.0 + KmCaMK / CaMKa) fINaLp = 1.0 / (1.0 + KmCaMK / CaMKa) @@ -1203,27 +1955,47 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): fJupp = 1.0 / (1.0 + KmCaMK / CaMKa) dnca_dt = anca * k2n - km2n * nca dnca_dt_linearized = -km2n - values[32] = ( - nca - + dnca_dt - * (numpy.exp(dnca_dt_linearized * dt) - 1) - / dnca_dt_linearized - * (numpy.abs(dnca_dt_linearized) > 1e-08) - + dnca_dt * dt * (~(numpy.abs(dnca_dt_linearized) > 1e-08)) + values[31] = nca + numpy.where( + numpy.logical_or( + (dnca_dt_linearized > 1e-08), + (dnca_dt_linearized < -1e-08), + ), + dnca_dt * (numpy.exp(dnca_dt_linearized * dt) - 1) / dnca_dt_linearized, + dnca_dt * dt, + ) + F1 = numpy.exp(C * p_b) - 1 + dCd = C - Cd + dCaTrpn_dt = ktrpn * (-CaTrpn + ((1000 * cai) / cat50) ** ntrpn * (1 - CaTrpn)) + dCaTrpn_dt_linearized = ktrpn * (-(((1000 * cai) / cat50) ** ntrpn) - 1) + values[32] = CaTrpn + numpy.where( + numpy.logical_or( + (dCaTrpn_dt_linearized > 1e-08), + (dCaTrpn_dt_linearized < -1e-08), + ), + dCaTrpn_dt + * (numpy.exp(dCaTrpn_dt_linearized * dt) - 1) + / dCaTrpn_dt_linearized, + dCaTrpn_dt * dt, ) + h_lambda_prima = Beta0 * ((lambda_min087 + lambda_min12) - 1.87) + 1 x2 = b4 * (a2 * a3) + (b4 * (a3 * b1) + (a3 * (a1 * a2) + b4 * (b1 * b2))) x1 = a2 * (a1 * b3) + (b3 * (a2 * b4) + (a2 * (a1 * a4) + b3 * (b2 * b4))) x3 = b1 * (a3 * a4) + (a4 * (b1 * b2) + (a4 * (a2 * a3) + b1 * (b2 * b3))) x4 = a1 * (b2 * b3) + (a1 * (a4 * b2) + (a1 * (a3 * a4) + b2 * (b3 * b4))) PCaKp = 0.0003574 * PCap PCaNap = 0.00125 * PCap - tau_relp = (0.001) * (tau_relp_tmp < 0.001) + ( - tau_relp_tmp - ) * numpy.logical_not((tau_relp_tmp < 0.001)) - k6 = kcaon * (cass * h6) - k6_i = kcaon * (cai * h6_i) + dXS_dt = -XS * gammasu + (-XS * ksu + XW * kws) + dXS_dt_linearized = -gammasu - ksu + values[33] = XS + numpy.where( + numpy.logical_or((dXS_dt_linearized > 1e-08), (dXS_dt_linearized < -1e-08)), + dXS_dt * (numpy.exp(dXS_dt_linearized * dt) - 1) / dXS_dt_linearized, + dXS_dt * dt, + ) + tau_relp = numpy.where((tau_relp_tmp < 0.001), 0.001, tau_relp_tmp) k1 = kcaon * (cao * h12) k1_i = kcaon * (cao * h12_i) + k6 = kcaon * (cass * h6) + k6_i = kcaon * (cai * h6_i) h2 = (hna * nass) / ((h1 * kna3)) h3 = 1.0 / h1 h2_i = (hna * nai) / ((h1_i * kna3)) @@ -1232,20 +2004,6 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): h9 = 1.0 / h7 h8_i = nao / ((h7_i * (hna * kna3))) h9_i = 1.0 / h7_i - # F1 = numpy.exp(C * p_b) - 1 - dCd = C - Cd - - dCaTrpn_dt = ktrpn * (-CaTrpn + ((1000 * cai) / cat50) ** ntrpn * (1 - CaTrpn)) - dCaTrpn_dt_linearized = ktrpn * (-(((1000 * cai) / cat50) ** ntrpn) - 1) - values[33] = ( - CaTrpn - + dCaTrpn_dt - * (numpy.exp(dCaTrpn_dt_linearized * dt) - 1) - / dCaTrpn_dt_linearized - * (numpy.abs(dCaTrpn_dt_linearized) > 1e-08) - + dCaTrpn_dt * dt * (~(numpy.abs(dCaTrpn_dt_linearized) > 1e-08)) - ) - # h_lambda_prima = Beta0 * ((lambda_min087 + lambda_min12) - 1.87) + 1 diFp_dt = (-iFp + iss) / tiFp diFp_dt_linearized = -1 / tiFp values[34] = ( @@ -1271,6 +2029,9 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): ) Jrel = Jrelnp * (1.0 - fJrelp) + Jrelp * fJrelp Jup = -Jleak + (Jupnp * (1.0 - fJupp) + scale_HF_Jup * (Jupp * fJupp)) + eta = numpy.where((dCd < 0), etas, etal) + J_TRPN = dCaTrpn_dt * trpnmax + h_lambda = numpy.where((h_lambda_prima > 0), h_lambda_prima, 0) E1 = x1 / (x4 + (x3 + (x1 + x2))) E2 = x2 / (x4 + (x3 + (x1 + x2))) E3 = x3 / (x4 + (x3 + (x1 + x2))) @@ -1295,11 +2056,6 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): k3pp_i = h8_i * wnaca k8_i = wna * (h11_i * h8_i) k3p_i = h9_i * wca - eta = (etas) * (dCd < 0) + (etal) * numpy.logical_not((dCd < 0)) - J_TRPN = dCaTrpn_dt * trpnmax - # h_lambda = (h_lambda_prima) * (h_lambda_prima > 0) + (0) * numpy.logical_not( - # (h_lambda_prima > 0), - # ) Jrel_inf = ((-ICaL) * a_rel) / ( ((1.5 * scale_HF_Jrel_inf) / cajsr) ** 8.0 + 1.0 ) @@ -1310,26 +2066,23 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): values[36] = cajsr + dcajsr_dt * dt dcansr_dt = Jup - (Jtr * vjsr) / vnsr values[37] = cansr + dcansr_dt * dt + Fd = dCd * eta + dCd_dt = (p_k * (C - Cd)) / eta + dCd_dt_linearized = -p_k / eta + values[38] = Cd + numpy.where( + numpy.logical_or((dCd_dt_linearized > 1e-08), (dCd_dt_linearized < -1e-08)), + dCd_dt * (numpy.exp(dCd_dt_linearized * dt) - 1) / dCd_dt_linearized, + dCd_dt * dt, + ) + Ta = (h_lambda * (Tref / rs)) * (XS * (Zetas + 1) + XW * Zetaw) JnakNa = 3.0 * (E1 * a3 - E2 * b3) JnakK = 2.0 * (-E3 * a1 + E4 * b1) dkss_dt = -JdiffK + (Acap * (-ICaK)) / ((F * vss)) - values[38] = dkss_dt * dt + kss + values[39] = dkss_dt * dt + kss k4 = k4p_ss + k4pp k4_i = k4p_i + k4pp_i k3 = k3p_ss + k3pp k3_i = k3p_i + k3pp_i - # Fd = dCd * eta - dCd_dt = (p_k * (C - Cd)) / eta - dCd_dt_linearized = -p_k / eta - values[39] = ( - Cd - + dCd_dt - * (numpy.exp(dCd_dt_linearized * dt) - 1) - / dCd_dt_linearized - * (numpy.abs(dCd_dt_linearized) > 1e-08) - + dCd_dt * dt * (~(numpy.abs(dCd_dt_linearized) > 1e-08)) - ) - # Ta = (h_lambda * (Tref / rs)) * (XS * (Zetas + 1) + XW * Zetaw) dJrelnp_dt = (Jrel_inf - Jrelnp) / tau_rel dJrelnp_dt_linearized = -1 / tau_rel values[40] = ( @@ -1346,6 +2099,7 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): * (numpy.exp(dJrelp_dt_linearized * dt) - 1) / dJrelp_dt_linearized ) + Tp = p_a * (F1 + Fd) INaK = (Pnak * scale_HF_Pnak) * (JnakK * zk + JnakNa * zna) x2_ss = (k1 * k7) * (k4 + k5) + (k4 * k6) * (k1 + k8) x2_i = (k1_i * k7_i) * (k4_i + k5_i) + (k4_i * k6_i) * (k1_i + k8_i) @@ -1355,7 +2109,7 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): x1_i = (k2_i * k4_i) * (k6_i + k7_i) + (k5_i * k7_i) * (k2_i + k3_i) x3_i = (k1_i * k3_i) * (k6_i + k7_i) + (k6_i * k8_i) * (k2_i + k3_i) x4_i = (k2_i * k8_i) * (k4_i + k5_i) + (k3_i * k5_i) * (k1_i + k8_i) - # Tp = p_a * (F1 + Fd) + Ttot = Ta + Tp dki_dt = ( Acap * ( @@ -1479,7 +2233,7 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): ) values[47] = dt * dv_dt + v - return numpy.nan_to_num(values, nan=0.0) + return values return forward_generalized_rush_larsen_ diff --git a/src/simcardems/postprocess.py b/src/simcardems/postprocess.py index 1baa5ec7..69d1a0a7 100644 --- a/src/simcardems/postprocess.py +++ b/src/simcardems/postprocess.py @@ -119,7 +119,7 @@ def plot_state_traces( fig, axs = plt.subplots(2, 2, figsize=(10, 8), sharex=True) for i, (group, key) in enumerate( - (("ep", "lambda"), ("mechanics", "Ta"), ("ep", "V"), ("ep", "Ca")), + (("ep", "lambda"), ("mechanics", "Ta"), ("ep", "v"), ("ep", "cai")), ): ax = axs.flatten()[i] try: diff --git a/src/simcardems/runner.py b/src/simcardems/runner.py index e4524c1e..aa006d5b 100644 --- a/src/simcardems/runner.py +++ b/src/simcardems/runner.py @@ -142,12 +142,12 @@ def _solve_mechanics_now(self) -> bool: if self._config.mechanics_solve_strategy == "fixed": return self.coupling.dt_mechanics > self._config.dt_mech - self.coupling.assigners.assign_pre() - norm = self.coupling.assigners.compute_pre_norm() - return ( - norm >= self._config.mech_threshold - or self.coupling.dt_mechanics > self._config.dt_mech - ) + # self.coupling.assigners.assign_pre() + # norm = self.coupling.assigners.compute_pre_norm() + # return ( + # norm >= self._config.mech_threshold + # or self.coupling.dt_mechanics > self._config.dt_mech + # ) return True def _post_mechanics_solve(self) -> None: From 3f5228363ec0996cd11e7ed9052ba33856207e6b Mon Sep 17 00:00:00 2001 From: Henrik Finsberg Date: Sun, 21 Jan 2024 14:41:15 +0100 Subject: [PATCH 5/7] Start working on endocardial stimulation example --- demos/endocardial_stimulation.py | 380 +++ demos/simple_demo.py | 1 - demos/ventricular_geometry.py | 5 +- .../models/explicit_ORdmm_Land/cell_model.py | 2797 ++++++----------- .../models/explicit_ORdmm_Land/em_model.py | 2 +- .../fully_coupled_ORdmm_Land/active_model.py | 3 + .../fully_coupled_ORdmm_Land/cell_model.py | 1663 +--------- .../fully_coupled_ORdmm_Land/em_model.py | 9 +- .../models/pureEP_ORdmm_Land/em_model.py | 2 +- src/simcardems/runner.py | 1 + 10 files changed, 1350 insertions(+), 3513 deletions(-) create mode 100644 demos/endocardial_stimulation.py diff --git a/demos/endocardial_stimulation.py b/demos/endocardial_stimulation.py new file mode 100644 index 00000000..4e04de96 --- /dev/null +++ b/demos/endocardial_stimulation.py @@ -0,0 +1,380 @@ +# # Endocardial stimulation (multiple cell models) +# In this demo we stimulate a Bi-ventricular geometry at the endocardium and compute a pseudo-ecg +# +# ```{figure} ../docs/_static/torso_electrodes.png +# --- +# name: torso_electrodes +# --- + +# Displacement ($u$), active tension ($T_a$), voltage ($V$) and calcium ($Ca$) +# visualized for a specific time point in Paraview. +# ``` +# +from collections import defaultdict +from pathlib import Path +import cardiac_geometries +import numpy as np +import matplotlib.pyplot as plt + +import dolfin +import pulse +import ldrb +import ufl_legacy as ufl +import simcardems + +try: + from tqdm import tqdm +except ImportError: + tqdm = lambda x: x + +import beat + +# import beat.cellmodels.tentusscher_panfilov_2006 as model + +# import beat.cellmodels.torord_dyn_chloride as model + +# model_name = model.__name__.split(".")[-1] + + +def get_data(datadir="data_endocardial_stimulation"): + datadir = Path(datadir) + msh_file = datadir / "biv_ellipsoid.msh" + if not msh_file.is_file(): + cardiac_geometries.create_biv_ellipsoid( + datadir, + char_length=0.5, # Reduce this value to get a finer mesh + center_lv_y=0.2, + center_lv_z=0.0, + a_endo_lv=5.0, + b_endo_lv=2.2, + c_endo_lv=2.2, + a_epi_lv=6.0, + b_epi_lv=3.0, + c_epi_lv=3.0, + center_rv_y=1.0, + center_rv_z=0.0, + a_endo_rv=6.0, + b_endo_rv=2.5, + c_endo_rv=2.7, + a_epi_rv=8.0, + b_epi_rv=5.5, + c_epi_rv=4.0, + create_fibers=True, + ) + + return cardiac_geometries.geometry.Geometry.from_folder(datadir) + + +def define_stimulus(mesh, chi, C_m, time, ffun, markers): + duration = 2.0 # ms + A = 5 # mu A/cm^3 + + factor = 1.0 / (chi * C_m) # NB: cbcbeat convention + amplitude = factor * A # mV/ms + + I_s = dolfin.Expression( + "time >= start ? (time <= (duration + start) ? amplitude : 0.0) : 0.0", + time=time, + start=0.0, + duration=duration, + amplitude=amplitude, + degree=0, + ) + + subdomain_data = dolfin.MeshFunction("size_t", mesh, 2) + subdomain_data.set_all(0) + marker = 1 + subdomain_data.array()[ffun.array() == markers["ENDO_LV"][0]] = 1 + subdomain_data.array()[ffun.array() == markers["ENDO_RV"][0]] = 1 + + ds = dolfin.Measure("ds", domain=mesh, subdomain_data=subdomain_data)(marker) + return beat.base_model.Stimulus(dz=ds, expr=I_s) + + +def define_conductivity_tensor(chi, C_m, f0, s0, n0): + # Conductivities as defined by page 4339 of Niederer benchmark + sigma_il = 0.17 # mS / mm + sigma_it = 0.019 # mS / mm + sigma_el = 0.62 # mS / mm + sigma_et = 0.24 # mS / mm + + # Compute monodomain approximation by taking harmonic mean in each + # direction of intracellular and extracellular part + def harmonic_mean(a, b): + return a * b / (a + b) + + sigma_l = harmonic_mean(sigma_il, sigma_el) + sigma_t = harmonic_mean(sigma_it, sigma_et) + + # Scale conducitivites by 1/(C_m * chi) + s_l = sigma_l / (C_m * chi) # mm^2 / ms + s_t = sigma_t / (C_m * chi) # mm^2 / ms + + # Define conductivity tensor + A = dolfin.as_matrix( + [ + [f0[0], s0[0], n0[0]], + [f0[1], s0[1], n0[1]], + [f0[2], s0[2], n0[2]], + ], + ) + + M_star = ufl.diag(dolfin.as_vector([s_l, s_t, s_t])) + M = A * M_star * A.T + + return M + + +def load_timesteps_from_xdmf(xdmffile): + import xml.etree.ElementTree as ET + + times = {} + i = 0 + tree = ET.parse(xdmffile) + for elem in tree.iter(): + if elem.tag == "Time": + times[i] = float(elem.get("Value")) + i += 1 + + return times + + +def load_from_file(heart_mesh, xdmffile, key="v", stop_index=None): + V = dolfin.FunctionSpace(heart_mesh, "Lagrange", 1) + v = dolfin.Function(V) + + timesteps = load_timesteps_from_xdmf(xdmffile) + with dolfin.XDMFFile(Path(xdmffile).as_posix()) as f: + for i, t in tqdm(timesteps.items()): + f.read_checkpoint(v, key, i) + yield v.copy(deepcopy=True), t + + +def compute_ecg_recovery(): + datadir = Path("data_endocardial_stimulation") + xdmffile = datadir / "state.xdmf" + data = get_data(datadir=datadir) + + # https://litfl.com/ecg-lead-positioning/ + vs = load_from_file(data.mesh, xdmffile, key="V") + + leads = dict( + RA=(-15.0, 0.0, -10.0), + LA=(4.0, -12.0, -7.0), + RL=(0.0, 20.0, 3.0), + LL=(17.0, 11.0, 7.0), + V1=(-3.0, 4.0, -9.0), + V2=(0.0, 2.0, -8.0), + V3=(3.0, 1.0, -8.0), + V4=(6.0, 1.0, -6.0), + V5=(10.0, 2.0, 0.0), + V6=(10.0, -6.0, 2.0), + ) + + fname = datadir / "extracellular_potential.npy" + if not fname.is_file(): + phie = defaultdict(list) + time = [] + for v, t in vs: + time.append(t) + for name, point in leads.items(): + phie[name].append( + beat.ecg.ecg_recovery( + v=v, + mesh=data.mesh, + sigma_b=1.0, + point=point, + ), + ) + np.save(fname, {"phie": phie, "time": time}) + + phie_time = np.load(fname, allow_pickle=True).item() + phie = phie_time["phie"] + time = phie_time["time"] + + fig, ax = plt.subplots(2, 5, sharex=True, figsize=(12, 8)) + for i, (name, values) in enumerate(phie.items()): + axi = ax.flatten()[i] + axi.plot(time, values) + axi.set_title(name) + fig.savefig(datadir / "extracellular_potential.png") + + ecg = beat.ecg.Leads12(**{k: np.array(v) for k, v in phie.items()}) + fig, ax = plt.subplots(3, 4, sharex=True, figsize=(12, 8)) + for i, name in enumerate( + [ + "I", + "II", + "III", + "aVR", + "aVL", + "aVF", + "V1_", + "V2_", + "V3_", + "V4_", + "V5_", + "V6_", + ], + ): + y = getattr(ecg, name) + axi = ax.flatten()[i] + axi.plot(time, y) + axi.set_title(name) + fig.savefig(datadir / "ecg_12_leads.png") + # breakpoint() + + +def main(): + datadir = Path("data_endocardial_stimulation") + data = get_data(datadir=datadir) + + dolfin.parameters["refinement_algorithm"] = "plaza_with_parent_facets" + ep_mesh = dolfin.adapt(data.mesh) + ffun_ep = dolfin.adapt(data.ffun, ep_mesh) + ldrb_markers = { + "base": data.markers["BASE"][0], + "lv": data.markers["ENDO_LV"][0], + "rv": data.markers["ENDO_RV"][0], + "epi": data.markers["EPI"][0], + } + + f0, s0, n0 = ldrb.dolfin_ldrb( + mesh=ep_mesh, + fiber_space="CG_1", + ffun=ffun_ep, + markers=ldrb_markers, + alpha_endo_lv=60, # Fiber angle on the endocardium + alpha_epi_lv=-60, # Fiber angle on the epicardium + ) + microstructure_ep = pulse.Microstructure(f0=f0, s0=s0, n0=n0) + microstructure = pulse.Microstructure(f0=data.f0, s0=data.s0, n0=data.n0) + geo = simcardems.lvgeometry.LeftVentricularGeometry( + mechanics_mesh=data.mesh, + ep_mesh=ep_mesh, + microstructure=microstructure, + microstructure_ep=microstructure_ep, + ffun=data.ffun, + ffun_ep=ffun_ep, + markers=data.markers, + ) + coupling = simcardems.models.fully_coupled_ORdmm_Land.EMCoupling(geometry=geo) + + V = dolfin.FunctionSpace(ep_mesh, "Lagrange", 1) + + markers = dolfin.Function(V) + arr = beat.utils.expand_layer( + markers=markers, + mfun=ffun_ep, + endo_markers=[data.markers["ENDO_LV"][0], data.markers["ENDO_RV"][0]], + epi_markers=[data.markers["EPI"][0]], + endo_marker=1, + epi_marker=2, + endo_size=0.3, + epi_size=0.3, + ) + + markers.vector().set_local(arr) + + with dolfin.XDMFFile((datadir / "markers.xdmf").as_posix()) as xdmf: + xdmf.write(markers) + + model = simcardems.models.fully_coupled_ORdmm_Land.cell_model + + init_states = { + 0: model.init_state_values(), + 1: model.init_state_values(), + 2: model.init_state_values(), + } + parameters = { + 0: model.init_parameter_values(amp=0.0, celltype=2), + 1: model.init_parameter_values(amp=0.0, celltype=0), + 2: model.init_parameter_values(amp=0.0, celltype=1), + } + fun = { + 0: model.forward_generalized_rush_larsen(coupling=coupling), + 1: model.forward_generalized_rush_larsen(coupling=coupling), + 2: model.forward_generalized_rush_larsen(coupling=coupling), + } + v_index = { + 0: model.state_index("v"), + 1: model.state_index("v"), + 2: model.state_index("v"), + } + # Surface to volume ratio + chi = 140.0 # mm^{-1} + # Membrane capacitance + C_m = 0.01 # muqq F / mm^2 + + time = dolfin.Constant(0.0) + I_s = define_stimulus( + mesh=ep_mesh, + chi=chi, + C_m=C_m, + time=time, + ffun=ffun_ep, + markers=data.markers, + ) + + M = define_conductivity_tensor(chi, C_m, f0=f0, s0=s0, n0=n0) + + params = {"preconditioner": "sor", "use_custom_preconditioner": False} + pde = beat.MonodomainModel(time=time, mesh=ep_mesh, M=M, I_s=I_s, params=params) + + ode = beat.odesolver.DolfinMultiODESolver( + pde.state, + markers=markers, + num_states={i: len(s) for i, s in init_states.items()}, + fun=fun, + init_states=init_states, + parameters=parameters, + v_index=v_index, + ) + + solver = beat.MonodomainSplittingSolver(pde=pde, ode=ode) + coupling.register_ep_model(solver) + mech_heart = simcardems.mechanics_model.setup_solver( + coupling=coupling, + ActiveModel=simcardems.models.fully_coupled_ORdmm_Land.ActiveModel, + ) + coupling.register_mech_model(mech_heart) + coupling.setup_assigners() + runner = simcardems.Runner.from_models(coupling=coupling) + + runner.solve(T=5.0, save_freq=1) + + # T = 1 + # # Change to 500 to simulate the full cardiac cycle + # # T = 500 + # t = 0.0 + # dt = 0.05 + + # fname = (datadir / f"state.xdmf").as_posix() + # i = 0 + # while t < T + 1e-12: + # if i % 20 == 0: + # v = solver.pde.state.vector().get_local() + # print(f"Solve for {t=:.2f}, {v.max() =}, {v.min() = }") + # with dolfin.XDMFFile(dolfin.MPI.comm_world, fname) as xdmf: + # xdmf.write_checkpoint( + # solver.pde.state, + # "V", + # float(t), + # dolfin.XDMFFile.Encoding.HDF5, + # True, + # ) + # solver.step((t, t + dt)) + # i += 1 + # t += dt + + +def postprocess(): + # simcardems.postprocess.plot_state_traces("results/results.h5") + simcardems.postprocess.make_xdmffiles("results/results.h5", names=["u", "v"]) + + +if __name__ == "__main__": + main() + # compute_ecg_recovery() + + postprocess() diff --git a/demos/simple_demo.py b/demos/simple_demo.py index 7b491229..a44aaae0 100644 --- a/demos/simple_demo.py +++ b/demos/simple_demo.py @@ -25,7 +25,6 @@ outdir=outdir, geometry_path=geometry_path, geometry_schema_path=geometry_schema_path, - # loglevel=10, coupling_type="fully_coupled_ORdmm_Land", T=200, ) diff --git a/demos/ventricular_geometry.py b/demos/ventricular_geometry.py index f7cc0d6f..e9cf7066 100644 --- a/demos/ventricular_geometry.py +++ b/demos/ventricular_geometry.py @@ -25,9 +25,8 @@ outdir=outdir, geometry_path=geometry_path, geometry_schema_path=geometry_schema_path, - T=1000, - coupling_type="explicit_ORdmm_Land", - mechanics_solve_strategy="fixed", + T=100, + coupling_type="fully_coupled_ORdmm_Land", spring=0.01, ) diff --git a/src/simcardems/models/explicit_ORdmm_Land/cell_model.py b/src/simcardems/models/explicit_ORdmm_Land/cell_model.py index 0dba209a..3112a679 100644 --- a/src/simcardems/models/explicit_ORdmm_Land/cell_model.py +++ b/src/simcardems/models/explicit_ORdmm_Land/cell_model.py @@ -1,28 +1,10 @@ # flake8: noqa: F841 -"""This module contains a ORdmm_Land_em_coupling cardiac cell model - -The module was autogenerated from a gotran ode file -# """ import math import numpy -from ... import utils from .em_model import EMCoupling -# from collections import OrderedDict -# from typing import Dict -# import dolfin -# from dolfin import as_vector -# from dolfin import Constant -# try: -# import ufl_legacy as ufl -# except ImportError: -# import ufl -# from ..cell_model import BaseCellModel - -logger = utils.getLogger(__name__) - def parameter_index(name: str) -> int: """Return the index of the parameter with the given name @@ -222,31 +204,31 @@ def state_index(name: str) -> int: "CaMKt": 12, "xk1": 13, "Zetaw": 14, - "XS": 15, - "XW": 16, - "TmB": 17, - "hLp": 18, - "iF": 19, - "iS": 20, - "fcaf": 21, - "fcas": 22, - "jca": 23, - "j": 24, - "fcafp": 25, - "ffp": 26, - "hsp": 27, - "jp": 28, - "mL": 29, - "xs2": 30, - "Zetas": 31, - "nca": 32, - "CaTrpn": 33, + "XW": 15, + "TmB": 16, + "hLp": 17, + "iF": 18, + "iS": 19, + "fcaf": 20, + "fcas": 21, + "jca": 22, + "j": 23, + "fcafp": 24, + "ffp": 25, + "hsp": 26, + "jp": 27, + "mL": 28, + "xs2": 29, + "Zetas": 30, + "nca": 31, + "CaTrpn": 32, + "XS": 33, "iFp": 34, "iSp": 35, "cajsr": 36, "cansr": 37, - "kss": 38, - "Cd": 39, + "Cd": 38, + "kss": 39, "Jrelnp": 40, "Jrelp": 41, "ki": 42, @@ -448,10 +430,10 @@ def init_parameter_values(**values): def init_state_values(**values): """Initialize state values""" # hL=1, a=0, ap=0, d=0, ff=1, fs=1, hf=1, hs=1, m=0, xrf=0 - # xrs=0, xs1=0, CaMKt=0, xk1=1, Zetaw=0, XS=0, XW=0, TmB=1 - # hLp=1, iF=1, iS=1, fcaf=1, fcas=1, jca=1, j=1, fcafp=1, ffp=1 - # hsp=1, jp=1, mL=0, xs2=0, Zetas=0, nca=0, CaTrpn=0, iFp=1 - # iSp=1, cajsr=1.2, cansr=1.2, kss=145, Cd=0, Jrelnp=0, Jrelp=0 + # xrs=0, xs1=0, CaMKt=0, xk1=1, Zetaw=0, XW=0, TmB=1, hLp=1 + # iF=1, iS=1, fcaf=1, fcas=1, jca=1, j=1, fcafp=1, ffp=1, hsp=1 + # jp=1, mL=0, xs2=0, Zetas=0, nca=0, CaTrpn=0, XS=0, iFp=1 + # iSp=1, cajsr=1.2, cansr=1.2, Cd=0, kss=145, Jrelnp=0, Jrelp=0 # ki=145, cass=0.0001, nass=7, cai=0.0001, nai=7, v=-87 states = numpy.array( @@ -472,7 +454,6 @@ def init_state_values(**values): 1, 0, 0, - 0, 1, 1, 1, @@ -490,12 +471,13 @@ def init_state_values(**values): 0, 0, 0, + 0, 1, 1, 1.2, 1.2, - 145, 0, + 145, 0, 0, 145, @@ -513,6 +495,752 @@ def init_state_values(**values): return states +def rhs(t, states, parameters): + # Assign states + hL = states[0] + a = states[1] + ap = states[2] + d = states[3] + ff = states[4] + fs = states[5] + hf = states[6] + hs = states[7] + m = states[8] + xrf = states[9] + xrs = states[10] + xs1 = states[11] + CaMKt = states[12] + xk1 = states[13] + Zetaw = states[14] + XW = states[15] + TmB = states[16] + hLp = states[17] + iF = states[18] + iS = states[19] + fcaf = states[20] + fcas = states[21] + jca = states[22] + j = states[23] + fcafp = states[24] + ffp = states[25] + hsp = states[26] + jp = states[27] + mL = states[28] + xs2 = states[29] + Zetas = states[30] + nca = states[31] + CaTrpn = states[32] + XS = states[33] + iFp = states[34] + iSp = states[35] + cajsr = states[36] + cansr = states[37] + Cd = states[38] + kss = states[39] + Jrelnp = states[40] + Jrelp = states[41] + ki = states[42] + cass = states[43] + nass = states[44] + cai = states[45] + nai = states[46] + v = states[47] + + # Assign parameters + Aff = parameters[0] + Ahf = parameters[1] + BSLmax = parameters[2] + BSRmax = parameters[3] + Beta0 = parameters[4] + Beta1 = parameters[5] + CaMKo = parameters[6] + Esac_ns = parameters[7] + F = parameters[8] + GKb = parameters[9] + GNa = parameters[10] + Gncx = parameters[11] + GpCa = parameters[12] + Gsac_k = parameters[13] + Gsac_ns = parameters[14] + Gto = parameters[15] + H = parameters[16] + Khp = parameters[17] + Kki = parameters[18] + Kko = parameters[19] + KmBSL = parameters[20] + KmBSR = parameters[21] + KmCaAct = parameters[22] + KmCaM = parameters[23] + KmCaMK = parameters[24] + Kmgatp = parameters[25] + Kmn = parameters[26] + Knai0 = parameters[27] + Knao0 = parameters[28] + Knap = parameters[29] + Kxkur = parameters[30] + L = parameters[31] + MgADP = parameters[32] + MgATP = parameters[33] + PCab = parameters[34] + PKNa = parameters[35] + PNab = parameters[36] + Pnak = parameters[37] + R = parameters[38] + T = parameters[39] + Tot_A = parameters[40] + Tref = parameters[41] + Trpn50 = parameters[42] + aCaMK = parameters[43] + amp = parameters[44] + bCaMK = parameters[45] + bt = parameters[46] + calib = parameters[47] + cao = parameters[48] + cat50_ref = parameters[49] + celltype = parameters[50] + cmdnmax = parameters[51] + csqnmax = parameters[52] + dLambda = parameters[53] + delta = parameters[54] + delta_epi = parameters[55] + duration = parameters[56] + eP = parameters[57] + emcoupling = parameters[58] + etal = parameters[59] + etas = parameters[60] + gammas = parameters[61] + gammaw = parameters[62] + isacs = parameters[63] + k1m = parameters[64] + k1p = parameters[65] + k2m = parameters[66] + k2n = parameters[67] + k2p = parameters[68] + k3m = parameters[69] + k3p = parameters[70] + k4m = parameters[71] + k4p = parameters[72] + kasymm = parameters[73] + kcaoff = parameters[74] + kcaon = parameters[75] + kmcmdn = parameters[76] + kmcsqn = parameters[77] + kmtrpn = parameters[78] + kna1 = parameters[79] + kna2 = parameters[80] + kna3 = parameters[81] + ko = parameters[82] + ktrpn = parameters[83] + ku = parameters[84] + kuw = parameters[85] + kws = parameters[86] + lambda_max = parameters[87] + lmbda = parameters[88] + mode = parameters[89] + nao = parameters[90] + ntm = parameters[91] + ntrpn = parameters[92] + p_a = parameters[93] + p_b = parameters[94] + p_k = parameters[95] + phi = parameters[96] + qca = parameters[97] + qna = parameters[98] + rad = parameters[99] + rs = parameters[100] + rw = parameters[101] + scale_HF_CaMKa = parameters[102] + scale_HF_GK1 = parameters[103] + scale_HF_GNaL = parameters[104] + scale_HF_Gncx = parameters[105] + scale_HF_Gto = parameters[106] + scale_HF_Jleak = parameters[107] + scale_HF_Jrel_inf = parameters[108] + scale_HF_Jup = parameters[109] + scale_HF_Pnak = parameters[110] + scale_HF_cat50_ref = parameters[111] + scale_HF_thL = parameters[112] + scale_ICaL = parameters[113] + scale_IK1 = parameters[114] + scale_IKr = parameters[115] + scale_IKs = parameters[116] + scale_INaL = parameters[117] + scale_drug_ICaL = parameters[118] + scale_drug_ICab = parameters[119] + scale_drug_IK1 = parameters[120] + scale_drug_IKb = parameters[121] + scale_drug_IKr = parameters[122] + scale_drug_IKs = parameters[123] + scale_drug_INa = parameters[124] + scale_drug_INaL = parameters[125] + scale_drug_INab = parameters[126] + scale_drug_IpCa = parameters[127] + scale_drug_Isack = parameters[128] + scale_drug_Isacns = parameters[129] + scale_drug_Ito = parameters[130] + thL = parameters[131] + tjca = parameters[132] + trpnmax = parameters[133] + wca = parameters[134] + wna = parameters[135] + wnaca = parameters[136] + zca = parameters[137] + zk = parameters[138] + + # Assign expressions + values = numpy.zeros_like(states) + zna = 1.0 + Afcaf = 0.3 + 0.6 / (numpy.exp((v - 10.0) / 10.0) + 1.0) + AiF = 1.0 / (numpy.exp((v - 213.6) / 151.2) + 1.0) + Axrf = 1.0 / (numpy.exp((v + 54.81) / 38.21) + 1.0) + ass = 1.0 / (numpy.exp((-(v - 14.34)) / 14.82) + 1.0) + assp = 1.0 / (numpy.exp((-(v - 24.34)) / 14.82) + 1.0) + dss = 1.0 / (numpy.exp((-(v + 3.94)) / 4.23) + 1.0) + dti_develop = 1.354 + 0.0001 / ( + numpy.exp((-(v - 12.23)) / 0.2154) + numpy.exp((v - 167.4) / 15.89) + ) + dti_recover = 1.0 - 0.5 / (numpy.exp((v + 70.0) / 20.0) + 1.0) + fss = 1.0 / (numpy.exp((v + 19.58) / 3.696) + 1.0) + hLss = 1.0 / (numpy.exp((v + 87.61) / 7.488) + 1.0) + hLssp = 1.0 / (numpy.exp((v + 93.81) / 7.488) + 1.0) + hss = 1.0 / (numpy.exp((v + 78.5) / 6.22) + 1) + hssp = 1.0 / (numpy.exp(((v + 78.5) + 6.2) / 6.22) + 1) + iss = 1.0 / (numpy.exp((v + 43.94) / 5.711) + 1.0) + mLss = 1.0 / (numpy.exp((-(v + 42.85)) / 5.264) + 1.0) + mss = 1.0 / (numpy.exp((-((v + 39.57) + 9.4)) / 7.5) + 1.0) + rkr = (1.0 * (1.0 / (numpy.exp((v + 55.0) / 75.0) + 1.0))) / ( + numpy.exp((v - 10.0) / 30.0) + 1.0 + ) + ta = 1.0515 / ( + 1.0 / ((1.2089 * (numpy.exp((-(v - 18.4099)) / 29.3814) + 1.0))) + + 3.5 / (numpy.exp((v + 100.0) / 29.3814) + 1.0) + ) + td = 0.6 + 1.0 / (numpy.exp((-0.05) * (v + 6.0)) + numpy.exp(0.09 * (v + 14.0))) + tfcaf = 7.0 + 1.0 / ( + 0.04 * numpy.exp((-(v - 4.0)) / 7.0) + 0.04 * numpy.exp((v - 4.0) / 7.0) + ) + tfcas = 100.0 + 1.0 / ( + 0.00012 * numpy.exp((-v) / 3.0) + 0.00012 * numpy.exp(v / 7.0) + ) + tff = 7.0 + 1.0 / ( + 0.0045 * numpy.exp((-(v + 20.0)) / 10.0) + 0.0045 * numpy.exp((v + 20.0) / 10.0) + ) + tfs = 1000.0 + 1.0 / ( + 3.5e-05 * numpy.exp((-(v + 5.0)) / 4.0) + 3.5e-05 * numpy.exp((v + 5.0) / 6.0) + ) + thf = 1.0 / ( + 6.149 * numpy.exp((v + 0.5096) / 20.27) + + 1.432e-05 * numpy.exp((-(v + 1.196)) / 6.285) + ) + ths = 1.0 / ( + 0.009794 * numpy.exp((-(v + 17.95)) / 28.05) + + 0.3343 * numpy.exp((v + 5.73) / 56.66) + ) + tj = 2.038 + 1.0 / ( + 0.3052 * numpy.exp((v + 0.9941) / 38.45) + + 0.02136 * numpy.exp((-(v + 100.6)) / 8.281) + ) + tm = 1.0 / ( + 6.765 * numpy.exp((v + 11.64) / 34.77) + + 8.552 * numpy.exp((-(v + 77.42)) / 5.955) + ) + txk1 = 122.2 / (numpy.exp((-(v + 127.2)) / 20.36) + numpy.exp((v + 236.8) / 69.33)) + txrf = 12.98 + 1.0 / ( + 4.123e-05 * numpy.exp((-(v - 47.78)) / 20.38) + + 0.3652 * numpy.exp((v - 31.66) / 3.869) + ) + txrs = 1.865 + 1.0 / ( + 1.128e-05 * numpy.exp((-(v - 29.74)) / 25.94) + + 0.06629 * numpy.exp((v - 34.7) / 7.355) + ) + txs1 = 817.3 + 1.0 / ( + 0.0002326 * numpy.exp((v + 48.28) / 17.8) + + 0.001292 * numpy.exp((-(v + 210.0)) / 230.0) + ) + txs2 = 1.0 / ( + 0.01 * numpy.exp((v - 50.0) / 20.0) + 0.0193 * numpy.exp((-(v + 66.54)) / 31.0) + ) + xkb = 1.0 / (numpy.exp((-(v - 14.48)) / 18.34) + 1.0) + xrss = 1.0 / (numpy.exp((-(v + 8.337)) / 6.789) + 1.0) + xs1ss = 1.0 / (numpy.exp((-(v + 11.6)) / 8.932) + 1.0) + Afs = 1.0 - Aff + Ageo = L * ((2 * 3.14) * rad) + rad * ((2 * 3.14) * rad) + vcell = L * (rad * ((3.14 * 1000) * rad)) + Ahs = 1.0 - Ahf + Aw = (Tot_A * rs) / (rs + rw * (1 - rs)) + Bcai = 1.0 / ((cmdnmax * kmcmdn) / (cai + kmcmdn) ** 2.0 + 1.0) + Jupnp = (0.004375 * cai) / (cai + 0.00092) + Jupp = ((0.004375 * 2.75) * cai) / ((cai + 0.00092) - 0.00017) + KsCa = 1.0 + 0.6 / ((3.8e-05 / cai) ** 1.4 + 1.0) + Bcajsr = 1.0 / ((csqnmax * kmcsqn) / (cajsr + kmcsqn) ** 2.0 + 1.0) + Bcass = 1.0 / ( + (BSLmax * KmBSL) / (KmBSL + cass) ** 2.0 + + ((BSRmax * KmBSR) / (KmBSR + cass) ** 2.0 + 1.0) + ) + Jdiff = (-cai + cass) / 0.2 + CaMKb = (CaMKo * (1.0 - CaMKt)) / (KmCaM / cass + 1.0) + CaTrpn_max = numpy.where((CaTrpn > 0), CaTrpn, 0) + rk1 = 1.0 / (numpy.exp((-2.6 * ko + (v + 105.8)) / 9.493) + 1.0) + xk1ss = 1.0 / ( + numpy.exp((-((2.5538 * ko + v) + 144.59)) / (1.5692 * ko + 3.8115)) + 1.0 + ) + vffrt = (F * (F * v)) / ((R * T)) + vfrt = (F * v) / ((R * T)) + EK = ((R * T) / F) * numpy.log(ko / ki) + EKs = ((R * T) / F) * numpy.log((PKNa * nao + ko) / (PKNa * nai + ki)) + ENa = ((R * T) / F) * numpy.log(nao / nai) + GK1 = scale_HF_GK1 * ((0.1908 * scale_IK1) * scale_drug_IK1) + GKr = (0.046 * scale_IKr) * scale_drug_IKr + GKs = (0.0034 * scale_IKs) * scale_drug_IKs + GNaL = scale_HF_GNaL * ((0.0075 * scale_INaL) * scale_drug_INaL) + km2n = 1.0 * jca + IpCa = (cai * (GpCa * scale_drug_IpCa)) / (cai + 0.0005) + lambda_min12 = numpy.where((lmbda < 1.2), lmbda, 1.2) + Isac_P_k = numpy.where( + (lmbda < 1.0), + 0.0, + (Gsac_k * ((lmbda - 1.0) / (lambda_max - 1.0))) + * (1.0 / (numpy.exp((19.05 - v) / 29.98) + 1.0)), + ) + Isac_P_ns = numpy.where( + (lmbda < 1.0), + 0.0, + (Gsac_ns * ((lmbda - 1.0) / (lambda_max - 1.0))) * (-Esac_ns + v), + ) + Istim = numpy.where((duration >= t), amp, 0) + JdiffK = (-ki + kss) / 2.0 + JdiffNa = (-nai + nass) / 2.0 + Jtr = (-cajsr + cansr) / 100.0 + Jleak = ((0.0039375 * cansr) * scale_HF_Jleak) / 15.0 + Knai = Knai0 * numpy.exp((F * (delta * v)) / (((3.0 * R) * T))) + Knao = Knao0 * numpy.exp((F * (v * (1.0 - delta))) / (((3.0 * R) * T))) + P = eP / (((H / Khp + 1.0) + nai / Knap) + ki / Kxkur) + PCa = (0.0001 * scale_ICaL) * scale_drug_ICaL + XS_max = numpy.where((XS > 0), XS, 0) + zetas1 = Zetas * numpy.where((Zetas > 0), 1.0, 0.0) + zetas2 = (-Zetas - 1.0) * numpy.where((Zetas < -1.0), 1.0, 0.0) + XW_max = numpy.where((XW > 0), XW, 0) + XU = -XW + (-XS + (1 - TmB)) + a2 = k2p + a4 = ((MgATP * k4p) / Kmgatp) / (1.0 + MgATP / Kmgatp) + a_rel = 0.5 * bt + btp = 1.25 * bt + tau_rel_tmp = bt / (1.0 + 0.0123 / cajsr) + allo_i = 1.0 / ((KmCaAct / cai) ** 2.0 + 1.0) + allo_ss = 1.0 / ((KmCaAct / cass) ** 2.0 + 1.0) + b1 = MgADP * k1m + cs = ((kws * phi) * (rw * (1 - rs))) / rs + ksu = (kws * rw) * (-1 + 1 / rs) + cw = ((kuw * phi) * ((1 - rs) * (1 - rw))) / ((rw * (1 - rs))) + kwu = kuw * (-1 + 1 / rw) - kws + gammawu = gammaw * numpy.abs(Zetaw) + h10 = (nao / kna1) * (1 + nao / kna2) + (kasymm + 1.0) + h10_i = (nao / kna1) * (1.0 + nao / kna2) + (kasymm + 1.0) + h4 = (nass / kna1) * (1 + nass / kna2) + 1.0 + h4_i = (nai / kna1) * (1 + nai / kna2) + 1.0 + hca = numpy.exp((F * (qca * v)) / ((R * T))) + hna = numpy.exp((F * (qna * v)) / ((R * T))) + k2 = kcaoff + k2_i = kcaoff + k5 = kcaoff + k5_i = kcaoff + kb = (Trpn50**ntm * ku) / (-rw * (1 - rs) + (1 - rs)) + thLp = scale_HF_thL * (3.0 * thL) + tiF = ( + delta_epi + * ( + 1 + / ( + 0.3933 * numpy.exp((-(v + 100.0)) / 100.0) + + 0.08004 * numpy.exp((v + 50.0) / 16.59) + ) + ) + + 4.562 + ) + tiS = ( + delta_epi + * ( + 1 + / ( + 0.001416 * numpy.exp((-(v + 96.52)) / 59.05) + + 1.78e-08 * numpy.exp((v + 114.1) / 8.079) + ) + ) + + 23.62 + ) + Afcas = 1.0 - Afcaf + AiS = 1.0 - AiF + Axrs = 1.0 - Axrf + fcass = fss + dhL_dt = (-hL + hLss) / ((scale_HF_thL * thL)) + values[0] = dhL_dt + jss = hss + da_dt = (-a + ass) / ta + values[1] = da_dt + dap_dt = (-ap + assp) / ta + values[2] = dap_dt + dd_dt = (-d + dss) / td + values[3] = dd_dt + tfcafp = 2.5 * tfcaf + tffp = 2.5 * tff + dff_dt = (-ff + fss) / tff + values[4] = dff_dt + dfs_dt = (-fs + fss) / tfs + values[5] = dfs_dt + dhf_dt = (-hf + hss) / thf + values[6] = dhf_dt + thsp = 3.0 * ths + dhs_dt = (-hs + hss) / ths + values[7] = dhs_dt + tjp = 1.46 * tj + tmL = tm + dm_dt = (-m + mss) / tm + values[8] = dm_dt + dxrf_dt = (-xrf + xrss) / txrf + values[9] = dxrf_dt + dxrs_dt = (-xrs + xrss) / txrs + values[10] = dxrs_dt + xs2ss = xs1ss + dxs1_dt = (-xs1 + xs1ss) / txs1 + values[11] = dxs1_dt + f = Aff * ff + Afs * fs + fp = Aff * ffp + Afs * fs + Acap = 2 * Ageo + vjsr = 0.0048 * vcell + vmyo = 0.68 * vcell + vnsr = 0.0552 * vcell + vss = 0.02 * vcell + h = Ahf * hf + Ahs * hs + hp = Ahf * hf + Ahs * hsp + As = Aw + CaMKa = scale_HF_CaMKa * (CaMKb + CaMKt) + dCaMKt_dt = -CaMKt * bCaMK + (CaMKb * aCaMK) * (CaMKb + CaMKt) + values[12] = dCaMKt_dt + dxk1_dt = (-xk1 + xk1ss) / txk1 + values[13] = dxk1_dt + ICab = ( + (vffrt * (4.0 * (PCab * scale_drug_ICab))) + * (cai * numpy.exp(2.0 * vfrt) - 0.341 * cao) + ) / (numpy.exp(2.0 * vfrt) - 1.0) + INab = ((vffrt * (PNab * scale_drug_INab)) * (nai * numpy.exp(vfrt) - nao)) / ( + numpy.exp(vfrt) - 1.0 + ) + PhiCaK = ((1.0 * vffrt) * (-0.75 * ko + (0.75 * kss) * numpy.exp(1.0 * vfrt))) / ( + numpy.exp(1.0 * vfrt) - 1.0 + ) + PhiCaL = ((4.0 * vffrt) * (-0.341 * cao + cass * numpy.exp(2.0 * vfrt))) / ( + numpy.exp(2.0 * vfrt) - 1.0 + ) + PhiCaNa = ( + (1.0 * vffrt) * (-0.75 * nao + (0.75 * nass) * numpy.exp(1.0 * vfrt)) + ) / (numpy.exp(1.0 * vfrt) - 1.0) + IKb = (xkb * (GKb * scale_drug_IKb)) * (-EK + v) + IK1 = (xk1 * (rk1 * (GK1 * math.sqrt(ko)))) * (-EK + v) + IKs = (xs2 * (xs1 * (GKs * KsCa))) * (-EKs + v) + anca = 1.0 / (k2n / km2n + (Kmn / cass + 1.0) ** 4.0) + C = lambda_min12 - 1 + cat50 = scale_HF_cat50_ref * (Beta1 * (lambda_min12 - 1) + cat50_ref) + lambda_min087 = numpy.where((lambda_min12 < 0.87), lambda_min12, 0.87) + a1 = (k1p * (nai / Knai) ** 3.0) / ( + ((1.0 + ki / Kki) ** 2.0 + (1.0 + nai / Knai) ** 3.0) - 1.0 + ) + b4 = (k4m * (ki / Kki) ** 2.0) / ( + ((1.0 + ki / Kki) ** 2.0 + (1.0 + nai / Knai) ** 3.0) - 1.0 + ) + a3 = (k3p * (ko / Kko) ** 2.0) / ( + ((1.0 + ko / Kko) ** 2.0 + (1.0 + nao / Knao) ** 3.0) - 1.0 + ) + b2 = (k2m * (nao / Knao) ** 3.0) / ( + ((1.0 + ko / Kko) ** 2.0 + (1.0 + nao / Knao) ** 3.0) - 1.0 + ) + b3 = (H * (P * k3m)) / (1.0 + MgATP / Kmgatp) + PCaK = 0.0003574 * PCa + PCaNa = 0.00125 * PCa + PCap = 1.1 * PCa + gammasu = gammas * numpy.where((zetas1 > zetas2), zetas1, zetas2) + a_relp = 0.5 * btp + tau_relp_tmp = btp / (1.0 + 0.0123 / cajsr) + tau_rel = numpy.where((tau_rel_tmp < 0.001), 0.001, tau_rel_tmp) + dZetaw_dt = Aw * dLambda - Zetaw * cw + values[14] = dZetaw_dt + dXW_dt = -XW * gammawu + (-XW * kws + (XU * kuw - XW * kwu)) + values[15] = dXW_dt + h11 = (nao * nao) / ((kna2 * (h10 * kna1))) + h12 = 1.0 / h10 + h11_i = (nao * nao) / ((kna2 * (h10_i * kna1))) + h12_i = 1.0 / h10_i + h5 = (nass * nass) / ((kna2 * (h4 * kna1))) + h6 = 1.0 / h4 + h5_i = (nai * nai) / ((kna2 * (h4_i * kna1))) + h6_i = 1.0 / h4_i + h1 = (nass / kna3) * (hna + 1) + 1 + h1_i = (nai / kna3) * (hna + 1) + 1 + h7 = (nao / kna3) * (1.0 + 1.0 / hna) + 1.0 + h7_i = (nao / kna3) * (1.0 + 1.0 / hna) + 1.0 + dTmB_dt = -TmB * CaTrpn ** (ntm / 2) * ku + XU * ( + kb + * numpy.where((CaTrpn ** (-1 / 2 * ntm) < 100), CaTrpn ** (-1 / 2 * ntm), 100) + ) + values[16] = dTmB_dt + dhLp_dt = (-hLp + hLssp) / thLp + values[17] = dhLp_dt + tiFp = tiF * (dti_develop * dti_recover) + diF_dt = (-iF + iss) / tiF + values[18] = diF_dt + tiSp = tiS * (dti_develop * dti_recover) + diS_dt = (-iS + iss) / tiS + values[19] = diS_dt + fca = Afcaf * fcaf + Afcas * fcas + fcap = Afcaf * fcafp + Afcas * fcas + i = AiF * iF + AiS * iS + ip = AiF * iFp + AiS * iSp + xr = Axrf * xrf + Axrs * xrs + dfcaf_dt = (-fcaf + fcass) / tfcaf + values[20] = dfcaf_dt + dfcas_dt = (-fcas + fcass) / tfcas + values[21] = dfcas_dt + djca_dt = (fcass - jca) / tjca + values[22] = djca_dt + dj_dt = (-j + jss) / tj + values[23] = dj_dt + dfcafp_dt = (-fcafp + fcass) / tfcafp + values[24] = dfcafp_dt + dffp_dt = (-ffp + fss) / tffp + values[25] = dffp_dt + dhsp_dt = (-hsp + hssp) / thsp + values[26] = dhsp_dt + djp_dt = (-jp + jss) / tjp + values[27] = djp_dt + dmL_dt = (-mL + mLss) / tmL + values[28] = dmL_dt + dxs2_dt = (-xs2 + xs2ss) / txs2 + values[29] = dxs2_dt + dZetas_dt = As * dLambda - Zetas * cs + values[30] = dZetas_dt + fICaLp = 1.0 / (1.0 + KmCaMK / CaMKa) + fINaLp = 1.0 / (1.0 + KmCaMK / CaMKa) + fINap = 1.0 / (1.0 + KmCaMK / CaMKa) + fItop = 1.0 / (1.0 + KmCaMK / CaMKa) + fJrelp = 1.0 / (1.0 + KmCaMK / CaMKa) + fJupp = 1.0 / (1.0 + KmCaMK / CaMKa) + dnca_dt = anca * k2n - km2n * nca + values[31] = dnca_dt + F1 = numpy.exp(C * p_b) - 1 + dCd = C - Cd + dCaTrpn_dt = ktrpn * (-CaTrpn + ((1000 * cai) / cat50) ** ntrpn * (1 - CaTrpn)) + values[32] = dCaTrpn_dt + h_lambda_prima = Beta0 * ((lambda_min087 + lambda_min12) - 1.87) + 1 + x2 = b4 * (a2 * a3) + (b4 * (a3 * b1) + (a3 * (a1 * a2) + b4 * (b1 * b2))) + x1 = a2 * (a1 * b3) + (b3 * (a2 * b4) + (a2 * (a1 * a4) + b3 * (b2 * b4))) + x3 = b1 * (a3 * a4) + (a4 * (b1 * b2) + (a4 * (a2 * a3) + b1 * (b2 * b3))) + x4 = a1 * (b2 * b3) + (a1 * (a4 * b2) + (a1 * (a3 * a4) + b2 * (b3 * b4))) + PCaKp = 0.0003574 * PCap + PCaNap = 0.00125 * PCap + dXS_dt = -XS * gammasu + (-XS * ksu + XW * kws) + values[33] = dXS_dt + tau_relp = numpy.where((tau_relp_tmp < 0.001), 0.001, tau_relp_tmp) + k1 = kcaon * (cao * h12) + k1_i = kcaon * (cao * h12_i) + k6 = kcaon * (cass * h6) + k6_i = kcaon * (cai * h6_i) + h2 = (hna * nass) / ((h1 * kna3)) + h3 = 1.0 / h1 + h2_i = (hna * nai) / ((h1_i * kna3)) + h3_i = 1.0 / h1_i + h8 = nao / ((h7 * (hna * kna3))) + h9 = 1.0 / h7 + h8_i = nao / ((h7_i * (hna * kna3))) + h9_i = 1.0 / h7_i + diFp_dt = (-iFp + iss) / tiFp + values[34] = diFp_dt + diSp_dt = (-iSp + iss) / tiSp + values[35] = diSp_dt + IKr = (rkr * (xr * (GKr * (0.4303314829119352 * math.sqrt(ko))))) * (-EK + v) + ICaL = (d * (PhiCaL * (PCa * (1.0 - fICaLp)))) * ( + f * (1.0 - nca) + nca * (fca * jca) + ) + (d * (PhiCaL * (PCap * fICaLp))) * (fp * (1.0 - nca) + nca * (fcap * jca)) + INaL = (mL * (GNaL * (-ENa + v))) * (fINaLp * hLp + hL * (1.0 - fINaLp)) + INa = (m**3.0 * ((GNa * scale_drug_INa) * (-ENa + v))) * ( + j * (h * (1.0 - fINap)) + jp * (fINap * hp) + ) + Ito = ((scale_HF_Gto * (Gto * scale_drug_Ito)) * (-EK + v)) * ( + i * (a * (1.0 - fItop)) + ip * (ap * fItop) + ) + Jrel = Jrelnp * (1.0 - fJrelp) + Jrelp * fJrelp + Jup = -Jleak + (Jupnp * (1.0 - fJupp) + scale_HF_Jup * (Jupp * fJupp)) + eta = numpy.where((dCd < 0), etas, etal) + J_TRPN = dCaTrpn_dt * trpnmax + h_lambda = numpy.where((h_lambda_prima > 0), h_lambda_prima, 0) + E1 = x1 / (x4 + (x3 + (x1 + x2))) + E2 = x2 / (x4 + (x3 + (x1 + x2))) + E3 = x3 / (x4 + (x3 + (x1 + x2))) + E4 = x4 / (x4 + (x3 + (x1 + x2))) + ICaK = (d * (PhiCaK * (PCaK * (1.0 - fICaLp)))) * ( + f * (1.0 - nca) + nca * (fca * jca) + ) + (d * (PhiCaK * (PCaKp * fICaLp))) * (fp * (1.0 - nca) + nca * (fcap * jca)) + ICaNa = (d * (PhiCaNa * (PCaNa * (1.0 - fICaLp)))) * ( + f * (1.0 - nca) + nca * (fca * jca) + ) + (d * (PhiCaNa * (PCaNap * fICaLp))) * (fp * (1.0 - nca) + nca * (fcap * jca)) + k4pp = h2 * wnaca + k7 = wna * (h2 * h5) + k4p_ss = (h3 * wca) / hca + k4pp_i = h2_i * wnaca + k7_i = wna * (h2_i * h5_i) + k4p_i = (h3_i * wca) / hca + k3pp = h8 * wnaca + k8 = wna * (h11 * h8) + k3p_ss = h9 * wca + k3pp_i = h8_i * wnaca + k8_i = wna * (h11_i * h8_i) + k3p_i = h9_i * wca + Jrel_inf = ((-ICaL) * a_rel) / (((1.5 * scale_HF_Jrel_inf) / cajsr) ** 8.0 + 1.0) + Jrel_infp = ((-ICaL) * a_relp) / (((1.5 * scale_HF_Jrel_inf) / cajsr) ** 8.0 + 1.0) + dcajsr_dt = Bcajsr * (-Jrel + Jtr) + values[36] = dcajsr_dt + dcansr_dt = Jup - (Jtr * vjsr) / vnsr + values[37] = dcansr_dt + Fd = dCd * eta + dCd_dt = (p_k * (C - Cd)) / eta + values[38] = dCd_dt + Ta = (h_lambda * (Tref / rs)) * (XS * (Zetas + 1) + XW * Zetaw) + JnakNa = 3.0 * (E1 * a3 - E2 * b3) + JnakK = 2.0 * (-E3 * a1 + E4 * b1) + dkss_dt = -JdiffK + (Acap * (-ICaK)) / ((F * vss)) + values[39] = dkss_dt + k4 = k4p_ss + k4pp + k4_i = k4p_i + k4pp_i + k3 = k3p_ss + k3pp + k3_i = k3p_i + k3pp_i + dJrelnp_dt = (Jrel_inf - Jrelnp) / tau_rel + values[40] = dJrelnp_dt + dJrelp_dt = (Jrel_infp - Jrelp) / tau_relp + values[41] = dJrelp_dt + Tp = p_a * (F1 + Fd) + INaK = (Pnak * scale_HF_Pnak) * (JnakK * zk + JnakNa * zna) + x2_ss = (k1 * k7) * (k4 + k5) + (k4 * k6) * (k1 + k8) + x2_i = (k1_i * k7_i) * (k4_i + k5_i) + (k4_i * k6_i) * (k1_i + k8_i) + x1_ss = (k2 * k4) * (k6 + k7) + (k5 * k7) * (k2 + k3) + x3_ss = (k1 * k3) * (k6 + k7) + (k6 * k8) * (k2 + k3) + x4_ss = (k2 * k8) * (k4 + k5) + (k3 * k5) * (k1 + k8) + x1_i = (k2_i * k4_i) * (k6_i + k7_i) + (k5_i * k7_i) * (k2_i + k3_i) + x3_i = (k1_i * k3_i) * (k6_i + k7_i) + (k6_i * k8_i) * (k2_i + k3_i) + x4_i = (k2_i * k8_i) * (k4_i + k5_i) + (k3_i * k5_i) * (k1_i + k8_i) + Ttot = Ta + Tp + dki_dt = ( + Acap + * ( + -( + -2.0 * INaK + + ( + Istim + + (Isac_P_ns / 3 + (Isac_P_k + (IKb + (IK1 + (IKs + (IKr + Ito)))))) + ) + ) + ) + ) / ((F * vmyo)) + (JdiffK * vss) / vmyo + values[42] = dki_dt + E1_ss = x1_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) + E2_ss = x2_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) + E3_ss = x3_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) + E4_ss = x4_ss / (x4_ss + (x3_ss + (x1_ss + x2_ss))) + E1_i = x1_i / (x4_i + (x3_i + (x1_i + x2_i))) + E2_i = x2_i / (x4_i + (x3_i + (x1_i + x2_i))) + E3_i = x3_i / (x4_i + (x3_i + (x1_i + x2_i))) + E4_i = x4_i / (x4_i + (x3_i + (x1_i + x2_i))) + JncxCa_ss = -E1_ss * k1 + E2_ss * k2 + JncxNa_ss = -E2_ss * k3pp + (E3_ss * k4pp + 3.0 * (-E1_ss * k8 + E4_ss * k7)) + JncxCa_i = -E1_i * k1_i + E2_i * k2_i + JncxNa_i = -E2_i * k3pp_i + (E3_i * k4pp_i + 3.0 * (-E1_i * k8_i + E4_i * k7_i)) + INaCa_ss = (allo_ss * ((0.2 * Gncx) * scale_HF_Gncx)) * ( + JncxCa_ss * zca + JncxNa_ss * zna + ) + INaCa_i = (allo_i * ((0.8 * Gncx) * scale_HF_Gncx)) * ( + JncxCa_i * zca + JncxNa_i * zna + ) + dcass_dt = Bcass * ( + -Jdiff + + ( + (Acap * (-(ICaL - 2.0 * INaCa_ss))) / (((2.0 * F) * vss)) + + (Jrel * vjsr) / vss + ) + ) + values[43] = dcass_dt + dnass_dt = -JdiffNa + (Acap * (-(ICaNa + 3.0 * INaCa_ss))) / ((F * vss)) + values[44] = dnass_dt + dcai_dt = Bcai * ( + -J_TRPN + + ( + ( + (Acap * (-(Isac_P_ns / 3 + (-2.0 * INaCa_i + (ICab + IpCa))))) + / (((2.0 * F) * vmyo)) + - (Jup * vnsr) / vmyo + ) + + (Jdiff * vss) / vmyo + ) + ) + values[45] = dcai_dt + dnai_dt = ( + Acap + * (-(Isac_P_ns / 3 + (INab + (3.0 * INaK + (3.0 * INaCa_i + (INa + INaL)))))) + ) / ((F * vmyo)) + (JdiffNa * vss) / vmyo + values[46] = dnai_dt + dv_dt = -( + Isac_P_k + + ( + Isac_P_ns + + ( + Istim + + ( + ICab + + ( + IpCa + + ( + IKb + + ( + INab + + ( + INaK + + ( + INaCa_ss + + ( + INaCa_i + + ( + IK1 + + ( + IKs + + ( + IKr + + ( + ICaK + + ( + ICaNa + + ( + ICaL + + ( + Ito + + (INa + INaL) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + values[47] = dv_dt + + return values + + def forward_generalized_rush_larsen(coupling: EMCoupling): def forward_generalized_rush_larsen_(states, t, dt, parameters): lmbda = coupling.lmbda_ep.vector().get_local() @@ -533,31 +1261,31 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): CaMKt = states[12] xk1 = states[13] Zetaw = states[14] - XS = states[15] - XW = states[16] - TmB = states[17] - hLp = states[18] - iF = states[19] - iS = states[20] - fcaf = states[21] - fcas = states[22] - jca = states[23] - j = states[24] - fcafp = states[25] - ffp = states[26] - hsp = states[27] - jp = states[28] - mL = states[29] - xs2 = states[30] - Zetas = states[31] - nca = states[32] - CaTrpn = states[33] + XW = states[15] + TmB = states[16] + hLp = states[17] + iF = states[18] + iS = states[19] + fcaf = states[20] + fcas = states[21] + jca = states[22] + j = states[23] + fcafp = states[24] + ffp = states[25] + hsp = states[26] + jp = states[27] + mL = states[28] + xs2 = states[29] + Zetas = states[30] + nca = states[31] + CaTrpn = states[32] + XS = states[33] iFp = states[34] iSp = states[35] cajsr = states[36] cansr = states[37] - kss = states[38] - Cd = states[39] + Cd = states[38] + kss = states[39] Jrelnp = states[40] Jrelp = states[41] ki = states[42] @@ -575,11 +1303,14 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): Beta0 = parameters[4] Beta1 = parameters[5] CaMKo = parameters[6] + Esac_ns = parameters[7] F = parameters[8] GKb = parameters[9] GNa = parameters[10] Gncx = parameters[11] GpCa = parameters[12] + Gsac_k = parameters[13] + Gsac_ns = parameters[14] Gto = parameters[15] H = parameters[16] Khp = parameters[17] @@ -612,8 +1343,10 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): amp = parameters[44] bCaMK = parameters[45] bt = parameters[46] + calib = parameters[47] cao = parameters[48] cat50_ref = parameters[49] + celltype = parameters[50] cmdnmax = parameters[51] csqnmax = parameters[52] # dLambda = parameters[53] @@ -621,10 +1354,12 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): delta_epi = parameters[55] duration = parameters[56] eP = parameters[57] + emcoupling = parameters[58] etal = parameters[59] etas = parameters[60] gammas = parameters[61] gammaw = parameters[62] + isacs = parameters[63] k1m = parameters[64] k1p = parameters[65] k2m = parameters[66] @@ -639,6 +1374,7 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): kcaon = parameters[75] kmcmdn = parameters[76] kmcsqn = parameters[77] + kmtrpn = parameters[78] kna1 = parameters[79] kna2 = parameters[80] kna3 = parameters[81] @@ -647,7 +1383,9 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): ku = parameters[84] kuw = parameters[85] kws = parameters[86] + lambda_max = parameters[87] # lmbda = parameters[88] + mode = parameters[89] nao = parameters[90] ntm = parameters[91] ntrpn = parameters[92] @@ -686,6 +1424,8 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): scale_drug_INaL = parameters[125] scale_drug_INab = parameters[126] scale_drug_IpCa = parameters[127] + scale_drug_Isack = parameters[128] + scale_drug_Isacns = parameters[129] scale_drug_Ito = parameters[130] thL = parameters[131] tjca = parameters[132] @@ -699,8 +1439,6 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): # Assign expressions values = numpy.zeros_like(states) zna = 1.0 - Isac_P_k = 0 - Isac_P_ns = 0 Afcaf = 0.3 + 0.6 / (numpy.exp((v - 10.0) / 10.0) + 1.0) AiF = 1.0 / (numpy.exp((v - 213.6) / 151.2) + 1.0) Axrf = 1.0 / (numpy.exp((v + 54.81) / 38.21) + 1.0) @@ -784,10 +1522,10 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): vcell = L * (rad * ((3.14 * 1000) * rad)) Ahs = 1.0 - Ahf Aw = (Tot_A * rs) / (rs + rw * (1 - rs)) + Bcai = 1.0 / ((cmdnmax * kmcmdn) / (cai + kmcmdn) ** 2.0 + 1.0) Jupnp = (0.004375 * cai) / (cai + 0.00092) Jupp = ((0.004375 * 2.75) * cai) / ((cai + 0.00092) - 0.00017) KsCa = 1.0 + 0.6 / ((3.8e-05 / cai) ** 1.4 + 1.0) - Bcai = 1.0 / ((cmdnmax * kmcmdn) / (cai + kmcmdn) ** 2.0 + 1.0) Bcajsr = 1.0 / ((csqnmax * kmcsqn) / (cajsr + kmcsqn) ** 2.0 + 1.0) Bcass = 1.0 / ( (BSLmax * KmBSL) / (KmBSL + cass) ** 2.0 @@ -795,13 +1533,14 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): ) Jdiff = (-cai + cass) / 0.2 CaMKb = (CaMKo * (1.0 - CaMKt)) / (KmCaM / cass + 1.0) + CaTrpn_max = numpy.where((CaTrpn > 0), CaTrpn, 0) rk1 = 1.0 / (numpy.exp((-2.6 * ko + (v + 105.8)) / 9.493) + 1.0) xk1ss = 1.0 / ( numpy.exp((-((2.5538 * ko + v) + 144.59)) / (1.5692 * ko + 3.8115)) + 1.0 ) - EK = ((R * T) / F) * numpy.log(ko / ki) vffrt = (F * (F * v)) / ((R * T)) vfrt = (F * v) / ((R * T)) + EK = ((R * T) / F) * numpy.log(ko / ki) EKs = ((R * T) / F) * numpy.log((PKNa * nao + ko) / (PKNa * nai + ki)) ENa = ((R * T) / F) * numpy.log(nao / nai) GK1 = scale_HF_GK1 * ((0.1908 * scale_IK1) * scale_drug_IK1) @@ -810,15 +1549,31 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): GNaL = scale_HF_GNaL * ((0.0075 * scale_INaL) * scale_drug_INaL) km2n = 1.0 * jca IpCa = (cai * (GpCa * scale_drug_IpCa)) / (cai + 0.0005) - Istim = 0 # (amp) * (duration >= t) + (0) * numpy.logical_not((duration >= t)) + lambda_min12 = numpy.where((lmbda < 1.2), lmbda, 1.2) + Isac_P_k = numpy.where( + (lmbda < 1.0), + 0.0, + (Gsac_k * ((lmbda - 1.0) / (lambda_max - 1.0))) + * (1.0 / (numpy.exp((19.05 - v) / 29.98) + 1.0)), + ) + Isac_P_ns = numpy.where( + (lmbda < 1.0), + 0.0, + (Gsac_ns * ((lmbda - 1.0) / (lambda_max - 1.0))) * (-Esac_ns + v), + ) + Istim = numpy.where((duration >= t), amp, 0) JdiffK = (-ki + kss) / 2.0 JdiffNa = (-nai + nass) / 2.0 - Jleak = ((0.0039375 * cansr) * scale_HF_Jleak) / 15.0 Jtr = (-cajsr + cansr) / 100.0 + Jleak = ((0.0039375 * cansr) * scale_HF_Jleak) / 15.0 Knai = Knai0 * numpy.exp((F * (delta * v)) / (((3.0 * R) * T))) Knao = Knao0 * numpy.exp((F * (v * (1.0 - delta))) / (((3.0 * R) * T))) P = eP / (((H / Khp + 1.0) + nai / Knap) + ki / Kxkur) PCa = (0.0001 * scale_ICaL) * scale_drug_ICaL + XS_max = numpy.where((XS > 0), XS, 0) + zetas1 = Zetas * numpy.where((Zetas > 0), 1.0, 0.0) + zetas2 = (-Zetas - 1.0) * numpy.where((Zetas < -1.0), 1.0, 0.0) + XW_max = numpy.where((XW > 0), XW, 0) XU = -XW + (-XS + (1 - TmB)) a2 = k2p a4 = ((MgATP * k4p) / Kmgatp) / (1.0 + MgATP / Kmgatp) @@ -828,20 +1583,15 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): allo_i = 1.0 / ((KmCaAct / cai) ** 2.0 + 1.0) allo_ss = 1.0 / ((KmCaAct / cass) ** 2.0 + 1.0) b1 = MgADP * k1m - ksu = (kws * rw) * (-1 + 1 / rs) cs = ((kws * phi) * (rw * (1 - rs))) / rs + ksu = (kws * rw) * (-1 + 1 / rs) cw = ((kuw * phi) * ((1 - rs) * (1 - rw))) / ((rw * (1 - rs))) kwu = kuw * (-1 + 1 / rw) - kws - gammasu = gammas * numpy.where( - Zetas * (Zetas > 0) > (-1 - Zetas) * (Zetas < -1), - Zetas * (Zetas > 0), - (-1 - Zetas) * (Zetas < -1), - ) gammawu = gammaw * numpy.abs(Zetaw) - h4 = (nass / kna1) * (1 + nass / kna2) + 1.0 - h4_i = (nai / kna1) * (1 + nai / kna2) + 1.0 h10 = (nao / kna1) * (1 + nao / kna2) + (kasymm + 1.0) h10_i = (nao / kna1) * (1.0 + nao / kna2) + (kasymm + 1.0) + h4 = (nass / kna1) * (1 + nass / kna2) + 1.0 + h4_i = (nai / kna1) * (1 + nai / kna2) + 1.0 hca = numpy.exp((F * (qca * v)) / ((R * T))) hna = numpy.exp((F * (qna * v)) / ((R * T))) k2 = kcaoff @@ -849,9 +1599,6 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): k5 = kcaoff k5_i = kcaoff kb = (Trpn50**ntm * ku) / (-rw * (1 - rs) + (1 - rs)) - lambda_min12 = (lmbda) * (lmbda < 1.2) + (1.2) * numpy.logical_not( - (lmbda < 1.2), - ) thLp = scale_HF_thL * (3.0 * thL) tiF = ( delta_epi @@ -962,13 +1709,15 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): CaMKa = scale_HF_CaMKa * (CaMKb + CaMKt) dCaMKt_dt = -CaMKt * bCaMK + (CaMKb * aCaMK) * (CaMKb + CaMKt) dCaMKt_dt_linearized = CaMKb * aCaMK - bCaMK - values[12] = ( - CaMKt - + dCaMKt_dt + values[12] = CaMKt + numpy.where( + numpy.logical_or( + (dCaMKt_dt_linearized > 1e-08), + (dCaMKt_dt_linearized < -1e-08), + ), + dCaMKt_dt * (numpy.exp(dCaMKt_dt_linearized * dt) - 1) - / dCaMKt_dt_linearized - * (numpy.abs(dCaMKt_dt_linearized) > 1e-08) - + dCaMKt_dt * dt * (~(numpy.abs(dCaMKt_dt_linearized) > 1e-08)) + / dCaMKt_dt_linearized, + dCaMKt_dt * dt, ) dxk1_dt = (-xk1 + xk1ss) / txk1 dxk1_dt_linearized = -1 / txk1 @@ -976,7 +1725,6 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): dxk1_dt * (numpy.exp(dt * dxk1_dt_linearized) - 1) / dxk1_dt_linearized + xk1 ) - IKb = (xkb * (GKb * scale_drug_IKb)) * (-EK + v) ICab = ( (vffrt * (4.0 * (PCab * scale_drug_ICab))) * (cai * numpy.exp(2.0 * vfrt) - 0.341 * cao) @@ -993,9 +1741,13 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): PhiCaNa = ( (1.0 * vffrt) * (-0.75 * nao + (0.75 * nass) * numpy.exp(1.0 * vfrt)) ) / (numpy.exp(1.0 * vfrt) - 1.0) + IKb = (xkb * (GKb * scale_drug_IKb)) * (-EK + v) IK1 = (xk1 * (rk1 * (GK1 * math.sqrt(ko)))) * (-EK + v) IKs = (xs2 * (xs1 * (GKs * KsCa))) * (-EKs + v) anca = 1.0 / (k2n / km2n + (Kmn / cass + 1.0) ** 4.0) + C = lambda_min12 - 1 + cat50 = scale_HF_cat50_ref * (Beta1 * (lambda_min12 - 1) + cat50_ref) + lambda_min087 = numpy.where((lambda_min12 < 0.87), lambda_min12, 0.87) a1 = (k1p * (nai / Knai) ** 3.0) / ( ((1.0 + ki / Kki) ** 2.0 + (1.0 + nai / Knai) ** 3.0) - 1.0 ) @@ -1012,49 +1764,37 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): PCaK = 0.0003574 * PCa PCaNa = 0.00125 * PCa PCap = 1.1 * PCa + gammasu = gammas * numpy.where((zetas1 > zetas2), zetas1, zetas2) a_relp = 0.5 * btp tau_relp_tmp = btp / (1.0 + 0.0123 / cajsr) - tau_rel = (0.001) * (tau_rel_tmp < 0.001) + (tau_rel_tmp) * numpy.logical_not( - (tau_rel_tmp < 0.001), - ) + tau_rel = numpy.where((tau_rel_tmp < 0.001), 0.001, tau_rel_tmp) dZetaw_dt = Aw * dLambda - Zetaw * cw dZetaw_dt_linearized = -cw - values[14] = ( - Zetaw - + dZetaw_dt + values[14] = Zetaw + numpy.where( + numpy.logical_or( + (dZetaw_dt_linearized > 1e-08), + (dZetaw_dt_linearized < -1e-08), + ), + dZetaw_dt * (numpy.exp(dZetaw_dt_linearized * dt) - 1) - / dZetaw_dt_linearized - * (numpy.abs(dZetaw_dt_linearized) > 1e-08) - + dZetaw_dt * dt * (~(numpy.abs(dZetaw_dt_linearized) > 1e-08)) - ) - dXS_dt = -XS * gammasu + (-XS * ksu + XW * kws) - dXS_dt_linearized = -gammasu - ksu - values[15] = ( - XS - + dXS_dt - * (numpy.exp(dXS_dt_linearized * dt) - 1) - / dXS_dt_linearized - * (numpy.abs(dXS_dt_linearized) > 1e-08) - + dXS_dt * dt * (~(numpy.abs(dXS_dt_linearized) > 1e-08)) + / dZetaw_dt_linearized, + dZetaw_dt * dt, ) dXW_dt = -XW * gammawu + (-XW * kws + (XU * kuw - XW * kwu)) dXW_dt_linearized = -gammawu - kws - kwu - values[16] = ( - XW - + dXW_dt - * (numpy.exp(dXW_dt_linearized * dt) - 1) - / dXW_dt_linearized - * (numpy.abs(dXW_dt_linearized) > 1e-08) - + dXW_dt * dt * (~(numpy.abs(dXW_dt_linearized) > 1e-08)) + values[15] = XW + numpy.where( + numpy.logical_or((dXW_dt_linearized > 1e-08), (dXW_dt_linearized < -1e-08)), + dXW_dt * (numpy.exp(dXW_dt_linearized * dt) - 1) / dXW_dt_linearized, + dXW_dt * dt, ) - h5 = (nass * nass) / ((kna2 * (h4 * kna1))) - h6 = 1.0 / h4 - h5_i = (nai * nai) / ((kna2 * (h4_i * kna1))) - h6_i = 1.0 / h4_i h11 = (nao * nao) / ((kna2 * (h10 * kna1))) h12 = 1.0 / h10 h11_i = (nao * nao) / ((kna2 * (h10_i * kna1))) h12_i = 1.0 / h10_i + h5 = (nass * nass) / ((kna2 * (h4 * kna1))) + h6 = 1.0 / h4 + h5_i = (nai * nai) / ((kna2 * (h4_i * kna1))) + h6_i = 1.0 / h4_i h1 = (nass / kna3) * (hna + 1) + 1 h1_i = (nai / kna3) * (hna + 1) + 1 h7 = (nao / kna3) * (1.0 + 1.0 / hna) + 1.0 @@ -1067,40 +1807,31 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): 100, ) ) - dTmB_dt_linearized = numpy.where( - numpy.isclose(CaTrpn, 0), - 0, - -(CaTrpn ** (ntm / 2)) * ku, + dTmB_dt_linearized = -(CaTrpn ** (ntm / 2)) * ku + values[16] = TmB + numpy.where( + numpy.logical_or( + (dTmB_dt_linearized > 1e-08), + (dTmB_dt_linearized < -1e-08), + ), + dTmB_dt * (numpy.exp(dTmB_dt_linearized * dt) - 1) / dTmB_dt_linearized, + dTmB_dt * dt, ) - values[17] = ( - TmB - + dTmB_dt - * (numpy.exp(dTmB_dt_linearized * dt) - 1) - / dTmB_dt_linearized - * (numpy.abs(dTmB_dt_linearized) > 1e-08) - + dTmB_dt * dt * (~(numpy.abs(dTmB_dt_linearized) > 1e-08)) - ) - C = lambda_min12 - 1 - cat50 = scale_HF_cat50_ref * (Beta1 * (lambda_min12 - 1) + cat50_ref) - lambda_min087 = (lambda_min12) * (lambda_min12 < 0.87) + ( - 0.87 - ) * numpy.logical_not((lambda_min12 < 0.87)) dhLp_dt = (-hLp + hLssp) / thLp dhLp_dt_linearized = -1 / thLp - values[18] = ( + values[17] = ( dhLp_dt * (numpy.exp(dhLp_dt_linearized * dt) - 1) / dhLp_dt_linearized + hLp ) tiFp = tiF * (dti_develop * dti_recover) diF_dt = (-iF + iss) / tiF diF_dt_linearized = -1 / tiF - values[19] = ( + values[18] = ( diF_dt * (numpy.exp(diF_dt_linearized * dt) - 1) / diF_dt_linearized + iF ) tiSp = tiS * (dti_develop * dti_recover) diS_dt = (-iS + iss) / tiS diS_dt_linearized = -1 / tiS - values[20] = ( + values[19] = ( diS_dt * (numpy.exp(diS_dt_linearized * dt) - 1) / diS_dt_linearized + iS ) fca = Afcaf * fcaf + Afcas * fcas @@ -1110,30 +1841,30 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): xr = Axrf * xrf + Axrs * xrs dfcaf_dt = (-fcaf + fcass) / tfcaf dfcaf_dt_linearized = -1 / tfcaf - values[21] = ( + values[20] = ( dfcaf_dt * (numpy.exp(dfcaf_dt_linearized * dt) - 1) / dfcaf_dt_linearized + fcaf ) dfcas_dt = (-fcas + fcass) / tfcas dfcas_dt_linearized = -1 / tfcas - values[22] = ( + values[21] = ( dfcas_dt * (numpy.exp(dfcas_dt_linearized * dt) - 1) / dfcas_dt_linearized + fcas ) djca_dt = (fcass - jca) / tjca djca_dt_linearized = -1 / tjca - values[23] = ( + values[22] = ( djca_dt * (numpy.exp(djca_dt_linearized * dt) - 1) / djca_dt_linearized + jca ) dj_dt = (-j + jss) / tj dj_dt_linearized = -1 / tj - values[24] = ( + values[23] = ( dj_dt * (numpy.exp(dj_dt_linearized * dt) - 1) / dj_dt_linearized + j ) dfcafp_dt = (-fcafp + fcass) / tfcafp dfcafp_dt_linearized = -1 / tfcafp - values[25] = ( + values[24] = ( dfcafp_dt * (numpy.exp(dfcafp_dt_linearized * dt) - 1) / dfcafp_dt_linearized @@ -1141,41 +1872,43 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): ) dffp_dt = (-ffp + fss) / tffp dffp_dt_linearized = -1 / tffp - values[26] = ( + values[25] = ( dffp_dt * (numpy.exp(dffp_dt_linearized * dt) - 1) / dffp_dt_linearized + ffp ) dhsp_dt = (-hsp + hssp) / thsp dhsp_dt_linearized = -1 / thsp - values[27] = ( + values[26] = ( dhsp_dt * (numpy.exp(dhsp_dt_linearized * dt) - 1) / dhsp_dt_linearized + hsp ) djp_dt = (-jp + jss) / tjp djp_dt_linearized = -1 / tjp - values[28] = ( + values[27] = ( djp_dt * (numpy.exp(djp_dt_linearized * dt) - 1) / djp_dt_linearized + jp ) dmL_dt = (-mL + mLss) / tmL dmL_dt_linearized = -1 / tmL - values[29] = ( + values[28] = ( dmL_dt * (numpy.exp(dmL_dt_linearized * dt) - 1) / dmL_dt_linearized + mL ) dxs2_dt = (-xs2 + xs2ss) / txs2 dxs2_dt_linearized = -1 / txs2 - values[30] = ( + values[29] = ( dxs2_dt * (numpy.exp(dt * dxs2_dt_linearized) - 1) / dxs2_dt_linearized + xs2 ) dZetas_dt = As * dLambda - Zetas * cs dZetas_dt_linearized = -cs - values[31] = ( - Zetas - + dZetas_dt + values[30] = Zetas + numpy.where( + numpy.logical_or( + (dZetas_dt_linearized > 1e-08), + (dZetas_dt_linearized < -1e-08), + ), + dZetas_dt * (numpy.exp(dZetas_dt_linearized * dt) - 1) - / dZetas_dt_linearized - * (numpy.abs(dZetas_dt_linearized) > 1e-08) - + dZetas_dt * dt * (~(numpy.abs(dZetas_dt_linearized) > 1e-08)) + / dZetas_dt_linearized, + dZetas_dt * dt, ) fICaLp = 1.0 / (1.0 + KmCaMK / CaMKa) fINaLp = 1.0 / (1.0 + KmCaMK / CaMKa) @@ -1185,27 +1918,47 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): fJupp = 1.0 / (1.0 + KmCaMK / CaMKa) dnca_dt = anca * k2n - km2n * nca dnca_dt_linearized = -km2n - values[32] = ( - nca - + dnca_dt - * (numpy.exp(dnca_dt_linearized * dt) - 1) - / dnca_dt_linearized - * (numpy.abs(dnca_dt_linearized) > 1e-08) - + dnca_dt * dt * (~(numpy.abs(dnca_dt_linearized) > 1e-08)) + values[31] = nca + numpy.where( + numpy.logical_or( + (dnca_dt_linearized > 1e-08), + (dnca_dt_linearized < -1e-08), + ), + dnca_dt * (numpy.exp(dnca_dt_linearized * dt) - 1) / dnca_dt_linearized, + dnca_dt * dt, + ) + F1 = numpy.exp(C * p_b) - 1 + dCd = C - Cd + dCaTrpn_dt = ktrpn * (-CaTrpn + ((1000 * cai) / cat50) ** ntrpn * (1 - CaTrpn)) + dCaTrpn_dt_linearized = ktrpn * (-(((1000 * cai) / cat50) ** ntrpn) - 1) + values[32] = CaTrpn + numpy.where( + numpy.logical_or( + (dCaTrpn_dt_linearized > 1e-08), + (dCaTrpn_dt_linearized < -1e-08), + ), + dCaTrpn_dt + * (numpy.exp(dCaTrpn_dt_linearized * dt) - 1) + / dCaTrpn_dt_linearized, + dCaTrpn_dt * dt, ) + h_lambda_prima = Beta0 * ((lambda_min087 + lambda_min12) - 1.87) + 1 x2 = b4 * (a2 * a3) + (b4 * (a3 * b1) + (a3 * (a1 * a2) + b4 * (b1 * b2))) x1 = a2 * (a1 * b3) + (b3 * (a2 * b4) + (a2 * (a1 * a4) + b3 * (b2 * b4))) x3 = b1 * (a3 * a4) + (a4 * (b1 * b2) + (a4 * (a2 * a3) + b1 * (b2 * b3))) x4 = a1 * (b2 * b3) + (a1 * (a4 * b2) + (a1 * (a3 * a4) + b2 * (b3 * b4))) PCaKp = 0.0003574 * PCap PCaNap = 0.00125 * PCap - tau_relp = (0.001) * (tau_relp_tmp < 0.001) + ( - tau_relp_tmp - ) * numpy.logical_not((tau_relp_tmp < 0.001)) - k6 = kcaon * (cass * h6) - k6_i = kcaon * (cai * h6_i) + dXS_dt = -XS * gammasu + (-XS * ksu + XW * kws) + dXS_dt_linearized = -gammasu - ksu + values[33] = XS + numpy.where( + numpy.logical_or((dXS_dt_linearized > 1e-08), (dXS_dt_linearized < -1e-08)), + dXS_dt * (numpy.exp(dXS_dt_linearized * dt) - 1) / dXS_dt_linearized, + dXS_dt * dt, + ) + tau_relp = numpy.where((tau_relp_tmp < 0.001), 0.001, tau_relp_tmp) k1 = kcaon * (cao * h12) k1_i = kcaon * (cao * h12_i) + k6 = kcaon * (cass * h6) + k6_i = kcaon * (cai * h6_i) h2 = (hna * nass) / ((h1 * kna3)) h3 = 1.0 / h1 h2_i = (hna * nai) / ((h1_i * kna3)) @@ -1214,20 +1967,6 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): h9 = 1.0 / h7 h8_i = nao / ((h7_i * (hna * kna3))) h9_i = 1.0 / h7_i - # F1 = numpy.exp(C * p_b) - 1 - dCd = C - Cd - - dCaTrpn_dt = ktrpn * (-CaTrpn + ((1000 * cai) / cat50) ** ntrpn * (1 - CaTrpn)) - dCaTrpn_dt_linearized = ktrpn * (-(((1000 * cai) / cat50) ** ntrpn) - 1) - values[33] = ( - CaTrpn - + dCaTrpn_dt - * (numpy.exp(dCaTrpn_dt_linearized * dt) - 1) - / dCaTrpn_dt_linearized - * (numpy.abs(dCaTrpn_dt_linearized) > 1e-08) - + dCaTrpn_dt * dt * (~(numpy.abs(dCaTrpn_dt_linearized) > 1e-08)) - ) - # h_lambda_prima = Beta0 * ((lambda_min087 + lambda_min12) - 1.87) + 1 diFp_dt = (-iFp + iss) / tiFp diFp_dt_linearized = -1 / tiFp values[34] = ( @@ -1253,6 +1992,9 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): ) Jrel = Jrelnp * (1.0 - fJrelp) + Jrelp * fJrelp Jup = -Jleak + (Jupnp * (1.0 - fJupp) + scale_HF_Jup * (Jupp * fJupp)) + eta = numpy.where((dCd < 0), etas, etal) + J_TRPN = dCaTrpn_dt * trpnmax + h_lambda = numpy.where((h_lambda_prima > 0), h_lambda_prima, 0) E1 = x1 / (x4 + (x3 + (x1 + x2))) E2 = x2 / (x4 + (x3 + (x1 + x2))) E3 = x3 / (x4 + (x3 + (x1 + x2))) @@ -1277,11 +2019,6 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): k3pp_i = h8_i * wnaca k8_i = wna * (h11_i * h8_i) k3p_i = h9_i * wca - eta = (etas) * (dCd < 0) + (etal) * numpy.logical_not((dCd < 0)) - J_TRPN = dCaTrpn_dt * trpnmax - # h_lambda = (h_lambda_prima) * (h_lambda_prima > 0) + (0) * numpy.logical_not( - # (h_lambda_prima > 0), - # ) Jrel_inf = ((-ICaL) * a_rel) / ( ((1.5 * scale_HF_Jrel_inf) / cajsr) ** 8.0 + 1.0 ) @@ -1292,26 +2029,23 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): values[36] = cajsr + dcajsr_dt * dt dcansr_dt = Jup - (Jtr * vjsr) / vnsr values[37] = cansr + dcansr_dt * dt + Fd = dCd * eta + dCd_dt = (p_k * (C - Cd)) / eta + dCd_dt_linearized = -p_k / eta + values[38] = Cd + numpy.where( + numpy.logical_or((dCd_dt_linearized > 1e-08), (dCd_dt_linearized < -1e-08)), + dCd_dt * (numpy.exp(dCd_dt_linearized * dt) - 1) / dCd_dt_linearized, + dCd_dt * dt, + ) + Ta = (h_lambda * (Tref / rs)) * (XS * (Zetas + 1) + XW * Zetaw) JnakNa = 3.0 * (E1 * a3 - E2 * b3) JnakK = 2.0 * (-E3 * a1 + E4 * b1) dkss_dt = -JdiffK + (Acap * (-ICaK)) / ((F * vss)) - values[38] = dkss_dt * dt + kss + values[39] = dkss_dt * dt + kss k4 = k4p_ss + k4pp k4_i = k4p_i + k4pp_i k3 = k3p_ss + k3pp k3_i = k3p_i + k3pp_i - # Fd = dCd * eta - dCd_dt = (p_k * (C - Cd)) / eta - dCd_dt_linearized = -p_k / eta - values[39] = ( - Cd - + dCd_dt - * (numpy.exp(dCd_dt_linearized * dt) - 1) - / dCd_dt_linearized - * (numpy.abs(dCd_dt_linearized) > 1e-08) - + dCd_dt * dt * (~(numpy.abs(dCd_dt_linearized) > 1e-08)) - ) - # Ta = (h_lambda * (Tref / rs)) * (XS * (Zetas + 1) + XW * Zetaw) dJrelnp_dt = (Jrel_inf - Jrelnp) / tau_rel dJrelnp_dt_linearized = -1 / tau_rel values[40] = ( @@ -1328,6 +2062,7 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): * (numpy.exp(dJrelp_dt_linearized * dt) - 1) / dJrelp_dt_linearized ) + Tp = p_a * (F1 + Fd) INaK = (Pnak * scale_HF_Pnak) * (JnakK * zk + JnakNa * zna) x2_ss = (k1 * k7) * (k4 + k5) + (k4 * k6) * (k1 + k8) x2_i = (k1_i * k7_i) * (k4_i + k5_i) + (k4_i * k6_i) * (k1_i + k8_i) @@ -1337,7 +2072,7 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): x1_i = (k2_i * k4_i) * (k6_i + k7_i) + (k5_i * k7_i) * (k2_i + k3_i) x3_i = (k1_i * k3_i) * (k6_i + k7_i) + (k6_i * k8_i) * (k2_i + k3_i) x4_i = (k2_i * k8_i) * (k4_i + k5_i) + (k3_i * k5_i) * (k1_i + k8_i) - # Tp = p_a * (F1 + Fd) + Ttot = Ta + Tp dki_dt = ( Acap * ( @@ -1461,1664 +2196,6 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): ) values[47] = dt * dv_dt + v - return numpy.nan_to_num(values, nan=0.0) + return values return forward_generalized_rush_larsen_ - - -# def Max(a, b): -# return (a + b + abs(a - b)) / Constant(2.0) - - -# def Min(a, b): -# return (a + b - abs(a - b)) / Constant(2.0) - - -# class ORdmmLandExplicit(BaseCellModel): -# def __init__( -# self, -# coupling: EMCoupling, -# params=None, -# init_conditions=None, -# ): -# """ -# Create cardiac cell model - -# *Arguments* -# params (dict, :py:class:`dolfin.Mesh`, optional) -# optional model parameters -# init_conditions (dict, :py:class:`dolfin.Mesh`, optional) -# optional initial conditions -# """ -# logger.debug("Initialize ORdmm Land model") - -# super().__init__(params, init_conditions) -# self.lmbda = coupling.lmbda_ep -# self.dLambda = coupling.dLambda_ep - -# @staticmethod -# def update_disease_parameters( -# params: Dict[str, float], -# disease_state: str = "healthy", -# ) -> None: -# if disease_state.lower() == "hf": -# logger.info("Update scaling parameters for heart failure model") -# params["HF_scaling_CaMKa"] = 1.50 -# params["HF_scaling_Jrel_inf"] = pow(0.8, 8.0) -# params["HF_scaling_Jleak"] = 1.3 -# params["HF_scaling_Jup"] = 0.45 -# params["HF_scaling_GNaL"] = 1.3 -# params["HF_scaling_GK1"] = 0.68 -# params["HF_scaling_thL"] = 1.8 -# params["HF_scaling_Gto"] = 0.4 -# params["HF_scaling_Gncx"] = 1.6 -# params["HF_scaling_Pnak"] = 0.7 -# params["HF_scaling_cat50_ref"] = 0.6 - -# @staticmethod -# def default_parameters() -> Dict[str, float]: -# """Set-up and return default parameters. - -# Parameters -# ---------- -# disease_state : str, optional -# String with "hf" or "healthy", by default "healthy". -# If "hf", then parameters representing heart failure -# will be used. - -# Returns -# ------- -# OrderedDict -# Dictionary with default values -# """ -# params = OrderedDict( -# [ -# ("scale_ICaL", 1.018), -# ("scale_IK1", 1.414), -# ("scale_IKr", 1.119), -# ("scale_IKs", 1.648), -# ("scale_INaL", 2.274), -# ("celltype", 0), -# ("cao", 1.8), -# ("ko", 5.4), -# ("nao", 140.0), -# ("F", 96485.0), -# ("R", 8314.0), -# ("T", 310.0), -# ("L", 0.01), -# ("rad", 0.0011), -# ("Ahf", 0.99), -# ("GNa", 31), -# ("thL", 200.0), -# ("Gto", 0.02), -# ("delta_epi", 1.0), -# ("Aff", 0.6), -# ("Kmn", 0.002), -# ("k2n", 1000.0), -# ("tjca", 75.0), -# ("zca", 2.0), -# ("bt", 4.75), -# ("Beta0", 2.3), -# ("Beta1", -2.4), -# ("Tot_A", 25), -# ("Tref", 120), -# ("Trpn50", 0.35), -# ("calib", 1), -# ("cat50_ref", 0.805), -# ("emcoupling", 1), -# ("etal", 200), -# ("etas", 20), -# ("gammas", 0.0085), -# ("gammaw", 0.615), -# ("isacs", 0), -# ("ktrpn", 0.1), -# ("ku", 0.04), -# ("kuw", 0.182), -# ("kws", 0.012), -# ("mode", 1), -# ("ntm", 2.4), -# ("ntrpn", 2.0), -# ("p_a", 2.1), -# ("p_b", 9.1), -# ("p_k", 7.0), -# ("phi", 2.23), -# ("rs", 0.25), -# ("rw", 0.5), -# ("CaMKo", 0.05), -# ("KmCaM", 0.0015), -# ("KmCaMK", 0.15), -# ("aCaMK", 0.05), -# ("bCaMK", 0.00068), -# ("PKNa", 0.01833), -# ("Gncx", 0.0008), -# ("KmCaAct", 0.00015), -# ("kasymm", 12.5), -# ("kcaoff", 5000.0), -# ("kcaon", 1500000.0), -# ("kna1", 15.0), -# ("kna2", 5.0), -# ("kna3", 88.12), -# ("qca", 0.167), -# ("qna", 0.5224), -# ("wca", 60000.0), -# ("wna", 60000.0), -# ("wnaca", 5000.0), -# ("H", 1e-07), -# ("Khp", 1.698e-07), -# ("Kki", 0.5), -# ("Kko", 0.3582), -# ("Kmgatp", 1.698e-07), -# ("Knai0", 9.073), -# ("Knao0", 27.78), -# ("Knap", 224.0), -# ("Kxkur", 292.0), -# ("MgADP", 0.05), -# ("MgATP", 9.8), -# ("Pnak", 30.0), -# ("delta", -0.155), -# ("eP", 4.2), -# ("k1m", 182.4), -# ("k1p", 949.5), -# ("k2m", 39.4), -# ("k2p", 687.2), -# ("k3m", 79300.0), -# ("k3p", 1899.0), -# ("k4m", 40.0), -# ("k4p", 639.0), -# ("zk", 1.0), -# ("GKb", 0.003), -# ("PNab", 3.75e-10), -# ("PCab", 2.5e-08), -# ("GpCa", 0.0005), -# ("Esac_ns", -10.0), -# ("Gsac_k", 1.097904761904762), -# ("Gsac_ns", 0.006), -# ("lambda_max", 1.1), -# ("amp", -80.0), -# ("duration", 0.5), -# ("BSLmax", 1.124), -# ("BSRmax", 0.047), -# ("KmBSL", 0.0087), -# ("KmBSR", 0.00087), -# ("cmdnmax", 0.05), -# ("csqnmax", 10.0), -# ("kmcmdn", 0.00238), -# ("kmcsqn", 0.8), -# ("kmtrpn", 0.0005), -# ("trpnmax", 0.07), -# # Drug factors -# ("scale_drug_INa", 1.0), -# ("scale_drug_INaL", 1.0), -# ("scale_drug_Ito", 1.0), -# ("scale_drug_ICaL", 1.0), -# ("scale_drug_IKr", 1.0), -# ("scale_drug_IKs", 1.0), -# ("scale_drug_IK1", 1.0), -# ("scale_drug_IKb", 1.0), -# ("scale_drug_INab", 1.0), -# ("scale_drug_ICab", 1.0), -# ("scale_drug_IpCa", 1.0), -# ("scale_drug_Isacns", 1.0), -# ("scale_drug_Isack", 1.0), -# # Population factors -# ("scale_popu_GNa", 1.0), -# ("scale_popu_GCaL", 1.0), -# ("scale_popu_Gto", 1.0), -# ("scale_popu_GNaL", 1.0), -# ("scale_popu_GKr", 1.0), -# ("scale_popu_GKs", 1.0), -# ("scale_popu_GK1", 1.0), -# ("scale_popu_GbK", 1.0), -# ("scale_popu_KNCX", 1.0), -# ("scale_popu_KNaK", 1.0), -# ("scale_popu_GbNa", 1.0), -# ("scale_popu_GbCa", 1.0), -# ("scale_popu_KpCa", 1.0), -# ("scale_popu_KRyR", 1.0), -# ("scale_popu_KSERCA", 1.0), -# ("scale_popu_Kleak", 1.0), -# ("scale_popu_nTm", 1.0), -# ("scale_popu_CaT50ref", 1.0), -# ("scale_popu_Tref", 1.0), -# ("scale_popu_kuw", 1.0), -# ("scale_popu_kws", 1.0), -# ("scale_popu_kTRPN", 1.0), -# ("scale_popu_nTRPN", 1.0), -# ("scale_popu_ku", 1.0), -# ("scale_popu_TRPN50", 1.0), -# ("scale_popu_rw", 1.0), -# ("scale_popu_rs", 1.0), -# # HF scaling factors -# ("HF_scaling_CaMKa", 1.0), -# ("HF_scaling_Jrel_inf", 1.0), -# ("HF_scaling_Jleak", 1.0), -# ("HF_scaling_Jup", 1.0), -# ("HF_scaling_GNaL", 1.0), -# ("HF_scaling_GK1", 1.0), -# ("HF_scaling_thL", 1.0), -# ("HF_scaling_Gto", 1.0), -# ("HF_scaling_Gncx", 1.0), -# ("HF_scaling_Pnak", 1.0), -# ("HF_scaling_cat50_ref", 1.0), -# ], -# ) - -# return params - -# @staticmethod -# def default_initial_conditions(): -# "Set-up and return default initial conditions." -# ic = OrderedDict( -# [ -# ("v", -87), -# ("CaMKt", 0), -# ("m", 0), -# ("hf", 1), -# ("hs", 1), -# ("j", 1), -# ("hsp", 1), -# ("jp", 1), -# ("mL", 0), -# ("hL", 1), -# ("hLp", 1), -# ("a", 0), -# ("iF", 1), -# ("iS", 1), -# ("ap", 0), -# ("iFp", 1), -# ("iSp", 1), -# ("d", 0), -# ("ff", 1), -# ("fs", 1), -# ("fcaf", 1), -# ("fcas", 1), -# ("jca", 1), -# ("ffp", 1), -# ("fcafp", 1), -# ("nca", 0), -# ("xrf", 0), -# ("xrs", 0), -# ("xs1", 0), -# ("xs2", 0), -# ("xk1", 1), -# ("Jrelnp", 0), -# ("Jrelp", 0), -# ("nai", 7), -# ("nass", 7), -# ("ki", 145), -# ("kss", 145), -# ("cass", 0.0001), -# ("cansr", 1.2), -# ("cajsr", 1.2), -# ("XS", 0), -# ("XW", 0), -# ("CaTrpn", 0), -# ("TmB", 1), -# ("Cd", 0), -# ("cai", 0.0001), -# ("Zetas", 0), -# ("Zetaw", 0), -# ], -# ) -# return ic - -# def _I(self, v, s, time): -# """ -# Original gotran transmembrane current dV/dt -# """ -# time = time if time else Constant(0.0) -# logger.debug("Evaluate transmembrane current") -# # Assign states -# assert len(s) == 47 -# ( -# CaMKt, -# m, -# hf, -# hs, -# j, -# hsp, -# jp, -# mL, -# hL, -# hLp, -# a, -# iF, -# iS, -# ap, -# iFp, -# iSp, -# d, -# ff, -# fs, -# fcaf, -# fcas, -# jca, -# ffp, -# fcafp, -# nca, -# xrf, -# xrs, -# xs1, -# xs2, -# xk1, -# Jrelnp, -# Jrelp, -# nai, -# nass, -# ki, -# kss, -# cass, -# cansr, -# cajsr, -# XS, -# XW, -# CaTrpn, -# TmB, -# Cd, -# cai, -# Zetas, -# Zetaw, -# ) = s - -# # Assign parameters -# scale_ICaL = self._parameters["scale_ICaL"] -# scale_IK1 = self._parameters["scale_IK1"] -# scale_IKr = self._parameters["scale_IKr"] -# scale_IKs = self._parameters["scale_IKs"] -# scale_INaL = self._parameters["scale_INaL"] -# cao = self._parameters["cao"] -# ko = self._parameters["ko"] -# nao = self._parameters["nao"] -# F = self._parameters["F"] -# R = self._parameters["R"] -# T = self._parameters["T"] -# CaMKo = self._parameters["CaMKo"] -# KmCaM = self._parameters["KmCaM"] -# KmCaMK = self._parameters["KmCaMK"] -# PKNa = self._parameters["PKNa"] -# Ahf = self._parameters["Ahf"] -# GNa = self._parameters["GNa"] -# Gto = self._parameters["Gto"] -# Aff = self._parameters["Aff"] -# zca = self._parameters["zca"] -# Gncx = self._parameters["Gncx"] -# KmCaAct = self._parameters["KmCaAct"] -# kasymm = self._parameters["kasymm"] -# kcaoff = self._parameters["kcaoff"] -# kcaon = self._parameters["kcaon"] -# kna1 = self._parameters["kna1"] -# kna2 = self._parameters["kna2"] -# kna3 = self._parameters["kna3"] -# qca = self._parameters["qca"] -# qna = self._parameters["qna"] -# wca = self._parameters["wca"] -# wna = self._parameters["wna"] -# wnaca = self._parameters["wnaca"] -# H = self._parameters["H"] -# Khp = self._parameters["Khp"] -# Kki = self._parameters["Kki"] -# Kko = self._parameters["Kko"] -# Kmgatp = self._parameters["Kmgatp"] -# Knai0 = self._parameters["Knai0"] -# Knao0 = self._parameters["Knao0"] -# Knap = self._parameters["Knap"] -# Kxkur = self._parameters["Kxkur"] -# MgADP = self._parameters["MgADP"] -# MgATP = self._parameters["MgATP"] -# Pnak = self._parameters["Pnak"] -# delta = self._parameters["delta"] -# eP = self._parameters["eP"] -# k1m = self._parameters["k1m"] -# k1p = self._parameters["k1p"] -# k2m = self._parameters["k2m"] -# k2p = self._parameters["k2p"] -# k3m = self._parameters["k3m"] -# k3p = self._parameters["k3p"] -# k4m = self._parameters["k4m"] -# k4p = self._parameters["k4p"] -# zk = self._parameters["zk"] -# GKb = self._parameters["GKb"] -# PNab = self._parameters["PNab"] -# PCab = self._parameters["PCab"] -# GpCa = self._parameters["GpCa"] -# # Drug factor -# scale_drug_INa = self._parameters["scale_drug_INa"] -# scale_drug_INaL = self._parameters["scale_drug_INaL"] -# scale_drug_Ito = self._parameters["scale_drug_Ito"] -# scale_drug_ICaL = self._parameters["scale_drug_ICaL"] -# scale_drug_IKr = self._parameters["scale_drug_IKr"] -# scale_drug_IKs = self._parameters["scale_drug_IKs"] -# scale_drug_IK1 = self._parameters["scale_drug_IK1"] -# scale_drug_IKb = self._parameters["scale_drug_IKb"] -# scale_drug_INab = self._parameters["scale_drug_INab"] -# scale_drug_ICab = self._parameters["scale_drug_ICab"] -# scale_drug_IpCa = self._parameters["scale_drug_IpCa"] -# scale_drug_Isacns = self._parameters["scale_drug_Isacns"] -# scale_drug_Isack = self._parameters["scale_drug_Isack"] -# # Population factors -# scale_popu_GNa = self._parameters["scale_popu_GNa"] -# scale_popu_GCaL = self._parameters["scale_popu_GCaL"] -# scale_popu_Gto = self._parameters["scale_popu_Gto"] -# scale_popu_GNaL = self._parameters["scale_popu_GNaL"] -# scale_popu_GKr = self._parameters["scale_popu_GKr"] -# scale_popu_GKs = self._parameters["scale_popu_GKs"] -# scale_popu_GK1 = self._parameters["scale_popu_GK1"] -# scale_popu_GbK = self._parameters["scale_popu_GbK"] -# scale_popu_KNCX = self._parameters["scale_popu_KNCX"] -# scale_popu_KNaK = self._parameters["scale_popu_KNaK"] -# scale_popu_GbNa = self._parameters["scale_popu_GbNa"] -# scale_popu_GbCa = self._parameters["scale_popu_GbCa"] -# scale_popu_KpCa = self._parameters["scale_popu_KpCa"] -# # Systolic Heart Failure (HF with preserved ejection fraction) -# HF_scaling_CaMKa = self._parameters["HF_scaling_CaMKa"] -# HF_scaling_GNaL = self._parameters["HF_scaling_GNaL"] -# HF_scaling_GK1 = self._parameters["HF_scaling_GK1"] -# HF_scaling_Gto = self._parameters["HF_scaling_Gto"] -# HF_scaling_Gncx = self._parameters["HF_scaling_Gncx"] -# HF_scaling_Pnak = self._parameters["HF_scaling_Pnak"] - -# # Init return args -# current = [ufl.zero()] * 1 - -# # Expressions for the CaMKt component -# CaMKb = CaMKo * (1.0 - CaMKt) / (1.0 + KmCaM / cass) -# CaMKa = (CaMKb + CaMKt) * HF_scaling_CaMKa - -# # Expressions for the reversal potentials component -# ENa = R * T * ufl.ln(nao / nai) / F -# EK = R * T * ufl.ln(ko / ki) / F -# EKs = R * T * ufl.ln((ko + PKNa * nao) / (PKNa * nai + ki)) / F -# vffrt = (F * F) * v / (R * T) -# vfrt = F * v / (R * T) - -# # Expressions for the I_Na component -# Ahs = 1.0 - Ahf -# h = Ahf * hf + Ahs * hs -# hp = Ahf * hf + Ahs * hsp -# fINap = 1.0 / (1.0 + KmCaMK / CaMKa) -# INa = ( -# GNa -# * scale_drug_INa -# * scale_popu_GNa -# * ufl.elem_pow(m, 3.0) -# * (-ENa + v) -# * ((1.0 - fINap) * h * j + fINap * hp * jp) -# ) - -# # Expressions for the INaL component -# GNaL = 0.0075 * scale_INaL * scale_drug_INaL * scale_popu_GNaL * HF_scaling_GNaL -# fINaLp = 1.0 / (1.0 + KmCaMK / CaMKa) -# INaL = (-ENa + v) * ((1.0 - fINaLp) * hL + fINaLp * hLp) * GNaL * mL - -# # Expressions for the Ito component -# AiF = 1.0 / (1.0 + 0.24348537187522867 * ufl.exp(0.006613756613756614 * v)) -# AiS = 1.0 - AiF -# i = AiF * iF + AiS * iS -# ip = AiF * iFp + AiS * iSp -# fItop = 1.0 / (1.0 + KmCaMK / CaMKa) -# Ito = ( -# Gto -# * scale_drug_Ito -# * scale_popu_Gto -# * HF_scaling_Gto -# * (-EK + v) -# * ((1.0 - fItop) * a * i + ap * fItop * ip) -# ) - -# # Expressions for the ICaL ICaNa ICaK component -# Afs = 1.0 - Aff -# f = Aff * ff + Afs * fs -# Afcaf = 0.3 + 0.6 / (1.0 + 0.36787944117144233 * ufl.exp(0.1 * v)) -# Afcas = 1.0 - Afcaf -# fca = Afcaf * fcaf + Afcas * fcas -# fp = Aff * ffp + Afs * fs -# fcap = Afcaf * fcafp + Afcas * fcas -# PhiCaL = ( -# 4.0 -# * (-0.341 * cao + cass * ufl.exp(2.0 * vfrt)) -# * vffrt -# / (-1.0 + ufl.exp(2.0 * vfrt)) -# ) -# PhiCaNa = ( -# 1.0 -# * (-0.75 * nao + 0.75 * ufl.exp(1.0 * vfrt) * nass) -# * vffrt -# / (-1.0 + ufl.exp(1.0 * vfrt)) -# ) -# PhiCaK = ( -# 1.0 -# * (-0.75 * ko + 0.75 * ufl.exp(1.0 * vfrt) * kss) -# * vffrt -# / (-1.0 + ufl.exp(1.0 * vfrt)) -# ) -# PCa = 0.0001 * scale_ICaL * scale_drug_ICaL * scale_popu_GCaL -# PCap = 1.1 * PCa -# PCaNa = 0.00125 * PCa -# PCaK = 0.0003574 * PCa -# PCaNap = 0.00125 * PCap -# PCaKp = 0.0003574 * PCap -# fICaLp = 1.0 / (1.0 + KmCaMK / CaMKa) -# ICaL = (1.0 - fICaLp) * ( -# (1.0 - nca) * f + fca * jca * nca -# ) * PCa * PhiCaL * d + ( -# (1.0 - nca) * fp + fcap * jca * nca -# ) * PCap * PhiCaL * d * fICaLp -# ICaNa = (1.0 - fICaLp) * ( -# (1.0 - nca) * f + fca * jca * nca -# ) * PCaNa * PhiCaNa * d + ( -# (1.0 - nca) * fp + fcap * jca * nca -# ) * PCaNap * PhiCaNa * d * fICaLp -# ICaK = (1.0 - fICaLp) * ( -# (1.0 - nca) * f + fca * jca * nca -# ) * PCaK * PhiCaK * d + ( -# (1.0 - nca) * fp + fcap * jca * nca -# ) * PCaKp * PhiCaK * d * fICaLp - -# # Expressions for the IKr component -# Axrf = 1.0 / (1.0 + 4.197299094734718 * ufl.exp(0.02617115938236064 * v)) -# Axrs = 1.0 - Axrf -# xr = Axrf * xrf + Axrs * xrs -# rkr = 1.0 / ( -# (1.0 + 2.0820090840784555 * ufl.exp(0.013333333333333334 * v)) -# * (1.0 + 0.7165313105737893 * ufl.exp(0.03333333333333333 * v)) -# ) -# GKr = 0.046 * scale_IKr * scale_drug_IKr * scale_popu_GKr -# IKr = 0.4303314829119352 * ufl.sqrt(ko) * (-EK + v) * GKr * rkr * xr - -# # Expressions for the IKs component -# KsCa = 1.0 + 0.6 / (1.0 + 6.481821026062645e-07 * ufl.elem_pow(1.0 / cai, 1.4)) -# GKs = 0.0034 * scale_IKs * scale_drug_IKs * scale_popu_GKs -# IKs = (-EKs + v) * GKs * KsCa * xs1 * xs2 -# rk1 = 1.0 / ( -# 1.0 -# + 69220.6322106767 -# * ufl.exp(0.10534077741493732 * v - 0.27388602127883704 * ko) -# ) -# GK1 = 0.1908 * scale_IK1 * scale_drug_IK1 * scale_popu_GK1 * HF_scaling_GK1 -# IK1 = ufl.sqrt(ko) * (-EK + v) * GK1 * rk1 * xk1 - -# # Expressions for the INaCa_i component -# hca = ufl.exp(F * qca * v / (R * T)) -# hna = ufl.exp(F * qna * v / (R * T)) -# h1_i = 1 + (1 + hna) * nai / kna3 -# h2_i = hna * nai / (kna3 * h1_i) -# h3_i = 1.0 / h1_i -# h4_i = 1.0 + (1 + nai / kna2) * nai / kna1 -# h5_i = (nai * nai) / (kna1 * kna2 * h4_i) -# h6_i = 1.0 / h4_i -# h7_i = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 -# h8_i = nao / (kna3 * h7_i * hna) -# h9_i = 1.0 / h7_i -# h10_i = 1.0 + kasymm + nao * (1.0 + nao / kna2) / kna1 -# h11_i = (nao * nao) / (kna1 * kna2 * h10_i) -# h12_i = 1.0 / h10_i -# k1_i = cao * kcaon * h12_i -# k2_i = kcaoff -# k3p_i = wca * h9_i -# k3pp_i = wnaca * h8_i -# k3_i = k3p_i + k3pp_i -# k4p_i = wca * h3_i / hca -# k4pp_i = wnaca * h2_i -# k4_i = k4p_i + k4pp_i -# k5_i = kcaoff -# k6_i = kcaon * cai * h6_i -# k7_i = wna * h2_i * h5_i -# k8_i = wna * h11_i * h8_i -# x1_i = (k2_i + k3_i) * k5_i * k7_i + (k6_i + k7_i) * k2_i * k4_i -# x2_i = (k1_i + k8_i) * k4_i * k6_i + (k4_i + k5_i) * k1_i * k7_i -# x3_i = (k2_i + k3_i) * k6_i * k8_i + (k6_i + k7_i) * k1_i * k3_i -# x4_i = (k1_i + k8_i) * k3_i * k5_i + (k4_i + k5_i) * k2_i * k8_i -# E1_i = x1_i / (x1_i + x2_i + x3_i + x4_i) -# E2_i = x2_i / (x1_i + x2_i + x3_i + x4_i) -# E3_i = x3_i / (x1_i + x2_i + x3_i + x4_i) -# E4_i = x4_i / (x1_i + x2_i + x3_i + x4_i) -# allo_i = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cai, 2.0)) -# zna = 1.0 -# JncxNa_i = E3_i * k4pp_i - E2_i * k3pp_i + 3.0 * E4_i * k7_i - 3.0 * E1_i * k8_i -# JncxCa_i = E2_i * k2_i - E1_i * k1_i -# INaCa_i = ( -# 0.8 -# * Gncx -# * scale_popu_KNCX -# * HF_scaling_Gncx -# * (zca * JncxCa_i + zna * JncxNa_i) -# * allo_i -# ) - -# # Expressions for the INaCa_ss component -# h1 = 1.0 + (1.0 + hna) * nass / kna3 -# h2 = hna * nass / (kna3 * h1) -# h3 = 1.0 / h1 -# h4 = 1.0 + (1 + nass / kna2) * nass / kna1 -# h5 = (nass * nass) / (kna1 * kna2 * h4) -# h6 = 1.0 / h4 -# h7 = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 -# h8 = nao / (kna3 * h7 * hna) -# h9 = 1.0 / h7 -# h10 = 1.0 + kasymm + nao * (1 + nao / kna2) / kna1 -# h11 = (nao * nao) / (kna1 * kna2 * h10) -# h12 = 1.0 / h10 -# k1 = cao * kcaon * h12 -# k2 = kcaoff -# k3p_ss = wca * h9 -# k3pp = wnaca * h8 -# k3 = k3p_ss + k3pp -# k4p_ss = wca * h3 / hca -# k4pp = wnaca * h2 -# k4 = k4p_ss + k4pp -# k5 = kcaoff -# k6 = kcaon * cass * h6 -# k7 = wna * h2 * h5 -# k8 = wna * h11 * h8 -# x1_ss = (k2 + k3) * k5 * k7 + (k6 + k7) * k2 * k4 -# x2_ss = (k1 + k8) * k4 * k6 + (k4 + k5) * k1 * k7 -# x3_ss = (k2 + k3) * k6 * k8 + (k6 + k7) * k1 * k3 -# x4_ss = (k1 + k8) * k3 * k5 + (k4 + k5) * k2 * k8 -# E1_ss = x1_ss / (x1_ss + x2_ss + x3_ss + x4_ss) -# E2_ss = x2_ss / (x1_ss + x2_ss + x3_ss + x4_ss) -# E3_ss = x3_ss / (x1_ss + x2_ss + x3_ss + x4_ss) -# E4_ss = x4_ss / (x1_ss + x2_ss + x3_ss + x4_ss) -# allo_ss = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cass, 2.0)) -# JncxNa_ss = E3_ss * k4pp - E2_ss * k3pp + 3.0 * E4_ss * k7 - 3.0 * E1_ss * k8 -# JncxCa_ss = E2_ss * k2 - E1_ss * k1 -# INaCa_ss = ( -# 0.2 -# * Gncx -# * scale_popu_KNCX -# * HF_scaling_Gncx -# * (zca * JncxCa_ss + zna * JncxNa_ss) -# * allo_ss -# ) - -# # Expressions for the INaK component -# Knai = Knai0 * ufl.exp(0.3333333333333333 * F * delta * v / (R * T)) -# Knao = Knao0 * ufl.exp(0.3333333333333333 * F * (1.0 - delta) * v / (R * T)) -# P = eP / (1.0 + H / Khp + nai / Knap + ki / Kxkur) -# a1 = ( -# k1p -# * ufl.elem_pow(nai / Knai, 3.0) -# / ( -# -1.0 -# + ufl.elem_pow(1.0 + ki / Kki, 2.0) -# + ufl.elem_pow(1.0 + nai / Knai, 3.0) -# ) -# ) -# b1 = MgADP * k1m -# a2 = k2p -# b2 = ( -# k2m -# * ufl.elem_pow(nao / Knao, 3.0) -# / ( -# -1.0 -# + ufl.elem_pow(1.0 + ko / Kko, 2.0) -# + ufl.elem_pow(1.0 + nao / Knao, 3.0) -# ) -# ) -# a3 = ( -# k3p -# * ufl.elem_pow(ko / Kko, 2.0) -# / ( -# -1.0 -# + ufl.elem_pow(1.0 + ko / Kko, 2.0) -# + ufl.elem_pow(1.0 + nao / Knao, 3.0) -# ) -# ) -# b3 = H * k3m * P / (1.0 + MgATP / Kmgatp) -# a4 = MgATP * k4p / (Kmgatp * (1.0 + MgATP / Kmgatp)) -# b4 = ( -# k4m -# * ufl.elem_pow(ki / Kki, 2.0) -# / ( -# -1.0 -# + ufl.elem_pow(1.0 + ki / Kki, 2.0) -# + ufl.elem_pow(1.0 + nai / Knai, 3.0) -# ) -# ) -# x1 = a1 * a2 * a4 + a1 * a2 * b3 + a2 * b3 * b4 + b2 * b3 * b4 -# x2 = a1 * a2 * a3 + a2 * a3 * b4 + a3 * b1 * b4 + b1 * b2 * b4 -# x3 = a2 * a3 * a4 + a3 * a4 * b1 + a4 * b1 * b2 + b1 * b2 * b3 -# x4 = a1 * a3 * a4 + a1 * a4 * b2 + a1 * b2 * b3 + b2 * b3 * b4 -# E1 = x1 / (x1 + x2 + x3 + x4) -# E2 = x2 / (x1 + x2 + x3 + x4) -# E3 = x3 / (x1 + x2 + x3 + x4) -# E4 = x4 / (x1 + x2 + x3 + x4) -# JnakNa = 3.0 * E1 * a3 - 3.0 * E2 * b3 -# JnakK = 2.0 * E4 * b1 - 2.0 * E3 * a1 -# INaK = Pnak * scale_popu_KNaK * HF_scaling_Pnak * (zk * JnakK + zna * JnakNa) - -# # Expressions for the IKb component -# xkb = 1.0 / (1.0 + 2.202363450949239 * ufl.exp(-0.05452562704471101 * v)) -# IKb = GKb * scale_popu_GbK * scale_drug_IKb * (-EK + v) * xkb - -# # Expressions for the INab component -# INab = ( -# PNab -# * scale_drug_INab -# * scale_popu_GbNa -# * (-nao + ufl.exp(vfrt) * nai) -# * vffrt -# / (-1.0 + ufl.exp(vfrt)) -# ) - -# # Expressions for the ICab component -# ICab = ( -# 4.0 -# * PCab -# * scale_drug_ICab -# * scale_popu_GbCa -# * (-0.341 * cao + cai * ufl.exp(2.0 * vfrt)) -# * vffrt -# / (-1.0 + ufl.exp(2.0 * vfrt)) -# ) - -# # Expressions for the IpCa component -# IpCa = GpCa * scale_drug_IpCa * scale_popu_KpCa * cai / (0.0005 + cai) - -# # Expressions for the Isac (Pueyo)--> ns + k component -# Gsac_ns = 0.006 * scale_drug_Isacns -# Esac_ns = -10.0 -# lambda_max = 1.1 -# Gsac_k = (0.2882 * 800.0 / 210.0) * scale_drug_Isack # Pueyo endo - -# Isac_P_ns = ufl.conditional( -# ufl.lt(self.lmbda, 1.0), -# 0.0, -# Gsac_ns * ((self.lmbda - 1.0) / (lambda_max - 1.0)) * (v - Esac_ns), -# ) -# Isac_P_k = ufl.conditional( -# ufl.lt(self.lmbda, 1.0), -# 0.0, -# Gsac_k -# * ((self.lmbda - 1.0) / (lambda_max - 1.0)) -# * (1.0 / (1.0 + ufl.exp((19.05 - v) / (29.98)))), -# ) - -# # Expressions for the Istim component -# Istim = 0 #0 # amp*(ufl.le(time, duration)) - -# # Expressions for the membrane potential component -# current[0] = ( -# -Isac_P_k -# - Isac_P_ns -# - ICaK -# - ICaL -# - ICaNa -# - ICab -# - IK1 -# - IKb -# - IKr -# - IKs -# - INa -# - INaCa_i -# - INaCa_ss -# - INaK -# - INaL -# - INab -# - IpCa -# - Istim -# - Ito -# ) - -# # Return results -# return current[0] - -# def I(self, v, s, time=None): # noqa: E741, E743 -# """ -# Transmembrane current - -# I = -dV/dt - -# """ -# return -self._I(v, s, time) - -# def F(self, v, s, time=None): -# """ -# Right hand side for ODE system -# """ -# logger.debug("Evaluate RHS") -# time = time if time else Constant(0.0) - -# # Assign states -# assert len(s) == 47 -# ( -# CaMKt, -# m, -# hf, -# hs, -# j, -# hsp, -# jp, -# mL, -# hL, -# hLp, -# a, -# iF, -# iS, -# ap, -# iFp, -# iSp, -# d, -# ff, -# fs, -# fcaf, -# fcas, -# jca, -# ffp, -# fcafp, -# nca, -# xrf, -# xrs, -# xs1, -# xs2, -# xk1, -# Jrelnp, -# Jrelp, -# nai, -# nass, -# ki, -# kss, -# cass, -# cansr, -# cajsr, -# XS, -# XW, -# CaTrpn, -# TmB, -# Cd, -# cai, -# Zetas, -# Zetaw, -# ) = s - -# # Assign parameters -# scale_ICaL = self._parameters["scale_ICaL"] -# scale_IK1 = self._parameters["scale_IK1"] -# scale_IKr = self._parameters["scale_IKr"] -# scale_IKs = self._parameters["scale_IKs"] -# scale_INaL = self._parameters["scale_INaL"] -# cao = self._parameters["cao"] -# ko = self._parameters["ko"] -# nao = self._parameters["nao"] -# F = self._parameters["F"] -# R = self._parameters["R"] -# T = self._parameters["T"] -# L = self._parameters["L"] -# rad = self._parameters["rad"] -# CaMKo = self._parameters["CaMKo"] -# KmCaM = self._parameters["KmCaM"] -# KmCaMK = self._parameters["KmCaMK"] -# aCaMK = self._parameters["aCaMK"] -# bCaMK = self._parameters["bCaMK"] -# PKNa = self._parameters["PKNa"] -# Ahf = self._parameters["Ahf"] -# GNa = self._parameters["GNa"] -# thL = self._parameters["thL"] -# Gto = self._parameters["Gto"] -# delta_epi = self._parameters["delta_epi"] -# Aff = self._parameters["Aff"] -# Kmn = self._parameters["Kmn"] -# k2n = self._parameters["k2n"] -# tjca = self._parameters["tjca"] -# zca = self._parameters["zca"] -# Gncx = self._parameters["Gncx"] -# KmCaAct = self._parameters["KmCaAct"] -# kasymm = self._parameters["kasymm"] -# kcaoff = self._parameters["kcaoff"] -# kcaon = self._parameters["kcaon"] -# kna1 = self._parameters["kna1"] -# kna2 = self._parameters["kna2"] -# kna3 = self._parameters["kna3"] -# qca = self._parameters["qca"] -# qna = self._parameters["qna"] -# wca = self._parameters["wca"] -# wna = self._parameters["wna"] -# wnaca = self._parameters["wnaca"] -# H = self._parameters["H"] -# Khp = self._parameters["Khp"] -# Kki = self._parameters["Kki"] -# Kko = self._parameters["Kko"] -# Kmgatp = self._parameters["Kmgatp"] -# Knai0 = self._parameters["Knai0"] -# Knao0 = self._parameters["Knao0"] -# Knap = self._parameters["Knap"] -# Kxkur = self._parameters["Kxkur"] -# MgADP = self._parameters["MgADP"] -# MgATP = self._parameters["MgATP"] -# Pnak = self._parameters["Pnak"] -# delta = self._parameters["delta"] -# eP = self._parameters["eP"] -# k1m = self._parameters["k1m"] -# k1p = self._parameters["k1p"] -# k2m = self._parameters["k2m"] -# k2p = self._parameters["k2p"] -# k3m = self._parameters["k3m"] -# k3p = self._parameters["k3p"] -# k4m = self._parameters["k4m"] -# k4p = self._parameters["k4p"] -# zk = self._parameters["zk"] -# GKb = self._parameters["GKb"] -# PNab = self._parameters["PNab"] -# PCab = self._parameters["PCab"] -# GpCa = self._parameters["GpCa"] -# bt = self._parameters["bt"] -# BSLmax = self._parameters["BSLmax"] -# BSRmax = self._parameters["BSRmax"] -# KmBSL = self._parameters["KmBSL"] -# KmBSR = self._parameters["KmBSR"] -# cmdnmax = self._parameters["cmdnmax"] -# csqnmax = self._parameters["csqnmax"] -# kmcmdn = self._parameters["kmcmdn"] -# kmcsqn = self._parameters["kmcsqn"] -# trpnmax = self._parameters["trpnmax"] -# Beta1 = self._parameters["Beta1"] -# Tot_A = self._parameters["Tot_A"] -# Trpn50 = self._parameters["Trpn50"] -# cat50_ref = self._parameters["cat50_ref"] -# # dLambda = self._parameters["dLambda"] -# etal = self._parameters["etal"] -# etas = self._parameters["etas"] -# gammas = self._parameters["gammas"] -# gammaw = self._parameters["gammaw"] -# ktrpn = self._parameters["ktrpn"] -# ku = self._parameters["ku"] -# kuw = self._parameters["kuw"] -# kws = self._parameters["kws"] -# # lmbda = self._parameters["lmbda"] -# ntm = self._parameters["ntm"] -# ntrpn = self._parameters["ntrpn"] -# p_k = self._parameters["p_k"] -# phi = self._parameters["phi"] -# rs = self._parameters["rs"] -# rw = self._parameters["rw"] - -# # Drug factor -# scale_drug_INa = self._parameters["scale_drug_INa"] -# scale_drug_INaL = self._parameters["scale_drug_INaL"] -# scale_drug_Ito = self._parameters["scale_drug_Ito"] -# scale_drug_ICaL = self._parameters["scale_drug_ICaL"] -# scale_drug_IKr = self._parameters["scale_drug_IKr"] -# scale_drug_IKs = self._parameters["scale_drug_IKs"] -# scale_drug_IK1 = self._parameters["scale_drug_IK1"] -# scale_drug_IKb = self._parameters["scale_drug_IKb"] -# scale_drug_INab = self._parameters["scale_drug_INab"] -# scale_drug_ICab = self._parameters["scale_drug_ICab"] -# scale_drug_IpCa = self._parameters["scale_drug_IpCa"] -# scale_drug_Isacns = self._parameters["scale_drug_Isacns"] -# scale_drug_Isack = self._parameters["scale_drug_Isack"] - -# # Population factors -# scale_popu_GNa = self._parameters["scale_popu_GNa"] -# scale_popu_GCaL = self._parameters["scale_popu_GCaL"] -# scale_popu_Gto = self._parameters["scale_popu_Gto"] -# scale_popu_GNaL = self._parameters["scale_popu_GNaL"] -# scale_popu_GKr = self._parameters["scale_popu_GKr"] -# scale_popu_GKs = self._parameters["scale_popu_GKs"] -# scale_popu_GK1 = self._parameters["scale_popu_GK1"] -# scale_popu_GbK = self._parameters["scale_popu_GbK"] -# scale_popu_KNCX = self._parameters["scale_popu_KNCX"] -# scale_popu_KNaK = self._parameters["scale_popu_KNaK"] -# scale_popu_GbNa = self._parameters["scale_popu_GbNa"] -# scale_popu_GbCa = self._parameters["scale_popu_GbCa"] -# scale_popu_KpCa = self._parameters["scale_popu_KpCa"] -# scale_popu_KRyR = self._parameters["scale_popu_KRyR"] -# scale_popu_KSERCA = self._parameters["scale_popu_KSERCA"] -# scale_popu_Kleak = self._parameters["scale_popu_Kleak"] -# scale_popu_nTm = self._parameters["scale_popu_nTm"] -# scale_popu_CaT50ref = self._parameters["scale_popu_CaT50ref"] -# scale_popu_kuw = self._parameters["scale_popu_kuw"] -# scale_popu_kws = self._parameters["scale_popu_kws"] -# scale_popu_kTRPN = self._parameters["scale_popu_kTRPN"] -# scale_popu_nTRPN = self._parameters["scale_popu_nTRPN"] -# scale_popu_ku = self._parameters["scale_popu_ku"] -# scale_popu_TRPN50 = self._parameters["scale_popu_TRPN50"] -# scale_popu_rw = self._parameters["scale_popu_rw"] -# scale_popu_rs = self._parameters["scale_popu_rs"] - -# # Systolic Heart Failure (HF with preserved ejection fraction) -# HF_scaling_CaMKa = self._parameters["HF_scaling_CaMKa"] -# HF_scaling_Jrel_inf = self._parameters["HF_scaling_Jrel_inf"] -# HF_scaling_Jleak = self._parameters["HF_scaling_Jleak"] -# HF_scaling_Jup = self._parameters["HF_scaling_Jup"] -# HF_scaling_GNaL = self._parameters["HF_scaling_GNaL"] -# HF_scaling_GK1 = self._parameters["HF_scaling_GK1"] -# HF_scaling_thL = self._parameters["HF_scaling_thL"] -# HF_scaling_Gto = self._parameters["HF_scaling_Gto"] -# HF_scaling_Gncx = self._parameters["HF_scaling_Gncx"] -# HF_scaling_Pnak = self._parameters["HF_scaling_Pnak"] -# HF_scaling_cat50_ref = self._parameters["HF_scaling_cat50_ref"] - -# # Init return args -# F_expressions = [dolfin.Constant(0.0)] * 47 - -# # Expressions for the cell geometry component -# vcell = 3140.0 * L * (rad * rad) -# Ageo = 6.28 * (rad * rad) + 6.28 * L * rad -# Acap = 2 * Ageo -# vmyo = 0.68 * vcell -# vnsr = 0.0552 * vcell -# vjsr = 0.0048 * vcell -# vss = 0.02 * vcell - -# # Expressions for the CaMKt component -# CaMKb = CaMKo * (1.0 - CaMKt) / (1.0 + KmCaM / cass) -# CaMKa = (CaMKb + CaMKt) * HF_scaling_CaMKa -# F_expressions[0] = -bCaMK * CaMKt + aCaMK * (CaMKb + CaMKt) * CaMKb - -# # Expressions for the reversal potentials component -# ENa = R * T * ufl.ln(nao / nai) / F -# EK = R * T * ufl.ln(ko / ki) / F -# EKs = R * T * ufl.ln((ko + PKNa * nao) / (PKNa * nai + ki)) / F -# vffrt = (F * F) * v / (R * T) -# vfrt = F * v / (R * T) - -# # Expressions for the I_Na component -# mss = 1.0 / (1.0 + 0.0014599788446489682 * ufl.exp(-0.13333333333333333 * v)) -# tm = 1.0 / ( -# 9.454904638564724 * ufl.exp(0.02876042565429968 * v) -# + 1.9314113558536928e-05 * ufl.exp(-0.16792611251049538 * v) -# ) -# F_expressions[1] = (-m + mss) / tm -# hss = 1.0 / (1 + 302724.605401998 * ufl.exp(0.1607717041800643 * v)) -# thf = 1.0 / ( -# 1.183856958289087e-05 * ufl.exp(-0.15910898965791567 * v) -# + 6.305549185817275 * ufl.exp(0.0493339911198816 * v) -# ) -# ths = 1.0 / ( -# 0.005164670235381792 * ufl.exp(-0.035650623885918005 * v) -# + 0.36987619372096325 * ufl.exp(0.017649135192375574 * v) -# ) -# Ahs = 1.0 - Ahf -# F_expressions[2] = (-hf + hss) / thf -# F_expressions[3] = (-hs + hss) / ths -# h = Ahf * hf + Ahs * hs -# jss = hss -# tj = 2.038 + 1.0 / ( -# 0.3131936394738773 * ufl.exp(0.02600780234070221 * v) -# + 1.1315282095590072e-07 * ufl.exp(-0.12075836251660427 * v) -# ) -# F_expressions[4] = (-j + jss) / tj -# hssp = 1.0 / (1 + 820249.0921708513 * ufl.exp(0.1607717041800643 * v)) -# thsp = 3.0 * ths -# F_expressions[5] = (-hsp + hssp) / thsp -# hp = Ahf * hf + Ahs * hsp -# tjp = 1.46 * tj -# F_expressions[6] = (-jp + jss) / tjp -# fINap = 1.0 / (1.0 + KmCaMK / CaMKa) -# INa = ( -# GNa -# * scale_drug_INa -# * scale_popu_GNa -# * ufl.elem_pow(m, 3.0) -# * (-ENa + v) -# * ((1.0 - fINap) * h * j + fINap * hp * jp) -# ) - -# # Expressions for the INaL component -# mLss = 1.0 / (1.0 + 0.000291579585635531 * ufl.exp(-0.18996960486322187 * v)) -# tmL = tm -# F_expressions[7] = (-mL + mLss) / tmL -# hLss = 1.0 / (1.0 + 120578.15595522427 * ufl.exp(0.13354700854700854 * v)) -# F_expressions[8] = (-hL + hLss) / (thL * HF_scaling_thL) -# hLssp = 1.0 / (1.0 + 275969.2903869871 * ufl.exp(0.13354700854700854 * v)) -# thLp = 3.0 * thL * HF_scaling_thL -# F_expressions[9] = (-hLp + hLssp) / thLp -# GNaL = 0.0075 * scale_INaL * scale_drug_INaL * scale_popu_GNaL * HF_scaling_GNaL -# fINaLp = 1.0 / (1.0 + KmCaMK / CaMKa) -# INaL = (-ENa + v) * ((1.0 - fINaLp) * hL + fINaLp * hLp) * GNaL * mL - -# # Expressions for the Ito component -# ass = 1.0 / (1.0 + 2.6316508161673635 * ufl.exp(-0.06747638326585695 * v)) -# ta = 1.0515 / ( -# 1.0 / (1.2089 + 2.2621017070578837 * ufl.exp(-0.03403513787634354 * v)) -# + 3.5 / (1.0 + 30.069572727397507 * ufl.exp(0.03403513787634354 * v)) -# ) -# F_expressions[10] = (-a + ass) / ta -# iss = 1.0 / (1.0 + 2194.970764538301 * ufl.exp(0.17510068289266328 * v)) -# tiF = 4.562 + delta_epi / ( -# 0.14468698421272827 * ufl.exp(-0.01 * v) -# + 1.6300896349780942 * ufl.exp(0.06027727546714889 * v) -# ) -# tiS = 23.62 + delta_epi / ( -# 0.00027617763953377436 * ufl.exp(-0.01693480101608806 * v) -# + 0.024208962804604526 * ufl.exp(0.12377769525931426 * v) -# ) -# AiF = 1.0 / (1.0 + 0.24348537187522867 * ufl.exp(0.006613756613756614 * v)) -# AiS = 1.0 - AiF -# F_expressions[11] = (-iF + iss) / tiF -# F_expressions[12] = (-iS + iss) / tiS -# i = AiF * iF + AiS * iS -# assp = 1.0 / (1.0 + 5.167428462230666 * ufl.exp(-0.06747638326585695 * v)) -# F_expressions[13] = (-ap + assp) / ta -# dti_develop = 1.354 + 0.0001 / ( -# 2.6591269045230603e-05 * ufl.exp(0.06293266205160478 * v) -# + 4.5541779737128264e24 * ufl.exp(-4.642525533890436 * v) -# ) -# dti_recover = 1.0 - 0.5 / (1.0 + 33.11545195869231 * ufl.exp(0.05 * v)) -# tiFp = dti_develop * dti_recover * tiF -# tiSp = dti_develop * dti_recover * tiS -# F_expressions[14] = (-iFp + iss) / tiFp -# F_expressions[15] = (-iSp + iss) / tiSp -# ip = AiF * iFp + AiS * iSp -# fItop = 1.0 / (1.0 + KmCaMK / CaMKa) -# Ito = ( -# Gto -# * scale_drug_Ito -# * scale_popu_Gto -# * HF_scaling_Gto -# * (-EK + v) -# * ((1.0 - fItop) * a * i + ap * fItop * ip) -# ) - -# # Expressions for the ICaL ICaNa ICaK component -# dss = 1.0 / (1.0 + 0.39398514226669484 * ufl.exp(-0.23640661938534277 * v)) -# td = 0.6 + 1.0 / ( -# 3.5254214873653824 * ufl.exp(0.09 * v) -# + 0.7408182206817179 * ufl.exp(-0.05 * v) -# ) -# F_expressions[16] = (-d + dss) / td -# fss = 1.0 / (1.0 + 199.86038496778565 * ufl.exp(0.27056277056277056 * v)) -# tff = 7.0 + 1.0 / ( -# 0.03325075244518792 * ufl.exp(0.1 * v) -# + 0.0006090087745647571 * ufl.exp(-0.1 * v) -# ) -# tfs = 1000.0 + 1.0 / ( -# 1.0027667890106652e-05 * ufl.exp(-0.25 * v) -# + 8.053415618124885e-05 * ufl.exp(0.16666666666666666 * v) -# ) -# Afs = 1.0 - Aff -# F_expressions[17] = (-ff + fss) / tff -# F_expressions[18] = (-fs + fss) / tfs -# f = Aff * ff + Afs * fs -# fcass = fss -# tfcaf = 7.0 + 1.0 / ( -# 0.0708317980974062 * ufl.exp(-0.14285714285714285 * v) -# + 0.02258872488031037 * ufl.exp(0.14285714285714285 * v) -# ) -# tfcas = 100.0 + 1.0 / ( -# 0.00012 * ufl.exp(0.14285714285714285 * v) -# + 0.00012 * ufl.exp(-0.3333333333333333 * v) -# ) -# Afcaf = 0.3 + 0.6 / (1.0 + 0.36787944117144233 * ufl.exp(0.1 * v)) -# Afcas = 1.0 - Afcaf -# F_expressions[19] = (-fcaf + fcass) / tfcaf -# F_expressions[20] = (-fcas + fcass) / tfcas -# fca = Afcaf * fcaf + Afcas * fcas -# F_expressions[21] = (-jca + fcass) / tjca -# tffp = 2.5 * tff -# F_expressions[22] = (-ffp + fss) / tffp -# fp = Aff * ffp + Afs * fs -# tfcafp = 2.5 * tfcaf -# F_expressions[23] = (-fcafp + fcass) / tfcafp -# fcap = Afcaf * fcafp + Afcas * fcas -# km2n = 1.0 * jca -# anca = 1.0 / (ufl.elem_pow(1.0 + Kmn / cass, 4.0) + k2n / km2n) -# F_expressions[24] = k2n * anca - km2n * nca -# PhiCaL = ( -# 4.0 -# * (-0.341 * cao + cass * ufl.exp(2.0 * vfrt)) -# * vffrt -# / (-1.0 + ufl.exp(2.0 * vfrt)) -# ) -# PhiCaNa = ( -# 1.0 -# * (-0.75 * nao + 0.75 * ufl.exp(1.0 * vfrt) * nass) -# * vffrt -# / (-1.0 + ufl.exp(1.0 * vfrt)) -# ) -# PhiCaK = ( -# 1.0 -# * (-0.75 * ko + 0.75 * ufl.exp(1.0 * vfrt) * kss) -# * vffrt -# / (-1.0 + ufl.exp(1.0 * vfrt)) -# ) -# PCa = 0.0001 * scale_ICaL * scale_drug_ICaL * scale_popu_GCaL -# PCap = 1.1 * PCa -# PCaNa = 0.00125 * PCa -# PCaK = 0.0003574 * PCa -# PCaNap = 0.00125 * PCap -# PCaKp = 0.0003574 * PCap -# fICaLp = 1.0 / (1.0 + KmCaMK / CaMKa) -# ICaL = (1.0 - fICaLp) * ( -# (1.0 - nca) * f + fca * jca * nca -# ) * PCa * PhiCaL * d + ( -# (1.0 - nca) * fp + fcap * jca * nca -# ) * PCap * PhiCaL * d * fICaLp -# ICaNa = (1.0 - fICaLp) * ( -# (1.0 - nca) * f + fca * jca * nca -# ) * PCaNa * PhiCaNa * d + ( -# (1.0 - nca) * fp + fcap * jca * nca -# ) * PCaNap * PhiCaNa * d * fICaLp -# ICaK = (1.0 - fICaLp) * ( -# (1.0 - nca) * f + fca * jca * nca -# ) * PCaK * PhiCaK * d + ( -# (1.0 - nca) * fp + fcap * jca * nca -# ) * PCaKp * PhiCaK * d * fICaLp - -# # Expressions for the IKr component -# xrss = 1.0 / (1.0 + 0.29287308872377504 * ufl.exp(-0.14729709824716453 * v)) -# txrf = 12.98 + 1.0 / ( -# 0.0001020239312894894 * ufl.exp(0.25846471956577927 * v) -# + 0.00042992960891929087 * ufl.exp(-0.04906771344455348 * v) -# ) -# txrs = 1.865 + 1.0 / ( -# 0.0005922420036809394 * ufl.exp(0.13596193065941536 * v) -# + 3.549966111802463e-05 * ufl.exp(-0.03855050115651503 * v) -# ) -# Axrf = 1.0 / (1.0 + 4.197299094734718 * ufl.exp(0.02617115938236064 * v)) -# Axrs = 1.0 - Axrf -# F_expressions[25] = (-xrf + xrss) / txrf -# F_expressions[26] = (-xrs + xrss) / txrs -# xr = Axrf * xrf + Axrs * xrs -# rkr = 1.0 / ( -# (1.0 + 2.0820090840784555 * ufl.exp(0.013333333333333334 * v)) -# * (1.0 + 0.7165313105737893 * ufl.exp(0.03333333333333333 * v)) -# ) -# GKr = 0.046 * scale_IKr * scale_drug_IKr * scale_popu_GKr -# IKr = 0.4303314829119352 * ufl.sqrt(ko) * (-EK + v) * GKr * rkr * xr - -# # Expressions for the IKs component -# xs1ss = 1.0 / (1.0 + 0.27288596035656526 * ufl.exp(-0.11195700850873264 * v)) -# txs1 = 817.3 + 1.0 / ( -# 0.003504067763074858 * ufl.exp(0.056179775280898875 * v) -# + 0.0005184809083581659 * ufl.exp(-0.004347826086956522 * v) -# ) -# F_expressions[27] = (-xs1 + xs1ss) / txs1 -# xs2ss = xs1ss -# txs2 = 1.0 / ( -# 0.0022561357010639103 * ufl.exp(-0.03225806451612903 * v) -# + 0.0008208499862389881 * ufl.exp(0.05 * v) -# ) -# F_expressions[28] = (-xs2 + xs2ss) / txs2 -# KsCa = 1.0 + 0.6 / (1.0 + 6.481821026062645e-07 * ufl.elem_pow(1.0 / cai, 1.4)) -# GKs = 0.0034 * scale_IKs * scale_drug_IKs * scale_popu_GKs -# IKs = (-EKs + v) * GKs * KsCa * xs1 * xs2 -# xk1ss = 1.0 / ( -# 1.0 + ufl.exp((-144.59 - v - 2.5538 * ko) / (3.8115 + 1.5692 * ko)) -# ) -# txk1 = 122.2 / ( -# 0.0019352007631390235 * ufl.exp(-0.049115913555992145 * v) -# + 30.43364757524903 * ufl.exp(0.014423770373575654 * v) -# ) -# F_expressions[29] = (-xk1 + xk1ss) / txk1 -# rk1 = 1.0 / ( -# 1.0 -# + 69220.6322106767 -# * ufl.exp(0.10534077741493732 * v - 0.27388602127883704 * ko) -# ) -# GK1 = 0.1908 * scale_IK1 * scale_drug_IK1 * scale_popu_GK1 * HF_scaling_GK1 -# IK1 = ufl.sqrt(ko) * (-EK + v) * GK1 * rk1 * xk1 - -# # Expressions for the INaCa_i component -# hca = ufl.exp(F * qca * v / (R * T)) -# hna = ufl.exp(F * qna * v / (R * T)) -# h1_i = 1.0 + (1.0 + hna) * nai / kna3 -# h2_i = hna * nai / (kna3 * h1_i) -# h3_i = 1.0 / h1_i -# h4_i = 1.0 + (1 + nai / kna2) * nai / kna1 -# h5_i = (nai * nai) / (kna1 * kna2 * h4_i) -# h6_i = 1.0 / h4_i -# h7_i = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 -# h8_i = nao / (kna3 * h7_i * hna) -# h9_i = 1.0 / h7_i -# h10_i = 1.0 + kasymm + nao * (1.0 + nao / kna2) / kna1 -# h11_i = (nao * nao) / (kna1 * kna2 * h10_i) -# h12_i = 1.0 / h10_i -# k1_i = cao * kcaon * h12_i -# k2_i = kcaoff -# k3p_i = wca * h9_i -# k3pp_i = wnaca * h8_i -# k3_i = k3p_i + k3pp_i -# k4p_i = wca * h3_i / hca -# k4pp_i = wnaca * h2_i -# k4_i = k4p_i + k4pp_i -# k5_i = kcaoff -# k6_i = kcaon * cai * h6_i -# k7_i = wna * h2_i * h5_i -# k8_i = wna * h11_i * h8_i -# x1_i = (k2_i + k3_i) * k5_i * k7_i + (k6_i + k7_i) * k2_i * k4_i -# x2_i = (k1_i + k8_i) * k4_i * k6_i + (k4_i + k5_i) * k1_i * k7_i -# x3_i = (k2_i + k3_i) * k6_i * k8_i + (k6_i + k7_i) * k1_i * k3_i -# x4_i = (k1_i + k8_i) * k3_i * k5_i + (k4_i + k5_i) * k2_i * k8_i -# E1_i = x1_i / (x1_i + x2_i + x3_i + x4_i) -# E2_i = x2_i / (x1_i + x2_i + x3_i + x4_i) -# E3_i = x3_i / (x1_i + x2_i + x3_i + x4_i) -# E4_i = x4_i / (x1_i + x2_i + x3_i + x4_i) -# allo_i = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cai, 2.0)) -# zna = 1.0 -# JncxNa_i = E3_i * k4pp_i - E2_i * k3pp_i + 3.0 * E4_i * k7_i - 3.0 * E1_i * k8_i -# JncxCa_i = E2_i * k2_i - E1_i * k1_i -# INaCa_i = ( -# 0.8 -# * Gncx -# * scale_popu_KNCX -# * HF_scaling_Gncx -# * (zca * JncxCa_i + zna * JncxNa_i) -# * allo_i -# ) - -# # Expressions for the INaCa_ss component -# h1 = 1.0 + (1.0 + hna) * nass / kna3 -# h2 = hna * nass / (kna3 * h1) -# h3 = 1.0 / h1 -# h4 = 1.0 + (1 + nass / kna2) * nass / kna1 -# h5 = (nass * nass) / (kna1 * kna2 * h4) -# h6 = 1.0 / h4 -# h7 = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 -# h8 = nao / (kna3 * h7 * hna) -# h9 = 1.0 / h7 -# h10 = 1.0 + kasymm + nao * (1 + nao / kna2) / kna1 -# h11 = (nao * nao) / (kna1 * kna2 * h10) -# h12 = 1.0 / h10 -# k1 = cao * kcaon * h12 -# k2 = kcaoff -# k3p_ss = wca * h9 -# k3pp = wnaca * h8 -# k3 = k3p_ss + k3pp -# k4p_ss = wca * h3 / hca -# k4pp = wnaca * h2 -# k4 = k4p_ss + k4pp -# k5 = kcaoff -# k6 = kcaon * cass * h6 -# k7 = wna * h2 * h5 -# k8 = wna * h11 * h8 -# x1_ss = (k2 + k3) * k5 * k7 + (k6 + k7) * k2 * k4 -# x2_ss = (k1 + k8) * k4 * k6 + (k4 + k5) * k1 * k7 -# x3_ss = (k2 + k3) * k6 * k8 + (k6 + k7) * k1 * k3 -# x4_ss = (k1 + k8) * k3 * k5 + (k4 + k5) * k2 * k8 -# E1_ss = x1_ss / (x1_ss + x2_ss + x3_ss + x4_ss) -# E2_ss = x2_ss / (x1_ss + x2_ss + x3_ss + x4_ss) -# E3_ss = x3_ss / (x1_ss + x2_ss + x3_ss + x4_ss) -# E4_ss = x4_ss / (x1_ss + x2_ss + x3_ss + x4_ss) -# allo_ss = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cass, 2.0)) -# JncxNa_ss = E3_ss * k4pp - E2_ss * k3pp + 3.0 * E4_ss * k7 - 3.0 * E1_ss * k8 -# JncxCa_ss = E2_ss * k2 - E1_ss * k1 -# INaCa_ss = ( -# 0.2 -# * Gncx -# * scale_popu_KNCX -# * HF_scaling_Gncx -# * (zca * JncxCa_ss + zna * JncxNa_ss) -# * allo_ss -# ) - -# # Expressions for the INaK component -# Knai = Knai0 * ufl.exp(0.3333333333333333 * F * delta * v / (R * T)) -# Knao = Knao0 * ufl.exp(0.3333333333333333 * F * (1.0 - delta) * v / (R * T)) -# P = eP / (1.0 + H / Khp + nai / Knap + ki / Kxkur) -# a1 = ( -# k1p -# * ufl.elem_pow(nai / Knai, 3.0) -# / ( -# -1.0 -# + ufl.elem_pow(1.0 + ki / Kki, 2.0) -# + ufl.elem_pow(1.0 + nai / Knai, 3.0) -# ) -# ) -# b1 = MgADP * k1m -# a2 = k2p -# b2 = ( -# k2m -# * ufl.elem_pow(nao / Knao, 3.0) -# / ( -# -1.0 -# + ufl.elem_pow(1.0 + ko / Kko, 2.0) -# + ufl.elem_pow(1.0 + nao / Knao, 3.0) -# ) -# ) -# a3 = ( -# k3p -# * ufl.elem_pow(ko / Kko, 2.0) -# / ( -# -1.0 -# + ufl.elem_pow(1.0 + ko / Kko, 2.0) -# + ufl.elem_pow(1.0 + nao / Knao, 3.0) -# ) -# ) -# b3 = H * k3m * P / (1.0 + MgATP / Kmgatp) -# a4 = MgATP * k4p / (Kmgatp * (1.0 + MgATP / Kmgatp)) -# b4 = ( -# k4m -# * ufl.elem_pow(ki / Kki, 2.0) -# / ( -# -1.0 -# + ufl.elem_pow(1.0 + ki / Kki, 2.0) -# + ufl.elem_pow(1.0 + nai / Knai, 3.0) -# ) -# ) -# x1 = a1 * a2 * a4 + a1 * a2 * b3 + a2 * b3 * b4 + b2 * b3 * b4 -# x2 = a1 * a2 * a3 + a2 * a3 * b4 + a3 * b1 * b4 + b1 * b2 * b4 -# x3 = a2 * a3 * a4 + a3 * a4 * b1 + a4 * b1 * b2 + b1 * b2 * b3 -# x4 = a1 * a3 * a4 + a1 * a4 * b2 + a1 * b2 * b3 + b2 * b3 * b4 -# E1 = x1 / (x1 + x2 + x3 + x4) -# E2 = x2 / (x1 + x2 + x3 + x4) -# E3 = x3 / (x1 + x2 + x3 + x4) -# E4 = x4 / (x1 + x2 + x3 + x4) -# JnakNa = 3.0 * E1 * a3 - 3.0 * E2 * b3 -# JnakK = 2.0 * E4 * b1 - 2.0 * E3 * a1 -# INaK = Pnak * scale_popu_KNaK * HF_scaling_Pnak * (zk * JnakK + zna * JnakNa) - -# # Expressions for the IKb component -# xkb = 1.0 / (1.0 + 2.202363450949239 * ufl.exp(-0.05452562704471101 * v)) -# IKb = GKb * scale_popu_GbK * scale_drug_IKb * (-EK + v) * xkb - -# # Expressions for the INab component -# INab = ( -# PNab -# * scale_drug_INab -# * scale_popu_GbNa -# * (-nao + ufl.exp(vfrt) * nai) -# * vffrt -# / (-1.0 + ufl.exp(vfrt)) -# ) - -# # Expressions for the ICab component -# ICab = ( -# 4.0 -# * PCab -# * scale_drug_ICab -# * scale_popu_GbCa -# * (-0.341 * cao + cai * ufl.exp(2.0 * vfrt)) -# * vffrt -# / (-1.0 + ufl.exp(2.0 * vfrt)) -# ) - -# # Expressions for the IpCa component -# IpCa = GpCa * scale_drug_IpCa * scale_popu_KpCa * cai / (0.0005 + cai) - -# # Expressions for the Isac (Pueyo)--> ns + k component -# Gsac_ns = 0.006 * scale_drug_Isacns -# Esac_ns = -10.0 -# lambda_max = 1.1 -# Gsac_k = (0.2882 * 800.0 / 210.0) * scale_drug_Isack # Pueyo endo -# Isac_P_ns = ufl.conditional( -# ufl.lt(self.lmbda, 1.0), -# 0.0, -# Gsac_ns * ((self.lmbda - 1.0) / (lambda_max - 1.0)) * (v - Esac_ns), -# ) -# Isac_P_k = ufl.conditional( -# ufl.lt(self.lmbda, 1.0), -# 0.0, -# Gsac_k -# * ((self.lmbda - 1.0) / (lambda_max - 1.0)) -# * (1.0 / (1.0 + ufl.exp((19.05 - v) / (29.98)))), -# ) - -# # Expressions for the Istim component -# Istim = 0 #0 # amp*(ufl.le(time, duration)) - -# # Expressions for the diffusion fluxes component -# JdiffNa = 0.5 * nass - 0.5 * nai -# JdiffK = 0.5 * kss - 0.5 * ki -# Jdiff = 5.0 * cass - 5.0 * cai - -# # Expressions for the ryanodine receptor component -# a_rel = 0.5 * bt -# Jrel_inf = ( -# -ICaL -# * a_rel -# / (1.0 + 25.62890625 * HF_scaling_Jrel_inf * ufl.elem_pow(1.0 / cajsr, 8.0)) -# ) -# tau_rel_tmp = bt / (1.0 + 0.0123 / cajsr) -# tau_rel = ufl.conditional(ufl.lt(tau_rel_tmp, 0.001), 0.001, tau_rel_tmp) -# F_expressions[30] = (-Jrelnp + Jrel_inf) / tau_rel -# btp = 1.25 * bt -# a_relp = 0.5 * btp -# Jrel_infp = ( -# -ICaL -# * a_relp -# / (1.0 + 25.62890625 * HF_scaling_Jrel_inf * ufl.elem_pow(1.0 / cajsr, 8.0)) -# ) -# tau_relp_tmp = btp / (1.0 + 0.0123 / cajsr) -# tau_relp = ufl.conditional(ufl.lt(tau_relp_tmp, 0.001), 0.001, tau_relp_tmp) -# F_expressions[31] = (-Jrelp + Jrel_infp) / tau_relp -# fJrelp = 1.0 / (1.0 + KmCaMK / CaMKa) -# Jrel = ((1.0 - fJrelp) * Jrelnp + Jrelp * fJrelp) * scale_popu_KRyR - -# # Expressions for the calcium buffers component -# Jupnp = 0.004375 * cai / (0.00092 + cai) -# Jupp = 0.01203125 * cai / (0.00075 + cai) -# fJupp = 1.0 / (1.0 + KmCaMK / CaMKa) -# Jleak = 0.0002625 * cansr * scale_popu_Kleak * HF_scaling_Jleak -# Jup = ( -# -Jleak -# + ((1.0 - fJupp) * Jupnp + Jupp * fJupp) -# * scale_popu_KSERCA -# * HF_scaling_Jup -# ) -# Jtr = 0.01 * cansr - 0.01 * cajsr - -# # Expressions for the intracellular concentrations component -# F_expressions[32] = JdiffNa * vss / vmyo + ( -# -INa - INaL - INab - Isac_P_ns / 3.0 - 3.0 * INaCa_i - 3.0 * INaK -# ) * Acap / (F * vmyo) -# F_expressions[33] = -JdiffNa + (-ICaNa - 3.0 * INaCa_ss) * Acap / (F * vss) -# F_expressions[34] = JdiffK * vss / vmyo + ( -# -Isac_P_k -# - IK1 -# - IKb -# - IKr -# - IKs -# - Istim -# - Ito -# - Isac_P_ns / 3.0 -# + 2.0 * INaK -# ) * Acap / (F * vmyo) -# F_expressions[35] = -JdiffK - Acap * ICaK / (F * vss) -# Bcass = 1.0 / ( -# 1.0 -# + BSLmax * KmBSL * ufl.elem_pow(KmBSL + cass, -2.0) -# + BSRmax * KmBSR * ufl.elem_pow(KmBSR + cass, -2.0) -# ) -# F_expressions[36] = ( -# -Jdiff -# + Jrel * vjsr / vss -# + 0.5 * (-ICaL + 2.0 * INaCa_ss) * Acap / (F * vss) -# ) * Bcass -# F_expressions[37] = -Jtr * vjsr / vnsr + Jup -# Bcajsr = 1.0 / (1.0 + csqnmax * kmcsqn * ufl.elem_pow(kmcsqn + cajsr, -2.0)) -# F_expressions[38] = (-Jrel + Jtr) * Bcajsr - -# # Expressions for the mechanics component -# kwu = -kws * scale_popu_kws + (kuw * scale_popu_kuw) * ( -# -1.0 + 1.0 / (rw * scale_popu_rw) -# ) -# ksu = ( -# kws -# * scale_popu_kws -# * rw -# * scale_popu_rw -# * (-1.0 + 1.0 / (rs * scale_popu_rs)) -# ) - -# Aw = Tot_A * rs / (rs + rw * (1 - rs)) -# As = Aw -# cw = kuw * phi * (1 - rw) / rw -# cs = kws * phi * rw * (1 - rs) / rs - -# lambda_min12 = ufl.conditional(ufl.lt(self.lmbda, 1.2), self.lmbda, 1.2) -# XS = ufl.conditional(ufl.lt(XS, 0.0), 0.0, XS) -# XW = ufl.conditional(ufl.lt(XW, 0.0), 0.0, XW) - -# XU = 1.0 - TmB - XS - XW -# gammawu = gammaw * abs(Zetaw) -# # gammasu = gammas*ufl.conditional(ufl.gt(Zetas*(ufl.gt(Zetas, 0)), (-1 -\ -# # Zetas)*(ufl.lt(Zetas, -1))), Zetas*(ufl.gt(Zetas, 0)), (-1 -\ -# # Zetas)*(ufl.lt(Zetas, -1))) -# zetas1 = Zetas * ufl.conditional(ufl.gt(Zetas, 0.0), 1.0, 0.0) -# zetas2 = (-1.0 - Zetas) * ufl.conditional( -# ufl.lt(Zetas, -1.0), -# 1.0, -# 0.0, -# ) -# gammasu = gammas * Max(zetas1, zetas2) - -# F_expressions[39] = kws * scale_popu_kws * XW - XS * gammasu - XS * ksu -# F_expressions[40] = ( -# kuw * scale_popu_kuw * XU -# - kws * scale_popu_kws * XW -# - XW * gammawu -# - XW * kwu -# ) -# cat50 = ( -# cat50_ref * scale_popu_CaT50ref + Beta1 * (-1.0 + lambda_min12) -# ) * HF_scaling_cat50_ref -# CaTrpn = ufl.conditional(ufl.lt(CaTrpn, 0.0), 0.0, CaTrpn) -# F_expressions[41] = ( -# ktrpn -# * scale_popu_kTRPN -# * ( -# -CaTrpn -# + ufl.elem_pow(1000.0 * cai / cat50, ntrpn * scale_popu_nTRPN) -# * (1.0 - CaTrpn) -# ) -# ) -# kb = ( -# ku -# * scale_popu_ku -# * ufl.elem_pow(Trpn50 * scale_popu_TRPN50, (ntm * scale_popu_nTm)) -# / ( -# 1.0 -# - (rs * scale_popu_rs) -# - rw * scale_popu_rw * (1.0 - (rs * scale_popu_rs)) -# ) -# ) - -# F_expressions[42] = ( -# ufl.conditional( -# ufl.lt(ufl.elem_pow(CaTrpn, -(ntm * scale_popu_nTm) / 2.0), 100.0), -# ufl.elem_pow(CaTrpn, -(ntm * scale_popu_nTm) / 2.0), -# 100.0, -# ) -# * XU -# * kb -# - ku -# * scale_popu_ku -# * ufl.elem_pow(CaTrpn, (ntm * scale_popu_nTm) / 2.0) -# * TmB -# ) - -# C = -1.0 + lambda_min12 -# dCd = -Cd + C -# eta = ufl.conditional(ufl.lt(dCd, 0.0), etas, etal) -# F_expressions[43] = p_k * (-Cd + C) / eta -# Bcai = 1.0 / (1.0 + cmdnmax * kmcmdn * ufl.elem_pow(kmcmdn + cai, -2.0)) -# J_TRPN = trpnmax * F_expressions[41] -# F_expressions[44] = ( -# -J_TRPN -# + Jdiff * vss / vmyo -# - Jup * vnsr / vmyo -# + 0.5 * (-ICab - IpCa - Isac_P_ns / 3.0 + 2.0 * INaCa_i) * Acap / (F * vmyo) -# ) * Bcai - -# F_expressions[45] = self.dLambda * As - Zetas * cs -# F_expressions[46] = self.dLambda * Aw - Zetaw * cw -# # State 46 and 47 is lambda and dLambda respectively - -# # Return results -# return as_vector(F_expressions) - -# def num_states(self): -# return 47 - -# def __str__(self): -# return "ORdmm_Land_em_coupling cardiac cell model" diff --git a/src/simcardems/models/explicit_ORdmm_Land/em_model.py b/src/simcardems/models/explicit_ORdmm_Land/em_model.py index 09146bc5..2f201f4f 100644 --- a/src/simcardems/models/explicit_ORdmm_Land/em_model.py +++ b/src/simcardems/models/explicit_ORdmm_Land/em_model.py @@ -204,7 +204,7 @@ def mech_state(self): @property def vs(self) -> np.ndarray: - return self.ep_solver.ode.values + return self.ep_solver.ode.full_values @property def dLambda_ep(self): diff --git a/src/simcardems/models/fully_coupled_ORdmm_Land/active_model.py b/src/simcardems/models/fully_coupled_ORdmm_Land/active_model.py index ed47bef2..6bc6383e 100644 --- a/src/simcardems/models/fully_coupled_ORdmm_Land/active_model.py +++ b/src/simcardems/models/fully_coupled_ORdmm_Land/active_model.py @@ -71,6 +71,9 @@ def __init__( self.XW = coupling.XW_mech if parameters is None: parameters = init_parameter_values() + if isinstance(parameters, dict): + # Just pick the endo parameters for now + parameters = parameters[0] # type: ignore self._parameters = parameters diff --git a/src/simcardems/models/fully_coupled_ORdmm_Land/cell_model.py b/src/simcardems/models/fully_coupled_ORdmm_Land/cell_model.py index 3fc9a31c..9fc0f99f 100644 --- a/src/simcardems/models/fully_coupled_ORdmm_Land/cell_model.py +++ b/src/simcardems/models/fully_coupled_ORdmm_Land/cell_model.py @@ -22,6 +22,7 @@ # """ import math +import beat import numpy from ... import utils @@ -1279,11 +1280,25 @@ def rhs(t, states, parameters): return values +celltype2marker = { + 2.0: 0, + 0.0: 1, + 1.0: 2, +} + + def forward_generalized_rush_larsen(coupling: EMCoupling): def forward_generalized_rush_larsen_(states, t, dt, parameters): - lmbda = coupling.lmbda_ep.vector().get_local() - Zetas = coupling.Zetas_ep.vector().get_local() - Zetaw = coupling.Zetaw_ep.vector().get_local() + if isinstance(coupling.ep_solver.ode, beat.odesolver.DolfinMultiODESolver): + marker = celltype2marker[parameters[parameter_index("celltype")]] + where = coupling.ep_solver.ode.markers.vector().get_local() == marker + lmbda = coupling.lmbda_ep.vector().get_local()[where] + Zetas = coupling.Zetas_ep.vector().get_local()[where] + Zetaw = coupling.Zetaw_ep.vector().get_local()[where] + else: + lmbda = coupling.lmbda_ep.vector().get_local() + Zetas = coupling.Zetas_ep.vector().get_local() + Zetaw = coupling.Zetaw_ep.vector().get_local() # Assign states hL = states[0] a = states[1] @@ -2236,1645 +2251,3 @@ def forward_generalized_rush_larsen_(states, t, dt, parameters): return values return forward_generalized_rush_larsen_ - - -# def Max(a, b): -# return (a + b + abs(a - b)) / Constant(2.0) - - -# def Min(a, b): -# return (a + b - abs(a - b)) / Constant(2.0) - - -# class ORdmmLandFull(BaseCellModel): -# def __init__( -# self, -# coupling: EMCoupling, -# params=None, -# init_conditions=None, -# ): -# """ -# Create cardiac cell model -# *Arguments* -# params (dict, :py:class:`dolfin.Mesh`, optional) -# optional model parameters -# init_conditions (dict, :py:class:`dolfin.Mesh`, optional) -# optional initial conditions -# """ -# logger.debug("Initialize ORdmm Land model") - -# super().__init__(params, init_conditions) -# self.lmbda = coupling.lmbda_ep -# self.Zetas = coupling.Zetas_ep -# self.Zetaw = coupling.Zetaw_ep - -# @staticmethod -# def update_disease_parameters( -# params: Dict[str, float], -# disease_state: str = "healthy", -# ) -> None: -# if disease_state.lower() == "hf": -# logger.info("Update scaling parameters for heart failure model") -# params["HF_scaling_CaMKa"] = 1.50 -# params["HF_scaling_Jrel_inf"] = pow(0.8, 8.0) -# params["HF_scaling_Jleak"] = 1.3 -# params["HF_scaling_Jup"] = 0.45 -# params["HF_scaling_GNaL"] = 1.3 -# params["HF_scaling_GK1"] = 0.68 -# params["HF_scaling_thL"] = 1.8 -# params["HF_scaling_Gto"] = 0.4 -# params["HF_scaling_Gncx"] = 1.6 -# params["HF_scaling_Pnak"] = 0.7 -# params["HF_scaling_cat50_ref"] = 0.6 - -# @staticmethod -# def default_parameters() -> Dict[str, float]: -# """Set-up and return default parameters. -# Parameters -# ---------- -# disease_state : str, optional -# String with "hf" or "healthy", by default "healthy". -# If "hf", then parameters representing heart failure -# will be used. -# Returns -# ------- -# OrderedDict -# Dictionary with default values -# """ -# params = OrderedDict( -# [ -# ("scale_ICaL", 1.018), -# ("scale_IK1", 1.414), -# ("scale_IKr", 1.119), -# ("scale_IKs", 1.648), -# ("scale_INaL", 2.274), -# ("celltype", 0), -# ("cao", 1.8), -# ("ko", 5.4), -# ("nao", 140.0), -# ("F", 96485.0), -# ("R", 8314.0), -# ("T", 310.0), -# ("L", 0.01), -# ("rad", 0.0011), -# ("Ahf", 0.99), -# ("GNa", 31), -# ("thL", 200.0), -# ("Gto", 0.02), -# ("delta_epi", 1.0), -# ("Aff", 0.6), -# ("Kmn", 0.002), -# ("k2n", 1000.0), -# ("tjca", 75.0), -# ("zca", 2.0), -# ("bt", 4.75), -# ("Beta0", 2.3), -# ("Beta1", -2.4), -# ("Tot_A", 25), -# ("Tref", 120), -# ("Trpn50", 0.35), -# ("calib", 1), -# ("cat50_ref", 0.805), -# ("emcoupling", 1), -# ("etal", 200), -# ("etas", 20), -# ("gammas", 0.0085), -# ("gammaw", 0.615), -# ("isacs", 0), -# ("ktrpn", 0.1), -# ("ku", 0.04), -# ("kuw", 0.182), -# ("kws", 0.012), -# ("mode", 1), -# ("ntm", 2.4), -# ("ntrpn", 2.0), -# ("p_a", 2.1), -# ("p_b", 9.1), -# ("p_k", 7.0), -# ("phi", 2.23), -# ("rs", 0.25), -# ("rw", 0.5), -# ("CaMKo", 0.05), -# ("KmCaM", 0.0015), -# ("KmCaMK", 0.15), -# ("aCaMK", 0.05), -# ("bCaMK", 0.00068), -# ("PKNa", 0.01833), -# ("Gncx", 0.0008), -# ("KmCaAct", 0.00015), -# ("kasymm", 12.5), -# ("kcaoff", 5000.0), -# ("kcaon", 1500000.0), -# ("kna1", 15.0), -# ("kna2", 5.0), -# ("kna3", 88.12), -# ("qca", 0.167), -# ("qna", 0.5224), -# ("wca", 60000.0), -# ("wna", 60000.0), -# ("wnaca", 5000.0), -# ("H", 1e-07), -# ("Khp", 1.698e-07), -# ("Kki", 0.5), -# ("Kko", 0.3582), -# ("Kmgatp", 1.698e-07), -# ("Knai0", 9.073), -# ("Knao0", 27.78), -# ("Knap", 224.0), -# ("Kxkur", 292.0), -# ("MgADP", 0.05), -# ("MgATP", 9.8), -# ("Pnak", 30.0), -# ("delta", -0.155), -# ("eP", 4.2), -# ("k1m", 182.4), -# ("k1p", 949.5), -# ("k2m", 39.4), -# ("k2p", 687.2), -# ("k3m", 79300.0), -# ("k3p", 1899.0), -# ("k4m", 40.0), -# ("k4p", 639.0), -# ("zk", 1.0), -# ("GKb", 0.003), -# ("PNab", 3.75e-10), -# ("PCab", 2.5e-08), -# ("GpCa", 0.0005), -# ("Esac_ns", -10.0), -# ("Gsac_k", 1.097904761904762), -# ("Gsac_ns", 0.006), -# ("lambda_max", 1.1), -# ("amp", -80.0), -# ("duration", 0.5), -# ("BSLmax", 1.124), -# ("BSRmax", 0.047), -# ("KmBSL", 0.0087), -# ("KmBSR", 0.00087), -# ("cmdnmax", 0.05), -# ("csqnmax", 10.0), -# ("kmcmdn", 0.00238), -# ("kmcsqn", 0.8), -# ("kmtrpn", 0.0005), -# ("trpnmax", 0.07), -# # Drug factors -# ("scale_drug_INa", 1.0), -# ("scale_drug_INaL", 1.0), -# ("scale_drug_Ito", 1.0), -# ("scale_drug_ICaL", 1.0), -# ("scale_drug_IKr", 1.0), -# ("scale_drug_IKs", 1.0), -# ("scale_drug_IK1", 1.0), -# ("scale_drug_IKb", 1.0), -# ("scale_drug_INab", 1.0), -# ("scale_drug_ICab", 1.0), -# ("scale_drug_IpCa", 1.0), -# ("scale_drug_Isacns", 1.0), -# ("scale_drug_Isack", 1.0), -# # Population factors -# ("scale_popu_GNa", 1.0), -# ("scale_popu_GCaL", 1.0), -# ("scale_popu_Gto", 1.0), -# ("scale_popu_GNaL", 1.0), -# ("scale_popu_GKr", 1.0), -# ("scale_popu_GKs", 1.0), -# ("scale_popu_GK1", 1.0), -# ("scale_popu_GbK", 1.0), -# ("scale_popu_KNCX", 1.0), -# ("scale_popu_KNaK", 1.0), -# ("scale_popu_GbNa", 1.0), -# ("scale_popu_GbCa", 1.0), -# ("scale_popu_KpCa", 1.0), -# ("scale_popu_KRyR", 1.0), -# ("scale_popu_KSERCA", 1.0), -# ("scale_popu_Kleak", 1.0), -# ("scale_popu_nTm", 1.0), -# ("scale_popu_CaT50ref", 1.0), -# ("scale_popu_Tref", 1.0), -# ("scale_popu_kuw", 1.0), -# ("scale_popu_kws", 1.0), -# ("scale_popu_kTRPN", 1.0), -# ("scale_popu_nTRPN", 1.0), -# ("scale_popu_ku", 1.0), -# ("scale_popu_TRPN50", 1.0), -# ("scale_popu_rw", 1.0), -# ("scale_popu_rs", 1.0), -# # HF scaling factors -# ("HF_scaling_CaMKa", 1.0), -# ("HF_scaling_Jrel_inf", 1.0), -# ("HF_scaling_Jleak", 1.0), -# ("HF_scaling_Jup", 1.0), -# ("HF_scaling_GNaL", 1.0), -# ("HF_scaling_GK1", 1.0), -# ("HF_scaling_thL", 1.0), -# ("HF_scaling_Gto", 1.0), -# ("HF_scaling_Gncx", 1.0), -# ("HF_scaling_Pnak", 1.0), -# ("HF_scaling_cat50_ref", 1.0), -# ], -# ) - -# return params - -# @staticmethod -# def default_initial_conditions(): -# "Set-up and return default initial conditions." -# ic = OrderedDict( -# [ -# ("v", -87), -# ("CaMKt", 0), -# ("m", 0), -# ("hf", 1), -# ("hs", 1), -# ("j", 1), -# ("hsp", 1), -# ("jp", 1), -# ("mL", 0), -# ("hL", 1), -# ("hLp", 1), -# ("a", 0), -# ("iF", 1), -# ("iS", 1), -# ("ap", 0), -# ("iFp", 1), -# ("iSp", 1), -# ("d", 0), -# ("ff", 1), -# ("fs", 1), -# ("fcaf", 1), -# ("fcas", 1), -# ("jca", 1), -# ("ffp", 1), -# ("fcafp", 1), -# ("nca", 0), -# ("xrf", 0), -# ("xrs", 0), -# ("xs1", 0), -# ("xs2", 0), -# ("xk1", 1), -# ("Jrelnp", 0), -# ("Jrelp", 0), -# ("nai", 7), -# ("nass", 7), -# ("ki", 145), -# ("kss", 145), -# ("cass", 0.0001), -# ("cansr", 1.2), -# ("cajsr", 1.2), -# ("XS", 0), -# ("XW", 0), -# ("CaTrpn", 0), -# ("TmB", 1), -# ("Cd", 0), -# ("cai", 0.0001), -# ], -# ) -# return ic - -# def _I(self, v, s, time): -# """ -# Original gotran transmembrane current dV/dt -# """ -# time = time if time else Constant(0.0) -# logger.debug("Evaluate transmembrane current") -# # Assign states -# assert len(s) == 45 -# ( -# CaMKt, -# m, -# hf, -# hs, -# j, -# hsp, -# jp, -# mL, -# hL, -# hLp, -# a, -# iF, -# iS, -# ap, -# iFp, -# iSp, -# d, -# ff, -# fs, -# fcaf, -# fcas, -# jca, -# ffp, -# fcafp, -# nca, -# xrf, -# xrs, -# xs1, -# xs2, -# xk1, -# Jrelnp, -# Jrelp, -# nai, -# nass, -# ki, -# kss, -# cass, -# cansr, -# cajsr, -# XS, -# XW, -# CaTrpn, -# TmB, -# Cd, -# cai, -# ) = s - -# # Assign parameters -# scale_ICaL = self._parameters["scale_ICaL"] -# scale_IK1 = self._parameters["scale_IK1"] -# scale_IKr = self._parameters["scale_IKr"] -# scale_IKs = self._parameters["scale_IKs"] -# scale_INaL = self._parameters["scale_INaL"] -# cao = self._parameters["cao"] -# ko = self._parameters["ko"] -# nao = self._parameters["nao"] -# F = self._parameters["F"] -# R = self._parameters["R"] -# T = self._parameters["T"] -# CaMKo = self._parameters["CaMKo"] -# KmCaM = self._parameters["KmCaM"] -# KmCaMK = self._parameters["KmCaMK"] -# PKNa = self._parameters["PKNa"] -# Ahf = self._parameters["Ahf"] -# GNa = self._parameters["GNa"] -# Gto = self._parameters["Gto"] -# Aff = self._parameters["Aff"] -# zca = self._parameters["zca"] -# Gncx = self._parameters["Gncx"] -# KmCaAct = self._parameters["KmCaAct"] -# kasymm = self._parameters["kasymm"] -# kcaoff = self._parameters["kcaoff"] -# kcaon = self._parameters["kcaon"] -# kna1 = self._parameters["kna1"] -# kna2 = self._parameters["kna2"] -# kna3 = self._parameters["kna3"] -# qca = self._parameters["qca"] -# qna = self._parameters["qna"] -# wca = self._parameters["wca"] -# wna = self._parameters["wna"] -# wnaca = self._parameters["wnaca"] -# H = self._parameters["H"] -# Khp = self._parameters["Khp"] -# Kki = self._parameters["Kki"] -# Kko = self._parameters["Kko"] -# Kmgatp = self._parameters["Kmgatp"] -# Knai0 = self._parameters["Knai0"] -# Knao0 = self._parameters["Knao0"] -# Knap = self._parameters["Knap"] -# Kxkur = self._parameters["Kxkur"] -# MgADP = self._parameters["MgADP"] -# MgATP = self._parameters["MgATP"] -# Pnak = self._parameters["Pnak"] -# delta = self._parameters["delta"] -# eP = self._parameters["eP"] -# k1m = self._parameters["k1m"] -# k1p = self._parameters["k1p"] -# k2m = self._parameters["k2m"] -# k2p = self._parameters["k2p"] -# k3m = self._parameters["k3m"] -# k3p = self._parameters["k3p"] -# k4m = self._parameters["k4m"] -# k4p = self._parameters["k4p"] -# zk = self._parameters["zk"] -# GKb = self._parameters["GKb"] -# PNab = self._parameters["PNab"] -# PCab = self._parameters["PCab"] -# GpCa = self._parameters["GpCa"] -# # Drug factor -# scale_drug_INa = self._parameters["scale_drug_INa"] -# scale_drug_INaL = self._parameters["scale_drug_INaL"] -# scale_drug_Ito = self._parameters["scale_drug_Ito"] -# scale_drug_ICaL = self._parameters["scale_drug_ICaL"] -# scale_drug_IKr = self._parameters["scale_drug_IKr"] -# scale_drug_IKs = self._parameters["scale_drug_IKs"] -# scale_drug_IK1 = self._parameters["scale_drug_IK1"] -# scale_drug_IKb = self._parameters["scale_drug_IKb"] -# scale_drug_INab = self._parameters["scale_drug_INab"] -# scale_drug_ICab = self._parameters["scale_drug_ICab"] -# scale_drug_IpCa = self._parameters["scale_drug_IpCa"] -# scale_drug_Isacns = self._parameters["scale_drug_Isacns"] -# scale_drug_Isack = self._parameters["scale_drug_Isack"] -# # Population factors -# scale_popu_GNa = self._parameters["scale_popu_GNa"] -# scale_popu_GCaL = self._parameters["scale_popu_GCaL"] -# scale_popu_Gto = self._parameters["scale_popu_Gto"] -# scale_popu_GNaL = self._parameters["scale_popu_GNaL"] -# scale_popu_GKr = self._parameters["scale_popu_GKr"] -# scale_popu_GKs = self._parameters["scale_popu_GKs"] -# scale_popu_GK1 = self._parameters["scale_popu_GK1"] -# scale_popu_GbK = self._parameters["scale_popu_GbK"] -# scale_popu_KNCX = self._parameters["scale_popu_KNCX"] -# scale_popu_KNaK = self._parameters["scale_popu_KNaK"] -# scale_popu_GbNa = self._parameters["scale_popu_GbNa"] -# scale_popu_GbCa = self._parameters["scale_popu_GbCa"] -# scale_popu_KpCa = self._parameters["scale_popu_KpCa"] -# # Systolic Heart Failure (HF with preserved ejection fraction) -# HF_scaling_CaMKa = self._parameters["HF_scaling_CaMKa"] -# HF_scaling_GNaL = self._parameters["HF_scaling_GNaL"] -# HF_scaling_GK1 = self._parameters["HF_scaling_GK1"] -# HF_scaling_Gto = self._parameters["HF_scaling_Gto"] -# HF_scaling_Gncx = self._parameters["HF_scaling_Gncx"] -# HF_scaling_Pnak = self._parameters["HF_scaling_Pnak"] - -# # Init return args -# current = [ufl.zero()] * 1 - -# # Expressions for the CaMKt component -# CaMKb = CaMKo * (1.0 - CaMKt) / (1.0 + KmCaM / cass) -# CaMKa = (CaMKb + CaMKt) * HF_scaling_CaMKa - -# # Expressions for the reversal potentials component -# ENa = R * T * ufl.ln(nao / nai) / F -# EK = R * T * ufl.ln(ko / ki) / F -# EKs = R * T * ufl.ln((ko + PKNa * nao) / (PKNa * nai + ki)) / F -# vffrt = (F * F) * v / (R * T) -# vfrt = F * v / (R * T) - -# # Expressions for the I_Na component -# Ahs = 1.0 - Ahf -# h = Ahf * hf + Ahs * hs -# hp = Ahf * hf + Ahs * hsp -# fINap = 1.0 / (1.0 + KmCaMK / CaMKa) -# INa = ( -# GNa -# * scale_drug_INa -# * scale_popu_GNa -# * ufl.elem_pow(m, 3.0) -# * (-ENa + v) -# * ((1.0 - fINap) * h * j + fINap * hp * jp) -# ) - -# # Expressions for the INaL component -# GNaL = 0.0075 * scale_INaL * scale_drug_INaL * scale_popu_GNaL * HF_scaling_GNaL -# fINaLp = 1.0 / (1.0 + KmCaMK / CaMKa) -# INaL = (-ENa + v) * ((1.0 - fINaLp) * hL + fINaLp * hLp) * GNaL * mL - -# # Expressions for the Ito component -# AiF = 1.0 / (1.0 + 0.24348537187522867 * ufl.exp(0.006613756613756614 * v)) -# AiS = 1.0 - AiF -# i = AiF * iF + AiS * iS -# ip = AiF * iFp + AiS * iSp -# fItop = 1.0 / (1.0 + KmCaMK / CaMKa) -# Ito = ( -# Gto -# * scale_drug_Ito -# * scale_popu_Gto -# * HF_scaling_Gto -# * (-EK + v) -# * ((1.0 - fItop) * a * i + ap * fItop * ip) -# ) - -# # Expressions for the ICaL ICaNa ICaK component -# Afs = 1.0 - Aff -# f = Aff * ff + Afs * fs -# Afcaf = 0.3 + 0.6 / (1.0 + 0.36787944117144233 * ufl.exp(0.1 * v)) -# Afcas = 1.0 - Afcaf -# fca = Afcaf * fcaf + Afcas * fcas -# fp = Aff * ffp + Afs * fs -# fcap = Afcaf * fcafp + Afcas * fcas -# PhiCaL = ( -# 4.0 -# * (-0.341 * cao + cass * ufl.exp(2.0 * vfrt)) -# * vffrt -# / (-1.0 + ufl.exp(2.0 * vfrt)) -# ) -# PhiCaNa = ( -# 1.0 -# * (-0.75 * nao + 0.75 * ufl.exp(1.0 * vfrt) * nass) -# * vffrt -# / (-1.0 + ufl.exp(1.0 * vfrt)) -# ) -# PhiCaK = ( -# 1.0 -# * (-0.75 * ko + 0.75 * ufl.exp(1.0 * vfrt) * kss) -# * vffrt -# / (-1.0 + ufl.exp(1.0 * vfrt)) -# ) -# PCa = 0.0001 * scale_ICaL * scale_drug_ICaL * scale_popu_GCaL -# PCap = 1.1 * PCa -# PCaNa = 0.00125 * PCa -# PCaK = 0.0003574 * PCa -# PCaNap = 0.00125 * PCap -# PCaKp = 0.0003574 * PCap -# fICaLp = 1.0 / (1.0 + KmCaMK / CaMKa) -# ICaL = (1.0 - fICaLp) * ( -# (1.0 - nca) * f + fca * jca * nca -# ) * PCa * PhiCaL * d + ( -# (1.0 - nca) * fp + fcap * jca * nca -# ) * PCap * PhiCaL * d * fICaLp -# ICaNa = (1.0 - fICaLp) * ( -# (1.0 - nca) * f + fca * jca * nca -# ) * PCaNa * PhiCaNa * d + ( -# (1.0 - nca) * fp + fcap * jca * nca -# ) * PCaNap * PhiCaNa * d * fICaLp -# ICaK = (1.0 - fICaLp) * ( -# (1.0 - nca) * f + fca * jca * nca -# ) * PCaK * PhiCaK * d + ( -# (1.0 - nca) * fp + fcap * jca * nca -# ) * PCaKp * PhiCaK * d * fICaLp - -# # Expressions for the IKr component -# Axrf = 1.0 / (1.0 + 4.197299094734718 * ufl.exp(0.02617115938236064 * v)) -# Axrs = 1.0 - Axrf -# xr = Axrf * xrf + Axrs * xrs -# rkr = 1.0 / ( -# (1.0 + 2.0820090840784555 * ufl.exp(0.013333333333333334 * v)) -# * (1.0 + 0.7165313105737893 * ufl.exp(0.03333333333333333 * v)) -# ) -# GKr = 0.046 * scale_IKr * scale_drug_IKr * scale_popu_GKr -# IKr = 0.4303314829119352 * ufl.sqrt(ko) * (-EK + v) * GKr * rkr * xr - -# # Expressions for the IKs component -# KsCa = 1.0 + 0.6 / (1.0 + 6.481821026062645e-07 * ufl.elem_pow(1.0 / cai, 1.4)) -# GKs = 0.0034 * scale_IKs * scale_drug_IKs * scale_popu_GKs -# IKs = (-EKs + v) * GKs * KsCa * xs1 * xs2 -# rk1 = 1.0 / ( -# 1.0 -# + 69220.6322106767 -# * ufl.exp(0.10534077741493732 * v - 0.27388602127883704 * ko) -# ) -# GK1 = 0.1908 * scale_IK1 * scale_drug_IK1 * scale_popu_GK1 * HF_scaling_GK1 -# IK1 = ufl.sqrt(ko) * (-EK + v) * GK1 * rk1 * xk1 - -# # Expressions for the INaCa_i component -# hca = ufl.exp(F * qca * v / (R * T)) -# hna = ufl.exp(F * qna * v / (R * T)) -# h1_i = 1 + (1 + hna) * nai / kna3 -# h2_i = hna * nai / (kna3 * h1_i) -# h3_i = 1.0 / h1_i -# h4_i = 1.0 + (1 + nai / kna2) * nai / kna1 -# h5_i = (nai * nai) / (kna1 * kna2 * h4_i) -# h6_i = 1.0 / h4_i -# h7_i = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 -# h8_i = nao / (kna3 * h7_i * hna) -# h9_i = 1.0 / h7_i -# h10_i = 1.0 + kasymm + nao * (1.0 + nao / kna2) / kna1 -# h11_i = (nao * nao) / (kna1 * kna2 * h10_i) -# h12_i = 1.0 / h10_i -# k1_i = cao * kcaon * h12_i -# k2_i = kcaoff -# k3p_i = wca * h9_i -# k3pp_i = wnaca * h8_i -# k3_i = k3p_i + k3pp_i -# k4p_i = wca * h3_i / hca -# k4pp_i = wnaca * h2_i -# k4_i = k4p_i + k4pp_i -# k5_i = kcaoff -# k6_i = kcaon * cai * h6_i -# k7_i = wna * h2_i * h5_i -# k8_i = wna * h11_i * h8_i -# x1_i = (k2_i + k3_i) * k5_i * k7_i + (k6_i + k7_i) * k2_i * k4_i -# x2_i = (k1_i + k8_i) * k4_i * k6_i + (k4_i + k5_i) * k1_i * k7_i -# x3_i = (k2_i + k3_i) * k6_i * k8_i + (k6_i + k7_i) * k1_i * k3_i -# x4_i = (k1_i + k8_i) * k3_i * k5_i + (k4_i + k5_i) * k2_i * k8_i -# E1_i = x1_i / (x1_i + x2_i + x3_i + x4_i) -# E2_i = x2_i / (x1_i + x2_i + x3_i + x4_i) -# E3_i = x3_i / (x1_i + x2_i + x3_i + x4_i) -# E4_i = x4_i / (x1_i + x2_i + x3_i + x4_i) -# allo_i = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cai, 2.0)) -# zna = 1.0 -# JncxNa_i = E3_i * k4pp_i - E2_i * k3pp_i + 3.0 * E4_i * k7_i - 3.0 * E1_i * k8_i -# JncxCa_i = E2_i * k2_i - E1_i * k1_i -# INaCa_i = ( -# 0.8 -# * Gncx -# * scale_popu_KNCX -# * HF_scaling_Gncx -# * (zca * JncxCa_i + zna * JncxNa_i) -# * allo_i -# ) - -# # Expressions for the INaCa_ss component -# h1 = 1.0 + (1.0 + hna) * nass / kna3 -# h2 = hna * nass / (kna3 * h1) -# h3 = 1.0 / h1 -# h4 = 1.0 + (1 + nass / kna2) * nass / kna1 -# h5 = (nass * nass) / (kna1 * kna2 * h4) -# h6 = 1.0 / h4 -# h7 = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 -# h8 = nao / (kna3 * h7 * hna) -# h9 = 1.0 / h7 -# h10 = 1.0 + kasymm + nao * (1 + nao / kna2) / kna1 -# h11 = (nao * nao) / (kna1 * kna2 * h10) -# h12 = 1.0 / h10 -# k1 = cao * kcaon * h12 -# k2 = kcaoff -# k3p_ss = wca * h9 -# k3pp = wnaca * h8 -# k3 = k3p_ss + k3pp -# k4p_ss = wca * h3 / hca -# k4pp = wnaca * h2 -# k4 = k4p_ss + k4pp -# k5 = kcaoff -# k6 = kcaon * cass * h6 -# k7 = wna * h2 * h5 -# k8 = wna * h11 * h8 -# x1_ss = (k2 + k3) * k5 * k7 + (k6 + k7) * k2 * k4 -# x2_ss = (k1 + k8) * k4 * k6 + (k4 + k5) * k1 * k7 -# x3_ss = (k2 + k3) * k6 * k8 + (k6 + k7) * k1 * k3 -# x4_ss = (k1 + k8) * k3 * k5 + (k4 + k5) * k2 * k8 -# E1_ss = x1_ss / (x1_ss + x2_ss + x3_ss + x4_ss) -# E2_ss = x2_ss / (x1_ss + x2_ss + x3_ss + x4_ss) -# E3_ss = x3_ss / (x1_ss + x2_ss + x3_ss + x4_ss) -# E4_ss = x4_ss / (x1_ss + x2_ss + x3_ss + x4_ss) -# allo_ss = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cass, 2.0)) -# JncxNa_ss = E3_ss * k4pp - E2_ss * k3pp + 3.0 * E4_ss * k7 - 3.0 * E1_ss * k8 -# JncxCa_ss = E2_ss * k2 - E1_ss * k1 -# INaCa_ss = ( -# 0.2 -# * Gncx -# * scale_popu_KNCX -# * HF_scaling_Gncx -# * (zca * JncxCa_ss + zna * JncxNa_ss) -# * allo_ss -# ) - -# # Expressions for the INaK component -# Knai = Knai0 * ufl.exp(0.3333333333333333 * F * delta * v / (R * T)) -# Knao = Knao0 * ufl.exp(0.3333333333333333 * F * (1.0 - delta) * v / (R * T)) -# P = eP / (1.0 + H / Khp + nai / Knap + ki / Kxkur) -# a1 = ( -# k1p -# * ufl.elem_pow(nai / Knai, 3.0) -# / ( -# -1.0 -# + ufl.elem_pow(1.0 + ki / Kki, 2.0) -# + ufl.elem_pow(1.0 + nai / Knai, 3.0) -# ) -# ) -# b1 = MgADP * k1m -# a2 = k2p -# b2 = ( -# k2m -# * ufl.elem_pow(nao / Knao, 3.0) -# / ( -# -1.0 -# + ufl.elem_pow(1.0 + ko / Kko, 2.0) -# + ufl.elem_pow(1.0 + nao / Knao, 3.0) -# ) -# ) -# a3 = ( -# k3p -# * ufl.elem_pow(ko / Kko, 2.0) -# / ( -# -1.0 -# + ufl.elem_pow(1.0 + ko / Kko, 2.0) -# + ufl.elem_pow(1.0 + nao / Knao, 3.0) -# ) -# ) -# b3 = H * k3m * P / (1.0 + MgATP / Kmgatp) -# a4 = MgATP * k4p / (Kmgatp * (1.0 + MgATP / Kmgatp)) -# b4 = ( -# k4m -# * ufl.elem_pow(ki / Kki, 2.0) -# / ( -# -1.0 -# + ufl.elem_pow(1.0 + ki / Kki, 2.0) -# + ufl.elem_pow(1.0 + nai / Knai, 3.0) -# ) -# ) -# x1 = a1 * a2 * a4 + a1 * a2 * b3 + a2 * b3 * b4 + b2 * b3 * b4 -# x2 = a1 * a2 * a3 + a2 * a3 * b4 + a3 * b1 * b4 + b1 * b2 * b4 -# x3 = a2 * a3 * a4 + a3 * a4 * b1 + a4 * b1 * b2 + b1 * b2 * b3 -# x4 = a1 * a3 * a4 + a1 * a4 * b2 + a1 * b2 * b3 + b2 * b3 * b4 -# E1 = x1 / (x1 + x2 + x3 + x4) -# E2 = x2 / (x1 + x2 + x3 + x4) -# E3 = x3 / (x1 + x2 + x3 + x4) -# E4 = x4 / (x1 + x2 + x3 + x4) -# JnakNa = 3.0 * E1 * a3 - 3.0 * E2 * b3 -# JnakK = 2.0 * E4 * b1 - 2.0 * E3 * a1 -# INaK = Pnak * scale_popu_KNaK * HF_scaling_Pnak * (zk * JnakK + zna * JnakNa) - -# # Expressions for the IKb component -# xkb = 1.0 / (1.0 + 2.202363450949239 * ufl.exp(-0.05452562704471101 * v)) -# IKb = GKb * scale_popu_GbK * scale_drug_IKb * (-EK + v) * xkb - -# # Expressions for the INab component -# INab = ( -# PNab -# * scale_drug_INab -# * scale_popu_GbNa -# * (-nao + ufl.exp(vfrt) * nai) -# * vffrt -# / (-1.0 + ufl.exp(vfrt)) -# ) - -# # Expressions for the ICab component -# ICab = ( -# 4.0 -# * PCab -# * scale_drug_ICab -# * scale_popu_GbCa -# * (-0.341 * cao + cai * ufl.exp(2.0 * vfrt)) -# * vffrt -# / (-1.0 + ufl.exp(2.0 * vfrt)) -# ) - -# # Expressions for the IpCa component -# IpCa = GpCa * scale_drug_IpCa * scale_popu_KpCa * cai / (0.0005 + cai) - -# # Expressions for the Isac (Pueyo)--> ns + k component -# Gsac_ns = 0.006 * scale_drug_Isacns -# Esac_ns = -10.0 -# lambda_max = 1.1 -# Gsac_k = (0.2882 * 800.0 / 210.0) * scale_drug_Isack # Pueyo endo - -# Isac_P_ns = ufl.conditional( -# ufl.lt(self.lmbda, 1.0), -# 0.0, -# Gsac_ns * ((self.lmbda - 1.0) / (lambda_max - 1.0)) * (v - Esac_ns), -# ) -# Isac_P_k = ufl.conditional( -# ufl.lt(self.lmbda, 1.0), -# 0.0, -# Gsac_k -# * ((self.lmbda - 1.0) / (lambda_max - 1.0)) -# * (1.0 / (1.0 + ufl.exp((19.05 - v) / (29.98)))), -# ) - -# # Expressions for the Istim component -# Istim = 0 # amp*(ufl.le(time, duration)) - -# # Expressions for the membrane potential component -# current[0] = ( -# -Isac_P_k -# - Isac_P_ns -# - ICaK -# - ICaL -# - ICaNa -# - ICab -# - IK1 -# - IKb -# - IKr -# - IKs -# - INa -# - INaCa_i -# - INaCa_ss -# - INaK -# - INaL -# - INab -# - IpCa -# - Istim -# - Ito -# ) - -# # Return results -# return current[0] - -# def I(self, v, s, time=None): # noqa: E741, E743 -# """ -# Transmembrane current -# I = -dV/dt -# """ -# return -self._I(v, s, time) - -# def F(self, v, s, time=None): -# """ -# Right hand side for ODE system -# """ -# logger.debug("Evaluate RHS") -# time = time if time else Constant(0.0) - -# # Assign states -# assert len(s) == 45 -# ( -# CaMKt, -# m, -# hf, -# hs, -# j, -# hsp, -# jp, -# mL, -# hL, -# hLp, -# a, -# iF, -# iS, -# ap, -# iFp, -# iSp, -# d, -# ff, -# fs, -# fcaf, -# fcas, -# jca, -# ffp, -# fcafp, -# nca, -# xrf, -# xrs, -# xs1, -# xs2, -# xk1, -# Jrelnp, -# Jrelp, -# nai, -# nass, -# ki, -# kss, -# cass, -# cansr, -# cajsr, -# XS, -# XW, -# CaTrpn, -# TmB, -# Cd, -# cai, -# ) = s - -# # Assign parameters -# scale_ICaL = self._parameters["scale_ICaL"] -# scale_IK1 = self._parameters["scale_IK1"] -# scale_IKr = self._parameters["scale_IKr"] -# scale_IKs = self._parameters["scale_IKs"] -# scale_INaL = self._parameters["scale_INaL"] -# cao = self._parameters["cao"] -# ko = self._parameters["ko"] -# nao = self._parameters["nao"] -# F = self._parameters["F"] -# R = self._parameters["R"] -# T = self._parameters["T"] -# L = self._parameters["L"] -# rad = self._parameters["rad"] -# CaMKo = self._parameters["CaMKo"] -# KmCaM = self._parameters["KmCaM"] -# KmCaMK = self._parameters["KmCaMK"] -# aCaMK = self._parameters["aCaMK"] -# bCaMK = self._parameters["bCaMK"] -# PKNa = self._parameters["PKNa"] -# Ahf = self._parameters["Ahf"] -# GNa = self._parameters["GNa"] -# thL = self._parameters["thL"] -# Gto = self._parameters["Gto"] -# delta_epi = self._parameters["delta_epi"] -# Aff = self._parameters["Aff"] -# Kmn = self._parameters["Kmn"] -# k2n = self._parameters["k2n"] -# tjca = self._parameters["tjca"] -# zca = self._parameters["zca"] -# Gncx = self._parameters["Gncx"] -# KmCaAct = self._parameters["KmCaAct"] -# kasymm = self._parameters["kasymm"] -# kcaoff = self._parameters["kcaoff"] -# kcaon = self._parameters["kcaon"] -# kna1 = self._parameters["kna1"] -# kna2 = self._parameters["kna2"] -# kna3 = self._parameters["kna3"] -# qca = self._parameters["qca"] -# qna = self._parameters["qna"] -# wca = self._parameters["wca"] -# wna = self._parameters["wna"] -# wnaca = self._parameters["wnaca"] -# H = self._parameters["H"] -# Khp = self._parameters["Khp"] -# Kki = self._parameters["Kki"] -# Kko = self._parameters["Kko"] -# Kmgatp = self._parameters["Kmgatp"] -# Knai0 = self._parameters["Knai0"] -# Knao0 = self._parameters["Knao0"] -# Knap = self._parameters["Knap"] -# Kxkur = self._parameters["Kxkur"] -# MgADP = self._parameters["MgADP"] -# MgATP = self._parameters["MgATP"] -# Pnak = self._parameters["Pnak"] -# delta = self._parameters["delta"] -# eP = self._parameters["eP"] -# k1m = self._parameters["k1m"] -# k1p = self._parameters["k1p"] -# k2m = self._parameters["k2m"] -# k2p = self._parameters["k2p"] -# k3m = self._parameters["k3m"] -# k3p = self._parameters["k3p"] -# k4m = self._parameters["k4m"] -# k4p = self._parameters["k4p"] -# zk = self._parameters["zk"] -# GKb = self._parameters["GKb"] -# PNab = self._parameters["PNab"] -# PCab = self._parameters["PCab"] -# GpCa = self._parameters["GpCa"] -# bt = self._parameters["bt"] -# BSLmax = self._parameters["BSLmax"] -# BSRmax = self._parameters["BSRmax"] -# KmBSL = self._parameters["KmBSL"] -# KmBSR = self._parameters["KmBSR"] -# cmdnmax = self._parameters["cmdnmax"] -# csqnmax = self._parameters["csqnmax"] -# kmcmdn = self._parameters["kmcmdn"] -# kmcsqn = self._parameters["kmcsqn"] -# trpnmax = self._parameters["trpnmax"] -# Beta1 = self._parameters["Beta1"] - -# Trpn50 = self._parameters["Trpn50"] -# cat50_ref = self._parameters["cat50_ref"] - -# etal = self._parameters["etal"] -# etas = self._parameters["etas"] -# gammas = self._parameters["gammas"] -# gammaw = self._parameters["gammaw"] -# ktrpn = self._parameters["ktrpn"] -# ku = self._parameters["ku"] -# kuw = self._parameters["kuw"] -# kws = self._parameters["kws"] -# # lmbda = self._parameters["lmbda"] -# ntm = self._parameters["ntm"] -# ntrpn = self._parameters["ntrpn"] -# p_k = self._parameters["p_k"] - -# rs = self._parameters["rs"] -# rw = self._parameters["rw"] - -# # Zetas = self._parameters["Zetas"] -# # Zetaw = self._parameters["Zetaw"] - -# # Drug factor -# scale_drug_INa = self._parameters["scale_drug_INa"] -# scale_drug_INaL = self._parameters["scale_drug_INaL"] -# scale_drug_Ito = self._parameters["scale_drug_Ito"] -# scale_drug_ICaL = self._parameters["scale_drug_ICaL"] -# scale_drug_IKr = self._parameters["scale_drug_IKr"] -# scale_drug_IKs = self._parameters["scale_drug_IKs"] -# scale_drug_IK1 = self._parameters["scale_drug_IK1"] -# scale_drug_IKb = self._parameters["scale_drug_IKb"] -# scale_drug_INab = self._parameters["scale_drug_INab"] -# scale_drug_ICab = self._parameters["scale_drug_ICab"] -# scale_drug_IpCa = self._parameters["scale_drug_IpCa"] -# scale_drug_Isacns = self._parameters["scale_drug_Isacns"] -# scale_drug_Isack = self._parameters["scale_drug_Isack"] - -# # Population factors -# scale_popu_GNa = self._parameters["scale_popu_GNa"] -# scale_popu_GCaL = self._parameters["scale_popu_GCaL"] -# scale_popu_Gto = self._parameters["scale_popu_Gto"] -# scale_popu_GNaL = self._parameters["scale_popu_GNaL"] -# scale_popu_GKr = self._parameters["scale_popu_GKr"] -# scale_popu_GKs = self._parameters["scale_popu_GKs"] -# scale_popu_GK1 = self._parameters["scale_popu_GK1"] -# scale_popu_GbK = self._parameters["scale_popu_GbK"] -# scale_popu_KNCX = self._parameters["scale_popu_KNCX"] -# scale_popu_KNaK = self._parameters["scale_popu_KNaK"] -# scale_popu_GbNa = self._parameters["scale_popu_GbNa"] -# scale_popu_GbCa = self._parameters["scale_popu_GbCa"] -# scale_popu_KpCa = self._parameters["scale_popu_KpCa"] -# scale_popu_KRyR = self._parameters["scale_popu_KRyR"] -# scale_popu_KSERCA = self._parameters["scale_popu_KSERCA"] -# scale_popu_Kleak = self._parameters["scale_popu_Kleak"] -# scale_popu_nTm = self._parameters["scale_popu_nTm"] -# scale_popu_CaT50ref = self._parameters["scale_popu_CaT50ref"] -# scale_popu_kuw = self._parameters["scale_popu_kuw"] -# scale_popu_kws = self._parameters["scale_popu_kws"] -# scale_popu_kTRPN = self._parameters["scale_popu_kTRPN"] -# scale_popu_nTRPN = self._parameters["scale_popu_nTRPN"] -# scale_popu_ku = self._parameters["scale_popu_ku"] -# scale_popu_TRPN50 = self._parameters["scale_popu_TRPN50"] -# scale_popu_rw = self._parameters["scale_popu_rw"] -# scale_popu_rs = self._parameters["scale_popu_rs"] - -# # Systolic Heart Failure (HF with preserved ejection fraction) -# HF_scaling_CaMKa = self._parameters["HF_scaling_CaMKa"] -# HF_scaling_Jrel_inf = self._parameters["HF_scaling_Jrel_inf"] -# HF_scaling_Jleak = self._parameters["HF_scaling_Jleak"] -# HF_scaling_Jup = self._parameters["HF_scaling_Jup"] -# HF_scaling_GNaL = self._parameters["HF_scaling_GNaL"] -# HF_scaling_GK1 = self._parameters["HF_scaling_GK1"] -# HF_scaling_thL = self._parameters["HF_scaling_thL"] -# HF_scaling_Gto = self._parameters["HF_scaling_Gto"] -# HF_scaling_Gncx = self._parameters["HF_scaling_Gncx"] -# HF_scaling_Pnak = self._parameters["HF_scaling_Pnak"] -# HF_scaling_cat50_ref = self._parameters["HF_scaling_cat50_ref"] - -# # Init return args -# F_expressions = [dolfin.Constant(0.0)] * 45 - -# # Expressions for the cell geometry component -# vcell = 3140.0 * L * (rad * rad) -# Ageo = 6.28 * (rad * rad) + 6.28 * L * rad -# Acap = 2 * Ageo -# vmyo = 0.68 * vcell -# vnsr = 0.0552 * vcell -# vjsr = 0.0048 * vcell -# vss = 0.02 * vcell - -# # Expressions for the CaMKt component -# CaMKb = CaMKo * (1.0 - CaMKt) / (1.0 + KmCaM / cass) -# CaMKa = (CaMKb + CaMKt) * HF_scaling_CaMKa -# F_expressions[0] = -bCaMK * CaMKt + aCaMK * (CaMKb + CaMKt) * CaMKb - -# # Expressions for the reversal potentials component -# ENa = R * T * ufl.ln(nao / nai) / F -# EK = R * T * ufl.ln(ko / ki) / F -# EKs = R * T * ufl.ln((ko + PKNa * nao) / (PKNa * nai + ki)) / F -# vffrt = (F * F) * v / (R * T) -# vfrt = F * v / (R * T) - -# # Expressions for the I_Na component -# mss = 1.0 / (1.0 + 0.0014599788446489682 * ufl.exp(-0.13333333333333333 * v)) -# tm = 1.0 / ( -# 9.454904638564724 * ufl.exp(0.02876042565429968 * v) -# + 1.9314113558536928e-05 * ufl.exp(-0.16792611251049538 * v) -# ) -# F_expressions[1] = (-m + mss) / tm -# hss = 1.0 / (1 + 302724.605401998 * ufl.exp(0.1607717041800643 * v)) -# thf = 1.0 / ( -# 1.183856958289087e-05 * ufl.exp(-0.15910898965791567 * v) -# + 6.305549185817275 * ufl.exp(0.0493339911198816 * v) -# ) -# ths = 1.0 / ( -# 0.005164670235381792 * ufl.exp(-0.035650623885918005 * v) -# + 0.36987619372096325 * ufl.exp(0.017649135192375574 * v) -# ) -# Ahs = 1.0 - Ahf -# F_expressions[2] = (-hf + hss) / thf -# F_expressions[3] = (-hs + hss) / ths -# h = Ahf * hf + Ahs * hs -# jss = hss -# tj = 2.038 + 1.0 / ( -# 0.3131936394738773 * ufl.exp(0.02600780234070221 * v) -# + 1.1315282095590072e-07 * ufl.exp(-0.12075836251660427 * v) -# ) -# F_expressions[4] = (-j + jss) / tj -# hssp = 1.0 / (1 + 820249.0921708513 * ufl.exp(0.1607717041800643 * v)) -# thsp = 3.0 * ths -# F_expressions[5] = (-hsp + hssp) / thsp -# hp = Ahf * hf + Ahs * hsp -# tjp = 1.46 * tj -# F_expressions[6] = (-jp + jss) / tjp -# fINap = 1.0 / (1.0 + KmCaMK / CaMKa) -# INa = ( -# GNa -# * scale_drug_INa -# * scale_popu_GNa -# * ufl.elem_pow(m, 3.0) -# * (-ENa + v) -# * ((1.0 - fINap) * h * j + fINap * hp * jp) -# ) - -# # Expressions for the INaL component -# mLss = 1.0 / (1.0 + 0.000291579585635531 * ufl.exp(-0.18996960486322187 * v)) -# tmL = tm -# F_expressions[7] = (-mL + mLss) / tmL -# hLss = 1.0 / (1.0 + 120578.15595522427 * ufl.exp(0.13354700854700854 * v)) -# F_expressions[8] = (-hL + hLss) / (thL * HF_scaling_thL) -# hLssp = 1.0 / (1.0 + 275969.2903869871 * ufl.exp(0.13354700854700854 * v)) -# thLp = 3.0 * thL * HF_scaling_thL -# F_expressions[9] = (-hLp + hLssp) / thLp -# GNaL = 0.0075 * scale_INaL * scale_drug_INaL * scale_popu_GNaL * HF_scaling_GNaL -# fINaLp = 1.0 / (1.0 + KmCaMK / CaMKa) -# INaL = (-ENa + v) * ((1.0 - fINaLp) * hL + fINaLp * hLp) * GNaL * mL - -# # Expressions for the Ito component -# ass = 1.0 / (1.0 + 2.6316508161673635 * ufl.exp(-0.06747638326585695 * v)) -# ta = 1.0515 / ( -# 1.0 / (1.2089 + 2.2621017070578837 * ufl.exp(-0.03403513787634354 * v)) -# + 3.5 / (1.0 + 30.069572727397507 * ufl.exp(0.03403513787634354 * v)) -# ) -# F_expressions[10] = (-a + ass) / ta -# iss = 1.0 / (1.0 + 2194.970764538301 * ufl.exp(0.17510068289266328 * v)) -# tiF = 4.562 + delta_epi / ( -# 0.14468698421272827 * ufl.exp(-0.01 * v) -# + 1.6300896349780942 * ufl.exp(0.06027727546714889 * v) -# ) -# tiS = 23.62 + delta_epi / ( -# 0.00027617763953377436 * ufl.exp(-0.01693480101608806 * v) -# + 0.024208962804604526 * ufl.exp(0.12377769525931426 * v) -# ) -# AiF = 1.0 / (1.0 + 0.24348537187522867 * ufl.exp(0.006613756613756614 * v)) -# AiS = 1.0 - AiF -# F_expressions[11] = (-iF + iss) / tiF -# F_expressions[12] = (-iS + iss) / tiS -# i = AiF * iF + AiS * iS -# assp = 1.0 / (1.0 + 5.167428462230666 * ufl.exp(-0.06747638326585695 * v)) -# F_expressions[13] = (-ap + assp) / ta -# dti_develop = 1.354 + 0.0001 / ( -# 2.6591269045230603e-05 * ufl.exp(0.06293266205160478 * v) -# + 4.5541779737128264e24 * ufl.exp(-4.642525533890436 * v) -# ) -# dti_recover = 1.0 - 0.5 / (1.0 + 33.11545195869231 * ufl.exp(0.05 * v)) -# tiFp = dti_develop * dti_recover * tiF -# tiSp = dti_develop * dti_recover * tiS -# F_expressions[14] = (-iFp + iss) / tiFp -# F_expressions[15] = (-iSp + iss) / tiSp -# ip = AiF * iFp + AiS * iSp -# fItop = 1.0 / (1.0 + KmCaMK / CaMKa) -# Ito = ( -# Gto -# * scale_drug_Ito -# * scale_popu_Gto -# * HF_scaling_Gto -# * (-EK + v) -# * ((1.0 - fItop) * a * i + ap * fItop * ip) -# ) - -# # Expressions for the ICaL ICaNa ICaK component -# dss = 1.0 / (1.0 + 0.39398514226669484 * ufl.exp(-0.23640661938534277 * v)) -# td = 0.6 + 1.0 / ( -# 3.5254214873653824 * ufl.exp(0.09 * v) -# + 0.7408182206817179 * ufl.exp(-0.05 * v) -# ) -# F_expressions[16] = (-d + dss) / td -# fss = 1.0 / (1.0 + 199.86038496778565 * ufl.exp(0.27056277056277056 * v)) -# tff = 7.0 + 1.0 / ( -# 0.03325075244518792 * ufl.exp(0.1 * v) -# + 0.0006090087745647571 * ufl.exp(-0.1 * v) -# ) -# tfs = 1000.0 + 1.0 / ( -# 1.0027667890106652e-05 * ufl.exp(-0.25 * v) -# + 8.053415618124885e-05 * ufl.exp(0.16666666666666666 * v) -# ) -# Afs = 1.0 - Aff -# F_expressions[17] = (-ff + fss) / tff -# F_expressions[18] = (-fs + fss) / tfs -# f = Aff * ff + Afs * fs -# fcass = fss -# tfcaf = 7.0 + 1.0 / ( -# 0.0708317980974062 * ufl.exp(-0.14285714285714285 * v) -# + 0.02258872488031037 * ufl.exp(0.14285714285714285 * v) -# ) -# tfcas = 100.0 + 1.0 / ( -# 0.00012 * ufl.exp(0.14285714285714285 * v) -# + 0.00012 * ufl.exp(-0.3333333333333333 * v) -# ) -# Afcaf = 0.3 + 0.6 / (1.0 + 0.36787944117144233 * ufl.exp(0.1 * v)) -# Afcas = 1.0 - Afcaf -# F_expressions[19] = (-fcaf + fcass) / tfcaf -# F_expressions[20] = (-fcas + fcass) / tfcas -# fca = Afcaf * fcaf + Afcas * fcas -# F_expressions[21] = (-jca + fcass) / tjca -# tffp = 2.5 * tff -# F_expressions[22] = (-ffp + fss) / tffp -# fp = Aff * ffp + Afs * fs -# tfcafp = 2.5 * tfcaf -# F_expressions[23] = (-fcafp + fcass) / tfcafp -# fcap = Afcaf * fcafp + Afcas * fcas -# km2n = 1.0 * jca -# anca = 1.0 / (ufl.elem_pow(1.0 + Kmn / cass, 4.0) + k2n / km2n) -# F_expressions[24] = k2n * anca - km2n * nca -# PhiCaL = ( -# 4.0 -# * (-0.341 * cao + cass * ufl.exp(2.0 * vfrt)) -# * vffrt -# / (-1.0 + ufl.exp(2.0 * vfrt)) -# ) -# PhiCaNa = ( -# 1.0 -# * (-0.75 * nao + 0.75 * ufl.exp(1.0 * vfrt) * nass) -# * vffrt -# / (-1.0 + ufl.exp(1.0 * vfrt)) -# ) -# PhiCaK = ( -# 1.0 -# * (-0.75 * ko + 0.75 * ufl.exp(1.0 * vfrt) * kss) -# * vffrt -# / (-1.0 + ufl.exp(1.0 * vfrt)) -# ) -# PCa = 0.0001 * scale_ICaL * scale_drug_ICaL * scale_popu_GCaL -# PCap = 1.1 * PCa -# PCaNa = 0.00125 * PCa -# PCaK = 0.0003574 * PCa -# PCaNap = 0.00125 * PCap -# PCaKp = 0.0003574 * PCap -# fICaLp = 1.0 / (1.0 + KmCaMK / CaMKa) -# ICaL = (1.0 - fICaLp) * ( -# (1.0 - nca) * f + fca * jca * nca -# ) * PCa * PhiCaL * d + ( -# (1.0 - nca) * fp + fcap * jca * nca -# ) * PCap * PhiCaL * d * fICaLp -# ICaNa = (1.0 - fICaLp) * ( -# (1.0 - nca) * f + fca * jca * nca -# ) * PCaNa * PhiCaNa * d + ( -# (1.0 - nca) * fp + fcap * jca * nca -# ) * PCaNap * PhiCaNa * d * fICaLp -# ICaK = (1.0 - fICaLp) * ( -# (1.0 - nca) * f + fca * jca * nca -# ) * PCaK * PhiCaK * d + ( -# (1.0 - nca) * fp + fcap * jca * nca -# ) * PCaKp * PhiCaK * d * fICaLp - -# # Expressions for the IKr component -# xrss = 1.0 / (1.0 + 0.29287308872377504 * ufl.exp(-0.14729709824716453 * v)) -# txrf = 12.98 + 1.0 / ( -# 0.0001020239312894894 * ufl.exp(0.25846471956577927 * v) -# + 0.00042992960891929087 * ufl.exp(-0.04906771344455348 * v) -# ) -# txrs = 1.865 + 1.0 / ( -# 0.0005922420036809394 * ufl.exp(0.13596193065941536 * v) -# + 3.549966111802463e-05 * ufl.exp(-0.03855050115651503 * v) -# ) -# Axrf = 1.0 / (1.0 + 4.197299094734718 * ufl.exp(0.02617115938236064 * v)) -# Axrs = 1.0 - Axrf -# F_expressions[25] = (-xrf + xrss) / txrf -# F_expressions[26] = (-xrs + xrss) / txrs -# xr = Axrf * xrf + Axrs * xrs -# rkr = 1.0 / ( -# (1.0 + 2.0820090840784555 * ufl.exp(0.013333333333333334 * v)) -# * (1.0 + 0.7165313105737893 * ufl.exp(0.03333333333333333 * v)) -# ) -# GKr = 0.046 * scale_IKr * scale_drug_IKr * scale_popu_GKr -# IKr = 0.4303314829119352 * ufl.sqrt(ko) * (-EK + v) * GKr * rkr * xr - -# # Expressions for the IKs component -# xs1ss = 1.0 / (1.0 + 0.27288596035656526 * ufl.exp(-0.11195700850873264 * v)) -# txs1 = 817.3 + 1.0 / ( -# 0.003504067763074858 * ufl.exp(0.056179775280898875 * v) -# + 0.0005184809083581659 * ufl.exp(-0.004347826086956522 * v) -# ) -# F_expressions[27] = (-xs1 + xs1ss) / txs1 -# xs2ss = xs1ss -# txs2 = 1.0 / ( -# 0.0022561357010639103 * ufl.exp(-0.03225806451612903 * v) -# + 0.0008208499862389881 * ufl.exp(0.05 * v) -# ) -# F_expressions[28] = (-xs2 + xs2ss) / txs2 -# KsCa = 1.0 + 0.6 / (1.0 + 6.481821026062645e-07 * ufl.elem_pow(1.0 / cai, 1.4)) -# GKs = 0.0034 * scale_IKs * scale_drug_IKs * scale_popu_GKs -# IKs = (-EKs + v) * GKs * KsCa * xs1 * xs2 -# xk1ss = 1.0 / ( -# 1.0 + ufl.exp((-144.59 - v - 2.5538 * ko) / (3.8115 + 1.5692 * ko)) -# ) -# txk1 = 122.2 / ( -# 0.0019352007631390235 * ufl.exp(-0.049115913555992145 * v) -# + 30.43364757524903 * ufl.exp(0.014423770373575654 * v) -# ) -# F_expressions[29] = (-xk1 + xk1ss) / txk1 -# rk1 = 1.0 / ( -# 1.0 -# + 69220.6322106767 -# * ufl.exp(0.10534077741493732 * v - 0.27388602127883704 * ko) -# ) -# GK1 = 0.1908 * scale_IK1 * scale_drug_IK1 * scale_popu_GK1 * HF_scaling_GK1 -# IK1 = ufl.sqrt(ko) * (-EK + v) * GK1 * rk1 * xk1 - -# # Expressions for the INaCa_i component -# hca = ufl.exp(F * qca * v / (R * T)) -# hna = ufl.exp(F * qna * v / (R * T)) -# h1_i = 1.0 + (1.0 + hna) * nai / kna3 -# h2_i = hna * nai / (kna3 * h1_i) -# h3_i = 1.0 / h1_i -# h4_i = 1.0 + (1 + nai / kna2) * nai / kna1 -# h5_i = (nai * nai) / (kna1 * kna2 * h4_i) -# h6_i = 1.0 / h4_i -# h7_i = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 -# h8_i = nao / (kna3 * h7_i * hna) -# h9_i = 1.0 / h7_i -# h10_i = 1.0 + kasymm + nao * (1.0 + nao / kna2) / kna1 -# h11_i = (nao * nao) / (kna1 * kna2 * h10_i) -# h12_i = 1.0 / h10_i -# k1_i = cao * kcaon * h12_i -# k2_i = kcaoff -# k3p_i = wca * h9_i -# k3pp_i = wnaca * h8_i -# k3_i = k3p_i + k3pp_i -# k4p_i = wca * h3_i / hca -# k4pp_i = wnaca * h2_i -# k4_i = k4p_i + k4pp_i -# k5_i = kcaoff -# k6_i = kcaon * cai * h6_i -# k7_i = wna * h2_i * h5_i -# k8_i = wna * h11_i * h8_i -# x1_i = (k2_i + k3_i) * k5_i * k7_i + (k6_i + k7_i) * k2_i * k4_i -# x2_i = (k1_i + k8_i) * k4_i * k6_i + (k4_i + k5_i) * k1_i * k7_i -# x3_i = (k2_i + k3_i) * k6_i * k8_i + (k6_i + k7_i) * k1_i * k3_i -# x4_i = (k1_i + k8_i) * k3_i * k5_i + (k4_i + k5_i) * k2_i * k8_i -# E1_i = x1_i / (x1_i + x2_i + x3_i + x4_i) -# E2_i = x2_i / (x1_i + x2_i + x3_i + x4_i) -# E3_i = x3_i / (x1_i + x2_i + x3_i + x4_i) -# E4_i = x4_i / (x1_i + x2_i + x3_i + x4_i) -# allo_i = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cai, 2.0)) -# zna = 1.0 -# JncxNa_i = E3_i * k4pp_i - E2_i * k3pp_i + 3.0 * E4_i * k7_i - 3.0 * E1_i * k8_i -# JncxCa_i = E2_i * k2_i - E1_i * k1_i -# INaCa_i = ( -# 0.8 -# * Gncx -# * scale_popu_KNCX -# * HF_scaling_Gncx -# * (zca * JncxCa_i + zna * JncxNa_i) -# * allo_i -# ) - -# # Expressions for the INaCa_ss component -# h1 = 1.0 + (1.0 + hna) * nass / kna3 -# h2 = hna * nass / (kna3 * h1) -# h3 = 1.0 / h1 -# h4 = 1.0 + (1 + nass / kna2) * nass / kna1 -# h5 = (nass * nass) / (kna1 * kna2 * h4) -# h6 = 1.0 / h4 -# h7 = 1.0 + nao * (1.0 + 1.0 / hna) / kna3 -# h8 = nao / (kna3 * h7 * hna) -# h9 = 1.0 / h7 -# h10 = 1.0 + kasymm + nao * (1 + nao / kna2) / kna1 -# h11 = (nao * nao) / (kna1 * kna2 * h10) -# h12 = 1.0 / h10 -# k1 = cao * kcaon * h12 -# k2 = kcaoff -# k3p_ss = wca * h9 -# k3pp = wnaca * h8 -# k3 = k3p_ss + k3pp -# k4p_ss = wca * h3 / hca -# k4pp = wnaca * h2 -# k4 = k4p_ss + k4pp -# k5 = kcaoff -# k6 = kcaon * cass * h6 -# k7 = wna * h2 * h5 -# k8 = wna * h11 * h8 -# x1_ss = (k2 + k3) * k5 * k7 + (k6 + k7) * k2 * k4 -# x2_ss = (k1 + k8) * k4 * k6 + (k4 + k5) * k1 * k7 -# x3_ss = (k2 + k3) * k6 * k8 + (k6 + k7) * k1 * k3 -# x4_ss = (k1 + k8) * k3 * k5 + (k4 + k5) * k2 * k8 -# E1_ss = x1_ss / (x1_ss + x2_ss + x3_ss + x4_ss) -# E2_ss = x2_ss / (x1_ss + x2_ss + x3_ss + x4_ss) -# E3_ss = x3_ss / (x1_ss + x2_ss + x3_ss + x4_ss) -# E4_ss = x4_ss / (x1_ss + x2_ss + x3_ss + x4_ss) -# allo_ss = 1.0 / (1.0 + ufl.elem_pow(KmCaAct / cass, 2.0)) -# JncxNa_ss = E3_ss * k4pp - E2_ss * k3pp + 3.0 * E4_ss * k7 - 3.0 * E1_ss * k8 -# JncxCa_ss = E2_ss * k2 - E1_ss * k1 -# INaCa_ss = ( -# 0.2 -# * Gncx -# * scale_popu_KNCX -# * HF_scaling_Gncx -# * (zca * JncxCa_ss + zna * JncxNa_ss) -# * allo_ss -# ) - -# # Expressions for the INaK component -# Knai = Knai0 * ufl.exp(0.3333333333333333 * F * delta * v / (R * T)) -# Knao = Knao0 * ufl.exp(0.3333333333333333 * F * (1.0 - delta) * v / (R * T)) -# P = eP / (1.0 + H / Khp + nai / Knap + ki / Kxkur) -# a1 = ( -# k1p -# * ufl.elem_pow(nai / Knai, 3.0) -# / ( -# -1.0 -# + ufl.elem_pow(1.0 + ki / Kki, 2.0) -# + ufl.elem_pow(1.0 + nai / Knai, 3.0) -# ) -# ) -# b1 = MgADP * k1m -# a2 = k2p -# b2 = ( -# k2m -# * ufl.elem_pow(nao / Knao, 3.0) -# / ( -# -1.0 -# + ufl.elem_pow(1.0 + ko / Kko, 2.0) -# + ufl.elem_pow(1.0 + nao / Knao, 3.0) -# ) -# ) -# a3 = ( -# k3p -# * ufl.elem_pow(ko / Kko, 2.0) -# / ( -# -1.0 -# + ufl.elem_pow(1.0 + ko / Kko, 2.0) -# + ufl.elem_pow(1.0 + nao / Knao, 3.0) -# ) -# ) -# b3 = H * k3m * P / (1.0 + MgATP / Kmgatp) -# a4 = MgATP * k4p / (Kmgatp * (1.0 + MgATP / Kmgatp)) -# b4 = ( -# k4m -# * ufl.elem_pow(ki / Kki, 2.0) -# / ( -# -1.0 -# + ufl.elem_pow(1.0 + ki / Kki, 2.0) -# + ufl.elem_pow(1.0 + nai / Knai, 3.0) -# ) -# ) -# x1 = a1 * a2 * a4 + a1 * a2 * b3 + a2 * b3 * b4 + b2 * b3 * b4 -# x2 = a1 * a2 * a3 + a2 * a3 * b4 + a3 * b1 * b4 + b1 * b2 * b4 -# x3 = a2 * a3 * a4 + a3 * a4 * b1 + a4 * b1 * b2 + b1 * b2 * b3 -# x4 = a1 * a3 * a4 + a1 * a4 * b2 + a1 * b2 * b3 + b2 * b3 * b4 -# E1 = x1 / (x1 + x2 + x3 + x4) -# E2 = x2 / (x1 + x2 + x3 + x4) -# E3 = x3 / (x1 + x2 + x3 + x4) -# E4 = x4 / (x1 + x2 + x3 + x4) -# JnakNa = 3.0 * E1 * a3 - 3.0 * E2 * b3 -# JnakK = 2.0 * E4 * b1 - 2.0 * E3 * a1 -# INaK = Pnak * scale_popu_KNaK * HF_scaling_Pnak * (zk * JnakK + zna * JnakNa) - -# # Expressions for the IKb component -# xkb = 1.0 / (1.0 + 2.202363450949239 * ufl.exp(-0.05452562704471101 * v)) -# IKb = GKb * scale_popu_GbK * scale_drug_IKb * (-EK + v) * xkb - -# # Expressions for the INab component -# INab = ( -# PNab -# * scale_drug_INab -# * scale_popu_GbNa -# * (-nao + ufl.exp(vfrt) * nai) -# * vffrt -# / (-1.0 + ufl.exp(vfrt)) -# ) - -# # Expressions for the ICab component -# ICab = ( -# 4.0 -# * PCab -# * scale_drug_ICab -# * scale_popu_GbCa -# * (-0.341 * cao + cai * ufl.exp(2.0 * vfrt)) -# * vffrt -# / (-1.0 + ufl.exp(2.0 * vfrt)) -# ) - -# # Expressions for the IpCa component -# IpCa = GpCa * scale_drug_IpCa * scale_popu_KpCa * cai / (0.0005 + cai) - -# # Expressions for the Isac (Pueyo)--> ns + k component -# Gsac_ns = 0.006 * scale_drug_Isacns -# Esac_ns = -10.0 -# lambda_max = 1.1 -# Gsac_k = (0.2882 * 800.0 / 210.0) * scale_drug_Isack # Pueyo endo -# Isac_P_ns = ufl.conditional( -# ufl.lt(self.lmbda, 1.0), -# 0.0, -# Gsac_ns * ((self.lmbda - 1.0) / (lambda_max - 1.0)) * (v - Esac_ns), -# ) -# Isac_P_k = ufl.conditional( -# ufl.lt(self.lmbda, 1.0), -# 0.0, -# Gsac_k -# * ((self.lmbda - 1.0) / (lambda_max - 1.0)) -# * (1.0 / (1.0 + ufl.exp((19.05 - v) / (29.98)))), -# ) - -# # Expressions for the Istim component -# Istim = 0 # amp*(ufl.le(time, duration)) - -# # Expressions for the diffusion fluxes component -# JdiffNa = 0.5 * nass - 0.5 * nai -# JdiffK = 0.5 * kss - 0.5 * ki -# Jdiff = 5.0 * cass - 5.0 * cai - -# # Expressions for the ryanodine receptor component -# a_rel = 0.5 * bt -# Jrel_inf = ( -# -ICaL -# * a_rel -# / (1.0 + 25.62890625 * HF_scaling_Jrel_inf * ufl.elem_pow(1.0 / cajsr, 8.0)) -# ) -# tau_rel_tmp = bt / (1.0 + 0.0123 / cajsr) -# tau_rel = ufl.conditional(ufl.lt(tau_rel_tmp, 0.001), 0.001, tau_rel_tmp) -# F_expressions[30] = (-Jrelnp + Jrel_inf) / tau_rel -# btp = 1.25 * bt -# a_relp = 0.5 * btp -# Jrel_infp = ( -# -ICaL -# * a_relp -# / (1.0 + 25.62890625 * HF_scaling_Jrel_inf * ufl.elem_pow(1.0 / cajsr, 8.0)) -# ) -# tau_relp_tmp = btp / (1.0 + 0.0123 / cajsr) -# tau_relp = ufl.conditional(ufl.lt(tau_relp_tmp, 0.001), 0.001, tau_relp_tmp) -# F_expressions[31] = (-Jrelp + Jrel_infp) / tau_relp -# fJrelp = 1.0 / (1.0 + KmCaMK / CaMKa) -# Jrel = ((1.0 - fJrelp) * Jrelnp + Jrelp * fJrelp) * scale_popu_KRyR - -# # Expressions for the calcium buffers component -# Jupnp = 0.004375 * cai / (0.00092 + cai) -# Jupp = 0.01203125 * cai / (0.00075 + cai) -# fJupp = 1.0 / (1.0 + KmCaMK / CaMKa) -# Jleak = 0.0002625 * cansr * scale_popu_Kleak * HF_scaling_Jleak -# Jup = ( -# -Jleak -# + ((1.0 - fJupp) * Jupnp + Jupp * fJupp) -# * scale_popu_KSERCA -# * HF_scaling_Jup -# ) -# Jtr = 0.01 * cansr - 0.01 * cajsr - -# # Expressions for the intracellular concentrations component -# F_expressions[32] = JdiffNa * vss / vmyo + ( -# -INa - INaL - INab - Isac_P_ns / 3.0 - 3.0 * INaCa_i - 3.0 * INaK -# ) * Acap / (F * vmyo) -# F_expressions[33] = -JdiffNa + (-ICaNa - 3.0 * INaCa_ss) * Acap / (F * vss) -# F_expressions[34] = JdiffK * vss / vmyo + ( -# -Isac_P_k -# - IK1 -# - IKb -# - IKr -# - IKs -# - Istim -# - Ito -# - Isac_P_ns / 3.0 -# + 2.0 * INaK -# ) * Acap / (F * vmyo) -# F_expressions[35] = -JdiffK - Acap * ICaK / (F * vss) -# Bcass = 1.0 / ( -# 1.0 -# + BSLmax * KmBSL * ufl.elem_pow(KmBSL + cass, -2.0) -# + BSRmax * KmBSR * ufl.elem_pow(KmBSR + cass, -2.0) -# ) -# F_expressions[36] = ( -# -Jdiff -# + Jrel * vjsr / vss -# + 0.5 * (-ICaL + 2.0 * INaCa_ss) * Acap / (F * vss) -# ) * Bcass -# F_expressions[37] = -Jtr * vjsr / vnsr + Jup -# Bcajsr = 1.0 / (1.0 + csqnmax * kmcsqn * ufl.elem_pow(kmcsqn + cajsr, -2.0)) -# F_expressions[38] = (-Jrel + Jtr) * Bcajsr - -# # Expressions for the mechanics component -# kwu = -kws * scale_popu_kws + (kuw * scale_popu_kuw) * ( -# -1.0 + 1.0 / (rw * scale_popu_rw) -# ) -# ksu = ( -# kws -# * scale_popu_kws -# * rw -# * scale_popu_rw -# * (-1.0 + 1.0 / (rs * scale_popu_rs)) -# ) - -# lambda_min12 = ufl.conditional(ufl.lt(self.lmbda, 1.2), self.lmbda, 1.2) -# XS = ufl.conditional(ufl.lt(XS, 0.0), 0.0, XS) -# XW = ufl.conditional(ufl.lt(XW, 0.0), 0.0, XW) - -# XU = 1.0 - TmB - XS - XW -# gammawu = gammaw * abs(self.Zetaw) -# # gammasu = gammas*ufl.conditional(ufl.gt(Zetas*(ufl.gt(Zetas, 0)), (-1 -\ -# # Zetas)*(ufl.lt(Zetas, -1))), Zetas*(ufl.gt(Zetas, 0)), (-1 -\ -# # Zetas)*(ufl.lt(Zetas, -1))) -# zetas1 = self.Zetas * ufl.conditional(ufl.gt(self.Zetas, 0.0), 1.0, 0.0) -# zetas2 = (-1.0 - self.Zetas) * ufl.conditional( -# ufl.lt(self.Zetas, -1.0), -# 1.0, -# 0.0, -# ) -# gammasu = gammas * Max(zetas1, zetas2) - -# F_expressions[39] = kws * scale_popu_kws * XW - XS * gammasu - XS * ksu -# F_expressions[40] = ( -# kuw * scale_popu_kuw * XU -# - kws * scale_popu_kws * XW -# - XW * gammawu -# - XW * kwu -# ) -# cat50 = ( -# cat50_ref * scale_popu_CaT50ref + Beta1 * (-1.0 + lambda_min12) -# ) * HF_scaling_cat50_ref -# CaTrpn = ufl.conditional(ufl.lt(CaTrpn, 0.0), 0.0, CaTrpn) -# F_expressions[41] = ( -# ktrpn -# * scale_popu_kTRPN -# * ( -# -CaTrpn -# + ufl.elem_pow(1000.0 * cai / cat50, ntrpn * scale_popu_nTRPN) -# * (1.0 - CaTrpn) -# ) -# ) -# kb = ( -# ku -# * scale_popu_ku -# * ufl.elem_pow(Trpn50 * scale_popu_TRPN50, (ntm * scale_popu_nTm)) -# / ( -# 1.0 -# - (rs * scale_popu_rs) -# - rw * scale_popu_rw * (1.0 - (rs * scale_popu_rs)) -# ) -# ) - -# F_expressions[42] = ( -# ufl.conditional( -# ufl.lt(ufl.elem_pow(CaTrpn, -(ntm * scale_popu_nTm) / 2.0), 100.0), -# ufl.elem_pow(CaTrpn, -(ntm * scale_popu_nTm) / 2.0), -# 100.0, -# ) -# * XU -# * kb -# - ku -# * scale_popu_ku -# * ufl.elem_pow(CaTrpn, (ntm * scale_popu_nTm) / 2.0) -# * TmB -# ) - -# C = -1.0 + lambda_min12 -# dCd = -Cd + C -# eta = ufl.conditional(ufl.lt(dCd, 0.0), etas, etal) -# F_expressions[43] = p_k * (-Cd + C) / eta -# Bcai = 1.0 / (1.0 + cmdnmax * kmcmdn * ufl.elem_pow(kmcmdn + cai, -2.0)) -# J_TRPN = trpnmax * F_expressions[41] -# F_expressions[44] = ( -# -J_TRPN -# + Jdiff * vss / vmyo -# - Jup * vnsr / vmyo -# + 0.5 * (-ICab - IpCa - Isac_P_ns / 3.0 + 2.0 * INaCa_i) * Acap / (F * vmyo) -# ) * Bcai - -# # Return results -# return as_vector(F_expressions) - -# def num_states(self): -# return 45 - -# def __str__(self): -# return "ORdmm_Land_em_coupling cardiac cell model" diff --git a/src/simcardems/models/fully_coupled_ORdmm_Land/em_model.py b/src/simcardems/models/fully_coupled_ORdmm_Land/em_model.py index 80617474..cadf12e3 100644 --- a/src/simcardems/models/fully_coupled_ORdmm_Land/em_model.py +++ b/src/simcardems/models/fully_coupled_ORdmm_Land/em_model.py @@ -130,7 +130,7 @@ def mech_state(self) -> dolfin.Function: @property def vs(self) -> np.ndarray: - return self.ep_solver.ode.values + return self.ep_solver.ode.full_values @property def assigners(self) -> datacollector.Assigners: @@ -291,7 +291,12 @@ def save_state( with io.h5pyfile(path, "a") as h5file: h5file["ep/vs"] = self.vs - h5file["ep/cell_params"] = self.cell_params() + cell_params = self.cell_params() + if isinstance(cell_params, dict): + for k, v in cell_params.items(): + h5file[f"ep/cell_params/{k}"] = v + else: + h5file["ep/cell_params"] = cell_params @classmethod def from_state( diff --git a/src/simcardems/models/pureEP_ORdmm_Land/em_model.py b/src/simcardems/models/pureEP_ORdmm_Land/em_model.py index 37f429d5..e0e8950f 100644 --- a/src/simcardems/models/pureEP_ORdmm_Land/em_model.py +++ b/src/simcardems/models/pureEP_ORdmm_Land/em_model.py @@ -33,7 +33,7 @@ def coupling_type(self): @property def vs(self) -> np.ndarray: - return self.ep_solver.ode.values + return self.ep_solver.ode.full_values def register_ep_model(self, solver: beat.MonodomainSplittingSolver): logger.debug("Registering EP model") diff --git a/src/simcardems/runner.py b/src/simcardems/runner.py index aa006d5b..2ecc82fe 100644 --- a/src/simcardems/runner.py +++ b/src/simcardems/runner.py @@ -197,6 +197,7 @@ def solve( # Solve EP model self.coupling.t = TimeStepper.ns2ms(t) self.coupling.solve_ep((TimeStepper.ns2ms(t0), TimeStepper.ns2ms(t))) + # breakpoint() self._post_ep() if self._solve_mechanics_now(): From eca027f141e577ee3ef643238b070da5f71aba97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9cile?= Date: Fri, 15 Mar 2024 11:52:48 +0100 Subject: [PATCH 6/7] Add pcl as input to get_biomarkers (pacing depends on pcl) + fix time to min displacement in case we don't start at t=0 --- src/simcardems/postprocess.py | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/simcardems/postprocess.py b/src/simcardems/postprocess.py index 69d1a0a7..9726648d 100644 --- a/src/simcardems/postprocess.py +++ b/src/simcardems/postprocess.py @@ -451,19 +451,25 @@ def extract_biomarkers( for name, arr in zip(["norm", "x", "y", "z"], [u_norm, ux, uy, uz]): d[f"max_displacement_{name}"] = np.max(arr) d[f"min_displacement_{name}"] = np.min(arr) - d[f"time_to_max_displacement_{name}"] = apf.features.time_to_peak( - y=arr, - x=time, + d[f"time_to_max_displacement_{name}"] = ( + apf.features.time_to_peak( + y=arr, + x=time, + ) + - time[0] ) - d[f"time_to_min_displacement_{name}"] = apf.features.time_to_peak( - y=-arr, - x=time, + d[f"time_to_min_displacement_{name}"] = ( + apf.features.time_to_peak( + y=-arr, + x=time, + ) + - time[0] ) return d -def get_biomarkers(results, outdir, num_models): +def get_biomarkers(results, outdir, num_models, pcl): biomarker_dict = {} fig, ax = plt.subplots() for PoMm in range(1, num_models + 1): @@ -473,7 +479,7 @@ def get_biomarkers(results, outdir, num_models): V = results[f"m{PoMm}"]["ep"]["V"] Ca = results[f"m{PoMm}"]["ep"]["Ca"] Ta = results[f"m{PoMm}"]["mechanics"]["Ta"] - lmbda = results[f"m{PoMm}"]["mechanics"]["lmbda"] + # lmbda = results[f"m{PoMm}"]["mechanics"]["lmbda"] u = results[f"m{PoMm}"]["mechanics"]["u"] inv_lmbda = results[f"m{PoMm}"]["mechanics"]["inv_lmbda"] @@ -486,7 +492,7 @@ def get_biomarkers(results, outdir, num_models): # Create a list with pacing indicators pacing = np.zeros_like(time) for i in range(0, len(pacing)): - if time[i] % 1000 <= 0.09 or i == 0: + if time[i] % pcl <= 0.09 or i == 0: pacing[i] = 1 # Overwrite the variables with data from only the last beat @@ -496,9 +502,10 @@ def get_biomarkers(results, outdir, num_models): pacing, return_interval=True, ) + Ca = Ca[interval[0] : interval[1]] Ta = Ta[interval[0] : interval[1]] - lmbda = lmbda[interval[0] : interval[1]] + # lmbda = lmbda[interval[0] : interval[1]] u = u[interval[0] : interval[1], :] inv_lmbda = inv_lmbda[interval[0] : interval[1]] @@ -515,7 +522,7 @@ def get_biomarkers(results, outdir, num_models): Ta=Ta, time=time, Ca=Ca, - lmbda=lmbda, + # lmbda=lmbda, inv_lmbda=inv_lmbda, u=u, ) From 3e9a7f6e2da6e2c21d2c1f0bc0ff5e8180ecd7c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9cile?= Date: Fri, 15 Mar 2024 13:17:33 +0100 Subject: [PATCH 7/7] Add default value for pcl --- src/simcardems/postprocess.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/simcardems/postprocess.py b/src/simcardems/postprocess.py index 9726648d..7524ec70 100644 --- a/src/simcardems/postprocess.py +++ b/src/simcardems/postprocess.py @@ -469,7 +469,7 @@ def extract_biomarkers( return d -def get_biomarkers(results, outdir, num_models, pcl): +def get_biomarkers(results, outdir, num_models, pcl=1000): biomarker_dict = {} fig, ax = plt.subplots() for PoMm in range(1, num_models + 1):