Example #1
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)
        m, h = s

        # Assign parameters
        E_h = self._parameters["E_h"]
        E_m = self._parameters["E_m"]
        delta_h = self._parameters["delta_h"]
        k_h = self._parameters["k_h"]
        k_m = self._parameters["k_m"]
        tau_h0 = self._parameters["tau_h0"]
        tau_m = self._parameters["tau_m"]

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

        # Expressions for the m gate component
        m_inf = 1.0/(1.0 + ufl.exp((E_m - V)/k_m))
        F_expressions[0] = (-m + m_inf)/tau_m

        # Expressions for the h gate component
        h_inf = 1.0/(1.0 + ufl.exp((-E_h + V)/k_h))
        tau_h = 2*tau_h0*ufl.exp(delta_h*(-E_h + V)/k_h)/(1 + ufl.exp((-E_h +\
            V)/k_h))
        F_expressions[1] = (-h + h_inf)/tau_h

        # Return results
        return dolfin.as_vector(F_expressions)
Example #2
0
    def holzapfelogden_dev(self, params, f0, s0, C):

        # anisotropic invariants - keep in mind that for growth, self.C is the elastic part of C (hence != to function input variable C)
        I4 = dot(dot(self.C,f0), f0)
        I6 = dot(dot(self.C,s0), s0)
        I8 = dot(dot(self.C,s0), f0)

        # to guarantee initial configuration is stress-free (in case of initially non-orthogonal fibers f0 and s0)
        I8 -= dot(f0,s0)

        a_0, b_0 = params['a_0'], params['b_0']
        a_f, b_f = params['a_f'], params['b_f']
        a_s, b_s = params['a_s'], params['b_s']
        a_fs, b_fs = params['a_fs'], params['b_fs']

        try: fiber_comp = params['fiber_comp']
        except: fiber_comp = False

        # conditional parameters: fibers are only active in tension if fiber_comp is False
        if not fiber_comp:
            a_f_c = conditional(ge(I4,1.), a_f, 0.)
            a_s_c = conditional(ge(I6,1.), a_s, 0.)
        else:
            a_f_c = a_f
            a_s_c = a_s
        
        # Holzapfel-Ogden (Holzapfel and Ogden 2009) material w/o split applied to invariants I4, I6, I8 (Sansour 2008)
        psi_dev = a_0/(2.*b_0)*(exp(b_0*(self.Ic_bar-3.)) - 1.) + \
            a_f_c/(2.*b_f)*(exp(b_f*(I4-1.)**2.) - 1.) + a_s_c/(2.*b_s)*(exp(b_s*(I6-1.)**2.) - 1.) + \
            a_fs/(2.*b_fs)*(exp(b_fs*I8**2.) - 1.)
        
        S = 2.*diff(psi_dev,C)
        
        return S
Example #3
0
    def I(self, v, s, time=None):
        """
        Transmembrane current
        """
        # Imports
        # No imports for now

        time = time if time else Constant(0.0)
        # Assign states
        _is_vector = False

        # Assign parameters
        a = self._parameters["a"]
        stim_start = self._parameters["stim_start"]
        stim_amplitude = self._parameters["stim_amplitude"]
        c_1 = self._parameters["c_1"]
        c_2 = self._parameters["c_2"]
        v_rest = self._parameters["v_rest"]
        stim_duration = self._parameters["stim_duration"]
        v_peak = self._parameters["v_peak"]

        current = -(v - v_rest)*(v_peak - v)*(-(v_peak - v_rest)*a + v -\
            v_rest)*c_1/((v_peak - v_rest)*(v_peak - v_rest)) + (v -\
            v_rest)*c_2*s/(v_peak - v_rest) - (1.0 - 1.0/(1.0 +\
            ufl.exp(-5.0*stim_start + 5.0*time)))*stim_amplitude/(1.0 +\
            ufl.exp(-5.0*stim_start + 5.0*time - 5.0*stim_duration))

        return current
  def eval(self, values, x):

    u  = self.omega*self.t - 3*pow(6,0.5)
    if abs(x[0] - self.center) < 0.25:
      Tp = ((0.25*pow(u,2) - 0.5)*exp(-0.25*pow(u,2)) - 13*exp(-13.5))/(0.5 + 13*exp(-13.5))
      values[0] = 0.0
      values[1] = 5000*Tp   # [KPa]
    else:
      values[0] = 0.0
      values[1] = 0.0      #5000*Tp 
  def eval(self, values, x):
    # Ricker pulse Parameters
    r  = ((x[0] - xc)**2 + (x[1] - yc)**2)**0.5
    
    u  = self.omega*self.t - 3*pow(6,0.5)
    Sp = (1.0 - (r / rd) ** 2) ** 3

    #if self.t <= 6 * pow(6, 0.5) / self.omega:

    Tp = ((0.25 * pow(u, 2) - 0.5) * exp(-0.25 * pow(u, 2)) \
         -13 * exp(-13.5)) / (0.5 + 13 * exp(-13.5))
    #else:
   #  Tp = 0

    values[0] = (5e4)*physical_parameters.amplitude * Tp * Sp * (x[0] - xc) / r
    values[1] = (5e4)*physical_parameters.amplitude * Tp * Sp * (x[1] - yc) / r
Example #6
0
def bessi0(x):
    """
    Modified Bessel function of the first kind.

    Code taken from

    [Flannery et al. 1992] B.P. Flannery,
    W.H. Press, S.A. Teukolsky, W. Vetterling,
    "Numerical recipes in C", Press Syndicate
    of the University of Cambridge, New York
    (1992).
    """
    ax = abs(x)
    y1 = x / 3.75
    y1 *= y1
    expr1 = 1.0 + y1 * (3.5156229 + y1 * (3.0899424 + y1 *
                                          (1.2067492 + y1 *
                                           (0.2659732 + y1 *
                                            (0.360768e-1 + y1 * 0.45813e-2)))))
    y2 = 3.75 / ax
    expr2 = (ufl.exp(ax) / ufl.sqrt(ax) *
             (0.39894228 + y2 *
              (0.1328592e-1 + y2 *
               (0.225319e-2 + y2 *
                (-0.157565e-2 + y2 *
                 (0.916281e-2 + y2 *
                  (-0.2057706e-1 + y2 *
                   (0.2635537e-1 + y2 *
                    (-0.1647633e-1 + y2 * 0.392377e-2)))))))))
    return ufl.conditional(ax < 3.75, expr1, expr2)
Example #7
0
def bessk0(x):
    """
    Modified Bessel function of the second kind.

    Code taken from

    [Flannery et al. 1992] B.P. Flannery,
    W.H. Press, S.A. Teukolsky, W. Vetterling,
    "Numerical recipes in C", Press Syndicate
    of the University of Cambridge, New York
    (1992).
    """
    y1 = x * x / 4.0
    expr1 = -ufl.ln(x / 2.0) * bessi0(x) + (
        -0.57721566 + y1 * (0.42278420 + y1 *
                            (0.23069756 + y1 *
                             (0.3488590e-1 + y1 *
                              (0.262698e-2 + y1 *
                               (0.10750e-3 + y1 * 0.74e-5))))))
    y2 = 2.0 / x
    expr2 = (ufl.exp(-x) / ufl.sqrt(x) *
             (1.25331414 + y2 * (-0.7832358e-1 + y2 *
                                 (0.2189568e-1 + y2 *
                                  (-0.1062446e-1 + y2 *
                                   (0.587872e-2 + y2 *
                                    (-0.251540e-2 + y2 * 0.53208e-3)))))))
    return ufl.conditional(x > 2, expr2, expr1)
 def eval(self, values, x):
   if abs(x[0] - self.center) < 0.25:
     values[0] = 0
     values[1] = 5000 * (1 - 0.5 * self.omega ** 2 * self.t ** 2) * exp( - 0.25 *  self.omega ** 2 * self.t ** 2) 
   else:
     values[0] = 0.0
     values[1] = 0.0      #5000*Tp 
Example #9
0
def hs(
        phi: fd.Function,
        epsilon: fd.Constant = fd.Constant(10000.0),
        width_h: float = None,
        shift: float = 0.0,
        min_value: fd.Function = fd.Constant(0.0),
):
    """Heaviside approximation

    Args:
        phi (fd.Function): Level set
        epsilon ([type], optional): Parameter to approximate the Heaviside.
        Defaults to Constant(10000.0).
        width_h (float): Width of the Heaviside approximation transition in
        terms of multiple of the mesh element size
        shift: (float): Shift the level set value to define the interface.

    Returns:
        [type]: [description]
    """
    if width_h:
        if epsilon:
            fd.warning(
                "Epsilon and width_h are both defined, pick one or the other. \
                Overriding epsilon choice")
        mesh = phi.ufl_domain()
        hmin = min_mesh_size(mesh)
        epsilon = fd.Constant(math.log(0.99**2 / 0.01**2) / (width_h * hmin))

    return (fd.Constant(1.0) /
            (fd.Constant(1.0) + ufl.exp(-epsilon *
                                        (phi - fd.Constant(shift)))) +
            min_value)
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 #11
0
def eta_dash(eta_dash0, dt, temp, hum):
    """Ageing viscosity of dashpot element

    Parameters
    ----------
    eta_dash0: Previous viscosity [MPa day]
    dt: Timestep [days]
    temp: Temperature [K]
    hum: Rel. humidity [-]

    Returns
    -------
    Ageing viscosity [MPa day]

    Note
    ----
    The Book, page 470, 471, 477, formulas (10.33, 10.36, 10.39, 10.60)

    """
    beta_sT = ufl.exp(3000 * (1.0 / room_temp - 1.0 / temp))
    alpha_s = 0.1
    beta_sh = alpha_s + (1 - alpha_s) * hum**2
    psi_s = beta_sT * beta_sh

    return eta_dash0 + dt * psi_s / MPS_q4 * 1.0e-6
Example #12
0
    def guccione_dev(self, params, f0, s0, C):

        n0 = cross(f0, s0)

        # anisotropic invariants - keep in mind that for growth, self.E is the elastic part of E
        E_ff = dot(dot(self.E, f0), f0)  # fiber GL strain
        E_ss = dot(dot(self.E, s0), s0)  # cross-fiber GL strain
        E_nn = dot(dot(self.E, n0), n0)  # radial GL strain

        E_fs = dot(dot(self.E, f0), s0)
        E_fn = dot(dot(self.E, f0), n0)
        E_sn = dot(dot(self.E, s0), n0)

        c_0 = params['c_0']
        b_f = params['b_f']
        b_t = params['b_t']
        b_fs = params['b_fs']

        Q = b_f * E_ff**2. + b_t * (E_ss**2. + E_nn**2. + 2. * E_sn**2.
                                    ) + b_fs * (2. * E_fs**2. + 2. * E_fn**2.)

        psi_dev = 0.5 * c_0 * (exp(Q) - 1.)

        S = 2. * diff(psi_dev, C)

        return S
Example #13
0
def damage(eps_eqv, mesh, E, f_t, G_f):
    h_cb = ufl.CellVolume(mesh) ** (1 / 3)
    eps0 = f_t / E

    eps_f = G_f / 1.0e+6 / (f_t * h_cb) + eps0 / 2

    dmg = ufl.Min(1.0 - eps0 / eps_eqv * ufl.exp(- (eps_eqv - eps0) / (eps_f - eps0)), 1.0 - dmg_eps)
    return ufl.conditional(eps_eqv <= eps0, 0.0, 0.0 if args.damage_off else dmg)
Example #14
0
def f4(temp):
    """Arrhenius activation term

    Note
    ----
    Saetta 1993, page 763, formula inlined

    """
    return A * ufl.exp(- E0 / (R * temp))
def test_dolfin_expression_compilation_of_math_functions(dolfin):

    # Define some PyDOLFIN coefficients
    mesh = dolfin.UnitSquareMesh(3, 3)
    # Using quadratic element deliberately for accuracy
    V = dolfin.FunctionSpace(mesh, "CG", 2)
    u = dolfin.Function(V)
    u.interpolate(dolfin.Expression("x[0]*x[1]"))
    w0 = u

    # Define ufl expression with math functions
    v = abs(ufl.cos(u))/2 + 0.02
    uexpr = ufl.sin(u) + ufl.tan(v) + ufl.exp(u) + ufl.ln(v) + ufl.atan(v) + ufl.acos(v) + ufl.asin(v)

    #print dolfin.assemble(uexpr**2*dolfin.dx, mesh=mesh) # 11.7846508409

    # Define expected output from compilation
    ucode = 'v_w0[0]'
    vcode = '0.02 + fabs(cos(v_w0[0])) / 2'
    funcs = 'asin(%(v)s) + (acos(%(v)s) + (atan(%(v)s) + (log(%(v)s) + (exp(%(u)s) + (sin(%(u)s) + tan(%(v)s))))))'
    oneliner = funcs % {'u':ucode, 'v':vcode}

    # Oneliner version (ignoring reuse):
    expected_lines = ['double s[1];',
                      'Array<double> v_w0(1);',
                      'w0->eval(v_w0, x);',
                      's[0] = %s;' % oneliner,
                      'values[0] = s[0];']
    #cppcode = format_dolfin_expression(classname="DebugExpression", shape=(), eval_body=expected_lines)
    #print '-'*100
    #print cppcode
    #print '-'*100
    #dolfin.plot(dolfin.Expression(cppcode=cppcode, mesh=mesh))
    #dolfin.interactive()

    # Split version (handles reuse of v, no other reuse):
    expected_lines = ['double s[2];',
                      'Array<double> v_w0(1);',
                      'w0->eval(v_w0, x);',
                      's[0] = %s;' % (vcode,),
                      's[1] = %s;' % (funcs % {'u':ucode,'v':'s[0]'},),
                      'values[0] = s[1];']

    # Define expected evaluation values: [(x,value), (x,value), ...]
    import math
    x, y = 0.6, 0.7
    u = x*y
    v = abs(math.cos(u))/2 + 0.02
    v0 = .52
    expected0 = math.tan(v0) + 1 + math.log(v0) + math.atan(v0) + math.acos(v0) + math.asin(v0)
    expected = math.sin(u) + math.tan(v) + math.exp(u) + math.log(v) + math.atan(v) + math.acos(v) + math.asin(v)
    expected_values = [((0.0, 0.0), (expected0,)),
                       ((x, y), (expected,)),
                       ]

    # Execute all tests
    check_dolfin_expression_compilation(uexpr, expected_lines, expected_values, members={'w0':w0})
Example #16
0
 def assembleWmm(self, x):
     """
     Assemble the derivative of the parameter equation with respect to the parameter (Newton method)
     """
     trial = dl.TrialFunction(self.Vh[PARAMETER])
     test  = dl.TestFunction(self.Vh[PARAMETER])
     u = vector2Function(x[STATE], self.Vh[STATE])
     m = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
     p = vector2Function(x[ADJOINT], self.Vh[ADJOINT])
     varf = ufl.inner(ufl.exp(m)*sigma(u),strain(p))*test*trial*ufl.dx
     return dl.assemble(varf)
Example #17
0
def test_complex_algebra(self):
    z1 = ComplexValue(1j)
    z2 = ComplexValue(1+1j)

    # Remember that ufl.algebra functions return ComplexValues, but ufl.mathfunctions return complex Python scalar
    # Any operations with a ComplexValue and a complex Python scalar promote to ComplexValue
    assert z1*z2 == ComplexValue(-1+1j)
    assert z2/z1 == ComplexValue(1-1j)
    assert pow(z2, z1) == ComplexValue((1+1j)**1j)
    assert sqrt(z2) * as_ufl(1) == ComplexValue(cmath.sqrt(1+1j))
    assert ((sin(z2) + cosh(z2) - atan(z2)) * z1) == ComplexValue((cmath.sin(1+1j) + cmath.cosh(1+1j) - cmath.atan(1+1j))*1j)
    assert (abs(z2) - ln(z2))/exp(z1) == ComplexValue((abs(1+1j) - cmath.log(1+1j))/cmath.exp(1j))
Example #18
0
def test_latex_formatting_of_cmath():
    x = ufl.SpatialCoordinate(ufl.triangle)[0]
    assert expr2latex(ufl.exp(x)) == r"e^{x_0}"
    assert expr2latex(ufl.ln(x)) == r"\ln(x_0)"
    assert expr2latex(ufl.sqrt(x)) == r"\sqrt{x_0}"
    assert expr2latex(abs(x)) == r"\|x_0\|"
    assert expr2latex(ufl.sin(x)) == r"\sin(x_0)"
    assert expr2latex(ufl.cos(x)) == r"\cos(x_0)"
    assert expr2latex(ufl.tan(x)) == r"\tan(x_0)"
    assert expr2latex(ufl.asin(x)) == r"\arcsin(x_0)"
    assert expr2latex(ufl.acos(x)) == r"\arccos(x_0)"
    assert expr2latex(ufl.atan(x)) == r"\arctan(x_0)"
Example #19
0
def nn(eps, u, p, v, q):
    #return inner(grad(p), grad(q)) * dx 

    def sigma_(vec, func=ufl.tanh):
        v = [func(vec[i]) for i in range(vec.ufl_shape[0])]
        return ufl.as_vector(v)
    relu = lambda vec: conditional(ufl.gt(vec, 0), vec, (ufl.exp(vec) - 1))
    sigma = lambda vec: sigma_(vec, func=relu)

    nn = dot(W_3, sigma(ufl.transpose(as_vector([W_1, W_2])) * eps * grad(p) + b_1)) + b_2

    return inner(nn, grad(q))*dx, inner(nn, nn)*dx
Example #20
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) == 3)
        m, h, n = s

        # Assign parameters

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

        # Expressions for the m gate component
        alpha_m = (-5.0 - 0.1 * V) / (-1.0 + ufl.exp(-5.0 - V / 10.0))
        beta_m = 4 * ufl.exp(-25.0 / 6.0 - V / 18.0)
        F_expressions[0] = (1 - m) * alpha_m - beta_m * m

        # Expressions for the h gate component
        alpha_h = 0.07 * ufl.exp(-15.0 / 4.0 - V / 20.0)
        beta_h = 1.0 / (1 + ufl.exp(-9.0 / 2.0 - V / 10.0))
        F_expressions[1] = (1 - h) * alpha_h - beta_h * h

        # Expressions for the n gate component
        alpha_n = (-0.65 - 0.01 * V) / (-1.0 + ufl.exp(-13.0 / 2.0 - V / 10.0))
        beta_n = 0.125 * ufl.exp(-15.0 / 16.0 - V / 80.0)
        F_expressions[2] = (1 - n) * alpha_n - beta_n * n

        # Return results
        return dolfin.as_vector(F_expressions)
Example #21
0
def test_cpp_formatting_of_cmath():
    x, y = ufl.SpatialCoordinate(ufl.triangle)
    # Test cmath functions
    assert expr2cpp(ufl.exp(x)) == "exp(x[0])"
    assert expr2cpp(ufl.ln(x)) == "log(x[0])"
    assert expr2cpp(ufl.sqrt(x)) == "sqrt(x[0])"
    assert expr2cpp(abs(x)) == "fabs(x[0])"
    assert expr2cpp(ufl.sin(x)) == "sin(x[0])"
    assert expr2cpp(ufl.cos(x)) == "cos(x[0])"
    assert expr2cpp(ufl.tan(x)) == "tan(x[0])"
    assert expr2cpp(ufl.asin(x)) == "asin(x[0])"
    assert expr2cpp(ufl.acos(x)) == "acos(x[0])"
    assert expr2cpp(ufl.atan(x)) == "atan(x[0])"
Example #22
0
    def assembleC(self, x):
        """
        Assemble the derivative of the forward problem with respect to the parameter
        """
        trial = dl.TrialFunction(self.Vh[PARAMETER])
        test = dl.TestFunction(self.Vh[STATE])
        u = vector2Function(x[STATE], Vh[STATE])
        m = vector2Function(x[PARAMETER], Vh[PARAMETER])
        Cvarf = ufl.inner(ufl.exp(m)*trial*sigma(u), strain(test))*ufl.dx
        C = dl.assemble(Cvarf)
#        print ( "||m||", x[PARAMETER].norm("l2"), "||u||", x[STATE].norm("l2"), "||C||", C.norm("linf") )
        self.bc0.zero(C)
        return C
Example #23
0
 def assembleWmu(self, x):
     """
     Assemble the derivative of the parameter equation with respect to the state
     """
     trial = dl.TrialFunction(self.Vh[STATE])
     test  = dl.TestFunction(self.Vh[PARAMETER])
     p = vector2Function(x[ADJOINT], self.Vh[ADJOINT])
     m = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
     varf = ufl.inner(ufl.exp(m)*sigma(trial), strain(p))*test*ufl.dx
     Wmu = dl.assemble(varf)
     Wmu_t = Transpose(Wmu)
     self.bc0.zero(Wmu_t)
     Wmu = Transpose(Wmu_t)
     return Wmu
Example #24
0
    def nn(u, p, v, q):
        # return inner(grad(p), grad(q)) * dx, None, None
        
        def sigma_(vec, func=ufl.tanh):
            v = [func(vec[i]) for i in range(vec.ufl_shape[0])]
            return ufl.as_vector(v)
        relu = lambda vec: conditional(ufl.gt(vec, 0), vec, (ufl.exp(vec) - 1))
        sigma = lambda vec: sigma_(vec, func=relu)#lambda x:x)

        nn_p = dot(W_3, sigma(ufl.transpose(as_vector([W_1, W_2])) * u + b_1)) + b_2

        #nn_q = dot(W_3, sigma(ufl.transpose(as_vector([W_1, W_2])) * grad(q) + b_1)) + b_2

        return inner(nn_p, v)*dx, inner(nn_p, nn_p)*dx, nn_p
Example #25
0
def dirac_delta(phi: fd.Function, epsilon=fd.Constant(10000.0), width_h=None):
    """Dirac delta approximation

    Args:
        phi (fd.Function): Level set
        epsilon ([type], optional): Parameter to approximate the Heaviside.
        Defaults to Constant(10000.0).
        width_h (float): Width of the Heaviside approximation transition in
        terms of multiple of the mesh element size

    Returns:
        [type]: [description]
    """
    if width_h:
        if epsilon:
            fd.warning(
                "Epsilon and width_h are both defined, pick one or the other. \
                Overriding epsilon choice")
        mesh = phi.ufl_domain()
        hmin = min_mesh_size(mesh)
        epsilon = fd.Constant(math.log(0.95**2 / 0.05**2) / (width_h * hmin))

    return (fd.Constant(epsilon) * ufl.exp(-epsilon * phi) /
            (fd.Constant(1.0) + ufl.exp(-epsilon * phi))**2)
Example #26
0
    def nn(u, v):

        inp = as_vector(
            [avg(u), jump(u), *grad(avg(u)), *grad(jump(u)), *n('+')])

        def sigma_(vec, func=ufl.tanh):
            v = [func(vec[i]) for i in range(vec.ufl_shape[0])]
            return ufl.as_vector(v)

        relu = lambda vec: conditional(ufl.gt(vec, 0), vec, (ufl.exp(vec) - 1))
        sigma = lambda vec: sigma_(vec, func=relu)

        nn = dot(W_2, sigma(ufl.transpose(as_vector(W_1)) * inp + b_1)) + b_2

        return inner(nn, jump(v) + avg(v)) * dS, inner(nn, nn) * dS
Example #27
0
def pfuncs(clargs, params0, t0=0.0):
    """Create functions for parameters

    Required arguments:
    clargs: Command line arguments.
    params0: a mappable of initial numerical values of parameters

    Optional parameter:
    t0=0.0: initial time (time at which params have valuve params0

    Returns a dict mapping param names (from params0) to
    functions. Each function has the call signature func(t, params={})
    and returns the value of the parameter at time t. 
    """
    import ufl
    from KSDG import ParameterList, KSDGException
    decays = ParameterList()
    decays.decode(clargs.decay, allow_new=True)
    slopes = ParameterList()
    slopes.decode(clargs.slope, allow_new=True)
    keys = set(decays.keys()) | set(slopes.keys())
    extras = keys - set(params0.keys())
    if extras:
        raise KSDGException(', '.join([k for k in extras]) +
                            ': no such parameter')
    funcs = {}
    for k in params0.keys():
        d = decays[k] if k in decays else 0.0
        s = slopes[k] if k in slopes else 0.0
        pt0 = params0[k] if k in params0 else 1.0
        if d == 0 and s == 0:

            def func(t, params={}, p0=pt0):
                return p0
        elif d == 0:
            p0 = pt0 - s * t0

            def func(t, params={}, p0=pt0, s=s):
                return p0 + s * t
        else:
            a = (ufl.exp(d * t0) * (d * pt0 - s) - s) / d
            pinf = s / d

            def func(t, params={}, d=d, pinf=pinf, a=a):
                return pinf + a * ufl.exp(-d * t)

        funcs[k] = func
    return funcs
Example #28
0
def p_sat(temp):
    """Water vapour saturation pressure

    Parameters
    ----------
    temp0: Previous temp function [K]

    Note
    ----
    Kunzel 1995, page 40, formula (50).

    """
    a = conditional(ge(temp, 273.15), 17.08, 22.44)
    theta0 = conditional(ge(temp, 273.15), 234.18, 272.44)

    return 611. * exp(a * (temp - 273.15) / (theta0 + (temp - 273.15)))
Example #29
0
    def nn(u, v):
        #return inner(grad(p), grad(q)) * dx

        def sigma_(vec, func=ufl.tanh):
            v = [func(vec[i]) for i in range(vec.ufl_shape[0])]
            return ufl.as_vector(v)

        relu = lambda vec: conditional(ufl.gt(vec, 0), vec, (ufl.exp(vec) - 1))
        sigma = lambda vec: sigma_(vec, func=relu)  #lambda x:x)

        #from IPython import embed
        #embed()

        n1 = dot(W_2, sigma(W_1 * u) + b_1)
        n2 = dot(W_3_1, sigma(W_3_2 * u.dx(0)) + b_2)

        return inner(n1, v) * dx + inner(n2, v.dx(0)) * dx, inner(
            n1, n1) * dx + inner(n2, n2) * dx, n1
Example #30
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]
Example #31
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)
        s, m = s

        # Assign parameters
        Cm = self._parameters["Cm"]
        E_L = self._parameters["E_L"]
        g_L = self._parameters["g_L"]

        # synapse components
        alpha = self._parameters["alpha"]
        g_S = self._parameters["g_S"]
        t0 = self._parameters["t0"]
        v_eq = self._parameters["v_eq"]

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

        # Expressions for the Membrane component
        # FIXME: base on stim_type + add to Hodgkin
        # if
        # i_Stim = g_S*(-v_eq + V)*ufl.conditional(ufl.ge(time, t0), 1, 0)*ufl.exp((t0 - time)/alpha)
        # elif sss:
        #     i_Stim = g_S*ufl.conditional(ufl.ge(time, t0), 1, 0)
        # else:
        #     i_Stim = g_S*ufl.conditional(ufl.And(ufl.ge(time, t0),
        #                                          ufl.le(time, t1), 1, 0))
        i_Stim = g_S * (-v_eq + V) * ufl.conditional(ufl.ge(
            time, t0), 1, 0) * ufl.exp((t0 - time) / alpha)
        i_L = g_L * (-E_L + V)
        current[0] = (-i_L - i_Stim) / Cm

        # Return results
        return current[0]
Example #32
0
def beta_cr(dt):
    """Beta creep coefficients

    Parameters
    ----------
    dt: Timestep size [day]

    Returns
    -------
    NumPy array of beta creep coefficients [-]

    Note
    ----
    The Book, page 160, formula (5.36)

    """
    beta = []

    for ta in tau:
        beta.append(ufl.conditional(dt / ta > 30.0, 0.0, ufl.exp(-dt / ta)))
    return beta
Example #33
0
 def assembleA(self,x, assemble_adjoint = False, assemble_rhs = False):
     """
     Assemble the matrices and rhs for the forward/adjoint problems
     """
     trial = dl.TrialFunction(self.Vh[STATE])
     test = dl.TestFunction(self.Vh[STATE])
     m = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
     Avarf = ufl.inner(ufl.exp(m)*sigma(trial), strain(test))*ufl.dx
     if not assemble_adjoint:
         bform = ufl.inner(self.f, test)*ufl.dx
         Matrix, rhs = dl.assemble_system(Avarf, bform, self.bc)
     else:
         # Assemble the adjoint of A (i.e. the transpose of A)
         u = vector2Function(x[STATE], self.Vh[STATE])
         obs = vector2Function(self.u_o, self.Vh[STATE])
         bform = ufl.inner(obs - u, test)*ufl.dx
         Matrix, rhs = dl.assemble_system(dl.adjoint(Avarf), bform, self.bc0)
         
     if assemble_rhs:
         return Matrix, rhs
     else:
         return Matrix
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)))
    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 = -(1.0 - 1.0/(1.0 + ufl.exp(-5.0*stim_start +\
        5.0*time)))*stim_amplitude/(1.0 + ufl.exp(-5.0*stim_start + 5.0*time\
        - 5.0*stim_duration))

    # 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