Ejemplo n.º 1
0
    def I(self, V, s, time=None):
        """dv/dt = -I."""
        Cm = self._parameters["Cm"]
        GNa = self._parameters["GNa"]
        GNaL = self._parameters["GNaL"]
        GK = self._parameters["GK"]
        GKL = self._parameters["GKL"]
        GAHP = self._parameters["GAHP"]
        control = self._parameters["control"]
        GClL = self._parameters["GClL"]

        # Define some parameters
        beta0 = 7
        Cli = 6
        Clo = 130

        Nao = 144 - beta0*(s[5] - 18)
        ENa = 26.64*df.ln(Nao/s[5])
        Ki = 140 + (18 - s[5])
        EK = 26.64*df.ln(control*s[4]/Ki)
        ECl = 26.64*df.ln(Cli/Clo)

        INa = GNa*s[0]**3*s[2]*(V - ENa) + GNaL*(V - ENa)
        IK = (GK*s[1]**4 + GAHP*s[3]/(1 + s[3]) + GKL)*(V - EK)
        ICl = GClL*(V - ECl)
        return (INa + IK + ICl)/Cm       # Check the sign
Ejemplo n.º 2
0
 def G_RK(self, v):
     # From the determined RK coefficients, obtain gMix
     P = self.P
     Vol = self.Vol
     # Convect vol frac to mol frac
     x = v/Vol[0]/((1-v)/Vol[1]+v/Vol[0])
#      x = v
     return 1/np.sqrt(self.length[0]*self.length[1])*(x*ln(x)+(1.0-x)*ln(1.0-x)+x*(1-x)*sum([P[::-1][i]*(2*x-1)**i for i in range(len(P))]))
Ejemplo n.º 3
0
def create_hydrostatic_pressure(mesh, cc):
    x = df.MeshCoordinates(mesh)
    p_h = -0.25 * (2.0 * x[1] - cc[r"\eps"] *
                   df.ln(df.cosh((1.0 - 2.0 * x[1]) / cc[r"\eps"])))
    p_h += 0.25 * (2.0 - cc[r"\eps"] * df.ln(df.cosh(1.0 / cc[r"\eps"])))
    p_h = cc[r"g_a"] * ((cc[r"\rho_1"] - cc[r"\rho_2"]) * p_h + cc[r"\rho_2"] *
                        (1.0 - x[1]))

    return p_h
Ejemplo n.º 4
0
    def updateCoefficients(self):

        x, y = SpatialCoordinate(self.mesh)

        self.a = as_matrix([[-5. / ln(sqrt(pow(x, 2) + pow(y, 2))) + 15, 1.0],
                            [1.0, -1. / ln(sqrt(pow(x, 2) + pow(y, 2))) + 3]])

        # Init exact solution
        self.u_ = pow(sqrt(pow(x, 2) + pow(y, 2)), 7. / 4)

        # Init right-hand side
        self.f = inner(self.a, grad(grad(self.u_)))

        # Set boundary conditions to exact solution
        self.g = self.u_
def softplus(y1, y2, alpha=1):
    # The softplus function is a differentiable approximation
    # to the ramp function.  Its derivative is the logistic function.
    # Larger alpha makes a sharper transition.
    return Max(y1,
               y2) + (1. / alpha) * ln(1 + exp(alpha *
                                               (Min(y1, y2) - Max(y1, y2))))
Ejemplo n.º 6
0
    def _init_forms(self):

        u = self.state
        v = self.state_test

        F = dolfin.variable(DeformationGradient(u))
        J = Jacobian(F)

        dx = self.geometry.dx

        # Add penalty term
        internal_energy = self.material.strain_energy(F) \
            + self.kappa * (J * dolfin.ln(J) - J + 1)

        self._virtual_work \
            = dolfin.derivative(internal_energy * dx,
                                self.state, self.state_test)

        self._virtual_work += self._external_work(u, v)

        self._jacobian \
            = dolfin.derivative(self._virtual_work, self.state,
                                dolfin.TrialFunction(self.state_space))

        self._set_dirichlet_bc()
Ejemplo n.º 7
0
    def append(self, uh):
        '''Update mesh size and dims of fem space and the error + rate'''
        error = self.get_error(uh)
        self.errors.append(error)

        h = uh.function_space().mesh().hmin()
        self.hs.append(h)

        ndofs = uh.function_space().dim()
        self.Vdims.append(ndofs)

        if len(self.errors) > 1:
            try:
                rate = df.ln(self.errors[-1]/self.errors[-2])/df.ln(self.hs[-1]/self.hs[-2])
            except ZeroDivisionError:
                rate = np.nan
        else:
            rate = np.nan
        self.rates.append(rate)
Ejemplo n.º 8
0
    def initialize_with_field(self, u):
        super().initialize_with_field(u)

        d = self.deformation_measures.d
        F = self.deformation_measures.F
        J = self.deformation_measures.J
        I1 = self.deformation_measures.I1
        # I2 = self.deformation_measures.I2
        # I3 = self.deformation_measures.I3

        for m in self.material_parameters:

            E = m.get('E', None)
            nu = m.get('nu', None)

            mu = m.get('mu', None)
            lm = m.get('lm', None)

            if mu is None:
                if E is None or nu is None:
                    raise RuntimeError(
                        'Material model requires parameter "mu"; '
                        'otherwise, require parameters "E" and "nu".')

                mu = E / (2 * (1 + nu))

            if lm is None:
                if E is None or nu is None:
                    raise RuntimeError(
                        'Material model requires parameter "lm"; '
                        'otherwise, require parameters "E" and "nu".')

                lm = E * nu / ((1 + nu) * (1 - 2 * nu))

            psi = (mu / 2) * (I1 - d - 2 * ln(J)) + (lm / 2) * ln(J)**2

            pk1 = diff(psi, F)
            pk2 = dot(inv(F), pk1)

            self.psi.append(psi)
            self.pk1.append(pk1)
            self.pk2.append(pk2)
Ejemplo n.º 9
0
    def updateCoefficients(self):

        x, y = SpatialCoordinate(self.mesh)
        z = -1. / ln(sqrt(pow(x, 2) + pow(y, 2)))

        # Init coefficient matrix
        self.a = as_matrix([[5 * z + 15, 1.], [1., 1 * z + 3]])
        self.u_ = pow(pow(x, 2) + pow(y, 2), 7. / 8)
        # Init right-hand side
        self.f = inner(self.a, grad(grad(self.u_)))

        # Set boundary conditions to exact solution
        self.g = self.u_
def r_temp_c_tilda_cal(c_tilda, Temp):

    a_0 = -5.73
    a_1 = 1.25e-2
    a_2 = 1.38
    a_3 = 2.61e-5
    a_4 = -4.01e-3
    a_5 = 3.26e-1

    #con_ln_log10 = 1.
    #con_ln_log10 = 2.3025850929940456840179914546843642076011
    con_ln_log10 = ln(10.)

    r_condition_1 = a_0 + a_1*Temp + a_2*ln(abs(c_tilda))/con_ln_log10\
    + a_3*pow(Temp, 2.0) + a_4*Temp*ln(abs(c_tilda))/con_ln_log10 + a_5*pow(ln(abs(c_tilda))/con_ln_log10, 2.0)

    b_0 = -6.45
    b_1 = 2.09e-2
    b_2 = -4.65e-2
    b_3 = 3.06e-5
    b_4 = 9.25e-3
    b_5 = -4.59e-1

    r_condition_2 = b_0 + b_1*Temp + b_2*ln(abs(c_tilda))/con_ln_log10\
    + b_3*pow(Temp, 2.0) + b_4*Temp*ln(abs(c_tilda))/con_ln_log10 + b_5*pow(ln(abs(c_tilda))/con_ln_log10, 2.0)

    c_0 = -5.80
    c_1 = 1.35e-2
    c_2 = 9.97e-1
    c_3 = 3.80e-5
    c_4 = 1.51e-5
    c_5 = -4.87e-4

    r_condition_3 = c_0 + c_1*Temp + c_2*ln(abs(c_tilda))/con_ln_log10\
    + c_3*pow(Temp, 2.0) + c_4*Temp*ln(abs(c_tilda))/con_ln_log10 + c_5*pow(ln(abs(c_tilda))/con_ln_log10, 2.0)
    return conditional(
        ge(c_tilda, 0.01), r_condition_1,
        conditional(ge(c_tilda, -0.01), r_condition_3, r_condition_2))
Ejemplo n.º 11
0
    def compute(self, inputs, outputs):
        pde_problem = self.options['pde_problem']
        # form = self.options['form']
        rho = self.options['rho']
        expression = self.options['expression']

        self._set_values(inputs)
        von_Mises_max = df.project(
            expression,
            self.density_function_space).vector().get_local().max()

        self.form = (1 / df.CellVolume(self.mesh) *
                     df.exp(rho * (expression - von_Mises_max))) * df.dx
        outputs['von_mises_max'] = 1 / rho * df.ln(df.assemble(
            self.form)) + von_Mises_max
Ejemplo n.º 12
0
    def F(self, V, s, time=None):
        m, h, n, NKo, NKi, NNao, NNai, NClo, NCli, voli, O = s
        O = dolfin.conditional(dolfin.ge(O, 0), O, 0)

        G_K = self._parameters["G_K"]
        G_Na = self._parameters["G_Na"]
        G_ClL = self._parameters["G_ClL"]
        G_Kl = self._parameters["G_KL"]
        G_NaL = self._parameters["G_NaL"]
        C = self._parameters["C"]

        # Ion Concentration related Parameters
        eps_K = self._parameters["eps_K"]
        G_glia = self._parameters["G_glia"]
        eps_O = self._parameters["eps_O"]
        Ukcc2 = self._parameters["Ukcc2"]
        Unkcc1 = self._parameters["Unkcc1"]
        rho_max = self._parameters["rho_max"]

        # Volume
        vol = 1.4368e-15  # unit:m^3, when r=7 um,v=1.4368e-15 m^3    # TODO: add to parameters
        beta0 = self._parameters["beta0"]

        # Time Constant
        tau = self._parameters["tau"]
        KBath = self._parameters["KBath"]
        OBath = self._parameters["OBath"]

        gamma = self._gamma(voli)
        volo = (1 + 1 / beta0) * vol - voli  # Extracellular volume
        beta = voli / volo  # Ratio of intracelluar to extracelluar volume

        # Gating variables
        alpha_m = 0.32 * (54 + V) / (1 - exp(-(V + 54) / 4))
        beta_m = 0.28 * (V + 27) / (exp((V + 27) / 5) - 1)

        alpha_h = 0.128 * exp(-(V + 50) / 18)
        beta_h = 4 / (1 + exp(-(V + 27) / 5))

        alpha_n = 0.032 * (V + 52) / (1 - exp(-(V + 52) / 5))
        beta_n = 0.5 * exp(-(V + 57) / 40)

        dotm = alpha_m * (1 - m) - beta_m * m
        doth = alpha_h * (1 - h) - beta_h * h
        dotn = alpha_n * (1 - n) - beta_n * n

        Ko, Ki, Nao, Nai, Clo, Cli = self._get_concentrations(V, s)

        fo = 1 / (1 + exp((2.5 - OBath) / 0.2))
        fv = 1 / (1 + exp((beta - 20) / 2))
        eps_K *= fo * fv
        G_glia *= fo

        rho = rho_max / (1 + exp((20 - O) / 3)) / gamma
        I_glia = G_glia / (1 + exp((18 - Ko) / 2.5))
        Igliapump = rho / 3 / (1 + exp((25 - 18) / 3)) / (1 + exp(3.5 - Ko))
        I_diff = eps_K * (Ko - KBath) + I_glia + 2 * Igliapump * gamma

        I_K = self._I_K(V, n, Ko, Ki)
        I_Na = self._I_Na(V, m, h, Nao, Nai)
        I_Cl = self._I_Cl(V, Clo, Cli)
        I_pump = self._I_pump(Nai, Ko, O, gamma)

        # Cloride transporter (mM/s)
        fKo = 1 / (1 + exp(16 - Ko))
        FKCC2 = Ukcc2 * ln((Ki * Cli) / (Ko * Clo))
        FNKCC1 = Unkcc1 * fKo * (ln((Ki * Cli) / (Ko * Clo)) + ln(
            (Nai * Cli) / (Nao * Clo)))

        dotNKo = tau * volo * (gamma * beta * (I_K - 2.0 * I_pump) - I_diff +
                               FKCC2 * beta + FNKCC1 * beta)
        dotNKi = -tau * voli * (gamma * (I_K - 2.0 * I_pump) + FKCC2 + FNKCC1)

        dotNNao = tau * volo * beta * (gamma * (I_Na + 3.0 * I_pump) + FNKCC1)
        dotNNai = -tau * voli * (gamma * (I_Na + 3.0 * I_pump) + FNKCC1)

        dotNClo = beta * volo * tau * (FKCC2 - gamma * I_Cl + 2 * FNKCC1)
        dotNCli = voli * tau * (gamma * I_Cl - FKCC2 - 2 * FNKCC1)

        r1 = vol / voli
        r2 = 1 / beta0 * vol / ((1 + 1 / beta0) * vol - voli)
        pii = Nai + Cli + Ki + 132 * r1
        pio = Nao + Ko + Clo + 18 * r2

        vol_hat = vol * (1.1029 - 0.1029 * exp((pio - pii) / 20))
        dotVoli = -(voli - vol_hat) / 0.25 * tau
        dotO = tau * (-5.3 * (I_pump + Igliapump) * gamma + eps_O *
                      (OBath - O))

        F_expressions = [ufl.zero()] * self.num_states()
        F_expressions[0] = dotm
        F_expressions[1] = doth
        F_expressions[2] = dotn
        F_expressions[3] = dotNKo
        F_expressions[4] = dotNKi
        F_expressions[5] = dotNNao
        F_expressions[6] = dotNNai
        F_expressions[7] = dotNClo
        F_expressions[8] = dotNCli
        F_expressions[9] = dotVoli
        F_expressions[10] = dotO
        return dolfin.as_vector(F_expressions)
def mu_newton_linear_adapt(c, mu_light, mu_heavy, c_light, c_heavy):
    mu_light = ln(mu_light)
    mu_heavy = ln(mu_heavy)
    mu = mu_light + (c - c_light) / (c_heavy - c_light) * (mu_heavy - mu_light)
    return exp(mu)
Ejemplo n.º 14
0
    def F(self, V, s, time=None):
        """ds/dt = F(v, s)."""
        GCa = self._parameters["GCa"]
        gamma1 = self._parameters["gamma1"]
        Gglia = self._parameters["Gglia"]
        tau = self._parameters["tau"]
        control = self._parameters["control"]
        GNa = self._parameters["GNa"]
        GNaL = self._parameters["GNaL"]
        GK = self._parameters["GK"]
        GKL = self._parameters["GKL"]
        GAHP = self._parameters["GAHP"]
        Koinf = self._parameters["Koinf"]

        # Define some parameters
        ECa = 120
        phi = 3
        rho = 1.25
        eps0 = 1.2
        beta0 = 7
        Cli = 6
        Clo = 130

        Nao = 144 - beta0*(s[5] - 18)
        ENa = 26.64*df.ln(Nao/s[5])
        Ki = 140 + (18 - s[5])
        EK = 26.64*df.ln(control*s[4]/Ki)
        INa = GNa*s[0]**3*s[2]*(V - ENa) + GNaL*(V - ENa)
        IK = (GK*s[1]**4 + GAHP*s[3]/(1 + s[3]) + GKL)*(V - EK)

        a_m = (3.0 + (0.1)*V)*(1 - df.exp(-3 -1/10*V))**(-1)
        b_m = 4*df.exp(-55/18 - 1/18*V)
        ah = (0.07)*df.exp(-11/5 - 1/20*V)
        bh = (1 + df.exp(-7/5 - 1/10*V))**(-1)
        an = (0.34 + (0.01)*V)*(1 - df.exp(-17/5 - 1/10*V))**(-1)
        bn = (0.125)*df.exp(-11/20 - 1/80*V)

        taum = (a_m + b_m)**(-1)
        minf = a_m*(a_m + b_m)**(-1)
        h_inf = (bh + ah)**(-1)*ah
        tauh = (bh + ah)**(-1)
        ninf = (an + bn)**(-1)*an
        taun = (an + bn)**(-1)

        dot_m = phi*(minf - s[0])*taum**(-1)
        dot_h = phi*(ninf - s[1])/taun
        dot_n = phi*(h_inf - s[2])/tauh

        Ipump = rho*(1/(1 + df.exp((25 - s[5])/3)))*(1/(1 + df.exp(5.5 - s[4])))
        IGlia = Gglia/(1 + df.exp((18 - s[4])/2.5))
        Idiff = eps0*(s[4] - Koinf)

        dot_Ca = -s[3]/80 - 0.002*GCa*(V - ECa)/(1 + df.exp(-(V + 25)/2.5))
        dot_K = (gamma1*beta0*IK - 2*beta0*Ipump - IGlia - Idiff)/tau
        # dot_Na = (gamma1*INa + 3*Ipump)/tau
        dot_Na = -(gamma1*INa + 3*Ipump)/tau    # Pretty sure it should me minus

        F_expressions = [ufl.zero()]*self.num_states()
        F_expressions[0] = dot_m
        F_expressions[1] = dot_h
        F_expressions[2] = dot_n
        F_expressions[3] = dot_Ca
        F_expressions[4] = dot_K
        F_expressions[5] = dot_Na
        return df.as_vector(F_expressions)
Ejemplo n.º 15
0
def get_residual_form(u,
                      v,
                      rho_e,
                      V_density,
                      tractionBC,
                      T,
                      iteration_number,
                      additive='strain',
                      k=8.,
                      method='RAMP'):

    df.dx = df.dx(metadata={"quadrature_degree": 4})
    # stiffness = rho_e/(1 + 8. * (1. - rho_e))

    if method == 'SIMP':
        stiffness = rho_e**3
    else:
        stiffness = rho_e / (1 + 8. * (1. - rho_e))

    # print('the value of stiffness is:', rho_e.vector().get_local())
    # Kinematics
    d = len(u)
    I = df.Identity(d)  # Identity tensor
    F = I + df.grad(u)  # Deformation gradient
    C = F.T * F  # Right Cauchy-Green tensor
    # Invariants of deformation tensors
    Ic = df.tr(C)
    J = df.det(F)
    stiffen_pow = 1.
    threshold_vol = 1.

    eps_star = 0.05
    # print("eps_star--------")

    if additive == 'strain':
        print("additive == strain")

        if iteration_number == 1:
            print('iteration_number == 1')
            eps = df.sym(df.grad(u))
            eps_dev = eps - 1 / 3 * df.tr(eps) * df.Identity(2)
            eps_eq = df.sqrt(2.0 / 3.0 * df.inner(eps_dev, eps_dev))
            # eps_eq_proj = df.project(eps_eq, density_function_space)
            ratio = eps_eq / eps_star
            ratio_proj = df.project(ratio, V_density)

            c1_e = k * (5.e-2) / (1 + 8. * (1. - (5.e-2))) / 6

            c2_e = df.Function(V_density)
            c2_e.vector().set_local(5e-4 * np.ones(V_density.dim()))

            fFile = df.HDF5File(df.MPI.comm_world, "c2_e_proj.h5", "w")
            fFile.write(c2_e, "/f")
            fFile.close()

            fFile = df.HDF5File(df.MPI.comm_world, "ratio_proj.h5", "w")
            fFile.write(ratio_proj, "/f")
            fFile.close()
            iteration_number += 1
            E = k * stiffness
            phi_add = (1 - stiffness) * ((c1_e * (Ic - 3)) + (c2_e *
                                                              (Ic - 3))**2)

        else:
            ratio_proj = df.Function(V_density)
            fFile = df.HDF5File(df.MPI.comm_world, "ratio_proj.h5", "r")
            fFile.read(ratio_proj, "/f")
            fFile.close()

            c2_e = df.Function(V_density)
            fFile = df.HDF5File(df.MPI.comm_world, "c2_e_proj.h5", "r")
            fFile.read(c2_e, "/f")
            fFile.close()
            c1_e = k * (5.e-2) / (1 + 8. * (1. - (5.e-2))) / 6

            c2_e = df.conditional(df.le(ratio_proj, eps_star),
                                  c2_e * df.sqrt(ratio_proj),
                                  c2_e * (ratio_proj**3))
            phi_add = (1 - stiffness) * ((c1_e * (Ic - 3)) + (c2_e *
                                                              (Ic - 3))**2)
            E = k * stiffness

            c2_e_proj = df.project(c2_e, V_density)
            print('c2_e projected -------------')

            eps = df.sym(df.grad(u))
            eps_dev = eps - 1 / 3 * df.tr(eps) * df.Identity(2)
            eps_eq = df.sqrt(2.0 / 3.0 * df.inner(eps_dev, eps_dev))
            # eps_eq_proj = df.project(eps_eq, V_density)
            ratio = eps_eq / eps_star
            ratio_proj = df.project(ratio, V_density)

            fFile = df.HDF5File(df.MPI.comm_world, "c2_e_proj.h5", "w")
            fFile.write(c2_e_proj, "/f")
            fFile.close()

            fFile = df.HDF5File(df.MPI.comm_world, "ratio_proj.h5", "w")
            fFile.write(ratio_proj, "/f")
            fFile.close()

    elif additive == 'vol':
        print("additive == vol")
        stiffness = stiffness / (df.det(F)**stiffen_pow)

        # stiffness = df.conditional(df.le(df.det(F),threshold_vol), (stiffness/(df.det(F)/threshold_vol))**stiffen_pow, stiffness)
        E = k * stiffness

    elif additive == 'False':
        print("additive == False")
        E = k * stiffness  # rho_e is the design variable, its values is from 0 to 1

    nu = 0.4  # Poisson's ratio

    lambda_ = E * nu / (1. + nu) / (1 - 2 * nu)
    mu = E / 2 / (1 + nu)  #lame's parameters

    # Stored strain energy density (compressible neo-Hookean model)
    psi = (mu / 2) * (Ic - 3) - mu * df.ln(J) + (lambda_ / 2) * (df.ln(J))**2
    # print('the length of psi is:',len(psi.vector()))
    if additive == 'strain':
        psi += phi_add
    B = df.Constant((0.0, 0.0))

    # Total potential energy
    '''The first term in this equation provided this error'''
    Pi = psi * df.dx - df.dot(B, u) * df.dx - df.dot(T, u) * tractionBC

    res = df.derivative(Pi, u, v)

    return res
def Softplus(a, b, alpha=1):
    return Max(a, b) + 1. / alpha * df.ln(1 + df.exp(-abs(a - b) * alpha))
Ejemplo n.º 17
0
d = len(u)  # Displacement dimension

I = dolfin.Identity(d)
F = dolfin.variable(I + dolfin.grad(u))

C = F.T * F
J = dolfin.det(F)
I1 = dolfin.tr(C)

# Lame material parameters
lm = E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu))
mu = E / (2.0 + 2.0 * nu)

# Energy density of a Neo-Hookean material model
psi = (mu / 2.0) * (I1 - d - 2.0 * dolfin.ln(J)) + (lm / 2.0) * dolfin.ln(J)**2

# First Piola-Kirchhoff
pk1 = dolfin.diff(psi, F)

# Boundary traction
N = dolfin.FacetNormal(mesh)
PN = dolfin.dot(pk1, N)

# Potential energy
Pi = psi * dx  # NOTE: There is no external force potential

# Equilibrium problem
F = dolfin.derivative(Pi, u)

### Model cost and constraints
def A_s_cal(phi, phi0, A_0):
    return A_0 * phi / phi0 * ln(phi) / ln(phi0)
Ejemplo n.º 19
0
 def _I_Cl(self, V, Clo, Cli):
     G_ClL = self._parameters["G_ClL"]
     E_Cl = 26.64 * ln(Cli / Clo)
     return G_ClL * (V - E_Cl)
Ejemplo n.º 20
0
def setup_EC(w_EC, c, V, V0, b, U, U0,
             rho_e, grad_g_c, c_reg, g_c,
             dx, ds, normal,
             dirichlet_bcs_EC, neumann_bcs, boundary_to_mark,
             c_1, u_1, K, veps,
             rho_, rho_1,
             dt,
             enable_NS,
             solutes,
             use_iterative_solvers,
             nonlinear_EC,
             V_lagrange, p_lagrange,
             q_rhs,
             reactions,
             beta,
             **namespace):
    """ Set up electrochemistry subproblem. """
    if enable_NS:
        # Projected velocity
        u_star = u_1 - dt/rho_1*sum([ci_1*grad_g_ci
                                     for ci_1, grad_g_ci
                                     in zip(c_1, grad_g_c)])

    F_c = []
    for ci, ci_1, bi, Ki, grad_g_ci, solute, ci_reg in zip(
            c, c_1, b, K, grad_g_c, solutes, c_reg):
        F_ci = (1./dt*(ci-ci_1)*bi*dx +
                Ki*ci_reg*df.dot(grad_g_ci, df.grad(bi))*dx)
        if enable_NS:
            F_ci += - ci_1*df.dot(u_star, df.grad(bi))*dx
        if solute[0] in q_rhs:
            F_ci += - q_rhs[solute[0]]*bi*dx
        if enable_NS:
            for boundary_name, value in neumann_bcs[solute[0]].iteritems():
                # F_ci += df.dot(u_1, normal)*bi*ci_1*ds(
                #     boundary_to_mark[boundary_name])
                pass
        F_c.append(F_ci)

    for reaction_constant, nu in reactions:
        g_less = []
        g_more = []
        for nui, ci_1, betai in zip(nu, c_1, beta):
            if nui < 0:
                g_less.append(-nui*(df.ln(ci_1)+betai))
            elif nui > 0:
                g_more.append(nui*(df.ln(ci_1)+betai))
        g_less = sum(g_less)
        g_more = sum(g_more)

        C = reaction_constant*(
            df.exp(g_less) - df.exp(g_more))/(g_less - g_more)

        R = C*sum([nui*g_ci for nui, g_ci in zip(nu, g_c)])
        for nui, bi in zip(nu, b):
            if nui != 0:
                F_c.append(nui*R*bi*dx)

    F_V = veps*df.dot(df.grad(V), df.grad(U))*dx
    for boundary_name, sigma_e in neumann_bcs["V"].iteritems():
        F_V += -sigma_e*U*ds(boundary_to_mark[boundary_name])
    if rho_e != 0:
        F_V += -rho_e*U*dx
    if V_lagrange:
        F_V += veps*V0*U*dx + veps*V*U0*dx
    if "V" in q_rhs:
        F_V += q_rhs["V"]*U*dx

    F = sum(F_c) + F_V
    if nonlinear_EC:
        J = df.derivative(F, w_EC)
        problem = df.NonlinearVariationalProblem(F, w_EC, dirichlet_bcs_EC, J)
        solver = df.NonlinearVariationalSolver(problem)
        solver.parameters["newton_solver"]["relative_tolerance"] = 1e-7
        if use_iterative_solvers:
            solver.parameters["newton_solver"]["linear_solver"] = "bicgstab"
            if not V_lagrange:
                solver.parameters["newton_solver"]["preconditioner"] = "hypre_amg"
    else:
        a, L = df.lhs(F), df.rhs(F)
        problem = df.LinearVariationalProblem(a, L, w_EC, dirichlet_bcs_EC)
        solver = df.LinearVariationalSolver(problem)
        if use_iterative_solvers:
            solver.parameters["linear_solver"] = "bicgstab"
            solver.parameters["preconditioner"] = "hypre_amg"

    return solver
Ejemplo n.º 21
0
def alpha(c):
    return c*(df.ln(c)-1)
Ejemplo n.º 22
0
 def P(u):                       # P = dW/dF:
     return mu*(F - inv(F.T)) + lmbda*ln(J)*inv(F.T)
Ejemplo n.º 23
0
    def __init__(self, mesh):

        self.mesh = mesh

        # Write mesh to file (for debugging only)
        # write_mesh(self.mesh, '/tmp/meshfromslicer.vtu')

        # define function space
        element_degree = 1
        quadrature_degree = element_degree + 1
        print("Degree of element: ", element_degree)
        print("Degree of quadrature: ", quadrature_degree)
        self.V = dolfin.VectorFunctionSpace(self.mesh, "Lagrange",
                                            element_degree)

        # Mark boundary subdomains
        zmin = min(self.mesh.coordinates()[:, 2])
        zmax = max(self.mesh.coordinates()[:, 2])
        print("zmin:", zmin)
        print("zmax:", zmax)
        bot = dolfin.CompiledSubDomain("near(x[2], side) && on_boundary",
                                       side=zmin)
        top = dolfin.CompiledSubDomain("near(x[2], side) && on_boundary",
                                       side=zmax)

        # Define Dirichlet boundary (z = 0 or z = 1)
        c = dolfin.Constant((0.0, 0.0, 0.0))
        self.r = dolfin.Expression((
            "scale*(x0 + (x[0] - x0)*cos(theta) - (x[1] - y0)*sin(theta) - x[0])",
            "scale*(y0 + (x[0] - x0)*sin(theta) + (x[1] - y0)*cos(theta) - x[1])",
            "displacement"),
                                   scale=1.0,
                                   x0=0.5,
                                   y0=0.5,
                                   theta=0.0,
                                   displacement=0.0,
                                   degree=2)

        self.bcs = [
            dolfin.DirichletBC(self.V, c, bot),
            dolfin.DirichletBC(self.V, self.r, top)
        ]

        # Define functions
        du = dolfin.TrialFunction(self.V)  # Incremental displacement
        v = dolfin.TestFunction(self.V)  # Test function
        # Displacement from previous iteration
        self.u = dolfin.Function(self.V)
        # Body force per unit volume
        self.B = dolfin.Constant((0.0, 0.0, 0.0))
        # Traction force on the boundary
        self.T = dolfin.Constant((0.0, 0.0, 0.0))

        # Kinematics
        d = len(self.u)
        I = dolfin.Identity(d)  # Identity tensor
        F = I + dolfin.grad(self.u)  # Deformation gradient
        C = F.T * F  # Right Cauchy-Green tensor

        # Invariants of deformation tensors
        Ic = dolfin.tr(C)
        J = dolfin.det(F)

        # Elasticity parameters
        E = 10.0
        nu = 0.3
        mu = dolfin.Constant(E / (2 * (1 + nu)))
        lmbda = dolfin.Constant(E * nu / ((1 + nu) * (1 - 2 * nu)))

        # Stored strain energy density (compressible neo-Hookean model)
        psi = (mu / 2) * (Ic - 3) - mu * dolfin.ln(J) + (lmbda /
                                                         2) * (dolfin.ln(J))**2

        dx = dolfin.Measure("dx",
                            domain=mesh,
                            metadata={'quadrature_degree': quadrature_degree})
        ds = dolfin.Measure("ds",
                            domain=mesh,
                            metadata={'quadrature_degree': quadrature_degree})
        print(dx)
        print(ds)
        Pi = psi*dx - dolfin.dot(self.B, self.u)*dx - \
            dolfin.dot(self.T, self.u)*ds
        self.F = dolfin.derivative(Pi, self.u, v)
        self.J = dolfin.derivative(self.F, self.u, du)
Ejemplo n.º 24
0
def softplus(y1, y2, alpha=1):
    # The softplus function is a differentiable approximation
    # to the ramp function.  Its derivative is the logistic function.
    # Larger alpha makes a sharper transition.
    return y1 + (1. / alpha) * df.ln(1 + df.exp(alpha * (y2 - y1)))
Ejemplo n.º 25
0
def alpha_c(c):
    return df.ln(c)
Ejemplo n.º 26
0
 def _I_K(self, V, n, Ko, Ki):
     G_K = self._parameters["G_K"]
     G_KL = self._parameters["G_KL"]
     E_K = 26.64 * ln(Ko / Ki)
     return G_K * n**4 * (V - E_K) + G_KL * (V - E_K)
Ejemplo n.º 27
0
 def _I_Na(self, V, m, h, Nao, Nai):
     G_Na = self._parameters["G_Na"]
     G_NaL = self._parameters["G_NaL"]
     E_Na = 26.64 * ln(Nao / Nai)
     return G_Na * m**3 * h * (V - E_Na) + G_NaL * (V - E_Na)
    # Lame material parameters
    lm = E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu))
    mu = E / (2.0 + 2.0 * nu)

    if large_deformations:

        I = dolfin.Identity(len(u))
        F = dolfin.variable(I + dolfin.grad(u))  # Deformation gradient
        C = F.T * F  # Right Cauchy-Green deformation tensor

        I1 = dolfin.tr(C)
        det_F = dolfin.det(F)

        # Strain energy density of a Neo-Hookean material
        psi = (mu / 2.0) * (I1 - len(u) - 2.0 * dolfin.ln(det_F)) + (
            lm / 2.0) * dolfin.ln(det_F)**2

        # First Piola-Kirchhoff stress tensor
        pk1 = dolfin.diff(psi, F)

    else:

        I = dolfin.Identity(len(u))
        e = sym(grad(u))

        # Cauchy stress tensor
        s = 2 * mu * e + lm * dolfin.tr(e) * I

        # Strain energy density of a linear-elastic material
        psi = 0.5 * inner(s, e)