예제 #1
0
    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
예제 #2
0
    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
예제 #3
0
 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)