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)
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
Exemple #3
0
 def _setup_solver(self):
     self.EMsolver = d.LinearVariationalSolver(self.EMproblem)
     self.Tsolver = d.LinearVariationalSolver(self.Tproblem)
     solver_info = return_solver(self.data)
     if solver_info is not None:
         for i in solver_info:
             self.logger.debug("Setting " +
                               str(self.EMsolver.parameters[i]) + " as " +
                               str(solver_info[i]))
             self.EMsolver.parameters[i] = solver_info[i]
             self.Tsolver.parameters[i] = solver_info[i]
    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)
    def linear_solver(self, phi_k):

        # cast params as constant functions so that, if they are set to 0, FEniCS still understand
        # what is being integrated
        mu, M = Constant(self.physics.mu), Constant(self.physics.M)
        lam = Constant(self.physics.lam)
        mn, mf = Constant(self.mn), Constant(self.mf)

        D = self.physics.D

        # boundary condition
        Dirichlet_bc = self.get_Dirichlet_bc()

        # trial and test function
        phi = d.TrialFunction(self.fem.S)
        v = d.TestFunction(self.fem.S)

        # r^(D-1)
        rD = Expression('pow(x[0],D-1)', D=D, degree=self.fem.func_degree)

        # bilinear form a and linear form L
        a = - inner( grad(phi), grad(v) ) * rD * dx + ( (mu/mn)**2  \
            - 3.*lam*(mf/mn)**2*phi_k**2 ) * phi * v * rD * dx
        L = ((mn**(D - 2.) / (mf * M)) * self.source.rho - 2. * lam *
             (mf / mn)**2 * phi_k**3) * v * rD * dx

        # define a vector with the solution
        sol = d.Function(self.fem.S)

        # solve linearised system
        pde = d.LinearVariationalProblem(a, L, sol, Dirichlet_bc)
        solver = d.LinearVariationalSolver(pde)
        solver.solve()

        return sol
Exemple #6
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):
        ?? 
Exemple #7
0
    def solve( self ):
        """
        Overrides the base-class nonlinear solver with a linear solver for the Poisson
        equation Eq. :eq:`Eq_Poisson`.
        """
        
        Dirichlet_bc = self.get_Dirichlet_bc()
        
        # trial and test function
        u = d.TrialFunction( self.fem.S )
        v = d.TestFunction( self.fem.S )
        PhiN = d.Function( self.fem.S )
        
        # define equation
        Mn, Mp = Constant( self.Mn ), Constant( self.Mp )
        r2 = Expression( 'pow(x[0],2)', degree=self.fem.func_degree )
        a = - inner( grad(u), grad(v) ) * r2 * dx
        L = 0.5 * self.source.rho * Mn / Mp**2 * v * r2 * dx
        
        # solve
        eqn = d.LinearVariationalProblem( a, L, PhiN, Dirichlet_bc )
        solver = d.LinearVariationalSolver( eqn )
        solver.solve()

        # set potential and force
        self.PhiN = PhiN
        self.Newton_force = self.grad( -PhiN, radial_units='physical' )
Exemple #8
0
    def initial_guess(self):
        r"""
        Obtains an initial guess for the Newton solver.

        This is done by solving the equation of motion for :math:`\lambda=0`, which form a linear system.
        All other parameters are unchanged.

        """

        # cast params as constant functions so that, if they are set to 0,
        # fenics still understand what it is integrating
        m, M, Mp = Constant(self.fields.m), Constant(self.fields.M), Constant(
            self.fields.Mp)
        alpha = Constant(self.fields.alpha)
        Mn, Mf1, Mf2 = Constant(self.Mn), Constant(self.Mf1), Constant(
            self.Mf2)

        # get the boundary conditions
        Dirichlet_bc = self.get_Dirichlet_bc()

        # create a vector (phi,h) with the two trial functions for the fields
        u = d.TrialFunction(self.V)
        # ... and split it into phi and h
        phi, h, y, z = d.split(u)

        # define test functions over the function space
        v1, v2, v3, v4 = d.TestFunctions(self.V)

        # r^2
        r2 = Expression('pow(x[0],2)', degree=self.fem.func_degree)

        # define bilinear form
        # Eq.1
        a1 = y * v1 * r2 * dx - ( m / Mn )**2 * phi * v1 * r2 * dx \
             - alpha * ( Mf2/Mf1 ) * z * v1 * r2 * dx

        # Eq.2
        a2 = z * v2 * r2 * dx - ( M / Mn )**2 * h * v2 * r2 * dx \
             - alpha * ( Mf1/Mf2 ) * y * v2 * r2 * dx

        a3 = -inner(grad(phi), grad(v3)) * r2 * dx - y * v3 * r2 * dx

        a4 = -inner(grad(h), grad(v4)) * r2 * dx - z * v4 * r2 * dx

        # both equations
        a = a1 + a2 + a3 + a4

        # define linear form
        L = self.source.rho / Mp * Mn / Mf1 * v1 * r2 * dx

        # define a vector with the solution
        sol = d.Function(self.V)

        # solve linearised system
        pde = d.LinearVariationalProblem(a, L, sol, Dirichlet_bc)
        solver = d.LinearVariationalSolver(pde)
        solver.solve()

        return sol
Exemple #9
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 __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)
def dTt_dolfin(T, t):
    """
    Finds dT/dt using dolfin.

    Arguments:
       T: Array representing the temperature at a specific time.
       t: Single value of time at which to find the derivative.
    Returns:
       The derivative of T with respect to t as an array.
    """

    # Convert T to dolfin function from array.
    TOld = df.Function(funcSpace)
    TOld.vector()[:] = T

    # Solve the "linear" problem to find dT/dt.

    # This 'a' represents the unknown, which contains no new information, but
    # will eventually contribute to the solution later.
    TNew = df.TrialFunction(funcSpace)
    v = df.TestFunction(funcSpace)
    a = TNew * v * df.dx

    # 'f' here represents an expression (but not a dolfin expression) which
    # describes the mathematical function that calculates dT/dt from T.
    f = TOld * df.Constant(-0.9) # df.inner(df.grad(TOld), df.grad(TOld)) # <!> Failure here?

    # This 'L' represents what we know, and will be used to calculate our
    # solution eventually.
    L = f * v
    L *= df.dx

    # This is not actually the solution, but it is where the solution will end
    # up eventually, once the solver has done its work.
    solutionEventually = df.Function(funcSpace)

    # The problem defines what we want to know, what we do know, and where to
    # put the solution. The solution argument is not actually the solution
    # (yet), but it's where the solution will end up eventually.
    problem = df.LinearVariationalProblem(a, L, solutionEventually)

    # The solver solves the problem eventually.
    solver = df.LinearVariationalSolver(problem)

    # Now we solve the problem. solutionEventually is now populated with the
    # solution to the problem.
    solver.solve()

    # Convert and return our solution.
    return solutionEventually.vector().array()
Exemple #12
0
 def _setup_solver(self):
     self.solver = d.LinearVariationalSolver(self.problem)
     solver_info = return_solver(self.data)
     if solver_info is not None:
         for i in solver_info:
             if isinstance(solver_info[i], dict):
                 for j in solver_info[i]:
                     self.logger.debug("Setting [" + str(i) + "][" +
                                       str(j) + "] as " +
                                       str(solver_info[i][j]))
                     self.solver.parameters[i][j] = solver_info[i][j]
             else:
                 self.logger.debug("Setting [" + str(i) + "] as " +
                                   str(solver_info[i]))
                 self.solver.parameters[i] = solver_info[i]
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
Exemple #14
0
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
Exemple #15
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_,
             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
Exemple #16
0
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
Exemple #17
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
Exemple #18
0
def setup_PF(w_PF, phi, g, psi, h, dx, ds, dirichlet_bcs_PF, neumann_bcs,
             boundary_to_mark, phi_1, u_1, M_, M_1, c_1, V_1, rho_1, dt,
             sigma_bar, eps, drho, dbeta, dveps, grav, enable_NS, enable_EC,
             use_iterative_solvers, **namespace):
    """ Set up phase field subproblem. """
    # Projected velocity (for energy stability)
    if enable_NS:
        u_proj = u_1  # - dt*phi_1*df.grad(g)/rho_1
        phi_adv = phi  # phi_1

    F_phi = (1. / dt * (phi - phi_1) * psi * dx +
             M_1 * df.dot(df.grad(g), df.grad(psi)) * dx)
    if enable_NS:
        F_phi += -phi_adv * df.dot(u_proj, df.grad(psi)) * dx
    F_g = (
        g * h * dx
        # - sigma_bar/eps * (phi - phi_1) * h * dx
        # Damping term (makes the system elliptic)
        - sigma_bar * eps * df.dot(df.grad(phi), df.grad(h)) * dx
        # - sigma_bar/eps * diff_pf_potential(phi_1)*h*dx
        - sigma_bar / eps * diff_pf_potential_linearised(phi, phi_1) * h * dx)
    # Add gravity
    # F_g += drho * df.dot(grav, x) * 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.grad(V_1), df.grad(V_1)) * h * dx)
    F = F_phi + F_g
    a, L = df.lhs(F), df.rhs(F)

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

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

    return solver
Exemple #19
0
def setup_EC(w_EC, c, V, b, U, rho_e, dx, ds, dirichlet_bcs_EC, neumann_bcs,
             boundary_to_mark, c_1, u_1, K_, veps_, phi_, rho_1, dt, z, dbeta,
             enable_NS, enable_PF, use_iterative_solvers, **namespace):
    """ Set up electrochemistry subproblem. """

    F_c = []
    for ci, ci_1, bi, Ki_, zi, dbetai in zip(c, c_1, b, K_, z, dbeta):
        u_proj_i = u_1  # - dt/rho_1*df.grad(ci)
        ci_adv = ci  # ci_1

        F_ci = (1. / dt * (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
            # u_proj_i += -dt/rho_1 * zi * ci_1 * df.grad(V)
        if enable_PF:
            F_ci += Ki_ * ci * dbetai * df.dot(df.nabla_grad(phi_),
                                               df.nabla_grad(bi)) * dx
            # u_proj_i += -dt/rho_1 * ci_1 * dbetai*df.grad(phi_)
        if enable_NS:
            F_ci += -ci_adv * df.dot(u_proj_i, df.nabla_grad(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
    F = sum(F_c) + F_V
    a, L = df.lhs(F), df.rhs(F)

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

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

    return solver
Exemple #20
0
    def compute_yukawa_force( self ):

        # solve an equation of motion that will give you
        # the force from a scalar without nonlinearities

        # cast params as constant functions so that, if they are set to 0, FEniCS still understand
        # what is being integrated
        mu = Constant( self.physics.mu )
        mn = Constant( self.mn )
        
        # trial and test function
        phi = d.TrialFunction( self.fem.S )
        v = d.TestFunction( self.fem.S )
        
        # boundary condition - always zero 
        phiD = d.Constant( 0. )
        # define 'infinity' boundary: the rightmost mesh point - within machine precision
        def boundary(x):
            return self.fem.mesh.r_max - x[0] < d.DOLFIN_EPS
        Dirichlet_bc = d.DirichletBC( self.fem.S, phiD, boundary, method='pointwise' )

        # r^(D-1)
        rD = Expression('pow(x[0],D-1)', D=self.physics.D, degree=self.fem.func_degree)
        
        # m^2 = 2.
        a = - inner( grad(phi), grad(v) ) * rD * dx - 2. * (mu/mn)**2 * phi * v * rD * dx
        L = mn**(self.physics.D-2.)*self.source.rho/(self.physics.M*self.mf) * v * rD * dx
        # the Yukawa potential has linear matter coupling even when
        # the symmetron has quadratic matter coupling
        
        yukawa = d.Function( self.fem.S )
        pde = d.LinearVariationalProblem( a, L, yukawa, Dirichlet_bc )
        solver = d.LinearVariationalSolver( pde )
        solver.solve()

        self.yukawa = d.Function( self.fem.S )
        self.yukawa.vector()[:] = self.mf * yukawa.vector()[:]
Exemple #21
0
def setup_S(w_S, 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 Stokes subproblem """
    F = (per_tau * rho_1 * df.dot(u - u_1, v) * dx +
         mu_ * df.inner(df.grad(u), df.grad(v)) * dx - p * df.div(v) * dx +
         q * df.div(u) * dx - rho_ * df.dot(grav, v) * dx)

    print("Linear system size", w_S.function_space().dim())

    a, L = df.system(F)
    problem = df.LinearVariationalProblem(a, L, w_S, dirichlet_bcs)
    solver = df.LinearVariationalSolver(problem)

    solver.parameters["linear_solver"] = "mumps"

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

    return solver
Exemple #22
0
    def __init__(self, gridsize=32, t_end=6, direction=1, adjoint=False):
        ## end time
        self.t_end = t_end

        self.u0_expr = dol.Expression('1 + 0.2*sin(pi*x[1])*sin(pi*x[0]/3)',
                                      degree=1)

        if adjoint:
            self.z0_expr = dol.Expression("0", degree=0)

        ## heat source term for weak formulation for Crank Nicolson, IE uses only f1
        self.f1 = dol.Expression('5*pow(t,3)', t=0, degree=2)
        self.f2 = dol.Expression('5*pow(t,3)', t=0, degree=2)

        ## Size of grid, number of cells = (2*gridsize)*gridsize*2
        self.gridsize = gridsize
        ## Mesh
        mesh = dol.RectangleMesh(dol.Point(0, 0), dol.Point(3, 1),
                                 3 * self.gridsize, self.gridsize)
        ## Function space for solution vector
        self.V = dol.FunctionSpace(mesh, "CG", 1)

        Problem_FE.__init__(self, adjoint)
        ## Function space for velocity
        V_velo = dol.VectorFunctionSpace(mesh, "CG", 2)

        ## direction of velocity
        self.direction = direction

        # create dol.Measures for relevant subdomains
        colours = dol.MeshFunction(
            "size_t", mesh,
            dim=2)  # Colouring for mesh to identify various subdomains
        colours.set_all(0)  # default colour

        # heat source
        heat_src = dol.CompiledSubDomain(
            "x[0] >= 0.25 && x[0] <= 0.75 && x[1] >= 0.25 && x[1] <= 0.75"
        )  # identify subdomain by condition
        heat_src.mark(colours, 2)  # change colour of domain
        self.dx_src = dol.Measure("dx", subdomain_data=colours)(
            2)  # define domain in the needed way for function definition

        # Area of interest
        subdom = dol.CompiledSubDomain(
            "x[0] >= 2.25 && x[0] <= 2.75 && x[1] >= 0.25 && x[1] <= 0.75")
        subdom.mark(colours, 1)  # change colour of domain
        self.dx_obs = dol.Measure("dx", subdomain_data=colours)(
            1)  # define domain in the needed way for function definition
        self.dx_cont = self.dx_obs

        ## u used in Crank Nicolson
        self.ucn = 0.5 * (self.utrial + self.uold)
        if self.direction == 1:
            self.velocity = dol.interpolate(
                dol.Expression((' 1', '0'), degree=0), V_velo)
        elif self.direction == -1:
            self.velocity = dol.interpolate(
                dol.Expression(('-1', '0'), degree=0), V_velo)
        else:
            raise ValueError('invalid advection direction, please try again')

        self.heat_cond = dol.Constant(0.01)
        self.outflow = dol.Constant(0.15)
        self.velo = dol.Constant(0.5)
        ## Variational formulation for Crank Nicolson
        F = (dol.inner(self.v, self.utrial - self.uold) * dol.dx +
             self.dt * self.heat_cond *
             dol.inner(dol.grad(self.ucn), dol.grad(self.v)) * dol.dx - 0.5 *
             self.dt * dol.inner(self.f1 + self.f2, self.v) * self.dx_src +
             self.velo * self.dt * dol.dot(dol.grad(self.ucn), self.velocity) *
             self.v * dol.dx + self.dt * self.heat_cond * self.outflow *
             dol.inner(self.ucn, self.v) * dol.ds)
        prob = dol.LinearVariationalProblem(dol.lhs(F), dol.rhs(F), self.unew)
        self.solver = dol.LinearVariationalSolver(prob)

        ## Variational formulation for Implicit Euler
        Flow = (dol.inner(self.v, self.utrial - self.uold) * dol.dx +
                self.dt * self.heat_cond *
                dol.inner(dol.grad(self.utrial), dol.grad(self.v)) * dol.dx -
                self.dt * dol.inner(self.f2, self.v) * self.dx_src +
                self.velo * self.dt * dol.dot(dol.grad(
                    self.utrial), self.velocity) * self.v * dol.dx +
                self.dt * self.heat_cond * self.outflow *
                dol.inner(self.utrial, self.v) * dol.ds)
        problow = dol.LinearVariationalProblem(dol.lhs(Flow), dol.rhs(Flow),
                                               self.ulow)
        self.solver_low = dol.LinearVariationalSolver(problow)

        if adjoint:
            adj_src = dol.Function(self.V)
            adj_src.interpolate(dol.Constant(1 / self.t_end))

            self.src_weight = dol.Expression(
                "((0.25 < x[0]) and (0.75 > x[0]) and (0.25 < x[1]) and (0.75 > x[1]))? 1 : 0",
                degree=0)

            class LeftBoundary(dol.SubDomain):
                def inside(self, x, on_boundary):
                    return on_boundary and dol.near(x[0], 0)

            class RightBoundary(dol.SubDomain):
                def inside(self, x, on_boundary):
                    return on_boundary and dol.near(x[0], 3)

            left = LeftBoundary()
            right = RightBoundary()

            boundaries = dol.MeshFunction("size_t", mesh, dim=1)
            boundaries.set_all(0)
            left.mark(boundaries, 1)
            right.mark(boundaries, 3)

            ds_self = dol.Measure('ds', domain=mesh, subdomain_data=boundaries)
            zcn = 0.5 * (self.ztrial + self.zold)

            Fadj = (dol.inner(self.ztrial - self.zold, self.v) * dol.dx -
                    self.dt * self.heat_cond *
                    dol.inner(dol.grad(zcn), dol.grad(self.v)) * dol.dx +
                    self.dt * dol.inner(adj_src, self.v) * self.dx_obs +
                    self.direction * self.dt * self.velo *
                    dol.dot(self.velocity, dol.grad(zcn)) * self.v * dol.dx -
                    self.velo * self.dt * dol.inner(zcn, self.v) * ds_self(1) -
                    self.velo * self.dt * dol.inner(zcn, self.v) * ds_self(3) -
                    self.outflow * self.heat_cond * self.dt *
                    dol.inner(zcn, self.v) * dol.ds)
            probadj = dol.LinearVariationalProblem(dol.lhs(Fadj),
                                                   dol.rhs(Fadj), self.znew)
            self.solver_adj = dol.LinearVariationalSolver(probadj)
Exemple #23
0
    n = df.FacetNormal(mesh)

    chi = df.TrialFunction(S)
    chi_ = df.Function(S, name="chi")
    psi = df.TestFunction(S)

    ds = df.Measure("ds", domain=mesh, subdomain_data=subd)

    F_chi = (n[0]*psi*ds(1)
             + df.inner(df.grad(chi), df.grad(psi))*df.dx)

    a_chi, L_chi = df.lhs(F_chi), df.rhs(F_chi)

    problem_chi2 = df.LinearVariationalProblem(a_chi, L_chi, chi_, bcs=[])
    solver_chi2 = df.LinearVariationalSolver(problem_chi2)
    solver_chi2.parameters["krylov_solver"]["absolute_tolerance"] = 1e-15

    solver_chi2.solve()

    with df.XDMFFile(mesh.mpi_comm(),
                     "chi_Pe0_b{}.xdmf".format(b)) as xdmff:
        xdmff.write(chi_)
    
    integral = (2*df.assemble(chi_.dx(0)*df.dx)/V_Omega
                + df.assemble(df.inner(df.grad(chi_),
                                       df.grad(chi_))*df.dx)/V_Omega)

    if rank == 0:
        print("b = {}, D_eff/D = {}".format(b, 1+integral))
Exemple #24
0
    def step(self, t0: float, t1: float) -> None:
        """Solve on the given time interval (t0, t1).

        Arguments:
            interval (:py:class:`tuple`)
                The time interval (t0, t1) for the step

        *Invariants*
            Assuming that v\_ is in the correct state for t0, gives
            self.vur in correct state at t1.
        """
        timer = df.Timer("PDE step")

        # Extract theta and conductivities
        theta = self._parameters["theta"]
        Mi = self._M_i
        Me = self._M_e

        # Extract interval and thus time-step
        kn = df.Constant(t1 - t0)

        # Define variational formulation
        if self._parameters["linear_solver_type"] == "direct":
            v, u, l = df.TrialFunctions(self.VUR)
            w, q, lamda = df.TestFunctions(self.VUR)
        else:
            v, u = df.TrialFunctions(self.VUR)
            w, q = df.TestFunctions(self.VUR)

        # Get physical parameters
        chi = self._parameters["Chi"]
        capacitance = self._parameters["Cm"]

        Dt_v = (v - self.v_) / kn
        Dt_v *= chi * capacitance
        v_mid = theta * v + (1.0 - theta) * self.v_

        # Set time
        t = t0 + theta * (t1 - t0)
        self.time.assign(t)

        # Define spatial integration domains:
        dz = df.Measure("dx",
                        domain=self._mesh,
                        subdomain_data=self._cell_domains)
        db = df.Measure("ds",
                        domain=self._mesh,
                        subdomain_data=self._facet_domains)

        # Get domain labels
        cell_tags = map(int, set(
            self._cell_domains.array()))  # np.int64 does not workv
        facet_tags = map(int, set(self._facet_domains.array()))

        # Loop overe all domain labels
        G = Dt_v * w * dz()
        for key in cell_tags:
            G += df.inner(Mi[key] * df.grad(v_mid), df.grad(w)) * dz(key)
            G += df.inner(Mi[key] * df.grad(u), df.grad(w)) * dz(key)
            G += df.inner(Mi[key] * df.grad(v_mid), df.grad(q)) * dz(key)
            G += df.inner(
                (Mi[key] + Me[key]) * df.grad(u), df.grad(q)) * dz(key)

            if self._I_s is None:
                G -= chi * df.Constant(0) * w * dz(key)
            else:
                # _is = self._I_s.get(key, df.Constant(0))
                # G -= chi*_is*w*dz(key)
                G -= chi * self._I_s[key] * w * dz(key)

            # If Lagrangian multiplier
            if self._parameters["linear_solver_type"] == "direct":
                G += (lamda * u + l * q) * dz(key)

            # Add applied current as source in elliptic equation if applicable
            if self._I_a:
                G -= chi * self._I_a[key] * q * dz(key)

        if self._ect_current is not None:
            for key in facet_tags:
                # Detfalt to 0 if not defined for that facet tag
                # TODO: Should I include `chi` here? I do not think so
                G += self._ect_current.get(key, df.Constant(0)) * q * db(key)

        # Define variational problem
        a, L = df.system(G)
        pde = df.LinearVariationalProblem(a, L, self.vur, bcs=self._bcs)

        # Set-up solver
        solver = df.LinearVariationalSolver(pde)
        solver.solve()
Exemple #25
0
def setup_EC(w_EC, c, V, V0, b, U, U0,
             rho_e, grad_g_c, c_reg, g_c,
             dx, ds, normal,
             dirichlet_bcs_EC, neumann_bcs, boundary_to_mark,
             c_1, u_1, K, veps,
             rho_, rho_1,
             dt,
             enable_NS,
             solutes,
             use_iterative_solvers,
             nonlinear_EC,
             V_lagrange, p_lagrange,
             q_rhs,
             reactions,
             beta,
             **namespace):
    """ Set up electrochemistry subproblem. """
    if enable_NS:
        # Projected velocity
        u_star = u_1 - dt/rho_1*sum([ci_1*grad_g_ci
                                     for ci_1, grad_g_ci
                                     in zip(c_1, grad_g_c)])

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

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

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

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

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

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

    return solver
def test_scipy_uprime_integration_with_fenics():

    NB_OF_CELLS_X = NB_OF_CELLS_Y = 2
    mesh = df.UnitSquare(NB_OF_CELLS_X, NB_OF_CELLS_Y)
    V = df.FunctionSpace(mesh, 'CG', 1)

    f = df.Expression("cos(t)",t=0)
    uprime = df.TrialFunction(V)
    uprev = df.interpolate(f,V)
    v = df.TestFunction(V)

    #ODE is du/dt= uprime = cos(t), exact solution is u(t)=sin(t)

    a = uprime*v*dx 
    L = f*v*dx

    uprime_solution = df.Function(V)
    uprime_problem  = df.LinearVariationalProblem(a, L, uprime_solution)
    uprime_solver   = df.LinearVariationalSolver(uprime_problem)

    def rhs_fenics(y,t):
        """A somewhat strange case where the right hand side is constant
        and thus we don't need to use the information in y."""
        #print "time: ",t
        uprev.vector()[:]=y
        f.t = t #dolfin needs to know the current time for cos(t)
        uprime_solver.solve()
        return uprime_solution.vector().array() 

    def rhs(y,t):
        """
        dy/dt = f(y,t) with y(0)=1
        dy/dt = -2y -> solution y(t) = c * exp(-2*t)"""
        return math.cos(t)

    T_MAX=2
    ts = numpy.arange(0,T_MAX+0.1,0.5)
    ysfenics=scipy.integrate.odeint(rhs_fenics, uprev.vector().array(), ts)

    def exact(t,y0=1):
        return y0*numpy.sin(t)

    print "With fenics:"
    err_abs = abs(ysfenics[-1][0]-exact(ts[-1])) #use value at mesh done 0 for check
    print "Error: abs=%g, rel=%g, y_exact=%g" % (err_abs,err_abs/exact(ts[-1]),exact(ts[-1]))
    fenics_error=err_abs


    print "Without fenics:"
    ys = scipy.integrate.odeint(rhs, 1, ts)

    err_abs = abs(ys[-1]-exact(ts[-1]))
    print "Error: abs=%g, rel=%g, y_exact=%g" % (err_abs,err_abs/exact(ts[-1]),exact(ts[-1]))

    non_fenics_error = float(err_abs)


    print("Difference between fenics and non-fenics calculation: %g" % abs(fenics_error-non_fenics_error))
    assert abs(fenics_error-non_fenics_error)<7e-15

    #should also check that solution is the same on all mesh points
    for i in range(ysfenics.shape[0]): #for all result rows
        #each row contains the data at all mesh points for one t in ts
        row = ysfenics[i,:]
        number_range = abs(row.min()-row.max())
        print "row: %d, time %f, range %g" % (i,ts[i],number_range)
        assert number_range < 16e-15

    #for debugging
    if False:
        from IPython.Shell import IPShellEmbed
        ipshell = IPShellEmbed()
        ipshell()

    if False:
            import pylab
            pylab.plot(ts,ys,'o')
            pylab.plot(ts,numpy.exp(-2*ts),'-')
            pylab.show()
Exemple #27
0
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
mu = dolfin.Constant(E/2./(1.+nu))
lambda_ = dolfin.Constant(E*nu/(1.+nu)/(1.-2.*nu))

def strain_displacement(u):
    return dolfin.sym(dolfin.grad(u))

def stress_strain(eps):
    return lambda_*dolfin.tr(eps)*I2+2*mu*eps

bilinear_form = dolfin.inner(stress_strain(strain_displacement(u_trial)),
                             strain_displacement(v))*dolfin.dx

traction = dolfin.Expression(('x[0] < x_right ? 0.0 : -12.*M/d/d/d*x[1]', '0.0'),
                             x_right=ell-atol, M=1.0, d=d, degree=degree)

linear_form = dolfin.dot(traction, v)*dolfin.ds

u_prescribed = dolfin.Constant((0., 0.))
boundary_condition_left = dolfin.DirichletBC(V, u_prescribed, left)
boundary_conditions = [boundary_condition_left]

problem = dolfin.LinearVariationalProblem(bilinear_form, linear_form, u, boundary_conditions)

solver = dolfin.LinearVariationalSolver(problem)
solver.solve()

dolfin.plot(u/u.vector().max(),mode="displacement")
plt.savefig("u.png")

with dolfin.XDMFFile(mesh.mpi_comm(), "output/u.xdmf") as file:
        file.write(u,  0)
    def _setup_problem(self):
        """
        Method setting up solver objects of the stationary problem.
        """
        assert hasattr(self, "_mesh")
        assert hasattr(self, "_boundary_markers")

        self._setup_function_spaces()
        self._setup_boundary_conditions()

        # creating test function
        self._v = dlfn.TestFunction(self._Vh)
        self._u = dlfn.TrialFunction(self._Vh)

        # solution
        self._solution = dlfn.Function(self._Vh)

        # volume element
        self._dV = dlfn.Measure("dx", domain=self._mesh)
        self._dA = dlfn.Measure("ds",
                                domain=self._mesh,
                                subdomain_data=self._boundary_markers)

        # setup the parameters for the elastic law
        self._elastic_law.set_parameters(self._mesh, self._C)

        # virtual work
        if self._elastic_law.linearity_type == "Linear":
            self._dw_int = self._elastic_law.dw_int(self._u,
                                                    self._v) * self._dV
        elif self._elastic_law.linearity_type == "Nonlinear":
            self._dw_int = self._elastic_law.dw_int(self._solution,
                                                    self._v) * self._dV

        # virtual work of external forces
        self._dw_ext = dlfn.dot(self._null_vector, self._v) * self._dV

        # add body force term
        if hasattr(self, "_body_force"):
            assert hasattr(self, "_D"), "Dimensionless parameter related to" + \
                                        "the body forces is not specified."
            self._dw_ext += self._D * dot(self._body_force, self._v) * self._dV

        # add boundary tractions
        if hasattr(self, "_traction_bcs"):
            for bc in self._traction_bcs:
                # unpack values
                if len(bc) == 3:
                    bc_type, bndry_id, traction = bc
                elif len(bc) == 4:
                    bc_type, bndry_id, component_index, traction = bc

                if bc_type is TractionBCType.constant:
                    assert isinstance(traction, (tuple, list))
                    const_function = dlfn.Constant(traction)
                    self._dw_ext += dot(const_function,
                                        self._v) * self._dA(bndry_id)

                elif bc_type is TractionBCType.constant_component:
                    assert isinstance(traction, float)
                    const_function = dlfn.Constant(traction)
                    self._dw_ext += const_function * self._v[
                        component_index] * self._dA(bndry_id)

                elif bc_type is TractionBCType.function:
                    assert isinstance(traction, dlfn.Expression)
                    self._dw_ext += dot(traction, self._v) * self._dA(bndry_id)

                elif bc_type is TractionBCType.function_component:
                    assert isinstance(traction, dlfn.Expression)
                    self._dw_ext += traction * self._v[
                        component_index] * self._dA(bndry_id)

        if self._elastic_law.linearity_type == "Linear":
            # linear variational problem
            self._problem = dlfn.LinearVariationalProblem(
                self._dw_int, self._dw_ext, self._solution,
                self._dirichlet_bcs)
            # setup linear variational solver
            self._solver = dlfn.LinearVariationalSolver(self._problem)
        elif self._elastic_law.linearity_type == "Nonlinear":
            self._Form = self._dw_int - self._dw_ext
            self._J_newton = dlfn.derivative(self._Form, self._solution)
            self._problem = dlfn.NonlinearVariationalProblem(
                self._Form,
                self._solution,
                self._dirichlet_bcs,
                J=self._J_newton)
            # setup linear variational solver
            self._solver = dlfn.NonlinearVariationalSolver(self._problem)
Exemple #30
0
    - half / dt * dot(v00, del_v) *  dV
#==============================================================================
pvd_velocity = dlfn.File("results_{1}/Re_{0:d}/solution_velocity_Re_{0:d}.pvd".\
                     format(int(reynolds), "FEniCS"))
pvd_pressure = dlfn.File("results_{1}/Re_{0:d}/solution_pressure_Re_{0:d}.pvd".\
                     format(int(reynolds), "FEniCS"))
#==============================================================================
# time loop
dlfn.tic()
t = 0.
cnt = 0
n_steps = 5000
t_end = 80.
while t < t_end:  #and cnt <= n_steps:
    problem = dlfn.LinearVariationalProblem(lhs, rhs, sol, bcs=bcs)
    solver = dlfn.LinearVariationalSolver(problem)
    solver.solve()
    v, p = sol.split()
    if cnt % 3200 == 0:
        print "t = {0:6.4f}".format(t)
        pvd_velocity << (v, t)
        pvd_pressure << (p, t)
    cd, cl = integrateFluidStress(v, p, nu, space_dim)
    drag_coeff_list.append(cd)
    lift_coeff_list.append(cl)
    iter_list.append(cnt)
    t_dim = t * t_ref
    t_list.append(t_dim)
    # update for next iteration
    sol00.assign(sol0)
    sol0.assign(sol)