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