示例#1
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
示例#2
0
    def g(self, lam):

        amp_min = self.params['amp_min']
        amp_max = self.params['amp_max']

        lam_threslo = self.params['lam_threslo']
        lam_maxlo = self.params['lam_maxlo']

        lam_threshi = self.params['lam_threshi']
        lam_maxhi = self.params['lam_maxhi']

        # Diss Hirschvogel eq. 2.107
        # TeX: g(\lambda_{\mathrm{myo}}) = \begin{cases} a_{\mathrm{min}}, & \lambda_{\mathrm{myo}} \leq \hat{\lambda}_{\mathrm{myo}}^{\mathrm{thres,lo}}, \\ a_{\mathrm{min}}+\frac{1}{2}\left(a_{\mathrm{max}}-a_{\mathrm{min}}\right)\left(1-\cos \frac{\pi(\lambda_{\mathrm{myo}}-\hat{\lambda}_{\mathrm{myo}}^{\mathrm{thres,lo}})}{\hat{\lambda}_{\mathrm{myo}}^{\mathrm{max,lo}}-\hat{\lambda}_{\mathrm{myo}}^{\mathrm{thres,lo}}}\right), &  \hat{\lambda}_{\mathrm{myo}}^{\mathrm{thres,lo}} \leq \lambda_{\mathrm{myo}}  \leq \hat{\lambda}_{\mathrm{myo}}^{\mathrm{max,lo}}, \\ a_{\mathrm{max}}, &  \hat{\lambda}_{\mathrm{myo}}^{\mathrm{max,lo}} \leq \lambda_{\mathrm{myo}} \leq \hat{\lambda}_{\mathrm{myo}}^{\mathrm{thres,hi}}, \\ a_{\mathrm{min}}+\frac{1}{2}\left(a_{\mathrm{max}}-a_{\mathrm{min}}\right)\left(1-\cos \frac{\pi(\lambda_{\mathrm{myo}}-\hat{\lambda}_{\mathrm{myo}}^{\mathrm{max,hi}})}{\hat{\lambda}_{\mathrm{myo}}^{\mathrm{max,hi}}-\hat{\lambda}_{\mathrm{myo}}^{\mathrm{thres,hi}}}\right), & \hat{\lambda}_{\mathrm{myo}}^{\mathrm{thres,hi}} \leq \lambda_{\mathrm{myo}} \leq \hat{\lambda}_{\mathrm{myo}}^{\mathrm{max,hi}}, \\ a_{\mathrm{min}}, & \lambda_{\mathrm{myo}} \geq \hat{\lambda}_{\mathrm{myo}}^{\mathrm{max,hi}} \end{cases}

        return conditional(
            le(lam, lam_threslo), amp_min,
            conditional(
                And(ge(lam, lam_threslo), le(lam, lam_maxlo)), amp_min + 0.5 *
                (amp_max - amp_min) * (1. - cos(pi * (lam - lam_threslo) /
                                                (lam_maxlo - lam_threslo))),
                conditional(
                    And(ge(lam, lam_maxlo), le(lam, lam_threshi)), amp_max,
                    conditional(
                        And(ge(lam, lam_threshi), le(lam, lam_maxhi)),
                        amp_min + 0.5 * (amp_max - amp_min) *
                        (1. - cos(pi * (lam - lam_maxhi) /
                                  (lam_maxhi - lam_threshi))),
                        conditional(ge(lam, lam_maxhi), amp_min, as_ufl(0))))))
示例#3
0
 def __init__(self, functionSpace, value, xL, xR, eps=1e-10):
     cond = 1
     x = ufl.SpatialCoordinate(functionSpace)
     for l, r, c in zip(xL, xR, x):
         if l is not None:
             cond *= ufl.conditional(c > l - eps, 1, 0)
         if r is not None:
             cond *= ufl.conditional(c < r + eps, 1, 0)
     DirichletBC.__init__(self, functionSpace, value, cond)
示例#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)
示例#5
0
def test_conditional(mode, compile_args):
    cell = ufl.triangle
    element = ufl.FiniteElement("Lagrange", cell, 1)
    u, v = ufl.TrialFunction(element), ufl.TestFunction(element)
    x = ufl.SpatialCoordinate(cell)
    condition = ufl.Or(ufl.ge(ufl.real(x[0] + x[1]), 0.1),
                       ufl.ge(ufl.real(x[1] + x[1]**2), 0.1))
    c1 = ufl.conditional(condition, 2.0, 1.0)
    a = c1 * ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx

    x1x2 = ufl.real(x[0] + ufl.as_ufl(2) * x[1])
    c2 = ufl.conditional(ufl.ge(x1x2, 0), 6.0, 0.0)
    b = c2 * ufl.conj(v) * ufl.dx

    forms = [a, b]

    compiled_forms, module = ffcx.codegeneration.jit.compile_forms(
        forms,
        parameters={'scalar_type': mode},
        cffi_extra_compile_args=compile_args)

    form0 = compiled_forms[0][0].create_cell_integral(-1)
    form1 = compiled_forms[1][0].create_cell_integral(-1)

    ffi = cffi.FFI()
    c_type, np_type = float_to_type(mode)

    A1 = np.zeros((3, 3), dtype=np_type)
    w1 = np.array([1.0, 1.0, 1.0], dtype=np_type)
    c = np.array([], dtype=np.float64)

    coords = np.array([0.0, 0.0, 1.0, 0.0, 0.0, 1.0], dtype=np.float64)

    form0.tabulate_tensor(
        ffi.cast('{type} *'.format(type=c_type), A1.ctypes.data),
        ffi.cast('{type} *'.format(type=c_type), w1.ctypes.data),
        ffi.cast('{type} *'.format(type=c_type), c.ctypes.data),
        ffi.cast('double *', coords.ctypes.data), ffi.NULL, ffi.NULL, 0)

    expected_result = np.array([[2, -1, -1], [-1, 1, 0], [-1, 0, 1]],
                               dtype=np_type)
    assert np.allclose(A1, expected_result)

    A2 = np.zeros(3, dtype=np_type)
    w2 = np.array([1.0, 1.0, 1.0], dtype=np_type)
    coords = np.array([0.0, 0.0, 1.0, 0.0, 0.0, 1.0], dtype=np.float64)

    form1.tabulate_tensor(
        ffi.cast('{type} *'.format(type=c_type), A2.ctypes.data),
        ffi.cast('{type} *'.format(type=c_type), w2.ctypes.data),
        ffi.cast('{type} *'.format(type=c_type), c.ctypes.data),
        ffi.cast('double *', coords.ctypes.data), ffi.NULL, ffi.NULL, 0)

    expected_result = np.ones(3, dtype=np_type)
    assert np.allclose(A2, expected_result)
示例#6
0
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"
示例#7
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)
示例#8
0
def handle_conditional(v, si, deps, SV_factors, FV, sv2fv, e2fi):
    fac0 = SV_factors[deps[0]]
    fac1 = SV_factors[deps[1]]
    fac2 = SV_factors[deps[2]]
    assert not fac0, "Cannot have argument in condition."

    if not (fac1 or fac2):  # non-arg ? non-arg : non-arg
        # Record non-argument subexpression
        sv2fv[si] = add_to_fv(v, FV, e2fi)
        factors = noargs
    else:
        f0 = FV[sv2fv[deps[0]]]
        f1 = FV[sv2fv[deps[1]]]
        f2 = FV[sv2fv[deps[2]]]

        # Term conditional(c, argument, non-argument) is not legal unless non-argument is 0.0
        assert fac1 or isinstance(f1, Zero)
        assert fac2 or isinstance(f2, Zero)
        assert () not in fac1
        assert () not in fac2

        z = as_ufl(0.0)

        # In general, can decompose like this:
        #    conditional(c, sum_i fi*ui, sum_j fj*uj) -> sum_i conditional(c, fi, 0)*ui + sum_j conditional(c, 0, fj)*uj
        mas = sorted(set(fac1.keys()) | set(fac2.keys()))
        factors = {}
        for k in mas:
            fi1 = fac1.get(k)
            fi2 = fac2.get(k)
            f1 = z if fi1 is None else FV[fi1]
            f2 = z if fi2 is None else FV[fi2]
            factors[k] = add_to_fv(conditional(f0, f1, f2), FV, e2fi)

    return factors
示例#9
0
def compute_welding_size(evo, V, threshold_temp, x, ds):
    '''Computes either the welding depth or the welding radius.

    Parameters:
        evo: ndarray
            The coefficients of the solution to the corresponding forward
            problem in the basis of the space V (see solve_forward).
        V: dolfin.FunctionSpace
            The FEM space of the problem being solved.
        threshold_temp: float
            The threshold temperature used as a criterion for successful welding.
        ds: dolfin.Measure
            The measure on either the symmetry axis (for welding depth) or
            the top boundary (for welding radius).

    Returns:
        evo_size: ndarray
            Contains size of either the welding depth or the welding radius over
            all time steps.

    '''

    theta_k = dolfin.Function(V)

    Nt = len(evo) - 1
    evo_size = np.zeros(Nt+1)

    for k in range(Nt+1):
        theta_k.vector().set_local(evo[k])

        evo_size[k] =  dolfin.assemble(
                conditional(ge(theta_k, threshold_temp), 1., 0.) * ds
        )

    return evo_size
示例#10
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)))
示例#11
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)
示例#12
0
    def sliding_law(self, alpha, U):

        constants = self.params.constants

        bed = self.bed
        H = self.H
        rhoi = constants.rhoi
        rhow = constants.rhow
        g = constants.g
        sl = self.params.ice_dynamics.sliding_law
        vel_rp = constants.vel_rp

        fl_ex = self.float_conditional(H)

        C = alpha * alpha
        u, v = split(U)

        if sl == 'linear':
            B2 = C

        elif sl == 'weertman':
            N = (1 - fl_ex) * (H * rhoi * g + ufl.Min(bed, 0.0) * rhow * g)
            U_mag = sqrt(U[0]**2 + U[1]**2 + vel_rp**2)
            # Need to catch N <= 0.0 here, as it's raised to
            # 1/3 (forward) and -2/3 (adjoint)
            N_term = ufl.conditional(N > 0.0, N**(1.0 / 3.0), 0)
            B2 = (1 - fl_ex) * (C * N_term * U_mag**(-2.0 / 3.0))

        return B2
示例#13
0
def liquidity(theta_k, theta_kp1, solidus, implicitness=1.):
    theta_avg = avg(theta_k, theta_kp1, implicitness)
    form = theta_avg - Constant(solidus)
    # filter to liquid parts
    form *= conditional(ge(form, 0.), 1., 0.)

    return form
示例#14
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 _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
示例#16
0
def handle_conditional(v, fac, sf, F):
    fac0 = fac[0]
    fac1 = fac[1]
    fac2 = fac[2]
    assert not fac0, "Cannot have argument in condition."

    if not (fac1 or fac2):  # non-arg ? non-arg : non-arg
        raise RuntimeError("No arguments")
    else:
        f0 = sf[0]
        f1 = sf[1]
        f2 = sf[2]

        # Term conditional(c, argument, non-argument) is not legal unless non-argument is 0.0
        assert fac1 or isinstance(f1, Zero)
        assert fac2 or isinstance(f2, Zero)
        assert () not in fac1
        assert () not in fac2

        z = as_ufl(0.0)

        # In general, can decompose like this:
        #    conditional(c, sum_i fi*ui, sum_j fj*uj) -> sum_i conditional(c, fi, 0)*ui + sum_j conditional(c, 0, fj)*uj
        mas = sorted(set(fac1.keys()) | set(fac2.keys()))
        factors = {}
        for k in mas:
            fi1 = fac1.get(k)
            fi2 = fac2.get(k)
            f1 = z if fi1 is None else F.nodes[fi1]['expression']
            f2 = z if fi2 is None else F.nodes[fi2]['expression']
            factors[k] = graph_insert(F, conditional(f0, f1, f2))

    return factors
示例#17
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)
    def res_dtheta_growth(self, u_, p_, ivar, theta_old_, thres, dt, rquant):

        theta_ = ivar["theta"]

        grfnc = growthfunction(theta_, self.I)

        try:
            omega = self.gandrparams['thres_tol']
        except:
            omega = 0

        try:
            reduc = self.gandrparams['trigger_reduction']
        except:
            reduc = 1

        assert (reduc <= 1 and reduc > 0)

        # threshold should not be lower than specified (only relevant for multiscale analysis, where threshold is set element-wise)
        threshold = conditional(gt(thres, self.gandrparams['growth_thres']),
                                (1. + omega) * thres,
                                self.gandrparams['growth_thres'])

        # trace of elastic Mandel stress
        if self.growth_trig == 'volstress':

            trigger = reduc * tr(self.M_e(u_, p_, self.kin.C(u_), ivar))

        # elastic fiber stretch
        elif self.growth_trig == 'fibstretch':

            trigger = reduc * self.fibstretch_e(self.kin.C(u_), theta_,
                                                self.kin.fib_funcs[0])

        else:
            raise NameError("Unknown growth_trig!")

        # growth function
        ktheta = grfnc.grfnc1(trigger, threshold, self.gandrparams)

        # growth residual
        r_growth = theta_ - theta_old_ - ktheta * (trigger - threshold) * dt

        # tangent
        K_growth = diff(r_growth, theta_)

        # increment
        del_theta = -r_growth / K_growth

        if rquant == 'res_del':
            return r_growth, del_theta
        elif rquant == 'ktheta':
            return ktheta
        elif rquant == 'tang':
            return K_growth
        else:
            raise NameError("Unknown return quantity!")
示例#19
0
 def grfnc1(self, trigger, thres, params):
     
     thetamax, thetamin = params['thetamax'], params['thetamin']
     tau_gr, tau_gr_rev = params['tau_gr'], params['tau_gr_rev']
     gamma_gr, gamma_gr_rev = params['gamma_gr'], params['gamma_gr_rev']
     
     k_plus = (1./tau_gr) * ((thetamax-self.theta)/(thetamax-thetamin))**(gamma_gr)
     k_minus = (1./tau_gr_rev) * ((self.theta-thetamin)/(thetamax-thetamin))**(gamma_gr_rev)
     
     k = conditional(ge(trigger,thres), k_plus, k_minus)
         
     return k
示例#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) == 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)
        def smooth(up_u_adv, up_u, o):
            # Calculate averaged velocities

            # Define the indicator function of the turbine support
            chi = ufl.conditional(ufl.gt(tf, 0), 1, 0)

            c_diff = Constant(1e6)
            F1 = chi * (inner(up_u - up_u_adv, o) + c_diff * inner(grad(up_u), grad(o))) * dx
            invchi = 1 - chi
            F2 = inner(invchi * up_u, o) * dx
            F = F1 + F2

            return F
示例#22
0
def eig(A):
    """Eigenvalues of 3x3 tensor"""
    eps = 1.0e-12

    q = ufl.tr(A) / 3.0
    p1 = 0.5 * (A[0, 1]**2 + A[1, 0]**2 + A[0, 2]**2 + A[2, 0]**2 +
                A[1, 2]**2 + A[2, 1]**2)
    p2 = (A[0, 0] - q)**2 + (A[1, 1] - q)**2 + (A[2, 2] - q)**2 + 2 * p1
    p = ufl.sqrt(p2 / 6)
    B = (A - q * ufl.Identity(3))
    r = ufl.det(B) / (2 * p**3)

    r = ufl.Max(ufl.Min(r, 1.0 - eps), -1.0 + eps)
    phi = ufl.acos(r) / 3.0

    eig0 = ufl.conditional(p2 < eps, q, q + 2 * p * ufl.cos(phi))
    eig2 = ufl.conditional(p2 < eps, q,
                           q + 2 * p * ufl.cos(phi + (2 * numpy.pi / 3)))
    eig1 = ufl.conditional(p2 < eps, q, 3 * q - eig0 -
                           eig2)  # since trace(A) = eig1 + eig2 + eig3

    return eig0, eig1, eig2
示例#23
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
示例#24
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]
示例#25
0
    def _I(self, v, s, time):
        """
        Original gotran transmembrane current dV/dt
        """
        time = time if time else Constant(0.0)

        # Assign states
        V = v

        # Assign parameters
        g_leak = self._parameters["g_L"]
        Cm = self._parameters["Cm"]
        E_leak = self._parameters["E_L"]
        stim_type = self._parameters["stim_type"]
        g_s = self._parameters["g_S"]
        alpha = self._parameters["alpha"]
        v_eq = self._parameters["v_eq"]
        t0 = self._parameters["t_start"]
        t1 = self._parameters["t_stop"]

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

        # Expressions for the Membrane component
        if stim_type == 0:
            i_stim = g_s * (-v_eq + V) * ufl.conditional(
                ufl.ge(time, t0), 1, 0) * ufl.exp((t0 - time) / alpha)
        elif stim_type == 1:
            i_stim = -g_s * ufl.conditional(ufl.ge(time, t0), 1, 0)
        elif stim_type == 2:
            i_stim = -g_s * ufl.conditional(
                ufl.And(ufl.ge(time, t0), ufl.le(time, t1)), 1, 0)

        i_leak = g_leak * (-E_leak + V)
        current[0] = (-i_leak - i_stim) / Cm

        # Return results
        return current[0]
        def smooth(u, up_u, o):
            # Calculate averaged velocities

            # Define the indicator function of the turbine support
            chi = ufl.conditional(ufl.gt(tf, 0), 1, 0)

            # Solve the Helmholtz equation in each turbine area to obtain averaged velocity values
            c_diff = Constant(1e6)
            F1 = chi * (inner(up_u - norm_approx(u), o) + Constant(distance_to_upstream) / norm_approx(u) * (inner(dot(grad(norm_approx(u)), u), o) + c_diff * inner(grad(up_u), grad(o)))) * dx
            invchi = 1 - chi
            F2 = inner(invchi * up_u, o) * dx
            F = F1 + F2

            return F
    def smooth(up_u_adv, up_u, o):
        # Calculate averaged velocities

        # Define the indicator function of the turbine support
        chi = ufl.conditional(ufl.gt(tf, 0), 1, 0)

        c_diff = Constant(1e6)
        F1 = chi * (inner(up_u - up_u_adv, o) +
                    c_diff * inner(grad(up_u), grad(o))) * dx
        invchi = 1 - chi
        F2 = inner(invchi * up_u, o) * dx
        F = F1 + F2

        return F
示例#28
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]
示例#29
0
def velocity(
        theta_k, theta_kp1,
        dt,
        liquidus, solidus,
        velocity_max=0.,
        filter_solidification=True,
        mean=False,
        filter_negative=True,
        inverse_sign=True,
        x=None,
        ):
    '''Provides the UFL form of the velocity function.

    Parameters:
        theta_k: dolfin.Function(V)
            Function representing the state from the current time slice.
        theta_kp1: dolfin.Function(V)
            Function representing the state from the next time slice.
        velocity_max: float
            The maximal allowed velocity which will not be penalized.
        implicitness: float
            The weight of theta_kp1 in the expression. Normally, should stay
            default. 
        implicitness: float

    Returns:
        form: UFL form
            The UFL form of theta_k and theta_kp1.

    '''

    velocity_ = velocity_expression(theta_k, theta_kp1, dt) \
              + dolfin.Constant(velocity_max)

    if filter_solidification:
        ind = solidification_indicator(theta_k, theta_kp1, solidus, liquidus)
        velocity_ *= ind
        if mean:
            area = dolfin.assemble(integral(ind, x))
            if area > 0:
                velocity_ /= area

    if filter_negative:
        velocity_ *= conditional(le(velocity_, 0.), 1., 0.)

    if inverse_sign:
        velocity_ *= -1

    return velocity_
    def smooth(u, up_u, o):
        # Calculate averaged velocities

        # Define the indicator function of the turbine support
        chi = ufl.conditional(ufl.gt(tf, 0), 1, 0)

        # Solve the Helmholtz equation in each turbine area to obtain averaged velocity values
        c_diff = Constant(1e6)
        F1 = chi * (inner(up_u - norm_approx(u), o) +
                    Constant(distance_to_upstream) / norm_approx(u) *
                    (inner(dot(grad(norm_approx(u)), u), o) +
                     c_diff * inner(grad(up_u), grad(o)))) * dx
        invchi = 1 - chi
        F2 = inner(invchi * up_u, o) * dx
        F = F1 + F2

        return F
示例#31
0
def test_latex_formatting_of_variables():
    x, y = ufl.SpatialCoordinate(ufl.triangle)
    # Test user-provided C variables for subexpressions
    # we can use variables for x[0], and sum, and power
    assert expr2latex(x**2 + y**2, variables={x**2: 'x2', y**2: 'y2'}) == "x2 + y2"
    assert expr2latex(x**2 + y**2, variables={x: 'z', y**2: 'y2'}) == r"{z}^{2} + y2"
    assert expr2latex(x**2 + y**2, variables={x**2 + y**2: 'q'}) == "q"
    # we can use variables in conditionals
    if 0:
        assert expr2latex(ufl.conditional(ufl.Or(ufl.eq(x, 2), ufl.ne(y, 4)), 7, 8), variables={ufl.eq(x, 2): 'c1', ufl.ne(y, 4): 'c2'}) == "c1 || c2 ? 7: 8"
    # we can replace coefficients (formatted by user provided code)
    V = ufl.FiniteElement("CG", ufl.triangle, 1)
    f = ufl.Coefficient(V, count=0)
    assert expr2latex(f, variables={f: 'f'}) == "f"
    assert expr2latex(f**3, variables={f: 'f'}) == r"{f}^{3}"
    # variables do not replace derivatives of variable expressions
    assert expr2latex(f.dx(0), variables={f: 'f'}) == r"\overset{0}{w}_{, 0}"
    # variables do replace variable expressions that are themselves derivatives
    assert expr2latex(f.dx(0), variables={f.dx(0): 'df', ufl.grad(f)[0]: 'df'}) == "df"
    assert expr2latex(ufl.grad(f)[0], variables={f.dx(0): 'df', ufl.grad(f)[0]: 'df'}) == "df"
示例#32
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]
示例#33
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
示例#34
0
def test_cpp_formatting_with_variables():
    x, y = ufl.SpatialCoordinate(ufl.triangle)
    # Test user-provided C variables for subexpressions
    # we can use variables for x[0], and sum, and power
    assert expr2cpp(x**2 + y**2, variables={x**2: 'x2', y**2: 'y2'}) == "x2 + y2"
    assert expr2cpp(x**2 + y**2, variables={x: 'z', y**2: 'y2'}) == "pow(z, 2) + y2"
    assert expr2cpp(x**2 + y**2, variables={x**2 + y**2: 'q'}) == "q"
    # we can use variables in conditionals
    assert expr2cpp(ufl.conditional(ufl.Or(ufl.eq(x, 2), ufl.ne(y, 4)), 7, 8),
                    variables={ufl.eq(x, 2): 'c1', ufl.ne(y, 4): 'c2'}) == "c1 || c2 ? 7: 8"
    # we can replace coefficients (formatted by user provided code)
    V = ufl.FiniteElement("CG", ufl.triangle, 1)
    f = ufl.Coefficient(V, count=0)
    assert expr2cpp(f, variables={f: 'f'}) == "f"
    assert expr2cpp(f**3, variables={f: 'f'}) == "pow(f, 3)"
    # variables do not replace derivatives of variable expressions
    assert expr2cpp(f.dx(0), variables={f: 'f'}) == "d1_w0[0]"

    # This test depends on which differentiation algorithm is in use
    # in UFL, representing derivatives as SpatialDerivative or Grad:
    # variables do replace variable expressions that are themselves derivatives
    assert expr2cpp(f.dx(0), variables={f.dx(0): 'df', ufl.grad(f)[0]: 'df'}) == "df"
    assert expr2cpp(ufl.grad(f)[0], variables={f.dx(0): 'df', ufl.grad(f)[0]: 'df'}) == "df"
示例#35
0
    def _I(self, v, s, time):
        """
        Original gotran transmembrane current dV/dt
        """
        time = time if time else Constant(0.0)

        # Assign states
        V = v
        assert(len(s) == 2)
        m, h = s

        # Assign parameters
        amp = self._parameters["amp"]
        duration = self._parameters["duration"]
        stimStart = self._parameters["stimStart"]
        E_Na = self._parameters["E_Na"]
        g_Na = self._parameters["g_Na"]
        E_K = self._parameters["E_K"]
        g_K = self._parameters["g_K"]
        k_r = self._parameters["k_r"]

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

        # Expressions for the Fast sodium current component
        i_Na = g_Na*ufl.elem_pow(m, 3.0)*(-E_Na + V)*h

        # Expressions for the Potassium current component
        i_K = g_K*(-E_K + V)*ufl.exp((E_K - V)/k_r)

        # Expressions for the Membrane component
        i_stim = ufl.conditional(ufl.And(ufl.gt(time, stimStart),\
            ufl.le(time, duration + stimStart)), amp, 0)
        current[0] = -i_K - i_Na - i_stim

        # Return results
        return current[0]
示例#36
0
文件: mesh.py 项目: hyharry/firedrake
def SubDomainData(geometric_expr):
    """Creates a subdomain data object from a boolean-valued UFL expression.

    The result can be attached as the subdomain_data field of a
    :class:`ufl.Measure`. For example:

        x = mesh.coordinates
        sd = SubDomainData(x[0] < 0.5)
        assemble(f*dx(subdomain_data=sd))

    """
    import firedrake.functionspace as functionspace
    import firedrake.projection as projection

    # Find domain from expression
    m = geometric_expr.ufl_domain()

    # Find selected cells
    fs = functionspace.FunctionSpace(m, 'DG', 0)
    f = projection.project(ufl.conditional(geometric_expr, 1, 0), fs)

    # Create cell subset
    indices, = np.nonzero(f.dat.data_ro_with_halos > 0.5)
    return op2.Subset(m.cell_set, indices)
示例#37
0
  def __define_boundary_terms(self):
    if self.verb > 2: print0("Defining boundary terms")

    self.bnd_vector_form = numpy.empty(self.DD.G, dtype=object)
    self.bnd_matrix_form = numpy.empty(self.DD.G, dtype=object)

    n = FacetNormal(self.DD.mesh)
    i,p,q = ufl.indices(3)
    
    natural_boundaries = self.BC.vacuum_boundaries.union(self.BC.incoming_fluxes.keys())

    nonzero = lambda x: numpy.all(x > 0)
    nonzero_inc_flux = any(map(nonzero, self.BC.incoming_fluxes.values()))

    if nonzero_inc_flux and not self.fixed_source_problem:
      coupled_solver_error(__file__,
                   "define boundary terms",
                   "Incoming flux specified for an eigenvalue problem"+\
                   "(Q must be given whenever phi_inc is; it may possibly be zero everywhere)")

    for g in range(self.DD.G):
      self.bnd_vector_form[g] = ufl.zero()
      self.bnd_matrix_form[g] = ufl.zero()

    if natural_boundaries:
      try:
        ds = Measure("ds")[self.DD.boundaries]
      except TypeError:
        coupled_solver_error(__file__,
                             "define boundary terms",
                             "File assigning boundary indices to facets required if vacuum or incoming flux boundaries "
                             "are specified.")
          
      for bnd_idx in natural_boundaries:
        # NOTE: The following doesn't work because ufl.abs requires a function
        #
        #for g in range(self.DD.G):
        #  self.bnd_matrix_form[g] += \
        #    abs(self.tensors.G[p,q,i]*n[i])*self.u[g][q]*self.v[g][p]*ds(bnd_idx)
        #
        # NOTE: Instead, the following explicit loop has to be used; this makes tensors.G unneccessary
        #
        for pp in range(self.DD.M):
          omega_p_dot_n = self.DD.ordinates_matrix[i,pp]*n[i]

          for g in range(self.DD.G):
            self.bnd_matrix_form[g] += \
              abs(omega_p_dot_n)*self.tensors.Wp[pp]*self.u[g][pp]*self.v[g][pp]*ds(bnd_idx)
    
      if nonzero_inc_flux:
        for pp in range(self.DD.M):
          omega_p_dot_n = self.DD.ordinates_matrix[i,pp]*n[i]
          
          for bnd_idx, psi_inc in self.BC.incoming_fluxes.iteritems():
              
            if psi_inc.shape != (self.DD.M, self.DD.G):
              coupled_solver_error(__file__,
                           "define boundary terms",
                           "Incoming flux with incorrect number of groups and directions specified: "+
                           "{}, expected ({}, {})".format(psi_inc.shape, self.DD.M, self.DD.G))
            
            
            for g in range(self.DD.G):
              self.bnd_vector_form[g] += \
                ufl.conditional(omega_p_dot_n < 0,
                                omega_p_dot_n*self.tensors.Wp[pp]*psi_inc[pp,g]*self.v[g][pp]*ds(bnd_idx),
                                ufl.zero())  # FIXME: This assumes zero adjoint outgoing flux
    else: # Apply vacuum b.c. everywhere
      ds = Measure("ds")

      for pp in range(self.DD.M):
        omega_p_dot_n = self.DD.ordinates_matrix[i,pp]*n[i]

        for g in range(self.DD.G):
          self.bnd_matrix_form[g] += abs(omega_p_dot_n)*self.tensors.Wp[pp]*self.u[g][pp]*self.v[g][pp]*ds()
示例#38
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"
示例#39
0
tf = project(Expression("sin(2*pi*x[0])"), V)

def norm_approx(u, alpha=1e-4):
    # A smooth approximation to ||u||
    return sqrt(inner(u, u)+alpha**2)

# Advect 
shift = 0.1
theta = 0.5 
uhalf = Constant(1.-theta)*u0 + Constant(theta)*u
F = (inner(u-u0, q) + Constant(shift)*inner(uhalf.dx(0)*1, q) + Constant(1e-8)*inner(grad(u), grad(q)))*dx 
solve(F == 0, u)

plot(u, interactive=True, title="Computed after shifting")
u_shift = project(Expression("1+sin(2*pi*(x[0]-shift))", shift=shift), V)
plot(u_shift, interactive=True, title="Expected after shifting")

# Diffuse
a = Function(V)
chi = ufl.conditional(ufl.ge(tf, 0.0), 0, 1)
F1 = chi*(inner(a-u0, q) + Constant(1e3)*inner(grad(a), grad(q)))*dx 
invchi = 1-chi
F2 = inner(invchi*a, q)*dx 
F = F1 + F2

solve(F == 0, a)
adg = interpolate(a, Vdg)
f = File("averaged.pvd") 
f << adg
plot(adg, interactive=True, title="Averaged")