def __init__(self, file_name): # ~~> 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.fle = {} self.fle.update({'name': file_name}) # "<" means little-endian, ">" means big-endian self.fle.update({'endian': ">"}) self.fle.update({'integer': ('i', 4)}) # 'i' size 4 self.fle.update({'float': ('f', 4)}) # 'f' size 4, 'd' = size 8 self.fle.update({'hook': open(file_name, 'r')}) fle = iter(self.fle['hook']) # ~~ Read/Write dimensions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Note: # The section MeshFormat is mandatory line = fle.next() proc = re.match(self.frst_keys, line) if proc: if proc.group('key') != "MeshFormat": raise TelemacException( '... Could not recognise your MSH file format. ' 'Missing MeshFormat key.') line = fle.next().split() if line[0] != "2.2": raise TelemacException( '... Could not read your MSH file format. ' 'Only the version 2.2 is allowed.') file_type = int(line[1]) if file_type == 1: print('... I have never done this before. Do check it works') line = fle.next() _, _, _ = unpack('>i', line.read(4 + 4 + 4)) float_size = int(line[2]) if float_size == 8: self.fle['float'] = ('d', 8) line = fle.next() proc = re.match(self.last_keys, line) if proc: if proc.group('key') != "MeshFormat": raise TelemacException( '... Could not complete reading the header of you MSH ' 'file format. Missing EndMeshFormat key.') # ~~ Loop on sections ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ while True: try: line = fle.next() except StopIteration: break proc = re.match(self.frst_keys, line) if not proc: raise TelemacException( '... Was expecting a new Section starter. ' 'Found this instead: {}'.format(line)) key = proc.group('key') # ~~ Section Nodes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if key == "Nodes": print(' +> mesh x,y,z') npoin = int(fle.next()) if self.fle['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 = fle.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 = fle.next() # ~~ Section Nodes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ elif proc.group('key') == "Elements": print(' +> renumbered connectivity') nelem = int(fle.next()) ikle2 = -np.ones((nelem, 3), dtype=np.int) for i in range(nelem): line = fle.next().split() if int(line[1]) != 2: continue expr = line[int(line[2]) + 3:] ikle2[i] = [ np.int(expr[0]), np.int(expr[1]), np.int(expr[2]) ] self.ikle2 = ikle2[np.not_equal(*(np.sort(ikle2).T[0::2]))] - 1 self.nelem2 = len(self.ikle2) line = fle.next() # TODO: fitting the unique node numbers with map_nodes ? # ~~ Unnecessary section ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else: while True: line = fle.next() if re.match(self.last_keys, line): break proc = re.match(self.last_keys, line) if proc: if proc.group('key') != key: raise TelemacException( '... Could not complete reading the header of your ' 'MSH file format. Missing {} end key.'.format(key)) # ~~> 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 _ = Triangulation(self.meshx, self.meshy, self.ikle3)\ .get_cpp_triangulation().get_neighbors() # ~~> build the enssemble of boundary segments # ~~> define ipobO from an arbitrary start point self.ipob3 = np.ones(self.npoin3, dtype=np.int) self.ipob2 = self.ipob3
def __init__(self, fname, vals=(None, None)): """ @brief Main class that fetches the GEBCO bathymetry data and puts it into the SELAFIN data format @param fname (string): the name of the GEBCO file """ # ~~> 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].lower() == "ncols": nx1d = int(gline[-1][1]) else: raise TelemacException(\ '.. Could not read this file format. ' 'Key ncols expected here.') gline.append(gebcofile.readline().split()) if gline[-1][0].lower() == "nrows": ny1d = int(gline[-1][1]) else: raise TelemacException(\ '.. Could not read this file format. ' 'Key nrows expected here.') gline.append(gebcofile.readline().split()) if gline[-1][0].lower() == "xllcorner": xllcorner = np.float(gline[-1][1]) else: raise TelemacException(\ '.. Could not read this file format. ' 'Key xllcorner expected here.') gline.append(gebcofile.readline().split()) if gline[-1][0].lower() == "yllcorner": yllcorner = np.float(gline[-1][1]) else: raise TelemacException(\ '.. Could not read this file format. ' 'Key yllcorner expected here.') gline.append(gebcofile.readline().split()) if gline[-1][0].lower() == "cellsize": xdim = np.float(gline[-1][1]) ydim = xdim elif gline[-1][0].lower() in ["xdim", "dx"]: xdim = np.float(gline[-1][1]) gline.append(gebcofile.readline().split()) if gline[-1][0].lower() in ["ydim", "dy"]: ydim = np.float(gline[-1][1]) else: raise TelemacException(\ '.. Could not read this file format.' ' Key ydim expected here.') else: raise TelemacException(\ '.. Could not read this file format. ' 'Key cellsize or xdim expected here.') gline.append(gebcofile.readline().split()) if gline[-1][0].lower() == "nodata_value": nodata_value = int(gline[-1][1]) else: raise TelemacException(\ '.. Could not read this file format. ' 'Key NODATA_value expected here.') # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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.join_segments(ebounds) # ~~> define ipobO from an arbitrary start point print(' - set') self.ipob3 = np.zeros(self.npoin3, dtype=np.int) iptfr = 0 for bound in pbounds: for n in bound[1:]: iptfr += 1 self.ipob3[n] = iptfr self.ipob2 = self.ipob3
def __init__(self, f): Selafin.__init__(self, f) self.ikle2, self.meshx, self.meshy, self.ipob2, \ self.interp, self.interp3 = \ subdivide_mesh4(self.ikle2, self.meshx, self.meshy)