def __init__(self, fileName): # ~~> empty SELAFIN SELAFIN.__init__(self, '') self.DATETIME = [] # ~~> variables self.TITLE = '' self.NBV1 = 1 self.NVAR = self.NBV1 self.VARINDEX = range(self.NVAR) self.VARNAMES = ['BOTTOM '] self.VARUNITS = ['M '] # ~~ Openning files ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ self.file = {} self.file.update({'name': fileName}) self.file.update({'endian': ">" }) # "<" means little-endian, ">" means big-endian self.file.update({'integer': ('i', 4)}) #'i' size 4 self.file.update({'float': ('f', 4)}) #'f' size 4, 'd' = size 8 self.file.update({'hook': open(fileName, 'rt')}) file = iter(self.file['hook']) # ~~ Read/Write dimensions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Note: # The section MeshFormat is mandatory line = file.next() proc = re.match(self.frst_keys, line) if proc: if proc.group('key') != "MeshFormat": print '... Could not recognise your MSH file format. Missing MeshFormat key.' sys.exit(1) line = file.next().split() if line[0] != "2.2": print '... Could not read your MSH file format. Only the version 2.2 is allowed.' sys.exit(1) fileType = int(line[1]) if fileType == 1: print '... I have never done this before. Do check it works' line = file.next() l, isize, chk = unpack('>i', line.read(4 + 4 + 4)) floatSize = int(line[2]) if floatSize == 8: self.file['float'] = ('d', 8) line = file.next() proc = re.match(self.last_keys, line) if proc: if proc.group('key') != "MeshFormat": print '... Could not complete reading the header of you MSH file format. Missing EndMeshFormat key.' sys.exit(1) # ~~ Loop on sections ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ while True: try: line = file.next() except: break proc = re.match(self.frst_keys, line) if not proc: print '... Was expecting a new Section starter. Found this instead: ', line sys.exit(1) key = proc.group('key') # ~~ Section Nodes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if key == "Nodes": print ' +> mesh x,y,z' NPOIN = int(file.next()) if self.file['float'][0] == 'd': MESHX = np.zeros(NPOIN, dtype=np.float64) MESHY = np.zeros(NPOIN, dtype=np.float64) MESHZ = np.zeros(NPOIN, dtype=np.float64) else: MESHX = np.zeros(NPOIN, dtype=np.float) MESHY = np.zeros(NPOIN, dtype=np.float) MESHZ = np.zeros(NPOIN, dtype=np.float) #map_nodes = [] for i in range(NPOIN): line = file.next().split() #map_nodes.append(int(line[0])) MESHX[i] = np.float(line[1]) MESHY[i] = np.float(line[2]) MESHZ[i] = np.float(line[3]) # TODO: renumbering nodes according to map_nodes ? #map_nodes = np.asarray(map_nodes) self.NPOIN2 = NPOIN self.MESHX = MESHX self.MESHY = MESHY self.MESHZ = MESHZ line = file.next() # ~~ Section Nodes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ elif proc.group('key') == "Elements": print ' +> renumbered connectivity' NELEM = int(file.next()) IKLE2 = -np.ones((NELEM, 3), dtype=np.int) for i in range(NELEM): line = file.next().split() if int(line[1]) != 2: continue e = line[int(line[2]) + 3:] IKLE2[i] = [np.int(e[0]), np.int(e[1]), np.int(e[2])] self.IKLE2 = IKLE2[np.not_equal(*(np.sort(IKLE2).T[0::2]))] - 1 self.NELEM2 = len(self.IKLE2) line = file.next() # TODO: fitting the unique node numbers with map_nodes ? # ~~ Unnecessary section ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else: while True: line = file.next() if re.match(self.last_keys, line): break proc = re.match(self.last_keys, line) if proc: if proc.group('key') != key: print '... Could not complete reading the header of you MSH file format. Missing ', key, ' end key.' sys.exit(1) # ~~> sizes print ' +> sizes' self.NDP3 = 3 self.NDP2 = 3 self.NPLAN = 1 self.NELEM3 = self.NELEM2 self.NPOIN3 = self.NPOIN2 self.IKLE3 = self.IKLE2 self.IPARAM = [0, 0, 0, 0, 0, 0, 1, 0, 0, 0] print ' +> boundaries' # ~~> establish neighborhood neighbours = Triangulation( self.MESHX, self.MESHY, self.IKLE3).get_cpp_triangulation().get_neighbors() # ~~> build the enssemble of boundary segments ebounds = [] #print ' - identify' #pbar = ProgressBar(maxval=self.NELEM3).start() #for i in range(self.NELEM3): # if neighbours[i,0] < 0: ebounds.append([self.IKLE3[i][0],self.IKLE3[i][1]]) # if neighbours[i,1] < 0: ebounds.append([self.IKLE3[i][1],self.IKLE3[i][2]]) # if neighbours[i,2] < 0: ebounds.append([self.IKLE3[i][2],self.IKLE3[i][0]]) # pbar.update(i) #pbar.finish() # ~~> assemble the enssemble of boundary segments #print ' - assemble' #pbounds = polygons.joinSegments(ebounds) # ~~> define IPOBO from an arbitrary start point #print ' - set' self.IPOB3 = np.ones(self.NPOIN3, dtype=np.int) #self.IPOB3 = np.zeros(self.NPOIN3,dtype=np.int) #iptfr = 0 #for p in pbounds: # for n in p[1:]: # iptfr += 1 # self.IPOB3[n] = iptfr self.IPOB2 = self.IPOB3
def __init__(self, fname, vals=(None, None)): # ~~> empty SELAFIN SELAFIN.__init__(self, '') self.DATETIME = [] # ~~> variables self.TITLE = '' self.NBV1 = 1 # bathymetry only self.NVAR = self.NBV1 self.VARINDEX = range(self.NVAR) self.VARNAMES = ['BOTTOM '] self.VARUNITS = ['M '] print ' +> header' # ~~> load header (ASC type) gebcofile = open(fname, 'r') # ~~ gline = [] gline.append(gebcofile.readline().split()) if gline[-1][0] == "ncols": NX1D = int(gline[-1][1]) else: print '.. Could not read this file format. Key ncols expected here.' sys.exit(1) gline.append(gebcofile.readline().split()) if gline[-1][0] == "nrows": NY1D = int(gline[-1][1]) else: print '.. Could not read this file format. Key nrows expected here.' sys.exit(1) gline.append(gebcofile.readline().split()) if gline[-1][0] == "xllcorner": xllcorner = np.float(gline[-1][1]) else: print '.. Could not read this file format. Key xllcorner expected here.' sys.exit(1) gline.append(gebcofile.readline().split()) if gline[-1][0] == "yllcorner": yllcorner = np.float(gline[-1][1]) else: print '.. Could not read this file format. Key yllcorner expected here.' sys.exit(1) gline.append(gebcofile.readline().split()) if gline[-1][0] == "cellsize": xdim = np.float(gline[-1][1]) ydim = xdim elif gline[-1][0] in ["xdim", "dx"]: xdim = np.float(gline[-1][1]) gline.append(gebcofile.readline().split()) if gline[-1][0] in ["ydim", "dy"]: ydim = np.float(gline[-1][1]) else: print '.. Could not read this file format. Key ydim expected here.' sys.exit(1) else: print '.. Could not read this file format. Key cellsize or xdim expected here.' sys.exit(1) gline.append(gebcofile.readline().split()) if gline[-1][0] == "NODATA_value": NODATA_value = int(gline[-1][1]) else: print '.. Could not read this file format. Key NODATA_value expected here.' sys.exit(1) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ gebcofile.close() print ' +> bathymetry' # ~~> load ASCII content, ignoring the header lines z = np.loadtxt(fname, skiprows=len(gline)).T.ravel() print ' +> filtered connectivity' # ~~> temporary IKLE aval = min(z) - 1 if vals[0] != None: aval = float(vals[0]) bval = max(z) + 1 if vals[1] != None: bval = float(vals[1]) ielem = 0 pbar = ProgressBar(maxval=2 * (NX1D - 1) * (NY1D - 1)).start() ikle3 = -np.ones((2 * (NX1D - 1) * (NY1D - 1), 3), dtype=np.int) for i in range(1, NX1D): for j in range(1, NY1D): ipoin = (i - 1) * NY1D + j - 1 # ~~> first triangle if ( aval < z[ipoin] < bval ) and \ ( aval < z[ipoin + NY1D] < bval ) and \ ( aval < z[ipoin + 1] < bval ): ikle3[ielem] = [ipoin, ipoin + 1, ipoin + NY1D] ielem = ielem + 1 pbar.update(ielem) # ~~> second triangle if ( aval < z[ipoin + NY1D] < bval ) and \ ( aval < z[ipoin + NY1D + 1] < bval ) and \ ( aval < z[ipoin + 1] < bval ): ikle3[ielem] = [ipoin + NY1D, ipoin + 1, ipoin + NY1D + 1] ielem = ielem + 1 pbar.update(ielem) pbar.finish() print ' +> renumbered connectivity' # ~~> intermediate connectivity GIKLE = ikle3[np.not_equal(*(np.sort(ikle3).T[0::2]))] KNOLG = np.unique(np.ravel(GIKLE)) KNOGL = dict(zip(KNOLG, range(len(KNOLG)))) # ~~> final connectivity self.IKLE3 = -np.ones_like(GIKLE, dtype=np.int) pbar = ProgressBar(maxval=len(GIKLE)).start() for k in range(len(GIKLE)): self.IKLE3[k] = [ KNOGL[GIKLE[k][0]], KNOGL[GIKLE[k][1]], KNOGL[GIKLE[k][2]] ] pbar.update(k) pbar.finish() print ' +> mesh x,y,z' # ~~> defines grid x = xllcorner + xdim * np.arange(NX1D, dtype=np.float) - xdim / 2. y = yllcorner - ydim * np.arange( NY1D, dtype=np.float) + ydim * NY1D - ydim / 2. self.MESHX = np.tile(x, NY1D).reshape(NY1D, NX1D).T.ravel()[KNOLG] self.MESHY = np.tile(y, NX1D)[KNOLG] self.z = z[KNOLG] print ' +> sizes' # ~~> sizes self.NPLAN = 1 self.NDP2 = 3 self.NDP3 = self.NDP2 self.NPOIN2 = len(self.MESHX) self.NPOIN3 = self.NPOIN2 self.NELEM2 = len(self.IKLE3) self.NELEM3 = self.NELEM2 self.IPARAM = [0, 0, 0, 0, 0, 0, 1, 0, 0, 0] print ' +> boundaries' # ~~> establish neighborhood neighbours = Triangulation( self.MESHX, self.MESHY, self.IKLE3).get_cpp_triangulation().get_neighbors() # ~~> build the enssemble of boundary segments ebounds = [] print ' - identify' pbar = ProgressBar(maxval=self.NELEM3).start() for i in range(self.NELEM3): if neighbours[i, 0] < 0: ebounds.append([self.IKLE3[i][0], self.IKLE3[i][1]]) if neighbours[i, 1] < 0: ebounds.append([self.IKLE3[i][1], self.IKLE3[i][2]]) if neighbours[i, 2] < 0: ebounds.append([self.IKLE3[i][2], self.IKLE3[i][0]]) pbar.update(i) pbar.finish() # ~~> assemble the enssemble of boundary segments print ' - assemble' pbounds = polygons.joinSegments(ebounds) # ~~> define IPOBO from an arbitrary start point print ' - set' self.IPOB3 = np.zeros(self.NPOIN3, dtype=np.int) iptfr = 0 for p in pbounds: for n in p[1:]: iptfr += 1 self.IPOB3[n] = iptfr self.IPOB2 = self.IPOB3