示例#1
0
    def __init__(self, A, solver=default_solver, parameters={}):
        from PyTrilinos import Epetra, Amesos
        from dolfin import info
        from time import time
        self.A = A  # Keep reference
        T = time()
        self.problem = Epetra.LinearProblem()
        self.problem.SetOperator(A.down_cast().mat())
        self.solver = Amesos.Factory().Create(solver, self.problem)
        if (self.solver == None):
            raise RuntimeError('Failed to create Amesos solver: ' + solver)

        # This prevents a use-after-free crash for the MPI communicator. It
        # enforces that the solver is destroyed before A.
        self.solver.A = A

        self.solver.SetParameters(parameters)
        if self.solver is None:
            raise RuntimeError("Unknown solver '%s'" % solver)
        err = self.solver.SymbolicFactorization()
        if err != 0:
            raise RuntimeError("Amesos " + solver +
                               " symbolic factorization failed, err=%d" % err)
        err = self.solver.NumericFactorization()
        if err != 0:
            raise RuntimeError("Amesos " + solver +
                               " numeric factorization failed, err=%d" % err)
        info('constructed direct solver (using %s) in %.2f s' %
             (solver, time() - T))
示例#2
0
    def __init__(self,
                 tolerance=1e-10,
                 iterations=10,
                 precon=None,
                 maxIterations=10):
        """
        :Parameters:
          - `tolerance`: The required error tolerance.
          - `iterations`: The maximum number of iterative steps to perform.

        """

        iterations = min(iterations, maxIterations)

        TrilinosSolver.__init__(self,
                                tolerance=tolerance,
                                iterations=iterations,
                                precon=None)

        if precon is not None:
            import warnings
            warnings.warn(
                "Trilinos KLU solver does not accept preconditioners.",
                UserWarning,
                stacklevel=2)
        self.Factory = Amesos.Factory()
示例#3
0
def solve_direct(A, rhs, x=None):
    if x is None:
        x = Epetra.Vector(A.RangeMap())

    problem = Epetra.LinearProblem(A, x, rhs)
    solver = Amesos.Klu(problem)
    ierr = solver.Solve()
    assert (ierr == 0), ierr

    return x
示例#4
0
 def query(which=None):
     """Return list of available solver backends, or True/False if given a solver name"""
     from PyTrilinos import Amesos
     factory = Amesos.Factory()
     if which is None:
         avail = []
         for s in serial_solvers + parallel_solvers:
             if factory.Query(s):
                 avail.append(s)
         return avail
     return factory.Query(which)
示例#5
0
    def direct_solve(self, jac, rhs):
        '''Currently unused direct solver that was used for testing.'''

        A = Epetra.CrsMatrix(Epetra.Copy, self.map, 27)
        for i in range(len(jac.begA)-1):
            if i == self.dim:
                A[i, i] = -1
                continue
            for j in range(jac.begA[i], jac.begA[i+1]):
                if jac.jcoA[j] != self.dim:
                    A[i, jac.jcoA[j]] = jac.coA[j]
        A.FillComplete()

        rhs[self.dim] = 0
        x = Vector(rhs)

        problem = Epetra.LinearProblem(A, x, rhs)
        factory = Amesos.Factory()
        solver = factory.Create('Klu', problem)
        solver.SymbolicFactorization()
        solver.NumericFactorization()
        solver.Solve()

        return x
示例#6
0
    def __init__(self, ckt):
        # Init base class
        _NLFunction.__init__(self)

        # Save ckt instance
        self.ckt = ckt
        # Make sure circuit is ready (analysis should take care)
        assert ckt.nD_ref

        # Allocate matrices/vectors
        # Create Epetra CrsMatrix: need communicator and map
        comm = Epetra.SerialComm()
        # Map: numelem, base index, communicator
        map = Epetra.Map(self.ckt.nD_dimension, 0, comm)
        # TODO: Find a good estimate for nnzRow
        nnzRow = min(10, self.ckt.nD_dimension)
        # G here is G1 = G + G0 in documentation
        self.G = Epetra.CrsMatrix(Epetra.Copy, map, nnzRow)
        # Jac is (G1 + di/dv) in doc
        self.Jac = Epetra.CrsMatrix(Epetra.Copy, map, nnzRow)
        # Allocate several vectors
        self.xVec = Epetra.Vector(map)
        self.iVec = Epetra.Vector(map)
        self.sVec = Epetra.Vector(map)
        self.errVec = Epetra.Vector(map)
        self.deltaxVec = Epetra.Vector(map)

        if hasattr(self.ckt, 'nD_namRClist'):
            # Allocate external currents vector
            self.extSVec = np.empty(self.ckt.nD_dimension)

        # Generate G and Jac sparse matrices
        # ----------------------------------
        self._get_Gnz()
        self.Jacnz = [([], []) for i in xrange(self.ckt.nD_dimension)]

        # Insert linear contributions into G and Jac (to fix structure)
        for row, data in enumerate(self.Gnz):
            self.G.InsertGlobalValues(row, *data)
            self.Jac.InsertGlobalValues(row, *data)

        # Finalize G (which should not change any more unless parameter sweep)
        assert not self.G.FillComplete()
        assert not self.G.OptimizeStorage()

        # Add nonlinear contribution to Jac. Insert ones for now as the
        # matrix values will be discarded anyway.
        for elem in self.ckt.nD_nlinElem:
            outJac = np.ones((len(elem.csOutPorts), len(elem.controlPorts)),
                             dtype=float)
            set_Jac(self.Jacnz, elem.nD_cpos, elem.nD_cneg, elem.nD_vpos,
                    elem.nD_vneg, outJac)

        for row, data in enumerate(self.Jacnz):
            self.Jac.InsertGlobalValues(row, *data)

        # Finalize and symbolically factor Jac
        assert not self.Jac.FillComplete()
        assert not self.Jac.OptimizeStorage()

        # Create pytrilinos solver
        problem = Epetra.LinearProblem(self.Jac, self.deltaxVec, self.errVec)
        factory = Amesos.Factory()
        self.solver = factory.Create("Klu", problem)
        assert not self.solver.SymbolicFactorization()
示例#7
0
    def run_solver(self, interpolation_method):
        """Run solver."""
        self.interpolation_method = interpolation_method
        t0 = time.time()
        n_vertex = len(set(self.mesh_data.all_nodes) - self.dirichlet_nodes)
        print("interpolation runing...")
        self.get_nodes_weights(interpolation_method)
        print(
            "done interpolation...",
            "took {0} seconds to interpolate over {1} verts".format(
                time.time() - t0, n_vertex
            ),
        )
        print("filling the transmissibility matrix...")
        begin = time.time()

        try:
            for volume in self.volumes:
                volume_id = self.mb.tag_get_data(self.global_id_tag, volume)[
                    0
                ][0]
                RHS = self.mb.tag_get_data(self.source_tag, volume)[0][0]
                self.Q[volume_id] += RHS
                # self.Q[volume_id, 0] += RHS
        except Exception:
            pass

        for face in self.neumann_faces:
            face_flow = self.mb.tag_get_data(self.neumann_tag, face)[0][0]
            volume = self.mtu.get_bridge_adjacencies(face, 2, 3)
            volume = np.asarray(volume, dtype="uint64")
            id_volume = self.mb.tag_get_data(self.global_id_tag, volume)[0][0]
            face_nodes = self.mtu.get_bridge_adjacencies(face, 0, 0)
            node_crds = self.mb.get_coords(face_nodes).reshape([3, 3])
            face_area = geo._area_vector(node_crds, norma=True)
            RHS = face_flow * face_area
            self.Q[id_volume] += -RHS
            # self.Q[id_volume, 0] += - RHS

        id_volumes = []
        all_LHS = []
        for face in self.dirichlet_faces:
            # '2' argument was initially '0' but it's incorrect
            I, J, K = self.mtu.get_bridge_adjacencies(face, 2, 0)

            left_volume = np.asarray(
                self.mtu.get_bridge_adjacencies(face, 2, 3), dtype="uint64"
            )
            id_volume = self.mb.tag_get_data(self.global_id_tag, left_volume)[
                0
            ][0]
            id_volumes.append(id_volume)

            JI = self.mb.get_coords([I]) - self.mb.get_coords([J])
            JK = self.mb.get_coords([K]) - self.mb.get_coords([J])
            LJ = (
                self.mb.get_coords([J])
                - self.mesh_data.mb.tag_get_data(
                    self.volume_centre_tag, left_volume
                )[0]
            )
            N_IJK = np.cross(JI, JK) / 2.0
            _test = np.dot(LJ, N_IJK)
            if _test < 0.0:
                I, K = K, I
                JI = self.mb.get_coords([I]) - self.mb.get_coords([J])
                JK = self.mb.get_coords([K]) - self.mb.get_coords([J])
                N_IJK = np.cross(JI, JK) / 2.0
            tan_JI = np.cross(N_IJK, JI)
            tan_JK = np.cross(N_IJK, JK)
            self.mb.tag_set_data(self.normal_tag, face, N_IJK)

            face_area = np.sqrt(np.dot(N_IJK, N_IJK))
            h_L = geo.get_height(N_IJK, LJ)

            g_I = self.get_boundary_node_pressure(I)
            g_J = self.get_boundary_node_pressure(J)
            g_K = self.get_boundary_node_pressure(K)

            K_L = self.mb.tag_get_data(self.perm_tag, left_volume).reshape(
                [3, 3]
            )
            K_n_L = self.vmv_multiply(N_IJK, K_L, N_IJK)
            K_L_JI = self.vmv_multiply(N_IJK, K_L, tan_JI)
            K_L_JK = self.vmv_multiply(N_IJK, K_L, tan_JK)

            D_JK = self.get_cross_diffusion_term(
                tan_JK, LJ, face_area, h_L, K_n_L, K_L_JK, boundary=True
            )
            D_JI = self.get_cross_diffusion_term(
                tan_JI, LJ, face_area, h_L, K_n_L, K_L_JI, boundary=True
            )
            K_eq = (1 / h_L) * (face_area * K_n_L)

            RHS = D_JK * (g_I - g_J) - K_eq * g_J + D_JI * (g_J - g_K)
            LHS = K_eq
            all_LHS.append(LHS)

            self.Q[id_volume] += -RHS
            # self.Q[id_volume, 0] += - RHS
            # self.mb.tag_set_data(self.flux_info_tag, face,
            #                      [D_JK, D_JI, K_eq, I, J, K, face_area])

        all_cols = []
        all_rows = []
        all_values = []
        self.ids = []
        self.v_ids = []
        self.ivalues = []
        for face in self.intern_faces:
            left_volume, right_volume = self.mtu.get_bridge_adjacencies(
                face, 2, 3
            )
            L = self.mesh_data.mb.tag_get_data(
                self.volume_centre_tag, left_volume
            )[0]
            R = self.mesh_data.mb.tag_get_data(
                self.volume_centre_tag, right_volume
            )[0]
            dist_LR = R - L
            I, J, K = self.mtu.get_bridge_adjacencies(face, 0, 0)
            JI = self.mb.get_coords([I]) - self.mb.get_coords([J])
            JK = self.mb.get_coords([K]) - self.mb.get_coords([J])

            N_IJK = np.cross(JI, JK) / 2.0
            test = np.dot(N_IJK, dist_LR)

            if test < 0:
                left_volume, right_volume = right_volume, left_volume
                L = self.mesh_data.mb.tag_get_data(
                    self.volume_centre_tag, left_volume
                )[0]
                R = self.mesh_data.mb.tag_get_data(
                    self.volume_centre_tag, right_volume
                )[0]
                dist_LR = R - L

            face_area = np.sqrt(np.dot(N_IJK, N_IJK))
            tan_JI = np.cross(N_IJK, JI)
            tan_JK = np.cross(N_IJK, JK)

            K_R = self.mb.tag_get_data(self.perm_tag, right_volume).reshape(
                [3, 3]
            )
            RJ = R - self.mb.get_coords([J])
            h_R = geo.get_height(N_IJK, RJ)

            K_R_n = self.vmv_multiply(N_IJK, K_R, N_IJK)
            K_R_JI = self.vmv_multiply(N_IJK, K_R, tan_JI)
            K_R_JK = self.vmv_multiply(N_IJK, K_R, tan_JK)

            K_L = self.mb.tag_get_data(self.perm_tag, left_volume).reshape(
                [3, 3]
            )

            LJ = L - self.mb.get_coords([J])
            h_L = geo.get_height(N_IJK, LJ)

            K_L_n = self.vmv_multiply(N_IJK, K_L, N_IJK)
            K_L_JI = self.vmv_multiply(N_IJK, K_L, tan_JI)
            K_L_JK = self.vmv_multiply(N_IJK, K_L, tan_JK)

            D_JI = self.get_cross_diffusion_term(
                tan_JI,
                dist_LR,
                face_area,
                h_L,
                K_L_n,
                K_L_JI,
                h_R,
                K_R_JI,
                K_R_n,
            )
            D_JK = self.get_cross_diffusion_term(
                tan_JK,
                dist_LR,
                face_area,
                h_L,
                K_L_n,
                K_L_JK,
                h_R,
                K_R_JK,
                K_R_n,
            )

            K_eq = (K_R_n * K_L_n) / (K_R_n * h_L + K_L_n * h_R) * face_area

            id_right = self.mb.tag_get_data(self.global_id_tag, right_volume)
            id_left = self.mb.tag_get_data(self.global_id_tag, left_volume)

            col_ids = [id_right, id_right, id_left, id_left]
            row_ids = [id_right, id_left, id_left, id_right]
            values = [K_eq, -K_eq, K_eq, -K_eq]
            all_cols.append(col_ids)
            all_rows.append(row_ids)
            all_values.append(values)
            # wait for interpolation to be done
            self._node_treatment(I, id_left, id_right, K_eq, D_JK=D_JK)
            self._node_treatment(
                J, id_left, id_right, K_eq, D_JI=D_JI, D_JK=-D_JK
            )
            self._node_treatment(K, id_left, id_right, K_eq, D_JI=-D_JI)
            # self.mb.tag_set_data(self.flux_info_tag, face,
            #                      [D_JK, D_JI, K_eq, I, J, K, face_area])

        self.T.InsertGlobalValues(self.ids, self.v_ids, self.ivalues)
        # self.T[
        #     np.asarray(self.ids)[:, :, 0, 0], np.asarray(self.v_ids)
        # ] = np.asarray(self.ivalues)
        self.T.InsertGlobalValues(id_volumes, id_volumes, all_LHS)
        # self.T[
        #     np.asarray(id_volumes), np.asarray(id_volumes)
        # ] = np.asarray(all_LHS)
        self.T.InsertGlobalValues(all_cols, all_rows, all_values)
        # self.T[
        #     np.asarray(all_cols)[:, 0, 0, 0],
        #     np.asarray(all_rows)[:, 0, 0, 0]
        # ] = np.asarray(all_values)[:, 0]
        self.T.FillComplete()
        mat_fill_time = time.time() - begin
        print("matrix fill took {0} seconds...".format(mat_fill_time))
        mesh_size = len(self.volumes)
        print("running solver...")
        USE_DIRECT_SOLVER = False
        linearProblem = Epetra.LinearProblem(self.T, self.x, self.Q)
        if USE_DIRECT_SOLVER:
            solver = Amesos.Lapack(linearProblem)
            print("1) Performing symbolic factorizations...")
            solver.SymbolicFactorization()
            print("2) Performing numeric factorizations...")
            solver.NumericFactorization()
            print("3) Solving the linear system...")
            solver.Solve()
            t = time.time() - t0
            print(
                "Solver took {0} seconds to run over {1} volumes".format(
                    t, mesh_size
                )
            )
        else:
            solver = AztecOO.AztecOO(linearProblem)
            solver.SetAztecOption(AztecOO.AZ_solver, AztecOO.AZ_gmres)
            solver.SetAztecOption(AztecOO.AZ_output, AztecOO.AZ_none)
            # solver.SetAztecOption(AztecOO.AZ_precond, AztecOO.AZ_Jacobi)
            # solver.SetAztecOption(AztecOO.AZ_kspace, 1251)
            # solver.SetAztecOption(AztecOO.AZ_orthog, AztecOO.AZ_modified)
            # solver.SetAztecOption(AztecOO.AZ_conv, AztecOO.AZ_Anorm)
            solver.Iterate(8000, 1e-10)
            t = time.time() - t0
            its = solver.GetAztecStatus()[0]
            solver_time = solver.GetAztecStatus()[6]
            print(
                "Solver took {0} seconds to run over {1} volumes".format(
                    t, mesh_size
                )
            )
            print(
                "Solver converged at %.dth iteration in %3f seconds."
                % (int(its), solver_time)
            )
        # self.T = self.T.tocsc()
        # self.Q = self.Q.tocsc()
        # self.x = spsolve(self.T, self.Q)
        # print(np.sum(self.T[50]), self.Q[50])
        self.mb.tag_set_data(self.pressure_tag, self.volumes, self.x)
    # }

    # prec = ML.MultiLevelPreconditioner(P_epetra, False)
    # prec.SetParameterList(mlList)
    # prec.ComputePreconditioner()

    # solver = AztecOO.AztecOO(A_epetra, x_epetra, b_epetra)
    # solver.SetPrecOperator(prec)
    # solver.SetAztecOption(AztecOO.AZ_solver, AztecOO.AZ_gmres);
    # solver.SetAztecOption(AztecOO.AZ_output, 100);
    # err = solver.Iterate(20000, 1e-10)

    tic()
    problem = Epetra.LinearProblem(A_epetra, x_epetra, b_epetra)
    print '\n\n\n\n\n\n'
    factory = Amesos.Factory()
    solver = factory.Create("Amesos_Umfpack", problem)
    # solver = factory.Create("MUMPS", problem)
    amesosList = {"PrintTiming": True, "PrintStatus": True}
    solver.SetParameters(amesosList)
    solver.SymbolicFactorization()
    solver.NumericFactorization()
    solver.Solve()
    soln = problem.GetLHS()
    print "||x_computed||_2 =", soln.Norm2()
    # solver.PrintTiming()
    print '\n\n\n\n\n\n'

    if case == 1:
        ue = Expression(("20*x[0]*pow(x[1],3)", "5*pow(x[0],4)-5*pow(x[1],4)"))
        pe = Expression("60*pow(x[0],2)*x[1]-20*pow(x[1],3)+5")
示例#9
0
print "Matrix fill took", time.time() - t0, "seconds... Ran over ", len(
    volumes), "elems"

mb.tag_set_data(pres_tag, volumes, np.asarray(b[v_ids]))

if USE_DIRECT_SOLVER:
    outfile_template = "Results/output_direct_{0}.vtk"
else:
    outfile_template = "output_iterative_fine_grid{0}.vtk"

mb.write_file(outfile_template.format(0))

linearProblem = Epetra.LinearProblem(A, x, b)

if USE_DIRECT_SOLVER:
    solver = Amesos.Lapack(linearProblem)

    print "1) Performing symbolic factorizations..."
    solver.SymbolicFactorization()

    print "2) Performing numeric factorizations..."
    solver.NumericFactorization()
    print "3) Solving the linear system..."
    ierr = solver.Solve()
else:

    solver = AztecOO.AztecOO(linearProblem)

    ierr = solver.Iterate(1000, 1e-9)

print "   solver.Solve() return code = ", ierr