Пример #1
0
def PETScKrylovSolver(comm, method, preconditioner):
    try:
        out = dl.PETScKrylovSolver(comm, method, preconditioner)
    except:
        out = dl.PETScKrylovSolver(method, preconditioner)

    return out
Пример #2
0
 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())
Пример #3
0
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)
Пример #4
0
    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)
Пример #5
0
 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)
Пример #6
0
 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)
Пример #9
0
    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
Пример #10
0
    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)
Пример #11
0
 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)
Пример #12
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
Пример #13
0
    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
Пример #14
0
    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
Пример #15
0
    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
Пример #16
0
 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)
Пример #17
0
    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)
Пример #18
0
    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
Пример #19
0
    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
Пример #20
0
    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)
Пример #21
0
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
Пример #22
0
    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)
Пример #23
0
    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
Пример #24
0
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
Пример #25
0
    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
Пример #26
0
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
Пример #27
0
    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
Пример #28
0
    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_
Пример #29
0
    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)