Example #1
0
def test_check_opt(capsys):
    fhtarg = [filters.kong_61_2007(), 43]
    qwehtarg = [
        np.array(1e-12),
        np.array(1e-30),
        np.array(51),
        np.array(100),
        np.array(33)
    ]

    res = utils.check_opt(None, None, 'fht', fhtarg, 4)
    assert_allclose(res, (False, True, False))
    out, _ = capsys.readouterr()
    outstr = "   Kernel Opt.     :  None\n   Loop over       :  Freq"
    assert out[:53] == outstr

    res = utils.check_opt(None, 'off', 'hqwe', qwehtarg, 4)
    assert_allclose(res, (False, True, False))
    out, _ = capsys.readouterr()
    outstr = "   Kernel Opt.     :  None\n   Loop over       :  Freq"
    assert out[:53] == outstr

    res = utils.check_opt('parallel', 'off', 'fht', [fhtarg[0], 0], 4)
    if use_vml:
        assert_allclose(callable(res[0]), True)
        outstr = "   Kernel Opt.     :  Use parallel\n   Loop over       :  Of"
    elif not use_ne_eval:
        assert_allclose(callable(res[0]), False)
        outstr = "* WARNING :: `numexpr` is not installed, `opt=='parallel'` "
    else:
        assert_allclose(callable(res[0]), False)
        outstr = "* WARNING :: `numexpr` is not installed with VML, `opt=='pa"
    assert_allclose(res[1:], (False, True))
    out, _ = capsys.readouterr()
    assert out[:59] == outstr

    res = utils.check_opt('parallel', 'freq', 'hqwe', qwehtarg, 4)
    if use_vml:
        assert_allclose(callable(res[0]), True)
        outstr = "   Kernel Opt.     :  Use parallel\n   Loop over       :  Fr"
    elif not use_ne_eval:
        assert_allclose(callable(res[0]), False)
        outstr = "* WARNING :: `numexpr` is not installed, `opt=='parallel'` "
    else:
        assert_allclose(callable(res[0]), False)
        outstr = "* WARNING :: `numexpr` is not installed with VML, `opt=='pa"
    assert_allclose(res[1:], (True, False))
    out, _ = capsys.readouterr()
    assert out[:59] == outstr
Example #2
0
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)
Example #3
0
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)
Example #4
0
    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)})