示例#1
0
    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
示例#2
0
    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