def inside_absorption_bounds_conditional(self, E, value): E_L, E_U = self.get_absorption_bounds() E_L = E_L.m_as('eV') E_U = E_U.m_as('eV') E = E.m_as('eV') return value.units * dolfin.conditional( ufl.And(E_L <= E, E < E_U), value.magnitude, 0)
def _I(self, v, s, time): """ Original gotran transmembrane current dV/dt """ time = time if time else Constant(0.0) # Assign states V = v assert(len(s) == 7) m, h, j, Cai, d, f, x1 = s # Assign parameters E_Na = self._parameters["E_Na"] g_Na = self._parameters["g_Na"] g_Nac = self._parameters["g_Nac"] g_s = self._parameters["g_s"] IstimAmplitude = self._parameters["IstimAmplitude"] IstimPulseDuration = self._parameters["IstimPulseDuration"] IstimStart = self._parameters["IstimStart"] C = self._parameters["C"] # Init return args current = [ufl.zero()]*1 # Expressions for the Sodium current component i_Na = (g_Nac + g_Na*(m*m*m)*h*j)*(-E_Na + V) # Expressions for the Slow inward current component E_s = -82.3 - 13.0287*ufl.ln(0.001*Cai) i_s = g_s*(-E_s + V)*d*f # Expressions for the Time dependent outward current component i_x1 = 0.00197277571153*(-1 +\ 21.7584023962*ufl.exp(0.04*V))*ufl.exp(-0.04*V)*x1 # Expressions for the Time independent outward current component i_K1 = 0.0035*(-4 +\ 119.85640019*ufl.exp(0.04*V))/(8.33113748769*ufl.exp(0.04*V) +\ 69.4078518388*ufl.exp(0.08*V)) + 0.0035*(4.6 + 0.2*V)/(1 -\ 0.398519041085*ufl.exp(-0.04*V)) # Expressions for the Stimulus protocol component Istim = ufl.conditional(ufl.And(ufl.ge(time, IstimStart),\ ufl.le(time, IstimPulseDuration + IstimStart)), IstimAmplitude,\ 0) # Expressions for the Membrane component current[0] = (-i_K1 + Istim - i_Na - i_x1 - i_s)/C # Return results return current[0]
def _I(self, v, s, time): """ Original gotran transmembrane current dV/dt """ time = time if time else Constant(0.0) # Assign states V = v # Assign parameters g_leak = self._parameters["g_L"] Cm = self._parameters["Cm"] E_leak = self._parameters["E_L"] stim_type = self._parameters["stim_type"] g_s = self._parameters["g_S"] alpha = self._parameters["alpha"] v_eq = self._parameters["v_eq"] t0 = self._parameters["t_start"] t1 = self._parameters["t_stop"] # Init return args current = [ufl.zero()] * 1 # Expressions for the Membrane component if stim_type == 0: i_stim = g_s * (-v_eq + V) * ufl.conditional( ufl.ge(time, t0), 1, 0) * ufl.exp((t0 - time) / alpha) elif stim_type == 1: i_stim = -g_s * ufl.conditional(ufl.ge(time, t0), 1, 0) elif stim_type == 2: i_stim = -g_s * ufl.conditional( ufl.And(ufl.ge(time, t0), ufl.le(time, t1)), 1, 0) i_leak = g_leak * (-E_leak + V) current[0] = (-i_leak - i_stim) / Cm # Return results return current[0]
def _I(self, v, s, time): """ Original gotran transmembrane current dV/dt """ time = time if time else Constant(0.0) # Assign states V = v assert(len(s) == 2) m, h = s # Assign parameters amp = self._parameters["amp"] duration = self._parameters["duration"] stimStart = self._parameters["stimStart"] E_Na = self._parameters["E_Na"] g_Na = self._parameters["g_Na"] E_K = self._parameters["E_K"] g_K = self._parameters["g_K"] k_r = self._parameters["k_r"] # Init return args current = [ufl.zero()]*1 # Expressions for the Fast sodium current component i_Na = g_Na*ufl.elem_pow(m, 3.0)*(-E_Na + V)*h # Expressions for the Potassium current component i_K = g_K*(-E_K + V)*ufl.exp((E_K - V)/k_r) # Expressions for the Membrane component i_stim = ufl.conditional(ufl.And(ufl.gt(time, stimStart),\ ufl.le(time, duration + stimStart)), amp, 0) current[0] = -i_K - i_Na - i_stim # Return results return current[0]
def F(self, v, s, time=None): """ Right hand side for ODE system """ time = time if time else Constant(0.0) # Assign states V = v assert (len(s) == 17) m, h, j, d, f1, f2, fCa, Xr1, Xr2, Xs, Xf, q, r, Nai, g, Cai, Ca_SR = s # Assign parameters TTX_10uM = self._parameters["TTX_10uM"] TTX_30uM = self._parameters["TTX_30uM"] TTX_3uM = self._parameters["TTX_3uM"] nifed_100nM = self._parameters["nifed_100nM"] nifed_10nM = self._parameters["nifed_10nM"] nifed_30nM = self._parameters["nifed_30nM"] nifed_3nM = self._parameters["nifed_3nM"] g_Na = self._parameters["g_Na"] g_CaL = self._parameters["g_CaL"] tau_fCa = self._parameters["tau_fCa"] L0 = self._parameters["L0"] Q = self._parameters["Q"] g_b_Na = self._parameters["g_b_Na"] g_b_Ca = self._parameters["g_b_Ca"] Km_K = self._parameters["Km_K"] Km_Na = self._parameters["Km_Na"] PNaK = self._parameters["PNaK"] KmCa = self._parameters["KmCa"] KmNai = self._parameters["KmNai"] Ksat = self._parameters["Ksat"] alpha = self._parameters["alpha"] gamma = self._parameters["gamma"] kNaCa = self._parameters["kNaCa"] KPCa = self._parameters["KPCa"] g_PCa = self._parameters["g_PCa"] Cao = self._parameters["Cao"] Cm = self._parameters["Cm"] F = self._parameters["F"] Ko = self._parameters["Ko"] Nao = self._parameters["Nao"] R = self._parameters["R"] T = self._parameters["T"] V_SR = self._parameters["V_SR"] Vc = self._parameters["Vc"] Buf_C = self._parameters["Buf_C"] Buf_SR = self._parameters["Buf_SR"] Kbuf_C = self._parameters["Kbuf_C"] Kbuf_SR = self._parameters["Kbuf_SR"] Kup = self._parameters["Kup"] V_leak = self._parameters["V_leak"] VmaxUp = self._parameters["VmaxUp"] a_rel = self._parameters["a_rel"] b_rel = self._parameters["b_rel"] c_rel = self._parameters["c_rel"] tau_g = self._parameters["tau_g"] # Init return args F_expressions = [ufl.zero()] * 17 # Expressions for the Electric potentials component E_Na = R * T * ufl.ln(Nao / Nai) / F E_Ca = 0.5 * R * T * ufl.ln(Cao / Cai) / F # Expressions for the i_Na component TTX_coeff = ufl.conditional(ufl.eq(TTX_3uM, 1), 0.18,\ ufl.conditional(ufl.eq(TTX_10uM, 1), 0.06,\ ufl.conditional(ufl.eq(TTX_30uM, 1), 0.02, 1))) i_Na = g_Na * (m * m * m) * (-E_Na + V) * TTX_coeff * h * j # Expressions for the m gate component m_inf = 1.0*ufl.elem_pow(1 +\ 0.00308976260789*ufl.exp(-169.491525424*V), -0.333333333333) alpha_m = 1.0 / (1 + 6.14421235333e-06 * ufl.exp(-200.0 * V)) beta_m = 0.1/(1 + 1096.63315843*ufl.exp(200.0*V)) + 0.1/(1 +\ 0.778800783071*ufl.exp(5.0*V)) tau_m = 0.001 * alpha_m * beta_m F_expressions[0] = (-m + m_inf) / tau_m # Expressions for the h gate component h_inf = 1.0 / ufl.sqrt(1 + 311490.091283 * ufl.exp(175.438596491 * V)) alpha_h = ufl.conditional(ufl.lt(V, -0.04),\ 4.43126792958e-07*ufl.exp(-147.058823529*V), 0) beta_h = ufl.conditional(ufl.lt(V, -0.04), 310000.0*ufl.exp(348.5*V)\ + 2.7*ufl.exp(79.0*V), 0.77/(0.13 +\ 0.0497581410839*ufl.exp(-90.0900900901*V))) tau_h = ufl.conditional(ufl.lt(V, -0.04), 1.5/(1000*alpha_h +\ 1000*beta_h), 0.002542) F_expressions[1] = (-h + h_inf) / tau_h # Expressions for the j gate component j_inf = 1.0 / ufl.sqrt(1 + 311490.091283 * ufl.exp(175.438596491 * V)) alpha_j = ufl.conditional(ufl.lt(V, -0.04), (37.78 +\ 1000*V)*(-25428*ufl.exp(244.4*V) -\ 6.948e-06*ufl.exp(-43.91*V))/(1 +\ 50262745826.0*ufl.exp(311.0*V)), 0) beta_j = ufl.conditional(ufl.lt(V, -0.04),\ 0.02424*ufl.exp(-10.52*V)/(1 +\ 0.0039608683399*ufl.exp(-137.8*V)), 0.6*ufl.exp(57.0*V)/(1 +\ 0.0407622039784*ufl.exp(-100.0*V))) tau_j = 7.0 / (1000 * alpha_j + 1000 * beta_j) F_expressions[2] = (-j + j_inf) / tau_j # Expressions for the i_CaL component nifed_coeff = ufl.conditional(ufl.eq(nifed_3nM, 1), 0.93,\ ufl.conditional(ufl.eq(nifed_10nM, 1), 0.79,\ ufl.conditional(ufl.eq(nifed_30nM, 1), 0.56,\ ufl.conditional(ufl.eq(nifed_100nM, 1), 0.28, 1)))) i_CaL = 4*g_CaL*(F*F)*(-0.341*Cao +\ Cai*ufl.exp(2*F*V/(R*T)))*V*d*f1*f2*fCa*nifed_coeff/(R*T*(-1 +\ ufl.exp(2*F*V/(R*T)))) # Expressions for the d gate component d_infinity = 1.0 / (1 + 0.272531793034 * ufl.exp(-1000 * V / 7)) alpha_d = 0.25 + 1.4 / (1 + ufl.exp(-35 / 13 - 1000 * V / 13)) beta_d = 1.4 / (1 + ufl.exp(1 + 200 * V)) gamma_d = 1.0 / (1 + ufl.exp(5 / 2 - 50 * V)) tau_d = 0.001 * gamma_d + 0.001 * alpha_d * beta_d F_expressions[3] = (-d + d_infinity) / tau_d # Expressions for the F1 gate component f1_inf = 1.0 / (1 + ufl.exp(26 / 3 + 1000 * V / 3)) constf1 = ufl.conditional(ufl.gt(-f1 + f1_inf, 0), 0.92835 +\ 1433*Cai, 1) tau_f1 = 0.001*(20 + 200.0/(1 + ufl.exp(13/10 - 100*V)) + 180.0/(1 +\ ufl.exp(3 + 100*V)) +\ 1102.5*ufl.exp(-0.00444444444444*ufl.elem_pow(27 + 1000*V,\ 4)))*constf1 F_expressions[4] = (-f1 + f1_inf) / tau_f1 # Expressions for the F2 gate component f2_inf = 0.33 + 0.67 / (1 + ufl.exp(35 / 4 + 250 * V)) constf2 = 1 tau_f2 = 0.001*constf2*(600*ufl.exp(-((25 + 1000*V)*(25 +\ 1000*V))/170) + 16.0/(1 + ufl.exp(3 + 100*V)) + 31.0/(1 +\ ufl.exp(5/2 - 100*V))) F_expressions[5] = (-f2 + f2_inf) / tau_f2 # Expressions for the FCa gate component alpha_fCa = 1.0 / (1 + 5.95374180765e+25 * ufl.elem_pow(Cai, 8)) beta_fCa = 0.1 / (1 + 0.000123409804087 * ufl.exp(10000.0 * Cai)) gamma_fCa = 0.3 / (1 + 0.391605626677 * ufl.exp(1250.0 * Cai)) fCa_inf = 0.760109455762*alpha_fCa + 0.760109455762*beta_fCa +\ 0.760109455762*gamma_fCa constfCa = ufl.conditional(ufl.And(ufl.gt(V, -0.06), ufl.gt(fCa_inf,\ fCa)), 0, 1) F_expressions[6] = (-fCa + fCa_inf) * constfCa / tau_fCa # Expressions for the Xr1 gate component V_half = -19.0 - 1000*R*T*ufl.ln(ufl.elem_pow(1 + 0.384615384615*Cao,\ 4)/(L0*ufl.elem_pow(1 + 1.72413793103*Cao, 4)))/(F*Q) Xr1_inf = 1.0 / (1 + ufl.exp(0.204081632653 * V_half - 204.081632653 * V)) alpha_Xr1 = 450.0 / (1 + ufl.exp(-9 / 2 - 100 * V)) beta_Xr1 = 6.0 / (1 + 13.5813245226 * ufl.exp(86.9565217391 * V)) tau_Xr1 = 0.001 * alpha_Xr1 * beta_Xr1 F_expressions[7] = (-Xr1 + Xr1_inf) / tau_Xr1 # Expressions for the Xr2 gate component Xr2_infinity = 1.0 / (1 + ufl.exp(44 / 25 + 20 * V)) alpha_Xr2 = 3.0 / (1 + ufl.exp(-3 - 50 * V)) beta_Xr2 = 1.12 / (1 + ufl.exp(-3 + 50 * V)) tau_Xr2 = 0.001 * alpha_Xr2 * beta_Xr2 F_expressions[8] = (-Xr2 + Xr2_infinity) / tau_Xr2 # Expressions for the Xs gate component Xs_infinity = 1.0 / (1 + ufl.exp(-5 / 4 - 125 * V / 2)) alpha_Xs = 1100.0 / ufl.sqrt(1 + ufl.exp(-5 / 3 - 500 * V / 3)) beta_Xs = 1.0 / (1 + ufl.exp(-3 + 50 * V)) tau_Xs = alpha_Xs * beta_Xs / 1000 F_expressions[9] = (-Xs + Xs_infinity) / tau_Xs # Expressions for the Xf gate component Xf_infinity = 1.0 / (1 + 5780495.71031 * ufl.exp(200 * V)) tau_Xf = 1.9 / (1 + ufl.exp(3 / 2 + 100 * V)) F_expressions[10] = (-Xf + Xf_infinity) / tau_Xf # Expressions for the i_b Na component i_b_Na = g_b_Na * (-E_Na + V) # Expressions for the i_b Ca component i_b_Ca = g_b_Ca * (-E_Ca + V) # Expressions for the i_NaK component i_NaK = Ko*PNaK*Nai/((Km_K + Ko)*(Km_Na + Nai)*(1 +\ 0.0353*ufl.exp(-F*V/(R*T)) + 0.1245*ufl.exp(-0.1*F*V/(R*T)))) # Expressions for the i_NaCa component i_NaCa = kNaCa*(Cao*(Nai*Nai*Nai)*ufl.exp(F*gamma*V/(R*T)) -\ alpha*(Nao*Nao*Nao)*Cai*ufl.exp(F*(-1 + gamma)*V/(R*T)))/((1 +\ Ksat*ufl.exp(F*(-1 + gamma)*V/(R*T)))*(Cao +\ KmCa)*((KmNai*KmNai*KmNai) + (Nao*Nao*Nao))) # Expressions for the i_PCa component i_PCa = g_PCa * Cai / (KPCa + Cai) # Expressions for the q gate component q_inf = 1.0 / (1 + ufl.exp(53 / 13 + 1000 * V / 13)) tau_q = 0.00606 + 0.039102/(0.0168716780457*ufl.exp(-80.0*V) +\ 6.42137321286*ufl.exp(100.0*V)) F_expressions[11] = (-q + q_inf) / tau_q # Expressions for the r gate component r_inf = 1.0 / (1 + 3.28489055021 * ufl.exp(-53.3333333333 * V)) tau_r = 0.00275352 + 0.01440516/(16.3010892258*ufl.exp(90.0*V) +\ 0.0211152735604*ufl.exp(-120.0*V)) F_expressions[12] = (-r + r_inf) / tau_r # Expressions for the Sodium dynamics component F_expressions[13] = -1e+18*Cm*(3*i_NaCa + 3*i_NaK + i_Na +\ i_b_Na)/(F*Vc) # Expressions for the Calcium dynamics component i_rel = 0.0411*(c_rel + a_rel*(Ca_SR*Ca_SR)/((b_rel*b_rel) +\ (Ca_SR*Ca_SR)))*d*g i_up = VmaxUp / (1 + (Kup * Kup) / (Cai * Cai)) i_leak = V_leak * (-Cai + Ca_SR) g_inf = ufl.conditional(ufl.le(Cai, 0.00035), 1.0/(1 +\ 5.43991024148e+20*ufl.elem_pow(Cai, 6)), 1.0/(1 +\ 1.9720198874e+55*ufl.elem_pow(Cai, 16))) const2 = ufl.conditional(ufl.And(ufl.gt(V, -0.06), ufl.gt(g_inf, g)),\ 0, 1) F_expressions[14] = (-g + g_inf) * const2 / tau_g Cai_bufc = 1.0 / (1 + Buf_C * Kbuf_C / ((Kbuf_C + Cai) * (Kbuf_C + Cai))) Ca_SR_bufSR = 1.0/(1 + Buf_SR*Kbuf_SR/((Kbuf_SR + Ca_SR)*(Kbuf_SR +\ Ca_SR))) F_expressions[15] = (-i_up - 5e+17*Cm*(-2*i_NaCa + i_CaL + i_PCa +\ i_b_Ca)/(F*Vc) + i_leak + i_rel)*Cai_bufc F_expressions[16] = Vc * (-i_leak - i_rel + i_up) * Ca_SR_bufSR / V_SR # Return results return dolfin.as_vector(F_expressions)
) # want the fluid to occupy 1/3 of the domain mesh = fenics_adjoint.Mesh( fenics.RectangleMesh(fenics.Point(0.0, 0.0), fenics.Point(delta, 1.0), N, N) ) A = fenics.FunctionSpace(mesh, "CG", 1) # control function space U_h = fenics.VectorElement("CG", mesh.ufl_cell(), 2) P_h = fenics.FiniteElement("CG", mesh.ufl_cell(), 1) W = fenics.FunctionSpace(mesh, U_h * P_h) # mixed Taylor-Hood function space # Define the boundary condition on velocity (x, y) = ufl.SpatialCoordinate(mesh) l = 1.0 / 6.0 # noqa: E741 gbar = 1.0 cond1 = ufl.And(ufl.gt(y, (1.0 / 4 - l / 2)), ufl.lt(y, (1.0 / 4 + l / 2))) val1 = gbar * (1 - (2 * (y - 0.25) / l) ** 2) cond2 = ufl.And(ufl.gt(y, (3.0 / 4 - l / 2)), ufl.lt(y, (3.0 / 4 + l / 2))) val2 = gbar * (1 - (2 * (y - 0.75) / l) ** 2) inflow_outflow = ufl.conditional(cond1, val1, ufl.conditional(cond2, val2, 0)) inflow_outflow_bc = fenics_adjoint.project(inflow_outflow, W.sub(0).sub(0).collapse()) solve_templates = (fenics_adjoint.Function(A),) assemble_templates = (fenics_adjoint.Function(W), fenics_adjoint.Function(A)) @build_jax_fem_eval(solve_templates) def forward(rho): """Solve the forward problem for a given fluid distribution rho(x).""" w = fenics_adjoint.Function(W) (u, p) = fenics.split(w)
def F(self, v, s, time=None): """ Right hand side for ODE system """ time = time if time else Constant(0.0) # Assign states V = v assert(len(s) == 16) Xr1, Xr2, Xs, m, h, j, d, f, fCa, s, r, Ca_SR, Ca_i, g, Na_i, K_i = s # Assign parameters P_kna = self._parameters["P_kna"] g_K1 = self._parameters["g_K1"] g_Kr = self._parameters["g_Kr"] g_Ks = self._parameters["g_Ks"] g_Na = self._parameters["g_Na"] g_bna = self._parameters["g_bna"] g_CaL = self._parameters["g_CaL"] g_bca = self._parameters["g_bca"] g_to = self._parameters["g_to"] K_mNa = self._parameters["K_mNa"] K_mk = self._parameters["K_mk"] P_NaK = self._parameters["P_NaK"] K_NaCa = self._parameters["K_NaCa"] K_sat = self._parameters["K_sat"] Km_Ca = self._parameters["Km_Ca"] Km_Nai = self._parameters["Km_Nai"] alpha = self._parameters["alpha"] gamma = self._parameters["gamma"] K_pCa = self._parameters["K_pCa"] g_pCa = self._parameters["g_pCa"] g_pK = self._parameters["g_pK"] Buf_c = self._parameters["Buf_c"] Buf_sr = self._parameters["Buf_sr"] Ca_o = self._parameters["Ca_o"] K_buf_c = self._parameters["K_buf_c"] K_buf_sr = self._parameters["K_buf_sr"] K_up = self._parameters["K_up"] V_leak = self._parameters["V_leak"] V_sr = self._parameters["V_sr"] Vmax_up = self._parameters["Vmax_up"] a_rel = self._parameters["a_rel"] b_rel = self._parameters["b_rel"] c_rel = self._parameters["c_rel"] tau_g = self._parameters["tau_g"] Na_o = self._parameters["Na_o"] Cm = self._parameters["Cm"] F = self._parameters["F"] R = self._parameters["R"] T = self._parameters["T"] V_c = self._parameters["V_c"] stim_amplitude = self._parameters["stim_amplitude"] stim_duration = self._parameters["stim_duration"] stim_start = self._parameters["stim_start"] K_o = self._parameters["K_o"] # Init return args F_expressions = [ufl.zero()]*16 # Expressions for the Reversal potentials component E_Na = R*T*ufl.ln(Na_o/Na_i)/F E_K = R*T*ufl.ln(K_o/K_i)/F E_Ks = R*T*ufl.ln((Na_o*P_kna + K_o)/(K_i + P_kna*Na_i))/F E_Ca = 0.5*R*T*ufl.ln(Ca_o/Ca_i)/F # Expressions for the Inward rectifier potassium current component alpha_K1 = 0.1/(1 + 6.14421235333e-06*ufl.exp(-0.06*E_K + 0.06*V)) beta_K1 = (3.06060402008*ufl.exp(0.0002*V - 0.0002*E_K) +\ 0.367879441171*ufl.exp(0.1*V - 0.1*E_K))/(1 + ufl.exp(0.5*E_K -\ 0.5*V)) xK1_inf = alpha_K1/(alpha_K1 + beta_K1) i_K1 = 0.430331482912*g_K1*ufl.sqrt(K_o)*(-E_K + V)*xK1_inf # Expressions for the Rapid time dependent potassium current component i_Kr = 0.430331482912*g_Kr*ufl.sqrt(K_o)*(-E_K + V)*Xr1*Xr2 # Expressions for the Xr1 gate component xr1_inf = 1.0/(1 + ufl.exp(-26/7 - V/7)) alpha_xr1 = 450/(1 + ufl.exp(-9/2 - V/10)) beta_xr1 = 6/(1 + 13.5813245226*ufl.exp(0.0869565217391*V)) tau_xr1 = alpha_xr1*beta_xr1 F_expressions[0] = (xr1_inf - Xr1)/tau_xr1 # Expressions for the Xr2 gate component xr2_inf = 1.0/(1 + ufl.exp(11/3 + V/24)) alpha_xr2 = 3/(1 + ufl.exp(-3 - V/20)) beta_xr2 = 1.12/(1 + ufl.exp(-3 + V/20)) tau_xr2 = alpha_xr2*beta_xr2 F_expressions[1] = (xr2_inf - Xr2)/tau_xr2 # Expressions for the Slow time dependent potassium current component i_Ks = g_Ks*(Xs*Xs)*(-E_Ks + V) # Expressions for the Xs gate component xs_inf = 1.0/(1 + ufl.exp(-5/14 - V/14)) alpha_xs = 1100/ufl.sqrt(1 + ufl.exp(-5/3 - V/6)) beta_xs = 1.0/(1 + ufl.exp(-3 + V/20)) tau_xs = alpha_xs*beta_xs F_expressions[2] = (xs_inf - Xs)/tau_xs # Expressions for the Fast sodium current component i_Na = g_Na*(m*m*m)*(-E_Na + V)*h*j # Expressions for the m gate component m_inf = 1.0/((1 + 0.00184221158117*ufl.exp(-0.110741971207*V))*(1 +\ 0.00184221158117*ufl.exp(-0.110741971207*V))) alpha_m = 1.0/(1 + ufl.exp(-12 - V/5)) beta_m = 0.1/(1 + ufl.exp(-1/4 + V/200)) + 0.1/(1 + ufl.exp(7 + V/5)) tau_m = alpha_m*beta_m F_expressions[3] = (-m + m_inf)/tau_m # Expressions for the h gate component h_inf = 1.0/((1 + 15212.5932857*ufl.exp(0.134589502019*V))*(1 +\ 15212.5932857*ufl.exp(0.134589502019*V))) alpha_h = 4.43126792958e-07*ufl.exp(-0.147058823529*V)/(1 +\ 2.35385266837e+17*ufl.exp(1.0*V)) beta_h = (2.7*ufl.exp(0.079*V) + 310000*ufl.exp(0.3485*V))/(1 +\ 2.35385266837e+17*ufl.exp(1.0*V)) + 0.77*(1 - 1/(1 +\ 2.35385266837e+17*ufl.exp(1.0*V)))/(0.13 +\ 0.0497581410839*ufl.exp(-0.0900900900901*V)) tau_h = 1.0/(alpha_h + beta_h) F_expressions[4] = (-h + h_inf)/tau_h # Expressions for the j gate component j_inf = 1.0/((1 + 15212.5932857*ufl.exp(0.134589502019*V))*(1 +\ 15212.5932857*ufl.exp(0.134589502019*V))) alpha_j = (37.78 + V)*(-25428*ufl.exp(0.2444*V) -\ 6.948e-06*ufl.exp(-0.04391*V))/((1 +\ 2.35385266837e+17*ufl.exp(1.0*V))*(1 +\ 50262745826.0*ufl.exp(0.311*V))) beta_j = 0.6*(1 - 1/(1 +\ 2.35385266837e+17*ufl.exp(1.0*V)))*ufl.exp(0.057*V)/(1 +\ 0.0407622039784*ufl.exp(-0.1*V)) +\ 0.02424*ufl.exp(-0.01052*V)/((1 +\ 2.35385266837e+17*ufl.exp(1.0*V))*(1 +\ 0.0039608683399*ufl.exp(-0.1378*V))) tau_j = 1.0/(alpha_j + beta_j) F_expressions[5] = (-j + j_inf)/tau_j # Expressions for the Sodium background current component i_b_Na = g_bna*(-E_Na + V) # Expressions for the L_type Ca current component i_CaL = 4*g_CaL*(F*F)*(Ca_i*ufl.exp(2*F*V/(R*T)) -\ 0.341*Ca_o)*V*d*f*fCa/(R*T*(-1 + ufl.exp(2*F*V/(R*T)))) # Expressions for the d gate component d_inf = 1.0/(1 + 0.513417119033*ufl.exp(-0.133333333333*V)) alpha_d = 0.25 + 1.4/(1 + ufl.exp(-35/13 - V/13)) beta_d = 1.4/(1 + ufl.exp(1 + V/5)) gamma_d = 1.0/(1 + ufl.exp(5/2 - V/20)) tau_d = alpha_d*beta_d + gamma_d F_expressions[6] = (-d + d_inf)/tau_d # Expressions for the f gate component f_inf = 1.0/(1 + ufl.exp(20/7 + V/7)) tau_f = 80 + 1125*ufl.exp(-((27 + V)*(27 + V))/240) + 165/(1 +\ ufl.exp(5/2 - V/10)) F_expressions[7] = (f_inf - f)/tau_f # Expressions for the FCa gate component alpha_fCa = 1.0/(1 + 8.03402376702e+27*ufl.elem_pow(Ca_i, 8)) exp_arg_0 = -5.0 + 10000.0*Ca_i exp_arg_00 = ufl.conditional(ufl.lt(exp_arg_0, 500.0), exp_arg_0,\ 500.0) beta_fCa = 0.1/(1 + ufl.exp(exp_arg_00)) exp_arg_1 = -0.9375 + 1250.0*Ca_i exp_arg_11 = ufl.conditional(ufl.lt(exp_arg_1, 500.0), exp_arg_1,\ 500.0) gama_fCa = 0.2/(1 + ufl.exp(exp_arg_11)) fCa_inf = 0.157534246575 + 0.684931506849*gama_fCa +\ 0.684931506849*alpha_fCa + 0.684931506849*beta_fCa tau_fCa = 2 d_fCa = (-fCa + fCa_inf)/tau_fCa F_expressions[8] = ufl.conditional(ufl.And(ufl.gt(V, -60),\ ufl.gt(fCa_inf, fCa)), 0, d_fCa) # Expressions for the Calcium background current component i_b_Ca = g_bca*(-E_Ca + V) # Expressions for the Transient outward current component i_to = g_to*(-E_K + V)*r*s # Expressions for the s gate component s_inf = 1.0/(1 + ufl.exp(4 + V/5)) tau_s = 3 + 5/(1 + ufl.exp(-4 + V/5)) + 85*ufl.exp(-((45 + V)*(45 +\ V))/320) F_expressions[9] = (s_inf - s)/tau_s # Expressions for the r gate component r_inf = 1.0/(1 + ufl.exp(10/3 - V/6)) tau_r = 0.8 + 9.5*ufl.exp(-((40 + V)*(40 + V))/1800) F_expressions[10] = (r_inf - r)/tau_r # Expressions for the Sodium potassium pump current component i_NaK = K_o*P_NaK*Na_i/((K_mNa + Na_i)*(K_mk + K_o)*(1 +\ 0.0353*ufl.exp(-F*V/(R*T)) + 0.1245*ufl.exp(-0.1*F*V/(R*T)))) # Expressions for the Sodium calcium exchanger current component i_NaCa = K_NaCa*(-alpha*(Na_o*Na_o*Na_o)*Ca_i*ufl.exp(F*(-1 +\ gamma)*V/(R*T)) +\ Ca_o*(Na_i*Na_i*Na_i)*ufl.exp(F*gamma*V/(R*T)))/((1 +\ K_sat*ufl.exp(F*(-1 + gamma)*V/(R*T)))*(Km_Ca +\ Ca_o)*((Na_o*Na_o*Na_o) + (Km_Nai*Km_Nai*Km_Nai))) # Expressions for the Calcium pump current component i_p_Ca = g_pCa*Ca_i/(Ca_i + K_pCa) # Expressions for the Potassium pump current component i_p_K = g_pK*(-E_K + V)/(1 + 65.4052157419*ufl.exp(-0.167224080268*V)) # Expressions for the Calcium dynamics component i_rel = (c_rel + a_rel*(Ca_SR*Ca_SR)/((b_rel*b_rel) +\ (Ca_SR*Ca_SR)))*d*g i_up = Vmax_up/(1 + (K_up*K_up)/(Ca_i*Ca_i)) i_leak = V_leak*(Ca_SR - Ca_i) g_inf = 1/((1 + 0.0301973834223*ufl.exp(10000.0*Ca_i))*(1 +\ 5.43991024148e+20*ufl.elem_pow(Ca_i, 6))) + (1 - 1/(1 +\ 0.0301973834223*ufl.exp(10000.0*Ca_i)))/(1 +\ 1.9720198874e+55*ufl.elem_pow(Ca_i, 16)) d_g = (-g + g_inf)/tau_g F_expressions[13] = (1 - 1.0/((1 + ufl.exp(60 + V))*(1 +\ ufl.exp(10.0*g_inf - 10.0*g))))*d_g Ca_i_bufc = 1.0/(1 + Buf_c*K_buf_c/((Ca_i + K_buf_c)*(Ca_i + K_buf_c))) Ca_sr_bufsr = 1.0/(1 + Buf_sr*K_buf_sr/((Ca_SR + K_buf_sr)*(Ca_SR +\ K_buf_sr))) F_expressions[12] = (i_rel - i_up - Cm*(i_b_Ca + i_p_Ca - 2*i_NaCa +\ i_CaL)/(2*F*V_c) + i_leak)*Ca_i_bufc F_expressions[11] = V_c*(i_up - i_leak - i_rel)*Ca_sr_bufsr/V_sr # Expressions for the Sodium dynamics component F_expressions[14] = Cm*(-i_b_Na - i_Na - 3*i_NaCa - 3*i_NaK)/(F*V_c) # Expressions for the Membrane component i_Stim = -stim_amplitude*(1 - 1/(1 + ufl.exp(5.0*time -\ 5.0*stim_start)))/(1 + ufl.exp(5.0*time - 5.0*stim_start -\ 5.0*stim_duration)) # Expressions for the Potassium dynamics component F_expressions[15] = Cm*(2*i_NaK - i_Ks - i_Kr - i_to - i_Stim - i_p_K\ - i_K1)/(F*V_c) # Return results return dolfin.as_vector(F_expressions)
def rhs(states, time, parameters, dy=None): """ Compute right hand side """ # Imports import ufl import dolfin # Assign states assert (isinstance(states, dolfin.Function)) assert (states.function_space().depth() == 1) assert (states.function_space().num_sub_spaces() == 17) Xr1, Xr2, Xs, m, h, j, d, f, fCa, s, r, Ca_SR, Ca_i, g, Na_i, V, K_i =\ dolfin.split(states) # Assign parameters assert (isinstance(parameters, (dolfin.Function, dolfin.Constant))) if isinstance(parameters, dolfin.Function): assert (parameters.function_space().depth() == 1) assert (parameters.function_space().num_sub_spaces() == 45) else: assert (parameters.value_size() == 45) P_kna, g_K1, g_Kr, g_Ks, g_Na, g_bna, g_CaL, g_bca, g_to, K_mNa, K_mk,\ P_NaK, K_NaCa, K_sat, Km_Ca, Km_Nai, alpha, gamma, K_pCa, g_pCa,\ g_pK, Buf_c, Buf_sr, Ca_o, K_buf_c, K_buf_sr, K_up, V_leak, V_sr,\ Vmax_up, a_rel, b_rel, c_rel, tau_g, Na_o, Cm, F, R, T, V_c,\ stim_amplitude, stim_duration, stim_period, stim_start, K_o =\ dolfin.split(parameters) # Reversal potentials E_Na = R * T * ufl.ln(Na_o / Na_i) / F E_K = R * T * ufl.ln(K_o / K_i) / F E_Ks = R * T * ufl.ln((Na_o * P_kna + K_o) / (Na_i * P_kna + K_i)) / F E_Ca = 0.5 * R * T * ufl.ln(Ca_o / Ca_i) / F # Inward rectifier potassium current alpha_K1 = 0.1 / (1.0 + 6.14421235332821e-6 * ufl.exp(0.06 * V - 0.06 * E_K)) beta_K1 = (3.06060402008027*ufl.exp(0.0002*V - 0.0002*E_K) +\ 0.367879441171442*ufl.exp(0.1*V - 0.1*E_K))/(1.0 + ufl.exp(0.5*E_K -\ 0.5*V)) xK1_inf = alpha_K1 / (alpha_K1 + beta_K1) i_K1 = 0.430331482911935 * ufl.sqrt(K_o) * (-E_K + V) * g_K1 * xK1_inf # Rapid time dependent potassium current i_Kr = 0.430331482911935 * ufl.sqrt(K_o) * (-E_K + V) * Xr1 * Xr2 * g_Kr # Rapid time dependent potassium current xr1 gate xr1_inf = 1.0 / (1.0 + 0.0243728440732796 * ufl.exp(-0.142857142857143 * V)) alpha_xr1 = 450.0 / (1.0 + ufl.exp(-9 / 2 - V / 10.0)) beta_xr1 = 6.0 / (1.0 + 13.5813245225782 * ufl.exp(0.0869565217391304 * V)) tau_xr1 = alpha_xr1 * beta_xr1 # Rapid time dependent potassium current xr2 gate xr2_inf = 1.0 / (1.0 + 39.1212839981532 * ufl.exp(0.0416666666666667 * V)) alpha_xr2 = 3.0 / (1.0 + 0.0497870683678639 * ufl.exp(-0.05 * V)) beta_xr2 = 1.12 / (1.0 + 0.0497870683678639 * ufl.exp(0.05 * V)) tau_xr2 = alpha_xr2 * beta_xr2 # Slow time dependent potassium current i_Ks = (Xs * Xs) * (V - E_Ks) * g_Ks # Slow time dependent potassium current xs gate xs_inf = 1.0 / (1.0 + 0.69967253737513 * ufl.exp(-0.0714285714285714 * V)) alpha_xs = 1100.0/ufl.sqrt(1.0 +\ 0.188875602837562*ufl.exp(-0.166666666666667*V)) beta_xs = 1.0 / (1.0 + 0.0497870683678639 * ufl.exp(0.05 * V)) tau_xs = alpha_xs * beta_xs # Fast sodium current i_Na = (m * m * m) * (-E_Na + V) * g_Na * h * j # Fast sodium current m gate m_inf = 1.0/((1.0 +\ 0.00184221158116513*ufl.exp(-0.110741971207087*V))*(1.0 +\ 0.00184221158116513*ufl.exp(-0.110741971207087*V))) alpha_m = 1.0 / (1.0 + ufl.exp(-12.0 - V / 5.0)) beta_m = 0.1/(1.0 + 0.778800783071405*ufl.exp(0.005*V)) + 0.1/(1.0 +\ ufl.exp(7.0 + V/5.0)) tau_m = alpha_m * beta_m # Fast sodium current h gate h_inf = 1.0/((1.0 + 15212.5932856544*ufl.exp(0.134589502018843*V))*(1.0 +\ 15212.5932856544*ufl.exp(0.134589502018843*V))) alpha_h = 4.43126792958051e-7*ufl.exp(-0.147058823529412*V)/(1.0 +\ 2.3538526683702e+17*ufl.exp(1.0*V)) beta_h = (310000.0*ufl.exp(0.3485*V) + 2.7*ufl.exp(0.079*V))/(1.0 +\ 2.3538526683702e+17*ufl.exp(1.0*V)) + 0.77*(1.0 - 1.0/(1.0 +\ 2.3538526683702e+17*ufl.exp(1.0*V)))/(0.13 +\ 0.0497581410839387*ufl.exp(-0.0900900900900901*V)) tau_h = 1.0 / (alpha_h + beta_h) # Fast sodium current j gate j_inf = 1.0/((1.0 + 15212.5932856544*ufl.exp(0.134589502018843*V))*(1.0 +\ 15212.5932856544*ufl.exp(0.134589502018843*V))) beta_j = ufl.conditional(ufl.lt(V, -40.0),\ 0.02424*ufl.exp(-0.01052*V)/(1.0 +\ 0.00396086833990426*ufl.exp(-0.1378*V)), 0.6*ufl.exp(0.057*V)/(1.0 +\ 0.0407622039783662*ufl.exp(-0.1*V))) alpha_j = (37.78 + V)*(-6.948e-6*ufl.exp(-0.04391*V) -\ 25428.0*ufl.exp(0.2444*V))/((1.0 +\ 2.3538526683702e+17*ufl.exp(1.0*V))*(1.0 +\ 50262745825.954*ufl.exp(0.311*V))) beta_j = 0.6*(1.0 - 1.0/(1.0 +\ 2.3538526683702e+17*ufl.exp(1.0*V)))*ufl.exp(0.057*V)/(1.0 +\ 0.0407622039783662*ufl.exp(-0.1*V)) +\ 0.02424*ufl.exp(-0.01052*V)/((1.0 +\ 2.3538526683702e+17*ufl.exp(1.0*V))*(1.0 +\ 0.00396086833990426*ufl.exp(-0.1378*V))) tau_j = 1.0 / (alpha_j + beta_j) # Sodium background current i_b_Na = (-E_Na + V) * g_bna # L type ca current i_CaL = 4.0*(F*F)*(-0.341*Ca_o +\ Ca_i*ufl.exp(2.0*F*V/(R*T)))*V*d*f*fCa*g_CaL/((-1.0 +\ ufl.exp(2.0*F*V/(R*T)))*R*T) # L type ca current d gate d_inf = 1.0 / (1.0 + 0.513417119032592 * ufl.exp(-0.133333333333333 * V)) alpha_d = 0.25 + 1.4/(1.0 +\ 0.0677244716592409*ufl.exp(-0.0769230769230769*V)) beta_d = 1.4 / (1.0 + ufl.exp(1.0 + V / 5.0)) gamma_d = 1.0 / (1.0 + 12.1824939607035 * ufl.exp(-0.05 * V)) tau_d = gamma_d + alpha_d * beta_d # L type ca current f gate f_inf = 1.0 / (1.0 + 17.4117080633276 * ufl.exp(0.142857142857143 * V)) tau_f = 80.0 + 165.0/(1.0 + ufl.exp(5/2 - V/10.0)) +\ 1125.0*ufl.exp(-0.00416666666666667*((27.0 + V)*(27.0 + V))) # L type ca current fca gate alpha_fCa = 1.0 / (1.0 + 8.03402376701711e+27 * ufl.elem_pow(Ca_i, 8.0)) beta_fCa = 0.1 / (1.0 + 0.00673794699908547 * ufl.exp(10000.0 * Ca_i)) gama_fCa = 0.2 / (1.0 + 0.391605626676799 * ufl.exp(1250.0 * Ca_i)) fCa_inf = 0.157534246575342 + 0.684931506849315*gama_fCa +\ 0.684931506849315*beta_fCa + 0.684931506849315*alpha_fCa tau_fCa = 2.0 d_fCa = (-fCa + fCa_inf) / tau_fCa # Calcium background current i_b_Ca = (V - E_Ca) * g_bca # Transient outward current i_to = (-E_K + V) * g_to * r * s # Transient outward current s gate s_inf = 1.0 / (1.0 + ufl.exp(4.0 + V / 5.0)) tau_s = 3.0 + 85.0*ufl.exp(-0.003125*((45.0 + V)*(45.0 + V))) + 5.0/(1.0 +\ ufl.exp(-4.0 + V/5.0)) # Transient outward current r gate r_inf = 1.0 / (1.0 + 28.0316248945261 * ufl.exp(-0.166666666666667 * V)) tau_r = 0.8 + 9.5 * ufl.exp(-0.000555555555555556 * ((40.0 + V) * (40.0 + V))) # Sodium potassium pump current i_NaK = K_o*Na_i*P_NaK/((K_mk + K_o)*(Na_i + K_mNa)*(1.0 +\ 0.0353*ufl.exp(-F*V/(R*T)) + 0.1245*ufl.exp(-0.1*F*V/(R*T)))) # Sodium calcium exchanger current i_NaCa = (-(Na_o*Na_o*Na_o)*Ca_i*alpha*ufl.exp((-1.0 + gamma)*F*V/(R*T))\ + (Na_i*Na_i*Na_i)*Ca_o*ufl.exp(F*V*gamma/(R*T)))*K_NaCa/((1.0 +\ K_sat*ufl.exp((-1.0 + gamma)*F*V/(R*T)))*((Na_o*Na_o*Na_o) +\ (Km_Nai*Km_Nai*Km_Nai))*(Km_Ca + Ca_o)) # Calcium pump current i_p_Ca = Ca_i * g_pCa / (K_pCa + Ca_i) # Potassium pump current i_p_K = (-E_K + V)*g_pK/(1.0 +\ 65.4052157419383*ufl.exp(-0.167224080267559*V)) # Calcium dynamics i_rel = ((Ca_SR * Ca_SR) * a_rel / ((Ca_SR * Ca_SR) + (b_rel * b_rel)) + c_rel) * d * g i_up = Vmax_up / (1.0 + (K_up * K_up) / (Ca_i * Ca_i)) i_leak = (-Ca_i + Ca_SR) * V_leak g_inf = (1.0 - 1.0/(1.0 + 0.0301973834223185*ufl.exp(10000.0*Ca_i)))/(1.0 +\ 1.97201988740492e+55*ufl.elem_pow(Ca_i, 16.0)) + 1.0/((1.0 +\ 0.0301973834223185*ufl.exp(10000.0*Ca_i))*(1.0 +\ 5.43991024148102e+20*ufl.elem_pow(Ca_i, 6.0))) d_g = (-g + g_inf) / tau_g Ca_i_bufc = 1.0 / (1.0 + Buf_c * K_buf_c / ((K_buf_c + Ca_i) * (K_buf_c + Ca_i))) Ca_sr_bufsr = 1.0/(1.0 + Buf_sr*K_buf_sr/((K_buf_sr + Ca_SR)*(K_buf_sr +\ Ca_SR))) # Sodium dynamics # Membrane i_Stim = ufl.conditional(ufl.And(ufl.ge(time, stim_start), ufl.le(time,\ stim_start + stim_duration)), -stim_amplitude, 0.0) # Potassium dynamics # The ODE system: 17 states # Init test function _v = dolfin.TestFunction(states.function_space()) # Derivative for state Xr1 dy = ((-Xr1 + xr1_inf) / tau_xr1) * _v[0] # Derivative for state Xr2 dy += ((-Xr2 + xr2_inf) / tau_xr2) * _v[1] # Derivative for state Xs dy += ((-Xs + xs_inf) / tau_xs) * _v[2] # Derivative for state m dy += ((-m + m_inf) / tau_m) * _v[3] # Derivative for state h dy += ((-h + h_inf) / tau_h) * _v[4] # Derivative for state j dy += ((j_inf - j) / tau_j) * _v[5] # Derivative for state d dy += ((d_inf - d) / tau_d) * _v[6] # Derivative for state f dy += ((-f + f_inf) / tau_f) * _v[7] # Derivative for state fCa dy += ((1.0 - 1.0/((1.0 + ufl.exp(60.0 + V))*(1.0 + ufl.exp(-10.0*fCa +\ 10.0*fCa_inf))))*d_fCa)*_v[8] # Derivative for state s dy += ((-s + s_inf) / tau_s) * _v[9] # Derivative for state r dy += ((-r + r_inf) / tau_r) * _v[10] # Derivative for state Ca_SR dy += ((-i_leak + i_up - i_rel) * Ca_sr_bufsr * V_c / V_sr) * _v[11] # Derivative for state Ca_i dy += ((-i_up - (i_CaL + i_p_Ca + i_b_Ca - 2.0*i_NaCa)*Cm/(2.0*F*V_c) +\ i_leak + i_rel)*Ca_i_bufc)*_v[12] # Derivative for state g dy += ((1.0 - 1.0/((1.0 + ufl.exp(60.0 + V))*(1.0 + ufl.exp(-10.0*g +\ 10.0*g_inf))))*d_g)*_v[13] # Derivative for state Na_i dy += ((-3.0 * i_NaK - 3.0 * i_NaCa - i_Na - i_b_Na) * Cm / (F * V_c)) * _v[14] # Derivative for state V dy += (-i_Ks - i_to - i_Kr - i_p_K - i_NaK - i_NaCa - i_Na - i_p_Ca -\ i_b_Na - i_CaL - i_Stim - i_K1 - i_b_Ca)*_v[15] # Derivative for state K_i dy += ((-i_Ks - i_to - i_Kr - i_p_K - i_Stim - i_K1 +\ 2.0*i_NaK)*Cm/(F*V_c))*_v[16] # Return dy return dy
def _I(self, v, s, time): """ Original gotran transmembrane current dV/dt """ time = time if time else Constant(0.0) # Assign states V = v assert(len(s) == 16) Xr1, Xr2, Xs, m, h, j, d, f, fCa, s, r, g, Ca_i, Ca_SR, Na_i, K_i = s # Assign parameters P_kna = self._parameters["P_kna"] g_K1 = self._parameters["g_K1"] g_Kr = self._parameters["g_Kr"] g_Ks = self._parameters["g_Ks"] g_Na = self._parameters["g_Na"] g_bna = self._parameters["g_bna"] g_CaL = self._parameters["g_CaL"] g_bca = self._parameters["g_bca"] g_to = self._parameters["g_to"] K_mNa = self._parameters["K_mNa"] K_mk = self._parameters["K_mk"] P_NaK = self._parameters["P_NaK"] K_NaCa = self._parameters["K_NaCa"] K_sat = self._parameters["K_sat"] Km_Ca = self._parameters["Km_Ca"] Km_Nai = self._parameters["Km_Nai"] alpha = self._parameters["alpha"] gamma = self._parameters["gamma"] K_pCa = self._parameters["K_pCa"] g_pCa = self._parameters["g_pCa"] g_pK = self._parameters["g_pK"] Ca_o = self._parameters["Ca_o"] Na_o = self._parameters["Na_o"] F = self._parameters["F"] R = self._parameters["R"] T = self._parameters["T"] stim_amplitude = self._parameters["stim_amplitude"] stim_duration = self._parameters["stim_duration"] stim_period = self._parameters["stim_period"] stim_start = self._parameters["stim_start"] K_o = self._parameters["K_o"] # Init return args current = [ufl.zero()]*1 # Expressions for the Reversal potentials component E_Na = R*T*ufl.ln(Na_o/Na_i)/F E_K = R*T*ufl.ln(K_o/K_i)/F E_Ks = R*T*ufl.ln((K_o + Na_o*P_kna)/(P_kna*Na_i + K_i))/F E_Ca = 0.5*R*T*ufl.ln(Ca_o/Ca_i)/F # Expressions for the Inward rectifier potassium current component alpha_K1 = 0.1/(1.0 + 6.14421235332821e-06*ufl.exp(0.06*V - 0.06*E_K)) beta_K1 = (0.36787944117144233*ufl.exp(0.1*V - 0.1*E_K) +\ 3.0606040200802673*ufl.exp(0.0002*V - 0.0002*E_K))/(1.0 +\ ufl.exp(0.5*E_K - 0.5*V)) xK1_inf = alpha_K1/(alpha_K1 + beta_K1) i_K1 = 0.4303314829119352*g_K1*ufl.sqrt(K_o)*(-E_K + V)*xK1_inf # Expressions for the Rapid time dependent potassium current component i_Kr = 0.4303314829119352*g_Kr*ufl.sqrt(K_o)*(-E_K + V)*Xr1*Xr2 # Expressions for the Slow time dependent potassium current component i_Ks = g_Ks*ufl.elem_pow(Xs, 2.0)*(-E_Ks + V) # Expressions for the Fast sodium current component i_Na = g_Na*ufl.elem_pow(m, 3.0)*(-E_Na + V)*h*j # Expressions for the Sodium background current component i_b_Na = g_bna*(-E_Na + V) # Expressions for the L_type Ca current component i_CaL = 4.0*g_CaL*ufl.elem_pow(F, 2.0)*(-0.341*Ca_o +\ Ca_i*ufl.exp(2.0*F*V/(R*T)))*V*d*f*fCa/(R*T*(-1.0 +\ ufl.exp(2.0*F*V/(R*T)))) # Expressions for the Calcium background current component i_b_Ca = g_bca*(-E_Ca + V) # Expressions for the Transient outward current component i_to = g_to*(-E_K + V)*r*s # Expressions for the Sodium potassium pump current component i_NaK = K_o*P_NaK*Na_i/((K_mNa + Na_i)*(K_mk + K_o)*(1.0 +\ 0.0353*ufl.exp(-F*V/(R*T)) + 0.1245*ufl.exp(-0.1*F*V/(R*T)))) # Expressions for the Sodium calcium exchanger current component i_NaCa = K_NaCa*(Ca_o*ufl.elem_pow(Na_i,\ 3.0)*ufl.exp(F*gamma*V/(R*T)) - alpha*ufl.elem_pow(Na_o,\ 3.0)*Ca_i*ufl.exp(F*(-1.0 + gamma)*V/(R*T)))/((1.0 +\ K_sat*ufl.exp(F*(-1.0 + gamma)*V/(R*T)))*(Ca_o +\ Km_Ca)*(ufl.elem_pow(Km_Nai, 3.0) + ufl.elem_pow(Na_o, 3.0))) # Expressions for the Calcium pump current component i_p_Ca = g_pCa*Ca_i/(K_pCa + Ca_i) # Expressions for the Potassium pump current component i_p_K = g_pK*(-E_K + V)/(1.0 +\ 65.40521574193832*ufl.exp(-0.16722408026755853*V)) # Expressions for the Membrane component i_Stim = ufl.conditional(ufl.And(ufl.ge(time -\ stim_period*ufl.floor(time/stim_period), stim_start), ufl.le(time\ - stim_period*ufl.floor(time/stim_period), stim_duration +\ stim_start)), -stim_amplitude, 0) current[0] = -1.0*i_CaL - 1.0*i_K1 - 1.0*i_Kr - 1.0*i_Ks - 1.0*i_Na -\ 1.0*i_NaCa - 1.0*i_NaK - 1.0*i_Stim - 1.0*i_b_Ca - 1.0*i_b_Na -\ 1.0*i_p_Ca - 1.0*i_p_K - 1.0*i_to # Return results return current[0]
def F(self, v, s, time=None): """ Right hand side for ODE system """ time = time if time else Constant(0.0) # Assign states V = v assert(len(s) == 16) Xr1, Xr2, Xs, m, h, j, d, f, fCa, s, r, g, Ca_i, Ca_SR, Na_i, K_i = s # Assign parameters P_kna = self._parameters["P_kna"] g_K1 = self._parameters["g_K1"] g_Kr = self._parameters["g_Kr"] g_Ks = self._parameters["g_Ks"] g_Na = self._parameters["g_Na"] g_bna = self._parameters["g_bna"] g_CaL = self._parameters["g_CaL"] g_bca = self._parameters["g_bca"] g_to = self._parameters["g_to"] K_mNa = self._parameters["K_mNa"] K_mk = self._parameters["K_mk"] P_NaK = self._parameters["P_NaK"] K_NaCa = self._parameters["K_NaCa"] K_sat = self._parameters["K_sat"] Km_Ca = self._parameters["Km_Ca"] Km_Nai = self._parameters["Km_Nai"] alpha = self._parameters["alpha"] gamma = self._parameters["gamma"] K_pCa = self._parameters["K_pCa"] g_pCa = self._parameters["g_pCa"] g_pK = self._parameters["g_pK"] Buf_c = self._parameters["Buf_c"] Buf_sr = self._parameters["Buf_sr"] Ca_o = self._parameters["Ca_o"] K_buf_c = self._parameters["K_buf_c"] K_buf_sr = self._parameters["K_buf_sr"] K_up = self._parameters["K_up"] V_leak = self._parameters["V_leak"] V_sr = self._parameters["V_sr"] Vmax_up = self._parameters["Vmax_up"] a_rel = self._parameters["a_rel"] b_rel = self._parameters["b_rel"] c_rel = self._parameters["c_rel"] tau_g = self._parameters["tau_g"] Na_o = self._parameters["Na_o"] Cm = self._parameters["Cm"] F = self._parameters["F"] R = self._parameters["R"] T = self._parameters["T"] V_c = self._parameters["V_c"] stim_amplitude = self._parameters["stim_amplitude"] stim_duration = self._parameters["stim_duration"] stim_period = self._parameters["stim_period"] stim_start = self._parameters["stim_start"] K_o = self._parameters["K_o"] # Init return args F_expressions = [ufl.zero()]*16 # Expressions for the Reversal potentials component E_Na = R*T*ufl.ln(Na_o/Na_i)/F E_K = R*T*ufl.ln(K_o/K_i)/F E_Ks = R*T*ufl.ln((K_o + Na_o*P_kna)/(P_kna*Na_i + K_i))/F E_Ca = 0.5*R*T*ufl.ln(Ca_o/Ca_i)/F # Expressions for the Inward rectifier potassium current component alpha_K1 = 0.1/(1.0 + 6.14421235332821e-06*ufl.exp(0.06*V - 0.06*E_K)) beta_K1 = (0.36787944117144233*ufl.exp(0.1*V - 0.1*E_K) +\ 3.0606040200802673*ufl.exp(0.0002*V - 0.0002*E_K))/(1.0 +\ ufl.exp(0.5*E_K - 0.5*V)) xK1_inf = alpha_K1/(alpha_K1 + beta_K1) i_K1 = 0.4303314829119352*g_K1*ufl.sqrt(K_o)*(-E_K + V)*xK1_inf # Expressions for the Rapid time dependent potassium current component i_Kr = 0.4303314829119352*g_Kr*ufl.sqrt(K_o)*(-E_K + V)*Xr1*Xr2 # Expressions for the Xr1 gate component xr1_inf = 1.0/(1.0 +\ 0.02437284407327961*ufl.exp(-0.14285714285714285*V)) alpha_xr1 = 450.0/(1.0 + 0.011108996538242306*ufl.exp(-0.1*V)) beta_xr1 = 6.0/(1.0 +\ 13.581324522578193*ufl.exp(0.08695652173913043*V)) tau_xr1 = 1.0*alpha_xr1*beta_xr1 F_expressions[0] = (-Xr1 + xr1_inf)/tau_xr1 # Expressions for the Xr2 gate component xr2_inf = 1.0/(1.0 + 39.12128399815321*ufl.exp(0.041666666666666664*V)) alpha_xr2 = 3.0/(1.0 + 0.049787068367863944*ufl.exp(-0.05*V)) beta_xr2 = 1.12/(1.0 + 0.049787068367863944*ufl.exp(0.05*V)) tau_xr2 = 1.0*alpha_xr2*beta_xr2 F_expressions[1] = (-Xr2 + xr2_inf)/tau_xr2 # Expressions for the Slow time dependent potassium current component i_Ks = g_Ks*ufl.elem_pow(Xs, 2.0)*(-E_Ks + V) # Expressions for the Xs gate component xs_inf = 1.0/(1.0 + 0.6996725373751304*ufl.exp(-0.07142857142857142*V)) alpha_xs = 1100.0/ufl.sqrt(1.0 +\ 0.18887560283756186*ufl.exp(-0.16666666666666666*V)) beta_xs = 1.0/(1.0 + 0.049787068367863944*ufl.exp(0.05*V)) tau_xs = 1.0*alpha_xs*beta_xs F_expressions[2] = (-Xs + xs_inf)/tau_xs # Expressions for the Fast sodium current component i_Na = g_Na*ufl.elem_pow(m, 3.0)*(-E_Na + V)*h*j # Expressions for the m gate component m_inf = 1.0*ufl.elem_pow(1.0 +\ 0.0018422115811651339*ufl.exp(-0.1107419712070875*V), -2.0) alpha_m = 1.0/(1.0 + 6.14421235332821e-06*ufl.exp(-0.2*V)) beta_m = 0.1/(1.0 + 1096.6331584284585*ufl.exp(0.2*V)) + 0.1/(1.0 +\ 0.7788007830714049*ufl.exp(0.005*V)) tau_m = 1.0*alpha_m*beta_m F_expressions[3] = (-m + m_inf)/tau_m # Expressions for the h gate component h_inf = 1.0*ufl.elem_pow(1.0 +\ 15212.593285654404*ufl.exp(0.13458950201884254*V), -2.0) alpha_h = ufl.conditional(ufl.lt(V, -40.0),\ 4.4312679295805147e-07*ufl.exp(-0.14705882352941177*V), 0) beta_h = ufl.conditional(ufl.lt(V, -40.0), 310000.0*ufl.exp(0.3485*V)\ + 2.7*ufl.exp(0.079*V), 0.77/(0.13 +\ 0.049758141083938695*ufl.exp(-0.0900900900900901*V))) tau_h = 1.0/(alpha_h + beta_h) F_expressions[4] = (-h + h_inf)/tau_h # Expressions for the j gate component j_inf = 1.0*ufl.elem_pow(1.0 +\ 15212.593285654404*ufl.exp(0.13458950201884254*V), -2.0) alpha_j = ufl.conditional(ufl.lt(V, -40.0), 1.0*(37.78 +\ V)*(-25428.0*ufl.exp(0.2444*V) -\ 6.948e-06*ufl.exp(-0.04391*V))/(1.0 +\ 50262745825.95399*ufl.exp(0.311*V)), 0) beta_j = ufl.conditional(ufl.lt(V, -40.0),\ 0.02424*ufl.exp(-0.01052*V)/(1.0 +\ 0.003960868339904256*ufl.exp(-0.1378*V)),\ 0.6*ufl.exp(0.057*V)/(1.0 +\ 0.040762203978366204*ufl.exp(-0.1*V))) tau_j = 1.0/(alpha_j + beta_j) F_expressions[5] = (-j + j_inf)/tau_j # Expressions for the Sodium background current component i_b_Na = g_bna*(-E_Na + V) # Expressions for the L_type Ca current component i_CaL = 4.0*g_CaL*ufl.elem_pow(F, 2.0)*(-0.341*Ca_o +\ Ca_i*ufl.exp(2.0*F*V/(R*T)))*V*d*f*fCa/(R*T*(-1.0 +\ ufl.exp(2.0*F*V/(R*T)))) # Expressions for the d gate component d_inf = 1.0/(1.0 + 0.513417119032592*ufl.exp(-0.13333333333333333*V)) alpha_d = 0.25 + 1.4/(1.0 +\ 0.0677244716592409*ufl.exp(-0.07692307692307693*V)) beta_d = 1.4/(1.0 + 2.718281828459045*ufl.exp(0.2*V)) gamma_d = 1.0/(1.0 + 12.182493960703473*ufl.exp(-0.05*V)) tau_d = 1.0*alpha_d*beta_d + gamma_d F_expressions[6] = (-d + d_inf)/tau_d # Expressions for the f gate component f_inf = 1.0/(1.0 + 17.411708063327644*ufl.exp(0.14285714285714285*V)) tau_f = 80.0 + 165.0/(1.0 + 12.182493960703473*ufl.exp(-0.1*V)) +\ 1125.0*ufl.exp(-0.004166666666666667*ufl.elem_pow(27.0 + V, 2.0)) F_expressions[7] = (-f + f_inf)/tau_f # Expressions for the FCa gate component alpha_fCa = 1.0/(1.0 + 8.03402376701711e+27*ufl.elem_pow(Ca_i, 8.0)) beta_fCa = 0.1/(1.0 + 0.006737946999085467*ufl.exp(10000.0*Ca_i)) gama_fCa = 0.2/(1.0 + 0.391605626676799*ufl.exp(1250.0*Ca_i)) fCa_inf = 0.15753424657534246 + 0.684931506849315*alpha_fCa +\ 0.684931506849315*beta_fCa + 0.684931506849315*gama_fCa tau_fCa = 2.0 d_fCa = (-fCa + fCa_inf)/tau_fCa F_expressions[8] = ufl.conditional(ufl.And(ufl.gt(V, -60.0),\ ufl.gt(fCa_inf, fCa)), 0, d_fCa) # Expressions for the Calcium background current component i_b_Ca = g_bca*(-E_Ca + V) # Expressions for the Transient outward current component i_to = g_to*(-E_K + V)*r*s # Expressions for the s gate component s_inf = 1.0/(1.0 + 54.598150033144236*ufl.exp(0.2*V)) tau_s = 3.0 + 5.0/(1.0 + 0.01831563888873418*ufl.exp(0.2*V)) +\ 85.0*ufl.exp(-0.003125*ufl.elem_pow(45.0 + V, 2.0)) F_expressions[9] = (-s + s_inf)/tau_s # Expressions for the r gate component r_inf = 1.0/(1.0 + 28.031624894526125*ufl.exp(-0.16666666666666666*V)) tau_r = 0.8 + 9.5*ufl.exp(-0.0005555555555555556*ufl.elem_pow(40.0 +\ V, 2.0)) F_expressions[10] = (-r + r_inf)/tau_r # Expressions for the Sodium potassium pump current component i_NaK = K_o*P_NaK*Na_i/((K_mNa + Na_i)*(K_mk + K_o)*(1.0 +\ 0.0353*ufl.exp(-F*V/(R*T)) + 0.1245*ufl.exp(-0.1*F*V/(R*T)))) # Expressions for the Sodium calcium exchanger current component i_NaCa = K_NaCa*(Ca_o*ufl.elem_pow(Na_i,\ 3.0)*ufl.exp(F*gamma*V/(R*T)) - alpha*ufl.elem_pow(Na_o,\ 3.0)*Ca_i*ufl.exp(F*(-1.0 + gamma)*V/(R*T)))/((1.0 +\ K_sat*ufl.exp(F*(-1.0 + gamma)*V/(R*T)))*(Ca_o +\ Km_Ca)*(ufl.elem_pow(Km_Nai, 3.0) + ufl.elem_pow(Na_o, 3.0))) # Expressions for the Calcium pump current component i_p_Ca = g_pCa*Ca_i/(K_pCa + Ca_i) # Expressions for the Potassium pump current component i_p_K = g_pK*(-E_K + V)/(1.0 +\ 65.40521574193832*ufl.exp(-0.16722408026755853*V)) # Expressions for the Calcium dynamics component i_rel = (c_rel + a_rel*ufl.elem_pow(Ca_SR, 2.0)/(ufl.elem_pow(b_rel,\ 2.0) + ufl.elem_pow(Ca_SR, 2.0)))*d*g i_up = Vmax_up/(1.0 + ufl.elem_pow(K_up, 2.0)*ufl.elem_pow(Ca_i, -2.0)) i_leak = V_leak*(-Ca_i + Ca_SR) g_inf = ufl.conditional(ufl.lt(Ca_i, 0.00035), 1.0/(1.0 +\ 5.439910241481018e+20*ufl.elem_pow(Ca_i, 6.0)), 1.0/(1.0 +\ 1.9720198874049195e+55*ufl.elem_pow(Ca_i, 16.0))) d_g = (-g + g_inf)/tau_g F_expressions[11] = ufl.conditional(ufl.And(ufl.gt(V, -60.0),\ ufl.gt(g_inf, g)), 0, d_g) Ca_i_bufc = 1.0/(1.0 + Buf_c*K_buf_c*ufl.elem_pow(K_buf_c + Ca_i,\ -2.0)) Ca_sr_bufsr = 1.0/(1.0 + Buf_sr*K_buf_sr*ufl.elem_pow(K_buf_sr +\ Ca_SR, -2.0)) F_expressions[12] = (-i_up - 0.5*Cm*(1.0*i_CaL + 1.0*i_b_Ca +\ 1.0*i_p_Ca - 2.0*i_NaCa)/(F*V_c) + i_leak + i_rel)*Ca_i_bufc F_expressions[13] = V_c*(-i_leak - i_rel + i_up)*Ca_sr_bufsr/V_sr # Expressions for the Sodium dynamics component F_expressions[14] = 1.0*Cm*(-1.0*i_Na - 1.0*i_b_Na - 3.0*i_NaCa -\ 3.0*i_NaK)/(F*V_c) # Expressions for the Membrane component i_Stim = ufl.conditional(ufl.And(ufl.ge(time -\ stim_period*ufl.floor(time/stim_period), stim_start), ufl.le(time\ - stim_period*ufl.floor(time/stim_period), stim_duration +\ stim_start)), -stim_amplitude, 0) # Expressions for the Potassium dynamics component F_expressions[15] = 1.0*Cm*(2.0*i_NaK - 1.0*i_K1 - 1.0*i_Kr -\ 1.0*i_Ks - 1.0*i_Stim - 1.0*i_p_K - 1.0*i_to)/(F*V_c) # Return results return dolfin.as_vector(F_expressions)
J = derivative(R, U, dU) # # GL Dynamics ########################## # # CN param for updating flotation condition theta_g = 0.9 # PTC time step (bigger means faster switch from grounded to floating) dtau = 0.2 # Flotation condition ghat = conditional( ufl.Or( ufl.And(ge(rho * g * H, ufl.Max(P_w, 1e-16)), ge(H, 1.5 * rho_w / rho * thklim)), ge(B, 1e-16)), 1, 0) # Flotation update system R_g = psi * (dg - grounded + dtau * (dg * theta_g + grounded * (1 - theta_g) - ghat)) * dx A_g = lhs(R_g) b_g = rhs(R_g) # # Erosion ########################## # mdot = erosion_constants["K"] * abs(u(1))**erosion_constants["l"] * grounded R_e = ((dg - B) / dt - mdot) * psi * dx A_e = lhs(R_e) b_e = rhs(R_e)