def _rush_larsen_step(rhs_exprs, diff_rhs_exprs, linear_terms,
                      system_size, y0, stage_solution, dt, time, a, c,
                      v, DX, time_dep_expressions):

    # If we need to replace the original solution with stage solution
    repl = None
    if stage_solution is not None:

        if system_size > 1:
            repl = {y0: stage_solution}
        else:
            repl = {y0[0]: stage_solution}

    # If we have time dependent expressions
    if time_dep_expressions and abs(float(c)) > DOLFIN_EPS:
        time_ = time
        time = time + dt * float(c)

        repl.update(_replace_dict_time_dependent_expression(time_dep_expressions,
                                                            time_, dt, float(c)))
        repl[time_] = time

    # If all terms are linear (using generalized=True) we add a safe
    # guard to the linearized term. See below
    safe_guard = sum(linear_terms) == system_size

    # Add componentwise contribution to rl form
    rl_ufl_form = ufl.zero()
    num_rl_steps = 0
    for ind in range(system_size):

        # forward euler step
        fe_du_i = rhs_exprs[ind] * dt * float(a)

        # If exact integration
        if linear_terms[ind]:
            num_rl_steps += 1

            # Rush Larsen step Safeguard the divisor: let's hope
            # diff_rhs_exprs[ind] is never 1.0e-16!  Let's get rid of
            # this when the conditional fixes land properly in UFL.
            eps = Constant(1.0e-16)
            rl_du_i = rhs_exprs[ind] / (diff_rhs_exprs[ind] + eps) * (
                ufl.exp(diff_rhs_exprs[ind] * dt) - 1.0)

            # If safe guard
            if safe_guard:
                du_i = ufl.conditional(ufl.lt(abs(diff_rhs_exprs[ind]), 1e-8), fe_du_i, rl_du_i)
            else:
                du_i = rl_du_i
        else:
            du_i = fe_du_i

        # If we should replace solution in form with stage solution
        if repl:
            du_i = ufl.replace(du_i, repl)

        rl_ufl_form += (y0[ind] + du_i) * v[ind]

    return rl_ufl_form * DX
Example #2
0
    def increase_conductivity(self, cond, e):
        # Set up the three way choice function
        intermediate = e * self.k + self.h
        not_less_than = ufl.conditional(ufl.gt(e, self.threshold_irreversible), self.sigma_end, intermediate)
        cond_expression = ufl.conditional(ufl.lt(e, self.threshold_reversible), self.sigma_start, not_less_than)

        # Project this onto the function space
        cond_function = d.project(ufl.Max(cond_expression, cond), cond.function_space())
        cond.assign(cond_function)
def test_cpp_formatting_of_conditionals():
    x, y = ufl.SpatialCoordinate(ufl.triangle)
    # Test conditional expressions
    assert expr2cpp(ufl.conditional(ufl.lt(x, 2), y, 3)) \
        == "x[0] < 2 ? x[1]: 3"
    assert expr2cpp(ufl.conditional(ufl.gt(x, 2), 4 + y, 3)) \
        == "x[0] > 2 ? 4 + x[1]: 3"
    assert expr2cpp(ufl.conditional(ufl.And(ufl.le(x, 2), ufl.ge(y, 4)), 7, 8)) \
        == "x[0] <= 2 && x[1] >= 4 ? 7: 8"
    assert expr2cpp(ufl.conditional(ufl.Or(ufl.eq(x, 2), ufl.ne(y, 4)), 7, 8)) \
        == "x[0] == 2 || x[1] != 4 ? 7: 8"
Example #4
0
    def increase_conductivity(self, cond, e):
        # Set up the three way choice function
        intermediate = e * self.k + self.h
        not_less_than = ufl.conditional(ufl.gt(e, self.threshold_irreversible),
                                        self.sigma_end, intermediate)
        cond_expression = ufl.conditional(ufl.lt(e, self.threshold_reversible),
                                          self.sigma_start, not_less_than)

        # Project this onto the function space
        cond_function = d.project(ufl.Max(cond_expression, cond),
                                  cond.function_space())
        cond.assign(cond_function)
Example #5
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) == 2)
        v, w = s

        # Assign parameters
        u_c = self._parameters["u_c"]
        u_v = self._parameters["u_v"]
        tau_v1_minus = self._parameters["tau_v1_minus"]
        tau_v2_minus = self._parameters["tau_v2_minus"]
        tau_v_plus = self._parameters["tau_v_plus"]
        tau_w_minus = self._parameters["tau_w_minus"]
        tau_w_plus = self._parameters["tau_w_plus"]
        V_0 = self._parameters["V_0"]
        V_fi = self._parameters["V_fi"]

        # Init return args
        F_expressions = [ufl.zero()] * 2

        # Expressions for the p component
        p = ufl.conditional(ufl.lt((-V_0 + V) / (V_fi - V_0), u_c), 0, 1)

        # Expressions for the q component
        q = ufl.conditional(ufl.lt((-V_0 + V) / (V_fi - V_0), u_v), 0, 1)

        # Expressions for the v gate component
        tau_v_minus = tau_v1_minus * q + tau_v2_minus * (1 - q)
        F_expressions[0] = (1 - p) * (1 - v) / tau_v_minus - p * v / tau_v_plus

        # Expressions for the w gate component
        F_expressions[1] = (1 - p) * (1 - w) / tau_w_minus - p * w / tau_w_plus

        # Return results
        return dolfin.as_vector(F_expressions)
Example #6
0
    def __init__(self, spline, ufl_element):
        self._ufl_coef = ufl.Coefficient(ufl_element)

        t = self._ufl_coef
        knots = spline.knots
        coef_array = spline.coef_array

        # assigning left polynomial
        form = ufl.conditional(lt(t, knots[0]), 1., 0.)\
                   * Polynomial(coef_array[0])(t)

        # assigning internal polynomials
        for knot, knot_, coef in\
                zip(knots[:-1], knots[1:], coef_array[1:-1]):
            form += ufl.conditional(And(ge(t, knot), lt(t, knot_)), 1., 0.)\
                        * Polynomial(coef)(t)

        # assigning right polynomial
        form += ufl.conditional(ge(t, knots[-1]), 1., 0.)\
                    * Polynomial(coef_array[-1])(t)

        self._ufl_form = form
Example #7
0
def test_scalar_conditions(R):
    c = Function(R)
    c.vector.set(1.5)

    # Float conversion does not interfere with boolean ufl expressions
    assert isinstance(ufl.lt(c, 3), ufl.classes.LT)
    assert not isinstance(ufl.lt(c, 3), bool)

    # Float conversion is not implicit in boolean Python expressions
    assert isinstance(c < 3, ufl.classes.LT)
    assert not isinstance(c < 3, bool)

    # == is used in ufl to compare equivalent representations,
    # <,> result in LT/GT expressions, bool conversion is illegal

    # Note that 1.5 < 0 == False == 1.5 < 1, but that is not what we
    # compare here:
    assert not (c < 0) == (c < 1)
    # This protects from "if c < 0: ..." misuse:
    with pytest.raises(ufl.UFLException):
        bool(c < 0)
    with pytest.raises(ufl.UFLException):
        not c < 0
Example #8
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)
        v, w = s

        # Assign parameters
        u_c = self._parameters["u_c"]
        g_fi_max = self._parameters["g_fi_max"]
        tau_0 = self._parameters["tau_0"]
        tau_r = self._parameters["tau_r"]
        k = self._parameters["k"]
        tau_si = self._parameters["tau_si"]
        u_csi = self._parameters["u_csi"]
        Cm = self._parameters["Cm"]
        V_0 = self._parameters["V_0"]
        V_fi = self._parameters["V_fi"]

        # Init return args
        current = [ufl.zero()] * 1

        # Expressions for the p component
        p = ufl.conditional(ufl.lt((-V_0 + V) / (V_fi - V_0), u_c), 0, 1)

        # Expressions for the Fast inward current component
        tau_d = Cm / g_fi_max
        J_fi = -(1 - (-V_0 + V)/(V_fi - V_0))*(-u_c + (-V_0 + V)/(V_fi -\
            V_0))*p*v/tau_d

        # Expressions for the Slow outward current component
        J_so = p / tau_r + (1 - p) * (-V_0 + V) / (tau_0 * (V_fi - V_0))

        # Expressions for the Slow inward current component
        J_si = -(1 + ufl.tanh(k*(-u_csi + (-V_0 + V)/(V_fi -\
            V_0))))*w/(2*tau_si)

        # Expressions for the Stimulus protocol component
        J_stim = 0

        # Expressions for the Membrane component
        current[0] = (V_0 - V_fi) * (J_stim + J_fi + J_si + J_so)

        # Return results
        return current[0]
Example #9
0
def test_comparison_checker(self):
    cell = triangle
    element = FiniteElement("Lagrange", cell, 1)

    u = TrialFunction(element)
    v = TestFunction(element)

    a = conditional(ge(abs(u), imag(v)), u, v)
    b = conditional(le(sqrt(abs(u)), imag(v)), as_ufl(1), as_ufl(1j))
    c = conditional(gt(abs(u), pow(imag(v), 0.5)), sin(u), cos(v))
    d = conditional(lt(as_ufl(-1), as_ufl(1)), u, v)
    e = max_value(as_ufl(0), real(u))
    f = min_value(sin(u), cos(v))
    g = min_value(sin(pow(u, 3)), cos(abs(v)))

    assert do_comparison_check(a) == conditional(ge(real(abs(u)), real(imag(v))), u, v)
    with pytest.raises(ComplexComparisonError):
        b = do_comparison_check(b)
    with pytest.raises(ComplexComparisonError):
        c = do_comparison_check(c)
    assert do_comparison_check(d) == conditional(lt(real(as_ufl(-1)), real(as_ufl(1))), u, v)
    assert do_comparison_check(e) == max_value(real(as_ufl(0)), real(real(u)))
    assert do_comparison_check(f) == min_value(real(sin(u)), real(cos(v)))
    assert do_comparison_check(g) == min_value(real(sin(pow(u, 3))), real(cos(abs(v))))
)  # 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)
Example #11
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)
Example #12
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, 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)
Example #13
0
def xtest_latex_formatting_of_conditionals():
    # Test conditional expressions
    assert expr2latex(ufl.conditional(ufl.lt(x, 2), y, 3)) == "x_0 < 2 ? x_1: 3"
    assert expr2latex(ufl.conditional(ufl.gt(x, 2), 4 + y, 3)) == "x_0 > 2 ? 4 + x_1: 3"
    assert expr2latex(ufl.conditional(ufl.And(ufl.le(x, 2), ufl.ge(y, 4)), 7, 8)) == "x_0 <= 2 && x_1 >= 4 ? 7: 8"
    assert expr2latex(ufl.conditional(ufl.Or(ufl.eq(x, 2), ufl.ne(y, 4)), 7, 8)) == "x_0 == 2 || x_1 != 4 ? 7: 8"
beta2 = df.interpolate(Beta2(), Q_cg)  # Traction

Smax = 2500.0  # above Smax, adot=amax [m]
Smin = 200.0  # below Smin, adot=amin [m]
Sela = 1000.0  # equilibrium line altidue [m]

if geom == "1sided":
    climate_factor = df.Constant(1.0)  # Climate
    adot = climate_factor * (amin + (amax - amin) / (1 - df.exp(-c)) *
                             (1.0 - df.exp(-c * ((S / 2000))))
                             )  # *grounded + (-0.5*H)*(1-grounded)
    bdot = df.Constant(0)
else:
    if climate == "elev":
        adot = ufl.conditional(
            ufl.lt(S, Sela),
            (-amin / (Sela - Smin)) * (S - Sela),
            (amax / (Smax - Sela)) * (S - Sela),
        ) * grounded + ufl.conditional(
            ufl.lt(S, Sela),
            (-amin / (Sela - Smin)) * (H0 - Sela),
            (amax / (Smax - Sela)) * (H0 * (1 - rho / rho_w) - Sela),
        ) * (1 - grounded)
    elif climate in "ltop":
        adot = df.Function(Q_cg)
        P = get_adot_from_orog_precip(ltop_constants)
        adot.vector().set_local(P)
    else:
        print(("precip model {} not supported".format(climate)))
    bdot = df.Constant(0) * (1 - grounded)
Example #15
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)
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
Example #17
0
def _rush_larsen_step(rhs_exprs, diff_rhs_exprs, linear_terms, system_size, \
                      y0, stage_solution, dt, time, a, c, v, DX, time_dep_expressions):

    # If we need to replace the original solution with stage solution
    repl = None
    if stage_solution is not None:

        if system_size > 1:
            repl = {y0: stage_solution}
        else:
            repl = {y0[0]: stage_solution}

    # If we have time dependent expressions
    if time_dep_expressions and abs(float(c)) > DOLFIN_EPS:
        time_ = time
        time = time + dt * float(c)

        repl.update(_replace_dict_time_dependent_expression(time_dep_expressions, \
                                                            time_, dt, float(c)))
        repl[time_] = time

    # If all terms are linear (using generalized=True) we add a safe
    # guard to the linearized term. See below
    safe_guard = sum(linear_terms) == system_size

    # Add componentwise contribution to rl form
    rl_ufl_form = ufl.zero()
    num_rl_steps = 0
    for ind in range(system_size):

        not_zero = diff_rhs_exprs[ind] != 0

        # forward euler step
        fe_du_i = rhs_exprs[ind] * dt * float(a)

        # If exact integration
        if not_zero and linear_terms[ind]:

            num_rl_steps += 1

            # Rush Larsen step
            rl_du_i = rhs_exprs[ind]/diff_rhs_exprs[ind]*(\
                ufl.exp(diff_rhs_exprs[ind]*dt) - 1.0)

            # If safe guard
            if safe_guard:
                du_i = ufl.conditional(ufl.lt(abs(diff_rhs_exprs[ind]), 1e-8),\
                                       fe_du_i, rl_du_i)
            else:
                du_i = rl_du_i

        # Else explicit Euler
        else:
            du_i = fe_du_i

        # If we should replace solution in form with stage solution
        if repl:
            du_i = ufl.replace(du_i, repl)

        rl_ufl_form += (y0[ind] + du_i) * v[ind]

    return rl_ufl_form * DX
Example #18
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) == 18)
        Xr1, Xr2, Xs, m, h, j, d, f, f2, fCass, s, r, Ca_SR, Ca_i, Ca_ss,\
            R_prime, 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"]
        Buf_ss = self._parameters["Buf_ss"]
        Ca_o = self._parameters["Ca_o"]
        EC = self._parameters["EC"]
        K_buf_c = self._parameters["K_buf_c"]
        K_buf_sr = self._parameters["K_buf_sr"]
        K_buf_ss = self._parameters["K_buf_ss"]
        K_up = self._parameters["K_up"]
        V_leak = self._parameters["V_leak"]
        V_rel = self._parameters["V_rel"]
        V_sr = self._parameters["V_sr"]
        V_ss = self._parameters["V_ss"]
        V_xfer = self._parameters["V_xfer"]
        Vmax_up = self._parameters["Vmax_up"]
        k1_prime = self._parameters["k1_prime"]
        k2_prime = self._parameters["k2_prime"]
        k3 = self._parameters["k3"]
        k4 = self._parameters["k4"]
        max_sr = self._parameters["max_sr"]
        min_sr = self._parameters["min_sr"]
        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"]
        K_o = self._parameters["K_o"]

        # Init return args
        F_expressions = [ufl.zero()] * 18

        # 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 = 1400 / ufl.sqrt(1 + ufl.exp(5 / 6 - V / 6))
        beta_xs = 1.0 / (1 + ufl.exp(-7 / 3 + V / 15))
        tau_xs = 80 + 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 = ufl.conditional(ufl.lt(V, -40),\
            4.43126792958e-07*ufl.exp(-0.147058823529*V), 0)
        beta_h = ufl.conditional(ufl.lt(V, -40), 2.7*ufl.exp(0.079*V) +\
            310000*ufl.exp(0.3485*V), 0.77/(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 = ufl.conditional(ufl.lt(V, -40), (37.78 +\
            V)*(-25428*ufl.exp(0.2444*V) - 6.948e-06*ufl.exp(-0.04391*V))/(1 +\
            50262745826.0*ufl.exp(0.311*V)), 0)
        beta_j = ufl.conditional(ufl.lt(V, -40),\
            0.02424*ufl.exp(-0.01052*V)/(1 +\
            0.0039608683399*ufl.exp(-0.1378*V)), 0.6*ufl.exp(0.057*V)/(1 +\
            0.0407622039784*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*g_CaL*(F*F)*(-15 + V)*(0.25*Ca_ss*ufl.exp(F*(-30 +\
            2*V)/(R*T)) - Ca_o)*d*f*f2*fCass/(R*T*(-1 + ufl.exp(F*(-30 +\
            2*V)/(R*T))))

        # Expressions for the d gate component
        d_inf = 1.0 / (1 + 0.344153786865 * 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 = 20 + 1102.5*ufl.exp(-((27 + V)*(27 + V))/225) + 180/(1 +\
            ufl.exp(3 + V/10)) + 200/(1 + ufl.exp(13/10 - V/10))
        F_expressions[7] = (f_inf - f) / tau_f

        # Expressions for the F2 gate component
        f2_inf = 0.33 + 0.67 / (1 + ufl.exp(5 + V / 7))
        tau_f2 = 80/(1 + ufl.exp(3 + V/10)) + 562*ufl.exp(-((27 + V)*(27 +\
            V))/240) + 31/(1 + ufl.exp(5/2 - V/10))
        F_expressions[8] = (-f2 + f2_inf) / tau_f2

        # Expressions for the FCass gate component
        fCass_inf = 0.4 + 0.6 / (1 + 400.0 * (Ca_ss * Ca_ss))
        tau_fCass = 2 + 80 / (1 + 400.0 * (Ca_ss * Ca_ss))
        F_expressions[9] = (fCass_inf - fCass) / tau_fCass

        # 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[10] = (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[11] = (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_up = Vmax_up / (1 + (K_up * K_up) / (Ca_i * Ca_i))
        i_leak = V_leak * (Ca_SR - Ca_i)
        i_xfer = V_xfer * (Ca_ss - Ca_i)
        kcasr = max_sr - (-min_sr + max_sr) / (1 + (EC * EC) / (Ca_SR * Ca_SR))
        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)))
        Ca_ss_bufss = 1.0/(1 + Buf_ss*K_buf_ss/((Ca_ss + K_buf_ss)*(Ca_ss +\
            K_buf_ss)))
        F_expressions[13] = (i_xfer - Cm*(i_b_Ca + i_p_Ca -\
            2*i_NaCa)/(2*F*V_c) + V_sr*(-i_up + i_leak)/V_c)*Ca_i_bufc
        k1 = k1_prime / kcasr
        k2 = k2_prime * kcasr
        O = (Ca_ss * Ca_ss) * R_prime * k1 / ((Ca_ss * Ca_ss) * k1 + k3)
        F_expressions[15] = -Ca_ss * R_prime * k2 + k4 * (1 - R_prime)
        i_rel = V_rel * (Ca_SR - Ca_ss) * O
        F_expressions[12] = (i_up - i_leak - i_rel) * Ca_sr_bufsr
        F_expressions[14] = (-Cm*i_CaL/(2*F*V_ss) - V_c*i_xfer/V_ss +\
            V_sr*i_rel/V_ss)*Ca_ss_bufss

        # Expressions for the Sodium dynamics component
        F_expressions[16] = Cm * (-i_b_Na - i_Na - 3 * i_NaCa -
                                  3 * i_NaK) / (F * V_c)

        # Expressions for the Membrane component
        i_Stim = 0

        # Expressions for the Potassium dynamics component
        F_expressions[17] = Cm*(2*i_NaK - i_Ks - i_Stim - i_Kr - i_to - i_p_K\
            - i_K1)/(F*V_c)

        # Return results
        return as_vector(F_expressions)
Example #19
0
def solidification_indicator(theta_k, theta_kp1, solidus, liquidus):
    return conditional(
            And(ge(theta_k, solidus), lt(theta_kp1, liquidus)),
            1.,
            0.,
        )