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)
예제 #2
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 __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)
예제 #4
0
    def setupSolver(self):
        if type(self.f) == type([]):
            self.n = len(self.f)
            if type(d.lhs(self.f[0]).integrals()[0].integrand()) == type(
                    UFL.constantvalue.Zero()
            ):  # Not particularly elegant. Should check for another solution.
                self.rank = 1
            else:
                self.rank = 2
        else:
            self.n = 1
            if type(d.lhs(self.f).integrals()[0].integrand()) == type(
                    UFL.constantvalue.Zero()
            ):  # Not particularly elegant. Should check for another solution.
                self.rank = 1
            else:
                self.rank = 2

        # Set appropriate solver
        if self.rank == 2:
            d.info("Using LU-solver to solve linear systems.")
            self.linear = True
            self.solver = d.LUSolver()
        else:
            d.info("Using Newton-solver to solve nonlinear systems.")
            self.linear = False
            self.solver = d.NewtonSolver()
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
예제 #6
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)
예제 #7
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
예제 #8
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
    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
예제 #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 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
예제 #12
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]
예제 #13
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
예제 #14
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())
예제 #15
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
예제 #16
0
 def create_lhs(self):
     self.a = self.create_a()
     if self.stab_enable == True:
         if self.stab_type == 'cip':
             self.a += self.apply_stabilization()
         elif self.stab_type == 'gls':
             self.a += df.lhs(self.apply_stabilization())
예제 #17
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
예제 #18
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)
예제 #19
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))
예제 #20
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)
예제 #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
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
예제 #23
0
    def lhs(self):
        """
        Constructs the LHS matrix (spatial components), AA of the eigenvalue problem.
        """
        lhs_matrix = dolf.PETScMatrix()
        lhs_forms = -self.forms._lhs_forms() - self.forms._rhs_forms(
            shift=self.complex_shift)
        lhs_matrix = dolf.assemble(dolf.lhs(lhs_forms), tensor=lhs_matrix)
        for bc in self.forms.dirichlet_boundary_conditions(is_linearised=True):
            bc.apply(lhs_matrix)

        return lhs_matrix.mat()
예제 #24
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
예제 #25
0
def lhs(form):
    """
    Wrapper for the DOLFIN lhs function. Correctly handles QForm s.
    """

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

    nform = dolfin.lhs(form)
    if isinstance(form, QForm):
        return QForm(nform, quadrature_degree = form_quadrature_degree(form))
    else:
        return nform
예제 #26
0
 def initialize_solver(self, form, bcs, solver_type="mumps"):
     """
     Performs solver initialization and matrix factorization is stored.
     As discussed at https://fenicsproject.org/docs/dolfin/dev/python/demos/elastodynamics/demo_elastodynamics.py.html:
     'Since the system matrix to solve is the same for each time step (constant time step), 
     it is not necessary to factorize the system at each increment. It can be done once and 
     for all and only perform assembly of the varying right-hand side and backsubstitution 
     to obtain the solution much more efficiently. 
     This is done by defining a LUSolver object while PETSc handles caching factorizations.'
     """
     self.bilinear_form = dolf.assemble(dolf.lhs(form))
     for bc in bcs:
         bc.apply(self.bilinear_form)
     self.LUSolver = dolf.LUSolver(self.bilinear_form, solver_type)
 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
예제 #28
0
 def assemble_lui_stiffness(self, g, f, mesh, robin_boundary):
     V = FunctionSpace(mesh, "Lagrange", self.p)
     u = TrialFunction(V)
     v = TestFunction(V)
     n = FacetNormal(mesh)
     robin = MeshFunction('size_t', mesh, mesh.topology().dim() - 1)
     robin_boundary.mark(robin, 1)
     ds = Measure('ds', subdomain_data=robin)
     a = inner(grad(u), grad(v)) * dx
     b = (1 - g) * (inner(grad(u), n)) * v * ds(1)
     c = f * u * v * ds(1)
     k = lhs(a + b - c)
     K = PETScMatrix()
     assemble(k, tensor=K)
     return K, V
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
예제 #30
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
예제 #31
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]
예제 #32
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
예제 #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
파일: 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
예제 #35
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))
예제 #36
0
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):

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