Example #1
0
class ElasticitySolver:
    """docstring for ElasticitySolver"""
    def __init__(self, energy, state, bcs, parameters={}):
        super(ElasticitySolver, self).__init__()
        solver_name = 'elasticity'
        self.problem = ElasticityProblem(energy, state, bcs)
        # Set the solver
        self.solver = PETScSNESSolver()
        snes = self.solver.snes()

        prefix = "elasticity_"
        snes.setOptionsPrefix(prefix)
        print(parameters)
        for parameter, value in parameters.items():
            log(LogLevel.DEBUG,
                "DEBUG: Set: {} = {}".format(prefix + parameter, value))
            PETScOptions.set(prefix + parameter, value)

        snes.setFromOptions()

    def solve(self):
        log(LogLevel.INFO,
            '________________________ EQUILIBRIUM _________________________')
        log(LogLevel.INFO, 'Solving elasticity')
        problem = self.problem

        u = problem.state["u"].vector()
        self.solver.solve(problem, u)
        return (self.solver.snes().getIterationNumber(),
                self.solver.snes().getConvergedReason())
    def set_solver(self):
        solver = PETScSNESSolver()
        snes = solver.snes()
        snes.setType("newtontr")
        ksp = snes.getKSP()
        ksp.setType("preonly")
        pc = ksp.getPC()
        pc.setType("lu")
        snes_solver_parameters = {
            # "linear_solver": "lu",
            "linear_solver": "umfpack",
            # "linear_solver": "mumps",
            "maximum_iterations": 300,
            "report": True,
            # "monitor": True,
            "line_search": "basic",
            "method": "newtonls",
            "absolute_tolerance": 1e-5,
            "relative_tolerance": 1e-5,
            "solution_tolerance": 1e-5
        }

        solver.parameters.update(snes_solver_parameters)
        info(solver.parameters, True)
        # import pdb; pdb.set_trace()
        return solver
Example #3
0
 def __init__(self, problem):
     PETScSNESSolver.__init__(self)
     self.problem = problem
     # =========== PETScSNESSolver::init() workaround for assembled matrices =========== #
     # Make sure to use a matrix with proper sparsity pattern if matrix_eval returns a matrix (rather than a Form)
     if isinstance(self.problem.jacobian_form_or_eval,
                   (types.FunctionType, types.MethodType)):
         jacobian_form_or_matrix = self.problem.jacobian_form_or_eval(
             self.problem.block_solution)
         if isinstance(jacobian_form_or_matrix, GenericBlockMatrix):
             jacobian_matrix = as_backend_type(
                 jacobian_form_or_matrix).mat().duplicate()
             self.snes().setJacobian(None, jacobian_matrix)
Example #4
0
    def __init__(self, problem, parameters={}, lb=None):
        super(DamageSolverSNES, self).__init__()
        self.problem = problem
        self.energy = problem.energy
        self.state = problem.state
        self.alpha = problem.state['alpha']
        self.alpha_dvec = as_backend_type(self.alpha.vector())
        self.alpha_pvec = self.alpha_dvec.vec()

        self.bcs = problem.bcs
        self.parameters = parameters
        comm = self.alpha.function_space().mesh().mpi_comm()
        self.comm = comm
        V = self.alpha.function_space()
        self.V = V
        self.Ealpha = derivative(
            self.energy, self.alpha,
            dolfin.TestFunction(self.alpha.ufl_function_space()))
        self.dm = self.alpha.function_space().dofmap()
        solver = PETScSNESSolver()
        snes = solver.snes()

        if lb == None:
            lb = interpolate(Constant(0.), V)
        ub = interpolate(Constant(1.), V)

        prefix = "damage_"
        snes.setOptionsPrefix(prefix)
        for option, value in self.parameters["snes"].items():
            PETScOptions.set(prefix + option, value)
            log(LogLevel.DEBUG,
                "DEBUG: Set: {} = {}".format(prefix + option, value))

        snes.setFromOptions()

        (J, F, bcs_alpha) = (problem.J, problem.F, problem.bcs)
        self.ass = SystemAssembler(J, F, bcs_alpha)
        self.b = self.init_residual()
        snes.setFunction(self.residual, self.b.vec())
        self.A = self.init_jacobian()
        snes.setJacobian(self.jacobian, self.A.mat())
        snes.ksp.setOperators(self.A.mat())

        snes.setVariableBounds(self.problem.lb.vec(), self.problem.ub.vec())  #

        # snes.solve(None, Function(V).vector().vec())

        self.solver = snes
Example #5
0
    def __init__(self, energy, state, bcs, parameters={}):
        super(ElasticitySolver, self).__init__()
        solver_name = 'elasticity'
        self.problem = ElasticityProblem(energy, state, bcs)
        # Set the solver
        self.solver = PETScSNESSolver()
        snes = self.solver.snes()

        prefix = "elasticity_"
        snes.setOptionsPrefix(prefix)
        print(parameters)
        for parameter, value in parameters.items():
            log(LogLevel.DEBUG,
                "DEBUG: Set: {} = {}".format(prefix + parameter, value))
            PETScOptions.set(prefix + parameter, value)

        snes.setFromOptions()
    def set_solver_u(self):
        for option, value in self.parameters["solver_u"].items():
            print("setting ", option, value)
            PETScOptions.set(option, value)
        solver = PETScSNESSolver()
        snes = solver.snes()
        snes.setOptionsPrefix("u_")
        snes.setType(self.parameters["solver_u"]["u_snes_type"])
        ksp = snes.getKSP()
        ksp.setType("preonly")
        pc = ksp.getPC()
        pc.setType("lu")

        # Namespace mismatch between petsc4py 3.7 and 3.9.
        if hasattr(pc, 'setFactorSolverType'):
            pc.setFactorSolverType("mumps")
        elif hasattr(pc, 'setFactorSolverPackage'):
            pc.setFactorSolverPackage('mumps')
        else:
            ColorPrint.print_warn('Could not configure preconditioner')
        solver.set_from_options()
        snes.setFromOptions()
        self.solver_u = solver
 def solve(self):
     PETScSNESSolver.solve(self, self.problem,
                           self.problem.block_solution.block_vector())
     # Keep subfunctions up to date
     self.problem.block_solution.apply("to subfunctions")
 def __init__(self, problem):
     PETScSNESSolver.__init__(self)
     self.problem = problem
Example #9
0
def solve(mesh, W_element, P_element, Q_element, u0, p0, theta0, kappa, rho,
          mu, cp, g, extra_force, heat_source, u_bcs, p_bcs,
          theta_dirichlet_bcs, theta_neumann_bcs, dx_submesh, ds_submesh):
    # First do a fixed_point iteration. This is usually quite robust and leads
    # to a point from where Newton can converge reliably.
    u0, p0, theta0 = solve_fixed_point(mesh,
                                       W_element,
                                       P_element,
                                       Q_element,
                                       theta0,
                                       kappa,
                                       rho,
                                       mu,
                                       cp,
                                       g,
                                       extra_force,
                                       heat_source,
                                       u_bcs,
                                       p_bcs,
                                       theta_dirichlet_bcs,
                                       theta_neumann_bcs,
                                       my_dx=dx_submesh,
                                       my_ds=ds_submesh,
                                       max_iter=100,
                                       tol=1.0e-8)

    WPQ = FunctionSpace(mesh, MixedElement([W_element, P_element, Q_element]))
    uptheta0 = Function(WPQ)

    # Initial guess
    assign(uptheta0.sub(0), u0)
    assign(uptheta0.sub(1), p0)
    assign(uptheta0.sub(2), theta0)

    rho_const = rho(_average(theta0))

    stokes_heat_problem = StokesHeat(WPQ,
                                     kappa,
                                     rho,
                                     rho_const,
                                     mu,
                                     cp,
                                     g,
                                     extra_force,
                                     heat_source,
                                     u_bcs,
                                     p_bcs,
                                     theta_dirichlet_bcs=theta_dirichlet_bcs,
                                     theta_neumann_bcs=theta_neumann_bcs,
                                     my_dx=dx_submesh,
                                     my_ds=ds_submesh)

    # solver = FixedPointSolver()
    from dolfin import PETScSNESSolver
    solver = PETScSNESSolver()
    # http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/SNES/SNESType.html
    solver.parameters['method'] = 'newtonls'
    # The Jacobian system for Stokes (+heat) are hard to solve.
    # Use LU for now.
    solver.parameters['linear_solver'] = 'lu'
    solver.parameters['maximum_iterations'] = 100
    # TODO tighten tolerance. might not always work though...
    solver.parameters['absolute_tolerance'] = 1.0e-3
    solver.parameters['relative_tolerance'] = 0.0
    solver.parameters['report'] = True

    solver.solve(stokes_heat_problem, uptheta0.vector())

    # u0, p0, theta0 = split(uptheta0)
    # Create a *deep* copy of u0, p0, theta0 to be able to deal with them
    # as actually separate entities vectors.
    u0, p0, theta0 = uptheta0.split(deepcopy=True)
    return u0, p0, theta0
 def solve(self):
     no_iterations, convergence_flag = PETScSNESSolver.solve(
         self, self.problem, self.problem.block_solution.block_vector())
     # Keep subfunctions up to date
     self.problem.block_solution.apply("to subfunctions")
     return no_iterations, convergence_flag
Example #11
0
def solve(
        mesh,
        W_element, P_element, Q_element,
        u0, p0, theta0,
        kappa, rho, mu, cp,
        g, extra_force,
        heat_source,
        u_bcs, p_bcs,
        theta_dirichlet_bcs,
        theta_neumann_bcs,
        dx_submesh, ds_submesh
        ):
    # First do a fixed_point iteration. This is usually quite robust and leads
    # to a point from where Newton can converge reliably.
    u0, p0, theta0 = solve_fixed_point(
        mesh,
        W_element, P_element, Q_element,
        theta0,
        kappa, rho, mu, cp,
        g, extra_force,
        heat_source,
        u_bcs, p_bcs,
        theta_dirichlet_bcs,
        theta_neumann_bcs,
        my_dx=dx_submesh,
        my_ds=ds_submesh,
        max_iter=100,
        tol=1.0e-8
        )

    WPQ = FunctionSpace(
        mesh, MixedElement([W_element, P_element, Q_element])
        )
    uptheta0 = Function(WPQ)

    # Initial guess
    assign(uptheta0.sub(0), u0)
    assign(uptheta0.sub(1), p0)
    assign(uptheta0.sub(2), theta0)

    rho_const = rho(_average(theta0))

    stokes_heat_problem = StokesHeat(
        WPQ,
        kappa, rho, rho_const, mu, cp,
        g, extra_force,
        heat_source,
        u_bcs, p_bcs,
        theta_dirichlet_bcs=theta_dirichlet_bcs,
        theta_neumann_bcs=theta_neumann_bcs,
        my_dx=dx_submesh,
        my_ds=ds_submesh
        )

    # solver = FixedPointSolver()
    from dolfin import PETScSNESSolver
    solver = PETScSNESSolver()
    # http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/SNES/SNESType.html
    solver.parameters['method'] = 'newtonls'
    # The Jacobian system for Stokes (+heat) are hard to solve.
    # Use LU for now.
    solver.parameters['linear_solver'] = 'lu'
    solver.parameters['maximum_iterations'] = 100
    # TODO tighten tolerance. might not always work though...
    solver.parameters['absolute_tolerance'] = 1.0e-3
    solver.parameters['relative_tolerance'] = 0.0
    solver.parameters['report'] = True

    solver.solve(stokes_heat_problem, uptheta0.vector())

    # u0, p0, theta0 = split(uptheta0)
    # Create a *deep* copy of u0, p0, theta0 to be able to deal with them
    # as actually separate entities vectors.
    u0, p0, theta0 = uptheta0.split(deepcopy=True)
    return u0, p0, theta0