def test_get_spline_values(): # 9. get_spline_values # Check one example filt = filters.key_81_CosSin_2009() out, new_inp = transform.get_spline_values(filt, np.arange(1, 6), -1) # Expected values oout = np.array([[6.70925256e-05, 8.19469958e-05, 1.00090287e-04, 1.22250552e-04, 1.49317162e-04, 1.82376393e-04, 2.22755030e-04, 2.72073608e-04, 3.32311455e-04, 4.05886127e-04, 4.95750435e-04, 6.05510949e-04, 7.39572743e-04, 9.03316189e-04, 1.10331288e-03, 1.34758940e-03, 1.64594941e-03, 2.01036715e-03, 2.45546798e-03, 2.99911536e-03, 3.66312778e-03, 4.47415437e-03, 5.46474449e-03, 6.67465399e-03, 8.15244080e-03, 9.95741367e-03, 1.21620125e-02, 1.48547156e-02, 1.81435907e-02, 2.21606317e-02, 2.70670566e-02, 3.30597776e-02, 4.03793036e-02, 4.93193928e-02, 6.02388424e-02, 7.35758882e-02, 8.98657928e-02, 1.09762327e-01, 1.34064009e-01, 1.63746151e-01, 2.00000000e-01, 2.44280552e-01, 2.98364940e-01, 3.64423760e-01, 4.45108186e-01, 5.43656366e-01, 6.64023385e-01, 8.11039993e-01, 9.90606485e-01, 1.20992949e+00, 1.47781122e+00, 1.80500270e+00, 2.20463528e+00, 2.69274761e+00, 3.28892935e+00, 4.01710738e+00, 4.90650604e+00, 5.99282001e+00, 7.31964689e+00, 8.94023690e+00, 1.09196300e+01, 1.33372662e+01, 1.62901737e+01, 1.98968631e+01, 2.43020835e+01, 2.96826318e+01, 3.62544484e+01, 4.42812832e+01, 5.40852815e+01, 6.60599120e+01, 8.06857587e+01, 9.85498082e+01, 1.20369008e+02, 1.47019038e+02, 1.79569458e+02, 2.19326632e+02, 2.67886153e+02, 3.27196886e+02, 3.99639179e+02, 4.88120396e+02, 5.96191597e+02, 7.28190061e+02, 8.89413350e+02, 1.08633192e+03, 1.32684880e+03, 1.62061679e+03, 1.97942581e+03, 2.41767615e+03, 2.95295631e+03, 3.60674899e+03]]) onew_inp = np.array([5., 4.09365377, 3.35160023, 2.74405818, 2.24664482, 1.83939721, 1.50597106, 1.23298482, 1.00948259, 0.82649444]) # Comparison assert_allclose(out, oout) assert_allclose(new_inp, onew_inp) # Ensure output dimension hfilt = filters.anderson_801_1982() out, _ = transform.get_spline_values(hfilt, np.array([1, 1.1]), -1) assert_allclose(out.size, 804) # Check a hypothetical short filter, with small pts_per_dec, and ensure # at least four points are returned filt = filters.DigitalFilter('shortest') filt.base = np.array([1., 1.1]) out, new_inp = transform.get_spline_values(filt, np.array([1.]), 1) assert_allclose(out.size, 4) # Check standard example ffilt = filters.key_81_CosSin_2009() inp = np.arange(1, 6) out, new_inp = transform.get_spline_values(ffilt, inp, 0) assert_allclose(inp, new_inp) assert_allclose(out, ffilt.base/inp[:, None])
def test_dlf(): # 10. dlf # DLF is integral of fht and ffht, and therefore tested a lot through # those. Here we just ensure status quo. And if a problem arises in fht or # ffht, it would make it obvious if the problem arises from dlf or not. # Check DLF for Fourier t = DATA['t'][()] for i in [0, 1, 2]: dat = DATA['ffht' + str(i)][()] tres = DATA['tEM' + str(i)][()] finp = dat['fEM'] ftarg = dat['ftarg'] if i > 0: finp /= 2j * np.pi * dat['f'] if i > 1: finp *= -1 if ftarg[1] == 0: finp = finp.reshape(t.size, -1) tEM = transform.dlf(finp, 2 * np.pi * dat['f'], t, ftarg[0], ftarg[1], kind=ftarg[2]) assert_allclose(tEM * 2 / np.pi, tres, rtol=1e-3) # Check DLF for Hankel for ab in [12, 22, 13, 33]: model = utils.check_model([], 10, 2, 2, 5, 1, 10, True, 0) depth, res, aniso, epermH, epermV, mpermH, mpermV, isfullspace = model frequency = utils.check_frequency(1, res, aniso, epermH, epermV, mpermH, mpermV, 0) freq, etaH, etaV, zetaH, zetaV = frequency src = [0, 0, 0] src, nsrc = utils.check_dipole(src, 'src', 0) ab, msrc, mrec = utils.check_ab(ab, 0) ht, htarg = utils.check_hankel('fht', None, 0) options = utils.check_opt(None, None, ht, htarg, 0) use_ne_eval, loop_freq, loop_off = options xdirect = False # Important, as we want to comp. wavenumber-frequency! rec = [np.arange(1, 11) * 500, np.zeros(10), 300] rec, nrec = utils.check_dipole(rec, 'rec', 0) off, angle = utils.get_off_ang(src, rec, nsrc, nrec, 0) lsrc, zsrc = utils.get_layer_nr(src, depth) lrec, zrec = utils.get_layer_nr(rec, depth) fhtfilt = htarg[0] pts_per_dec = htarg[1] # # # 0. No Spline # # # # fht calculation lambd = fhtfilt.base / off[:, None] PJ = kernel.wavenumber(zsrc, zrec, lsrc, lrec, depth, etaH, etaV, zetaH, zetaV, lambd, ab, xdirect, msrc, mrec, use_ne_eval) factAng = kernel.angle_factor(angle, ab, msrc, mrec) # dlf calculation fEM0 = transform.dlf(PJ, lambd, off, fhtfilt, 0, factAng=factAng, ab=ab) # Analytical frequency-domain solution freq1 = kernel.fullspace(off, angle, zsrc, zrec, etaH, etaV, zetaH, zetaV, ab, msrc, mrec) # Compare assert_allclose(np.squeeze(fEM0), np.squeeze(freq1)) # # # 1. Spline; One angle # # # options = utils.check_opt('spline', None, ht, htarg, 0) use_ne_eval, loop_freq, loop_off = options # fht calculation lambd, _ = transform.get_spline_values(fhtfilt, off, pts_per_dec) PJ1 = kernel.wavenumber(zsrc, zrec, lsrc, lrec, depth, etaH, etaV, zetaH, zetaV, lambd, ab, xdirect, msrc, mrec, use_ne_eval) # dlf calculation fEM1 = transform.dlf(PJ1, lambd, off, fhtfilt, pts_per_dec, factAng=factAng, ab=ab) # Compare assert_allclose(np.squeeze(fEM1), np.squeeze(freq1), rtol=1e-4) # # # 2.a Lagged; One angle # # # rec = [np.arange(1, 11) * 500, np.arange(-5, 5) * 0, 300] rec, nrec = utils.check_dipole(rec, 'rec', 0) off, angle = utils.get_off_ang(src, rec, nsrc, nrec, 0) # fht calculation lambd, _ = transform.get_spline_values(fhtfilt, off, -1) PJ2 = kernel.wavenumber(zsrc, zrec, lsrc, lrec, depth, etaH, etaV, zetaH, zetaV, lambd, ab, xdirect, msrc, mrec, use_ne_eval) factAng = kernel.angle_factor(angle, ab, msrc, mrec) # dlf calculation fEM2 = transform.dlf(PJ2, lambd, off, fhtfilt, -1, factAng=factAng, ab=ab) # Analytical frequency-domain solution freq2 = kernel.fullspace(off, angle, zsrc, zrec, etaH, etaV, zetaH, zetaV, ab, msrc, mrec) # Compare assert_allclose(np.squeeze(fEM2), np.squeeze(freq2), rtol=1e-4) # # # 2.b Lagged; Multi angle # # # rec = [np.arange(1, 11) * 500, np.arange(-5, 5) * 200, 300] rec, nrec = utils.check_dipole(rec, 'rec', 0) off, angle = utils.get_off_ang(src, rec, nsrc, nrec, 0) # fht calculation lambd, _ = transform.get_spline_values(fhtfilt, off, -1) PJ2 = kernel.wavenumber(zsrc, zrec, lsrc, lrec, depth, etaH, etaV, zetaH, zetaV, lambd, ab, xdirect, msrc, mrec, use_ne_eval) factAng = kernel.angle_factor(angle, ab, msrc, mrec) # dlf calculation fEM2 = transform.dlf(PJ2, lambd, off, fhtfilt, -1, factAng=factAng, ab=ab) # Analytical frequency-domain solution freq2 = kernel.fullspace(off, angle, zsrc, zrec, etaH, etaV, zetaH, zetaV, ab, msrc, mrec) # Compare assert_allclose(np.squeeze(fEM2), np.squeeze(freq2), rtol=1e-4) # # # 3. Spline; Multi angle # # # lambd, _ = transform.get_spline_values(fhtfilt, off, 10) # fht calculation PJ3 = kernel.wavenumber(zsrc, zrec, lsrc, lrec, depth, etaH, etaV, zetaH, zetaV, lambd, ab, xdirect, msrc, mrec, use_ne_eval) # dlf calculation fEM3 = transform.dlf(PJ3, lambd, off, fhtfilt, 10, factAng=factAng, ab=ab) # Compare assert_allclose(np.squeeze(fEM3), np.squeeze(freq2), rtol=1e-3)
def forward(self, m, output_type='response'): """ Return Bz or dBzdt """ self.model = m n_frequency = self.survey.n_frequency flag = self.survey.field_type n_layer = self.survey.n_layer depth = self.survey.depth I = self.survey.I n_filter = self.n_filter # Get lambd and offset, will depend on pts_per_dec if self.survey.src_type == "VMD": r = self.survey.offset else: # a is the radius of the loop r = self.survey.a * np.ones(n_frequency) # Use function from empymod # size of lambd is (n_frequency x n_filter) lambd = np.empty([self.survey.frequency.size, n_filter], order='F') lambd[:, :], _ = get_spline_values(self.fhtfilt, r, self.hankel_pts_per_dec) # lambd, _ = get_spline_values(self.fhtfilt, r, self.hankel_pts_per_dec) # TODO: potentially store f = np.empty([self.survey.frequency.size, n_filter], order='F') f[:,:] = np.tile(self.survey.frequency.reshape([-1, 1]), (1, n_filter)) # h is an inversion parameter if self.hMap is not None: h = self.h else: h = self.survey.h z = h + self.survey.dz chi = self.chi if np.isscalar(self.chi): chi = np.ones_like(self.sigma) * self.chi # TODO: potentially store sig = self.sigma_cole() if output_type == 'response': # for simulation if self.survey.src_type == 'VMD': hz = self.hz_kernel_vertical_magnetic_dipole( lambd, f, n_layer, sig, chi, depth, h, z, flag, output_type=output_type ) # kernels for each bessel function # (j0, j1, j2) PJ = (hz, None, None) # PJ0 elif self.survey.src_type == 'CircularLoop': hz = self.hz_kernel_circular_loop( lambd, f, n_layer, sig, chi, depth, h, z, I, r, flag, output_type=output_type ) # kernels for each bessel function # (j0, j1, j2) PJ = (None, hz, None) # PJ1 # TODO: This has not implemented yet! elif self.survey.src_type == "piecewise_line": # Need to compute y hz = self.hz_kernel_horizontal_electric_dipole( lambd, f, n_layer, sig, chi, depth, h, z, I, r, flag, output_type=output_type ) # kernels for each bessel function # (j0, j1, j2) PJ = (None, hz, None) # PJ1 else: raise Exception("Src options are only VMD or CircularLoop!!") elif output_type == 'sensitivity_sigma': # for simulation if self.survey.src_type == 'VMD': hz = self.hz_kernel_vertical_magnetic_dipole( lambd, f, n_layer, sig, chi, depth, h, z, flag, output_type=output_type ) PJ = (hz, None, None) # PJ0 elif self.survey.src_type == 'CircularLoop': hz = self.hz_kernel_circular_loop( lambd, f, n_layer, sig, chi, depth, h, z, I, r, flag, output_type=output_type ) PJ = (None, hz, None) # PJ1 else: raise Exception("Src options are only VMD or CircularLoop!!") r = np.tile(r, (n_layer, 1)) elif output_type == 'sensitivity_height': # for simulation if self.survey.src_type == 'VMD': hz = self.hz_kernel_vertical_magnetic_dipole( lambd, f, n_layer, sig, chi, depth, h, z, flag, output_type=output_type ) PJ = (hz, None, None) # PJ0 elif self.survey.src_type == 'CircularLoop': hz = self.hz_kernel_circular_loop( lambd, f, n_layer, sig, chi, depth, h, z, I, r, flag, output_type=output_type ) PJ = (None, hz, None) # PJ1 else: raise Exception("Src options are only VMD or CircularLoop!!") # Carry out Hankel DLF # ab=66 => 33 (vertical magnetic src and rec) # For response # HzFHT size = (n_frequency,) # For sensitivity # HzFHT size = (n_layer, n_frequency) HzFHT = dlf(PJ, lambd, r, self.fhtfilt, self.hankel_pts_per_dec, factAng=None, ab=33) if output_type == "sensitivity_sigma": return HzFHT.T return HzFHT
def forward(self, m, output_type='response'): """ Return Bz or dBzdt """ self.model = m n_frequency = self.survey.n_frequency flag = self.survey.field_type n_layer = self.survey.n_layer depth = self.survey.depth I = self.survey.I n_filter = self.n_filter # Get lambd and offset, will depend on pts_per_dec if self.survey.src_type == "VMD": r = self.survey.offset else: # a is the radius of the loop r = self.survey.a * np.ones(n_frequency) # Use function from empymod # size of lambd is (n_frequency x n_filter) lambd = np.empty([self.survey.frequency.size, n_filter], order='F') lambd[:, :], _ = get_spline_values( self.fhtfilt, r, self.hankel_pts_per_dec ) # TODO: potentially store f = np.empty([self.survey.frequency.size, n_filter], order='F') f[:, :] = np.tile( self.survey.frequency.reshape([-1, 1]), (1, n_filter) ) # h is an inversion parameter if self.hMap is not None: h = self.h else: h = self.survey.h z = h + self.survey.dz chi = self.chi if np.isscalar(self.chi): chi = np.ones_like(self.sigma) * self.chi # TODO: potentially store sig = self.sigma_cole() if output_type == 'response': # for simulation if self.survey.src_type == 'VMD': hz = self.hz_kernel_vertical_magnetic_dipole( lambd, f, n_layer, sig, chi, depth, h, z, flag, output_type=output_type ) # kernels for each bessel function # (j0, j1, j2) PJ = (hz, None, None) # PJ0 elif self.survey.src_type == 'CircularLoop': hz = self.hz_kernel_circular_loop( lambd, f, n_layer, sig, chi, depth, h, z, I, r, flag, output_type=output_type ) # kernels for each bessel function # (j0, j1, j2) PJ = (None, hz, None) # PJ1 # TODO: This has not implemented yet! elif self.survey.src_type == "piecewise_line": # Need to compute y hz = self.hz_kernel_horizontal_electric_dipole( lambd, f, n_layer, sig, chi, depth, h, z, I, r, flag, output_type=output_type ) # kernels for each bessel function # (j0, j1, j2) PJ = (None, hz, None) # PJ1 else: raise Exception("Src options are only VMD or CircularLoop!!") elif output_type == 'sensitivity_sigma': # for simulation if self.survey.src_type == 'VMD': hz = self.hz_kernel_vertical_magnetic_dipole( lambd, f, n_layer, sig, chi, depth, h, z, flag, output_type=output_type ) PJ = (hz, None, None) # PJ0 elif self.survey.src_type == 'CircularLoop': hz = self.hz_kernel_circular_loop( lambd, f, n_layer, sig, chi, depth, h, z, I, r, flag, output_type=output_type ) PJ = (None, hz, None) # PJ1 else: raise Exception("Src options are only VMD or CircularLoop!!") r = np.tile(r, (n_layer, 1)) elif output_type == 'sensitivity_height': # for simulation if self.survey.src_type == 'VMD': hz = self.hz_kernel_vertical_magnetic_dipole( lambd, f, n_layer, sig, chi, depth, h, z, flag, output_type=output_type ) PJ = (hz, None, None) # PJ0 elif self.survey.src_type == 'CircularLoop': hz = self.hz_kernel_circular_loop( lambd, f, n_layer, sig, chi, depth, h, z, I, r, flag, output_type=output_type ) PJ = (None, hz, None) # PJ1 else: raise Exception("Src options are only VMD or CircularLoop!!") # Carry out Hankel DLF # ab=66 => 33 (vertical magnetic src and rec) # For response # HzFHT size = (n_frequency,) # For sensitivity # HzFHT size = (n_layer, n_frequency) HzFHT = dlf(PJ, lambd, r, self.fhtfilt, self.hankel_pts_per_dec, factAng=None, ab=33) if output_type == "sensitivity_sigma": return HzFHT.T return HzFHT
def test_hankel(htype): # 1. fht / 2. hqwe / 3. hquad # Compare wavenumber-domain calculation / FHT with analytical # frequency-domain fullspace solution calc = getattr(transform, htype) model = utils.check_model([], 10, 2, 2, 5, 1, 10, True, 0) depth, res, aniso, epermH, epermV, mpermH, mpermV, _ = model frequency = utils.check_frequency(1, res, aniso, epermH, epermV, mpermH, mpermV, 0) _, etaH, etaV, zetaH, zetaV = frequency src = [0, 0, 0] src, nsrc = utils.check_dipole(src, 'src', 0) for ab_inp in [11, 12, 13, 33]: ab, msrc, mrec = utils.check_ab(ab_inp, 0) _, htarg = utils.check_hankel(htype, None, 0) xdirect = False # Important, as we want to compare wavenr-frequency! rec = [np.arange(1, 11)*500, np.zeros(10), 300] rec, nrec = utils.check_dipole(rec, 'rec', 0) off, angle = utils.get_off_ang(src, rec, nsrc, nrec, 0) factAng = kernel.angle_factor(angle, ab, msrc, mrec) lsrc, zsrc = utils.get_layer_nr(src, depth) lrec, zrec = utils.get_layer_nr(rec, depth) # # # 0. No Spline # # # if htype != 'hquad': # hquad is always using spline # Wavenumber solution plus transform # Adjust htarg for fht if htype == 'fht': lambd, int_pts = transform.get_spline_values(htarg[0], off, htarg[1]) htarg = (htarg[0], htarg[1], lambd, int_pts) wvnr0, _, conv = calc(zsrc, zrec, lsrc, lrec, off, factAng, depth, ab, etaH, etaV, zetaH, zetaV, xdirect, htarg, False, msrc, mrec) # Analytical frequency-domain solution freq0 = kernel.fullspace(off, angle, zsrc, zrec, etaH, etaV, zetaH, zetaV, ab, msrc, mrec) # Compare assert_allclose(conv, True) assert_allclose(np.squeeze(wvnr0), np.squeeze(freq0)) # # # 1. Spline; One angle # # # htarg, _ = utils.spline_backwards_hankel(htype, None, 'spline') _, htarg = utils.check_hankel(htype, htarg, 0) if htype == 'hquad': # Lower atol to ensure convergence _, htarg = utils.check_hankel('quad', [1e-8], 0) elif htype == 'fht': # Adjust htarg for fht lambd, int_pts = transform.get_spline_values(htarg[0], off, htarg[1]) htarg = (htarg[0], htarg[1], lambd, int_pts) # Wavenumber solution plus transform wvnr1, _, conv = calc(zsrc, zrec, lsrc, lrec, off, factAng, depth, ab, etaH, etaV, zetaH, zetaV, xdirect, htarg, False, msrc, mrec) # Analytical frequency-domain solution freq1 = kernel.fullspace(off, angle, zsrc, zrec, etaH, etaV, zetaH, zetaV, ab, msrc, mrec) # Compare if htype == 'hqwe' and ab in [13, 33]: assert_allclose(conv, False) else: assert_allclose(conv, True) assert_allclose(np.squeeze(wvnr1), np.squeeze(freq1), rtol=1e-4) # # # 2. Spline; Multi angle # # # rec = [np.arange(1, 11)*500, np.arange(-5, 5)*200, 300] rec, nrec = utils.check_dipole(rec, 'rec', 0) off, angle = utils.get_off_ang(src, rec, nsrc, nrec, 0) factAng = kernel.angle_factor(angle, ab, msrc, mrec) if htype == 'hqwe': # Put a very low diff_quad, to test it.; lower err _, htarg = utils.check_hankel('qwe', [1e-8, '', '', 200, 80, .1, 1e-6, .1, 1000], 0) elif htype == 'fht': # Adjust htarg for fht lambd, int_pts = transform.get_spline_values(htarg[0], off, htarg[1]) htarg = (htarg[0], htarg[1], lambd, int_pts) # Analytical frequency-domain solution wvnr2, _, conv = calc(zsrc, zrec, lsrc, lrec, off, factAng, depth, ab, etaH, etaV, zetaH, zetaV, xdirect, htarg, False, msrc, mrec) # Analytical frequency-domain solution freq2 = kernel.fullspace(off, angle, zsrc, zrec, etaH, etaV, zetaH, zetaV, ab, msrc, mrec) # Compare assert_allclose(conv, True) assert_allclose(np.squeeze(wvnr2), np.squeeze(freq2), rtol=1e-4) # # # 3. Spline; pts_per_dec # # # if htype == 'fht': _, htarg = utils.check_hankel('fht', ['key_201_2012', 20], 0) lambd, int_pts = transform.get_spline_values(htarg[0], off, htarg[1]) htarg = (htarg[0], htarg[1], lambd, int_pts) elif htype == 'hqwe': _, htarg = utils.check_hankel('qwe', ['', '', '', 80, 100], 0) if htype != 'hquad': # hquad is always pts_per_dec # Analytical frequency-domain solution wvnr3, _, conv = calc(zsrc, zrec, lsrc, lrec, off, factAng, depth, ab, etaH, etaV, zetaH, zetaV, xdirect, htarg, False, msrc, mrec) # Analytical frequency-domain solution freq3 = kernel.fullspace(off, angle, zsrc, zrec, etaH, etaV, zetaH, zetaV, ab, msrc, mrec) # Compare assert_allclose(conv, True) assert_allclose(np.squeeze(wvnr3), np.squeeze(freq3), rtol=1e-4) # # # 4. Spline; Only one offset # # # rec = [5000, 0, 300] rec, nrec = utils.check_dipole(rec, 'rec', 0) off, angle = utils.get_off_ang(src, rec, nsrc, nrec, 0) factAng = kernel.angle_factor(angle, ab, msrc, mrec) if htype == 'hqwe': _, htarg = utils.check_hankel('qwe', ['', '', '', 200, 80], 0) elif htype == 'hquad': _, htarg = utils.check_hankel('quad', None, 0) elif htype == 'fht': lambd, int_pts = transform.get_spline_values(htarg[0], off, htarg[1]) htarg = (htarg[0], htarg[1], lambd, int_pts) # Analytical frequency-domain solution wvnr4, _, conv = calc(zsrc, zrec, lsrc, lrec, off, factAng, depth, ab, etaH, etaV, zetaH, zetaV, xdirect, htarg, False, msrc, mrec) # Analytical frequency-domain solution freq4 = kernel.fullspace(off, angle, zsrc, zrec, etaH, etaV, zetaH, zetaV, ab, msrc, mrec) # Compare assert_allclose(conv, True) assert_allclose(np.squeeze(wvnr4), np.squeeze(freq4), rtol=1e-4)
def setup(self, size): # One big, one small model if size == 'Small': # Total size: 5*1*1*1 = 5 off = np.array([500., 1000.]) else: # Total size: 5*100*1*201 = 100'500 off = np.arange(1, 101)*200. # Define survey freq = np.array([1]) lsrc = 1 lrec = 1 angle = np.zeros(off.shape) ab = 11 msrc = False mrec = False if VERSION2: zsrc = 250. zrec = 300. else: zsrc = np.array([250.]) # Not sure if this distinction zrec = np.array([300.]) # is actually needed use_ne_eval = False # Define model depth = np.array([-np.infty, 0, 300, 2000, 2100]) res = np.array([2e14, .3, 1, 50, 1]) aniso = np.ones(res.shape) epermH = np.ones(res.shape) epermV = np.ones(res.shape) mpermH = np.ones(res.shape) mpermV = np.ones(res.shape) # Other parameters xdirect = False verb = 0 # Compute eta, zeta etaH = 1/res + np.outer(2j*np.pi*freq, epermH*epsilon_0) etaV = 1/(res*aniso*aniso) + np.outer(2j*np.pi*freq, epermV*epsilon_0) zetaH = np.outer(2j*np.pi*freq, mpermH*mu_0) zetaV = np.outer(2j*np.pi*freq, mpermV*mu_0) # Collect input self.hankel = {'zsrc': zsrc, 'zrec': zrec, 'lsrc': lsrc, 'lrec': lrec, 'off': off, 'depth': depth, 'ab': ab, 'etaH': etaH, 'etaV': etaV, 'zetaH': zetaH, 'zetaV': zetaV, 'xdirect': xdirect, 'msrc': msrc, 'mrec': mrec} if not VERSION2: self.hankel['use_ne_eval'] = use_ne_eval # Before c73d6647; you had to give `ab` to `check_hankel`; # check_opt didn't exist then. if VERSION2: charg = (verb, ) new_version = True else: try: opt = utils.check_opt(None, None, 'fht', ['', 0], verb) charg = (verb, ) if np.size(opt) == 4: new_version = False else: new_version = True except VariableCatch: new_version = False charg = (ab, verb) # From 9bed72b0 onwards, there is no `use_spline`; `htarg` input # changed (29/04/2018; before v1.4.1). if new_version: if VERSION2: htarg = {'dlf': 'key_201_2009', 'pts_per_dec': -1} else: htarg = ['key_201_2009', -1] else: htarg = ['key_201_2009', None] # HT arguments if VERSION2: dlfargname = 'htarg' qweargname = 'htarg' quadargname = 'htarg' htarg1 = {'dlf': 'key_201_2009', 'pts_per_dec': 0} htarg2 = {'dlf': 'key_201_2009', 'pts_per_dec': 10} name = 'dlf' else: dlfargname = 'fhtarg' qweargname = 'qweargs' quadargname = 'quadargs' htarg1 = ['key_201_2009', 0] htarg2 = ['key_201_2009', 10] name = 'fht' _, fhtarg_st = utils.check_hankel(name, htarg1, *charg) self.fhtarg_st = {dlfargname: fhtarg_st} _, fhtarg_sp = utils.check_hankel(name, htarg2, *charg) self.fhtarg_sp = {dlfargname: fhtarg_sp} _, fhtarg_la = utils.check_hankel(name, htarg, *charg) self.fhtarg_la = {dlfargname: fhtarg_la} # QWE: We lower the requirements here, otherwise it takes too long # ['rtol', 'atol', 'nquad', 'maxint', 'pts_per_dec', 'diff_quad', 'a', # 'b', 'limit'] # Args depend if QUAD included into QWE or not try: if VERSION2: args_sp = {'atol': 1e-6, 'rtol': 1e-10, 'nquad': 51, 'maxint': 100, 'pts_per_dec': 10, 'diff_quad': np.inf} args_st = {'atol': 1e-6, 'rtol': 1e-10, 'nquad': 51, 'maxint': 100, 'pts_per_dec': 0, 'diff_quad': np.inf} else: args_sp = [1e-6, 1e-10, 51, 100, 10, np.inf] args_st = [1e-6, 1e-10, 51, 100, 0, np.inf] _, qwearg_sp = utils.check_hankel('qwe', args_sp, *charg) _, qwearg_st = utils.check_hankel('qwe', args_st, *charg) except VariableCatch: args_sp = [1e-6, 1e-10, 51, 100, 10] args_st = [1e-6, 1e-10, 51, 100, 0] _, qwearg_sp = utils.check_hankel('qwe', args_sp, *charg) _, qwearg_st = utils.check_hankel('qwe', args_st, *charg) self.qwearg_st = {qweargname: qwearg_st} self.qwearg_sp = {qweargname: qwearg_sp} # QUAD: We lower the requirements here, otherwise it takes too long # ['rtol', 'atol', 'limit', 'a', 'b', 'pts_per_dec'] if VERSION2: args = {'atol': 1e-6, 'rtol': 1e-10, 'limit': 100, 'a': 1e-6, 'b': 0.1, 'pts_per_dec': 10} else: args = [1e-6, 1e-10, 100, 1e-6, 0.1, 10] try: # QUAD only included since 6104614e (before v1.3.0) _, quadargs = utils.check_hankel('quad', args, *charg) self.quadargs = {quadargname: quadargs} except VariableCatch: self.quadargs = {} if not new_version and not VERSION2: self.fhtarg_la.update({'use_spline': True}) self.fhtarg_sp.update({'use_spline': True}) self.fhtarg_st.update({'use_spline': False}) self.qwearg_sp.update({'use_spline': True}) self.qwearg_st.update({'use_spline': False}) self.quadargs.update({'use_spline': True}) if VERSION2: self.hankel['ang_fact'] = kernel.angle_factor( angle, ab, msrc, mrec) else: # From bb6447a onwards ht-transforms take `factAng`, not `angle`, # to avoid re-calculation in loops. try: transform.fht(angle=angle, **self.fhtarg_la, **self.hankel) self.hankel['angle'] = angle except VariableCatch: self.hankel['factAng'] = kernel.angle_factor( angle, ab, msrc, mrec) if not VERSION2: # From b6f6872 onwards fht-transforms calculates lambd/int_pts in # model.fem, not in transform.fht, to avoid re-calculation in # loops. try: transform.fht(**self.fhtarg_la, **self.hankel) except VariableCatch: lambd, int_pts = transform.get_spline_values( fhtarg_st[0], off, fhtarg_st[1]) self.fhtarg_st.update({'fhtarg': ( fhtarg_st[0], fhtarg_st[1], lambd, int_pts)}) lambd, int_pts = transform.get_spline_values( fhtarg_la[0], off, fhtarg_la[1]) self.fhtarg_la.update( {'fhtarg': (fhtarg_la[0], fhtarg_la[1], lambd, int_pts)}) lambd, int_pts = transform.get_spline_values( fhtarg_sp[0], off, fhtarg_sp[1]) self.fhtarg_sp.update( {'fhtarg': (fhtarg_sp[0], fhtarg_sp[1], lambd, int_pts)})
def setup_cache(self): """setup_cache is not parametrized, so we do it manually. """ data = {} for size in self.params[0]: # size data[size] = {} # One big, one small model if size == 'Small': # Small; Total size: 5*1*1*1 = 5 x = np.array([500., 1000.]) else: # Big; Total size: 5*100*100*201 = 10'050'000 x = np.arange(1, 101)*200. # Define model parameters freq = np.array([1]) src = [0, 0, 250] rec = [x, np.zeros(x.shape), 300] depth = np.array([-np.infty, 0, 300, 2000, 2100]) res = np.array([2e14, .3, 1, 50, 1]) ab = 11 xdirect = False verb = 0 if not VERSION2: use_ne_eval = False # Checks (since DLF exists the `utils`-checks haven't changed, so # we just use them here. model = utils.check_model(depth, res, None, None, None, None, None, xdirect, verb) depth, res, aniso, epermH, epermV, mpermH, mpermV, _ = model frequency = utils.check_frequency(freq, res, aniso, epermH, epermV, mpermH, mpermV, verb) freq, etaH, etaV, zetaH, zetaV = frequency ab, msrc, mrec = utils.check_ab(ab, verb) src, nsrc = utils.check_dipole(src, 'src', verb) rec, nrec = utils.check_dipole(rec, 'rec', verb) off, angle = utils.get_off_ang(src, rec, nsrc, nrec, verb) lsrc, zsrc = utils.get_layer_nr(src, depth) lrec, zrec = utils.get_layer_nr(rec, depth) for htype in self.params[1]: # htype # pts_per_dec depending on htype if htype == 'Standard': pts_per_dec = 0 elif htype == 'Lagged': pts_per_dec = -1 else: pts_per_dec = 10 # Compute kernels for dlf if VERSION2: # HT arguments _, fhtarg = utils.check_hankel( 'dlf', {'dlf': 'key_201_2009', 'pts_per_dec': pts_per_dec}, 0) inp = (fhtarg['dlf'], off, fhtarg['pts_per_dec']) lambd, _ = transform.get_dlf_points(*inp) else: # HT arguments _, fhtarg = utils.check_hankel( 'fht', ['key_201_2009', pts_per_dec], 0) inp = (fhtarg[0], off, fhtarg[1]) lambd, _ = transform.get_spline_values(*inp) if VERSION2: inp = (zsrc, zrec, lsrc, lrec, depth, etaH, etaV, zetaH, zetaV, lambd, ab, xdirect, msrc, mrec) else: inp = (zsrc, zrec, lsrc, lrec, depth, etaH, etaV, zetaH, zetaV, lambd, ab, xdirect, msrc, mrec, use_ne_eval) PJ = kernel.wavenumber(*inp) factAng = kernel.angle_factor(angle, ab, msrc, mrec) # Signature changed at commit a15af07 (20/05/2018; before # v1.6.2) try: dlf = {'signal': PJ, 'points': lambd, 'out_pts': off, 'ab': ab} if VERSION2: dlf['ang_fact'] = factAng dlf['filt'] = fhtarg['dlf'] dlf['pts_per_dec'] = fhtarg['pts_per_dec'] else: dlf['factAng'] = factAng dlf['filt'] = fhtarg[0] dlf['pts_per_dec'] = fhtarg[1] transform.dlf(**dlf) except VariableCatch: dlf = {'signal': PJ, 'points': lambd, 'out_pts': off, 'targ': fhtarg, 'factAng': factAng} data[size][htype] = dlf return data