示例#1
0
def setup_NS(w_NS, u, p, v, q, p0, q0,
             dx, ds, normal,
             dirichlet_bcs_NS, neumann_bcs, boundary_to_mark,
             u_1, rho_, rho_1, mu_, c_1, grad_g_c_,
             dt, grav,
             enable_EC,
             trial_functions,
             use_iterative_solvers,
             p_lagrange,
             mesh,
             q_rhs,
             density_per_concentration,
             K,
             **namespace):
    """ Set up the Navier-Stokes subproblem. """
    mom_1 = rho_1 * u_1
    if enable_EC and density_per_concentration is not None:
        for drhodci, ci_1, grad_g_ci_, Ki in zip(
                density_per_concentration, c_1, grad_g_c_, K):
            if drhodci > 0.:
                mom_1 += -drhodci*Ki*ci_1*grad_g_ci_

    F = (1./dt * rho_1 * df.dot(u - u_1, v) * dx
         + df.inner(df.nabla_grad(u), df.outer(mom_1, v)) * dx
         + 2*mu_*df.inner(df.sym(df.nabla_grad(u)),
                          df.sym(df.nabla_grad(v))) * dx
         + 0.5*(
             1./dt * (rho_ - rho_1) * df.inner(u, v)
             - df.inner(mom_1, df.nabla_grad(df.dot(u, v)))) * dx
         - p * df.div(v) * dx
         - q * df.div(u) * dx
         - rho_ * df.dot(grav, v) * dx)

    for boundary_name, pressure in neumann_bcs["p"].iteritems():
        F += pressure * df.inner(
            normal, v) * ds(boundary_to_mark[boundary_name])

    if enable_EC:
        F += sum([ci_1*df.dot(grad_g_ci_, v)*dx
                  for ci_1, grad_g_ci_ in zip(c_1, grad_g_c_)])

    if p_lagrange:
        F += (p*q0 + q*p0)*dx

    if "u" in q_rhs:
        F += -df.dot(q_rhs["u"], v)*dx

    a, L = df.lhs(F), df.rhs(F)
    if not use_iterative_solvers:
        problem = df.LinearVariationalProblem(a, L, w_NS, dirichlet_bcs_NS)
        solver = df.LinearVariationalSolver(problem)

    else:
        solver = df.LUSolver("mumps")
        # solver.set_operator(A)
        return solver, a, L, dirichlet_bcs_NS

    return solver
def setup_NSu(w_NSu, u, v, dx, ds, normal, dirichlet_bcs_NSu, neumann_bcs,
              boundary_to_mark, u_, p_, u_1, p_1, rho_, rho_1, mu_, c_1,
              grad_g_c_, dt, grav, enable_EC, trial_functions,
              use_iterative_solvers, mesh, density_per_concentration,
              viscosity_per_concentration, K, **namespace):
    """ Set up the Navier-Stokes velocity subproblem. """
    solvers = dict()

    mom_1 = rho_1 * u_1
    if enable_EC and density_per_concentration is not None:
        for drhodci, ci_1, grad_g_ci_, Ki in zip(density_per_concentration,
                                                 c_1, grad_g_c_, K):
            if drhodci > 0.:
                mom_1 += -drhodci * Ki * ci_1 * grad_g_ci_

    F_predict = (
        1. / dt * rho_1 * df.dot(u - u_1, v) * dx +
        df.inner(df.nabla_grad(u), df.outer(mom_1, v)) * dx + 2 * mu_ *
        df.inner(df.sym(df.nabla_grad(u)), df.sym(df.nabla_grad(v))) * dx +
        0.5 * (1. / dt * (rho_ - rho_1) * df.dot(u, v) -
               df.inner(mom_1, df.grad(df.dot(u, v)))) * dx -
        p_1 * df.div(v) * dx - rho_ * df.dot(grav, v) * dx)

    for boundary_name, pressure in neumann_bcs["p"].iteritems():
        F_predict += pressure * df.inner(normal, v) * ds(
            boundary_to_mark[boundary_name])

    if enable_EC:
        F_predict += sum([
            ci_1 * df.dot(grad_g_ci_, v) * dx
            for ci_1, grad_g_ci_ in zip(c_1, grad_g_c_)
        ])

    a_predict, L_predict = df.lhs(F_predict), df.rhs(F_predict)
    #    if not use_iterative_solvers:
    problem_predict = df.LinearVariationalProblem(a_predict, L_predict, w_NSu,
                                                  dirichlet_bcs_NSu)
    solvers["predict"] = df.LinearVariationalSolver(problem_predict)
    if use_iterative_solvers:
        solvers["predict"].parameters["linear_solver"] = "bicgstab"
        solvers["predict"].parameters["preconditioner"] = "amg"

    F_correct = (rho_ * df.inner(u - u_, v) * dx - dt *
                 (p_ - p_1) * df.div(v) * dx)
    a_correct, L_correct = df.lhs(F_correct), df.rhs(F_correct)
    problem_correct = df.LinearVariationalProblem(a_correct, L_correct, w_NSu,
                                                  dirichlet_bcs_NSu)
    solvers["correct"] = df.LinearVariationalSolver(problem_correct)

    if use_iterative_solvers:
        solvers["correct"].parameters["linear_solver"] = "bicgstab"
        solvers["correct"].parameters["preconditioner"] = "amg"
    #else:
    #    solver = df.LUSolver("mumps")
    #    # solver.set_operator(A)
    #    return solver, a, L, dirichlet_bcs_NS

    return solvers
示例#3
0
def setup_NSu(u, v, u_, p_, bcs_NSu, u_1, p_1, phi_, rho_, rho_1, g_, M_, nu_,
              rho_e_, V_, dt, drho, sigma_bar, eps, dveps, grav, enable_PF,
              enable_EC):
    """ Set up the Navier-Stokes subproblem. """
    # Crank-Nicolson velocity
    # u_CN = 0.5*(u_1 + u)

    F_predict = (
        1. / dt * df.sqrt(rho_) *
        df.dot(df.sqrt(rho_) * u - df.sqrt(rho_1) * u_1, v) * df.dx
        # + rho_*df.inner(df.grad(u), df.outer(u_1, v))*df.dx
        # + 2*nu_*df.inner(df.sym(df.grad(u)), df.grad(v))*df.dx
        # - p_1 * df.div(v)*df.dx
        # + df.div(u)*q*df.dx
        + rho_ * df.dot(df.dot(u_1, df.nabla_grad(u)), v) * df.dx +
        2 * nu_ * df.inner(df.sym(df.grad(u)), df.sym(df.grad(v))) * df.dx -
        p_1 * df.div(v) * df.dx - df.dot(rho_ * grav, v) * df.dx)

    phi_filtered = unit_interval_filter(phi_)
    if enable_PF:
        F_predict += -drho * M_ * df.dot(
            df.dot(df.nabla_grad(g_), df.nabla_grad(u)), v) * df.dx
        F_predict += -sigma_bar * eps * df.inner(
            df.outer(df.grad(phi_filtered), df.grad(phi_filtered)),
            df.grad(v)) * df.dx
    if enable_EC and rho_e_ != 0:
        F_predict += rho_e_ * df.dot(df.grad(V_), v) * df.dx
    if enable_PF and enable_EC:
        F_predict += dveps * df.dot(df.grad(phi_filtered), v) * df.dot(
            df.grad(V_), df.grad(V_)) * df.dx

    # a1, L1 = df.lhs(F_predict), df.rhs(F_predict)

    F_correct = (df.inner(u - u_, v) * df.dx +
                 dt / rho_ * df.inner(df.grad(p_ - p_1), v) * df.dx)
    # a3 = df.dot(u, v)*df.dx
    # L3 = df.dot(u_, v)*df.dx - dt*df.dot(df.grad(p_), v)*df.dx
    # a3, L3 = df.lhs(F_correct), df.rhs(F_correct)

    solver = dict()
    # solver["a1"] = a1
    # solver["L1"] = L1
    solver["Fu"] = F_predict
    solver["Fu_corr"] = F_correct
    # solver["a3"] = a3
    # solver["L3"] = L3
    solver["bcs"] = bcs_NSu
    return solver
示例#4
0
def les_setup(u_, mesh, Smagorinsky, CG1Function, nut_krylov_solver, bcs,
              **NS_namespace):
    """
    Set up for solving Smagorinsky-Lilly LES model.
    """
    DG = FunctionSpace(mesh, "DG", 0)
    CG1 = FunctionSpace(mesh, "CG", 1)

    # Compute cell size and put in delta
    dim = mesh.geometry().dim()
    delta = Function(DG)
    delta.vector().zero()
    delta.vector().set_local(
        assemble(TestFunction(DG) * dx).array()**(1. / dim))
    delta.vector().apply('insert')

    # Set up Smagorinsky form
    Sij = sym(grad(u_))
    magS = sqrt(2 * inner(Sij, Sij))
    nut_form = Smagorinsky['Cs']**2 * delta**2 * magS
    bcs_nut = derived_bcs(CG1, bcs['u0'], u_)
    nut_ = CG1Function(nut_form,
                       mesh,
                       method=nut_krylov_solver,
                       bcs=bcs_nut,
                       bounded=True,
                       name="nut")
    return dict(Sij=Sij, nut_=nut_, delta=delta, bcs_nut=bcs_nut)
示例#5
0
def les_update(nut_, nut_form, A_mass, At, u_, dt, bc_ksgs, bt, ksgs_sol,
               KineticEnergySGS, CG1, ksgs, delta, **NS_namespace):

    p, q = TrialFunction(CG1), TestFunction(CG1)

    Ck = KineticEnergySGS["Ck"]
    Ce = KineticEnergySGS["Ce"]

    Sij = sym(grad(u_))
    assemble(dt * inner(dot(u_, 0.5 * grad(p)), q) * dx + inner(
        (dt * Ce * sqrt(ksgs) / delta) * 0.5 * p, q) * dx +
             inner(dt * Ck * sqrt(ksgs) * delta * grad(0.5 * p), grad(q)) * dx,
             tensor=At)

    assemble(dt * 2 * Ck * delta * sqrt(ksgs) * inner(Sij, grad(u_)) * q * dx,
             tensor=bt)
    bt.axpy(1.0, A_mass * ksgs.vector())
    bt.axpy(-1.0, At * ksgs.vector())
    At.axpy(1.0, A_mass, True)

    # Solve for ksgs
    bc_ksgs.apply(At, bt)
    ksgs_sol.solve(At, ksgs.vector(), bt)
    ksgs.vector().set_local(ksgs.vector().array().clip(min=1e-7))
    ksgs.vector().apply("insert")

    # Update nut_
    nut_()
示例#6
0
def les_update(nut_, nut_form, A_mass, At, u_, dt, bc_ksgs, bt, ksgs_sol,
        KineticEnergySGS, CG1, ksgs, delta, **NS_namespace):

    p, q = TrialFunction(CG1), TestFunction(CG1)

    Ck = KineticEnergySGS["Ck"]
    Ce = KineticEnergySGS["Ce"]

    Sij = sym(grad(u_))
    assemble(dt*inner(dot(u_, 0.5*grad(p)), q)*dx
             + inner((dt*Ce*sqrt(ksgs)/delta)*0.5*p, q)*dx
             + inner(dt*Ck*sqrt(ksgs)*delta*grad(0.5*p), grad(q))*dx, tensor=At)
    
    assemble(dt*2*Ck*delta*sqrt(ksgs)*inner(Sij,grad(u_))*q*dx, tensor=bt)
    bt.axpy(1.0, A_mass*ksgs.vector())
    bt.axpy(-1.0, At*ksgs.vector())
    At.axpy(1.0, A_mass, True)

    # Solve for ksgs
    bc_ksgs.apply(At, bt)
    ksgs_sol.solve(At, ksgs.vector(), bt)
    ksgs.vector().set_local(ksgs.vector().array().clip(min=1e-7))
    ksgs.vector().apply("insert")

    # Update nut_
    nut_()
示例#7
0
文件: Wale.py 项目: ChaliZhg/Oasis
def les_setup(u_, mesh, Wale, bcs, CG1Function, nut_krylov_solver, **NS_namespace):
    """Set up for solving Wale LES model
    """
    DG = FunctionSpace(mesh, "DG", 0)
    CG1 = FunctionSpace(mesh, "CG", 1)
    delta = Function(DG)
    delta.vector().zero()
    delta.vector().axpy(1.0, assemble(TestFunction(DG)*dx))
    Gij = grad(u_)
    Sij = sym(Gij)
    Skk = tr(Sij)
    dim = mesh.geometry().dim()
    Sd = sym(Gij*Gij) - 1./3.*Identity(mesh.geometry().dim())*Skk*Skk 
    nut_form = Wale['Cw']**2 * pow(delta, 2./dim) * pow(inner(Sd, Sd), 1.5) / (Max(pow(inner(Sij, Sij), 2.5) + pow(inner(Sd, Sd), 1.25), 1e-6))
    ff = FacetFunction("size_t", mesh, 0)
    bcs_nut = derived_bcs(CG1, bcs['u0'], u_)
    nut_ = CG1Function(nut_form, mesh, method=nut_krylov_solver, bcs=bcs_nut, name='nut', bounded=True)
    return dict(Sij=Sij, Sd=Sd, Skk=Skk, nut_=nut_, delta=delta, bcs_nut=bcs_nut)
示例#8
0
def neumann_elasticity_data():
    '''
    Return:
        a  bilinear form in the neumann elasticity problem
        L  linear form in therein
        V  function space, where a, L are defined
        bc homog. dirichlet conditions for case where we want pos. def problem
        z  list of orthonormal vectors in the nullspace of A that form basis
           of ker(A)
    '''
    mesh = UnitSquareMesh(40, 40)

    V = VectorFunctionSpace(mesh, 'CG', 1)
    u = TrialFunction(V)
    v = TestFunction(V)

    f = Expression(('sin(pi*x[0])', 'cos(pi*x[1])'))

    epsilon = lambda u: sym(grad(u))

    # Material properties
    E, nu = 10.0, 0.3
    mu, lmbda = Constant(E/(2*(1 + nu))), Constant(E*nu/((1 + nu)*(1 - 2*nu)))

    sigma = lambda u: 2*mu*epsilon(u) + lmbda*tr(epsilon(u))*Identity(2)

    a = inner(sigma(u), epsilon(v))*dx
    L = inner(f, v)*dx  # Zero stress

    bc = DirichletBC(V, Constant((0, 0)), DomainBoundary())

    z0 = interpolate(Constant((1, 0)), V).vector()
    normalize(z0, 'l2')

    z1 = interpolate(Constant((0, 1)), V).vector()
    normalize(z1, 'l2')

    X = mesh.coordinates().reshape((-1, 2))
    c0, c1 = np.sum(X, axis=0)/len(X)
    z2 = interpolate(Expression(('x[1]-c1',
                                 '-(x[0]-c0)'), c0=c0, c1=c1), V).vector()
    normalize(z2, 'l2')

    z = [z0, z1, z2]

    # Check that this is orthonormal basis
    I = np.zeros((3, 3))
    for i, zi in enumerate(z):
        for j, zj in enumerate(z):
            I[i, j] = zi.inner(zj)

    print I
    print la.norm(I-np.eye(3))
    assert la.norm(I-np.eye(3)) < 1E-13

    return a, L, V, bc, z
示例#9
0
def les_setup(u_, mesh, Wale, bcs, CG1Function, nut_krylov_solver, **NS_namespace):
    """Set up for solving Wale LES model
    """
    DG = FunctionSpace(mesh, "DG", 0)
    CG1 = FunctionSpace(mesh, "CG", 1)
    
    # Compute cell size and put in delta
    delta = Function(DG)
    delta.vector().zero()
    delta.vector().axpy(1.0, assemble(TestFunction(DG)*dx))
    
    # Set up Wale form
    Gij = grad(u_)
    Sij = sym(Gij)
    Skk = tr(Sij)
    dim = mesh.geometry().dim()
    Sd = sym(Gij*Gij) - 1./3.*Identity(mesh.geometry().dim())*Skk*Skk 
    nut_form = Wale['Cw']**2 * pow(delta, 2./dim) * pow(inner(Sd, Sd), 1.5) / (Max(pow(inner(Sij, Sij), 2.5) + pow(inner(Sd, Sd), 1.25), 1e-6))
    ff = FacetFunction("size_t", mesh, 0)
    bcs_nut = derived_bcs(CG1, bcs['u0'], u_)
    nut_ = CG1Function(nut_form, mesh, method=nut_krylov_solver, bcs=bcs_nut, name='nut', bounded=True)
    return dict(Sij=Sij, Sd=Sd, Skk=Skk, nut_=nut_, delta=delta, bcs_nut=bcs_nut)
    def eps(self, u):
        e = df.sym(df.grad(u))
        dim = self.mesh.geometric_dimension()
        if dim == 1:
            return df.as_vector([e[0, 0]])

        if dim == 2:
            return df.as_vector([e[0, 0], e[1, 1], 2 * e[0, 1]])

        if dim == 3:
            return df.as_vector([
                e[0, 0], e[1, 1], e[2, 2], 2 * e[1, 2], 2 * e[0, 2],
                2 * e[0, 1]
            ])
示例#11
0
def create_forms(W, rho, nu, g_a, boundary_markers, gamma=0.0):
    v, p = df.TrialFunctions(W)
    v_t, p_t = df.TestFunctions(W)

    a = (
        2.0 * nu * df.inner(df.sym(df.grad(v)), df.grad(v_t)) -
        p * df.div(v_t) - df.div(v) * p_t
        #- nu * df.div(v) * p_t
    ) * df.dx

    L = rho * df.inner(df.Constant((0.0, -g_a)), v_t) * df.dx

    # Grad-div stabilization
    a += df.Constant(gamma) * df.div(v) * df.div(v_t) * df.dx

    return a, L
示例#12
0
    def strain_rate_tensor(self, u):
        r"""Define the symmetric strain-rate tensor

        :param u: The velocity field (2D).
        :return: The strain rate tensor.
        """
        r = dolfin.SpatialCoordinate(self._mesh)[0]
        ur = u[0]
        uz = u[1]
        ur_r = ur.dx(0)
        ur_z = ur.dx(1)
        uz_r = uz.dx(0)
        uz_z = uz.dx(1)
        return dolfin.sym(
            dolfin.as_tensor([[ur_r, 0, 0.5 * (uz_r + ur_z)], [0, ur / r, 0],
                              [0.5 * (uz_r + ur_z), 0, uz_z]]))
示例#13
0
def les_setup(u_, mesh, Smagorinsky, CG1Function, nut_krylov_solver, bcs, **NS_namespace):
    """
    Set up for solving Smagorinsky-Lilly LES model.
    """
    DG = FunctionSpace(mesh, "DG", 0)
    CG1 = FunctionSpace(mesh, "CG", 1)
    dim = mesh.geometry().dim()
    delta = Function(DG)
    delta.vector().zero()
    delta.vector().axpy(1.0, assemble(TestFunction(DG)*dx))
    delta.vector().apply('insert')
    Sij = sym(grad(u_))
    magS = sqrt(2*inner(Sij,Sij))    
    nut_form = Smagorinsky['Cs']**2 * delta**2 * magS
    bcs_nut = derived_bcs(CG1, bcs['u0'], u_)
    nut_ = CG1Function(nut_form, mesh, method=nut_krylov_solver, bcs=bcs_nut, bounded=True, name="nut")
    return dict(Sij=Sij, nut_=nut_, delta=delta, bcs_nut=bcs_nut)    
示例#14
0
def create_forms(W, rho, nu, F, g_a, p_h, boundary_markers):
    v, p = df.TrialFunctions(W)
    v_t, p_t = df.TestFunctions(W)

    a = (
        2.0 * nu * df.inner(df.sym(df.grad(v)), df.grad(v_t)) -
        p * df.div(v_t) - df.div(v) * p_t
        #- nu * df.div(v) * p_t
    ) * df.dx

    L = rho * df.inner(df.Constant((0.0, -g_a)), v_t) * df.dx

    n = df.FacetNormal(W.mesh())
    ds = df.Measure("ds", subdomain_data=boundary_markers)
    L += df.inner(df.Constant((F, 0.0)), v_t) * ds(3)  # driving force
    L -= p_h * df.inner(n, v_t) * (ds(2) + ds(4))  # hydrostatic balance

    return a, L
示例#15
0
def les_setup(u_, mesh, Smagorinsky, CG1Function, nut_krylov_solver, bcs, **NS_namespace):
    """
    Set up for solving Smagorinsky-Lilly LES model.
    """
    DG = FunctionSpace(mesh, "DG", 0)
    CG1 = FunctionSpace(mesh, "CG", 1)

    # Compute cell size and put in delta
    delta = Function(DG)
    delta.vector().zero()
    delta.vector().axpy(1.0, assemble(TestFunction(DG) * dx))
    delta.vector().apply("insert")

    # Set up Smagorinsky form
    Sij = sym(grad(u_))
    magS = sqrt(2 * inner(Sij, Sij))
    nut_form = Smagorinsky["Cs"] ** 2 * delta ** 2 * magS
    bcs_nut = derived_bcs(CG1, bcs["u0"], u_)
    nut_ = CG1Function(nut_form, mesh, method=nut_krylov_solver, bcs=bcs_nut, bounded=True, name="nut")
    return dict(Sij=Sij, nut_=nut_, delta=delta, bcs_nut=bcs_nut)
示例#16
0
    def stress_tensor(self, L, p):
        """
        Return the Cauchy stress tensor for an incompressible Newtonian fluid,
        namely

        .. math::

           \mathbf{T} = -p\mathbf{I} + 2\mu\\text{Sym}(\mathbf{L}),

        where :math:`\mathbf{L} = \\text{grad}(\mathbf{v})`, :math:`\mathbf{I}`
        is the identity tensor, :math:`p` is the hydrostatic pressure, and
        :math:`\mu` is the dynamic viscosity.


        Parameters
        ----------

        L : ufl.differentiation.Grad
            The velocity gradient.
        p : dolfin.Function, ufl.indexed.Indexed
            The hydrostatic pressure.


        Returns
        -------

        T : ufl.algebra.Sum
            The Cauchy stress tensor defined above.


        """

        params = self._parameters
        dim = ufl.domain.find_geometric_dimension(L)
        mu = dlf.Constant(params['mu'], name='mu')

        I = dlf.Identity(dim)
        D = dlf.sym(L)

        return -p * I + dlf.Constant(2.0) * mu * D
示例#17
0
def nn_setup(u_, mesh, ModifiedCross, CG1Function, nu_nn_krylov_solver, bcs,
             **NS_namespace):
    """
    Set up for solving Modified-Cross non-Newtonian model.
    """
    CG1 = FunctionSpace(mesh, "CG", 1)
    mu_inf = ModifiedCross['mu_inf']
    mu_o = ModifiedCross['mu_o']
    rho = ModifiedCross['rho']
    lam = ModifiedCross['lam']
    m_param = ModifiedCross['m_param']
    a_param = ModifiedCross['a_param']
    # Set up Modified Cross form
    Sij = sym(grad(u_))
    SII = sqrt(2 * inner(Sij, Sij))
    nu_nn_form = ((mu_o - mu_inf) / ((1 +
                                      (lam * SII)**m_param)**a_param)) / rho
    #bcs_nu_nn = derived_bcs(CG1, bcs['u0'], u_)
    nunn_ = CG1Function(nu_nn_form,
                        mesh,
                        method=nu_nn_krylov_solver,
                        bounded=True,
                        name="nu_nn")
    return dict(Sij=Sij, nunn_=nunn_, bcs_nu_nn=[])
示例#18
0
    def initialize_with_field(self, u):
        super().initialize_with_field(u)

        I = Identity(len(u))
        eps = sym(grad(u))

        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))

            sig = 2 * mu * eps + lm * tr(eps) * I
            psi = 0.5 * inner(sig, eps)

            self.psi.append(psi)
            self.pk1.append(sig)
            self.pk2.append(sig)
示例#19
0
def les_setup(u_, mesh, assemble_matrix, CG1Function, nut_krylov_solver, bcs, **NS_namespace):
    """
    Set up for solving the Germano Dynamic LES model applying
    Lagrangian Averaging.
    """

    # Create function spaces
    CG1 = FunctionSpace(mesh, "CG", 1)
    p, q = TrialFunction(CG1), TestFunction(CG1)
    dim = mesh.geometry().dim()

    # Define delta and project delta**2 to CG1
    delta = pow(CellVolume(mesh), 1. / dim)
    delta_CG1_sq = project(delta, CG1)
    delta_CG1_sq.vector().set_local(delta_CG1_sq.vector().array()**2)
    delta_CG1_sq.vector().apply("insert")

    # Define nut_
    Sij = sym(grad(u_))
    magS = sqrt(2 * inner(Sij, Sij))
    Cs = Function(CG1)
    nut_form = Cs**2 * delta**2 * magS
    # Create nut_ BCs
    ff = MeshFunction("size_t", mesh, mesh.topology().dim() - 1, 0)
    bcs_nut = []
    for i, bc in enumerate(bcs['u0']):
        bc.apply(u_[0].vector())  # Need to initialize bc
        m = bc.markers()  # Get facet indices of boundary
        ff.array()[m] = i + 1
        bcs_nut.append(DirichletBC(CG1, Constant(0), ff, i + 1))
    nut_ = CG1Function(nut_form, mesh, method=nut_krylov_solver,
                       bcs=bcs_nut, bounded=True, name="nut")

    # Create functions for holding the different velocities
    u_CG1 = as_vector([Function(CG1) for i in range(dim)])
    u_filtered = as_vector([Function(CG1) for i in range(dim)])
    dummy = Function(CG1)
    ll = LagrangeInterpolator()

    # Assemble required filter matrices and functions
    G_under = Function(CG1, assemble(TestFunction(CG1) * dx))
    G_under.vector().set_local(1. / G_under.vector().array())
    G_under.vector().apply("insert")
    G_matr = assemble(inner(p, q) * dx)

    # Set up functions for Lij and Mij
    Lij = [Function(CG1) for i in range(dim * dim)]
    Mij = [Function(CG1) for i in range(dim * dim)]
    # Check if case is 2D or 3D and set up uiuj product pairs and
    # Sij forms, assemble required matrices
    Sijcomps = [Function(CG1) for i in range(dim * dim)]
    Sijfcomps = [Function(CG1) for i in range(dim * dim)]
    # Assemble some required matrices for solving for rate of strain terms
    Sijmats = [assemble_matrix(p.dx(i) * q * dx) for i in range(dim)]
    if dim == 3:
        tensdim = 6
        uiuj_pairs = ((0, 0), (0, 1), (0, 2), (1, 1), (1, 2), (2, 2))
    else:
        tensdim = 3
        uiuj_pairs = ((0, 0), (0, 1), (1, 1))

    # Set up Lagrange functions
    JLM = Function(CG1)
    JLM.vector()[:] += 1E-32
    JMM = Function(CG1)
    JMM.vector()[:] += 1

    return dict(Sij=Sij, nut_form=nut_form, nut_=nut_, delta=delta, bcs_nut=bcs_nut,
                delta_CG1_sq=delta_CG1_sq, CG1=CG1, Cs=Cs, u_CG1=u_CG1,
                u_filtered=u_filtered, ll=ll, Lij=Lij, Mij=Mij, Sijcomps=Sijcomps,
                Sijfcomps=Sijfcomps, Sijmats=Sijmats, JLM=JLM, JMM=JMM, dim=dim,
                tensdim=tensdim, G_matr=G_matr, G_under=G_under, dummy=dummy,
                uiuj_pairs=uiuj_pairs)
def test_unsteady_stokes():
    nx, ny = 15, 15
    k = 1
    nu = Constant(1.0e-0)
    dt = Constant(2.5e-2)
    num_steps = 20
    theta0 = 1.0  # Initial theta value
    theta1 = 0.5  # Theta after 1 step
    theta = Constant(theta0)

    mesh = UnitSquareMesh(nx, ny)

    # The 'unsteady version' of the benchmark in the 2012 paper by Labeur&Wells
    u_exact = Expression(
        (
            "sin(t) * x[0]*x[0]*(1.0 - x[0])*(1.0 - x[0])*(2.0*x[1] \
                           -6.0*x[1]*x[1] + 4.0*x[1]*x[1]*x[1])",
            "-sin(t)* x[1]*x[1]*(1.0 - x[1])*(1.0 - x[1])*(2.0*x[0] \
                           - 6.0*x[0]*x[0] + 4.0*x[0]*x[0]*x[0])",
        ),
        t=0,
        degree=7,
        domain=mesh,
    )
    p_exact = Expression("sin(t) * x[0]*(1.0 - x[0])",
                         t=0,
                         degree=7,
                         domain=mesh)
    du_exact = Expression(
        (
            "cos(t) * x[0]*x[0]*(1.0 - x[0])*(1.0 - x[0])*(2.0*x[1] \
                            - 6.0*x[1]*x[1] + 4.0*x[1]*x[1]*x[1])",
            "-cos(t)* x[1]*x[1]*(1.0 - x[1])*(1.0 - x[1])*(2.0*x[0] \
                            -6.0*x[0]*x[0] + 4.0*x[0]*x[0]*x[0])",
        ),
        t=0,
        degree=7,
        domain=mesh,
    )

    ux_exact = Expression(
        (
            "x[0]*x[0]*(1.0 - x[0])*(1.0 - x[0])*(2.0*x[1] \
                            - 6.0*x[1]*x[1] + 4.0*x[1]*x[1]*x[1])",
            "-x[1]*x[1]*(1.0 - x[1])*(1.0 - x[1])*(2.0*x[0] \
                            - 6.0*x[0]*x[0] + 4.0*x[0]*x[0]*x[0])",
        ),
        degree=7,
        domain=mesh,
    )

    px_exact = Expression("x[0]*(1.0 - x[0])", degree=7, domain=mesh)

    sin_ext = Expression("sin(t)", t=0, degree=7, domain=mesh)

    f = du_exact + sin_ext * div(px_exact * Identity(2) -
                                 2 * sym(grad(ux_exact)))

    Vhigh = VectorFunctionSpace(mesh, "DG", 7)
    Phigh = FunctionSpace(mesh, "DG", 7)

    # New syntax:
    V = VectorElement("DG", mesh.ufl_cell(), k)
    Q = FiniteElement("DG", mesh.ufl_cell(), k - 1)
    Vbar = VectorElement("DGT", mesh.ufl_cell(), k)
    Qbar = FiniteElement("DGT", mesh.ufl_cell(), k)

    mixedL = FunctionSpace(mesh, MixedElement([V, Q]))
    mixedG = FunctionSpace(mesh, MixedElement([Vbar, Qbar]))
    V2 = FunctionSpace(mesh, V)

    Uh = Function(mixedL)
    Uhbar = Function(mixedG)
    U0 = Function(mixedL)
    Uhbar0 = Function(mixedG)
    u0, p0 = split(U0)
    ubar0, pbar0 = split(Uhbar0)
    ustar = Function(V2)

    # Then the boundary conditions
    bc0 = DirichletBC(mixedG.sub(0), Constant((0, 0)), Gamma)
    bc1 = DirichletBC(mixedG.sub(1), Constant(0), Corner, "pointwise")
    bcs = [bc0, bc1]

    alpha = Constant(6 * k * k)
    forms_stokes = FormsStokes(mesh, mixedL, mixedG,
                               alpha).forms_unsteady(ustar, dt, nu, f)
    ssc = StokesStaticCondensation(
        mesh,
        forms_stokes["A_S"],
        forms_stokes["G_S"],
        forms_stokes["G_ST"],
        forms_stokes["B_S"],
        forms_stokes["Q_S"],
        forms_stokes["S_S"],
    )

    t = 0.0
    step = 0
    for step in range(num_steps):
        step += 1
        t += float(dt)
        if comm.Get_rank() == 0:
            print("Step " + str(step) + " Time " + str(t))

        # Set time level in exact solution
        u_exact.t = t
        p_exact.t = t

        du_exact.t = t - (1 - float(theta)) * float(dt)
        sin_ext.t = t - (1 - float(theta)) * float(dt)

        ssc.assemble_global_lhs()
        ssc.assemble_global_rhs()
        for bc in bcs:
            ssc.apply_boundary(bc)

        ssc.solve_problem(Uhbar, Uh, "none", "default")
        assign(U0, Uh)
        assign(ustar, U0.sub(0))
        assign(Uhbar0, Uhbar)
        if step == 1:
            theta.assign(theta1)

        udiv_e = sqrt(assemble(div(Uh.sub(0)) * div(Uh.sub(0)) * dx))

    u_ex_h = interpolate(u_exact, Vhigh)
    p_ex_h = interpolate(p_exact, Phigh)

    u_error = sqrt(assemble(dot(Uh.sub(0) - u_ex_h, Uh.sub(0) - u_ex_h) * dx))
    p_error = sqrt(assemble(dot(Uh.sub(1) - p_ex_h, Uh.sub(1) - p_ex_h) * dx))

    assert udiv_e < 1e-12
    assert u_error < 1.5e-4
    assert p_error < 1e-2
 def strain(self, u):
     """
     Strain tensor: s = .5( u_{i,j} + u_{j,i})
     """
     return dl.sym(dl.grad(u))
示例#23
0
def run_with_params(Tb, mu_value, k_s, path):
    run_time_init = clock()

    mesh = BoxMesh(Point(0.0, 0.0, 0.0), Point(mesh_width, mesh_width, mesh_height), nx, ny, nz)

    pbc = PeriodicBoundary()

    WE = VectorElement('CG', mesh.ufl_cell(), 2)
    SE = FiniteElement('CG', mesh.ufl_cell(), 1)
    WSSS = FunctionSpace(mesh, MixedElement(WE, SE, SE, SE), constrained_domain=pbc)
    # W = FunctionSpace(mesh, WE, constrained_domain=pbc)
    # S = FunctionSpace(mesh, SE, constrained_domain=pbc)
    W = WSSS.sub(0).collapse()
    S = WSSS.sub(1).collapse()

    temperature_vals = [27.0 + 273, Tb + 273, 1300.0 + 273, 1305.0 + 273]
    temp_prof = TemperatureProfile(temperature_vals, element=S.ufl_element())

    mu_a = mu_value  # this was taken from the Blankenbach paper, can change

    Ep = b / temp_prof.delta

    mu_bot = exp(-Ep * (temp_prof.bottom * temp_prof.delta - 1573.0) + cc) * mu_a

    # TODO: verify exponentiation
    Ra = rho_0 * alpha * g * temp_prof.delta * h ** 3 / (kappa_0 * mu_a)
    w0 = rho_0 * alpha * g * temp_prof.delta * h ** 2 / mu_a
    tau = h / w0
    p0 = mu_a * w0 / h

    log(mu_a, mu_bot, Ra, w0, p0)

    slip_vx = 1.6E-09 / w0  # Non-dimensional
    slip_velocity = Constant((slip_vx, 0.0, 0.0))
    zero_slip = Constant((0.0, 0.0, 0.0))

    time_step = 3.0E11 / tau * 2

    dt = Constant(time_step)
    t_end = 3.0E15 / tau / 5.0  # Non-dimensional times

    u = Function(WSSS)

    # Instead of TrialFunctions, we use split(u) for our non-linear problem
    v, p, T, Tf = split(u)
    v_t, p_t, T_t, Tf_t = TestFunctions(WSSS)

    T0 = interpolate(temp_prof, S)

    mu_exp = Expression('exp(-Ep * (T_val * dTemp - 1573.0) + cc * x[2] / mesh_height)',
                       Ep=Ep, dTemp=temp_prof.delta, cc=cc, mesh_height=mesh_height, T_val=T0,
                       element=S.ufl_element())

    Tf0 = interpolate(temp_prof, S)

    mu = Function(S)
    v0 = Function(W)

    v_theta = (1.0 - theta) * v0 + theta * v

    T_theta = (1.0 - theta) * T0 + theta * T

    Tf_theta = (1.0 - theta) * Tf0 + theta * Tf

    # TODO: Verify forms

    r_v = (inner(sym(grad(v_t)), 2.0 * mu * sym(grad(v)))
           - div(v_t) * p
           - T * v_t[2]) * dx

    r_p = p_t * div(v) * dx

    heat_transfer = Constant(k_s) * (Tf_theta - T_theta) * dt

    r_T = (T_t * ((T - T0) + dt * inner(v_theta, grad(T_theta)))  # TODO: Inner vs dot
           + (dt / Ra) * inner(grad(T_t), grad(T_theta))
           - T_t * heat_transfer) * dx

    v_melt = Function(W)
    z_hat = Constant((0.0, 0.0, 1.0))

    # TODO: inner -> dot, take out Tf_t
    r_Tf = (Tf_t * ((Tf - Tf0) + dt * inner(v_melt, grad(Tf_theta)))
            + Tf_t * heat_transfer) * dx

    r = r_v + r_p + r_T + r_Tf

    bcv0 = DirichletBC(WSSS.sub(0), zero_slip, top)
    bcv1 = DirichletBC(WSSS.sub(0), slip_velocity, bottom)
    bcv2 = DirichletBC(WSSS.sub(0).sub(1), Constant(0.0), back)
    bcv3 = DirichletBC(WSSS.sub(0).sub(1), Constant(0.0), front)

    bcp0 = DirichletBC(WSSS.sub(1), Constant(0.0), bottom)
    bct0 = DirichletBC(WSSS.sub(2), Constant(temp_prof.surface), top)
    bct1 = DirichletBC(WSSS.sub(2), Constant(temp_prof.bottom), bottom)
    bctf1 = DirichletBC(WSSS.sub(3), Constant(temp_prof.bottom), bottom)

    bcs = [bcv0, bcv1, bcv2, bcv3, bcp0, bct0, bct1, bctf1]

    t = 0
    count = 0
    files = DefaultDictByKey(partial(create_xdmf, path))

    while t < t_end:
        mu.interpolate(mu_exp)
        rhosolid = rho_0 * (1.0 - alpha * (T0 * temp_prof.delta - 1573.0))
        deltarho = rhosolid - rho_melt
        # TODO: project (accuracy) vs interpolate
        assign(v_melt, project(v0 - darcy * (grad(p) * p0 / h - deltarho * z_hat * g) / w0, W))
        # TODO: Written out one step later?
        # v_melt.assign(v0 - darcy * (grad(p) * p0 / h - deltarho * yvec * g) / w0)
        # TODO: use nP after to avoid projection?

        solve(r == 0, u, bcs)
        nV, nP, nT, nTf = u.split()  # TODO: write with Tf, ... etc

        if count % output_every == 0:
            time_left(count, t_end / time_step, run_time_init)  # TODO: timestep vs dt

            # TODO: Make sure all writes are to the same function for each time step
            files['T_fluid'].write(nTf, t)
            files['p'].write(nP, t)
            files['v_solid'].write(nV, t)
            files['T_solid'].write(nT, t)
            files['mu'].write(mu, t)
            files['v_melt'].write(v_melt, t)
            files['gradp'].write(project(grad(nP), W), t)
            files['rho'].write(project(rhosolid, S), t)
            files['Tf_grad'].write(project(grad(Tf), W), t)
            files['advect'].write(project(dt * dot(v_melt, grad(nTf))), t)
            files['ht'].write(project(heat_transfer, S), t)

        assign(T0, nT)
        assign(v0, nV)
        assign(Tf0, nTf)

        t += time_step
        count += 1

    log('Case mu={}, Tb={}, k={} complete. Run time = {:.2f} minutes'.format(mu_a, Tb, k_s, (clock() - run_time_init) / 60.0))
示例#24
0
def epsilon(u):
    return df.sym(df.nabla_grad(u))
def test_steady_stokes(k):
    # Polynomial order and mesh resolution
    nx_list = [4, 8, 16]

    nu = Constant(1)

    if comm.Get_rank() == 0:
        print('{:=^72}'.format('Computing for polynomial order ' + str(k)))

    # Error listst
    error_u, error_p, error_div = [], [], []

    for nx in nx_list:
        if comm.Get_rank() == 0:
            print('# Resolution ' + str(nx))

        mesh = UnitSquareMesh(nx, nx)

        # Get forcing from exact solutions
        u_exact, p_exact = exact_solution(mesh)
        f = div(p_exact * Identity(2) - 2 * nu * sym(grad(u_exact)))

        # Define FunctionSpaces and functions
        V = VectorElement("DG", mesh.ufl_cell(), k)
        Q = FiniteElement("DG", mesh.ufl_cell(), k - 1)
        Vbar = VectorElement("DGT", mesh.ufl_cell(), k)
        Qbar = FiniteElement("DGT", mesh.ufl_cell(), k)

        mixedL = FunctionSpace(mesh, MixedElement([V, Q]))
        mixedG = FunctionSpace(mesh, MixedElement([Vbar, Qbar]))

        Uh = Function(mixedL)
        Uhbar = Function(mixedG)

        # Set forms
        alpha = Constant(6 * k * k)
        forms_stokes = FormsStokes(mesh, mixedL, mixedG,
                                   alpha).forms_steady(nu, f)

        # No-slip boundary conditions, set pressure in one of the corners
        bc0 = DirichletBC(mixedG.sub(0), Constant((0, 0)), Gamma)
        bc1 = DirichletBC(mixedG.sub(1), Constant(0), Corner, "pointwise")
        bcs = [bc0, bc1]

        # Initialize static condensation class
        ssc = StokesStaticCondensation(mesh, forms_stokes['A_S'],
                                       forms_stokes['G_S'],
                                       forms_stokes['B_S'],
                                       forms_stokes['Q_S'],
                                       forms_stokes['S_S'], bcs)

        # Assemble global system and incorporates bcs
        ssc.assemble_global_system(True)
        # Solve using mumps
        ssc.solve_problem(Uhbar, Uh, "mumps", "default")

        # Compute velocity/pressure/local div error
        uh, ph = Uh.split()
        e_u = np.sqrt(np.abs(assemble(dot(uh - u_exact, uh - u_exact) * dx)))
        e_p = np.sqrt(np.abs(assemble((ph - p_exact) * (ph - p_exact) * dx)))
        e_d = np.sqrt(np.abs(assemble(div(uh) * div(uh) * dx)))

        if comm.rank == 0:
            error_u.append(e_u)
            error_p.append(e_p)
            error_div.append(e_d)
            print('Error in velocity ' + str(error_u[-1]))
            print('Error in pressure ' + str(error_p[-1]))
            print('Local mass error ' + str(error_div[-1]))

    if comm.rank == 0:
        iterator_list = [1. / float(nx) for nx in nx_list]
        conv_u = compute_convergence(iterator_list, error_u)
        conv_p = compute_convergence(iterator_list, error_p)

        assert any(conv > k + 0.75 for conv in conv_u)
        assert any(conv > (k - 1) + 0.75 for conv in conv_p)
def RunJob(Tb, mu_value, path):
    runtimeInit = clock()

    tfile = File(path + '/t6t.pvd')
    mufile = File(path + "/mu.pvd")
    ufile = File(path + '/velocity.pvd')
    gradpfile = File(path + '/gradp.pvd')
    pfile = File(path + '/pstar.pvd')
    parameters = open(path + '/parameters', 'w', 0)
    vmeltfile = File(path + '/vmelt.pvd')
    rhofile = File(path + '/rhosolid.pvd')

    for name in dir():
        ev = str(eval(name))
        if name[0] != '_' and ev[0] != '<':
            parameters.write(name + ' = ' + ev + '\n')

    temp_values = [27. + 273, Tb + 273, 1300. + 273, 1305. + 273]
    dTemp = temp_values[3] - temp_values[0]
    temp_values = [x / dTemp for x in temp_values]  # non dimensionalising temp

    mu_a = mu_value  # this was taken from the blankenbach paper, can change..
    
    Ep = b / dTemp

    mu_bot = exp(-Ep * (temp_values[3] * dTemp - 1573) + cc) * mu_a

    Ra = rho_0 * alpha * g * dTemp * h**3 / (kappa_0 * mu_a)
    w0 = rho_0 * alpha * g * dTemp * h**2 / mu_a
    tau = h / w0
    p0 = mu_a * w0 / h

    print(mu_a, mu_bot, Ra, w0, p0)

    vslipx = 1.6e-09 / w0
    vslip = Constant((vslipx, 0.0))  # nondimensional
    noslip = Constant((0.0, 0.0))

    dt = 3.E11 / tau
    tEnd = 3.E13 / tau  # non-dimensionalising times

    class PeriodicBoundary(SubDomain):
        def inside(self, x, on_boundary):
            return left(x, on_boundary)

        def map(self, x, y):
            y[0] = x[0] - MeshWidth
            y[1] = x[1]

    pbc = PeriodicBoundary()

    class TempExp(Expression):
        def eval(self, value, x):
            if x[1] >= LAB(x):
                value[0] = temp_values[0] + (temp_values[1] - temp_values[0]) * (MeshHeight - x[1]) / (MeshHeight - LAB(x))
            else:
                value[0] = temp_values[3] - (temp_values[3] - temp_values[2]) * (x[1]) / (LAB(x))

    class FluidTemp(Expression):
        def eval(self, value, x):
            if value[0] < 1295:
                value[0] = 1295

    mesh = RectangleMesh(Point(0.0, 0.0), Point(MeshWidth, MeshHeight), nx, ny)

    Svel = VectorFunctionSpace(mesh, 'CG', 2, constrained_domain=pbc)
    Spre = FunctionSpace(mesh, 'CG', 1, constrained_domain=pbc)
    Stemp = FunctionSpace(mesh, 'CG', 1, constrained_domain=pbc)
    Smu = FunctionSpace(mesh, 'CG', 1, constrained_domain=pbc)
    Sgradp = VectorFunctionSpace(mesh, 'CG', 2, constrained_domain=pbc)
    Srho = FunctionSpace(mesh, 'CG', 1, constrained_domain=pbc)
    S0 = MixedFunctionSpace([Svel, Spre, Stemp])

    u = Function(S0)
    v, p, T = split(u)
    v_t, p_t, T_t = TestFunctions(S0)

    T0 = interpolate(TempExp(), Stemp)

    muExp = Expression('exp(-Ep * (T_val * dTemp - 1573) + cc * x[2] / meshHeight)', Smu.ufl_element(),
                        Ep=Ep, dTemp=dTemp, cc=cc, meshHeight=MeshHeight, T_val=T0)

    mu = interpolate(muExp, Smu)

    rhosolid = Function(Srho)
    deltarho = Function(Srho)

    v0 = Function(Svel)
    vmelt = Function(Svel)

    v_theta = (1. - theta)*v0 + theta*v

    T_theta = (1. - theta)*T + theta*T0

    r_v = (inner(sym(grad(v_t)), 2.*mu*sym(grad(v))) \
        - div(v_t)*p \
        - T*v_t[1] )*dx

    r_p = p_t*div(v)*dx

    r_T = (T_t*((T - T0) \
        + dt*inner(v_theta, grad(T_theta))) \
        + (dt/Ra)*inner(grad(T_t), grad(T_theta)) )*dx
#           + k_s*(Tf-T_theta)*dt

    Tf = T0.interpolate(FluidTemp())
    # Tf = T0.interpolate(Expression('value[0] >= 1295.0 ? value[0] : 1295.0'))

    # Tf.interpolate(Expression('value[0] >= 1295 ? value[0] : 1295'))
    # project(Expression('value[0] >= 1295 ? value[0] : 1295'), Tf)
# Alex, a question for you:
# can you see if there is a way to set Tf = T in regions where T >=1295 celsius
#
# 1295 celsius is my arbitrary choice for the LAB isotherm.  In regions
# where T < 1295 C, set Tf to be some constant for now, such as 1295 C.
# Once we do this, then we can add in a term like that last line above where
# it will only be non-zero when the solid temperature, T, is cooler than 1295
# can you do this? After this is done, we will then worry about a calculation
# where we solve for Tf as a function of time in the regions cooler than 1295 C
# Makes sense?  If not, we can skype soon -- email me with questions
# 3/19/16
    r = r_v + r_p + r_T

    bcv0 = DirichletBC(S0.sub(0), noslip, top)
    bcv1 = DirichletBC(S0.sub(0), vslip, bottom)
    bcp0 = DirichletBC(S0.sub(1), Constant(0.0), bottom)
    bct0 = DirichletBC(S0.sub(2), Constant(temp_values[0]), top)
    bct1 = DirichletBC(S0.sub(2), Constant(temp_values[3]), bottom)

    bcs = [bcv0, bcv1, bcp0, bct0, bct1]

    t = 0
    count = 0
    while (t < tEnd):
        solve(r == 0, u, bcs)
        t += dt
        nV, nP, nT = u.split()
        gp = grad(nP)
        rhosolid = rho_0 * (1 - alpha * (nT * dTemp - 1573))
        deltarho = rhosolid - rhomelt
        yvec = Constant((0.0, 1.0))
        vmelt = nV * w0 - darcy * (gp * p0 / h - deltarho * yvec * g)
        if (count % 100 == 0):
            pfile << nP
            ufile << nV
            tfile << nT
            mufile << mu
            gradpfile << project(grad(nP), Sgradp)
            mufile << project(mu * mu_a, Smu)
            rhofile << project(rhosolid, Srho)
            vmeltfile << project(vmelt, Svel)
        count += 1
        assign(T0, nT)
        assign(v0, nV)
        mu.interpolate(muExp)

    print('Case mu=%g, Tb=%g complete.' % (mu_a, Tb), ' Run time =', clock() - runtimeInit, 's')
示例#27
0
文件: basic.py 项目: mstiegl/BERNAISE
def setup_NS(w_NS, u, p, v, q, p0, q0, dx, ds, normal, dirichlet_bcs,
             neumann_bcs, boundary_to_mark, u_1, phi_, rho_, rho_1, g_, M_,
             mu_, rho_e_, c_, V_, c_1, V_1, dbeta, solutes, per_tau, drho,
             sigma_bar, eps, dveps, grav, fric, u_comoving, enable_PF,
             enable_EC, use_iterative_solvers, use_pressure_stabilization,
             p_lagrange, q_rhs):
    """ Set up the Navier-Stokes subproblem. """
    # F = (
    #     per_tau * rho_ * df.dot(u - u_1, v)*dx
    #     + rho_*df.inner(df.grad(u), df.outer(u_1, v))*dx
    #     + 2*mu_*df.inner(df.sym(df.grad(u)), df.grad(v))*dx
    #     - p * df.div(v)*dx
    #     + df.div(u)*q*dx
    #     - df.dot(rho_*grav, v)*dx
    # )
    mom_1 = rho_1 * (u_1 + u_comoving)
    if enable_PF:
        mom_1 += -M_ * drho * df.nabla_grad(g_)

    F = (per_tau * rho_1 * df.dot(u - u_1, v) * dx +
         fric * mu_ * df.dot(u + u_comoving, v) * dx + 2 * mu_ *
         df.inner(df.sym(df.nabla_grad(u)), df.sym(df.nabla_grad(v))) * dx -
         p * df.div(v) * dx + q * df.div(u) * dx +
         df.inner(df.nabla_grad(u), df.outer(mom_1, v)) * dx + 0.5 *
         (per_tau * (rho_ - rho_1) * df.dot(u, v) -
          df.dot(mom_1, df.nabla_grad(df.dot(u, v)))) * dx -
         rho_ * df.dot(grav, v) * dx -
         mu_ * df.dot(df.nabla_grad(u) * normal, v) * df.ds)
    for boundary_name, slip_length in neumann_bcs["u"].items():
        F += 1./slip_length * \
             df.dot(u, v) * ds(boundary_to_mark[boundary_name])

    for boundary_name, pressure in neumann_bcs["p"].items():
        F += pressure * df.dot(normal, v) * ds(boundary_to_mark[boundary_name])
    #          - 2*mu_*df.dot(df.dot(df.sym(df.nabla_grad(u)), v),
    #                         normal)) * ds(boundary_to_mark[boundary_name])

    if enable_PF:
        F += phi_ * df.dot(df.nabla_grad(g_), v) * dx

    if enable_EC:
        for ci_, ci_1, dbetai, solute in zip(c_, c_1, dbeta, solutes):
            zi = solute[1]
            F += df.dot(df.grad(ci_), v)*dx \
                + zi*ci_1*df.dot(df.grad(V_), v)*dx
            if enable_PF:
                F += ci_ * dbetai * df.dot(df.grad(phi_), v) * dx

    if p_lagrange:
        F += (p * q0 + q * p0) * dx

    if "u" in q_rhs:
        F += -df.dot(q_rhs["u"], v) * dx

    a, L = df.lhs(F), df.rhs(F)

    problem = df.LinearVariationalProblem(a, L, w_NS, dirichlet_bcs)
    solver = df.LinearVariationalSolver(problem)

    if use_iterative_solvers and use_pressure_stabilization:
        solver.parameters["linear_solver"] = "gmres"
        #solver.parameters["preconditioner"] = "jacobi"
        #solver.parameters["preconditioner"] = "ilu"

    return solver
示例#28
0
def RunJob(Tb, mu_value, path):
    runtimeInit = clock()

    tfile = File(path + '/t6t.pvd')
    mufile = File(path + "/mu.pvd")
    ufile = File(path + '/velocity.pvd')
    gradpfile = File(path + '/gradp.pvd')
    pfile = File(path + '/pstar.pvd')
    parameters = open(path + '/parameters', 'w', 0)
    vmeltfile = File(path + '/vmelt.pvd')
    rhofile = File(path + '/rhosolid.pvd')

    for name in dir():
        ev = str(eval(name))
        if name[0] != '_' and ev[0] != '<':
            parameters.write(name + ' = ' + ev + '\n')

    temp_values = [27. + 273, Tb + 273, 1300. + 273, 1305. + 273]
    dTemp = temp_values[3] - temp_values[0]
    temp_values = [x / dTemp for x in temp_values]  # non dimensionalising temp

    mu_a = mu_value  # this was taken from the blankenbach paper, can change..

    Ep = b / dTemp

    mu_bot = exp(-Ep * (temp_values[3] * dTemp - 1573) + cc) * mu_a

    Ra = rho_0 * alpha * g * dTemp * h**3 / (kappa_0 * mu_a)
    w0 = rho_0 * alpha * g * dTemp * h**2 / mu_a
    tau = h / w0
    p0 = mu_a * w0 / h

    print(mu_a, mu_bot, Ra, w0, p0)

    vslipx = 1.6e-09 / w0
    vslip = Constant((vslipx, 0.0))  # nondimensional
    noslip = Constant((0.0, 0.0))

    dt = 3.E11 / tau
    tEnd = 3.E13 / tau  # non-dimensionalising times

    class PeriodicBoundary(SubDomain):
        def inside(self, x, on_boundary):
            return left(x, on_boundary)

        def map(self, x, y):
            y[0] = x[0] - MeshWidth
            y[1] = x[1]

    pbc = PeriodicBoundary()

    class TempExp(Expression):
        def eval(self, value, x):
            if x[1] >= LAB(x):
                value[0] = temp_values[0] + (temp_values[1] - temp_values[0]
                                             ) * (MeshHeight -
                                                  x[1]) / (MeshHeight - LAB(x))
            else:
                value[0] = temp_values[3] - (
                    temp_values[3] - temp_values[2]) * (x[1]) / (LAB(x))

    class FluidTemp(Expression):
        def eval(self, value, x):
            if value[0] < 1295:
                value[0] = 1295

    mesh = RectangleMesh(Point(0.0, 0.0), Point(MeshWidth, MeshHeight), nx, ny)

    Svel = VectorFunctionSpace(mesh, 'CG', 2, constrained_domain=pbc)
    Spre = FunctionSpace(mesh, 'CG', 1, constrained_domain=pbc)
    Stemp = FunctionSpace(mesh, 'CG', 1, constrained_domain=pbc)
    Smu = FunctionSpace(mesh, 'CG', 1, constrained_domain=pbc)
    Sgradp = VectorFunctionSpace(mesh, 'CG', 2, constrained_domain=pbc)
    Srho = FunctionSpace(mesh, 'CG', 1, constrained_domain=pbc)
    S0 = MixedFunctionSpace([Svel, Spre, Stemp])

    u = Function(S0)
    v, p, T = split(u)
    v_t, p_t, T_t = TestFunctions(S0)

    T0 = interpolate(TempExp(), Stemp)

    muExp = Expression(
        'exp(-Ep * (T_val * dTemp - 1573) + cc * x[2] / meshHeight)',
        Smu.ufl_element(),
        Ep=Ep,
        dTemp=dTemp,
        cc=cc,
        meshHeight=MeshHeight,
        T_val=T0)

    mu = interpolate(muExp, Smu)

    rhosolid = Function(Srho)
    deltarho = Function(Srho)

    v0 = Function(Svel)
    vmelt = Function(Svel)

    v_theta = (1. - theta) * v0 + theta * v

    T_theta = (1. - theta) * T + theta * T0

    r_v = (inner(sym(grad(v_t)), 2.*mu*sym(grad(v))) \
        - div(v_t)*p \
        - T*v_t[1] )*dx

    r_p = p_t * div(v) * dx

    r_T = (T_t*((T - T0) \
        + dt*inner(v_theta, grad(T_theta))) \
        + (dt/Ra)*inner(grad(T_t), grad(T_theta)) )*dx
    #           + k_s*(Tf-T_theta)*dt

    Tf = T0.interpolate(FluidTemp())
    # Tf = T0.interpolate(Expression('value[0] >= 1295.0 ? value[0] : 1295.0'))

    # Tf.interpolate(Expression('value[0] >= 1295 ? value[0] : 1295'))
    # project(Expression('value[0] >= 1295 ? value[0] : 1295'), Tf)
    # Alex, a question for you:
    # can you see if there is a way to set Tf = T in regions where T >=1295 celsius
    #
    # 1295 celsius is my arbitrary choice for the LAB isotherm.  In regions
    # where T < 1295 C, set Tf to be some constant for now, such as 1295 C.
    # Once we do this, then we can add in a term like that last line above where
    # it will only be non-zero when the solid temperature, T, is cooler than 1295
    # can you do this? After this is done, we will then worry about a calculation
    # where we solve for Tf as a function of time in the regions cooler than 1295 C
    # Makes sense?  If not, we can skype soon -- email me with questions
    # 3/19/16
    r = r_v + r_p + r_T

    bcv0 = DirichletBC(S0.sub(0), noslip, top)
    bcv1 = DirichletBC(S0.sub(0), vslip, bottom)
    bcp0 = DirichletBC(S0.sub(1), Constant(0.0), bottom)
    bct0 = DirichletBC(S0.sub(2), Constant(temp_values[0]), top)
    bct1 = DirichletBC(S0.sub(2), Constant(temp_values[3]), bottom)

    bcs = [bcv0, bcv1, bcp0, bct0, bct1]

    t = 0
    count = 0
    while (t < tEnd):
        solve(r == 0, u, bcs)
        t += dt
        nV, nP, nT = u.split()
        gp = grad(nP)
        rhosolid = rho_0 * (1 - alpha * (nT * dTemp - 1573))
        deltarho = rhosolid - rhomelt
        yvec = Constant((0.0, 1.0))
        vmelt = nV * w0 - darcy * (gp * p0 / h - deltarho * yvec * g)
        if (count % 100 == 0):
            pfile << nP
            ufile << nV
            tfile << nT
            mufile << mu
            gradpfile << project(grad(nP), Sgradp)
            mufile << project(mu * mu_a, Smu)
            rhofile << project(rhosolid, Srho)
            vmeltfile << project(vmelt, Svel)
        count += 1
        assign(T0, nT)
        assign(v0, nV)
        mu.interpolate(muExp)

    print('Case mu=%g, Tb=%g complete.' % (mu_a, Tb), ' Run time =',
          clock() - runtimeInit, 's')
示例#29
0
def strain_displacement(u):
    return dolfin.sym(dolfin.grad(u))
示例#30
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
示例#31
0
 def differential_op(self, u):
     return sym(nabla_grad(u))
示例#32
0
## Next make a function space
V = d.VectorFunctionSpace(mesh, 'Lagrange', 1)

# Create a test function and a trial function, and a source term:
u = d.TrialFunction(V)
w = d.TestFunction(V)
b = d.Constant((1.0,0.,0.))

# Elasticity parameters:
E, nu = 10., 0.3
mu, lambda_param = E / (2. * (1.+nu)), E * nu / ((1. + nu) * (1.-2. * nu))

# Stress tensor:
# + usually of form \sigma_{ij} = \lambda e_{kk}\delta_{ij} + 2\mu e_{ij},
# + or                          = \lambda Tr(e_{ij})I + 2\mu e_{ij}, for e_{ij} the strain tensor.
sigma = lambda_param*d.tr(d.grad(u)) * d.Identity(w.cell().d) + 2 * mu * d.sym(d.grad(u))

# Governing balance equation:
F = d.inner(sigma, d.grad(w)) * d.dx - d.dot(b,w)*d.dx

# Extract the bi- and linear forms from F:
a = d.lhs(F)
L = d.rhs(F)

# Dirichlet BC on entire boundary:
c = d.Constant((0.,0.,0.))
bc = d.DirichletBC(V, c, d.DomainBoundary())

## Testing some new boundary definitions:
def bzo_boundary(r_vec, on_boundary):
示例#33
0
def setup_NSu(w_NSu, u, v, dx, ds, normal, dirichlet_bcs_NSu, neumann_bcs,
              boundary_to_mark, u_, u_1, p_, p_1, phi_, phi_1, rho_, rho_1, g_,
              g_1, c_, c_1, M_, M_1, mu_, mu_1, rho_e_, rho_e_1, V_, dt, drho,
              sigma_bar, eps, dveps, grav, dbeta, z, enable_PF, enable_EC,
              use_iterative_solvers, **namespace):
    """ Set up the Navier-Stokes velocity subproblem. """
    mom_1 = rho_1 * u_1
    if enable_PF:
        mom_1 += -drho * M_1 * df.grad(g_1)

    F_predict = (
        1. / dt * rho_1 * df.dot(u - u_1, v) * dx +
        df.inner(df.nabla_grad(u), df.outer(mom_1, v)) * dx + 2 * mu_ *
        df.inner(df.sym(df.nabla_grad(u)), df.sym(df.nabla_grad(v))) * dx -
        p_1 * df.div(v) * dx - rho_ * df.dot(grav, v) * dx + 0.5 *
        (1. / dt *
         (rho_ - rho_1) - df.inner(mom_1, df.grad(df.dot(u, v)))) * dx)
    if enable_PF:
        F_predict += phi_1 * df.dot(df.grad(g_), v) * dx

    for boundary_name, pressure in neumann_bcs["p"].items():
        F_predict += pressure * df.inner(normal, v) * ds(
            boundary_to_mark[boundary_name])

    if enable_EC:
        for ci_, ci_1_ in zip(c_, c_1):
            # F_predict += df.dot(df.nabla_grad(ci_), v) * dx
            pass

    #if enable_EC and rho_e_ != 0:
    #    F += rho_e_1 * df.dot(df.nabla_grad(V_), v) * dx
    #if enable_PF and enable_EC:
    #    # Not clear how to discretize this term!
    #    # F += dveps * df.dot(df.grad(phi_), v)*df.dot(df.grad(V_),
    #    #                                              df.grad(V_))*dx
    #    F_c = []
    #    for ci_, ci_1, zi, dbetai in zip(c_, c_1, z, dbeta):
    #        F_ci = ci_1*dbetai*df.dot(df.grad(phi_), v)*dx
    #        F_c.append(F_ci)
    #    F += sum(F_c)

    solvers = dict()

    a_predict, L_predict = df.lhs(F_predict), df.rhs(F_predict)

    problem_predict = df.LinearVariationalProblem(a_predict, L_predict, w_NSu,
                                                  dirichlet_bcs_NSu)
    solvers["predict"] = df.LinearVariationalSolver(problem_predict)

    if use_iterative_solvers:
        solvers["predict"].parameters["linear_solver"] = "bicgstab"
        solvers["predict"].parameters["preconditioner"] = "jacobi"  # "amg"

    F_correct = (rho_ * df.inner(u - u_, v) * dx - dt *
                 (p_ - p_1) * df.div(v) * dx)
    a_correct, L_correct = df.lhs(F_correct), df.rhs(F_correct)
    problem_correct = df.LinearVariationalProblem(a_correct, L_correct, w_NSu,
                                                  dirichlet_bcs_NSu)
    solvers["correct"] = df.LinearVariationalSolver(problem_correct)

    if use_iterative_solvers:
        solvers["correct"].parameters["linear_solver"] = "cg"  # "bicgstab"
        solvers["correct"].parameters["preconditioner"] = "jacobi"  # "amg"

    return solvers
示例#34
0
 def strain(v):
     return dl.sym(dl.nabla_grad(v))
示例#35
0
def epsilon(u):
    # Define symmetric gradient
    return sym(nabla_grad(u))
示例#36
0
def setup_NSPFEC(w_NSPFEC, w_1NSPFEC,
                 dirichlet_bcs_NSPFEC,
                 neumann_bcs,
                 boundary_to_mark,
                 dx, ds, normal,
                 v, q, q0, psi, h, b, U,
                 u_, p_, p0_, phi_, g_, c_, V_,
                 u_1, p_1, p0_1, phi_1, g_1, c_1, V_1,
                 M_, nu_, veps_, rho_, K_, beta_, rho_e_,
                 dbeta, dveps, drho,
                 per_tau, sigma_bar, eps, grav, z,
                 solutes,
                 enable_NS, enable_PF, enable_EC,
                 use_iterative_solvers,
                 p_lagrange,
                 q_rhs):
    """ The full problem of electrohydrodynamics in two phases.
    Note that it is possible to turn off the different parts at will.
    """
    # Setup of the Navier-Stokes part of F
    mom_ = rho_*u_
    if enable_PF:
        mom_ += -M_*drho * df.nabla_grad(g_)
    
    F = []
    if enable_NS:
        F_NS = (per_tau * rho_ * df.dot(u_ - u_1, v) * dx
                + df.inner(df.nabla_grad(u_), df.outer(mom_, v)) * dx
                + 2*nu_*df.inner(df.sym(df.nabla_grad(u_)),
                                 df.sym(df.nabla_grad(v))) * dx
                - p_ * df.div(v) * dx
                - df.div(u_) * q * dx
                - df.dot(rho_ * grav, v) * dx)
        # if enable_PF:
        #     F_NS += - sigma_bar*eps*df.inner(
        #         df.outer(df.grad(phi_),
        #                  df.grad(phi_)), df.grad(v)) * dx
        # if enable_EC and rho_e_ != 0:
        #     F_NS += rho_e_*df.dot(df.grad(V_), v) * dx
        # if enable_PF and enable_EC:
        #     F_NS += dveps*df.dot(
        #         df.grad(phi_), v)*df.dot(df.grad(V_),
        #                                  df.grad(V_)) * dx

        if enable_PF:
            F_NS += phi_*df.dot(df.grad(g_), v) * dx

        if enable_EC:
            for ci_, dbetai, solute in zip(c_, dbeta, solutes):
                zi = solute[1]
                F_NS += df.dot(df.grad(ci_), v) * dx \
                        + ci_*dbetai*df.dot(df.grad(phi_), v) * dx \
                        + zi*ci_*df.dot(df.grad(V_), v) * dx

        # Slip boundary condition
        for boundary_name, slip_length in neumann_bcs["u"].items():
            F_NS += 1./slip_length * \
                    df.dot(u_, v) * ds(boundary_to_mark[boundary_name])

        # Pressure boundary condition
        for boundary_name, pressure in neumann_bcs["p"].items():
            F_NS += pressure * df.inner(
                normal, v) * ds(boundary_to_mark[boundary_name])

        # Lagrange pressure
        if p_lagrange:
            F_NS += (p_*q0 + q*p0_)*dx

        # RHS source terms
        if "u" in q_rhs:
            F_NS += -df.dot(q_rhs["u"], v)*dx

        F.append(F_NS)

    # Setup of the phase-field equations
    if enable_PF:
        phi_1_flt = unit_interval_filter(phi_1)
        F_PF_phi = (per_tau*(phi_-phi_1_flt)*psi*df.dx +
                    M_*df.dot(df.grad(g_), df.grad(psi)) * dx)
        if enable_NS:
            F_PF_phi += df.dot(u_, df.grad(phi_)) * psi * dx

        F_PF_g = (g_ * h * dx
                  - sigma_bar*eps*df.dot(df.grad(phi_), df.grad(h)) * dx
                  - sigma_bar/eps*diff_pf_potential(phi_) * h * dx)
        if enable_EC:
            F_PF_g += (-sum([dbeta_i * ci_ * h * dx
                             for dbeta_i, ci_ in zip(dbeta, c_)])
                       + dveps * df.dot(df.grad(V_), df.grad(V_)) * h * dx)

        # Contact angle boundary condtions
        for boundary_name, costheta in neumann_bcs["phi"].items():
            fw_prime = diff_pf_contact(phi_)
            F_PF_g += sigma_bar * costheta * fw_prime * h * ds(
                boundary_to_mark[boundary_name])

        # RHS source terms
        if "phi" in q_rhs:
            F_PF_phi += -q_rhs["phi"]*psi*dx

        F_PF = F_PF_phi + F_PF_g
        F.append(F_PF)

    # Setup of the electrochemistry
    if enable_EC:
        F_E_c = []
        for ci_, ci_1, bi, Ki_, zi, dbetai, solute in zip(
                c_, c_1, b, K_, z, dbeta, solutes):
            ci_1_flt = max_value(ci_1, 0.)
            F_E_ci = (per_tau*(ci_-ci_1_flt)*bi*df.dx
                       + Ki_*df.dot(df.grad(ci_), df.grad(bi))*df.dx)
            if zi != 0:
                F_E_ci += Ki_*zi*ci_*df.dot(df.grad(V_),
                                             df.grad(bi))*df.dx
            if enable_NS:
                F_E_ci += df.dot(u_, df.grad(ci_))*bi*df.dx

            if enable_PF:
                F_E_ci += Ki_*ci_*dbetai*df.dot(df.grad(phi_),
                                                df.grad(bi)) * dx

            if solute[0] in q_rhs:
                F_E_ci += - q_rhs[solute[0]] * bi * dx

            F_E_c.append(F_E_ci)

        F_E_V = veps_*df.dot(df.grad(V_), df.grad(U))*df.dx

        if rho_e_ != 0:
            F_E_V += -rho_e_*U*df.dx

        # Surface charge boundary condition
        for boundary_name, sigma_e in neumann_bcs["V"].items():
            F_E_V += -sigma_e*U*ds(boundary_to_mark[boundary_name])

        # RHS source terms
        if "V" in q_rhs:
            F_E_V += q_rhs["V"]*U*dx

        F_E = sum(F_E_c) + F_E_V

        F.append(F_E)

    F = sum(F)

    J = df.derivative(F, w_NSPFEC)
    problem_NSPFEC = df.NonlinearVariationalProblem(F, w_NSPFEC, dirichlet_bcs_NSPFEC, J)
    solver_NSPFEC = df.NonlinearVariationalSolver(problem_NSPFEC)
    if use_iterative_solvers:
        solver_NSPFEC.parameters['newton_solver']['linear_solver'] = 'gmres'
        solver_NSPFEC.parameters['newton_solver']['preconditioner'] = 'ilu'

    return solver_NSPFEC
示例#37
0
	def epsilon(self, uu):
		return dolfin.sym(dolfin.grad(uu))
示例#38
0
def les_setup(u_, mesh, assemble_matrix, CG1Function, nut_krylov_solver, bcs,
              **NS_namespace):
    """
    Set up for solving the Germano Dynamic LES model applying
    Lagrangian Averaging.
    """

    # Create function spaces
    CG1 = FunctionSpace(mesh, "CG", 1)
    p, q = TrialFunction(CG1), TestFunction(CG1)
    dim = mesh.geometry().dim()

    # Define delta and project delta**2 to CG1
    delta = pow(CellVolume(mesh), 1. / dim)
    delta_CG1_sq = project(delta, CG1)
    delta_CG1_sq.vector().set_local(delta_CG1_sq.vector().array()**2)
    delta_CG1_sq.vector().apply("insert")

    # Define nut_
    Sij = sym(grad(u_))
    magS = sqrt(2 * inner(Sij, Sij))
    Cs = Function(CG1)
    nut_form = Cs**2 * delta**2 * magS
    # Create nut_ BCs
    ff = FacetFunction("size_t", mesh, 0)
    bcs_nut = []
    for i, bc in enumerate(bcs['u0']):
        bc.apply(u_[0].vector())  # Need to initialize bc
        m = bc.markers()  # Get facet indices of boundary
        ff.array()[m] = i + 1
        bcs_nut.append(DirichletBC(CG1, Constant(0), ff, i + 1))
    nut_ = CG1Function(nut_form,
                       mesh,
                       method=nut_krylov_solver,
                       bcs=bcs_nut,
                       bounded=True,
                       name="nut")

    # Create functions for holding the different velocities
    u_CG1 = as_vector([Function(CG1) for i in range(dim)])
    u_filtered = as_vector([Function(CG1) for i in range(dim)])
    dummy = Function(CG1)
    ll = LagrangeInterpolator()

    # Assemble required filter matrices and functions
    G_under = Function(CG1, assemble(TestFunction(CG1) * dx))
    G_under.vector().set_local(1. / G_under.vector().array())
    G_under.vector().apply("insert")
    G_matr = assemble(inner(p, q) * dx)

    # Set up functions for Lij and Mij
    Lij = [Function(CG1) for i in range(dim * dim)]
    Mij = [Function(CG1) for i in range(dim * dim)]
    # Check if case is 2D or 3D and set up uiuj product pairs and
    # Sij forms, assemble required matrices
    Sijcomps = [Function(CG1) for i in range(dim * dim)]
    Sijfcomps = [Function(CG1) for i in range(dim * dim)]
    # Assemble some required matrices for solving for rate of strain terms
    Sijmats = [assemble_matrix(p.dx(i) * q * dx) for i in range(dim)]
    if dim == 3:
        tensdim = 6
        uiuj_pairs = ((0, 0), (0, 1), (0, 2), (1, 1), (1, 2), (2, 2))
    else:
        tensdim = 3
        uiuj_pairs = ((0, 0), (0, 1), (1, 1))

    # Set up Lagrange functions
    JLM = Function(CG1)
    JLM.vector()[:] += 1E-32
    JMM = Function(CG1)
    JMM.vector()[:] += 1

    return dict(Sij=Sij,
                nut_form=nut_form,
                nut_=nut_,
                delta=delta,
                bcs_nut=bcs_nut,
                delta_CG1_sq=delta_CG1_sq,
                CG1=CG1,
                Cs=Cs,
                u_CG1=u_CG1,
                u_filtered=u_filtered,
                ll=ll,
                Lij=Lij,
                Mij=Mij,
                Sijcomps=Sijcomps,
                Sijfcomps=Sijfcomps,
                Sijmats=Sijmats,
                JLM=JLM,
                JMM=JMM,
                dim=dim,
                tensdim=tensdim,
                G_matr=G_matr,
                G_under=G_under,
                dummy=dummy,
                uiuj_pairs=uiuj_pairs)
示例#39
0
文件: common.py 项目: jorgensd/nirom
def epsilon(u):
    # Define symmetric gradient
    return dolfin.sym(dolfin.nabla_grad(u))
示例#40
0
 def strain(v):
     return dl.sym(dl.nabla_grad(v))
示例#41
0
    def __ufl_forms(self, nu, f):
        (w, q, wbar, qbar) = self.__test_functions()
        (u, p, ubar, pbar) = self.__trial_functions()

        # Infer geometric dimension
        zero_vec = np.zeros(self.gdim)

        ds = self.ds
        n = self.n
        he = self.he
        alpha = self.alpha
        h_d = self.h_d
        beta_stab = self.beta_stab
        facet_integral = self.facet_integral

        pI = p * Identity(
            self.mixedL.sub(1).ufl_cell().topological_dimension())
        pbI = pbar * \
            Identity(self.mixedL.sub(1).ufl_cell().topological_dimension())

        # Upper left block
        # Contribution comes from local momentum balance
        AB = inner(2*nu*sym(grad(u)), grad(w))*dx \
            + facet_integral(dot(-2*nu*sym(grad(u))*n
                                 + (2*nu*alpha/he)*u, w)) \
            + facet_integral(dot(-2*nu*u, sym(grad(w))*n)) \
            - inner(pI, grad(w))*dx
        # Contribution comes from local mass balance
        BtF = -dot(q, div(u))*dx - \
            facet_integral(beta_stab*he/(nu+1)*dot(p, q))
        A_S = AB + BtF

        # Upper right block
        # Contribution from local momentum
        CD = facet_integral(-alpha/he*2*nu*inner(ubar, w)) \
            + facet_integral(2*nu*inner(ubar, sym(grad(w))*n)) \
            + facet_integral(dot(pbI*n, w))
        H = facet_integral(beta_stab * he / (nu + 1) * dot(pbar, q))
        G_S = CD + H

        # Transpose block
        CDT = facet_integral(- alpha/he*2*nu*inner(wbar, u)) \
            + facet_integral(2*nu*inner(wbar, sym(grad(u))*n)) \
            + facet_integral(qbar * dot(u, n))
        HT = facet_integral(beta_stab * he / (nu + 1) * dot(p, qbar))
        G_ST = CDT + HT

        # Lower right block, penalty on ds(98) approximates free-slip
        KL = facet_integral(alpha/he * 2 * nu*dot(ubar, wbar)) \
            - facet_integral(dot(pbar*n, wbar)) \
            + Constant(1E12)/he * inner(outer(ubar, wbar), outer(n, n)) * ds(98)
        LtP = - facet_integral(dot(ubar, n)*qbar) \
            - facet_integral(beta_stab*he/(nu+1) * pbar * qbar)
        B_S = KL + LtP

        # Righthandside
        Q_S = dot(f, w) * dx
        S_S = facet_integral(dot(Constant(zero_vec), wbar))
        S_S += dot(h_d[0], wbar) * ds(99) + dot(h_d[1], wbar) * ds(
            100)  #Neumann BC
        return {
            'A_S': A_S,
            'G_S': G_S,
            'G_ST': G_ST,
            'B_S': B_S,
            'Q_S': Q_S,
            'S_S': S_S
        }