def test_fullspace(): # 6. fullspace # Compare all to maintain status quo. fs = DATAEMPYMOD['fs'][()] fsres = DATAEMPYMOD['fsres'][()] for key in fs: # Get fullspace fs_res = kernel.fullspace(**fs[key]) # Check assert_allclose(fs_res, fsres[key])
def test_fullspace(self): # Comparison to analytical fullspace solution fs = DATAEMPYMOD['fs'][()] fsbp = DATAEMPYMOD['fsbp'][()] for key in fs: # Get fullspace fs_res = fullspace(**fs[key]) # Get bipole bip_res = bipole(**fsbp[key]) # Check assert_allclose(fs_res, bip_res)
# Model 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, nsrc = utils.check_dipole([0, 0, 0], 'src', 0) ab, msrc, mrec = utils.check_ab(11, 0) ht, htarg = utils.check_hankel('qwe', None, 0) 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) # Frequency-domain result freqres = kernel.fullspace(off, angle, zsrc, zrec, etaH, etaV, zetaH, zetaV, ab, msrc, mrec) # The following is a condensed version of transform.hqwe etaH = etaH[0, :] etaV = etaV[0, :] zetaH = zetaH[0, :] zetaV = zetaV[0, :] rtol, atol, nquad, maxint, pts_per_dec, diff_quad, a, b, limit = htarg g_x, g_w = special.p_roots(nquad) b_zero = np.pi * np.arange(1.25, maxint + 1) for i in range(10): b_x0 = special.j1(b_zero) b_x1 = special.jv(2, b_zero) b_h = -b_x0 / (b_x0 / b_zero - b_x1) b_zero += b_h if all(np.abs(b_h) < 8 * np.finfo(float).eps * b_zero): break
def test_dlf(): # 10. dlf # DLF is integral of hankel_dlf and fourier_dlf, and therefore tested a lot # through those. Here we just ensure status quo. And if a problem arises in # hankel_dlf or fourier_dlf, 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['fourier_dlf' + 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['pts_per_dec'] == 0: finp = finp.reshape(t.size, -1) tEM = transform.dlf(finp, 2 * np.pi * dat['f'], t, ftarg['dlf'], ftarg['pts_per_dec'], kind=ftarg['kind']) 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, _ = 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) ab, msrc, mrec = utils.check_ab(ab, 0) ht, htarg = utils.check_hankel('dlf', {}, 0) 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) dlf = htarg['dlf'] pts_per_dec = htarg['pts_per_dec'] # # # 0. No Spline # # # # dlf calculation lambd = dlf.base / off[:, None] PJ = kernel.wavenumber(zsrc, zrec, lsrc, lrec, depth, etaH, etaV, zetaH, zetaV, lambd, ab, xdirect, msrc, mrec) # Angle factor, one example with None instead of 1's. if ab != 13: ang_fact = kernel.angle_factor(angle, ab, msrc, mrec) else: ang_fact = None # dlf calculation fEM0 = transform.dlf(PJ, lambd, off, dlf, 0, ang_fact=ang_fact, 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 # # # # dlf calculation lambd, _ = transform.get_dlf_points(dlf, off, pts_per_dec) PJ1 = kernel.wavenumber(zsrc, zrec, lsrc, lrec, depth, etaH, etaV, zetaH, zetaV, lambd, ab, xdirect, msrc, mrec) # dlf calculation fEM1 = transform.dlf(PJ1, lambd, off, dlf, pts_per_dec, ang_fact=ang_fact, 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) # dlf calculation lambd, _ = transform.get_dlf_points(dlf, off, -1) PJ2 = kernel.wavenumber(zsrc, zrec, lsrc, lrec, depth, etaH, etaV, zetaH, zetaV, lambd, ab, xdirect, msrc, mrec) ang_fact = kernel.angle_factor(angle, ab, msrc, mrec) # dlf calculation fEM2 = transform.dlf(PJ2, lambd, off, dlf, -1, ang_fact=ang_fact, 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) # dlf calculation lambd, _ = transform.get_dlf_points(dlf, off, -1) PJ2 = kernel.wavenumber(zsrc, zrec, lsrc, lrec, depth, etaH, etaV, zetaH, zetaV, lambd, ab, xdirect, msrc, mrec) ang_fact = kernel.angle_factor(angle, ab, msrc, mrec) # dlf calculation fEM2 = transform.dlf(PJ2, lambd, off, dlf, -1, ang_fact=ang_fact, 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_dlf_points(dlf, off, 30) # dlf calculation PJ3 = kernel.wavenumber(zsrc, zrec, lsrc, lrec, depth, etaH, etaV, zetaH, zetaV, lambd, ab, xdirect, msrc, mrec) # dlf calculation fEM3 = transform.dlf(PJ3, lambd, off, dlf, 30, ang_fact=ang_fact, ab=ab) # Compare assert_allclose(np.squeeze(fEM3), np.squeeze(freq2), rtol=1e-3)
def test_hankel(htype): # 1. DLF / 2. QWE / 3. QUAD # Compare wavenumber-domain calculation / DLF with analytical # frequency-domain fullspace solution calc = getattr(transform, 'hankel_' + 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, {}, 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) ang_fact = 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 != 'quad': # quad is always using spline # Wavenumber solution plus transform # Adjust htarg for dlf if htype == 'dlf': lambd, int_pts = transform.get_dlf_points( htarg['dlf'], off, htarg['pts_per_dec']) htarg['lambd'] = lambd htarg['int_pts'] = int_pts wvnr0, _, conv = calc(zsrc, zrec, lsrc, lrec, off, ang_fact, depth, ab, etaH, etaV, zetaH, zetaV, xdirect, htarg, 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.check_hankel(htype, {'pts_per_dec': 80}, 0) if htype == 'quad': # Lower atol to ensure convergence _, htarg = utils.check_hankel('quad', {'rtol': 1e-8}, 0) elif htype == 'dlf': # Adjust htarg for dlf lambd, int_pts = transform.get_dlf_points(htarg['dlf'], off, htarg['pts_per_dec']) htarg['lambd'] = lambd htarg['int_pts'] = int_pts # Wavenumber solution plus transform wvnr1, _, conv = calc(zsrc, zrec, lsrc, lrec, off, ang_fact, depth, ab, etaH, etaV, zetaH, zetaV, xdirect, htarg, msrc, mrec) # Analytical frequency-domain solution freq1 = kernel.fullspace(off, angle, zsrc, zrec, etaH, etaV, zetaH, zetaV, ab, msrc, mrec) # Compare if htype == 'qwe' 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) ang_fact = kernel.angle_factor(angle, ab, msrc, mrec) if htype == 'qwe': # Put a very low diff_quad, to test it.; lower err _, htarg = utils.check_hankel( 'qwe', { 'rtol': 1e-8, 'maxint': 200, 'pts_per_dec': 80, 'diff_quad': .1, 'a': 1e-6, 'b': .1, 'limit': 1000 }, 0) elif htype == 'dlf': # Adjust htarg for dlf lambd, int_pts = transform.get_dlf_points(htarg['dlf'], off, htarg['pts_per_dec']) htarg['lambd'] = lambd htarg['int_pts'] = int_pts # Analytical frequency-domain solution wvnr2, _, conv = calc(zsrc, zrec, lsrc, lrec, off, ang_fact, depth, ab, etaH, etaV, zetaH, zetaV, xdirect, htarg, 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 == 'dlf': _, htarg = utils.check_hankel('dlf', { 'dlf': 'key_201_2012', 'pts_per_dec': 20 }, 0) lambd, int_pts = transform.get_dlf_points(htarg['dlf'], off, htarg['pts_per_dec']) htarg['lambd'] = lambd htarg['int_pts'] = int_pts elif htype == 'qwe': _, htarg = utils.check_hankel('qwe', { 'maxint': 80, 'pts_per_dec': 100 }, 0) if htype != 'quad': # quad is always pts_per_dec # Analytical frequency-domain solution wvnr3, _, conv = calc(zsrc, zrec, lsrc, lrec, off, ang_fact, depth, ab, etaH, etaV, zetaH, zetaV, xdirect, htarg, 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) ang_fact = kernel.angle_factor(angle, ab, msrc, mrec) if htype == 'qwe': _, htarg = utils.check_hankel('qwe', { 'maxint': 200, 'pts_per_dec': 80 }, 0) elif htype == 'quad': _, htarg = utils.check_hankel('quad', {}, 0) elif htype == 'dlf': lambd, int_pts = transform.get_dlf_points(htarg['dlf'], off, htarg['pts_per_dec']) htarg['lambd'] = lambd htarg['int_pts'] = int_pts # Analytical frequency-domain solution wvnr4, _, conv = calc(zsrc, zrec, lsrc, lrec, off, ang_fact, depth, ab, etaH, etaV, zetaH, zetaV, xdirect, htarg, 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 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 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, 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(11, 0) ht, htarg = utils.check_hankel(htype, None, 0) options = utils.check_opt(None, None, htype, htarg, 0) use_ne_eval, loop_freq, loop_off = options xdirect = False # Important, as we want to compare 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) # # # 0. No Spline # # # if htype != 'hquad': # hquad is always using spline # Wavenumber solution plus transform wvnr0, _, conv = calc(zsrc, zrec, lsrc, lrec, off, angle, 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, opt = utils.spline_backwards_hankel(htype, None, 'spline') ht, htarg = utils.check_hankel(htype, htarg, 0) options = utils.check_opt(None, None, htype, htarg, 0) use_ne_eval, loop_freq, loop_off = options if htype == 'hquad': # Lower atol to ensure convergence ht, htarg = utils.check_hankel('quad', [1e-8], 0) # Wavenumber solution plus transform wvnr1, _, conv = calc(zsrc, zrec, lsrc, lrec, off, angle, 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 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) if htype == 'hqwe': # Put a very low diff_quad, to test it.; lower err ht, htarg = utils.check_hankel( 'qwe', [1e-8, '', '', 200, 80, .1, 1e-6, .1, 1000], 0) # Analytical frequency-domain solution wvnr2, _, conv = calc(zsrc, zrec, lsrc, lrec, off, angle, 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': ht, htarg = utils.check_hankel('fht', ['key_201_2012', 20], 0) elif htype == 'hqwe': ht, 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, angle, 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) if htype == 'hqwe': ht, htarg = utils.check_hankel('qwe', ['', '', '', 200, 80], 0) elif htype == 'hquad': ht, htarg = utils.check_hankel('quad', None, 0) # Analytical frequency-domain solution wvnr4, _, conv = calc(zsrc, zrec, lsrc, lrec, off, angle, 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)
'srcpts': 1, 'mrec': mrec, 'recpts': 1, 'strength': 0, 'xdirect': False, 'ht': 'fht', 'htarg': None, 'ft': None, 'ftarg': None, 'opt': None, 'loop': None, 'verb': 0 } # Get result for fullspace fs_res[str(pab[i])] = fullspace(**fs[str(pab[i])]) # # D -- HALFSPACE # # # More or less random values, to test a wide range of models. # src fixed at [0, 0, 100]; Never possible to test all combinations... # halfspace is only implemented for electric sources and receivers so far, # and for the diffusive approximation (low freq). pab = [11, 12, 13, 21, 22, 23, 31, 32, 33] prec = [[10000, -300, 500], [5000, 200, 400], [1000, 0, 300], [100, 500, 500], [1000, 200, 300], [0, 2000, 200], [3000, 0, 300], [10, 1000, 10], [100, 6000, 200]] pres = [10, 3, 3, 3, 4, .004, 300, 20, 1] paniso = [1, 5, 1, 3, 2, 3, 1, 1, 1] # this is freq or time; for diffusive approximation, we must use low freqs # or late time, according to signal pfreq = [0.1, 5, 6, 7, 8, 9, 10, 1, 0.1]
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)