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