def selfs(self): '''The self-starter''' # Conditions for the delta function si = self._zs / self._dz _is = int(numpy.floor(si)) # Source depth index dis = si - _is # Offset self.u[_is] = (1 - dis) * numpy.sqrt(2 * numpy.pi / self.k0) / \ (self._dz * self.alpw[_is]) self.u[_is + 1] = dis * numpy.sqrt(2 * numpy.pi / self.k0) / \ (self._dz * self.alpw[_is]) # Divide the delta function by (1-X)**2 to get a smooth rhs self.pd1[0] = 0 self.pd2[0] = -1 matrc(self.k0, self._dz, self.iz, self.iz, self.nz, 1, self.f1, self.f2, self.f3, self.ksq, self.alpw, self.alpb, self.ksqw, self.ksqb, self.rhob, self.r1, self.r2, self.r3, self.s1, self.s2, self.s3, self.pd1, self.pd2) for _ in range(2): solve(self.u, self.v, self.s1, self.s2, self.s3, self.r1, self.r2, self.r3, self.iz, self.nz, 1) # Apply the operator (1-X)**2*(1+X)**(-1/4)*exp(ci*k0*r*sqrt(1+X)) self.epade(ip=2) matrc(self.k0, self._dz, self.iz, self.iz, self.nz, self._np, self.f1, self.f2, self.f3, self.ksq, self.alpw, self.alpb, self.ksqw, self.ksqb, self.rhob, self.r1, self.r2, self.r3, self.s1, self.s2, self.s3, self.pd1, self.pd2) solve(self.u, self.v, self.s1, self.s2, self.s3, self.r1, self.r2, self.r3, self.iz, self.nz, self._np)
def updat(self): '''Matrix updates''' # Varying bathymetry if self.rd_bt: npt = self._rbzb.shape[0] while (self.bt_ind < npt - 1) and (self.r >= self._rbzb[self.bt_ind + 1, 0]): self.bt_ind += 1 jz = self.iz z = self._rbzb[self.bt_ind, 1] + \ (self.r + 0.5 * self._dr - self._rbzb[self.bt_ind, 0]) * \ (self._rbzb[self.bt_ind + 1, 1] - self._rbzb[self.bt_ind, 1]) / \ (self._rbzb[self.bt_ind + 1, 0] - self._rbzb[self.bt_ind, 0]) self.iz = int(numpy.floor(z / self._dz)) # First index below seabed self.iz = max(1, self.iz) self.iz = min(self.nz - 1, self.iz) if (self.iz != jz): matrc(self.k0, self._dz, self.iz, jz, self.nz, self._np, self.f1, self.f2, self.f3, self.ksq, self.alpw, self.alpb, self.ksqw, self.ksqb, self.rhob, self.r1, self.r2, self.r3, self.s1, self.s2, self.s3, self.pd1, self.pd2) # Varying sound speed profile if self.rd_ss: npt = self._rp_ss.size ss_ind_o = self.ss_ind while (self.ss_ind < npt - 1) and (self.r >= self._rp_ss[self.ss_ind + 1]): self.ss_ind += 1 if self.ss_ind != ss_ind_o: self.profl() matrc(self.k0, self._dz, self.iz, self.iz, self.nz, self._np, self.f1, self.f2, self.f3, self.ksq, self.alpw, self.alpb, self.ksqw, self.ksqb, self.rhob, self.r1, self.r2, self.r3, self.s1, self.s2, self.s3, self.pd1, self.pd2) # Varying seabed profile if self.rd_sb: npt = self._rp_sb.size sb_ind_o = self.sb_ind while (self.sb_ind < npt - 1) and (self.r >= self._rp_sb[self.sb_ind + 1]): self.sb_ind += 1 if self.sb_ind != sb_ind_o: self.profl() matrc(self.k0, self._dz, self.iz, self.iz, self.nz, self._np, self.f1, self.f2, self.f3, self.ksq, self.alpw, self.alpb, self.ksqw, self.ksqb, self.rhob, self.r1, self.r2, self.r3, self.s1, self.s2, self.s3, self.pd1, self.pd2) # Turn off the stability constraints if self.r >= self._rs: self._ns = 0 self._rs = self._rmax + self._dr self.epade() matrc(self.k0, self._dz, self.iz, self.iz, self.nz, self._np, self.f1, self.f2, self.f3, self.ksq, self.alpw, self.alpb, self.ksqw, self.ksqb, self.rhob, self.r1, self.r2, self.r3, self.s1, self.s2, self.s3, self.pd1, self.pd2)
def setup(self): '''Initialise the parameters, acoustic field, and matrices''' if self._rbzb[-1, 0] < self._rmax: self._rbzb = numpy.append(self._rbzb, [[self._rmax, self._rbzb[-1, 1]]], axis=0) self.eta = 1 / (40 * numpy.pi * numpy.log10(numpy.exp(1))) self.ib = 0 # Bathymetry pair index self.mdr = 0 # Output range counter self.r = self._dr self.omega = 2 * numpy.pi * self._freq ri = self._zr / self._dz self.ir = int(numpy.floor(ri)) # Receiver depth index self.dir = ri - self.ir # Offset self.k0 = self.omega / self._c0 self._z_sb += self._z_ss[ -1] # Make seabed profiles relative to deepest water profile point self._zmax = self._z_sb.max() + self._lyrw * self._lambda self.nz = int(numpy.floor( self._zmax / self._dz)) - 1 # Number of depth grid points - 2 self.nzplt = int(numpy.floor(self._zmplt / self._dz)) # Deepest output grid point self.iz = int(numpy.floor(self._rbzb[0, 1] / self._dz)) # First index below seabed self.iz = max(1, self.iz) self.iz = min(self.nz - 1, self.iz) self.u = numpy.zeros(self.nz + 2, dtype=numpy.complex) self.v = numpy.zeros(self.nz + 2, dtype=numpy.complex) self.ksq = numpy.zeros(self.nz + 2, dtype=numpy.complex) self.ksqb = numpy.zeros(self.nz + 2, dtype=numpy.complex) self.r1 = numpy.zeros([self.nz + 2, self._np], dtype=numpy.complex) self.r2 = numpy.zeros([self.nz + 2, self._np], dtype=numpy.complex) self.r3 = numpy.zeros([self.nz + 2, self._np], dtype=numpy.complex) self.s1 = numpy.zeros([self.nz + 2, self._np], dtype=numpy.complex) self.s2 = numpy.zeros([self.nz + 2, self._np], dtype=numpy.complex) self.s3 = numpy.zeros([self.nz + 2, self._np], dtype=numpy.complex) self.pd1 = numpy.zeros(self._np, dtype=numpy.complex) self.pd2 = numpy.zeros(self._np, dtype=numpy.complex) self.alpw = numpy.zeros(self.nz + 2) self.alpb = numpy.zeros(self.nz + 2) self.f1 = numpy.zeros(self.nz + 2) self.f2 = numpy.zeros(self.nz + 2) self.f3 = numpy.zeros(self.nz + 2) self.ksqw = numpy.zeros(self.nz + 2) nvr = int(numpy.floor(self._rmax / (self._dr * self._ndr))) self._rmax = nvr * self._dr * self._ndr nvz = int(numpy.floor(self.nzplt / self._ndz)) self.vr = numpy.arange(1, nvr + 1) * self._dr * self._ndr self.vz = numpy.arange(1, nvz + 1) * self._dz * self._ndz self.tll = numpy.zeros(nvr) self.tlg = numpy.zeros([nvz, nvr]) self.tlc = -1 # TL output range counter self.ss_ind = 0 # Sound speed profile range index self.sb_ind = 0 # Seabed parameters range index self.bt_ind = 0 # Bathymetry range index # The initial profiles and starting field self.profl() self.selfs() self.mdr, self.tlc = \ (outpt(self.r, self.mdr, self._ndr, self._ndz, self.tlc, self.f3, self.u, self.dir, self.ir, self.tll, self.tlg)[:]) # The propagation matrices self.epade() matrc(self.k0, self._dz, self.iz, self.iz, self.nz, self._np, self.f1, self.f2, self.f3, self.ksq, self.alpw, self.alpb, self.ksqw, self.ksqb, self.rhob, self.r1, self.r2, self.r3, self.s1, self.s2, self.s3, self.pd1, self.pd2)