예제 #1
0
    def __init__(self, filename, comm):
        super().__init__(filename)

        self.comm = comm
        self.rank = comm.MyPID()
        self.size = comm.NumProc()

        if self.rank == 0:
            self.convert_to_true_stress_and_strain()
        else:
            self.true_stress = np.array([], dtype=np.double)
            self.true_strain = np.array([], dtype=np.double)

        ######################
        #### Add Code Here ###
        ######################
        unbalanced_map = Epetra.Map(-1, len(self.true_stress), 0, self.comm)
        unbalanced_stress = Epetra.Vector(Epetra.Copy, unbalanced_map,
                                          self.true_stress)
        unbalanced_strain = Epetra.Vector(Epetra.Copy, unbalanced_map,
                                          self.true_strain)

        balanced_map = self.create_balanced_map(unbalanced_map)

        importer = Epetra.Import(balanced_map, unbalanced_map)

        self.true_strain = Epetra.Vector(balanced_map)
        self.true_stress = Epetra.Vector(balanced_map)

        self.true_stress.Import(unbalanced_stress, importer, Epetra.Insert)
        self.true_strain.Import(unbalanced_strain, importer, Epetra.Insert)
    def __init__(self, filename, comm):
        super().__init__(filename)

        self.comm = comm
        self.rank = comm.MyPID()
        self.size = comm.NumProc()

        if self.rank == 0:
            self.convert_to_true_stress_and_strain()
        else:
            self.true_stress = np.array([], dtype=np.double)
            self.true_strain = np.array([], dtype=np.double)

        unbalanced_map = Epetra.Map(-1, self.true_stress.shape[0], 0,
                                    self.comm)

        unbalanced_stress = Epetra.Vector(Epetra.Copy, unbalanced_map,
                                          self.true_stress)
        unbalanced_strain = Epetra.Vector(Epetra.Copy, unbalanced_map,
                                          self.true_strain)

        balanced_map = self.create_balanced_map(unbalanced_map)
        self.true_stress = Epetra.Vector(balanced_map)
        self.true_strain = Epetra.Vector(balanced_map)

        importer = Epetra.Import(balanced_map, unbalanced_map)

        self.true_stress.Import(
            unbalanced_stress, importer, Epetra.Insert
        )  #insert or add, if importing data from unbalanced to balanced, Insert(overwrite) or add

        self.true_strain.Import(unbalanced_strain, importer, Epetra.Insert)
예제 #3
0
    def _getGhostedValues(self, var):
        """Obtain current ghost values from across processes

        Returns
        -------
        ndarray
            Ghosted values
        """
        mesh = var.mesh
        localNonOverlappingCellIDs = mesh._localNonOverlappingCellIDs

        ## The following conditional is required because empty indexing is
        ## not altogether functional.  This numpy.empty((0,))[[]] and this
        ## numpy.empty((0,))[...,[]] both work, but this numpy.empty((3,
        ## 0))[...,[]] is broken.
        if var.shape[-1] != 0:
            s = (Ellipsis, localNonOverlappingCellIDs)
        else:
            s = (localNonOverlappingCellIDs, )

        nonOverlappingVector = Epetra.Vector(self.domainMap, var[s].ravel())

        overlappingVector = Epetra.Vector(self.colMap)
        overlappingVector.Import(nonOverlappingVector,
                                 Epetra.Import(self.colMap, self.domainMap),
                                 Epetra.Insert)

        return numerix.reshape(numerix.asarray(overlappingVector), var.shape)
 def __init__(self, layers):
     self.__comm = Epetra.PyComm()
     self.__layers = layers
     self.__single_proc_map, self.__multiple_proc_map = self.generate_maps()
     self.__importer = Epetra.Import(self.__multiple_proc_map,
                                     self.__single_proc_map)
     self.__exporter = Epetra.Export(self.__multiple_proc_map,
                                     self.__single_proc_map)
예제 #5
0
    def takeDiagonal(self):
        nonoverlapping_result = _TrilinosMatrixFromShape.takeDiagonal(self)

        overlapping_result = Epetra.Vector(self.colMap)
        overlapping_result.Import(nonoverlapping_result,
                                  Epetra.Import(self.colMap, self.domainMap),
                                  Epetra.Insert)

        return overlapping_result
예제 #6
0
def gather(x):
    from PyTrilinos import Epetra

    local_elements = []
    if x.Comm().MyPID() == 0:
        local_elements = range(x.Map().NumGlobalElements())
    local_map = Epetra.Map(-1, local_elements, 0, x.Comm())
    importer = Epetra.Import(local_map, x.Map())
    out = Epetra.Vector(local_map)
    out.Import(x, importer, Epetra.Insert)
    return out
 def __init__(self, graph, layers):
     self.__comm = Epetra.PyComm()
     self.__layers = layers
     self.__single_proc_map, self.__multiple_proc_map = self.generate_maps()
     self.__importer = Epetra.Import(self.__multiple_proc_map,
                                     self.__single_proc_map)
     self.__exporter = Epetra.Export(self.__multiple_proc_map,
                                     self.__single_proc_map)
     self.__nproc = self.__comm.NumProc()
     self.__block_matrix_layout = procmap(blockmap(graph), self.__nproc)
     self.__scheduler = partition(self.__block_matrix_layout)
예제 #8
0
    def __init_overlap_import_export(self):
        """
           Initialize Jacobian based on the row and column maps of the balanced
           neighborhood graph.
        """

        balanced_map = self.get_balanced_map()
        field_balanced_map = self.get_balanced_field_map()

        overlap_map = self.get_overlap_map()
        field_overlap_map = self.get_field_overlap_map()

        self.overlap_importer = Epetra.Import(balanced_map, overlap_map)
        self.overlap_exporter = Epetra.Export(overlap_map, balanced_map)
        self.field_overlap_importer = Epetra.Import(field_balanced_map,
                                                    field_overlap_map)

        self.field_overlap_exporter = Epetra.Export(field_overlap_map,
                                                    field_balanced_map)

        return
예제 #9
0
    def _calcResidualVector(self, residualFn=None):
        if residualFn is not None:
            return residualFn(self.var, self.matrix, self.RHSvector)
        else:
	    residual, globalMatrix = self._calcResidualVectorNonOverlapping_()
	    
            overlappingResidual = Epetra.Vector(globalMatrix.colMap)
            overlappingResidual.Import(residual, 
				       Epetra.Import(globalMatrix.colMap, 
						     globalMatrix.domainMap), 
				       Epetra.Insert)

            return overlappingResidual
예제 #10
0
    def __init__(self, filename, comm):
        super().__init__(filename)

        self.comm = comm
        self.rank = comm.MyPID()
        self.size = comm.NumProc()

        if self.rank == 0:
            self.convert_to_true_stress_and_strain()
        else:
            self.true_stress = np.array([], dtype=np.double)
            self.true_strain = np.array([], dtype=np.double)

        global_vector_length = self.true_stress.shape[0]
        if self.rank == 0:
            vector_length = global_vector_length
        else:
            vector_length = 0
            
        stdMap_stress = Epetra.Map(global_vector_length, vector_length, 0, self.comm)
        balanced_map_stress = Epetra.Map(global_vector_length, 0, self.comm)
        
        stdMap_strain = Epetra.Map(global_vector_length, vector_length, 0, self.comm)
        balanced_map_strain = Epetra.Map(global_vector_length, 0, self.comm)
        
        x_stress = Epetra.Vector(stdMap_stress, self.true_stress)
        y_stress = Epetra.Vector(balanced_map_stress)
        
        x_strain = Epetra.Vector(stdMap_strain, self.true_stress)
        y_strain = Epetra.Vector(balanced_map_strain)
        
        comm.Barrier()
        importer_stress = Epetra.Import(balanced_map_stress, stdMap_stress)
        y_stress.Import(x_stress, importer_stress, Epetra.Insert)
        
        importer_strain = Epetra.Import(balanced_map_stress, stdMap_stress)
        y_strain.Import(x_stress, importer_strain, Epetra.Insert)
예제 #11
0
    def takeDiagonal(self):
        nonoverlapping_result = _TrilinosMatrix.takeDiagonal(self)

        comm = self.mesh.communicator.epetra_comm

        globalOverlappingCellIDs = self.mesh._getGlobalOverlappingCellIDs()
        overlappingMap = Epetra.Map(-1, list(globalOverlappingCellIDs), 0, comm)

        overlapping_result = Epetra.Vector(overlappingMap)
        overlapping_result.Import(nonoverlapping_result,
                                  Epetra.Import(overlappingMap,
                                                self.nonOverlappingMap),
                                  Epetra.Insert)

        return overlapping_result
예제 #12
0
def _trilinosToNumpyVector(v):
    """
    Takes a distributed Trilinos vector and gives all processors a copy of it
    in a numpy vector.
    """

    if(v.Comm().NumProc() == 1):
        return numerix.array(v)
    else:
        PersonalMap = Epetra.Map(-1, range(0, v.GlobalLength()), 0, v.Comm())
        DistToPers = Epetra.Import(PersonalMap, v.Map())

        PersonalV = Epetra.Vector(PersonalMap)
        PersonalV.Import(v, DistToPers, Epetra.Insert)

        return numerix.array(PersonalV)
예제 #13
0
    def computeF(self, u, F, flag):
        try:
            overlappingVector = Epetra.Vector(self.colMap, self.solver.var)

            overlappingVector.Import(
                u, Epetra.Import(self.colMap, self.domainMap), Epetra.Insert)

            self.solver.var.value = overlappingVector
            F[:] = self.solver.equation.justResidualVector(dt=self.dt)

            return True

        except Exception, e:
            print "TrilinosNonlinearSolver.computeF() has thrown an exception:"
            print str(type(e))[18:-2] + ":", e
            return False
예제 #14
0
    def re_init(self):
        self.comm = Epetra.PyComm()
        self.mpicomm = MPI.COMM_WORLD

        self.unique_map, self.nonunique_map, self.subgraph_ids_vec = self.create_maps(
            self.graph, self.comm)
        self.epetra_importer = Epetra.Import(self.nonunique_map,
                                             self.unique_map)

        unique_map = self.unique_map
        nonunique_map = self.nonunique_map

        self.p_c = Epetra.Vector(unique_map)
        self.p_w = Epetra.Vector(unique_map)
        self.sat = Epetra.Vector(unique_map)
        self.global_source_wett = Epetra.Vector(unique_map)
        self.global_source_nonwett = Epetra.Vector(unique_map)
        self.out_flux_w = Epetra.Vector(unique_map)
        self.out_flux_n = Epetra.Vector(unique_map)

        self.p_c_with_ghost = Epetra.Vector(nonunique_map)
        self.p_w_with_ghost = Epetra.Vector(nonunique_map)
        self.sat_with_ghost = Epetra.Vector(nonunique_map)
        self.global_source_nonwett_with_ghost = Epetra.Vector(nonunique_map)
        self.out_flux_n_with_ghost = Epetra.Vector(nonunique_map)
        self.p_c = self._update_pc_from_subnetworks(self.p_c,
                                                    self.my_subnetworks)
        ierr = self.p_c_with_ghost.Import(self.p_c, self.epetra_importer,
                                          Epetra.Insert)
        assert ierr == 0

        self.sat = self._update_sat_from_subnetworks(self.sat,
                                                     self.my_subnetworks)
        ierr = self.sat_with_ghost.Import(self.sat, self.epetra_importer,
                                          Epetra.Insert)

        A = create_matrix(self.unique_map, ["k_n", "k_w"], self.my_subnetworks,
                          self.inter_processor_edges,
                          self.inter_subgraph_edges)

        self.Epetra_graph = A.Graph()

        self.ms = MSRSB(A, self.my_subgraph_support, self.my_basis_support)
        self.ms.smooth_prolongation_operator(A, tol=self.btol)

        assert ierr == 0
예제 #15
0
    def get_final_solution(self):

        balanced_map = self.u.Map()

        if self.rank == 0:
            my_global_elements = balanced_map.NumGlobalElements()
        else:
            my_global_elements = 0

        temp_map = Epetra.Map(-1, my_global_elements, 0, self.comm)
        solution = Epetra.Vector(temp_map)

        importer = Epetra.Import(temp_map, balanced_map)

        solution.Import(self.u, importer, Epetra.Insert)

        return solution.ExtractCopy()
예제 #16
0
    def _getDistributedMatrix(self):
        """
        Returns an equivalent Trilinos matrix, but redistributed evenly over
        all processors.
        """
        if self.comm.NumProc() == 1:
            return self.matrix
            # No redistribution necessary in serial mode
        else:
##            self.matrix.GlobalAssemble()
            totalElements = self.matrix.NumGlobalRows()

            DistributedMap = Epetra.Map(totalElements, 0, self.comm)
            RootToDist = Epetra.Import(DistributedMap, self.nonOverlappingMap)

            DistMatrix = Epetra.CrsMatrix(Epetra.Copy, DistributedMap, self.bandwidth*3/2)

            DistMatrix.Import(self.matrix, RootToDist, Epetra.Insert)

            return DistMatrix
예제 #17
0
    def create_vectors_and_importer(self):

        self.u = Epetra.Vector(self.graph.RowMap(), True)

        #Fill with initial guess (a straight line between boundary conditions)
        self.u[:] = self.boundary_condition_1 + (
            self.get_standard_map().MyGlobalElements() *
            (self.boundary_condition_2 - self.boundary_condition_1) /
            (self.nx - 1))

        self.u_overlap = Epetra.Vector(self.get_overlap_map())

        self.u_sorted_overlap = np.zeros_like(self.u_overlap[:],
                                              dtype=np.double)

        self.sorted_overlap_indices = np.argsort(
            self.get_overlap_map().MyGlobalElements())

        self.importer = Epetra.Import(self.get_overlap_map(),
                                      self.get_standard_map())
 def computeJacobian(self, u, Jac):
     try:
         
         overlappingVector = Epetra.Vector(self.colMap, self.solver.var)
         
         overlappingVector.Import(u, 
                                  Epetra.Import(self.colMap, 
                                                self.domainMap), 
                                  Epetra.Insert)
                                  
         self.solver.var.value = overlappingVector
         
         self.solver.jacobian.matrix.trilinosMatrix = Jac
         self.solver.jacobian._prepareLinearSystem(var=None, solver=self.jacsolver, boundaryConditions=(), dt=1.)
         
         return True
         
     except Exception as e:
         print("TrilinosNonlinearSolver.computeJacobian() has thrown an exception:")
         print(str(type(e))[18:-2] + ":", e)
         return False
예제 #19
0
    def _getDistributedMatrix(self):
        """
        Returns an equivalent Trilinos matrix, but redistributed evenly over
        all processors.
        """
        if self.comm.NumProc() == 1:
            return self.matrix
            # No redistribution necessary in serial mode
        else:
            ##            self._matrix.GlobalAssemble()
            totalElements = self.matrix.NumGlobalRows()

            # Epetra.Map(numGlobalElements, indexBase, comm)
            # implicit number of elements per processor
            DistributedMap = Epetra.Map(totalElements, 0, self.comm)
            RootToDist = Epetra.Import(DistributedMap, self.rangeMap)

            DistMatrix = Epetra.CrsMatrix(Epetra.Copy, DistributedMap,
                                          (self.bandwidth * 3) // 2)

            DistMatrix.Import(self.matrix, RootToDist, Epetra.Insert)

            return DistMatrix
예제 #20
0
def _numpyToTrilinosVector(v):
    """
    Takes a numpy vector and return an equivalent Trilinos vector, distributed
    across all processors as specified by the map.
    """
    comm = Epetra.PyComm()

    map =Epetra.Map(v.shape[0], 0 , comm)
    if(map.Comm().NumProc() == 1):
        return Epetra.Vector(v)
        # No redistribution necessary in serial mode
    else:
        if map.Comm().MyPID() == 0:
            myElements=len(v)
        else:
            myElements=0
        RootMap = Epetra.Map(-1, range(0, myElements), 0, map.Comm())

        RootToDist = Epetra.Import(map, RootMap)

        rootVector = Epetra.Vector(RootMap, v)
        distVector = Epetra.Vector(map)
        distVector.Import(rootVector, RootToDist, Epetra.Insert)
        return distVector
예제 #21
0
    def _solve(self):
        from fipy.terms import SolutionVariableNumberError
        
        globalMatrix, nonOverlappingVector, nonOverlappingRHSvector, overlappingVector = self._globalMatrixAndVectors

        if not (globalMatrix.rangeMap.SameAs(globalMatrix.domainMap)
                and globalMatrix.rangeMap.SameAs(nonOverlappingVector.Map())):

            raise SolutionVariableNumberError
        
        self._solve_(globalMatrix.matrix, 
                     nonOverlappingVector, 
                     nonOverlappingRHSvector)

        overlappingVector.Import(nonOverlappingVector, 
                                 Epetra.Import(globalMatrix.colMap, 
                                               globalMatrix.domainMap), 
                                 Epetra.Insert)
        
        self.var.value = numerix.reshape(numerix.array(overlappingVector), self.var.shape)

        self._deleteGlobalMatrixAndVectors()
        del self.var
        del self.RHSvector
예제 #22
0
def get_supports(A_scipy, v_per_subdomain=1000):
    comm = Epetra.PyComm()
    num_proc = comm.NumProc()

    graph = scipy_matrix_to_igraph(A_scipy)

    num_subdomains = A_scipy.get_shape()[0] / v_per_subdomain

    # create global_id attributes before creating subgraphs.
    graph.vs["global_id"] = np.arange(graph.vcount())
    graph.es["global_id"] = np.arange(graph.ecount())

    n_components, _ = connected_components(A_scipy, directed=False)
    print "number of components", n_components

    if n_components == 1:
        _, subgraph_ids_each_vertex = pymetis.part_graph(
            num_subdomains, graph.get_adjlist())
    else:
        _, subgraph_ids_each_vertex = partition_multicomponent_graph(
            A_scipy, v_per_subdomain)
        print "num of subdomains created", _

    subgraph_ids_each_vertex = np.asarray(subgraph_ids_each_vertex)
    graph.vs["subgraph_id"] = subgraph_ids_each_vertex

    # Assign a processor id to each subgraph
    coarse_graph = coarse_graph_from_partition(graph, subgraph_ids_each_vertex)

    _, proc_ids = pymetis.part_graph(num_proc, coarse_graph.get_adjlist())
    coarse_graph.vs['proc_id'] = proc_ids
    coarse_graph.vs["subgraph_id"] = np.arange(coarse_graph.vcount())

    # Assign a processor id to each pore
    subgraph_id_to_proc_id = {
        v["subgraph_id"]: v['proc_id']
        for v in coarse_graph.vs
    }
    graph.vs["proc_id"] = [
        subgraph_id_to_proc_id[v["subgraph_id"]] for v in graph.vs
    ]

    subgraph_ids = np.unique(subgraph_ids_each_vertex)

    subgraph_id_to_v_center_id = MultiScaleSimUnstructured.subgraph_central_vertices(
        graph, subgraph_ids)

    # Epetra maps to facilitate data transfer between processors
    unique_map, nonunique_map, subgraph_ids_vec = MultiScaleSimUnstructured.create_maps(
        graph, comm)

    epetra_importer = Epetra.Import(nonunique_map, unique_map)
    epetra_importer.NumPermuteIDs() == 0
    epetra_importer.NumSameIDs() == unique_map.NumMyElements()

    my_basis_support = dict()

    my_global_elements = unique_map.MyGlobalElements()

    graph["global_to_local"] = dict(
        (v["global_id"], v.index) for v in graph.vs)
    graph["local_to_global"] = dict(
        (v.index, v["global_id"]) for v in graph.vs)

    my_restriction_supports = dict()

    subgraph_id_vec = np.asarray(graph.vs['subgraph_id'])
    for i in subgraph_ids:
        vs_subgraph = (subgraph_id_vec == i).nonzero()[0]
        my_restriction_supports[i] = graph.vs.select(vs_subgraph)["global_id"]

    for i in subgraph_ids:
        support_vertices = support_of_basis_function(
            i, graph, coarse_graph, subgraph_id_to_v_center_id,
            my_restriction_supports)

        my_basis_support[i] = np.intersect1d(
            support_vertices, my_global_elements).astype(np.int32)

    return my_restriction_supports, my_basis_support
예제 #23
0
    def __init_grid_data(self):
        """
           Create data structures needed for doing computations
        """
        # Create some local (to function) convenience variables
        global_indices = self.balanced_map.MyGlobalElements()
        balanced_map = self.get_balanced_map()
        field_balanced_map = self.get_balanced_field_map()

        overlap_map = self.get_overlap_map()
        field_overlap_map = self.get_field_overlap_map()

        nodes_numb = self.nodes_numb

        # Store the unbalanced nodes in temporary vectors
        if self.rank == 0:
            my_x_temp = self.nodes[:, 0]
            my_y_temp = self.nodes[:, 1]
            my_field_temp = np.zeros(self.number_of_field_variables,
                                     dtype=np.double)

        else:
            my_x_temp = np.array([], dtype=np.double)
            my_y_temp = np.array([], dtype=np.double)
            my_field_temp = np.array([], dtype=np.double)

        # Create a temporary unbalanced map
        unbalanced_map = Epetra.Map(self.__global_number_of_nodes,
                                    my_x_temp.shape[0], 0, self.comm)

        # Needed to build the combined unbalanced map to export values
        # from head node to all nodes
        field_unbalanced_map = Epetra.Map(self.number_of_field_variables,
                                          my_field_temp.shape[0], 0, self.comm)

        # Create the unbalanced Epetra vectors that will only be used to import
        # to the balanced x and y vectors
        my_x_unbalanced = Epetra.Vector(unbalanced_map, my_x_temp)
        my_y_unbalanced = Epetra.Vector(unbalanced_map, my_y_temp)
        my_field_unbalanced = Epetra.Vector(field_unbalanced_map,
                                            my_field_temp)

        # Create the balanced vectors
        my_x = Epetra.Vector(balanced_map)
        my_y = Epetra.Vector(balanced_map)
        my_field = Epetra.Vector(field_balanced_map)
        self.init_guess = my_field

        # Create importers
        grid_importer = Epetra.Import(balanced_map, unbalanced_map)
        field_importer = Epetra.Import(field_balanced_map,
                                       field_unbalanced_map)

        grid_overlap_importer = self.get_overlap_importer()
        field_overlap_importer = self.get_field_overlap_importer()

        # Import the unbalanced data to balanced and overlap data
        my_x.Import(my_x_unbalanced, grid_importer, Epetra.Insert)
        my_y.Import(my_y_unbalanced, grid_importer, Epetra.Insert)
        my_field.Import(my_field_unbalanced, field_importer, Epetra.Insert)

        my_x_overlap = Epetra.Vector(overlap_map)
        my_y_overlap = Epetra.Vector(overlap_map)
        my_field_overlap = Epetra.Vector(field_overlap_map)
        self.my_field_overlap = my_field_overlap

        my_x_overlap.Import(my_x, grid_overlap_importer, Epetra.Insert)
        my_y_overlap.Import(my_y, grid_overlap_importer, Epetra.Insert)
        self.my_field_overlap.Import(my_field, field_overlap_importer,
                                     Epetra.Insert)

        # Residual vector
        self.F_fill = Epetra.Vector(field_balanced_map)
        self.F_fill_overlap = Epetra.Vector(field_overlap_map)

        self.global_overlap_indices = (
            self.get_overlap_map().MyGlobalElements())

        self.field_overlap_indices = field_overlap_map.MyGlobalElements()
        #rambod
        odd_indices_mask = (self.field_overlap_indices % 2 == 1)
        even_indices_mask = (self.field_overlap_indices % 2 == 0)
        self.ux_overlap_indices = (
            self.field_overlap_indices[even_indices_mask])
        self.uy_overlap_indices = (
            self.field_overlap_indices[odd_indices_mask])

        even_indices_mask = (global_indices % 2 == 0)
        self.ux_local_indices = (global_indices[even_indices_mask])
        odd_indices_mask = (global_indices % 2 == 1)
        self.uy_local_indices = (global_indices[odd_indices_mask])

        self.sorted_local_indices = np.argsort(self.global_overlap_indices)
        self.unsorted_local_indices = np.arange(
            self.global_overlap_indices.shape[0])[self.sorted_local_indices]

        # x stride
        self.my_x_overlap_stride = (np.argmax(
            my_x_overlap[self.sorted_local_indices]))
        self.my_y_overlap_stride = (np.argmax(
            my_y_overlap[self.sorted_local_indices]))
        x_max = np.amax(my_x_overlap)
        x_min = np.amin(my_x_overlap)
        y_max = np.amax(my_y_overlap)
        y_min = np.amin(my_y_overlap)
        delta_x = x_max - x_min
        delta_y = y_max - y_min
        #print self.grid_spacing
        x_length = delta_y / self.grid_spacing
        y_length = delta_x / self.grid_spacing
        self.my_y_stride = y_length + 1

        #self.term_x = np.zeros((int(y_length),int(x_length)))
        #self.term_y = np.zeros((int(y_length),int(x_length)))

        self.my_x = my_x
        self.my_y = my_y

        # This is a mess, I'm not even attempting...
        #
        # Establish Boundary Condition
        balanced_nodes = zip(self.my_x, self.my_y)
        hgs = 0.5 * self.grid_spacing
        gs = self.grid_spacing
        l = self.length
        w = self.width
        num_elements = balanced_map.NumMyElements()

        #Right BC with one horizon thickness
        x_min_right = np.where(self.my_x >= l - (3.0 * gs + hgs))
        x_max_right = np.where(self.my_y <= l + hgs)
        x_min_right = np.array(x_min_right)
        x_max_right = np.array(x_max_right)
        BC_Right_Edge = np.intersect1d(x_min_right, x_max_right)
        BC_Right_Index = np.sort(BC_Right_Edge)
        BC_Right_fill = np.zeros(len(BC_Right_Edge), dtype=np.int32)
        BC_Right_fill_ux = np.zeros(len(BC_Right_Edge), dtype=np.int32)
        BC_Right_fill_uy = np.zeros(len(BC_Right_Edge), dtype=np.int32)
        for item in range(len(BC_Right_Index)):
            BC_Right_fill[item] = BC_Right_Index[item]
            BC_Right_fill_ux[item] = 2 * BC_Right_Index[item]
            BC_Right_fill_uy[item] = 2 * BC_Right_Index[item] + 1
        self.BC_Right_fill = BC_Right_fill
        self.BC_Right_fill_ux = BC_Right_fill_ux
        self.BC_Right_fill_uy = BC_Right_fill_uy

        #Left BC with one horizon thickness
        x_min_left = np.where(self.my_x >= -hgs)[0]
        x_max_left = np.where(self.my_x <= (3.0 * gs + hgs))[0]
        BC_Left_Edge = np.intersect1d(x_min_left, x_max_left)
        BC_Left_Index = np.sort(BC_Left_Edge)

        BC_Left_fill = np.zeros(len(BC_Left_Edge), dtype=np.int32)
        BC_Left_fill_ux = np.zeros(len(BC_Left_Edge), dtype=np.int32)
        BC_Left_fill_uy = np.zeros(len(BC_Left_Edge), dtype=np.int32)
        for item in range(len(BC_Left_Index)):
            BC_Left_fill[item] = BC_Left_Index[item]
            BC_Left_fill_ux[item] = 2 * BC_Left_Index[item]
            BC_Left_fill_uy[item] = 2 * BC_Left_Index[item] + 1

        self.BC_Left_fill_uy = BC_Left_fill_uy
        self.BC_Left_fill_ux = BC_Left_fill_uy

        #Bottom BC with one horizon thickness"""
        ymin_bottom = np.where(self.my_y >= (-hgs))[0]
        ymax_bottom = np.where(self.my_y <= (3.0 * gs + hgs))[0]
        BC_Bottom_Edge = np.intersect1d(ymin_bottom, ymax_bottom)
        BC_Bottom_fill = np.zeros(len(BC_Bottom_Edge), dtype=np.int32)
        BC_Bottom_fill_ux = np.zeros(len(BC_Bottom_Edge), dtype=np.int32)
        BC_Bottom_fill_uy = np.zeros(len(BC_Bottom_Edge), dtype=np.int32)
        for item in range(len(BC_Bottom_Edge)):
            BC_Bottom_fill[item] = BC_Bottom_Edge[item]
            BC_Bottom_fill_ux[item] = 2 * BC_Bottom_Edge[item]
            BC_Bottom_fill_uy[item] = 2 * BC_Bottom_Edge[item] + 1
        self.BC_Bottom_fill = BC_Bottom_fill
        self.BC_Bottom_fill_ux = BC_Bottom_fill_ux
        self.BC_Bottom_fill_uy = BC_Bottom_fill_uy

        #TOP BC with one horizon thickness
        ymin_top = np.where(self.my_y >= w - (3.0 * gs + hgs))[0]
        ymax_top = np.where(self.my_y <= w + hgs)[0]
        BC_Top_Edge = np.intersect1d(ymin_top, ymax_top)
        BC_Top_fill = np.zeros(len(BC_Top_Edge), dtype=np.int32)
        BC_Top_fill_ux = np.zeros(len(BC_Top_Edge), dtype=np.int32)
        BC_Top_fill_uy = np.zeros(len(BC_Top_Edge), dtype=np.int32)
        for item in range(len(BC_Top_Edge)):
            BC_Top_fill[item] = BC_Top_Edge[item]
            BC_Top_fill_ux[item] = 2 * BC_Top_Edge[item]
            BC_Top_fill_uy[item] = 2 * BC_Top_Edge[item] + 1
        self.BC_Top_fill = BC_Top_fill
        self.BC_Top_fill_ux = BC_Top_fill_ux
        self.BC_Top_fill_uy = BC_Top_fill_uy

        #center  bc with two horizon radius
        center = 10.0 * (((nodes_numb / 2.0) - 1.0) / (nodes_numb - 1.0))
        size = np.size(self.my_x)
        hl = l / 10
        hw = self.width / 2 + self.width / 20
        r = w / 20
        rad = np.ones(size)
        rad = np.sqrt((self.my_x[:] - hl)**2 + (self.my_y[:] - hw)**2)
        central_nodes = np.where(rad <= r)
        #central_nodes = np.array(central_nodes)
        #c_2 = central_nodes
        #print c_2
        #ttt.sleep(1)
        xmin_center_2 = np.where((0) < self.my_x)[0]
        xmax_center_2 = np.where((l) > self.my_x)[0]
        ymin_center_2 = np.where((0) < self.my_y)[0]
        ymax_center_2 = np.where((w) > self.my_y)[0]
        c1_2 = np.intersect1d(xmin_center_2, xmax_center_2)
        c2_2 = np.intersect1d(ymin_center_2, ymax_center_2)
        c_2 = np.intersect1d(c1_2, c2_2)
        c_2 = np.intersect1d(c_2, central_nodes)

        center_2_neighb_fill_ux = np.zeros(len(c_2), dtype=np.int32)
        center_2_neighb_fill_uy = np.zeros(len(c_2), dtype=np.int32)
        for item in range(len(c_2)):
            center_2_neighb_fill_ux[item] = c_2[item] * 2.0
            center_2_neighb_fill_uy[item] = c_2[item] * 2.0 + 1.0
        self.center_fill_uy = center_2_neighb_fill_uy
        self.center_fill_ux = center_2_neighb_fill_ux
        self.center_nodes_2 = c_2
        """ Left side of grid """
        x_min = np.where(self.my_x >= -hgs)[0]
        x_max = np.where(self.my_x <= (l - (4.0 * gs + hgs)))[0]
        BC_Edge = np.intersect1d(x_min, x_max)
        BC_Index = np.sort(BC_Edge)
        BC_fill = np.zeros(len(BC_Edge), dtype=np.int32)
        BC_fill_ux = np.zeros(len(BC_Edge), dtype=np.int32)
        BC_fill_uy = np.zeros(len(BC_Edge), dtype=np.int32)
        for item in range(len(BC_Index)):
            BC_fill[item] = BC_Index[item]
            BC_fill_ux[item] = 2 * BC_Index[item]
            BC_fill_uy[item] = 2 * BC_Index[item] + 1
        self.BC_fill_left_end = BC_fill
        self.BC_fill_left_end_p = BC_fill_ux
        self.BC_fill_left_end_s = BC_fill_uy
        """ Left side of grid """
        x_min = np.where(self.my_x >= (4.0 * gs + hgs))[0]
        x_max = np.where(self.my_x <= (l - (4.0 * gs + hgs)))[0]
        BC_Edge = np.intersect1d(x_min, x_max)
        BC_Index = np.sort(BC_Edge)
        BC_fill = np.zeros(len(BC_Edge), dtype=np.int32)
        BC_fill_ux = np.zeros(len(BC_Edge), dtype=np.int32)
        BC_fill_uy = np.zeros(len(BC_Edge), dtype=np.int32)
        for item in range(len(BC_Index)):
            BC_fill[item] = BC_Index[item]
            BC_fill_ux[item] = 2 * BC_Index[item]
            BC_fill_uy[item] = 2 * BC_Index[item] + 1
        self.BC_fill_right_end = BC_fill
        self.BC_fill_right_end_p = BC_fill_ux
        self.BC_fill_right_end_s = BC_fill_uy
        return
예제 #24
0
    def __init__(self, network,  fluid_properties, num_subnetworks, comm=None, mpicomm=None, subgraph_ids=None,
                 delta_s_max=0.01, delta_pc=0.01, ptol_ms=1.e-6, ptol_fs=1.e-6, btol=1.e-2):
        self.network = network

        if comm is None:
            comm = Epetra.PyComm()

        if mpicomm is None:
            mpicomm = MPI.COMM_WORLD

        self.comm, self.mpicomm = comm, mpicomm
        self.fluid_properties = fluid_properties
        self.my_id = comm.MyPID()
        my_id = self.my_id
        self.num_proc = comm.NumProc()

        self.num_subnetworks = num_subnetworks

        # On the master cpu do the following:
        # 1) Create graph corresponding to pore network.
        # 2) Partition the graph into subgraphs
        # 3) Create a coarse graph with the subgraphs as the nodes
        # 4) Use the coarse graph to assign each subgraph to a processor
        if my_id == 0:
            self.graph = network_to_igraph(network, edge_attributes=["l", "A_tot", "r", "G"])

            # create global_id attributes before creating subgraphs.
            self.graph.vs["global_id"] = np.arange(self.graph.vcount())
            self.graph.es["global_id"] = np.arange(self.graph.ecount())

            if subgraph_ids is None:
                _, subgraph_ids = pymetis.part_graph(num_subnetworks, self.graph.get_adjlist())

            subgraph_ids = np.asarray(subgraph_ids)
            self.graph.vs["subgraph_id"] = subgraph_ids

            # Assign a processor id to each subgraph
            coarse_graph = coarse_graph_from_partition(self.graph, subgraph_ids)
            _, proc_ids = pymetis.part_graph(self.num_proc, coarse_graph.get_adjlist())
            coarse_graph.vs['proc_id'] = proc_ids
            coarse_graph.vs["subgraph_id"] = np.arange(coarse_graph.vcount())

            # Assign a processor id to each pore
            subgraph_id_to_proc_id = {v["subgraph_id"]: v['proc_id'] for v in coarse_graph.vs}
            self.graph.vs["proc_id"] = [subgraph_id_to_proc_id[v["subgraph_id"]] for v in self.graph.vs]

        if my_id != 0:
            coarse_graph = None
            self.graph = None
            network = None
            subgraph_ids = None

        self.coarse_graph = self.mpicomm.bcast(coarse_graph, root=0)
        self.graph = self.distribute_graph(self.graph, self.coarse_graph, self.mpicomm)

        self.my_subnetworks = _create_subnetworks(network, subgraph_ids, self.coarse_graph, self.mpicomm)

        self.my_subgraph_ids = self.my_subnetworks.keys()
        self.my_subgraph_ids_with_ghost = list(set().union(*self.coarse_graph.neighborhood(self.my_subgraph_ids)))

        self.inter_subgraph_edges = _create_inter_subgraph_edgelist(self.graph, self.my_subgraph_ids, self.mpicomm)
        self.inter_processor_edges = self.create_inter_processor_edgelist(self.graph, self.my_subgraph_ids, self.mpicomm)

        self.subgraph_id_to_v_center_id = self.subgraph_central_vertices(self.graph, self.my_subgraph_ids_with_ghost)

        # Epetra maps to facilitate data transfer between processors
        self.unique_map, self.nonunique_map, self.subgraph_ids_vec = self.create_maps(self.graph, self.comm)

        self.epetra_importer = Epetra.Import(self.nonunique_map, self.unique_map)
        assert self.epetra_importer.NumPermuteIDs() == 0
        assert self.epetra_importer.NumSameIDs() == self.unique_map.NumMyElements()

        # subgraph_id to support vertices map. Stores the support vertex ids (global ids) of both
        # subnetworks belonging to this processor as well as those belonging to ghost subnetworks.
        # Only support vertex ids belonging to this processor are stored.
        self.my_basis_support = dict()
        self.my_subgraph_support = dict()

        my_global_elements = self.unique_map.MyGlobalElements()


        self.graph["global_to_local"] = dict((v["global_id"], v.index) for v in self.graph.vs)
        self.graph["local_to_global"] = dict((v.index, v["global_id"]) for v in self.graph.vs)

        # support region for each subgraph
        for i in self.my_subgraph_ids:
            self.my_subgraph_support[i] = self.my_subnetworks[i].pi_local_to_global

        # support region for each subgraph
        self.my_subgraph_support_with_ghosts = dict()
        for i in self.my_subgraph_ids_with_ghost:
            self.my_subgraph_support_with_ghosts[i] = np.asarray(self.graph.vs.select(subgraph_id=i)["global_id"])

        for i in self.my_subgraph_ids:
            assert np.all(np.sort(self.my_subgraph_support[i]) == np.sort(self.my_subgraph_support_with_ghosts[i]))

        for i in self.my_subgraph_ids:
            if num_subnetworks == 1:
                support_vertices = self.my_subnetworks[0].pi_local_to_global
            else:
                support_vertices = support_of_basis_function(i, self.graph, self.coarse_graph,
                                                             self.subgraph_id_to_v_center_id, self.my_subgraph_support_with_ghosts)

            self.my_basis_support[i] = np.intersect1d(support_vertices, my_global_elements).astype(np.int32)

        # Create distributed arrays - Note: Memory wasted here by allocating extra arrays which include ghost cells.
        # This can be optimized but the python interface for PyTrilinos is not documented well enough.
        # Better would be to create only the arrays which include ghost cells.
        unique_map = self.unique_map
        nonunique_map = self.nonunique_map
        self.p_c = Epetra.Vector(unique_map)
        self.p_w = Epetra.Vector(unique_map)
        self.sat = Epetra.Vector(unique_map)
        self.global_source_wett = Epetra.Vector(unique_map)
        self.global_source_nonwett = Epetra.Vector(unique_map)
        self.out_flux_w = Epetra.Vector(unique_map)
        self.out_flux_n = Epetra.Vector(unique_map)

        self.p_c_with_ghost = Epetra.Vector(nonunique_map)
        self.p_w_with_ghost = Epetra.Vector(nonunique_map)
        self.sat_with_ghost = Epetra.Vector(nonunique_map)
        self.global_source_nonwett_with_ghost = Epetra.Vector(nonunique_map)
        self.out_flux_n_with_ghost = Epetra.Vector(nonunique_map)

        # Simulation parameters
        self.delta_s_max = delta_s_max
        self.ptol_ms = ptol_ms
        self.ptol_fs = ptol_fs
        self.delta_pc = delta_pc
        self.btol = btol

        # Crate dynamic simulations
        self.simulations = dict()

        for i in self.my_subgraph_ids:
            self.simulations[i] = DynamicSimulation(self.my_subnetworks[i], self.fluid_properties, delta_pc=self.delta_pc,
                                                    ptol=self.ptol_fs)

            self.simulations[i].solver_type = "lu"

            k_comp = ConductanceCalc(self.my_subnetworks[i], self.fluid_properties)
            k_comp.compute()
            pc_comp = DynamicCapillaryPressureComputer(self.my_subnetworks[i])
            pc_comp.compute()

        self.time = 0.0
        self.stop_time = None

        self.pi_list_press_inlet = []
        self.press_inlet_w = None
        self.press_inlet_nw = None

        self.pi_list_press_outlet = []
        self.press_outlet_w = None
        self.press_outlet_nw = None
예제 #25
0
    def __mul__(self, other):
        """
        Multiply a sparse matrix by another sparse matrix.

            >>> L1 = _TrilinosMatrix(size=3)
            >>> L1.addAt((3,10,numerix.pi,2.5), (0,0,1,2), (2,1,1,0))
            >>> L2 = _TrilinosIdentityMatrix(size=3)
            >>> L2.addAt((4.38,12357.2,1.1), (2,1,0), (1,0,2))

            >>> tmp = numerix.array(((1.23572000e+05, 2.31400000e+01, 3.00000000e+00),
            ...                      (3.88212887e+04, 3.14159265e+00, 0.00000000e+00),
            ...                      (2.50000000e+00, 0.00000000e+00, 2.75000000e+00)))

            >>> for i in range(0,3):
            ...     for j in range(0,3):
            ...         numerix.allclose(((L1*L2)[i,j],), tmp[i,j])
            True
            True
            True
            True
            True
            True
            True
            True
            True

        or a sparse matrix by a vector

            >>> tmp = numerix.array((29., 6.28318531, 2.5))
            >>> numerix.allclose(L1 * numerix.array((1,2,3),'d'), tmp)
            1

        or a vector by a sparse matrix

            >>> tmp = numerix.array((7.5, 16.28318531,  3.))
            >>> numerix.allclose(numerix.array((1,2,3),'d') * L1, tmp)
            1


        """
        if not self._getMatrix().Filled():
            self._getMatrix().FillComplete()

        N = self._getMatrix().NumMyCols()

        if isinstance(other, _TrilinosMatrixBase):
            return _TrilinosMatrix.__mul__(self, other=other)
        else:
            shape = numerix.shape(other)
            if shape == ():
                result = self.copy()
                result._getMatrix().Scale(other)
                return result
            else:
                if isinstance(other, Epetra.Vector):
                    other_map = other.Map()
                else:
                    other_map = self.overlappingMap

                if other_map.SameAs(self.overlappingMap):
                    localNonOverlappingCellIDs = self.mesh._getLocalNonOverlappingCellIDs()
                    other = Epetra.Vector(self.nonOverlappingMap,
                                          other[localNonOverlappingCellIDs])

                if other.Map().SameAs(self.matrix.RowMap()):

                    nonoverlapping_result = Epetra.Vector(self.nonOverlappingMap)

                    self._getMatrix().Multiply(False, other, nonoverlapping_result)

                    if other_map.SameAs(self.overlappingMap):
                        overlapping_result = Epetra.Vector(self.overlappingMap)
                        overlapping_result.Import(nonoverlapping_result,
                                                  Epetra.Import(self.overlappingMap,
                                                                self.nonOverlappingMap),
                                                  Epetra.Insert)

                        return overlapping_result
                    else:
                        return nonoverlapping_result
                else:
                    raise TypeError("%s: %s != (%d,)" % (self.__class__, str(shape), N))
예제 #26
0
 parameter_list = Teuchos.ParameterList()
 parameter_list.set("Partitioning Method","RCB")
 if not VERBOSE:
     parameter_sublist = parameter_list.sublist("ZOLTAN")
     parameter_sublist.set("DEBUG_LEVEL", "0")
 #Create a partitioner to load balance the grid
 partitioner = Isorropia.Epetra.Partitioner(my_nodes, parameter_list)
 #And a redistributer
 redistributer = Isorropia.Epetra.Redistributor(partitioner)
 #Redistribute nodes
 my_nodes_balanced = redistributer.redistribute(my_nodes)
 #The new load balanced map
 balanced_map = my_nodes_balanced.Map()
 #Create importer and exporters to move data between banlanced and 
 #unbalanced maps
 importer = Epetra.Import(balanced_map, unbalanced_map)
 exporter = Epetra.Export(balanced_map, unbalanced_map)
 #Create distributed vectors to store the balanced node positions
 my_x = Epetra.Vector(balanced_map)
 my_y = Epetra.Vector(balanced_map)
 my_families_balanced = Epetra.MultiVector(balanced_map, max_family_length)
 #Import the balanced node positions and family information
 my_x.Import(my_nodes[0],importer, Epetra.Insert)
 my_y.Import(my_nodes[1],importer, Epetra.Insert)
 my_families_balanced.Import(my_families,importer, Epetra.Insert)
 #Convert to integer data type for indexing purposes later
 my_families = np.array(my_families_balanced.T, dtype=np.int32)
 #Create a flattened list of all family global indices (locally owned 
 #+ ghosts)
 my_global_ids_required = np.unique(my_families[my_families != -1])
 #Create a list of locally owned global ids
예제 #27
0
    def __mul__(self, other):
        """
        Multiply a sparse matrix by another sparse matrix.

            >>> L1 = _TrilinosMatrixFromShape(rows=3, cols=3)
            >>> L1.addAt((3, 10, numerix.pi, 2.5), (0, 0, 1, 2), (2, 1, 1, 0))
            >>> L2 = _TrilinosIdentityMatrix(size=3)
            >>> L2.addAt((4.38, 12357.2, 1.1), (2, 1, 0), (1, 0, 2))

            >>> tmp = numerix.array(((1.23572000e+05, 2.31400000e+01, 3.00000000e+00),
            ...                      (3.88212887e+04, 3.14159265e+00, 0.00000000e+00),
            ...                      (2.50000000e+00, 0.00000000e+00, 2.75000000e+00)))

            >>> L = (L1 * L2).numpyArray

            >>> print(numerix.allclose(tmp, L))
            True

        or a sparse matrix by a vector

            >>> tmp = numerix.array((29., 6.28318531, 2.5))
            >>> print(numerix.allclose(L1 * numerix.array((1, 2, 3), 'd'), tmp)) # doctest: +SERIAL
            True

        or a vector by a sparse matrix

            >>> tmp = numerix.array((7.5, 16.28318531,  3.))
            >>> numerix.allclose(numerix.array((1, 2, 3), 'd') * L1, tmp) # doctest: +SERIAL
            True

        Should be able to multiply an overlapping value obtained from a
        `CellVariable`. This is required to make the `--no-pysparse` flag
        work correctly.

            >>> from fipy import *
            >>> m = Grid1D(nx=6)
            >>> v0 = CellVariable(mesh=m, value=numerix.arange(m.globalNumberOfCells, dtype=float))
            >>> v1 = CellVariable(mesh=m, value=_TrilinosIdentityMeshMatrix(mesh=m) * v0.value)
            >>> print(numerix.allclose(v0, v1))
            True

        """
        self.fillComplete()

        N = self.matrix.NumMyCols()

        if isinstance(other, _TrilinosMatrix):
            return super(_TrilinosMeshMatrix, self).__mul__(other=other)
        else:
            shape = numerix.shape(other)

            if shape == ():
                result = self.copy()
                result.matrix.Scale(other)
                return result
            else:

                if isinstance(other, Epetra.Vector):
                    other_map = other.Map()
                else:
                    other_map = self.colMap

                if other_map.SameAs(self.colMap):
                    localNonOverlappingColIDs = self._m2m.localNonOverlappingColIDs

                    other = Epetra.Vector(self.domainMap,
                                          other[localNonOverlappingColIDs])

                if other.Map().SameAs(self.matrix.DomainMap()):
                    nonoverlapping_result = Epetra.Vector(self.rangeMap)
                    self.matrix.Multiply(False, other, nonoverlapping_result)

                    if other_map.SameAs(self.colMap):
                        overlapping_result = Epetra.Vector(self.colMap)
                        overlapping_result.Import(
                            nonoverlapping_result,
                            Epetra.Import(self.colMap, self.domainMap),
                            Epetra.Insert)

                        return overlapping_result
                    else:
                        return nonoverlapping_result

                else:
                    raise TypeError("%s: %s != (%d,)" %
                                    (self.__class__, str(shape), N))
예제 #28
0
    def __init__(self, comm, parameters, nx, ny, nz, dim, dof, x=None, y=None, z=None):
        fvm.Interface.__init__(self, parameters, nx, ny, nz, dim, dof)

        self.nx_global = nx
        self.ny_global = ny
        self.nz_global = nz
        self.dof = dof

        self.comm = comm

        HYMLS.Tools.InitializeIO(self.comm)

        self.parameters = parameters
        problem_parameters = self.parameters.sublist('Problem')
        problem_parameters.set('nx', self.nx_global)
        problem_parameters.set('ny', self.ny_global)
        problem_parameters.set('nz', self.nz_global)
        problem_parameters.set('Dimension', self.dim)
        problem_parameters.set('Degrees of Freedom', self.dof)
        problem_parameters.set('Equations', 'Stokes-C')

        solver_parameters = self.parameters.sublist('Solver')
        solver_parameters.set('Initial Vector', 'Zero')

        iterative_solver_parameters = solver_parameters.sublist('Iterative Solver')
        set_default_parameter(iterative_solver_parameters, 'Maximum Iterations', 1000)
        set_default_parameter(iterative_solver_parameters, 'Maximum Restarts', 20)
        set_default_parameter(iterative_solver_parameters, 'Num Blocks', 100)
        set_default_parameter(iterative_solver_parameters, 'Flexible Gmres', False)
        set_default_parameter(iterative_solver_parameters, 'Convergence Tolerance', 1e-8)
        set_default_parameter(iterative_solver_parameters, 'Output Frequency', 1)
        set_default_parameter(iterative_solver_parameters, 'Show Maximum Residual Norm Only', False)

        prec_parameters = self.parameters.sublist('Preconditioner')
        prec_parameters.set('Partitioner', 'Skew Cartesian')
        set_default_parameter(prec_parameters, 'Separator Length', min(8, self.nx_global))
        set_default_parameter(prec_parameters, 'Coarsening Factor', 2)
        set_default_parameter(prec_parameters, 'Number of Levels', 1)

        coarse_solver_parameters = prec_parameters.sublist('Coarse Solver')
        set_default_parameter(coarse_solver_parameters, "amesos: solver type", "Amesos_Superludist")

        self.partition_domain()
        self.map = self.create_map()

        self.assembly_map = self.create_map(True)
        self.assembly_importer = Epetra.Import(self.assembly_map, self.map)

        partitioner = HYMLS.SkewCartesianPartitioner(self.parameters, self.comm)
        partitioner.Partition()

        self.solve_map = partitioner.Map()
        self.solve_importer = Epetra.Import(self.solve_map, self.map)

        # Create local coordinate vectors
        x_length = self.parameters.get('xmax', 1.0) - self.parameters.get('xmin', 0.0)
        x_start = self.parameters.get('xmin', 0.0) + self.nx_offset / self.nx_global * x_length
        x_end = x_start + self.nx_local / self.nx_global * x_length

        y_length = self.parameters.get('ymax', 1.0) - self.parameters.get('ymin', 0.0)
        y_start = self.parameters.get('ymin', 0.0) + self.ny_offset / self.ny_global * y_length
        y_end = y_start + self.ny_local / self.ny_global * y_length

        z_length = self.parameters.get('zmax', 1.0) - self.parameters.get('zmin', 0.0)
        z_start = self.parameters.get('zmin', 0.0) + self.nz_offset / self.nz_global * z_length
        z_end = z_start + self.nz_local / self.nz_global * z_length

        if self.parameters.get('Grid Stretching', False):
            sigma = self.parameters.get('Grid Stretching Factor', 1.5)
            x = fvm.utils.create_stretched_coordinate_vector(x_start, x_end, self.nx_local, sigma) if x is None else x
            y = fvm.utils.create_stretched_coordinate_vector(y_start, y_end, self.ny_local, sigma) if y is None else y
            z = fvm.utils.create_stretched_coordinate_vector(z_start, z_end, self.nz_local, sigma) if z is None else z
        else:
            x = fvm.utils.create_uniform_coordinate_vector(x_start, x_end, self.nx_local) if x is None else x
            y = fvm.utils.create_uniform_coordinate_vector(y_start, y_end, self.ny_local) if y is None else y
            z = fvm.utils.create_uniform_coordinate_vector(z_start, z_end, self.nz_local) if z is None else z

        # Re-initialize the fvm.Interface parameters
        self.nx = self.nx_local
        self.ny = self.ny_local
        self.nz = self.nz_local
        self.discretization = fvm.Discretization(self.parameters, self.nx_local, self.ny_local, self.nz_local,
                                                 self.dim, self.dof, x, y, z)

        self.jac = None
        self.mass = None
        self.initialize()