Exemple #1
0
def main():
    parser = argparse.ArgumentParser(description="Test divergence")
    parser.add_argument("--show", "--plot", action="store_true")
    args = vutil.common_argparse(parser)

    dtype = 'float64'

    # use 512 512 256 to inspect memory related things
    x = np.array(np.linspace(-0.5, 0.5, 256), dtype=dtype)
    y = np.array(np.linspace(-0.5, 0.5, 256), dtype=dtype)
    z = np.array(np.linspace(-0.5, 0.5, 64), dtype=dtype)

    v = viscid.empty([x, y, z], name="V", nr_comps=3, center="cell",
                     layout="interlaced")
    exact_cc = viscid.empty([x, y, z], name="exact_cc", center='cell')


    Xcc, Ycc, Zcc = exact_cc.get_crds_cc(shaped=True) #pylint: disable=W0612

    v['x'] = ne.evaluate("(sin(Xcc))")  # + Zcc
    v['y'] = ne.evaluate("(cos(Ycc))")  # + Xcc# + Zcc
    v['z'] = ne.evaluate("-((sin(Zcc)))")  # + Xcc# + Ycc
    exact_cc[:, :, :] = ne.evaluate("cos(Xcc) - sin(Ycc) - cos(Zcc)")

    logger.info("node centered tests")
    v_nc = v.as_centered('node')
    exact_nc = viscid.empty_like(v_nc['x'])
    X, Y, Z = exact_nc.get_crds_nc(shaped=True) #pylint: disable=W0612
    exact_nc[:, :, :] = ne.evaluate("cos(X) - sin(Y) - cos(Z)")
    # FIXME: why is the error so much larger here?
    run_div_test(v_nc, exact_nc, show=args.show, ignore_inexact=True)

    logger.info("cell centered tests")
    v_cc = v_nc.as_centered('cell')
    run_div_test(v_cc, exact_cc, show=args.show)
Exemple #2
0
def _main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--prof", action="store_true")
    parser.add_argument("--show", "--plot", action="store_true")
    args = vutil.common_argparse(parser)

    dtype = 'float64'

    # use 512 512 256 to inspect memory related things
    x = np.array(np.linspace(-0.5, 0.5, 256), dtype=dtype)
    y = np.array(np.linspace(-0.5, 0.5, 256), dtype=dtype)
    z = np.array(np.linspace(-0.5, 0.5, 64), dtype=dtype)

    v = viscid.empty([x, y, z], name="V", nr_comps=3, center="cell",
                     layout="interlaced")
    exact_cc = viscid.empty([x, y, z], name="exact_cc", center='cell')

    Xcc, Ycc, Zcc = exact_cc.get_crds_cc(shaped=True)  # pylint: disable=W0612

    if HAS_NUMEXPR:
        v['x'] = ne.evaluate("(sin(Xcc))")  # + Zcc
        v['y'] = ne.evaluate("(cos(Ycc))")  # + Xcc# + Zcc
        v['z'] = ne.evaluate("-((sin(Zcc)))")  # + Xcc# + Ycc
        exact_cc[:, :, :] = ne.evaluate("cos(Xcc) - sin(Ycc) - cos(Zcc)")
    else:
        v['x'] = (np.sin(Xcc))  # + Zcc
        v['y'] = (np.cos(Ycc))  # + Xcc# + Zcc
        v['z'] = -((np.sin(Zcc)))  # + Xcc# + Ycc
        exact_cc[:, :, :] = np.cos(Xcc) - np.sin(Ycc) - np.cos(Zcc)

    if args.prof:
        print("Without boundaries")
        viscid.timeit(viscid.div, v, bnd=False, timeit_repeat=10,
                      timeit_print_stats=True)
        print("With boundaries")
        viscid.timeit(viscid.div, v, bnd=True, timeit_repeat=10,
                      timeit_print_stats=True)

    logger.info("node centered tests")
    v_nc = v.as_centered('node')
    exact_nc = viscid.empty_like(v_nc['x'])
    X, Y, Z = exact_nc.get_crds_nc(shaped=True)  # pylint: disable=W0612
    if HAS_NUMEXPR:
        exact_nc[:, :, :] = ne.evaluate("cos(X) - sin(Y) - cos(Z)")
    else:
        exact_nc[:, :, :] = np.cos(X) - np.sin(Y) - np.cos(Z)
    # FIXME: why is the error so much larger here?
    run_div_test(v_nc, exact_nc, title='Node Centered', show=args.show,
                 ignore_inexact=True)

    logger.info("cell centered tests")
    v_cc = v_nc.as_centered('cell')
    run_div_test(v_cc, exact_cc, title="Cell Centered", show=args.show)

    return 0
def main():
    mhd_type = "C3"
    make_plots = 1

    mhd_type = mhd_type.upper()
    if mhd_type.startswith("C"):
        if mhd_type in ("C",):
            f = viscid.load_file("$WORK/tmedium/*.3d.[-1].xdmf")
        elif mhd_type in ("C2", "C3"):
            f = viscid.load_file("$WORK/tmedium2/*.3d.[-1].xdmf")
        else:
            raise ValueError()
        catol = 1e-8
        rtol = 2e-6
    elif mhd_type in ("F", "FORTRAN"):
        f = viscid.load_file("$WORK/tmedium3/*.3df.[-1]")
        catol = 1e-8
        rtol = 7e-2
    else:
        raise ValueError()

    b = f['b_cc']
    b1 = f['b_fc']
    e_cc = f['e_cc']
    e_ec = f['e_ec']
    # divb =  f['divB']

    # viscid.interact()

    if True:
        bD = viscid.empty_like(b)
        bD.data = np.array(b.data)

        b1D = viscid.empty_like(b1)
        b1D.data = np.array(b1.data)

        mask5 = viscid.make_spherical_mask(bD, rmax=3.5)
        mask1_5 = viscid.make_spherical_mask(bD, rmax=1.5)
        viscid.fill_dipole(bD, mask=mask5)
        viscid.set_in_region(bD, bD, 0.0, 0.0, mask=mask1_5, out=bD)

        # compare_vectors(_b, bD, make_plots=True)
        mask5 = viscid.make_spherical_mask(b1D, rmax=3.5)
        mask1_5 = viscid.make_spherical_mask(b1D, rmax=1.5)
        viscid.fill_dipole(b1D, mask=mask5)
        viscid.set_in_region(b1D, b1D, 0.0, 0.0, mask=mask1_5, out=b1D)

        compare_vectors(bD["x=1:-1, y=1:-1, z=1:-1"], b1D.as_cell_centered(),
                        make_plots=True)

        # plt.clf()
        # dkwargs = dict(symmetric=True, earth=True, clim=(-1e2, 1e2))
        # ax1 = plt.subplot(311)
        # vlt.plot(viscid.div(b1)['y=0j'], **dkwargs)
        # plt.subplot(312, sharex=ax1, sharey=ax1)
        # vlt.plot(viscid.div(b)['y=0j'], **dkwargs)
        # plt.subplot(313, sharex=ax1, sharey=ax1)
        # vlt.plot(viscid.div(b1D)['y=0j'], **dkwargs)
        # vlt.show()

        bD = b1D = mask5 = mask1_5 = None

    # straight up interpolate b1 to cc crds and compare with b
    if True:
        b1_cc = viscid.interp_trilin(b1, b).as_flat()

        viscid.set_in_region(b, b, alpha=0.0, beta=0.0, out=b,
                             mask=viscid.make_spherical_mask(b, rmax=5.0))
        viscid.set_in_region(b1_cc, b1_cc, alpha=0.0, beta=0.0, out=b1_cc,
                             mask=viscid.make_spherical_mask(b1_cc, rmax=5.0))

        compare_vectors(b, b1_cc, make_plots=True)

    # make div?
    if True:
        # make seeds for 1.5x supersampling b1
        n = 128
        seeds = viscid.Volume((5.1, -0.02, -5.0), (12.0, 0.02, 5.0), (n, 3, n))
        # do interpolation onto new seeds
        b2 = viscid.interp_trilin(b1, seeds)

        div_b = viscid.div(b)
        div_b1 = viscid.div(b1)
        div_b2 = viscid.div(b2)

        viscid.set_in_region(div_b, div_b, alpha=0.0, beta=0.0, out=div_b,
                             mask=viscid.make_spherical_mask(div_b, rmax=5.0))
        viscid.set_in_region(div_b1, div_b1, alpha=0.0, beta=0.0, out=div_b1,
                             mask=viscid.make_spherical_mask(div_b1, rmax=5.0))
        viscid.set_in_region(div_b2, div_b2, alpha=0.0, beta=0.0, out=div_b2,
                             mask=viscid.make_spherical_mask(div_b2, rmax=5.0))
        viscid.set_in_region(divb, divb, alpha=0.0, beta=0.0, out=divb,
                             mask=viscid.make_spherical_mask(divb, rmax=5.0))

        plt.clf()
        ax1 = vlt.subplot(311)
        vlt.plot(div_b['y=0j'], symmetric=True, earth=True)
        vlt.subplot(312, sharex=ax1, sharey=ax1)
        # vlt.plot(div_b1['y=0j'], symmetric=True, earth=True)
        vlt.plot(div_b2['y=0j'], symmetric=True, earth=True)
        vlt.subplot(313, sharex=ax1, sharey=ax1)
        vlt.plot(divb['y=0j'], symmetric=True, earth=True)

        vlt.show()

    return 0
Exemple #4
0
def get_mp_info(pp, b, j, e, cache=True, cache_dir=None,
                slc="x=5.5j:11.0j, y=-4.0j:4.0j, z=-3.6j:3.6j",
                fit="mp_xloc", fit_p0=(9.0, 0.0, 0.0, 1.0, -1.0, -1.0)):
    """Get info about m-pause as flattened fields

    Notes:
        The first thing this function does is mask locations where
        the GSE-y current density < 1e-4. This masks out the bow
        shock and current free regions. This works for southward IMF,
        but it is not very general.

    Parameters:
        pp (ScalarcField): pressure
        b (VectorField): magnetic field
        j (VectorField): current density
        e (VectorField, None): electric field (same centering as b). If
            None, then the info that requires E will be filled with NaN
        cache (bool, str): Save to and load from cache, if "force",
            then don't load from cache if it exists, but do save a
            cache at the end
        cache_dir (str): Directory for cache, if None, same directory
            as that file to which the grid belongs
        slc (str): slice that gives a box that contains the m-pause
        fit (str): to which resulting field should the paraboloid be fit,
            defaults to mp_xloc, but pp_max_xloc might be useful in some
            circumstances
        fit_p0 (tuple): Initial guess vector for paraboloid fit

    Returns:
        dict: Unless otherwise noted, the entiries are 2D (y-z) fields

          - **mp_xloc** location of minimum abs(Bz), this works
            better than max of J^2 for FTEs
          - **mp_sheath_edge** location where Jy > 0.1 * Jy when
            coming in from the sheath side
          - **mp_sphere_edge** location where Jy > 0.1 * Jy when
            coming in from the sphere side
          - **mp_width** difference between m-sheath edge and
            msphere edge
          - **mp_shear** magnetic shear taken 6 grid points into
            the m-sheath / m-sphere
          - **pp_max** max pp
          - **pp_max_xloc** location of max pp
          - **epar_max** max e parallel
          - **epar_max_xloc** location of max e parallel
          - **paraboloid** numpy.recarray of paraboloid fit. The
            parameters are given in the 0th element, and
            the 1st element contains the 1-sigma values for the fit

    Raises:
        RuntimeError: if using MHD crds instead of GSE crds
    """
    if not cache_dir:
        cache_dir = pp.find_info("_viscid_dirname", "./")
    run_name = pp.find_info("run", None)
    if cache and run_name:
        t = pp.time
        mp_fname = "{0}/{1}.mpause.{2:06.0f}".format(cache_dir, run_name, t)
    else:
        mp_fname = ""

    try:
        force = cache.strip().lower() == "force"
    except AttributeError:
        force = False

    try:
        if force or not mp_fname or not os.path.isfile(mp_fname + ".xdmf"):
            raise IOError()

        mp_info = {}
        with viscid.load_file(mp_fname + ".xdmf") as dat:
            fld_names = ["mp_xloc", "mp_sheath_edge", "mp_sphere_edge",
                         "mp_width", "mp_shear", "pp_max", "pp_max_xloc",
                         "epar_max", "epar_max_xloc"]
            for fld_name in fld_names:
                mp_info[fld_name] = dat[fld_name]["x=0"]

    except (IOError, KeyError):
        mp_info = {}

        crd_system = viscid.as_crd_system(b, None)
        if crd_system != 'gse':
            raise RuntimeError("get_mp_info can't work in MHD crds, "
                               "switch to GSE please")

        if j.nr_patches == 1:
            pp_block = pp[slc]
            b_block = b[slc]
            j_block = j[slc]
            if e is None:
                e_block = np.nan * viscid.empty_like(j_block)
            else:
                e_block = e[slc]
        else:
            # interpolate an amr grid so we can proceed
            obnd = pp.get_slice_extent(slc)
            dx = np.min(pp.skeleton.L / pp.skeleton.n, axis=0)
            nx = np.ceil((obnd[1] - obnd[0]) / dx)
            vol = viscid.seed.Volume(obnd[0], obnd[1], nx, cache=True)
            pp_block = vol.wrap_field(viscid.interp_trilin(pp, vol),
                                      name="P").as_cell_centered()
            b_block = vol.wrap_field(viscid.interp_trilin(b, vol),
                                     name="B").as_cell_centered()
            j_block = vol.wrap_field(viscid.interp_trilin(j, vol),
                                     name="J").as_cell_centered()
            if e is None:
                e_block = np.nan * viscid.empty_like(j_block)
            else:
                e_block = vol.wrap_field(viscid.interp_trilin(e, vol),
                                         name="E").as_cell_centered()

        # jsq = viscid.dot(j_block, j_block)
        bsq = viscid.dot(b_block, b_block)

        # extract ndarrays and mask out bow shock / current free regions
        maskval = 1e-4
        jy_mask = j_block['y'].data < maskval
        masked_bsq = 1.0 * bsq
        masked_bsq.data = np.ma.masked_where(jy_mask, bsq)

        xcc = j_block.get_crd_cc('x')
        nx = len(xcc)

        mp_xloc = np.argmin(masked_bsq, axis=0)  # indices
        mp_xloc = mp_xloc.wrap(xcc[mp_xloc.data])  # location

        pp_max = np.max(pp_block, axis=0)
        pp_max_xloc = np.argmax(pp_block, axis=0)  # indices
        pp_max_xloc = pp_max_xloc.wrap(xcc[pp_max_xloc.data])  # location

        epar = viscid.project(e_block, b_block)
        epar_max = np.max(epar, axis=0)
        epar_max_xloc = np.argmax(epar, axis=0)  # indices
        epar_max_xloc = pp_max_xloc.wrap(xcc[epar_max_xloc.data])  # location

        _ret = find_mp_edges(j_block, 0.1, 0.1, maskval=maskval)
        sheath_edge, msphere_edge, mp_width, sheath_ind, sphere_ind = _ret

        # extract b and b**2 at sheath + 6 grid points and sphere - 6 grid pointns
        # clipping cases where things go outside the block. clipped ponints are
        # set to nan
        step = 6
        # extract b
        if b_block.layout == "flat":
            comp_axis = 0
            ic, _, iy, iz = np.ix_(*[np.arange(si) for si in b_block.shape])
            ix = np.clip(sheath_ind + step, 0, nx - 1)
            b_sheath = b_block.data[ic, ix, iy, iz]
            ix = np.clip(sheath_ind - step, 0, nx - 1)
            b_sphere = b_block.data[ic, ix, iy, iz]
        elif b_block.layout == "interlaced":
            comp_axis = 3
            _, iy, iz = np.ix_(*[np.arange(si) for si in b_block.shape[:-1]])
            ix = np.clip(sheath_ind + step, 0, nx - 1)
            b_sheath = b_block.data[ix, iy, iz]
            ix = np.clip(sheath_ind - step, 0, nx - 1)
            b_sphere = b_block.data[ix, iy, iz]
        # extract b**2
        bmag_sheath = np.sqrt(np.sum(b_sheath**2, axis=comp_axis))
        bmag_sphere = np.sqrt(np.sum(b_sphere**2, axis=comp_axis))
        costheta = (np.sum(b_sheath * b_sphere, axis=comp_axis) /
                    (bmag_sphere * bmag_sheath))
        costheta = np.where((sheath_ind + step < nx) & (sphere_ind - step >= 0),
                            costheta, np.nan)
        mp_shear = mp_width.wrap((180.0 / np.pi) * np.arccos(costheta))

        # don't bother with pretty name since it's not written to file
        # plane_crds = b_block.crds.slice_keep('x=0', cc=True)
        # fld_kwargs = dict(center="Cell", time=b.time)
        mp_width.name = "mp_width"
        mp_xloc.name = "mp_xloc"
        sheath_edge.name = "mp_sheath_edge"
        msphere_edge.name = "mp_sphere_edge"
        mp_shear.name = "mp_shear"
        pp_max.name = "pp_max"
        pp_max_xloc.name = "pp_max_xloc"
        epar_max.name = "epar_max"
        epar_max_xloc.name = "epar_max_xloc"

        mp_info = {}
        mp_info["mp_width"] = mp_width
        mp_info["mp_xloc"] = mp_xloc
        mp_info["mp_sheath_edge"] = sheath_edge
        mp_info["mp_sphere_edge"] = msphere_edge
        mp_info["mp_shear"] = mp_shear
        mp_info["pp_max"] = pp_max
        mp_info["pp_max_xloc"] = pp_max_xloc
        mp_info["epar_max"] = epar_max
        mp_info["epar_max_xloc"] = epar_max_xloc

        # cache new fields to disk
        if mp_fname:
            viscid.save_fields(mp_fname + ".h5", list(mp_info.values()))

    try:
        _paraboloid_params = fit_paraboloid(mp_info[fit], p0=fit_p0)
        mp_info["paraboloid"] = _paraboloid_params
    except ImportError as _exception:
        try:
            msg = _exception.message
        except AttributeError:
            msg = _exception.msg
        mp_info["paraboloid"] = viscid.DeferredImportError(msg)

    mp_info["mp_width"].pretty_name = "Magnetopause Width"
    mp_info["mp_xloc"].pretty_name = "Magnetopause $X_{gse}$ Location"
    mp_info["mp_sheath_edge"].pretty_name = "Magnetosheath Edge"
    mp_info["mp_sphere_edge"].pretty_name = "Magnetosphere Edge"
    mp_info["mp_shear"].pretty_name = "Magnetic Shear"
    mp_info["pp_max"].pretty_name = "Max Pressure"
    mp_info["pp_max_xloc"].pretty_name = "Max Pressure Location"
    mp_info["epar_max"].pretty_name = "Max E Parallel"
    mp_info["epar_max_xloc"].pretty_name = "Max E Parallel Location"

    return mp_info
def main():
    mhd_type = "C3"
    make_plots = 1

    mhd_type = mhd_type.upper()
    if mhd_type.startswith("C"):
        if mhd_type in ("C", ):
            f = viscid.load_file("$WORK/tmedium/*.3d.[-1].xdmf")
        elif mhd_type in ("C2", "C3"):
            f = viscid.load_file("$WORK/tmedium2/*.3d.[-1].xdmf")
        else:
            raise ValueError()
        catol = 1e-8
        rtol = 2e-6
    elif mhd_type in ("F", "FORTRAN"):
        f = viscid.load_file("$WORK/tmedium3/*.3df.[-1]")
        catol = 1e-8
        rtol = 7e-2
    else:
        raise ValueError()

    b = f['b_cc']
    b1 = f['b_fc']
    e_cc = f['e_cc']
    e_ec = f['e_ec']
    # divb =  f['divB']

    # viscid.interact()

    if True:
        bD = viscid.empty_like(b)
        bD.data = np.array(b.data)

        b1D = viscid.empty_like(b1)
        b1D.data = np.array(b1.data)

        mask5 = viscid.make_spherical_mask(bD, rmax=3.5)
        mask1_5 = viscid.make_spherical_mask(bD, rmax=1.5)
        viscid.fill_dipole(bD, mask=mask5)
        viscid.set_in_region(bD, bD, 0.0, 0.0, mask=mask1_5, out=bD)

        # compare_vectors(_b, bD, make_plots=True)
        mask5 = viscid.make_spherical_mask(b1D, rmax=3.5)
        mask1_5 = viscid.make_spherical_mask(b1D, rmax=1.5)
        viscid.fill_dipole(b1D, mask=mask5)
        viscid.set_in_region(b1D, b1D, 0.0, 0.0, mask=mask1_5, out=b1D)

        compare_vectors(bD["x=1:-1, y=1:-1, z=1:-1"],
                        b1D.as_cell_centered(),
                        make_plots=True)

        # plt.clf()
        # dkwargs = dict(symmetric=True, earth=True, clim=(-1e2, 1e2))
        # ax1 = plt.subplot(311)
        # vlt.plot(viscid.div(b1)['y=0j'], **dkwargs)
        # plt.subplot(312, sharex=ax1, sharey=ax1)
        # vlt.plot(viscid.div(b)['y=0j'], **dkwargs)
        # plt.subplot(313, sharex=ax1, sharey=ax1)
        # vlt.plot(viscid.div(b1D)['y=0j'], **dkwargs)
        # vlt.show()

        bD = b1D = mask5 = mask1_5 = None

    # straight up interpolate b1 to cc crds and compare with b
    if True:
        b1_cc = viscid.interp_trilin(b1, b).as_flat()

        viscid.set_in_region(b,
                             b,
                             alpha=0.0,
                             beta=0.0,
                             out=b,
                             mask=viscid.make_spherical_mask(b, rmax=5.0))
        viscid.set_in_region(b1_cc,
                             b1_cc,
                             alpha=0.0,
                             beta=0.0,
                             out=b1_cc,
                             mask=viscid.make_spherical_mask(b1_cc, rmax=5.0))

        compare_vectors(b, b1_cc, make_plots=True)

    # make div?
    if True:
        # make seeds for 1.5x supersampling b1
        n = 128
        seeds = viscid.Volume((5.1, -0.02, -5.0), (12.0, 0.02, 5.0), (n, 3, n))
        # do interpolation onto new seeds
        b2 = viscid.interp_trilin(b1, seeds)

        div_b = viscid.div(b)
        div_b1 = viscid.div(b1)
        div_b2 = viscid.div(b2)

        viscid.set_in_region(div_b,
                             div_b,
                             alpha=0.0,
                             beta=0.0,
                             out=div_b,
                             mask=viscid.make_spherical_mask(div_b, rmax=5.0))
        viscid.set_in_region(div_b1,
                             div_b1,
                             alpha=0.0,
                             beta=0.0,
                             out=div_b1,
                             mask=viscid.make_spherical_mask(div_b1, rmax=5.0))
        viscid.set_in_region(div_b2,
                             div_b2,
                             alpha=0.0,
                             beta=0.0,
                             out=div_b2,
                             mask=viscid.make_spherical_mask(div_b2, rmax=5.0))
        viscid.set_in_region(divb,
                             divb,
                             alpha=0.0,
                             beta=0.0,
                             out=divb,
                             mask=viscid.make_spherical_mask(divb, rmax=5.0))

        plt.clf()
        ax1 = vlt.subplot(311)
        vlt.plot(div_b['y=0j'], symmetric=True, earth=True)
        vlt.subplot(312, sharex=ax1, sharey=ax1)
        # vlt.plot(div_b1['y=0j'], symmetric=True, earth=True)
        vlt.plot(div_b2['y=0j'], symmetric=True, earth=True)
        vlt.subplot(313, sharex=ax1, sharey=ax1)
        vlt.plot(divb['y=0j'], symmetric=True, earth=True)

        vlt.show()

    return 0
Exemple #6
0
def get_mp_info(pp,
                b,
                j,
                e,
                cache=True,
                cache_dir=None,
                slc="x=5.5f:11.0f, y=-4.0f:4.0f, z=-3.6f:3.6f",
                fit="mp_xloc",
                fit_p0=(9.0, 0.0, 0.0, 1.0, -1.0, -1.0)):
    """Get info about m-pause as flattened fields

    Notes:
        The first thing this function does is mask locations where
        the GSE-y current density < 1e-4. This masks out the bow
        shock and current free regions. This works for southward IMF,
        but it is not very general.

    Parameters:
        pp (ScalarcField): pressure
        b (VectorField): magnetic field
        j (VectorField): current density
        e (VectorField, None): electric field (same centering as b). If
            None, then the info that requires E will be filled with NaN
        cache (bool, str): Save to and load from cache, if "force",
            then don't load from cache if it exists, but do save a
            cache at the end
        cache_dir (str): Directory for cache, if None, same directory
            as that file to which the grid belongs
        slc (str): slice that gives a box that contains the m-pause
        fit (str): to which resulting field should the paraboloid be fit,
            defaults to mp_xloc, but pp_max_xloc might be useful in some
            circumstances
        fit_p0 (tuple): Initial guess vector for paraboloid fit

    Returns:
        dict: Unless otherwise noted, the entiries are 2D (y-z) fields

          - **mp_xloc** location of minimum abs(Bz), this works
            better than max of J^2 for FTEs
          - **mp_sheath_edge** location where Jy > 0.1 * Jy when
            coming in from the sheath side
          - **mp_sphere_edge** location where Jy > 0.1 * Jy when
            coming in from the sphere side
          - **mp_width** difference between m-sheath edge and
            msphere edge
          - **mp_shear** magnetic shear taken 6 grid points into
            the m-sheath / m-sphere
          - **pp_max** max pp
          - **pp_max_xloc** location of max pp
          - **epar_max** max e parallel
          - **epar_max_xloc** location of max e parallel
          - **paraboloid** numpy.recarray of paraboloid fit. The
            parameters are given in the 0th element, and
            the 1st element contains the 1-sigma values for the fit

    Raises:
        RuntimeError: if using MHD crds instead of GSE crds
    """
    if not cache_dir:
        cache_dir = pp.find_info("_viscid_dirname", "./")
    run_name = pp.find_info("run", None)
    if cache and run_name:
        t = pp.time
        mp_fname = "{0}/{1}.mpause.{2:06.0f}".format(cache_dir, run_name, t)
    else:
        mp_fname = ""

    try:
        force = cache.strip().lower() == "force"
    except AttributeError:
        force = False

    try:
        if force or not mp_fname or not os.path.isfile(mp_fname + ".xdmf"):
            raise IOError()

        mp_info = {}
        with viscid.load_file(mp_fname + ".xdmf") as dat:
            fld_names = [
                "mp_xloc", "mp_sheath_edge", "mp_sphere_edge", "mp_width",
                "mp_shear", "pp_max", "pp_max_xloc", "epar_max",
                "epar_max_xloc"
            ]
            for fld_name in fld_names:
                mp_info[fld_name] = dat[fld_name]["x=0"]

    except (IOError, KeyError):
        mp_info = {}

        crd_system = viscid.as_crd_system(b, None)
        if crd_system != 'gse':
            raise RuntimeError("get_mp_info can't work in MHD crds, "
                               "switch to GSE please")

        if j.nr_patches == 1:
            pp_block = pp[slc]
            b_block = b[slc]
            j_block = j[slc]
            if e is None:
                e_block = np.nan * viscid.empty_like(j_block)
            else:
                e_block = e[slc]
        else:
            # interpolate an amr grid so we can proceed
            obnd = pp.get_slice_extent(slc)
            dx = np.min(pp.skeleton.L / pp.skeleton.n, axis=0)
            nx = np.ceil((obnd[1] - obnd[0]) / dx)
            vol = viscid.seed.Volume(obnd[0], obnd[1], nx, cache=True)
            pp_block = vol.wrap_field(viscid.interp_trilin(pp, vol),
                                      name="P").as_cell_centered()
            b_block = vol.wrap_field(viscid.interp_trilin(b, vol),
                                     name="B").as_cell_centered()
            j_block = vol.wrap_field(viscid.interp_trilin(j, vol),
                                     name="J").as_cell_centered()
            if e is None:
                e_block = np.nan * viscid.empty_like(j_block)
            else:
                e_block = vol.wrap_field(viscid.interp_trilin(e, vol),
                                         name="E").as_cell_centered()

        # jsq = viscid.dot(j_block, j_block)
        bsq = viscid.dot(b_block, b_block)

        # extract ndarrays and mask out bow shock / current free regions
        maskval = 1e-4
        jy_mask = j_block['y'].data < maskval
        masked_bsq = 1.0 * bsq
        masked_bsq.data = np.ma.masked_where(jy_mask, bsq)

        xcc = j_block.get_crd_cc('x')
        nx = len(xcc)

        mp_xloc = np.argmin(masked_bsq, axis=0)  # indices
        mp_xloc = mp_xloc.wrap(xcc[mp_xloc.data])  # location

        pp_max = np.max(pp_block, axis=0)
        pp_max_xloc = np.argmax(pp_block, axis=0)  # indices
        pp_max_xloc = pp_max_xloc.wrap(xcc[pp_max_xloc.data])  # location

        epar = viscid.project(e_block, b_block)
        epar_max = np.max(epar, axis=0)
        epar_max_xloc = np.argmax(epar, axis=0)  # indices
        epar_max_xloc = pp_max_xloc.wrap(xcc[epar_max_xloc.data])  # location

        _ret = find_mp_edges(j_block, 0.1, 0.1, maskval=maskval)
        sheath_edge, msphere_edge, mp_width, sheath_ind, sphere_ind = _ret

        # extract b and b**2 at sheath + 6 grid points and sphere - 6 grid pointns
        # clipping cases where things go outside the block. clipped ponints are
        # set to nan
        step = 6
        # extract b
        if b_block.layout == "flat":
            comp_axis = 0
            ic, _, iy, iz = np.ix_(*[np.arange(si) for si in b_block.shape])
            ix = np.clip(sheath_ind + step, 0, nx - 1)
            b_sheath = b_block.data[ic, ix, iy, iz]
            ix = np.clip(sheath_ind - step, 0, nx - 1)
            b_sphere = b_block.data[ic, ix, iy, iz]
        elif b_block.layout == "interlaced":
            comp_axis = 3
            _, iy, iz = np.ix_(*[np.arange(si) for si in b_block.shape[:-1]])
            ix = np.clip(sheath_ind + step, 0, nx - 1)
            b_sheath = b_block.data[ix, iy, iz]
            ix = np.clip(sheath_ind - step, 0, nx - 1)
            b_sphere = b_block.data[ix, iy, iz]
        # extract b**2
        bmag_sheath = np.sqrt(np.sum(b_sheath**2, axis=comp_axis))
        bmag_sphere = np.sqrt(np.sum(b_sphere**2, axis=comp_axis))
        costheta = (np.sum(b_sheath * b_sphere, axis=comp_axis) /
                    (bmag_sphere * bmag_sheath))
        costheta = np.where(
            (sheath_ind + step < nx) & (sphere_ind - step >= 0), costheta,
            np.nan)
        mp_shear = mp_width.wrap((180.0 / np.pi) * np.arccos(costheta))

        # don't bother with pretty name since it's not written to file
        # plane_crds = b_block.crds.slice_keep('x=0', cc=True)
        # fld_kwargs = dict(center="Cell", time=b.time)
        mp_width.name = "mp_width"
        mp_xloc.name = "mp_xloc"
        sheath_edge.name = "mp_sheath_edge"
        msphere_edge.name = "mp_sphere_edge"
        mp_shear.name = "mp_shear"
        pp_max.name = "pp_max"
        pp_max_xloc.name = "pp_max_xloc"
        epar_max.name = "epar_max"
        epar_max_xloc.name = "epar_max_xloc"

        mp_info = {}
        mp_info["mp_width"] = mp_width
        mp_info["mp_xloc"] = mp_xloc
        mp_info["mp_sheath_edge"] = sheath_edge
        mp_info["mp_sphere_edge"] = msphere_edge
        mp_info["mp_shear"] = mp_shear
        mp_info["pp_max"] = pp_max
        mp_info["pp_max_xloc"] = pp_max_xloc
        mp_info["epar_max"] = epar_max
        mp_info["epar_max_xloc"] = epar_max_xloc

        # cache new fields to disk
        if mp_fname:
            viscid.save_fields(mp_fname + ".h5", mp_info.values())

    try:
        _paraboloid_params = fit_paraboloid(mp_info[fit], p0=fit_p0)
        mp_info["paraboloid"] = _paraboloid_params
    except ImportError as _exception:
        try:
            msg = _exception.message
        except AttributeError:
            msg = _exception.msg
        mp_info["paraboloid"] = viscid.DeferredImportError(msg)

    mp_info["mp_width"].pretty_name = "Magnetopause Width"
    mp_info["mp_xloc"].pretty_name = "Magnetopause $X_{gse}$ Location"
    mp_info["mp_sheath_edge"].pretty_name = "Magnetosheath Edge"
    mp_info["mp_sphere_edge"].pretty_name = "Magnetosphere Edge"
    mp_info["mp_shear"].pretty_name = "Magnetic Shear"
    mp_info["pp_max"].pretty_name = "Max Pressure"
    mp_info["pp_max_xloc"].pretty_name = "Max Pressure Location"
    mp_info["epar_max"].pretty_name = "Max E Parallel"
    mp_info["epar_max_xloc"].pretty_name = "Max E Parallel Location"

    return mp_info