def test_Hexmesh3(self): # Hexagonal mesh # # 1---2---7 # /5\0/1\6/7\ # 6---0---3---8 # \4/3\2/9\8/ # 5---4---9 # # Divided 2 ways # Calling order is: elements, verticies, edge list # element type, number parts edgecut, epart, npart = metis.partMeshNodal(10, 10,\ [0, 2, 1,\ 0, 3, 2,\ 0, 4, 3,\ 0, 5, 4,\ 0, 6, 5,\ 0, 1, 6,\ 3, 2, 7,\ 3, 7, 8,\ 3, 8, 9,\ 3, 9, 4],\ 1,\ 3,) #print edgecut #print epart #print npart if sys.platform == 'win32': epart_expected = array([2, 0, 2, 2, 1, 1, 0, 0, 0, 0], 'i') npart_expected = array([2, 1, 0, 0, 2, 1, 1, 0, 2, 0], 'i') self.assert_(edgecut == 12) assert allclose(epart, epart_expected) assert allclose(npart, npart_expected) elif sys.platform == 'darwin': epart_expected = array([0, 2, 2, 2, 1, 0, 0, 1, 1, 2], 'i') npart_expected = array([2, 0, 0, 1, 2, 1, 2, 0, 1, 2], 'i') self.assert_(edgecut == 13) assert allclose(epart, epart_expected) assert allclose(npart, npart_expected) else: epart_expected = array([0, 0, 0, 1, 2, 2, 2, 2, 1, 1], 'i') npart_expected = array([0, 2, 0, 2, 1, 1, 2, 2, 0, 1], 'i') self.assert_(edgecut == 14) assert allclose(epart, epart_expected) assert allclose(npart, npart_expected)
def test_Hexmesh2(self): # Hexagonal mesh # # 1---2 # / \ / \ # 6---0---3 # \ / \ / # 5---4 # # Divided 2 ways # Calling order is: elements, verticies, edge list # element type, number parts edgecut, epart, npart = metis.partMeshNodal(6, 7,\ [0, 2, 1,\ 0, 3, 2,\ 0, 4, 3,\ 0, 5, 4,\ 0, 6, 5,\ 0, 1, 6],\ 1,\ 2,) #print edgecut #print epart #print npart #print sys.platform if sys.platform == 'win32': epart_expected = array([1, 1, 1, 1, 1, 1], 'i') npart_expected = array([1, 1, 1, 1, 1, 1, 1], 'i') self.assert_(edgecut == 0) assert allclose(epart, epart_expected) assert allclose(npart, npart_expected) elif sys.platform == 'darwin': epart_expected = array([1, 1, 1, 1, 1, 1], 'i') npart_expected = array([1, 1, 1, 1, 1, 1, 1], 'i') self.assert_(edgecut == 0) assert allclose(epart, epart_expected) assert allclose(npart, npart_expected) else: epart_expected = array([1, 0, 0, 0, 1, 1], 'i') npart_expected = array([0, 1, 1, 0, 0, 0, 1], 'i') self.assert_(edgecut == 5) assert allclose(epart, epart_expected) assert allclose(npart, npart_expected)
def test_Hexmesh3(self): # Hexagonal mesh # # 1---2---7 # /5\0/1\6/7\ # 6---0---3---8 # \4/3\2/9\8/ # 5---4---9 # # Divided 2 ways # Calling order is: elements, verticies, edge list # element type, number parts edgecut, epart, npart = metis.partMeshNodal(10, 10,\ [0, 2, 1,\ 0, 3, 2,\ 0, 4, 3,\ 0, 5, 4,\ 0, 6, 5,\ 0, 1, 6,\ 3, 2, 7,\ 3, 7, 8,\ 3, 8, 9,\ 3, 9, 4],\ 1,\ 3,) #print edgecut #print epart #print npart if sys.platform == 'win32': epart_expected = array([2, 0, 2, 2, 1, 1, 0, 0, 0, 0], 'i') npart_expected = array([2, 1, 0, 0, 2, 1, 1, 0, 2, 0], 'i') self.assert_(edgecut == 12) assert allclose(epart, epart_expected) assert allclose(npart, npart_expected) else: epart_expected = array([0, 0, 0, 1, 2, 2, 2, 2, 1, 1], 'i') npart_expected = array([0, 2, 0, 2, 1, 1, 2, 2, 0, 1], 'i') self.assert_(edgecut == 14) assert allclose(epart, epart_expected) assert allclose(npart, npart_expected)
def test_Hexmesh2(self): # Hexagonal mesh # # 1---2 # / \ / \ # 6---0---3 # \ / \ / # 5---4 # # Divided 2 ways # Calling order is: elements, verticies, edge list # element type, number parts edgecut, epart, npart = metis.partMeshNodal(6, 7,\ [0, 2, 1,\ 0, 3, 2,\ 0, 4, 3,\ 0, 5, 4,\ 0, 6, 5,\ 0, 1, 6],\ 1,\ 2,) #print edgecut #print epart #print npart if sys.platform == 'win32': epart_expected = array([1, 1, 1, 1, 1, 1], 'i') npart_expected = array([1, 1, 1, 1, 1, 1, 1], 'i') self.assert_(edgecut == 0) assert allclose(epart, epart_expected) assert allclose(npart, npart_expected) else: epart_expected = array([1, 0, 0, 0, 1, 1], 'i') npart_expected = array([0, 1, 1, 0, 0, 0, 1], 'i') self.assert_(edgecut == 5) assert allclose(epart, epart_expected) assert allclose(npart, npart_expected)
def pmesh_divide_metis_helper(domain, n_procs): # Initialise the lists # List, indexed by processor of # triangles. #triangles_per_proc = [] # List of lists, indexed by processor of vertex numbers #tri_list = [] # Serial to Parallel and Parallel to Serial Triangle index maps tri_index = {} r_tri_index = {} # reverse tri index, parallel to serial triangle index mapping # Prepare variables for the metis call n_tri = len(domain.triangles) if n_procs != 1: #Because metis chokes on it... n_vert = domain.get_number_of_nodes() t_list = domain.triangles.copy() t_list = num.reshape(t_list, (-1,)) # The 1 here is for triangular mesh elements. # FIXME: Should update to Metis 5 edgecut, epart, npart = partMeshNodal(n_tri, n_vert, t_list, 1, n_procs) # print edgecut # print npart #print epart del edgecut del npart # Sometimes (usu. on x86_64), partMeshNodal returns an array of zero # dimensional arrays. Correct this. if type(epart[0]) == num.ndarray: epart_new = num.zeros(len(epart), num.int) epart_new[:] = epart[:][0] # for i in xrange(len(epart)): # epart_new[i] = epart[i][0] epart = epart_new del epart_new triangles_per_proc = num.bincount(epart) msg = "Metis created a partition where at least one submesh has no triangles. " msg += "Try using a smaller number of mpi processes." assert num.all(triangles_per_proc>0), msg proc_sum = num.zeros(n_procs+1,num.int) proc_sum[1:] = num.cumsum(triangles_per_proc) epart_order = num.argsort(epart, kind='mergesort') new_triangles = domain.triangles[epart_order] #new_r_tri_index_flat = num.zeros((n_tri,3), num.int) new_tri_index = num.zeros((n_tri,2), num.int) for i in xrange(n_procs): ids = num.arange(proc_sum[i],proc_sum[i+1]) eids = epart_order[ids] nrange = num.reshape(num.arange(triangles_per_proc[i]), (-1,1)) nones = num.ones_like(nrange) #print ids.shape #print nrange.shape new_tri_index[eids] = num.concatenate((i*nones, nrange), axis = 1) #new_r_tri_index_flat[ids] = num.concatenate((i*nones, nrange, num.reshape(eids, (-1,1))), axis = 1) if verbose: from pprint import pprint print 'epart' pprint(epart) print 'new_tri_index' pprint(new_tri_index) #print 50*'=' new_boundary = {} for b in domain.boundary: t = new_tri_index[b[0]] #print t new_boundary[proc_sum[t[0]]+t[1], b[1]] = domain.boundary[b] #quantities = reorder(domain.quantities, tri_index, proc_sum) new_quantities = reorder_new(domain.quantities, epart_order, proc_sum) else: new_boundary = domain.boundary.copy() triangles_per_proc = [n_tri] new_triangles = domain.triangles.copy() new_tri_index = [] epart_order = [] # This is essentially the same as a chunk of code from reorder. new_quantities = {} for k in domain.quantities: new_quantities[k] = num.zeros((n_tri, 3), num.float) for i in range(n_tri): new_quantities[k][i] = domain.quantities[k].vertex_values[i] # Extract the node list new_nodes = domain.get_nodes().copy() return new_nodes, new_triangles, new_boundary, triangles_per_proc, new_quantities, new_tri_index, epart_order
def pmesh_divide_metis_helper(domain, n_procs): # Initialise the lists # List, indexed by processor of # triangles. #triangles_per_proc = [] # List of lists, indexed by processor of vertex numbers #tri_list = [] # Serial to Parallel and Parallel to Serial Triangle index maps tri_index = {} r_tri_index = { } # reverse tri index, parallel to serial triangle index mapping # Prepare variables for the metis call n_tri = len(domain.triangles) if n_procs != 1: #Because metis chokes on it... n_vert = domain.get_number_of_nodes() t_list = domain.triangles.copy() t_list = num.reshape(t_list, (-1, )) # The 1 here is for triangular mesh elements. # FIXME: Should update to Metis 5 edgecut, epart, npart = partMeshNodal(n_tri, n_vert, t_list, 1, n_procs) # print edgecut # print npart #print epart del edgecut del npart # Sometimes (usu. on x86_64), partMeshNodal returns an array of zero # dimensional arrays. Correct this. if type(epart[0]) == num.ndarray: epart_new = num.zeros(len(epart), num.int) epart_new[:] = epart[:][0] # for i in xrange(len(epart)): # epart_new[i] = epart[i][0] epart = epart_new del epart_new triangles_per_proc = num.bincount(epart) msg = "Metis created a partition where at least one submesh has no triangles. " msg += "Try using a smaller number of mpi processes." assert num.all(triangles_per_proc > 0), msg proc_sum = num.zeros(n_procs + 1, num.int) proc_sum[1:] = num.cumsum(triangles_per_proc) epart_order = num.argsort(epart, kind='mergesort') new_triangles = domain.triangles[epart_order] #new_r_tri_index_flat = num.zeros((n_tri,3), num.int) new_tri_index = num.zeros((n_tri, 2), num.int) for i in xrange(n_procs): ids = num.arange(proc_sum[i], proc_sum[i + 1]) eids = epart_order[ids] nrange = num.reshape(num.arange(triangles_per_proc[i]), (-1, 1)) nones = num.ones_like(nrange) #print ids.shape #print nrange.shape new_tri_index[eids] = num.concatenate((i * nones, nrange), axis=1) #new_r_tri_index_flat[ids] = num.concatenate((i*nones, nrange, num.reshape(eids, (-1,1))), axis = 1) if verbose: from pprint import pprint print 'epart' pprint(epart) print 'new_tri_index' pprint(new_tri_index) #print 50*'=' new_boundary = {} for b in domain.boundary: t = new_tri_index[b[0]] #print t new_boundary[proc_sum[t[0]] + t[1], b[1]] = domain.boundary[b] #quantities = reorder(domain.quantities, tri_index, proc_sum) new_quantities = reorder_new(domain.quantities, epart_order, proc_sum) else: new_boundary = domain.boundary.copy() triangles_per_proc = [n_tri] new_triangles = domain.triangles.copy() new_tri_index = [] epart_order = [] # This is essentially the same as a chunk of code from reorder. new_quantities = {} for k in domain.quantities: new_quantities[k] = num.zeros((n_tri, 3), num.float) for i in range(n_tri): new_quantities[k][i] = domain.quantities[k].vertex_values[i] # Extract the node list new_nodes = domain.get_nodes().copy() return new_nodes, new_triangles, new_boundary, triangles_per_proc, new_quantities, new_tri_index, epart_order