def PETScKrylovSolver(comm, method, preconditioner): try: out = dl.PETScKrylovSolver(comm, method, preconditioner) except: out = dl.PETScKrylovSolver(method, preconditioner) return out
def _createLUSolver(self): if dlversion() <= (1, 6, 0): # return dl.PETScLUSolver() return dl.PETScKrylovSolver("cg", amg_method()) else: # return dl.PETScLUSolver(self.Vh[STATE].mesh().mpi_comm()) return dl.PETScKrylovSolver(self.Vh[STATE].mesh().mpi_comm(), "cg", amg_method())
def test2(): """ Test what Krylov solver are completely deterministic """ mesh = dl.UnitSquareMesh(40, 40) Vm = dl.FunctionSpace(mesh, 'CG', 1) x1 = dl.Function(Vm) x2 = dl.Function(Vm) rhs = dl.Function(Vm) #regul = LaplacianPrior({'Vm':Vm, 'gamma':1e-4, 'beta':1e-4}) regul = TVPD({'Vm': Vm, 'k': 1e-4, 'eps': 1e-3}) precond = 'ml_amg' for ii in range(1): rhs.vector()[:] = (ii + 1.0) * np.random.randn( rhs.vector().local_size()) regul.assemble_hessian(rhs) solver1 = dl.PETScKrylovSolver('cg', precond) solver1.parameters["maximum_iterations"] = 1000 solver1.parameters["relative_tolerance"] = 1e-24 solver1.parameters["absolute_tolerance"] = 1e-24 solver1.parameters["error_on_nonconvergence"] = True solver1.parameters["nonzero_initial_guess"] = False #solver1 = dl.PETScLUSolver() solver1.set_operator(regul.precond) iter1 = solver1.solve(x1.vector(), rhs.vector()) x1n = x1.vector().norm('l2') solver2 = dl.PETScKrylovSolver('cg', precond) solver2.parameters["maximum_iterations"] = 1000 solver2.parameters["relative_tolerance"] = 1e-24 solver2.parameters["absolute_tolerance"] = 1e-24 solver2.parameters["error_on_nonconvergence"] = True solver2.parameters["nonzero_initial_guess"] = False #solver2 = dl.PETScLUSolver() solver2.set_operator(regul.precond) iter2 = solver2.solve(x2.vector(), rhs.vector()) diffn = (x1.vector() - x2.vector()).norm('l2') print '|x1|={}, |diff|={}'.format(x1n, diffn) print 'iter={}, diff_iter={}'.format(iter1, np.abs(iter1 - iter2)) solver3 = dl.PETScKrylovSolver('cg', 'petsc_amg') solver3.parameters["maximum_iterations"] = 1000 solver3.parameters["relative_tolerance"] = 1e-24 solver3.parameters["absolute_tolerance"] = 1e-24 solver3.parameters["error_on_nonconvergence"] = True solver3.parameters["nonzero_initial_guess"] = False solver3.set_operator(regul.precond) iter3 = solver3.solve(x2.vector(), rhs.vector()) x3n = x2.vector().norm('l2') diffn = (x1.vector() - x2.vector()).norm('l2') print '|x3|={}, |diff|={}, iter3={}'.format(x3n, diffn, iter3)
def setUp(self): mesh = dl.UnitSquareMesh(10, 10) self.mpi_rank = dl.MPI.rank(mesh.mpi_comm()) self.mpi_size = dl.MPI.size(mesh.mpi_comm()) Vh1 = dl.FunctionSpace(mesh, 'Lagrange', 1) uh, vh = dl.TrialFunction(Vh1), dl.TestFunction(Vh1) mh, test_mh = dl.TrialFunction(Vh1), dl.TestFunction(Vh1) ## Set up B ndim = 2 ntargets = 200 np.random.seed(seed=1) targets = np.random.uniform(0.1, 0.9, [ntargets, ndim]) B = assemblePointwiseObservation(Vh1, targets) ## Set up Asolver alpha = dl.Constant(1.0) varfA = dl.inner(dl.grad(uh), dl.grad(vh))*dl.dx +\ alpha*dl.inner(uh,vh)*dl.dx A = dl.assemble(varfA) Asolver = dl.PETScKrylovSolver(A.mpi_comm(), "cg", amg_method()) Asolver.set_operator(A) Asolver.parameters["maximum_iterations"] = 100 Asolver.parameters["relative_tolerance"] = 1e-12 ## Set up C varfC = dl.inner(mh, vh) * dl.dx C = dl.assemble(varfC) self.Hop = Hop(B, Asolver, C) ## Set up RHS Matrix M. varfM = dl.inner(mh, test_mh) * dl.dx self.M = dl.assemble(varfM) self.Minv = dl.PETScKrylovSolver(self.M.mpi_comm(), "cg", amg_method()) self.Minv.set_operator(self.M) self.Minv.parameters["maximum_iterations"] = 100 self.Minv.parameters["relative_tolerance"] = 1e-12 myRandom = Random(self.mpi_rank, self.mpi_size) x_vec = dl.Vector(mesh.mpi_comm()) self.Hop.init_vector(x_vec, 1) k_evec = 10 p_evec = 50 self.Omega = MultiVector(x_vec, k_evec + p_evec) self.k_evec = k_evec myRandom.normal(1., self.Omega)
def solveAdjIncremental(self, sol, rhs, tol): """ Solve the incremental adjoint problem for a given rhs """ if dlversion() <= (1, 6, 0): solver = dl.PETScKrylovSolver("cg", amg_method()) else: solver = dl.PETScKrylovSolver(self.mesh.mpi_comm(), "cg", amg_method()) solver.set_operator(self.At) solver.parameters["relative_tolerance"] = tol self.At.init_vector(sol, 1) nit = solver.solve(sol, rhs)
def solveFwd(self, out, x, tol=1e-9): """ Solve the forward problem. """ A, b = self.assembleA(x, assemble_rhs=True) A.init_vector(out, 1) if dlversion() <= (1, 6, 0): solver = dl.PETScKrylovSolver("cg", amg_method()) else: solver = dl.PETScKrylovSolver(self.mesh.mpi_comm(), "cg", amg_method()) solver.parameters["relative_tolerance"] = tol solver.set_operator(A) nit = solver.solve(out, b)
def solveAdj(self, out, x, tol=1e-9): """ Solve the adjoint problem. """ At, badj = self.assembleA(x, assemble_adjoint=True, assemble_rhs=True) At.init_vector(out, 1) if dlversion() <= (1, 6, 0): solver = dl.PETScKrylovSolver("cg", amg_method()) else: solver = dl.PETScKrylovSolver(self.mesh.mpi_comm(), "cg", amg_method()) solver.parameters["relative_tolerance"] = tol solver.set_operator(At) solver.solve(out, badj)
def __init__(self, Vh, sigma2, mean=None, max_iter=100, rel_tol=1e-9): self.sigma2 = sigma2 trial = dl.TrialFunction(Vh) test = dl.TestFunction(Vh) varfM = dl.inner(trial, test) * dl.dx self.M = dl.assemble(varfM) self.M.zero() self.M.ident_zeros() self.Rm = dl.assemble(varfM) self.Rm.zero() sigma2inv_vector = dl.Vector() self.Rm.init_vector(sigma2inv_vector, 0) sigma2inv_vector[:] = np.power(sigma2, -1) self.Rm.set_diagonal(sigma2inv_vector) self.Ai = dl.assemble(varfM) self.Ai.zero() sigma_vector = dl.Vector() self.Ai.init_vector(sigma_vector, 0) sigma_vector[:] = np.sqrt(sigma2) self.Ai.set_diagonal(sigma_vector) self.Msolver = dl.PETScKrylovSolver("cg", "jacobi") self.Msolver.set_operator(self.M) self.Msolver.parameters["maximum_iterations"] = max_iter self.Msolver.parameters["relative_tolerance"] = rel_tol self.Msolver.parameters["error_on_nonconvergence"] = True self.Msolver.parameters["nonzero_initial_guess"] = False self.Rsolver = dl.PETScKrylovSolver("cg", "jacobi") self.Rsolver.set_operator(self.Rm) self.Rsolver.parameters["maximum_iterations"] = max_iter self.Rsolver.parameters["relative_tolerance"] = rel_tol self.Rsolver.parameters["error_on_nonconvergence"] = True self.Rsolver.parameters["nonzero_initial_guess"] = False if mean is None: self.mean = dl.Vector() self.init_vector(self.mean, 0) else: self.mean = mean.copy() self.R = FiniteDimensionalGaussianR(self.Rm)
def searchdirection(self, MG, cgtol): """ Compute search direction """ self.Regul.assemble_hessian(self.u) if self.Regul.isPD(): H = self.Hess + self.Regul.Hrs * self.alpha #H = self.Hess + self.Regul.H*self.alpha else: H = self.Hess + self.Regul.H * self.alpha if True: solver = dl.PETScKrylovSolver("cg", self.precond) solver.parameters['nonzero_initial_guess'] = False solver.parameters['relative_tolerance'] = cgtol solver.set_operator(H) cgiter = solver.solve(self.du.vector(), -1.0 * MG) else: solver = CGSolverSteihaug() solver.set_operator(H) solver.set_preconditioner(self.Regul.getprecond()) solver.parameters["rel_tolerance"] = cgtol solver.parameters["zero_initial_guess"] = True solver.parameters["print_level"] = -1 solver.solve(self.du.vector(), -1.0 * MG) cgiter = solver.iter MGdu = MG.inner(self.du.vector()) if MGdu > 0.0: print "*** WARNING: NOT a descent direction" return cgiter, MGdu
def __init__(self, Vh, simulation_time, dt, init_vectors, subdmn_path = './subdomains/', mesh_tag = 'mesh_5h', qoi_type='state', reset_exposed = True, save = False, save_days = True, out_path = './fwd_result/'): self.Vh = Vh self.init_vectors = init_vectors self.dt = dt self._save = save self._reset_exposed = reset_exposed self._qoi_type = qoi_type self._save_days = save_days if not simulation_time.is_integer(): raise ValueError("The total simulation time is should be a whole number.") else: self.T = round(simulation_time) self.nt = round(self.T/self.dt) if not self.nt*self.dt == self.T: raise ValueError("t = 1, 2, ... cannot be reached with the given time step.") self.out_freq = round(1./dt) _linear_solver = dl.PETScKrylovSolver("gmres", "ilu") _linear_solver.parameters["nonzero_initial_guess"] = True self._solver = picard_solver(_linear_solver) self.problem = seird_forms(Vh, dt, save, out_path, subdmn_path, mesh_tag, qoi_type) self.u_0 = self.generate_pde_state() self.u = self.generate_pde_state() self.u_ic = self.generate_pde_state() self._set_initial_conditions(self.u_ic)
def __init__(self,V,sigma=1.25,s=0.0625,mean=None,rel_tol=1e-10,max_iter=100,**kwargs): self.V=V self.dim=V.dim() self.dof_coords=get_dof_coords(V) self.sigma=sigma self.s=s self.mean=mean self.mpi_comm=kwargs['mpi_comm'] if 'mpi_comm' in kwargs else df.mpi_comm_world() # mass matrix and its inverse M_form=df.inner(df.TrialFunction(V),df.TestFunction(V))*df.dx self.M=df.PETScMatrix() df.assemble(M_form,tensor=self.M) self.Msolver = df.PETScKrylovSolver("cg", "jacobi") self.Msolver.set_operator(self.M) self.Msolver.parameters["maximum_iterations"] = max_iter self.Msolver.parameters["relative_tolerance"] = rel_tol self.Msolver.parameters["error_on_nonconvergence"] = True self.Msolver.parameters["nonzero_initial_guess"] = False # square root of mass matrix self.rtM=self._get_rtmass() # kernel matrix and its square root self.K=self._get_ker() self.rtK = _get_sqrtm(self.K,'K') # set solvers for op in ['K']: operator=getattr(self, op) solver=self._set_solver(operator,op) setattr(self, op+'solver', solver) if mean is None: self.mean=df.Vector() self.init_vector(self.mean,0)
def _create_linear_solver(self) -> None: """Helper function for creating linear solver based on parameters.""" solver_type = self._parameters["linear_solver_type"] if solver_type == "direct": solver = df.LUSolver(self._lhs_matrix) elif solver_type == "iterative": # Initialize KrylovSolver with matrix alg = self._parameters["algorithm"] prec = self._parameters["preconditioner"] solver = df.PETScKrylovSolver(alg, prec) solver.set_operator(self._lhs_matrix) solver.parameters["nonzero_initial_guess"] = True # Important! A = df.as_backend_type(self._lhs_matrix) A.set_nullspace(self.nullspace) else: df.error( "Unknown linear_solver_type given: {}".format(solver_type)) return solver
def __init__(self, simulation, u_conv): """ Given a velocity in DG, e.g DG2, produce a velocity in DGT0, i.e. a constant on each facet """ V = u_conv[0].function_space() V_dgt0 = dolfin.FunctionSpace(V.mesh(), 'DGT', 0) u = dolfin.TrialFunction(V_dgt0) v = dolfin.TestFunction(V_dgt0) ndim = simulation.ndim w = u_conv w_new = dolfin.as_vector( [dolfin.Function(V_dgt0) for _ in range(ndim)]) dot, avg, dS, ds = dolfin.dot, dolfin.avg, dolfin.dS, dolfin.ds a = dot(avg(u), avg(v)) * dS + dot(u, v) * ds L = [] for d in range(ndim): L.append(avg(w[d]) * avg(v) * dS + w[d] * v * ds) self.lhs = [dolfin.Form(Li) for Li in L] self.A = dolfin.assemble(a) self.solver = dolfin.PETScKrylovSolver('cg') self.velocity = simulation.data['u_conv_dgt0'] = w_new
def __init__(self, mesh, Vh, prior): """ Construct a model by proving - the mesh - the finite element spaces for the STATE/ADJOINT variable and the PARAMETER variable - the prior information """ self.mesh = mesh self.Vh = Vh # Initialize Expressions mtrue_exp = dl.Expression( 'std::log(2 + 7*(std::pow(std::pow(x[0] - 0.5,2) + std::pow(x[1] - 0.5,2),0.5) > 0.2))', element=Vh[PARAMETER].ufl_element()) self.mtrue = dl.interpolate(mtrue_exp, self.Vh[PARAMETER]).vector() self.f = dl.Constant(1.0) self.u_o = dl.Vector() self.u_bdr = dl.Constant(0.0) self.u_bdr0 = dl.Constant(0.0) self.bc = dl.DirichletBC(self.Vh[STATE], self.u_bdr, u_boundary) self.bc0 = dl.DirichletBC(self.Vh[STATE], self.u_bdr0, u_boundary) # Assemble constant matrices self.prior = prior self.Wuu = self.assembleWuu() self.computeObservation(self.u_o) self.A = None self.At = None self.C = None self.Wmm = None self.Wmu = None self.gauss_newton_approx = False self.solver = dl.PETScKrylovSolver(mesh.mpi_comm(), "cg", amg_method()) self.solver_fwd_inc = dl.PETScKrylovSolver(mesh.mpi_comm(), "cg", amg_method()) self.solver_adj_inc = dl.PETScKrylovSolver(mesh.mpi_comm(), "cg", amg_method()) self.solver.parameters["relative_tolerance"] = 1e-15 self.solver.parameters["absolute_tolerance"] = 1e-20 self.solver_fwd_inc.parameters = self.solver.parameters self.solver_adj_inc.parameters = self.solver.parameters
def __init__(self, simulation, input_path, params): """ Wrap a PETScKrylov solver that is configured through petsc4py """ self.simulation = simulation self._input_path = input_path self._config_params = params self.is_first_solve = True self.is_iterative = True self.is_direct = False # Create the solver prefix = 'sol_%s_' % input_path.split('/')[-1] self._solver = dolfin.PETScKrylovSolver() # Help is treated specially, this is used to enquire about PETSc capabilities request_petsc_help = 'petsc_help' in params if request_petsc_help: params.pop('petsc_help') # Translate the petsc_* keys to the correct solver prefix # and insert them into the PETSc options database for param, value in sorted(params.items()): if not param.startswith('petsc_'): continue # Citations are treated specially, does not work with prefix if param == 'petsc_citations': option = 'citations' else: option = prefix + param[6:] simulation.log.info(' %-50s: %20r' % (option, value)) # Some options do not have a value, but we must have one on the input # file, the below translation fixes that if value == 'ENABLED': dolfin.PETScOptions.set(option) elif value == 'DISABLED': pass else: # Normal option with value dolfin.PETScOptions.set(option, value) if request_petsc_help: simulation.log.warning('PETSc help coming up') simulation.log.warning('-' * 80) dolfin.PETScOptions.set('help') # Configure the solver self._solver.set_options_prefix(prefix) self._solver.ksp().setFromOptions() if request_petsc_help: simulation.log.warning('-' * 80) simulation.log.warning('Showing PETSc help done, exiting') exit() # Only used when calling the basic .solve() method self.reuse_precon = False
def solveFwdIncremental(self, sol, rhs, tol): """ Solve the incremental forward problem for a given rhs """ solver = dl.PETScKrylovSolver("cg", amg_method()) solver.set_operator(self.A) solver.parameters["relative_tolerance"] = tol self.A.init_vector(sol, 1) nit = solver.solve(sol, rhs)
def solveAdj(self, out, x, tol=1e-9): """ Solve the adjoint problem. """ At, badj = self.assembleA(x, assemble_adjoint=True, assemble_rhs=True) At.init_vector(out, 1) solver = dl.PETScKrylovSolver("cg", amg_method()) solver.parameters["relative_tolerance"] = tol solver.set_operator(At) nit = solver.solve(out, badj)
def get_solver(self, **kwargs): # solver=df.PETScLUSolver(self.prior.mpi_comm,self._as_petscmat(),'mumps' if df.has_lu_solver_method('mumps') else 'default') # # solver.set_operator(self._as_petscmat()) # # solver.parameters['reuse_factorization']=True # # solver.parameters['symmetric']=True preconditioner = kwargs.pop('preconditioner', None) if preconditioner: solver = df.PETScKrylovSolver("default", "default") solver.set_operators(self, preconditioner) else: solver = df.PETScKrylovSolver( "cg", "none") # very slow without proper preconditioner solver.set_operator(self) solver.parameters["maximum_iterations"] = 1000 solver.parameters["relative_tolerance"] = 1e-7 solver.parameters["error_on_nonconvergence"] = True solver.parameters["nonzero_initial_guess"] = False return solver
def __init__(self, u, boundary_is_streamline=False, degree=1): """ Heavily based on https://github.com/mikaem/fenicstools/blob/master/fenicstools/Streamfunctions.py Stream function for a given general 2D velocity field. The boundary conditions are weakly imposed through the term inner(q, grad(psi)*n)*ds, where grad(psi) = [-v, u] is set on all boundaries. This should work for any collection of boundaries: walls, inlets, outlets etc. """ Vu = u[0].function_space() mesh = Vu.mesh() # Check dimension if not mesh.geometry().dim() == 2: df.error("Stream-function can only be computed in 2D.") # Define the weak form V = df.FunctionSpace(mesh, 'CG', degree) q = df.TestFunction(V) psi = df.TrialFunction(V) n = df.FacetNormal(mesh) a = df.dot(df.grad(q), df.grad(psi)) * df.dx L = df.dot(q, df.curl(u)) * df.dx if boundary_is_streamline: # Strongly set psi = 0 on entire domain boundary self.bcs = [df.DirichletBC(V, df.Constant(0), df.DomainBoundary())] self.normalize = False else: self.bcs = [] self.normalize = True L = L + q * (n[1] * u[0] - n[0] * u[1]) * df.ds # Create preconditioned iterative solver solver = df.PETScKrylovSolver('gmres', 'hypre_amg') solver.parameters['nonzero_initial_guess'] = True solver.parameters['relative_tolerance'] = 1e-10 solver.parameters['absolute_tolerance'] = 1e-10 # Store for later computation self.psi = df.Function(V) self.A = df.assemble(a) self.L = L self.mesh = mesh self.solver = solver self._triangulation = None
def setUp(self): mesh = dl.UnitSquareMesh(10, 10) self.mpi_rank = dl.MPI.rank(mesh.mpi_comm()) self.mpi_size = dl.MPI.size(mesh.mpi_comm()) Vh1 = dl.FunctionSpace(mesh, 'Lagrange', 1) uh, vh = dl.TrialFunction(Vh1), dl.TestFunction(Vh1) mh = dl.TrialFunction(Vh1) # Define B ndim = 2 ntargets = 10 np.random.seed(seed=1) targets = np.random.uniform(0.1, 0.9, [ntargets, ndim]) B = assemblePointwiseObservation(Vh1, targets) # Define Asolver alpha = dl.Constant(0.1) varfA = dl.inner(dl.nabla_grad(uh), dl.nabla_grad(vh))*dl.dx +\ alpha*dl.inner(uh,vh)*dl.dx A = dl.assemble(varfA) Asolver = dl.PETScKrylovSolver(A.mpi_comm(), "cg", amg_method()) Asolver.set_operator(A) Asolver.parameters["maximum_iterations"] = 100 Asolver.parameters["relative_tolerance"] = 1e-12 # Define M varfC = dl.inner(mh, vh) * dl.dx C = dl.assemble(varfC) self.J = J_op(B, Asolver, C) self.k_evec = 10 p_evec = 50 myRandom = Random(self.mpi_rank, self.mpi_size) x_vec = dl.Vector(C.mpi_comm()) C.init_vector(x_vec, 1) self.Omega = MultiVector(x_vec, self.k_evec + p_evec) myRandom.normal(1., self.Omega) y_vec = dl.Vector(C.mpi_comm()) B.init_vector(y_vec, 0) self.Omega_adj = MultiVector(y_vec, self.k_evec + p_evec) myRandom.normal(1., self.Omega_adj)
def make_fenics_amg_solver(A_petsc): prec = dl.PETScPreconditioner('hypre_amg') dl.PETScOptions.set('pc_hypre_boomeramg_relax_type_coarse', 'jacobi') solver = dl.PETScKrylovSolver('cg', prec) solver.set_operator(A_petsc) def solve_A(b_petsc, atol=0.0, rtol=1e-10, maxiter=100, verbose=False): x_petsc = dl.Vector(b_petsc) solver.parameters['absolute_tolerance'] = atol solver.parameters['relative_tolerance'] = rtol solver.parameters['maximum_iterations'] = maxiter solver.parameters['monitor_convergence'] = verbose solver.solve(x_petsc, b_petsc) return x_petsc return solve_A
def solvetikhonov(self): print '\t{:12s} {:12s} {:12s} {:12s} {:12s} {:12s}'.format(\ 'iter', 'cost', 'misfit', 'reg', 'medmisfit', 'n_cg') self.u.vector().zero() MG, MGnorm = self.gradient() H = self.Hess + self.Regul.R * self.alpha solver = dl.PETScKrylovSolver("cg", "petsc_amg") solver.set_operator(H) cgiter = solver.solve(self.u.vector(), -MG) cost, misfit, reg = self.costmisfitreg() print '{:12s} {:12.4e} {:12.4e} {:12.4e} {:12.4e} {:12d}'.format(\ '', cost, misfit, reg, self.mediummisfit(), cgiter)
def __init__(self, solver_method, preconditioner=None, lu_method=None, parameters=None): """ Wrap a DOLFIN PETScKrylovSolver or PETScLUSolver You must either specify solver_method = 'lu' and give the name of the solver, e.g lu_solver='mumps' or give a valid Krylov solver name, eg. solver_method='minres' and give the name of a preconditioner, eg. preconditioner_name='hypre_amg'. The parameters argument is a *list* of dictionaries which are to be used as parameters to the Krylov solver. Settings in the first dictionary in this list will be (potentially) overwritten by settings in later dictionaries. The use case is to provide sane defaults as well as allow the user to override the defaults in the input file The reason for this wrapper is to provide easy querying of iterative/direct and not crash when set_reuse_preconditioner is run before the first solve. This simplifies usage """ self.solver_method = solver_method self.preconditioner = preconditioner self.lu_method = lu_method self.input_parameters = parameters self.is_first_solve = True self.is_iterative = False self.is_direct = False if solver_method.lower() == 'lu': solver = dolfin.PETScLUSolver(lu_method) self.is_direct = True else: precon = dolfin.PETScPreconditioner(preconditioner) solver = dolfin.PETScKrylovSolver(solver_method, precon) self._pre_obj = precon # Keep from going out of scope self.is_iterative = True for parameter_set in parameters: apply_settings(solver_method, solver.parameters, parameter_set) self._solver = solver
def solve_krylov( a, L, bcs, u: df.Function, verbose: bool = False, ksp_type="cg", ksp_norm_type="unpreconditioned", ksp_atol=1e-15, ksp_rtol=1e-10, ksp_max_it=10000, ksp_error_if_not_converged=False, pc_type="hypre", ) -> df.PETScKrylovSolver: pc_hypre_type = "boomeramg" ksp_monitor = verbose ksp_view = verbose pc_view = verbose solver = df.PETScKrylovSolver() df.PETScOptions.set("ksp_type", ksp_type) df.PETScOptions.set("ksp_norm_type", ksp_norm_type) df.PETScOptions.set("ksp_atol", ksp_atol) df.PETScOptions.set("ksp_rtol", ksp_rtol) df.PETScOptions.set("ksp_max_it", ksp_max_it) df.PETScOptions.set("ksp_error_if_not_converged", ksp_error_if_not_converged) if ksp_monitor: df.PETScOptions.set("ksp_monitor") if ksp_view: df.PETScOptions.set("ksp_view") df.PETScOptions.set("pc_type", pc_type) df.PETScOptions.set("pc_hypre_type", pc_hypre_type) if pc_view: df.PETScOptions.set("pc_view") solver.set_from_options() A, b = df.assemble_system(a, L, bcs) solver.set_operator(A) solver.solve(u.vector(), b) df.info("Sucessfully solved using Krylov solver") return solver
def _create_linear_solver(self): """Helper function for creating linear solver based on parameters.""" solver_type = self._parameters.linear_solver_type if solver_type == "direct": solver = df.LUSolver(self._lhs_matrix) elif solver_type == "iterative": alg = self._parameters.krylov_method prec = self._parameters.krylov_preconditioner solver = df.PETScKrylovSolver(alg, prec) solver.set_operator(self._lhs_matrix) solver.parameters["nonzero_initial_guess"] = True A = df.as_backend_type(self._lhs_matrix) A.set_nullspace(self._nullspace()) else: msg = "Unknown solver type. Got {}, expected 'iterative' or 'direct'".format(solver_type) raise ValueError(msg) return solver
def create_linear_solver( lhs_matrix, parameters: CoupledMonodomainParameters ) -> Union[df.LUSolver, df.KrylovSolver]: """helper function for creating linear solver.""" solver_type = parameters.linear_solver_type # direct or iterative if solver_type == "direct": solver = df.LUSolver(lhs_matrix, parameters.lu_type) solver.parameters["symmetric"] = True elif solver_type == "iterative": method = parameters.krylov_method preconditioner = parameters.krylov_preconditioner solver = df.PETScKrylovSolver(method, preconditioner) solver.set_operator(lhs_matrix) solver.parameters["nonzero_initial_guess"] = True solver.ksp().setFromOptions() # TODO: What is this? else: raise ValueError(f"Unknown linear_solver_type given: {solver_type}") return solver
def _create_linear_solver(self) -> tp.Union[df.KrylovSolver, df.LUSolver]: """Helper function for creating linear solver based on parameters.""" solver_type = self.parameters["linear_solver_type"] if solver_type == "direct": solver = df.LUSolver(self._lhs_matrix, self.parameters["lu_type"]) solver.parameters["symmetric"] = True elif solver_type == "iterative": # Preassemble preconditioner (will be updated if time-step changes) # Initialize KrylovSolver with matrix and preconditioner alg = self.parameters["algorithm"] prec = self.parameters["preconditioner"] solver = df.PETScKrylovSolver(alg, prec) solver.set_operator(self._lhs_matrix) solver.parameters["nonzero_initial_guess"] = True solver.parameters["monitor_convergence"] = True solver.ksp().setFromOptions() else: raise TypeError( "Unknown linear_solver_type given: {}".format(solver_type)) return solver
def __init__(self, V, element='CG', degree=1): self.V = V self.solver = df.PETScKrylovSolver('cg', 'hypre_amg') self.solver.parameters['absolute_tolerance'] = 1e-14 self.solver.parameters['relative_tolerance'] = 1e-12 self.solver.parameters['maximum_iterations'] = 1000 self.solver.parameters['nonzero_initial_guess'] = True # cell = V.mesh().ufl_cell() # W = df.VectorElement("Lagrange", cell, 1) W = df.VectorFunctionSpace(V.mesh(), element, degree) # V = FiniteElement("Lagrange", cell, 1) self.W = W E = df.TrialFunction(W) E_ = df.TestFunction(W) # phi = Coefficient(V) self.a = df.inner(E, E_) * df.dx self.A = df.assemble(self.a) self.E_ = E_
def __init__(self, mesh, Vh, t_init, t_final, t_1, dt, wind_velocity, gls_stab, Prior): self.mesh = mesh self.Vh = Vh self.t_init = t_init self.t_final = t_final self.t_1 = t_1 self.dt = dt self.sim_times = np.arange(self.t_init, self.t_final + .5 * self.dt, self.dt) u = dl.TrialFunction(Vh[STATE]) v = dl.TestFunction(Vh[STATE]) kappa = dl.Constant(.001) dt_expr = dl.Constant(self.dt) r_trial = u + dt_expr * (-dl.div(kappa * dl.nabla_grad(u)) + dl.inner(wind_velocity, dl.nabla_grad(u))) r_test = v + dt_expr * (-dl.div(kappa * dl.nabla_grad(v)) + dl.inner(wind_velocity, dl.nabla_grad(v))) h = dl.CellSize(mesh) vnorm = dl.sqrt(dl.inner(wind_velocity, wind_velocity)) if gls_stab: tau = dl.Min((h * h) / (dl.Constant(2.) * kappa), h / vnorm) else: tau = dl.Constant(0.) self.M = dl.assemble(dl.inner(u, v) * dl.dx) self.M_stab = dl.assemble(dl.inner(u, v + tau * r_test) * dl.dx) self.Mt_stab = dl.assemble(dl.inner(u + tau * r_trial, v) * dl.dx) Nvarf = (dl.inner(kappa * dl.nabla_grad(u), dl.nabla_grad(v)) + dl.inner(wind_velocity, dl.nabla_grad(u)) * v) * dl.dx Ntvarf = (dl.inner(kappa * dl.nabla_grad(v), dl.nabla_grad(u)) + dl.inner(wind_velocity, dl.nabla_grad(v)) * u) * dl.dx self.N = dl.assemble(Nvarf) self.Nt = dl.assemble(Ntvarf) stab = dl.assemble(tau * dl.inner(r_trial, r_test) * dl.dx) self.L = self.M + dt * self.N + stab self.Lt = self.M + dt * self.Nt + stab boundaries = dl.FacetFunction("size_t", mesh) boundaries.set_all(0) class InsideBoundary(dl.SubDomain): def inside(self, x, on_boundary): x_in = x[0] > dl.DOLFIN_EPS and x[0] < 1 - dl.DOLFIN_EPS y_in = x[1] > dl.DOLFIN_EPS and x[1] < 1 - dl.DOLFIN_EPS return on_boundary and x_in and y_in Gamma_M = InsideBoundary() Gamma_M.mark(boundaries, 1) ds_marked = dl.Measure("ds")[boundaries] self.Q = dl.assemble(self.dt * dl.inner(u, v) * ds_marked(1)) self.Prior = Prior self.solver = dl.PETScKrylovSolver("gmres", "ilu") self.solver.set_operator(self.L) self.solvert = dl.PETScKrylovSolver("gmres", "ilu") self.solvert.set_operator(self.Lt) self.ud = self.generate_vector(STATE) self.noise_variance = 0
def solve(self, J, grad, H, m): rtol = self.parameters["rel_tolerance"] atol = self.parameters["abs_tolerance"] gdm_tol = self.parameters["gdm_tolerance"] max_iter = self.parameters["max_iter"] c_armijo = self.parameters["c_armijo"] max_backtrack = self.parameters["max_backtracking_iter"] prt_level = self.parameters["print_level"] cg_coarse_tol = self.parameters["cg_coarse_tolerance"] Jn = dl.assemble( J(m) ) gn = dl.assemble( grad(m) ) g0_norm = gn.norm("l2") gn_norm = g0_norm tol = max(g0_norm*rtol, atol) dm = dl.Vector() self.converged = False self.reason = 0 if prt_level > 0: print( "{0:>3} {1:>15} {2:>15} {3:>15} {4:>15} {5:>15} {6:>7}".format( "It", "Energy", "||g||", "(g,du)", "alpha", "tol_cg", "cg_it") ) for self.it in range(max_iter): Hn = dl.assemble( H(m) ) Hn.init_vector(dm,1) solver = dl.PETScKrylovSolver("cg", "petsc_amg") solver.set_operator(Hn) solver.parameters["nonzero_initial_guess"] = False cg_tol = min(cg_coarse_tol, math.sqrt( gn_norm/g0_norm) ) solver.parameters["relative_tolerance"] = cg_tol lin_it = solver.solve(dm,-gn) self.total_cg_iter += lin_it dm_gn = dm.inner(gn) if(-dm_gn < gdm_tol): self.converged=True self.reason = 3 break m_backtrack = m.copy(deepcopy=True) alpha = 1. bk_converged = False #Backtrack for j in range(max_backtrack): m.assign(m_backtrack) m.vector().axpy(alpha, dm) Jnext = dl.assemble( J(m) ) if Jnext < Jn + alpha*c_armijo*dm_gn: Jn = Jnext bk_converged = True break alpha = alpha/2. if not bk_converged: self.reason = 2 break gn = dl.assemble( grad(m) ) gn_norm = gn.norm("l2") if prt_level > 0: print( "{0:3d} {1:15e} {2:15e} {3:15e} {4:15e} {5:15e} {6:7d}".format( self.it, Jn, gn_norm, dm_gn, alpha, cg_tol, lin_it) ) if gn_norm < tol: self.converged = True self.reason = 1 break self.final_grad_norm = gn_norm if prt_level > -1: print( self.termination_reasons[self.reason] ) if self.converged: print( "Inexact Newton CG converged in ", self.it, \ "nonlinear iterations and ", self.total_cg_iter, "linear iterations." ) else: print( "Inexact Newton CG did NOT converge after ", self.it, \ "nonlinear iterations and ", self.total_cg_iter, "linear iterations.") print ("Final norm of the gradient", self.final_grad_norm) print ("Value of the cost functional", Jn)