コード例 #1
0
ファイル: cdomain.py プロジェクト: ipselium/fdgrid
    def __init__(self, shape, obstacles, bc, stencil, Npml=15):

        self._shape = shape
        self._obstacles = obstacles
        self._check_obstacles()
        self._bc = bc
        self._stencil = stencil
        self._Npml = Npml
        self._nx, self._nz = shape
        self.dxdomains = Domain(shape)  # For x derivatives
        self.dzdomains = Domain(shape)  # For z derivatives
        self.fxdomains = Domain(shape)  # For x filters
        self.fzdomains = Domain(shape)  # For z filters
        self.adomains = Domain(shape)  # For PMLs
        self.gdomain = Subdomain([0, 0, self._nx - 1, self._nz - 1],
                                 bc=self._bc,
                                 key=0,
                                 tag='g')

        # Indexes of the subdomains
        self._tnd = 0
        self._tndx = 0
        self._tndz = 0

        # Initialize masks
        self._xmask, self._zmask = self.init_masks(shape, bc, obstacles)

        # Set up all Domain and Subdomain objects
        self._proceed()
コード例 #2
0
ファイル: cdomain.py プロジェクト: ipselium/fdgrid
    def init_masks(shape, bc, obstacles):
        """ Init masks with obstacles. """

        gdomain = Subdomain([0, 0, shape[0] - 1, shape[1] - 1], bc=bc)
        xmask = _np.zeros(shape, dtype=int)
        zmask = xmask.copy()

        for obs in obstacles:
            for mask in [xmask, zmask]:
                mask[obs.sx, obs.sz] = -1
                mask[obs.sx, obs.iz] = -2
                mask[obs.ix, obs.sz] = -2

        for obs1, obs2 in _itertools.permutations(obstacles, r=2):
            c = obs1.intersection(obs2)
            if c:
                xmask[c[0], c[1]] = -1
                zmask[c[0], c[1]] = -1

        for obs in obstacles:
            coords = obs.touch(gdomain)
            if coords:
                for c in coords:
                    xmask[c[0], c[1]] = -1
                    zmask[c[0], c[1]] = -1

        _utils.remove_singles(xmask)
        _utils.remove_singles(zmask)

        return xmask, zmask
コード例 #3
0
ファイル: cdomain.py プロジェクト: ipselium/fdgrid
    def _extrude_left(self, obs, idz):
        """ Extrude left wall of the obstacle. """
        xc1, zc1 = obs.xz[0], idz[0]
        xc2, zc2 = obs.xz[0], idz[1]
        bc = '{}.{}.'.format(self._bc[0], obs.bc[0])
        for i in range(xc1 - 1, -1, -1):
            xc2 = i
            mk = self._xmask[i, zc1 + 1:zc2]
            if _np.any(mk != 0):
                if _np.all(mk == -2):
                    bc = 'W.{}.'.format(obs.bc[0])
                elif _np.any(mk == -2):
                    xc2 = int((xc1 + xc2) / 2 + 1)
                    bc = 'X.{}.'.format(obs.bc[0])
                elif _np.any(mk == 1):
                    xc2 += 1
                    bc = 'X.{}.'.format(obs.bc[1])
                break

        if abs(xc2 - xc1) < self._stencil:
            msg = _exceptions.CloseObstaclesError.msg.format(
                obs, self._stencil)
            raise _exceptions.CloseObstaclesError(msg)

        self._update_domains(
            Subdomain((xc2, zc1, xc1, zc2), bc, self._ndx, axis=0, tag='X'))
コード例 #4
0
ファイル: cdomain.py プロジェクト: ipselium/fdgrid
    def _extrude_right(self, obs, idz):
        xc1, zc1 = obs.xz[2], idz[0]
        xc2, zc2 = obs.xz[2], idz[1]
        bc = '{}.{}.'.format(obs.bc[2], self._bc[2])
        for i in range(xc1 + 1, self._nx):
            xc2 = i
            mk = self._xmask[i, zc1 + 1:zc2]
            if _np.any(mk != 0):
                if _np.all(mk != 0):
                    bc = '{}.W.'.format(obs.bc[2])
                elif _np.any(mk == -2):
                    xc2 = int((xc1 + xc2) / 2 - 1)
                    bc = '{}.X.'.format(obs.bc[2])
                elif _np.any(mk == 1):
                    xc2 -= 1
                    bc = '{}.X.'.format(obs.bc[1])
                break

        if abs(xc2 - xc1) < self._stencil:
            msg = _exceptions.CloseObstaclesError.msg.format(
                obs, self._stencil)
            raise _exceptions.CloseObstaclesError(msg)

        self._update_domains(
            Subdomain((xc1, zc1, xc2, zc2), bc, self._ndx, axis=0, tag='X'))
コード例 #5
0
ファイル: cdomain.py プロジェクト: ipselium/fdgrid
    def _extrude_bottom(self, obs, idx):
        """ Extrude bottom wall of the obstacle. """
        xc1, zc1 = idx[0], obs.xz[1]
        xc2, zc2 = idx[1], obs.xz[1]
        bc = '.{}.{}'.format(self._bc[1], obs.bc[1])
        for j in range(zc1 - 1, -1, -1):
            zc2 = j
            mk = self._zmask[xc1 + 1:xc2, j]
            if _np.any(mk != 0):
                if _np.all(mk == -2):
                    bc = '.W.{}'.format(obs.bc[1])
                elif _np.any(mk == -2):
                    zc2 = int((zc1 + zc2) / 2 + 1)
                    bc = '.X.{}'.format(obs.bc[1])
                elif _np.any(mk == 1):
                    zc2 += 1
                    bc = '.X.{}'.format(obs.bc[1])
                break

        if abs(zc2 - zc1) < self._stencil:
            msg = _exceptions.CloseObstaclesError.msg.format(
                obs, self._stencil)
            raise _exceptions.CloseObstaclesError(msg)

        self._update_domains(
            Subdomain((xc1, zc2, xc2, zc1), bc, self._ndz, axis=1, tag='X'))
コード例 #6
0
ファイル: cdomain.py プロジェクト: ipselium/fdgrid
    def _update_patches(self):
        """ Add patches. TODO : Fix 'else W' if an obstacle has another bc !"""

        for patch in _utils.find_areas(self._xmask, val=-2):
            bc = ['.', '.', '.', '.']
            if patch[0] == 0:
                bc[0] = self._bc[0]
            else:
                bc[0] = 'X' if self._xmask[patch[0] - 1,
                                           patch[1]] == 1 else 'W'

            if patch[2] == self._nx - 1:
                bc[2] = self._bc[2]
            else:
                bc[2] = 'X' if self._xmask[patch[2] + 1,
                                           patch[1]] == 1 else 'W'

            self._update_domains(
                Subdomain(patch,
                          axis=0,
                          key=self._ndx,
                          bc=''.join(bc),
                          tag='W'))

        for patch in _utils.find_areas(self._zmask, val=-2):
            bc = ['.', '.', '.', '.']
            if patch[1] == 0:
                bc[1] = self._bc[1]
            else:
                bc[1] = 'X' if self._xmask[patch[0],
                                           patch[1] - 1] == 1 else 'W'

            if patch[3] == self._nz - 1:
                bc[3] = self._bc[3]
            else:
                bc[3] = 'X' if self._xmask[patch[0],
                                           patch[3] + 1] == 1 else 'W'

            self._update_domains(
                Subdomain(patch,
                          axis=1,
                          key=self._ndz,
                          bc=''.join(bc),
                          tag='W'))
コード例 #7
0
ファイル: cdomain.py プロジェクト: ipselium/fdgrid
    def _fill(self):
        """ Search remaining domains along both x and z axises. """

        xmissings = _utils.find_areas(self._xmask, val=0)
        zmissings = _utils.find_areas(self._zmask, val=0)

        for c in xmissings:
            bc = ['X', '.', 'X', '.']
            if c[0] == 0:
                bc[0] = self._bc[0]
            if c[2] == self._nx - 1:
                bc[2] = self._bc[2]
            self._update_domains(
                Subdomain(c, key=self._ndx, bc=''.join(bc), axis=0, tag='X'))

        for c in zmissings:
            bc = ['.', 'X', '.', 'X']
            if c[1] == 0:
                bc[1] = self._bc[1]
            if c[3] == self._nz - 1:
                bc[3] = self._bc[3]
            self._update_domains(
                Subdomain(c, key=self._ndz, bc=''.join(bc), axis=1, tag='X'))
コード例 #8
0
ファイル: cdomain.py プロジェクト: ipselium/fdgrid
    def _zbetween(self):
        """ Find domains between obstacles along z axis. """

        idx = ComputationDomains.bounds(self._shape,
                                        self._bc,
                                        self._obstacles,
                                        axis=0)
        if idx:
            void = [(i[0], 0, i[1], self._nz - 1) for i in idx if i[2] == 'v']
            void = _utils.remove_dups(void)
            for sub in void:
                self._update_domains(
                    Subdomain(sub,
                              '.{}.{}'.format(self._bc[1], self._bc[3]),
                              self._ndz,
                              axis=1,
                              tag='X'))
コード例 #9
0
ファイル: cdomain.py プロジェクト: ipselium/fdgrid
    def _xbetween(self):
        """ Find domains between obstacles along x axis. """

        idz = ComputationDomains.bounds(self._shape,
                                        self._bc,
                                        self._obstacles,
                                        axis=1)
        if idz:
            void = [(0, i[0], self._nx - 1, i[1]) for i in idz if i[2] == 'v']
            void = _utils.remove_dups(void)
            for sub in void:
                self._update_domains(
                    Subdomain(sub,
                              '{}.{}.'.format(self._bc[0], self._bc[2]),
                              self._ndx,
                              axis=0,
                              tag='X'))