def toMesh(self, meshID=None): if meshID == None: meshID = self.filename if meshID[-4:].lower() == '.inp': meshID = meshID[:-4] for count, dict_elm in enumerate(self.__Element): if len(self.__Element) < 2: importedMeshName = meshID else: importedMeshName = meshID + str(count) elm = self.__ConvertNode(dict_elm['ElementTable']) Mesh(self.__NodeCoordinate, elm, dict_elm['ElementType'], ID=importedMeshName) #add set of nodes for SetOfId, NodeIndexes in enumerate(self.__NodeSet): Mesh.GetAll()[importedMeshName].AddSetOfNodes( self.__ConvertNode(NodeIndexes), SetOfId) ElementNumber = dict_elm['ElementNumber'] ConvertElementDict = dict( zip(ElementNumber, list(range(0, len(ElementNumber))))) ConvertElement = np.vectorize(ConvertElementDict.get) #function for SetOfId, ElementIndexes in enumerate(self.__ElementSet): Temp = ConvertElement(ElementIndexes) Mesh.GetAll()[importedMeshName].AddSetOfElements( Temp[Temp != None].astype(int), SetOfId)
def GridMeshCylindric(Nr=11, Ntheta=11, r_min=0, r_max=1, theta_min=0, theta_max=1, ElementShape = 'quad4', init_rep_loc = 0, ID = ""): """ Define the mesh as a grid in cylindrical coordinate Parameters ---------- Nx, Ny : int Numbers of nodes in the x and y axes (default = 11). x_min, x_max, y_min, y_max : int,float The boundary of the square (default : 0, 1, 0, 1). ElementShape : {'tri3', 'quad4', 'quad8', 'quad9'} The type of the element generated (default='quad4') * 'tri3' -- 3 node linear triangular mesh * 'quad4' -- 4 node quadrangular mesh * 'quad8' -- 8 node quadrangular mesh (à tester) * 'quad9' -- 9 node quadrangular mesh init_rep_loc : {0, 1} if init_rep_loc is set to 1, the local basis is initialized with the global basis. Returns ------- Mesh The generated geometry in Mesh format. See the Mesh class for more details. See Also -------- LineMesh : 1D mesh of a line RectangleMesh : Surface mesh of a rectangle BoxMesh : Volume mesh of a box LineMeshCylindric : Line mesh in cylindrical coordinate """ if theta_min<theta_max: m = RectangleMesh(Nr, Ntheta, r_min, r_max, theta_min, theta_max, ElementShape, ID) else: m = RectangleMesh(Nr, Ntheta, r_min, r_max, theta_max, theta_min, ElementShape, ID) r = m.GetNodeCoordinates()[:,0] theta = m.GetNodeCoordinates()[:,1] crd = np.c_[r*np.cos(theta) , r*np.sin(theta)] ReturnedMesh = Mesh(crd, m.GetElementTable(), ElementShape, m.GetLocalFrame(), ID) if theta_min<theta_max: ReturnedMesh.AddSetOfNodes(m.GetSetOfNodes("left"), "bottom") ReturnedMesh.AddSetOfNodes(m.GetSetOfNodes("right"), "top") ReturnedMesh.AddSetOfNodes(m.GetSetOfNodes("bottom"), "left") ReturnedMesh.AddSetOfNodes(m.GetSetOfNodes("top"), "right") else: ReturnedMesh.AddSetOfNodes(m.GetSetOfNodes("left"), "bottom") ReturnedMesh.AddSetOfNodes(m.GetSetOfNodes("right"), "top") ReturnedMesh.AddSetOfNodes(m.GetSetOfNodes("top"), "left") ReturnedMesh.AddSetOfNodes(m.GetSetOfNodes("bottom"), "right") return ReturnedMesh
def LineMeshCylindric(Ntheta=11, r=1, theta_min=0, theta_max=3.14, ElementShape='lin2', init_rep_loc=0, ID=""): """ Define the mesh of a line in cylindrical coordinates Parameters ---------- Ntheta : int Numbers of nodes along the angular coordinate (default = 11). theta_min, theta_max : int,float The boundary of the line defined by the angular coordinate (default : 0, 3.14). ElementShape : {'lin2', 'lin3', 'lin4'} The shape of the elements (default='lin2') * 'lin2' -- 2 node line * 'lin3' -- 3 node line * 'lin4' -- 4 node line init_rep_loc : {0, 1} if init_rep_loc is set to 1, the local frame is initialized with the cylindrical local basis. Returns ------- Mesh The generated geometry in Mesh format. See the Mesh class for more details. See Also -------- LineMesh : Mesh of a line whith choosen dimension RectangleMesh : Surface mesh of a rectangle BoxMesh : Volume mesh of a box GridMeshCylindric : Surface mesh of a grid in cylindrical coodrinate LineMeshCylindric : Line mesh in cylindrical coordinate """ # init_rep_loc = 1 si on veut initialiser le repère local (0 par défaut) m = LineMesh1D(Ntheta, theta_min, theta_max, ElementShape, ID) theta = m.GetNodeCoordinates()[:, 0] elm = m.GetElementTable() LocalFrame = np.array([[[np.sin(t), -np.cos(t)], [np.cos(t), np.sin(t)]] for t in theta]) crd = np.c_[r * np.cos(theta), r * np.sin(theta)] ReturnedMesh = Mesh(crd, elm, ElementShape, LocalFrame, ID) ReturnedMesh.AddSetOfNodes(m.GetSetOfNodes("left"), "left") ReturnedMesh.AddSetOfNodes(m.GetSetOfNodes("right"), "right") return ReturnedMesh
def LineMesh1D(N=11, x_min=0, x_max=1, ElementShape='lin2', ID=""): """ Define the mesh of a line with corrdinates in 1D. Parameters ---------- N : int Numbers of nodes (default = 11). x_min, x_max : int,float The boundary of the line (default : 0, 1). ElementShape : {'lin2', 'lin3', 'lin4'} The shape of the elements (default='lin2') * 'lin2' -- 2 node line * 'lin3' -- 3 node line * 'lin4' -- 4 node line Returns ------- Mesh The generated geometry in Mesh format. See the Mesh class for more details. See Also -------- LineMesh : Mesh of a line whith choosen dimension RectangleMesh : Surface mesh of a rectangle BoxMesh : Volume mesh of a box GridMeshCylindric : Surface mesh of a grid in cylindrical coodrinate LineMeshCylindric : Line mesh in cylindrical coordinate """ if ElementShape == 'lin2': #1D element with 2 nodes crd = np.c_[np.linspace(x_min, x_max, N)] #Nodes coordinates elm = np.c_[range(N - 1), np.arange(1, N)] #Elements elif ElementShape == 'lin3': #1D element with 3 nodes N = N // 2 * 2 + 1 #In case N is not initially odd crd = np.c_[np.linspace(x_min, x_max, N)] #Nodes coordinates elm = np.c_[np.arange(0, N - 2, 2), np.arange(1, N - 1, 2), np.arange(2, N, 2)] #Elements elif ElementShape == 'lin4': N = N // 3 * 3 + 1 crd = np.c_[np.linspace(x_min, x_max, N)] #Nodes coordinates elm = np.c_[np.arange(0, N - 3, 3), np.arange(1, N - 2, 3), np.arange(2, N - 1, 3), np.arange(3, N, 3)] #Elements ReturnedMesh = Mesh(crd, elm, ElementShape, None, ID) ReturnedMesh.AddSetOfNodes([0], "left") ReturnedMesh.AddSetOfNodes([N - 1], "right") return ReturnedMesh
def SetElementType(self, listElementType, listSubMesh=None): """ Define the Type of Element used for the finite element assembly of each subMesh Example of available element type: 'lin2', 'beam', 'tri6', ... PGD.Assembly.SetElementType([ElementType_1,...,ElementType_n ]) * ElementType_i is a list of ElementType cooresponding to the ith subMesh (as defined in the constructor of the PGD.Mesh object related to the Assembly) PGD.Assembly.SetElementType([ElementType_1,...,ElementType_n ], [subMesh_1,...,subMesh_n] ) * ElementType_i is a list of ElementType cooresponding to the mesh indicated in subMesh_i * subMesh_i can be either a mesh ID (str object) or a Mesh object * If a subMesh is not included in listSubMesh, the ElementType for assembly is not modified (based on the geometrical element shape by default) """ if listSubMesh is None: if len(listElementType) != len(self.__Mesh.GetListMesh()): assert 0, "The lenght of the Element Type List must be equal to the number of submeshes" self.__listElementType = [ ElementType for ElementType in listElementType ] self.__listNumberOfGaussPoints = [ GetDefaultNbPG(self.__listElementType[dd], self.__Mesh.GetListMesh()[dd]) for dd in range(len(self.__listElementType)) ] #Nb_pg for every subMesh defined in self.__Mesh (default value) else: for i, m in enumerate(listSubMesh): if isinstance(m, str): m = MeshFEM.GetAll()[m] dd = self.__Mesh.GetListMesh().index(m) self.__listElementType[dd] = listElementType[i] self.__listNumberOfGaussPoints[dd] = GetDefaultNbPG( listElementType[i], m)
def GenerateCylindricalLocalFrame(crd, axis=2, origin=[0, 0, 0], dim=3): if isinstance(crd, MeshFEM): crd = MeshFEM.GetNodeCoordinates() localFrame = np.zeros((len(crd), dim, dim)) if dim == 3: plane = [0, 1, 2] plane.pop(axis) localFrame[:, 2, axis] = 1. #ez else: plane = [0, 1] crd = crd[:, 0:2] origin = np.array(origin)[0:2] crd = crd - np.array(origin).reshape(1, -1) #changement of origin localFrame[:, 0, plane] = crd[:, plane] / np.sqrt(crd[:, plane[0]]**2 + crd[:, plane[1]]**2).reshape( -1, 1) #er if dim == 3: localFrame[:, 1] = np.cross(localFrame[:, 2], localFrame[:, 0]) #etheta is the cross product else: localFrame[:, 1, 0] = -localFrame[:, 0, 1] localFrame[:, 1, 1] = localFrame[:, 0, 0] return localFrame.view(LocalFrame)
def GridStructuredMesh2D(data, Edge1, Edge2, Edge3, Edge4, ElementShape = 'quad4', ID =""): # #Edge1 and Edge3 should have the same lenght # #Edge2 and Edge4 should have the same lenght # #last node of Edge1 should be the first of Edge2 and so on... # if no ID is defined, the ID is the same as crd if hasattr(data,'GetElementTable'): #data is a mesh if data.GetElementTable() is None: elm = [] else: elm = list(data.GetElementTable()) ElementShape = data.GetElementShape() crd = data.GetNodeCoordinates() if ID == "": ID = data.GetID() else: elm = [] crd = data x1 = crd[Edge1,0] ; x2 = crd[Edge2,0] ; x3 = crd[Edge3,0][::-1] ; x4 = crd[Edge4,0][::-1] y1 = crd[Edge1,1] ; y2 = crd[Edge2,1] ; y3 = crd[Edge3,1][::-1] ; y4 = crd[Edge4,1][::-1] new_crd = list(crd.copy()) grid = np.empty((len(x1), len(x2))) grid[0,:] = Edge4[::-1] ; grid[-1,:] = Edge2 grid[:,0] = Edge1 ; grid[:,-1] = Edge3[::-1] N = len(new_crd) for i in range(1,len(x1)-1): px= ( (x1[i]*y3[i]-y1[i]*x3[i])*(x2-x4)-(x1[i]-x3[i])*(x2*y4-y2*x4) ) / ( (x1[i]-x3[i])*(y2-y4)-(y1[i]-y3[i])*(x2-x4) ) py= ( (x1[i]*y3[i]-y1[i]*x3[i])*(y2-y4)-(y1[i]-y3[i])*(x2*y4-y2*x4) ) / ( (x1[i]-x3[i])*(y2-y4)-(y1[i]-y3[i])*(x2-x4) ) new_crd += list(np.c_[px[1:-1],py[1:-1]]) grid[i,1:-1] = np.arange(N,len(new_crd),1) N = len(new_crd) Nx = grid.shape[0] ; Ny = grid.shape[1] if ElementShape == 'quad4': elm += [[grid[i,j], grid[i+1,j],grid[i+1,j+1], grid[i,j+1]] for j in range(Ny-1) for i in range(Nx-1)] elif ElementShape == 'quad9': elm += [[grid[i,j],grid[i+2,j],grid[i+2,j+2],grid[i,j+2],grid[i+1,j],grid[i+2,j+1],grid[i+1,j+2],grid[i,j+1],grid[i+1,j+1]] for j in range(0,Ny-2,2) for i in range(0,Nx-2,2)] elif ElementShape == 'tri3': for j in range(Ny-1): elm += [[grid[i,j],grid[i+1,j],grid[i,j+1]] for i in range(Nx-1)] elm += [[grid[i+1,j],grid[i+1,j+1],grid[i,j+1]] for i in range(Nx-1)] elif ElementShape == 'tri6': for j in range(0,Ny-2,2): elm += [[grid[i,j],grid[i+2,j],grid[i,j+2], grid[i+1,j],grid[i+1,j+1],grid[i,j+1]] for i in range(0,Nx-2,2)] elm += [[grid[i+2,j],grid[i+2,j+2],grid[i,j+2], grid[i+2,j+1],grid[i+1,j+2],grid[i+1,j+1]] for i in range(0,Nx-2,2)] elif ElementShape == 'quad8': raise NameError("'quad8' elements are not implemented") elm = np.array(elm, dtype=int) return Mesh(np.array(new_crd), elm, ElementShape, None, ID)
def LineMesh(N=11, x_min=0, x_max=1, ElementShape='lin2', ID=""): """ Define the mesh of a line Parameters ---------- N : int Numbers of nodes (default = 11). x_min, x_max : int,float,list The boundary of the line as scalar (1D) or list (default : 0, 1). ElementShape : {'lin2', 'lin3', 'lin4'} The shape of the elements (default='lin2') * 'lin2' -- 2 node line * 'lin3' -- 3 node line * 'lin4' -- 4 node line Returns ------- Mesh The generated geometry in Mesh format. See the Mesh class for more details. See Also -------- RectangleMesh : Surface mesh of a rectangle BoxMesh : Volume mesh of a box GridMeshCylindric : Surface mesh of a grid in cylindrical coodrinate LineMeshCylindric : Line mesh in cylindrical coordinate """ if np.isscalar(x_min): m = LineMesh1D(N, x_min, x_max, ElementShape, ID) if ProblemDimension.Get() in ['2Dplane', '2Dstress']: dim = 2 else: dim = 3 crd = np.c_[m.GetNodeCoordinates(), np.zeros((N, dim - 1))] elm = m.GetElementTable() ReturnedMesh = Mesh(crd, elm, ElementShape, None, ID) ReturnedMesh.AddSetOfNodes(m.GetSetOfNodes("left"), "left") ReturnedMesh.AddSetOfNodes(m.GetSetOfNodes("right"), "right") else: m = LineMesh1D(N, 0., 1., ElementShape, ID) crd = m.GetNodeCoordinates() crd = (np.array(x_max) - np.array(x_min)) * crd + np.array(x_min) elm = m.GetElementTable() ReturnedMesh = Mesh(crd, elm, ElementShape, None, ID) ReturnedMesh.AddSetOfNodes(m.GetSetOfNodes("left"), "left") ReturnedMesh.AddSetOfNodes(m.GetSetOfNodes("right"), "right") return ReturnedMesh
def __init__(self, weakForm, mesh="", ID=""): #mesh should be of type PGD.Mesh if isinstance(weakForm, str): weakForm = WeakForm.GetAll()[weakForm] if isinstance(mesh, str): mesh = MeshFEM.GetAll()[mesh] AssemblyBase.__init__(self, ID) self.__weakForm = weakForm self.__Mesh = mesh #should be a MeshPGD object self.__listElementType = [ m.GetElementShape() for m in mesh.GetListMesh() ] #ElementType for every subMesh defined in self.__Mesh self.__listNumberOfGaussPoints = [ GetDefaultNbPG(eltype) for eltype in self.__listElementType ] #Nb_pg for every subMesh defined in self.__Mesh (default value)
def __init__(self, weakForm, mesh="", elementType="", ID="", **kargs): # t0 = time.time() if isinstance(weakForm, str): weakForm = WeakForm.GetAll()[weakForm] if isinstance(mesh, str): mesh = Mesh.GetAll()[mesh] AssemblyBase.__init__(self, ID) self.__MeshChange = kargs.pop('MeshChange', False) self.__Mesh = mesh self.__weakForm = weakForm self.__elmType = elementType #.lower() self.__nb_pg = kargs.pop('nb_pg', None) if self.__nb_pg is None: self.__nb_pg = GetDefaultNbPG(elementType, mesh) #print('Finite element operator for Assembly "' + ID + '" built in ' + str(time.time()-t0) + ' seconds') self.computeMatrixMethod = 'new'
def BoxMesh(Nx=11, Ny=11, Nz=11, x_min=0, x_max=1, y_min=0, y_max=1, z_min=0, z_max=1, ElementShape='hex8', ID=""): """ Define the mesh of a box Parameters ---------- Nx, Ny, Nz : int Numbers of nodes in the x, y and z axes (default = 11). x_min, x_max, y_min, y_max, z_min, z_max : int,float The boundary of the box (default : 0, 1, 0, 1, 0, 1). ElementShape : {'hex8', 'hex20'} The type of the element generated (default='hex8') * 'hex8' -- 8 node hexahedron * 'hex20' -- 20 node second order hexahedron Returns ------- Mesh The generated geometry in Mesh format. See the Mesh class for more details. See Also -------- LineMesh : 1D mesh of a line RectangleMesh : Surface mesh of a rectangle GridMeshCylindric : Surface mesh of a grid in cylindrical coodrinate LineMeshCylindric : Line mesh in cylindrical coord """ Y, Z, X = np.meshgrid(np.linspace(y_min, y_max, Ny), np.linspace(z_min, z_max, Nz), np.linspace(x_min, x_max, Nx)) crd = np.c_[np.reshape(X, (-1, 1)), np.reshape(Y, (-1, 1)), np.reshape(Z, (-1, 1))] if ElementShape == 'hex20': dx = (x_max - x_min) / (Nx - 1.) dy = (y_max - y_min) / (Ny - 1.) dz = (z_max - z_min) / (Nz - 1.) Y, Z, X = np.meshgrid( np.linspace(y_min, y_max, Ny), np.linspace(z_min, z_max, Nz), np.linspace(x_min + dx / 2., x_max + dx / 2., Nx - 1, endpoint=False)) crd2 = np.c_[np.reshape(X, (-1, 1)), np.reshape(Y, (-1, 1)), np.reshape(Z, (-1, 1))] Y, Z, X = np.meshgrid( np.linspace(y_min, y_max, Ny), np.linspace(z_min + dz / 2., z_max + dz / 2., Nz - 1, endpoint=False), np.linspace(x_min, x_max, Nx)) crd3 = np.c_[np.reshape(X, (-1, 1)), np.reshape(Y, (-1, 1)), np.reshape(Z, (-1, 1))] Y, Z, X = np.meshgrid( np.linspace(y_min + dy / 2., y_max + dy / 2., Ny - 1, endpoint=False), np.linspace(z_min, z_max, Nz), np.linspace(x_min, x_max, Nx)) crd4 = np.c_[np.reshape(X, (-1, 1)), np.reshape(Y, (-1, 1)), np.reshape(Z, (-1, 1))] crd = np.vstack((crd, crd2, crd3, crd4)) elm = [[Nx*j+i+(k*Nx*Ny), Nx*j+i+1+(k*Nx*Ny), Nx*(j+1)+i+1+(k*Nx*Ny), Nx*(j+1)+i+(k*Nx*Ny), \ Nx*j+i+(k*Nx*Ny)+Nx*Ny, Nx*j+i+1+(k*Nx*Ny)+Nx*Ny, Nx*(j+1)+i+1+(k*Nx*Ny)+Nx*Ny, Nx*(j+1)+i+(k*Nx*Ny)+Nx*Ny, \ Nx*Ny*Nz+(Nx-1)*j+i+k*(Nx-1)*Ny,Nx*j+i+1+Nx*Ny*Nz+(Nx-1)*Ny*Nz+(Nz-1)*Nx*Ny+(k*Nx*(Ny-1)),Nx*Ny*Nz+(Nx-1)*(j+1)+i+k*(Nx-1)*Ny,Nx*j+i+Nx*Ny*Nz+(Nx-1)*Ny*Nz+(Nz-1)*Nx*Ny+(k*Nx*(Ny-1)), \ Nx*Ny*Nz+(Nx-1)*Ny*Nz+Nx*j+i+k*Ny*Nx,Nx*Ny*Nz+(Nx-1)*Ny*Nz+Nx*j+i+1+k*Ny*Nx,Nx*Ny*Nz+(Nx-1)*Ny*Nz+Nx+Nx*j+i+1+k*Ny*Nx,Nx*Ny*Nz+(Nx-1)*Ny*Nz+Nx+Nx*j+i+k*Ny*Nx, \ Nx*Ny*Nz+(Nx-1)*Ny+(Nx-1)*j+i+k*(Nx-1)*Ny,Nx*j+i+1+Nx*Ny*Nz+(Nx-1)*Ny*Nz+(Nz-1)*Nx*Ny+Nx*(Ny-1)+(k*Nx*(Ny-1)),Nx*Ny*Nz+(Nx-1)*Ny+(Nx-1)*(j+1)+i+k*(Nx-1)*Ny,Nx*j+i+Nx*Ny*Nz+(Nx-1)*Ny*Nz+(Nz-1)*Nx*Ny+Nx*(Ny-1)+(k*Nx*(Ny-1))] for k in range(Nz-1) for j in range(Ny-1) for i in range(Nx-1)] bottom = [nd for nd in range(Ny * Nx)] + range( Nx * Ny * Nz, (Nx - 1) * Ny + Nx * Ny * Nz) + range( Nx * Ny * Nz + (Nx - 1) * Ny * Nz + (Nz - 1) * Nx * Ny, Nx * Ny * Nz + (Nx - 1) * Ny * Nz + (Nz - 1) * Nx * Ny + (Ny - 1) * Nx) top = [nd for nd in range((Nz - 1) * Ny * Nx, Nz * Nx * Ny)] + range( Nx * Ny * Nz + (Nx - 1) * Ny * (Nz - 1), Nx * Ny * Nz + (Nx - 1) * Ny * Nz) + range( Nx * Ny * Nz + (Nx - 1) * Ny * Nz + (Nz - 1) * Nx * Ny + (Ny - 1) * Nx * (Nz - 1), Nx * Ny * Nz + (Nx - 1) * Ny * Nz + (Nz - 1) * Nx * Ny + (Ny - 1) * Nx * Nz) left = list( itertools.chain.from_iterable([ range(i * Nx * Ny, i * Nx * Ny + Nx * Ny, Nx) for i in range(Nz) ])) + range(Nx * Ny * Nz + (Nx - 1) * Ny * Nz, Nx * Ny * Nz + (Nx - 1) * Ny * Nz + (Nz - 1) * Nx * Ny, Nx) + range( Nx * Ny * Nz + (Nx - 1) * Ny * Nz + (Nz - 1) * Nx * Ny, Nx * Ny * Nz + (Nx - 1) * Ny * Nz + (Nz - 1) * Nx * Ny + Nx * (Ny - 1) * Nz, Nx) right = list( itertools.chain.from_iterable([ range(i * Nx * Ny + Nx - 1, i * Nx * Ny + Nx * Ny, Nx) for i in range(Nz) ])) + range(Nx * Ny * Nz + (Nx - 1) * Ny * Nz + Nx - 1, Nx * Ny * Nz + (Nx - 1) * Ny * Nz + (Nz - 1) * Nx * Ny, Nx) + range( Nx * Ny * Nz + (Nx - 1) * Ny * Nz + (Nz - 1) * Nx * Ny + Nx - 1, Nx * Ny * Nz + (Nx - 1) * Ny * Nz + (Nz - 1) * Nx * Ny + Nx * (Ny - 1) * Nz, Nx) front = list( itertools.chain.from_iterable([ range(i * Nx * Ny, i * Nx * Ny + Nx) for i in range(Nz) ])) + list( itertools.chain.from_iterable([ range(i * (Nx - 1) * Ny + Nx * Ny * Nz, i * (Nx - 1) * Ny + Nx * Ny * Nz + Nx - 1) for i in range(Nz) ])) + list( itertools.chain.from_iterable([ range( i * Nx * Ny + Nx * Ny * Nz + (Nx - 1) * Ny * Nz, i * Nx * Ny + Nx * Ny * Nz + (Nx - 1) * Ny * Nz + Nx) for i in range(Nz - 1) ])) back = list( itertools.chain.from_iterable([ range(i * Nx * Ny + Nx * Ny - Nx, i * Nx * Ny + Nx * Ny) for i in range(Nz) ])) + list( itertools.chain.from_iterable([ range( i * (Nx - 1) * Ny + Nz * Nx * Ny + (Nx - 1) * (Ny - 1), i * (Nx - 1) * Ny + Nz * Nx * Ny + (Nx - 1) * (Ny - 1) + Nx - 1) for i in range(Nz) ])) + list( itertools.chain.from_iterable([ range( i * Nx * Ny + Nz * Nx * Ny + (Nx - 1) * Ny * Nz + (Ny - 1) * Nx, i * Nx * Ny + Nz * Nx * Ny + (Nx - 1) * Ny * Nz + (Ny - 1) * Nx + Nx) for i in range(Nz - 1) ])) if ElementShape == 'hex8': elm = [[ Nx * j + i + (k * Nx * Ny), Nx * j + i + 1 + (k * Nx * Ny), Nx * (j + 1) + i + 1 + (k * Nx * Ny), Nx * (j + 1) + i + (k * Nx * Ny), Nx * j + i + (k * Nx * Ny) + Nx * Ny, Nx * j + i + 1 + (k * Nx * Ny) + Nx * Ny, Nx * (j + 1) + i + 1 + (k * Nx * Ny) + Nx * Ny, Nx * (j + 1) + i + (k * Nx * Ny) + Nx * Ny ] for k in range(Nz - 1) for j in range(Ny - 1) for i in range(Nx - 1)] front = list( itertools.chain.from_iterable( [range(i * Nx * Ny, i * Nx * Ny + Nx) for i in range(Nz)]) ) # [item for sublist in bas for item in sublist] #flatten a list back = list( itertools.chain.from_iterable([ range(i * Nx * Ny + Nx * Ny - Nx, i * Nx * Ny + Nx * Ny) for i in range(Nz) ])) left = list( itertools.chain.from_iterable([ range(i * Nx * Ny, i * Nx * Ny + Nx * Ny, Nx) for i in range(Nz) ])) right = list( itertools.chain.from_iterable([ range(i * Nx * Ny + Nx - 1, i * Nx * Ny + Nx * Ny, Nx) for i in range(Nz) ])) bottom = [nd for nd in range(Ny * Nx)] top = [nd for nd in range((Nz - 1) * Ny * Nx, Nz * Nx * Ny)] else: raise NameError( 'Element not implemented. Only support hex8 and hex20 elements') N = np.shape(crd)[0] elm = np.array(elm) ReturnedMesh = Mesh(crd, elm, ElementShape, None, ID) for i, ndSet in enumerate([right, left, top, bottom, front, back]): ndSetId = ('right', 'left', 'top', 'bottom', 'front', 'back')[i] ReturnedMesh.AddSetOfNodes(ndSet, ndSetId) return ReturnedMesh
def RectangleMesh(Nx=11, Ny=11, x_min=0, x_max=1, y_min=0, y_max=1, ElementShape='quad4', ID=""): """ Define the mesh of a rectangle. Parameters ---------- Nx, Ny : int Numbers of nodes in the x and y axes (default = 11). x_min, x_max, y_min, y_max : int,float The boundary of the square (default : 0, 1, 0, 1). ElementShape : {'tri3', 'quad4', 'quad8', 'quad9'} The type of the element generated (default='quad4') * 'tri3' -- 3 node linear triangular mesh * 'tri6' -- 6 node linear triangular mesh * 'quad4' -- 4 node quadrangular mesh * 'quad8' -- 8 node quadrangular mesh (à tester) * 'quad9' -- 9 node quadrangular mesh Returns ------- Mesh The generated geometry in Mesh format. See the Mesh class for more details. See Also -------- LineMesh : 1D mesh of a line RectangleMesh : Surface mesh of a rectangle BoxMesh : Volume mesh of a box GridMeshCylindric : Surface mesh of a grid in cylindrical coodrinate LineMeshCylindric : Line mesh in cylindrical coordinate """ if ElementShape == 'quad9' or ElementShape == 'tri6': Nx = int(Nx // 2 * 2 + 1) Ny = int(Ny // 2 * 2 + 1) #pour nombre impair de noeuds X, Y = np.meshgrid(np.linspace(x_min, x_max, Nx), np.linspace(y_min, y_max, Ny)) crd = np.c_[np.reshape(X, (-1, 1)), np.reshape(Y, (-1, 1))] if ElementShape == 'quad8': dx = (x_max - x_min) / (Nx - 1.) dy = (y_max - y_min) / (Ny - 1.) X, Y = np.meshgrid( np.linspace(x_min + dx / 2., x_max - dx / 2., Nx - 1), np.linspace(y_min, y_max, Ny)) crd2 = np.c_[np.reshape(X, (-1, 1)), np.reshape(Y, (-1, 1))] X, Y = np.meshgrid(np.linspace(x_min, x_max, Nx), np.linspace(y_min + dy / 2, y_max - dy / 2, Ny - 1)) crd3 = np.c_[np.reshape(X, (-1, 1)), np.reshape(Y, (-1, 1))] crd = np.vstack((crd, crd2, crd3)) elm = [[ Nx * j + i, Nx * j + i + 1, Nx * (j + 1) + i + 1, Nx * (j + 1) + i, Nx * Ny + (Nx - 1) * j + i, Nx * Ny + (Nx - 1) * Ny + Nx * j + i + 1, Nx * Ny + (Nx - 1) * (j + 1) + i, Nx * Ny + (Nx - 1) * Ny + Nx * j + i ] for j in range(0, Ny - 1) for i in range(0, Nx - 1)] elif ElementShape == 'quad4': elm = [[ Nx * j + i, Nx * j + i + 1, Nx * (j + 1) + i + 1, Nx * (j + 1) + i ] for j in range(Ny - 1) for i in range(Nx - 1)] elif ElementShape == 'quad9': elm = [[ Nx * j + i, Nx * j + i + 2, Nx * (j + 2) + i + 2, Nx * (j + 2) + i, Nx * j + i + 1, Nx * (j + 1) + i + 2, Nx * (j + 2) + i + 1, Nx * (j + 1) + i, Nx * (j + 1) + i + 1 ] for j in range(0, Ny - 2, 2) for i in range(0, Nx - 2, 2)] elif ElementShape == 'tri3': elm = [] for j in range(Ny - 1): elm += [[Nx * j + i, Nx * j + i + 1, Nx * (j + 1) + i] for i in range(Nx - 1)] elm += [[Nx * j + i + 1, Nx * (j + 1) + i + 1, Nx * (j + 1) + i] for i in range(Nx - 1)] elif ElementShape == 'tri6': elm = [] for j in range(0, Ny - 2, 2): elm += [[ Nx * j + i, Nx * j + i + 2, Nx * (j + 2) + i, Nx * j + i + 1, Nx * (j + 1) + i + 1, Nx * (j + 1) + i ] for i in range(0, Nx - 2, 2)] elm += [[ Nx * j + i + 2, Nx * (j + 2) + i + 2, Nx * (j + 2) + i, Nx * (j + 1) + i + 2, Nx * (j + 2) + i + 1, Nx * (j + 1) + i + 1 ] for i in range(0, Nx - 2, 2)] elm = np.array(elm) ReturnedMesh = Mesh(crd, elm, ElementShape, None, ID) if ElementShape != 'quad8': N = ReturnedMesh.GetNumberOfNodes() ReturnedMesh.AddSetOfNodes([nd for nd in range(Nx)], 'bottom') ReturnedMesh.AddSetOfNodes([nd for nd in range(N - Nx, N)], 'top') ReturnedMesh.AddSetOfNodes([nd for nd in range(0, N, Nx)], 'left') ReturnedMesh.AddSetOfNodes([nd for nd in range(Nx - 1, N, Nx)], 'right') else: print('Warning: no boundary set of nodes defined for quad8 elements') return ReturnedMesh
def ImportFromVTK(filename, meshID=None): filename = filename.strip() if meshID == None: meshID = filename if meshID[-4:].lower() == '.vtk': meshID = meshID[:-4] #print 'Reading file',`filename` f = open(filename, 'r') vtk = f.read() f.close() vtk = vtk.split('\n') vtk = [line.strip() for line in vtk if line.strip() != ''] l = vtk.pop(0) fileversion = l.replace(' ', '').lower() if not fileversion == '#vtkdatafileversion2.0': print('File %s is not in VTK 2.0 format, got %s' % (filename, fileversion)) print(' but continuing anyway..') header = vtk.pop(0) format = vtk.pop(0).lower() if format not in ['ascii', 'binary']: raise ValueError('Expected ascii|binary but got %s' % (format)) if format == 'binary': raise NotImplementedError('reading vtk binary format') l = vtk.pop(0).lower() if l[0:7] != 'dataset': raise ValueError('expected dataset but got %s' % (l[0:7])) if l[-17:] != 'unstructured_grid': raise NotImplementedError('Only unstructured grid are implemented') point_data = False cell_data = False NodeData = [] ElmData = [] NodeDataName = [] ElmDataName = [] # à partir de maintenant il n'y a plus d'ordre. il faut tout tester. while vtk != []: l = vtk.pop(0).split() if l[0].lower() == 'points': Nb_nodes = int(l[1]) #l[2] est considéré comme float dans tous les cas crd = np.array([vtk[nd].split() for nd in range(Nb_nodes)], dtype=float) del vtk[0:Nb_nodes] elif l[0].lower() == 'cells': Nb_el = int(l[1]) cells = vtk[0:Nb_el] del vtk[0:Nb_el] elif l[0].lower() == 'cell_types': Nb_el = int(l[1]) celltype_all = np.array(vtk[0:Nb_el], dtype=int) del vtk[0:Nb_el] elif l[0].lower() == 'point_data': Nb_nodes = int(l[1]) point_data = True cell_data = False elif l[0].lower() == 'cell_data': Nb_el = int(l[1]) point_data = False cell_data = True if l[0].lower() == 'scalars' or l[0].lower() == 'vectors': name = l[1] #l[2] est considéré comme float dans tous les cas if l[0].lower() == 'scalars': vtk.pop(0) #lookup_table not implemented ncol = int(l[3]) elif l[0].lower() == 'vectors': ncol = 3 if point_data == True: NodeData.append( np.reshape( np.array(' '.join([vtk[ii] for ii in range(Nb_nodes)]).split(), dtype=float), (-1, ncol))) # NodeData.append(np.array([vtk[ii].split() for ii in range(Nb_nodes)], dtype = float)) NodeDataName.append(name) del vtk[0:Nb_nodes] elif cell_data == True: ElmData.append( np.reshape( np.array(' '.join([vtk[ii] for ii in range(Nb_el)]).split(), dtype=float), (-1, ncol))) # ElmData.append(np.array([vtk[ii].split() for ii in range(Nb_el)], dtype = float)) print(np.shape(ElmData)) ElmDataName.append(name) del vtk[0:Nb_el] else: Print('Warning: Data ignored') if l[0].lower() == 'tensors': Print('Warning: tensor data not implemented. Data ignored') if point_data == True: del vtk[0:Nb_nodes] elif cell_data == True: del vtk[0:Nb_el] #Traitement des éléments count = 0 for celltype in list(np.unique(celltype_all)): list_el = np.where(celltype_all == celltype)[0] elm = np.array([cells[el].split()[1:] for el in list_el], dtype=int) type_elm = { '3': 'lin2', '5': 'tri3', '9': 'quad4', '10': 'tet4', '12': 'hex8', '21': 'lin3', '22': 'tri6', '23': 'quad8', '24': 'tet10', '25': 'hex20' }.get(str(celltype)) #not implemented '13':wed6 - '14':pyr5 #vtk format doesnt support quad9 if type_elm == None: print('Warning : Elements type {} is not implemeted!'.format( celltype)) #element ignored else: if len(list(np.unique(celltype_all))) == 1: importedMeshName = meshID else: importedMeshName = meshID + str(count) print('Mesh imported: "' + importedMeshName + '" with elements ' + type_elm) Mesh(crd, elm, type_elm, ID=importedMeshName) count += 1 return NodeData, NodeDataName, ElmData, ElmDataName
def ImportFromMSH(filename, meshID=None): filename = filename.strip() if meshID == None: meshID = filename if meshID[-4:].lower() == '.msh': meshID = meshID[:-4] mesh = None #print 'Reading file',`filename` f = open(filename, 'r') msh = f.read() f.close() msh = msh.split('\n') msh = [line.strip() for line in msh if line.strip() != ''] l = msh.pop(0) if l.lower() != '$meshformat': raise NameError('Unknown file format') l = msh.pop(0).lower().split() #versionnumber, file-type, data-size l = msh.pop(0) #$EndMeshFormat NodeData = [] ElmData = [] NodeDataName = [] ElmDataName = [] while msh != []: l = msh.pop(0).lower() if l == '$nodes': Nb_nodes = int(msh.pop(0)) numnode0 = int( msh[0].split() [0]) #0 or 1, in the mesh format the first node is 0 #a conversion is required if the msh file begin with another number #The numbering of nodes is assumed to be continuous (p. ex 1,2,3,....) crd = np.array([msh[nd].split()[1:] for nd in range(Nb_nodes)], dtype=float) del msh[0:Nb_nodes] msh.pop(0) #$EndNodes elif l == '$elements': Nb_el = int(msh.pop(0)) cells = [msh[el].split()[1:] for el in range(Nb_el)] del msh[0:Nb_el] celltype_all = np.array([cells[el][0] for el in range(Nb_el)], int) Nb_tag = int(cells[0][1]) #assume to be constant # if np.linalg.norm(cells[:,1] - Nb_tag) != 0: # raise NameError('Only uniform number of Tags are readable') if Nb_tag < 2: raise NameError('A minimum of 2 tags is required') elif Nb_tag > 2: print('Warning: only the second tag is read') msh.pop(0) #$EndElements #Tags = [cells[el][2:Nb_tag] for el in range(Nb_el)] #not used #PhysicalEntity = np.array([cells[el][2] for el in range(Nb_el)]) #fist tag not used for now Geom_all = np.array([cells[el][3] for el in range(Nb_el)], int) list_geom = list(np.unique(Geom_all)) elif l == '$nodedata' or l == '$elementdata': nb_str_tag = int(msh.pop(0)) if l == '$nodedata': NodeDataName += [str(msh.pop(0)) ] #the first string tag is the name of data else: ElmDataName += [str(msh.pop(0))] del msh[0:nb_str_tag - 1] #remove unused string tags nb_real_tag = int(msh.pop(0)) del msh[0:nb_real_tag] #remove unused real tags nb_int_tag = int(msh.pop(0)) del msh[0:nb_int_tag] #remove unused int tags if l == '$nodedata': if len(msh[0].split()) == 2: NodeData += [ np.array( [msh[nd].split()[1] for nd in range(Nb_nodes)], dtype=float) ] elif len(msh[0].split()) > 3: NodeData += [ np.array( [msh[nd].split()[1:] for nd in range(Nb_nodes)], dtype=float) ] del msh[0:Nb_nodes] else: if len(msh[0].split()) == 2: ElmData += [ np.array([msh[el].split()[1] for el in range(Nb_el)], dtype=float) ] elif len(msh[0].split()) > 3: ElmData += [ np.array([msh[el].split()[1:] for el in range(Nb_el)], dtype=float) ] del msh[0:Nb_el] count = 0 for celltype in list(np.unique(celltype_all)): type_elm = None list_el = np.where(celltype_all == celltype)[0] elm = np.array([cells[el][2 + Nb_tag:] for el in list_el], int) - numnode0 type_elm = { '1': 'lin2', '2': 'tri3', '3': 'quad4', '4': 'tet4', '5': 'hex8', '8': 'lin3', '9': 'tri6', '10': 'quad9', '11': 'tet10', '16': 'quad8', '17': 'hex20' }.get(str(celltype)) #not implemented '6':wed6 - '7':pyr5 GeometricalEntity = [] for geom in list_geom: GeometricalEntity.append([ i for i in range(len(list_el)) if Geom_all[list_el[i]] == geom ]) if type_elm == None: print('Warning : Elements type {} is not implemeted!'.format( celltype)) #element ignored else: if len(list(np.unique(celltype_all))) == 1: importedMeshName = meshID else: importedMeshName = meshID + str(count) print('Mesh imported: "' + importedMeshName + '" with elements ' + type_elm) Mesh(crd, elm, type_elm, ID=importedMeshName) #Rajouter GeometricalEntity en elSet count += 1 # res= MeshData(mesh) # res.NodeData = NodeData # res.NodeDataName = NodeDataName # res.ElmData = ElmData # res.ElmDataName = ElmDataName # res.GeometricalEntity = GeometricalEntity return NodeData, NodeDataName, ElmData, ElmDataName