def run(self): ''' Run the model. Sets the following instance variables: vr: Calculation ranges (m), NumPy 1D array. vz: Calculation depths (m), NumPy 1D array. tll: Transmission loss (dB) at receiver depth (zr), NumPy 1D array, length vr.size. tlg: Transmission loss (dB) grid, NumPy 2D array, dimensions vz.size by vr.size. proc_time: Processing time (s). ''' t0 = process_time() self.setup() nr = int(numpy.round(self._rmax / self._dr)) - 1 for rn in range(nr): self.updat() solve(self.u, self.v, self.s1, self.s2, self.s3, self.r1, self.r2, self.r3, self.iz, self.nz, self._np) self.r = (rn + 2) * self._dr 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, self.cpl, self.cpg)[:]) self.proc_time = process_time() - t0 results = { 'ID': self._id, 'Proc Time': self.proc_time, 'Ranges': self.vr, 'Depths': self.vz, 'TL Grid': self.tlg, 'TL Line': self.tll, 'CP Grid': self.cpg, 'CP Line': self.cpl, 'c0': self._c0 } return results
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)