def _check_pml(self): """ Check if PML is compatible with obstacles. """ msg = 'Obstacle {} not compatible with PML' for sub in self._obstacles: if self._bc[0] == 'A': if 0 < sub.xz[0] < self._Npml + self._stencil or sub.xz[ 2] < self._Npml + 1: raise _exceptions.CloseObstaclesError(msg.format(sub)) if self._bc[1] == 'A': if 0 < sub.xz[1] < self._Npml + self._stencil or sub.xz[ 3] < self._Npml + 1: raise _exceptions.CloseObstaclesError(msg.format(sub)) if self._bc[2] == 'A': if self._nx-self._Npml-self._stencil < sub.xz[2] < self._nx-1 \ or sub.xz[0] >= self._nx - self._Npml - 1: raise _exceptions.CloseObstaclesError(msg.format(sub)) if self._bc[3] == 'A': if self._nz-self._Npml-self._stencil < sub.xz[3] < self._nz-1 \ or sub.xz[1] >= self._nz - self._Npml - 1: raise _exceptions.CloseObstaclesError(msg.format(sub))
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'))
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'))
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'))
def _check_stencil(self): """ Check if Subdomain are larger enough considering the stencil. """ msg = "{} too small considering stencil" for sub in self.dxdomains: if len(sub.rx) < 2 * self._stencil + 1 and sub.bc == "WW": raise _exceptions.CloseObstaclesError(msg.format(sub)) for sub in self.dzdomains: if len(sub.rz) < 2 * self._stencil + 1 and sub.bc == "WW": raise _exceptions.CloseObstaclesError(msg.format(sub)) for sub in self.adomains: if sub.axis == 0 and len(sub.rz) < 2 * self._stencil and _re.match( r'.W.W', sub.bc): raise _exceptions.CloseObstaclesError(msg.format(sub)) if sub.axis == 1 and len(sub.rx) < 2 * self._stencil and _re.match( r'W.W.', sub.bc): raise _exceptions.CloseObstaclesError(msg.format(sub))