def solve_thermal(self):
        """
        Solve the thermal diffusion problem.
        Both ice and solution.
        """

        ### Solve heat equation
        alphalog_i = dolfin.project(dolfin.Expression('astar*exp(-2.*x[0])',degree=1,astar=self.astar_i),self.ice_V)
        # Set up the variational form for the current mesh location
        F_i = (self.u_i-self.u0_i)*self.v_i*dolfin.dx + self.dt*dolfin.inner(dolfin.grad(self.u_i), dolfin.grad(alphalog_i*self.v_i))*dolfin.dx
        a_i = dolfin.lhs(F_i)
        L_i = dolfin.rhs(F_i)
        # Solve ice temperature
        dolfin.solve(a_i==L_i,self.T_i,[self.bc_inf,self.bc_iWall])
        # Update previous profile to current
        self.u0_i.assign(self.T_i)

        diff_ratio = (self.ks*const.rhoi*const.ci)/(const.ki*self.rhos*self.cs)
        alphalog_s = dolfin.project(dolfin.Expression('astar*exp(-2.*x[0])',degree=1,astar=self.astar_i),self.sol_V)
        # Set up the variational form for the current mesh location
        F_s = (self.u_s-self.u0_s)*self.v_s*dolfin.dx + self.dt*dolfin.inner(dolfin.grad(self.u_s), dolfin.grad(alphalog_s*diff_ratio*self.v_s))*dolfin.dx
                #- self.dt*(self.Q_sol*self.t0/abs(self.T_inf)/(const.rhoi*const.ci))*self.v_s*dolfin.dx #TODO: check this solution source term
        # TODO: Center heat flux
        #F_s -= (self.Q_center/(self.ks*diff_ratio*2.*np.pi*abs(self.T_inf)))*self.v_s*self.sds(2)
        a_s = dolfin.lhs(F_s)
        L_s = dolfin.rhs(F_s)
        # Solve solution temperature
        dolfin.solve(a_s==L_s,self.T_s,self.bc_sWall)
        # Update previous profile to current
        self.u0_s.assign(self.T_s)
    def __init__(self, t_end=None, func=None):
        Problem_verification.__init__(self, t_end, func)

        self.u0_expr = dol.Constant(1)
        self.V = dol.FunctionSpace(dol.UnitIntervalMesh(1), 'DG', 0)

        # rhs
        self.f1 = dol.Expression('pow(t, 2)', t=0, degree=2)
        self.f2 = dol.Expression('pow(t, 2)', t=0, degree=2)

        Problem_FE.__init__(self)
        # CN, higher order
        F = (dol.inner(
            self.v, self.utrial - self.uold + self.dt * 0.5 *
            (self.uold + self.utrial)) * dol.dx -
             0.5 * self.dt * dol.inner(self.f1 + self.f2, self.v) * dol.dx)
        prob = dol.LinearVariationalProblem(dol.lhs(F), dol.rhs(F), self.unew)
        self.solver = dol.LinearVariationalSolver(prob)
        # IE, lower order
        Flow = (dol.inner(
            self.v, self.utrial - self.uold + self.dt * self.utrial) * dol.dx -
                self.dt * dol.inner(self.f2, self.v) * dol.dx)
        problow = dol.LinearVariationalProblem(dol.lhs(Flow), dol.rhs(Flow),
                                               self.ulow)
        self.solver_low = dol.LinearVariationalSolver(problow)
예제 #3
0
def solve_initial_pressure(w_NSp, p, q, u, v, bcs_NSp, M_, g_, phi_, rho_,
                           rho_e_, V_, drho, sigma_bar, eps, grav, dveps,
                           enable_PF, enable_EC):
    V = u.function_space()
    grad_p = df.TrialFunction(V)
    grad_p_out = df.Function(V)
    F_grad_p = (df.dot(grad_p, v) * df.dx - rho_ * df.dot(grav, v) * df.dx)
    if enable_PF:
        F_grad_p += -drho * M_ * df.inner(df.grad(u), df.outer(df.grad(g_),
                                                               v)) * df.dx
        F_grad_p += -sigma_bar * eps * df.inner(
            df.outer(df.grad(phi_), df.grad(phi_)), df.grad(v)) * df.dx
    if enable_EC and rho_e_ != 0:
        F_grad_p += rho_e_ * df.dot(df.grad(V_), v) * df.dx
    if enable_PF and enable_EC:
        F_grad_p += dveps * df.dot(df.grad(phi_), v) * df.dot(
            df.grad(V_), df.grad(V_)) * df.dx

    info_red("Solving initial grad_p...")
    df.solve(df.lhs(F_grad_p) == df.rhs(F_grad_p), grad_p_out)

    F_p = (df.dot(df.grad(q), df.grad(p)) * df.dx -
           df.dot(df.grad(q), grad_p_out) * df.dx)
    info_red("Solving initial p...")
    df.solve(df.lhs(F_p) == df.rhs(F_p), w_NSp, bcs_NSp)
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
예제 #5
0
    def __init__(self, t_end = None, func = None, para_stiff = None, adjoint = False):
        Problem_Basic.__init__(self, t_end = t_end, func = func, para_stiff = para_stiff)
        
        self.k = dol.Constant(self.k)
        self.u0_expr = dol.Constant(self.u0) # initial value
        
        mesh = dol.UnitIntervalMesh(1)
        R_elem = dol.FiniteElement("R", mesh.ufl_cell(), 0)
        V_elem = dol.MixedElement([R_elem, R_elem])
        self.V = dol.FunctionSpace(mesh, V_elem)
        
        if adjoint:
            self.z0_expr = dol.Constant(np.array([0., 0.])) # initial value adj
            
        Problem_FE.__init__(self, adjoint)
        
        (self.v1     , self.v2)      = dol.split(self.v)
        (self.u1trial, self.u2trial) = dol.split(self.utrial)
        (self.u1old  , self.u2old)   = dol.split(self.uold)
        (self.u1low  , self.u2low)   = dol.split(self.ulow)
        
        ## Crank nicolson weak formulation
        F = (dol.inner(self.v1, self.u1trial - self.u1old + self.dt * (0.5 * (self.u1old + self.u1trial) - 0.5 * (self.u2old + self.u2trial)))*dol.dx
           + dol.inner(self.v2, self.u2trial - self.u2old - self.k * self.dt * 0.5 * (self.u2old + self.u2trial))*dol.dx)
        prob = dol.LinearVariationalProblem(dol.lhs(F), dol.rhs(F), self.unew)
        self.solver = dol.LinearVariationalSolver(prob)
        ## Implicit Euler weak formulation for error estimation
        Flow = (dol.inner(self.v1, self.u1trial - self.u1old + self.dt * (self.u1trial - self.u2trial))*dol.dx
              + dol.inner(self.v2, self.u2trial - self.u2old - self.k * self.dt * self.u2trial)*dol.dx)
        problow = dol.LinearVariationalProblem(dol.lhs(Flow), dol.rhs(Flow), self.ulow)
        self.solver_low = dol.LinearVariationalSolver(problow)

        if adjoint:
            (self.z1old  , self.z2old)   = dol.split(self.zold)
            (self.z1trial, self.z2trial) = dol.split(self.ztrial)
            
            if self.func not in [1, 2]:
                raise ValueError('DWR not (yet) implemented for this functional')
                
            adj_src = dol.Function(self.V)
            if   self.func == 1:    adj_src.interpolate(dol.Constant((1, 0)))
            elif self.func == 2:    adj_src.interpolate(dol.Constant((0, 1)))
            
            src1, src2 = dol.split(adj_src)
 
            Fadj = (dol.inner(self.z1trial - self.z1old + 0.5 * self.dt * (-self.z1trial - self.z1old + 2*src1), self.v1)*dol.dx +
                    dol.inner(self.z2trial - self.z2old + 0.5 * self.dt * ( self.z1trial + self.z1old + self.k*(self.z2trial + self.z2old) + 2*src2), self.v2)*dol.dx)
            prob_adj = dol.LinearVariationalProblem(dol.lhs(Fadj), dol.rhs(Fadj), self.znew)
            self.solver_adj = dol.LinearVariationalSolver(prob_adj)
예제 #6
0
 def solveFwd(self, state, x):
     """ Solve the possibly nonlinear forward problem:
     Given :math:`m`, find :math:`u` such that
     
         .. math:: \\delta_p F(u, m, p;\\hat{p}) = 0,\\quad \\forall \\hat{p}."""
     if self.solver is None:
         self.solver = self._createLUSolver()
     if self.is_fwd_linear:
         u = dl.TrialFunction(self.Vh[STATE])
         m = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
         p = dl.TestFunction(self.Vh[ADJOINT])
         res_form = self.varf_handler(u, m, p)
         A_form = dl.lhs(res_form)
         b_form = dl.rhs(res_form)
         A, b = dl.assemble_system(A_form, b_form, bcs=self.bc)
         self.solver.set_operator(A)
         self.solver.solve(state, b)
     else:
         u = vector2Function(x[STATE], self.Vh[STATE])
         m = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
         p = dl.TestFunction(self.Vh[ADJOINT])
         res_form = self.varf_handler(u, m, p)
         dl.solve(res_form == 0, u, self.bc)
         state.zero()
         state.axpy(1., u.vector())
예제 #7
0
    def stokes(self):
        P2 = VectorElement("CG", self.mesh.ufl_cell(), 2)
        P1 = FiniteElement("CG", self.mesh.ufl_cell(), 1)
        TH = P2 * P1
        VQ = FunctionSpace(self.mesh, TH)
        mf = self.mf
        self.no_slip = Constant((0., 0))
        self.topflow = Expression(("-x[0] * (x[0] - 1.0) * 6.0 * m", "0.0"),
                                  m=self.U_m,
                                  degree=2)
        bc0 = DirichletBC(VQ.sub(0), self.topflow, mf, self.bc_dict["top"])
        bc1 = DirichletBC(VQ.sub(0), self.no_slip, mf, self.bc_dict["left"])
        bc2 = DirichletBC(VQ.sub(0), self.no_slip, mf, self.bc_dict["bottom"])
        bc3 = DirichletBC(VQ.sub(0), self.no_slip, mf, self.bc_dict["right"])
        # bc4 = DirichletBC(VQ.sub(1), Constant(0), mf, self.bc_dict["top"])
        bcs = [bc0, bc1, bc2, bc3]

        vup = TestFunction(VQ)
        up = TrialFunction(VQ)
        # the solution will be in here:
        up_ = Function(VQ)

        u, p = split(up)  # Trial
        vu, vp = split(vup)  # Test
        u_, p_ = split(up_)  # Function holding the solution
        F = self.mu*inner(grad(vu), grad(u))*dx - inner(div(vu), p)*dx \
            - inner(vp, div(u))*dx + dot(self.g*self.rho, vu)*dx
        solve(lhs(F) == rhs(F), up_, bcs=bcs)
        self.u_.assign(project(u_, self.V))
        self.p_.assign(project(p_, self.Q))
        return
예제 #8
0
    def EvaluateImpl(self, inputs):
        """
        
        """
        m = dl.Function(self.V)
        m.vector().set_local(inputs[0])

        p_n = dl.interpolate(m, self.V)
        p_nm1 = dl.interpolate(m, self.V)
        p_trial = self.p_trial
        v = self.v

        F = (self.c**2) * (self.dt**2) * dl.inner(
            dl.grad(p_trial), dl.grad(v)
        ) * dl.dx - 2. * p_n * v * dl.dx + p_trial * v * dl.dx + p_nm1 * v * dl.dx
        a, L = dl.lhs(F), dl.rhs(F)

        # Time-stepping
        p = dl.Function(self.V)
        t = 0
        for n in range(self.numSteps):
            # Update current timtime
            t += self.dt

            # Compute solution
            dl.solve(a == L, p)

            # Update previous solution
            p_nm1.assign(p_n)
            p_n.assign(p)

        out = p.vector().array()[:]

        self.outputs = [out]
예제 #9
0
    def stokes(self):
        P2 = df.VectorElement("CG", self.mesh.ufl_cell(), 2)
        P1 = df.FiniteElement("CG", self.mesh.ufl_cell(), 1)
        TH = P2 * P1
        VQ = df.FunctionSpace(self.mesh, TH)
        mf = self.mf
        self.no_slip = df.Constant((0., 0))
        U0_str = "4.*U_m*x[1]*(.41-x[1])/(.41*.41)"
        U0 = df.Expression((U0_str, "0"), U_m=self.U_m, degree=2)
        bc0 = df.DirichletBC(VQ.sub(0), df.Constant((0, 0)), mf,
                             self.bc_dict["obstacle"])
        bc1 = df.DirichletBC(VQ.sub(0), df.Constant((0, 0)), mf,
                             self.bc_dict["channel_walls"])
        bc2 = df.DirichletBC(VQ.sub(0), U0, mf, self.bc_dict["inlet"])
        bc3 = df.DirichletBC(VQ.sub(1), df.Constant(0), mf,
                             self.bc_dict["outlet"])
        bcs = [bc0, bc1, bc2, bc3]

        vup = df.TestFunction(VQ)
        up = df.TrialFunction(VQ)
        up_ = df.Function(VQ)

        u, p = df.split(up)  # Trial
        vu, vp = df.split(vup)  # Test
        u_, p_ = df.split(up_)  # Function holding the solution
        inner, grad, dx, div = df.inner, df.grad, df.dx, df.div
        F = self.mu*inner(grad(vu), grad(u))*dx - inner(div(vu), p)*dx \
            - inner(vp, div(u))*dx
        df.solve(df.lhs(F) == df.rhs(F), up_, bcs=bcs)
        self.u_.assign(df.project(u_, self.V))
        self.p_.assign(df.project(p_, self.Q))
        return
예제 #10
0
    def setup_EC(w_EC, c, V, b, U, rho_e,
             dx, ds,
             dirichlet_bcs, neumann_bcs, boundary_to_mark,
             c_1, u_1, K_, veps_, phi_,
             per_tau, z, dbeta,
             enable_NS, enable_PF,
             use_iterative_solvers):
    """ Set up electrochemistry subproblem. """
         
    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 += -V*U*dx
    F = F_V
    a, L = df.lhs(F), df.rhs(F)

    
   

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

    for ci, ci_1, bi, Ki_, zi, dbetai in zip(c, c_1, b, K_, z, dbeta):
        ?? 
예제 #11
0
    def solve_petsc(self):
        """
        Solves the linear problem using PETSc interface, and manipulates with PETSc matrices.

        :return: list[state vectors]
        """
        form = self.forms._rhs_forms(
            shift=self.frequency) + self.forms._lhs_forms()
        w = dolf.Function(self.forms.function_space)

        lhs_matrix = dolf.PETScMatrix()
        lhs_matrix = dolf.assemble(dolf.lhs(form), tensor=lhs_matrix)
        for bc in self.forms.dirichlet_boundary_conditions():
            bc.apply(lhs_matrix)
        lhs_matrix = lhs_matrix.mat()

        averaged_boundary_terms = self.forms.boundary_averaged_velocity()
        if averaged_boundary_terms:
            lhs_matrix.axpy(-1.0, averaged_boundary_terms)

        solver = self.create_ksp_solver(lhs_matrix)

        rhs_vector = dolf.assemble(dolf.rhs(form))
        for bc in self.forms.dirichlet_boundary_conditions():
            bc.apply(rhs_vector)

        solver.solve(
            dolf.as_backend_type(rhs_vector).vec(),
            dolf.as_backend_type(w.vector()).vec(),
        )
        state = w.split(True)
        return state
예제 #12
0
def test_lhs_rhs_simple():
    """Test taking lhs/rhs of DOLFIN specific forms (constants
    without cell). """

    mesh = RectangleMesh.create(MPI.comm_world,
                                [Point(0, 0), Point(2, 1)], [3, 5],
                                CellType.Type.triangle)
    V = FunctionSpace(mesh, "CG", 1)
    f = 2.0
    g = 3.0
    v = TestFunction(V)
    u = TrialFunction(V)

    F = inner(g * grad(f * v), grad(u)) * dx + f * v * dx
    a, L = system(F)

    Fl = lhs(F)
    Fr = rhs(F)
    assert (Fr)

    a0 = inner(grad(v), grad(u)) * dx

    n = assemble(a).norm("frobenius")  # noqa
    nl = assemble(Fl).norm("frobenius")  # noqa
    n0 = 6.0 * assemble(a0).norm("frobenius")  # noqa

    assert round(n - n0, 7) == 0
    assert round(n - nl, 7) == 0
    def __init__(self, domain):
        rho, mu, dt, g = domain.rho, domain.mu, domain.dt, domain.g
        u, u_1, vu = domain.u, domain.u_1, domain.vu
        p_1 = domain.p_1

        n = FacetNormal(domain.mesh)

        acceleration = rho * inner((u - u_1) / dt, vu) * dx
        pressure = inner(p_1, div(vu)) * dx - dot(p_1 * n, vu) * ds
        body_force = dot(g*rho, vu)*dx \
            + dot(Constant((0.0, 0.0)), vu) * ds
        # diffusion = (-inner(mu * (grad(u_1) + grad(u_1).T), grad(vu))*dx
        #               + dot(mu * (grad(u_1) + grad(u_1).T)*n, vu)*ds)  # just fine
        # diffusion = (-inner(mu * (grad(u) + grad(u).T), grad(vu))*dx)  # just fine
        # just fine, but horribly slow in combination with ???  -> not reproducable
        diffusion = (-inner(mu * (grad(u) + grad(u).T), grad(vu)) * dx +
                     dot(mu * (grad(u) + grad(u).T) * n, vu) * ds)
        # convection = rho*dot(dot(u, nabla_grad(u_1)), vu) * dx  # no vortices
        convection = rho * dot(dot(u_1, nabla_grad(u)), vu) * dx
        # stabilization = -gamma*psi_p*p_1
        # convection = dot(div(rho * outer(u_1, u_1)), vu) * dx  # not stable!
        # convection = rho * dot(dot(u_1, nabla_grad(u_1)), vu) * dx  # just fine
        F_impl = -acceleration - convection + diffusion + pressure + body_force

        self.a, self.L = lhs(F_impl), rhs(F_impl)
        self.domain = domain
        self.A = assemble(self.a)
        [bc.apply(self.A) for bc in domain.bcu]
        return
예제 #14
0
    def __init__(self, parameters, domain):
        rho = Constant(parameters["density [kg/m3]"])
        mu = Constant(parameters["viscosity [Pa*s]"])
        dt = Constant(parameters["dt [s]"])
        u, u_1, u_k, vu = domain.u, domain.u_1, domain.u_k, domain.vu
        p_1 = domain.p_1

        n = FacetNormal(domain.mesh)
        acceleration = rho*inner((u-u_1)/dt, vu) * dx
        convection = dot(div(rho*outer(u_k, u)), vu) * dx
        convection = rho*dot(dot(u_k, nabla_grad(u)), vu) * dx
        pressure = (inner(p_1, div(vu))*dx - dot(p_1*n, vu)*ds)
        diffusion = (-inner(mu * (grad(u) + grad(u).T), grad(vu))*dx)  # good
        # diffusion = (-inner(mu * (grad(u) + grad(u).T), grad(vu))*dx
        #               + dot(mu * (grad(u) + grad(u).T)*n, vu)*ds)  # very slow!

        # F_impl = acceleration + convection + pressure + diffusion

        # dot(u_1, nabla_grad(u_1)) works
        # dot(u, nabla_grad(u_1)) does not change!
        u_mid = (u + u_1) / 2.0
        F_impl = rho*dot((u - u_1) / dt, vu)*dx \
            + rho*dot(dot(u_1, nabla_grad(u_1)), vu)*dx \
            + inner(sigma(u_mid, p_1, mu), epsilon(vu))*dx \
            + dot(p_1*n, vu)*ds - dot(mu*nabla_grad(u_mid)*n, vu)*ds

        self.a, self.L = lhs(F_impl), rhs(F_impl)
        self.domain = domain
        self.A = assemble(self.a)
        [bc.apply(self.A) for bc in domain.bcu]
        return
예제 #15
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
예제 #16
0
    def solve(self):
        super(backwardEuler, self).solve()

        # Array for storing the stage values
        X = [self.u.copy(deepcopy=True)]

        # Get the variational linear/nonlinear variational forms
        # and embed them in respective solver class
        if self.linear:
            l = self.getLinearVariationalForms(X)
            p = [linearStage(d.lhs(l[0]), d.rhs(l[0]), self.bcs, self.solver)]
        else:
            l = self.getNonlinearVariationalForms(X)
            a = [d.derivative(l[0], X[0], self.U)]
            p = [nonlinearStage(a[0], l[0], self.bcs)]

        # Initialize save/plot of function(s)
        self.figureHandling(Init=True)

        # Time stepping loop
        while True:
            timestepStart = time.time()

            # Update time dependent functions
            for i in range(len(self.tdfButcher)):
                for j in range(0, 1):
                    self.tdfButcher[i][j].t = self.t + self.dt

            # Update time dependent functions on boundary
            for F in self.tdfBC:
                F.t = self.t + self.dt

            # Solve for implicit stages
            if self.linear:
                p[0].solve(X[0].vector())
            else:
                self.solver.solve(p[0], X[0].vector())

            # Constant step size integration
            self.u.vector()[:] = X[0].vector()[:]
            self.t += self.dt
            self.nAcc += 1
            if self.parameters['verbose']:
                self.printProgress(self.estimateRuntime)

            # Update / save plots
            self.figureHandling(Update=True)

            # Break if this is final time step
            if self.breakTimeLoop:
                terminateReason = "Success"
                break

            self.timestepTimer = time.time() - timestepStart
            self.verifyStepsize()

        super(backwardEuler, self).terminateTimeLoop(terminateReason)
예제 #17
0
 def create_rhs(self):
     self.L = self.create_bc()
     if self.moment_order == 3:
         self.L += self.source_term()
     if self.stab_type == 'gls':
         self.L += df.rhs(self.apply_stabilization())
     if self.problem_type == 'nonlinear':
         self.L += self.add_nonlinearity()
         self.F = self.a - self.L
예제 #18
0
 def get_system(self, t):
     kappa.t = t
     f.t = t
     n = FacetNormal(self.V.mesh())
     u = TrialFunction(self.V)
     v = TestFunction(self.V)
     F = inner(kappa * grad(u), grad(v / self.rho_cp)) * dx \
         - inner(kappa * grad(u), n) * v / self.rho_cp * ds \
         - f * v / self.rho_cp * dx
     return assemble(lhs(F)), assemble(rhs(F))
예제 #19
0
    def __init__(self, t_end=None, func=None):
        Problem_verification.__init__(self, t_end, func)

        self.u0_expr = dol.Constant(1)
        self.V = dol.FunctionSpace(dol.UnitIntervalMesh(1), 'DG', 0)

        Problem_FE.__init__(self)
        # CN, higher order
        F = dol.inner(
            self.v, self.utrial - self.uold + self.dt * 0.5 *
            (self.uold + self.utrial)) * dol.dx
        prob = dol.LinearVariationalProblem(dol.lhs(F), dol.rhs(F), self.unew)
        self.solver = dol.LinearVariationalSolver(prob)
        # IE, lower order
        Flow = dol.inner(
            self.v, self.utrial - self.uold + self.dt * self.utrial) * dol.dx
        problow = dol.LinearVariationalProblem(dol.lhs(Flow), dol.rhs(Flow),
                                               self.ulow)
        self.solver_low = dol.LinearVariationalSolver(problow)
예제 #20
0
def navier_stokes_IPCS(mesh, dt, parameter):
    """
    fenics code: weak form of the problem.
    """
    mu, rho, nu = parameter
    V = VectorFunctionSpace(mesh, 'P', 2)
    Q = FunctionSpace(mesh, 'P', 1)

    bc0 = DirichletBC(V, Constant((0, 0)), cylinderwall)
    bc1 = DirichletBC(V, Constant((0, 0)), topandbottom)
    bc2 = DirichletBC(V, U0, inlet)
    bc3 = DirichletBC(Q, Constant(1), outlet)
    bcs = [bc0, bc1, bc2, bc3]

    # ds is needed to compute drag and lift. Not used here.
    ASD1 = AutoSubDomain(topandbottom)
    ASD2 = AutoSubDomain(cylinderwall)
    mf = MeshFunction("size_t", mesh, 1)
    mf.set_all(0)
    ASD1.mark(mf, 1)
    ASD2.mark(mf, 2)
    ds_ = ds(subdomain_data=mf, domain=mesh)

    vu, vp = TestFunction(V), TestFunction(Q)  # for integration
    u_, p_ = Function(V), Function(Q)  # for the solution
    u_1, p_1 = Function(V), Function(Q)  # for the prev. solution
    u, p = TrialFunction(V), TrialFunction(Q)  # unknown!
    bcu = [bcs[0], bcs[1], bcs[2]]
    bcp = [bcs[3]]

    n = FacetNormal(mesh)
    u_mid = (u + u_1) / 2.0
    F1 = rho*dot((u - u_1) / dt, vu)*dx \
        + rho*dot(dot(u_1, nabla_grad(u_1)), vu)*dx \
        + inner(sigma(u_mid, p_1, mu), epsilon(vu))*dx \
        + dot(p_1*n, vu)*ds - dot(mu*nabla_grad(u_mid)*n, vu)*ds
    a1 = lhs(F1)
    L1 = rhs(F1)
    # Define variational problem for step 2
    a2 = dot(nabla_grad(p), nabla_grad(vp)) * dx
    L2 = dot(nabla_grad(p_1), nabla_grad(vp)) * dx - (
        rho / dt) * div(u_) * vp * dx  # rho missing in FEniCS tutorial
    # Define variational problem for step 3
    a3 = dot(u, vu) * dx
    L3 = dot(u_, vu) * dx - dt * dot(nabla_grad(p_ - p_1), vu) * dx
    # Assemble matrices
    A1 = assemble(a1)
    A2 = assemble(a2)
    A3 = assemble(a3)
    # Apply boundary conditions to matrices
    [bc.apply(A1) for bc in bcu]
    [bc.apply(A2) for bc in bcp]
    return u_, p_, u_1, p_1, L1, A1, L2, A2, L3, A3, bcu, bcp
예제 #21
0
 def solve(self):
     form = self.forms._rhs_forms(
         shift=self.frequency) + self.forms._lhs_forms()
     w = dolf.Function(self.forms.function_space)
     dolf.solve(
         dolf.lhs(form) == dolf.rhs(form),
         w,
         self.forms.dirichlet_boundary_conditions(),
         solver_parameters={"linear_solver": "mumps"},
     )
     state = w.split(True)
     return state
예제 #22
0
파일: pde.py 프로젝트: zhouqp631/DREAM-BUQ
    def soln_fwd(self):
        """
        Solve the forward equation.
        F = 0
        """
        # 5. Solve (non)linear variational problem
#         df.solve(self.F==0,self.states_fwd,self.ess_bc,J=self.dFdstates)
#         self.states_fwd = df.Function(self.W)
        df.solve(df.lhs(self.F)==df.rhs(self.F),self.states_fwd,self.ess_bc)
#         df.solve(self.a==self.L,self.states_fwd,self.ess_bc)
        self.soln_count[0] += 1
        u_fwd, l_fwd = df.split(self.states_fwd)
        return u_fwd, l_fwd
예제 #23
0
def rhs(form):
    """
    Wrapper for the DOLFIN rhs function. Correctly handles QForm s.
    """

    if not isinstance(form, ufl.form.Form):
        raise InvalidArgumentException("form must be a Form")

    nform = dolfin.rhs(form)
    if isinstance(form, QForm):
        return QForm(nform, quadrature_degree = form_quadrature_degree(form))
    else:
        return nform
def matrix_optimisation(form):
    """
    Attempt to convert a linear form into the action of a bi-linear form.
    Return a (bi-linear Form, Function) pair on success, and None on failure.
    """

    if not isinstance(form, ufl.form.Form):
        raise InvalidArgumentException("form must be a Form")

    # Find the test function
    args = ufl.algorithms.extract_arguments(form)
    if not len(args) == 1:
        # This is not a linear form
        return None

    # Look for a single non-static Function dependency
    tcs = extract_non_static_coefficients(form)
    if not len(tcs) == 1:
        # Found too many non-static coefficients
        return None
    elif not isinstance(tcs[0], dolfin.Function):
        # The only non-static coefficient is not a Function
        return None
    # Found a single non-static Function dependency
    fn = tcs[0]

    # Look for a static bi-linear form whose action can be used to construct
    # the linear form
    mat_form = derivative(
        form,
        fn,
        # Hack to work around an obscure FEniCS bug
        expand=dolfin.MPI.size(dolfin.mpi_comm_world()) == 1
        or (not is_r0_function_space(args[0].function_space())
            and not is_r0_function(fn)))
    if n_non_static_coefficients(mat_form) > 0:
        # The form is non-linear
        return None
    try:
        rhs_form = dolfin.rhs(
            dolfin.replace(form,
                           {fn: dolfin.TrialFunction(fn.function_space())}))
    except ufl.log.UFLException:
        # The form might be inhomogeneous
        return None
    if not is_empty_form(rhs_form):
        # The form might be inhomogeneous
        return None

    # Success
    return mat_form, fn
 def __init__(self, domain):
     rho, mu, dt = domain.rho, domain.mu, domain.dt
     u, u_1, p_1, vu = domain.u, domain.u_1, domain.p_1, domain.vu
     n = FacetNormal(domain.mesh)
     acceleration = rho * inner((u - u_1) / dt, vu) * dx
     diffusion = (-inner(mu * (grad(u_1) + grad(u_1).T), grad(vu)) * dx +
                  dot(mu * (grad(u_1) + grad(u_1).T) * n, vu) * ds)
     pressure = inner(p_1, div(vu)) * dx - dot(p_1 * n, vu) * ds
     convection = rho * dot(dot(u_1, nabla_grad(u_1)), vu) * dx
     F_impl = -acceleration - convection + diffusion + pressure
     self.a, self.L = lhs(F_impl), rhs(F_impl)
     self.domain = domain
     self.A = assemble(self.a)
     [bc.apply(self.A) for bc in domain.bcu]
     return
def setup_NSp(w_NSp, p, q, dirichlet_bcs_NSp, dt, u_, p_1, rho_0,
              use_iterative_solvers, **namespace):
    """ Set up Navier-Stokes pressure subproblem. """
    F = (df.dot(df.nabla_grad(p - p_1), df.nabla_grad(q)) * df.dx +
         1. / dt * rho_0 * df.div(u_) * q * df.dx)

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

    problem = df.LinearVariationalProblem(a, L, w_NSp, dirichlet_bcs_NSp)
    solver = df.LinearVariationalSolver(problem)

    if use_iterative_solvers:
        solver.parameters["linear_solver"] = "bicgstab"
        solver.parameters["preconditioner"] = "amg"

    return solver
예제 #27
0
파일: TDLUES.py 프로젝트: mstiegl/BERNAISE
def setup_NSp(w_NSp, p, q, dx, ds, dirichlet_bcs_NSp, neumann_bcs,
              boundary_to_mark, u_, u_1, p_, p_1, rho_, dt, rho_min,
              use_iterative_solvers, **namespace):
    F = (df.dot(df.nabla_grad(p - p_1), df.nabla_grad(q)) * df.dx +
         1. / dt * rho_min * df.div(u_) * q * df.dx)

    a, L = df.lhs(F), df.rhs(F)
    problem = df.LinearVariationalProblem(a, L, w_NSp, dirichlet_bcs_NSp)
    solver = df.LinearVariationalSolver(problem)

    if use_iterative_solvers:
        solver.parameters["linear_solver"] = "gmres"
        solver.parameters["preconditioner"] = "hypre_amg"  # "amg"
        # solver.parameters["preconditioner"] = "hypre_euclid"

    return solver
예제 #28
0
파일: basic.py 프로젝트: daveb-dev/BERNAISE
def setup_EC(w_EC, c, V, b, U, rho_e,
             dx, ds,
             dirichlet_bcs, neumann_bcs, boundary_to_mark,
             c_1, u_1, K_, veps_, phi_,
             solutes,
             per_tau, z, dbeta,
             enable_NS, enable_PF,
             use_iterative_solvers,
             q_rhs):
    """ Set up electrochemistry subproblem. """
    F_c = []
    for ci, ci_1, bi, Ki_, zi, dbetai, solute in zip(c, c_1, b, K_, z, dbeta, solutes):
        F_ci = (per_tau*(ci-ci_1)*bi*dx +
                Ki_*df.dot(df.nabla_grad(ci), df.nabla_grad(bi))*dx)
        if zi != 0:
            F_ci += Ki_*zi*ci_1*df.dot(df.nabla_grad(V), df.nabla_grad(bi))*dx

        if enable_PF:
            F_ci += Ki_*ci*dbetai*df.dot(df.nabla_grad(phi_), df.nabla_grad(bi))*dx

        if enable_NS:
            # F_ci += df.div(ci*u_1)*bi*dx
            F_ci += - ci*df.dot(u_1, df.grad(bi))*dx

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

        F_c.append(F_ci)
    F_V = veps_*df.dot(df.nabla_grad(V), df.nabla_grad(U))*dx
    for boundary_name, sigma_e in neumann_bcs["V"].items():
        F_V += -sigma_e*U*ds(boundary_to_mark[boundary_name])
    if rho_e != 0:
        F_V += -rho_e*U*dx
    if "V" in q_rhs:
        F_V += q_rhs["V"]*U*dx

    F = sum(F_c) + F_V
    a, L = df.lhs(F), df.rhs(F)

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

    if use_iterative_solvers:
        solver.parameters["linear_solver"] = "gmres"
        # solver.parameters["preconditioner"] = "hypre_euclid"

    return solver
예제 #29
0
    def EvaluateImpl(self, inputs):
        """
        
        """
        numObs = self.numObs
        numSteps = self.numSteps
        # Each
        output = np.zeros((numObs * numSteps))
        m = dl.Function(self.V)
        m.vector().set_local(inputs[0])

        p_n = dl.Function(self.V)
        p_nm1 = dl.Function(self.V)
        p_n.assign(m)
        p_nm1.assign(m)
        p_trial = self.p_trial
        v = self.v

        F = (self.c**2) * (self.dt**2) * dl.inner(
            dl.grad(p_trial), dl.grad(v)
        ) * dl.dx - 2. * p_n * v * dl.dx + p_trial * v * dl.dx + p_nm1 * v * dl.dx
        a, L = dl.lhs(F), dl.rhs(F)

        # Time-stepping
        p = dl.Function(self.V)
        t = 0

        output[0:numObs] = self.ObservationOperator(p_nm1)
        output[numObs:2 * numObs] = self.ObservationOperator(p_n)

        for n in range(2, self.numSteps):
            # Update current timtime
            t += self.dt

            # Compute solution
            dl.solve(a == L, p)
            #             nb.plot(p)
            #             plt.title("p")
            #             plt.show()

            output[n * numObs:(n + 1) * numObs] = self.ObservationOperator(p)

            # Update previous solution
            p_nm1.assign(p_n)
            p_n.assign(p)

        self.outputs = [output]
예제 #30
0
    def algo_fvs_to_cell_averages(self,
                                  mesh_util,
                                  bcdata,
                                  fv_adjacent_cells_function,
                                  target_unit=None):
        '''Algorithm for turning BC data into cell averages.

Parameters
----------
mesh_util: :py:class:`.mesh_util.MeshUtil`
    Mesh utilities and data.
bcdata: dict
    Mapping `{expr: {(facet_value, sign), ...}}`.
target_unit: optional
    Unit to ``expr`` to in the ``bcdict`` argument.
fv_adjacent_cells_function: :py:class:`dolfin.Function`
    DG0 function containing ones and zeros; ones iff the cell is
    adjacent to a BC.
'''
        mu = mesh_util
        dless = mu.unit_registry('dimensionless')
        DG0 = mu.space.DG0
        dx = mu.dx
        u = dolfin.TrialFunction(DG0)
        v = dolfin.TestFunction(DG0)

        form = DelayedForm()
        for expr, fvss in bcdata.items():
            expr = dless * expr.object
            if target_unit is None:
                target_unit = expr.units
            expr_ = expr.m_as(target_unit)
            for fv, sign in fvss:
                # TODO: figure out what to do with the sign - relevant
                # for internal boundary conditions
                form += mu.ds(subdomain_id=fv) * v('+') * (u('+') - expr_)

        if target_unit is None:
            target_unit = dless

        form += dx * u * v * (1.0 - fv_adjacent_cells_function)
        form = form.delete_units().to_ufl().m

        u = dolfin.Function(DG0)
        dolfin.solve(dolfin.lhs(form) == dolfin.rhs(form), u, [])

        return target_unit * u
예제 #31
0
파일: basic.py 프로젝트: daveb-dev/BERNAISE
def setup_PF(w_PF, phi, g, psi, h,
             dx, ds,
             dirichlet_bcs, neumann_bcs, boundary_to_mark,
             phi_1, u_1, M_1, c_1, V_1,
             per_tau, sigma_bar, eps,
             dbeta, dveps,
             enable_NS, enable_EC,
             use_iterative_solvers,
             q_rhs):
    """ Set up phase field subproblem. """

    F_phi = (per_tau*(phi-unit_interval_filter(phi_1))*psi*dx +
             M_1*df.dot(df.grad(g), df.grad(psi))*dx)
    if enable_NS:
        F_phi += -phi*df.dot(u_1, df.grad(psi))*dx
        # F_phi += df.div(phi*u_1)*psi*dx
    F_g = (g*h*dx
           - sigma_bar*eps*df.dot(df.nabla_grad(phi), df.nabla_grad(h))*dx
           - sigma_bar/eps*(
               diff_pf_potential_linearised(phi,
                                            unit_interval_filter(
                                                phi_1))*h*dx))
    if enable_EC:
        F_g += (-sum([dbeta_i*ci_1*h*dx
                      for dbeta_i, ci_1 in zip(dbeta, c_1)])
                + 0.5*dveps*df.dot(df.nabla_grad(V_1), df.nabla_grad(V_1))*h*dx)

    for boundary_name, costheta in neumann_bcs["phi"].items():
        fw_prime = diff_pf_contact_linearised(phi, unit_interval_filter(phi_1))
        # Should be just surface tension!
        F_g += sigma_bar*costheta*fw_prime*h*ds(boundary_to_mark[boundary_name])

    if "phi" in q_rhs:        
        F_phi += -q_rhs["phi"]*psi*dx
    
    F = F_phi + F_g
    a, L = df.lhs(F), df.rhs(F)

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

    if use_iterative_solvers:
        solver.parameters["linear_solver"] = "gmres"
        # solver.parameters["preconditioner"] = "hypre_euclid"

    return solver
예제 #32
0
 def setSolverParams(self, step=None):
     if self.eqn == "poisboltz":
         print("PoisBoltz")
         self.F = dolfin.action(self.F, self.u_s)
         J = dolfin.derivative(self.F, self.u_s, self.u)
         problem = dolfin.NonlinearVariationalProblem(
             self.F, self.u_s, self.bcs, J)
         self.solver = dolfin.NonlinearVariationalSolver(problem)
         prm = self.solver.parameters
         prm['newton_solver']['absolute_tolerance'] = self.max_abs_error
         prm['newton_solver']['relative_tolerance'] = self.max_rel_error
         prm['newton_solver']['maximum_iterations'] = 10000
         prm['newton_solver']['relaxation_parameter'] = 0.1
         prm['newton_solver']['report'] = True
         prm['newton_solver']['linear_solver'] = self.method
         prm['newton_solver']['preconditioner'] = self.preconditioner
         prm['newton_solver']['krylov_solver']['maximum_iterations'] = 10000
         prm['newton_solver']['krylov_solver'][
             'absolute_tolerance'] = self.max_abs_error
         prm['newton_solver']['krylov_solver'][
             'relative_tolerance'] = self.max_rel_error
         prm['newton_solver']['krylov_solver']['monitor_convergence'] = True
     else:
         print("Separating LHS and RHS...")
         # Separate left and right hand sides of equation
         self.a, self.L = dolfin.lhs(self.F), dolfin.rhs(self.F)
         self.problem = dolfin.LinearVariationalProblem(
             self.a, self.L, self.u_s, self.bcs)
         self.solver = dolfin.LinearVariationalSolver(self.problem)
         dolfin.parameters['form_compiler']['optimize'] = True
         self.solver.parameters['linear_solver'] = self.method
         self.solver.parameters['preconditioner'] = self.preconditioner
         spec_param = self.solver.parameters['krylov_solver']
         #These only accessible after spec_param available.
         if self.init_guess == "prev":
             if step == 0:
                 spec_param['nonzero_initial_guess'] = False
             else:
                 spec_param['nonzero_initial_guess'] = True
         elif self.init_guess == "zero":
             spec_param['nonzero_initial_guess'] = False
         spec_param['absolute_tolerance'] = self.max_abs_error
         spec_param['relative_tolerance'] = self.max_rel_error
         spec_param['maximum_iterations'] = self.max_linear_iters
예제 #33
0
파일: heat.py 프로젝트: nschloe/maelstrom
    def __init__(
        self,
        Q,
        kappa,
        rho,
        cp,
        convection,
        source,
        dirichlet_bcs=None,
        neumann_bcs=None,
        robin_bcs=None,
        my_dx=dx,
        my_ds=ds,
        stabilization=None,
    ):
        super(Heat, self).__init__()
        self.Q = Q

        dirichlet_bcs = dirichlet_bcs or []
        neumann_bcs = neumann_bcs or {}
        robin_bcs = robin_bcs or {}

        self.convection = convection

        u = TrialFunction(Q)
        v = TestFunction(Q)

        # If there are sharp temperature gradients, numerical oscillations may
        # occur. This happens because the resulting matrix is not an M-matrix,
        # caused by the fact that A1 puts positive elements in places other
        # than the main diagonal. To prevent that, it is suggested by
        # Großmann/Roos to use a vertex-centered discretization for the mass
        # matrix part.
        # Check
        # https://bitbucket.org/fenics-project/ffc/issues/145/uflacs-error-for-vertex-quadrature-scheme
        #
        self.M = assemble(
            u * v * dx,
            form_compiler_parameters={
                "representation": "quadrature",
                "quadrature_rule": "vertex",
            },
        )

        mesh = Q.mesh()
        r = SpatialCoordinate(mesh)[0]
        self.F0 = F(
            u,
            v,
            kappa,
            rho,
            cp,
            convection,
            source,
            r,
            neumann_bcs,
            robin_bcs,
            my_dx,
            my_ds,
            stabilization,
        )

        self.dirichlet_bcs = dirichlet_bcs

        self.A, self.b = assemble_system(-lhs(self.F0), rhs(self.F0))
        return
예제 #34
0
 def get_system(self, t):
     # Don't use assemble_system()! See bugs
     # <https://bitbucket.org/fenics-project/dolfin/issue/257/system_assembler-bilinear-and-linear-forms>,
     # <https://bitbucket.org/fenics-project/dolfin/issue/78/systemassembler-problem-with-subdomains-on>.
     return assemble(lhs(self.F0)), assemble(rhs(self.F0))
예제 #35
0
파일: stokes.py 프로젝트: nschloe/maelstrom
def stokes_solve(up_out, mu, u_bcs, p_bcs, f, my_dx=dx):
    # Some initial sanity checks.
    assert mu > 0.0

    WP = up_out.function_space()

    # Translate the boundary conditions into the product space.
    new_bcs = helpers.dbcs_to_productspace(WP, [u_bcs, p_bcs])

    # TODO define p*=-1 and reverse sign in the end to get symmetric system?

    # Define variational problem
    (u, p) = TrialFunctions(WP)
    (v, q) = TestFunctions(WP)

    mesh = WP.mesh()
    r = SpatialCoordinate(mesh)[0]

    # build system
    f = F(u, p, v, q, f, r, mu, my_dx)
    a = lhs(f)
    L = rhs(f)
    A, b = assemble_system(a, L, new_bcs)

    mode = "lu"

    assert mode == "lu"
    solve(A, up_out.vector(), b, "lu")

    # TODO Krylov solver for Stokes
    # assert mode == 'gmres'
    # # For preconditioners for the Stokes system, see
    # #
    # #     Fast iterative solvers for discrete Stokes equations;
    # #     J. Peters, V. Reichelt, A. Reusken.
    # #
    # prec = mu * inner(r * grad(u), grad(v)) * 2 * pi * my_dx \
    #     - p * q * 2 * pi * r * my_dx
    # P, _ = assemble_system(prec, L, new_bcs)
    # solver = KrylovSolver('tfqmr', 'hypre_amg')
    # # solver = KrylovSolver('gmres', 'hypre_amg')
    # solver.set_operators(A, P)

    # solver.parameters['monitor_convergence'] = verbose
    # solver.parameters['report'] = verbose
    # solver.parameters['absolute_tolerance'] = 0.0
    # solver.parameters['relative_tolerance'] = tol
    # solver.parameters['maximum_iterations'] = maxiter

    # # Solve
    # solver.solve(up_out.vector(), b)
    # elif mode == 'fieldsplit':
    #     # For an assortment of preconditioners, see
    #     #
    #     # Performance and analysis of saddle point preconditioners
    #     # for the discrete steady-state Navier-Stokes equations;
    #     # H.C. Elman, D.J. Silvester, A.J. Wathen;
    #     # Numer. Math. (2002) 90: 665-688;
    #     # <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.145.3554>.
    #     #
    #     # Set up field split.
    #     W = SubSpace(WP, 0)
    #     P = SubSpace(WP, 1)
    #     u_dofs = W.dofmap().dofs()
    #     p_dofs = P.dofmap().dofs()
    #     prec = PETScPreconditioner()
    #     prec.set_fieldsplit([u_dofs, p_dofs], ['u', 'p'])

    #     PETScOptions.set('pc_type', 'fieldsplit')
    #     PETScOptions.set('pc_fieldsplit_type', 'additive')
    #     PETScOptions.set('fieldsplit_u_pc_type', 'lu')
    #     PETScOptions.set('fieldsplit_p_pc_type', 'jacobi')

    #     # Create Krylov solver with custom preconditioner.
    #     solver = PETScKrylovSolver('gmres', prec)
    #     solver.set_operator(A)

    return
예제 #36
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):

    # NB: input r_vec is a position vector
    r,theta,z = cart_to_cyl(x)  # NB: check the function cart_to_cyl can take non-tuple collecs.
    return d.near(r,bzo_radius)

## Testing some differing-boundary BCs:
bzo = d.DirichletBC(V, u_bzo, bzo_boundary)
ybco = d.DirichletBC(V, u_ybco, ybco_boundary)