Example #1
0
def _fld_xform_common(fld,
                      base,
                      target,
                      unit,
                      crd_xform,
                      dat_xform,
                      raw=False):
    dcrd, _ = _get_axinds(fld, base)

    unit_xform = _make_transform_unit_func(fld.crds.get_unit(base), unit)
    if not unit:
        unit = fld.crds.get_unit(base)

    xforms = (unit_xform, crd_xform, dat_xform)
    if base == target and all(f is arr_noop for f in xforms):
        return fld
    else:
        clist = fld.get_clist()
        clist[dcrd][0] = target
        if fld.crds.is_uniform() and not raw:
            clist[dcrd][1][:2] = crd_xform(unit_xform(clist[dcrd][1][:2]))
        else:
            clist[dcrd][1] = crd_xform(unit_xform(clist[dcrd][1]))

        units = list(fld.crds.units)
        units[dcrd] = unit
        crds = wrap_crds(fld.crds.crdtype,
                         clist,
                         dtype=fld.crds.dtype,
                         units=units)
        ctx = dict(crds=crds)
        return fld.wrap(dat_xform(fld.data), context=ctx)
Example #2
0
    def _parse(self):
        g = self._make_grid(self)

        with open(self.fname, 'r') as fin:
            ndim = int(fin.readline().strip().split()[1])
            nfields = int(fin.readline().strip().split()[1])

            clist = []

            for _ in range(ndim):
                ax_name, ax_dtype = fin.readline().strip().split()
                crd_dat = np.fromstring(fin.readline().strip(), sep=' ',
                                        dtype=ax_dtype)
                clist.append([ax_name, crd_dat])

            crds = coordinate.wrap_crds("nonuniform_cartesian", clist)
            g.set_crds(crds)

            for _ in range(nfields):
                fld_name, fld_dtype = fin.readline().strip().split()
                fld_dat = np.fromstring(fin.readline().strip(), sep=' ',
                                        dtype=fld_dtype)
                fld = self._make_field(g, "Scalar", fld_name, crds,
                                       fld_dat)
                g.add_field(fld)

        self.add(g)
        self.activate(0)
Example #3
0
def get_trilinear_field():
    xl, xh, nx = -1.0, 1.0, 41
    yl, yh, ny = -1.5, 1.5, 41
    zl, zh, nz = -2.0, 2.0, 41
    x = np.linspace(xl, xh, nx)
    y = np.linspace(yl, yh, ny)
    z = np.linspace(zl, zh, nz)
    crds = coordinate.wrap_crds("nonuniform_cartesian",
                                [('x', x), ('y', y), ('z', z)])
    b = field.empty(crds, name="f", nr_comps=3, center="Cell",
                    layout="interlaced")
    X, Y, Z = b.get_crds(shaped=True)

    x01, y01, z01 = 0.5, 0.5, 0.5
    x02, y02, z02 = 0.5, 0.5, 0.5
    x03, y03, z03 = 0.5, 0.5, 0.5

    b['x'][:] = 0.0 + 1.0 * (X - x01) + 1.0 * (Y - y01) + 1.0 * (Z - z01) + \
                1.0 * (X - x01) * (Y - y01) + 1.0 * (Y - y01) * (Z - z01) + \
                1.0 * (X - x01) * (Y - y01) * (Z - z01)
    b['y'][:] = 0.0 + 1.0 * (X - x02) - 1.0 * (Y - y02) + 1.0 * (Z - z02) + \
                1.0 * (X - x02) * (Y - y02) + 1.0 * (Y - y02) * (Z - z02) - \
                1.0 * (X - x02) * (Y - y02) * (Z - z02)
    b['z'][:] = 0.0 + 1.0 * (X - x03) + 1.0 * (Y - y03) - 1.0 * (Z - z03) + \
                1.0 * (X - x03) * (Y - y03) + 1.0 * (Y - y03) * (Z - z03) + \
                1.0 * (X - x03) * (Y - y03) * (Z - z03)
    return b
Example #4
0
    def read_crds(cls, fname, dims=None):
        # dims are xyz order unlike all other interfaces
        if dims is None:
            dims = cls.parse_header(fname)['dims']
        dat = np.loadtxt(fname, usecols=list(range(len(dims), 2 * len(dims))),
                         unpack=True, ndmin=2)

        dxmin = np.inf
        cclist = []
        nclist = []

        for i, dim, axis in zip(count(), dims, "xyz"):
            stop = int(np.prod(dims[:i + 1]))
            step = int(np.prod(dims[:i]))
            cc = dat[i][:stop:step]
            dxmin = np.min([dxmin, np.min(cc[1:] - cc[:-1])])
            assert len(cc) == dim
            cclist.append((axis, cc))

        for axis, cc in cclist:
            if len(cc) > 1:
                hd = 0.5 * (cc[1:] - cc[:-1])
                nc = np.hstack([cc[0] - hd[0],
                                cc[:-1] + hd,
                                cc[-1] + hd[-1]])
            else:
                hd = 0.5 * dxmin
                nc = np.array([cc[0] - hd, cc[0] + hd])
            nclist.append((axis, nc))

        return coordinate.wrap_crds("nonuniform_cartesian", nclist)
Example #5
0
 def _make_crds(self, filename):
     fw = AthenaBinFileWrapper(filename,
                               keep_crd_clist=True,
                               float_type_name=self.float_type_name,
                               var_type=self.var_type)
     with fw as f:
         crd_clist = f.crd_clist
         new_clist = []
         dxmin = np.inf
         for c in crd_clist:
             if len(c[1]) > 1:
                 dxmin = np.min([dxmin, np.min(c[1][1:] - c[1][:-1])])
         for i, cli in enumerate(crd_clist):
             cc = cli[1]
             try:
                 hd = 0.5 * (cc[1:] - cc[:-1])
                 nc = np.hstack(
                     [cc[0] - hd[0], cc[:-1] + hd, cc[-1] + hd[-1]])
             except IndexError:
                 dxminh = 0.5 * dxmin
                 nc = np.array([cc[0] - dxminh, cc[0] + dxminh])
             new_clist.append([crd_clist[i][0], nc])
         crds = coordinate.wrap_crds("nonuniform_cartesian",
                                     new_clist[::-1])
     return crds
Example #6
0
    def _parse(self):
        # get field names from header
        with open(self.fname, 'r') as f:
            line = f.readline()
            line = f.readline().lstrip("#").strip()
            fld_names = re.split(r"\[[0-9]+\]=", line)[1:]
            fld_names = [fn.strip() for fn in fld_names]

        # crds here are really times
        dat = np.loadtxt(self.fname, unpack=True)
        t = dat[0]
        crds = coordinate.wrap_crds("nonuniform_cartesian", [('t', t)])

        g = self._make_grid(self, name="AthenaHstGrid")
        g.set_crds(crds)
        g.time = 0
        for i in range(1, len(fld_names)):
            fld = self._make_field(g,
                                   "Scalar",
                                   fld_names[i],
                                   crds,
                                   dat[i],
                                   center="Node")
            g.add_field(fld)
        self.add(g)
        self.activate(0)
Example #7
0
def make_dipole(m=None, twod=False):
    dtype = 'float64'
    n = 256
    x = np.array(np.linspace(-5, 5, n), dtype=dtype)
    y = np.array(np.linspace(-5, 5, n), dtype=dtype)
    z = np.array(np.linspace(-5, 5, n), dtype=dtype)
    if twod:
        y = np.array(np.linspace(-0.1, 0.1, 2), dtype=dtype)
    crds = coordinate.wrap_crds("nonuniform_cartesian", (('z', z), ('y', y), ('x', x)))

    one = np.array([1.0], dtype=dtype)  # pylint: disable=W0612
    three = np.array([3.0], dtype=dtype)  # pylint: disable=W0612
    if not m:
        m = [0.0, 0.0, -1.0]
    m = np.array(m, dtype=dtype)
    mx, my, mz = m  # pylint: disable=W0612

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

    rsq = ne.evaluate("Xcc**2 + Ycc**2 + Zcc**2")  # pylint: disable=W0612
    mdotr = ne.evaluate("mx * Xcc + my * Ycc + mz * Zcc")  # pylint: disable=W0612
    Bx = ne.evaluate("((three * Xcc * mdotr / rsq) - mx) / rsq**1.5")
    By = ne.evaluate("((three * Ycc * mdotr / rsq) - my) / rsq**1.5")
    Bz = ne.evaluate("((three * Zcc * mdotr / rsq) - mz) / rsq**1.5")

    fld = field.VectorField("B_cc", crds, [Bx, By, Bz],
                            center="Cell", forget_source=True,
                            _force_layout=field.LAYOUT_INTERLACED,
                           )
    # fld_rsq = field.ScalarField("r", crds, hmm,
    #                             center="Cell", forget_source=True)
    return fld  # , fld_rsq
Example #8
0
    def read_crds(cls, fname, dims=None):
        # dims are xyz order unlike all other interfaces
        if dims is None:
            dims = cls.parse_header(fname)['dims']
        dat = np.loadtxt(fname,
                         usecols=list(range(len(dims), 2 * len(dims))),
                         unpack=True,
                         ndmin=2)

        dxmin = np.inf
        cclist = []
        nclist = []

        for i, dim, axis in zip(count(), dims, "xyz"):
            stop = int(np.prod(dims[:i + 1]))
            step = int(np.prod(dims[:i]))
            cc = dat[i][:stop:step]
            dxmin = np.min([dxmin, np.min(cc[1:] - cc[:-1])])
            assert len(cc) == dim
            cclist.append((axis, cc))

        for axis, cc in cclist:
            if len(cc) > 1:
                hd = 0.5 * (cc[1:] - cc[:-1])
                nc = np.hstack([cc[0] - hd[0], cc[:-1] + hd, cc[-1] + hd[-1]])
            else:
                hd = 0.5 * dxmin
                nc = np.array([cc[0] - hd, cc[0] + hd])
            nclist.append((axis, nc))

        return coordinate.wrap_crds("nonuniform_cartesian", nclist)
Example #9
0
    def make_crds(self):
        if self.get_info('fieldtype') == 'iof':
            # 181, 61
            nphi, ntheta = self._shape_discovery_hack(self._collection[0])
            crdlst = [['phi', [0.0, 360.0, nphi]],
                      ['theta', [0.0, 180.0, ntheta]]]
            return wrap_crds("uniform_spherical", crdlst, units='deg')

        else:
            return self.read_grid2()
Example #10
0
    def make_crds(self):
        if self.get_info('fieldtype') == 'iof':
            # 181, 61
            nlon, nlat = self._shape_discovery_hack(self._collection[0])
            crdlst = [['lon', [0.0, 360.0, nlon]],
                      ['lat', [0.0, 180.0, nlat]]]
            return wrap_crds("uniform_spherical", crdlst)

        else:
            return self.read_grid2()
Example #11
0
    def read_grid2(self):
        # TODO: iof files can be hacked in here
        grid2_basename = "{0}.grid2".format(self.find_info('run'))
        self.grid2 = find_file_uptree(self.dirname, grid2_basename)
        if self.grid2 is None:
            self.grid2 = find_file_uptree(".", grid2_basename)
        if self.grid2 is None:
            raise IOError("Could not find a grid2 file for "
                          "{0}".format(self.fname))

        # load the cell centered grid
        with open(self.grid2, 'r') as fin:
            nx = int(next(fin).split()[0])
            gx = list(islice(fin, 0, nx, 1))
            gx = np.array(gx, dtype='f4')

            ny = int(next(fin).split()[0])
            gy = list(islice(fin, 0, ny, 1))
            gy = np.array(gy, dtype='f4')

            nz = int(next(fin).split()[0])
            gz = list(islice(fin, 0, nz, 1))
            gz = np.array(gz, dtype='f4')

        xnc = np.empty(len(gx) + 1, dtype=gx.dtype)
        ync = np.empty(len(gy) + 1, dtype=gy.dtype)
        znc = np.empty(len(gz) + 1, dtype=gz.dtype)

        for cc, nc in [(gx, xnc), (gy, ync), (gz, znc)]:
            hd = 0.5 * (cc[1:] - cc[:-1])
            nc[:] = np.hstack([cc[0] - hd[0], cc[:-1] + hd, cc[-1] + hd[-1]])

        # for 2d files
        crdlst = []
        for dim, nc, cc in zip("xyz", [xnc, ync, znc], [gx, gy, gz]):
            fieldtype = self.get_info('fieldtype')
            if fieldtype.startswith('p'):
                self.set_info('plane', fieldtype[1])
                if fieldtype[1] == dim:
                    planeloc = float(fieldtype.split('_')[1])
                    planeloc /= 10  # value is in tenths of Re
                    # FIXME: it is not good to depend on an attribute of
                    # GGCMGrid like this... it could lead to unexpected
                    # behavior if the user starts playing with the value
                    # of an instance, but I'm not sure in practice how or why
                    # since reading the grid should happen fairly early in
                    # the construction process
                    if GGCMGrid.mhd_to_gse_on_read and dim in 'xy':
                        planeloc *= -1
                    self.set_info('planeloc', planeloc)
                    ccind = np.argmin(np.abs(cc - planeloc))
                    nc = nc[ccind:ccind + 2]
            crdlst.append([dim, nc])

        return wrap_crds("nonuniform_cartesian", crdlst, units='Re')
Example #12
0
    def make_crds(self, fname):
        with h5py.File(fname, 'r') as f:
            clist = []

            # FIXME: xyz
            crds = "xyz"
            nr_crds = len(f['StructGridField'].shape) - 1
            for i in range(nr_crds):
                try:
                    clist.append((crds[i], self._get_single_crd(f, i, nr_crds)))
                except IndexError:
                    pass

            if f['StructGrid'].attrs['vsKind'].decode() in ['uniform']:
                # FIXME: this goes xyz -> zyx
                crds = wrap_crds("uniform_cartesian", clist)
            else:
                crds = wrap_crds("nonuniform_cartesian", clist)

            return crds
Example #13
0
    def make_crds(self, fname):
        with h5py.File(fname, 'r') as f:
            clist = []

            # FIXME: xyz
            crds = "xyz"
            nr_crds = len(f['StructGridField'].shape) - 1
            for i in range(nr_crds):
                try:
                    clist.append((crds[i], self._get_single_crd(f, i, nr_crds)))
                except IndexError:
                    pass

            if f['StructGrid'].attrs['vsKind'].decode() in ['uniform']:
                # FIXME: this goes xyz -> zyx
                crds = wrap_crds("uniform_cartesian", clist)
            else:
                crds = wrap_crds("nonuniform_cartesian", clist)

            return crds
Example #14
0
    def _parse(self):
        g = self._make_grid(self)

        arr = np.loadtxt(self.fname)
        crds = coordinate.wrap_crds("nonuniform_cartesian", [['x', arr[:, 0]]])
        g.set_crds(crds)

        if len(arr.shape) > 1:
            for i in range(1, arr.shape[1]):
                fld = self._make_field(g, "Scalar", 'c' + str(i), crds,
                                       arr[:, i])
                g.add_field(fld)

        self.add(g)
        self.activate(0)
Example #15
0
    def _parse(self):
        g = self._make_grid(self, **self._grid_opts)

        with np.load(self.fname) as f:
            fld_names = list(f.keys())

            crd_names = []
            # try to get crds names from an array of strings called _KEY_CRDS
            # else, assume it's x, y, z and see if that works
            try:
                clist = [(ax, f[ax]) for ax in f[self._KEY_CRDS]]
                crd_names = f[self._KEY_CRDS]
                fld_names.remove(self._KEY_CRDS)
            except KeyError:
                for axisname in "xyz":
                    if axisname in f:
                        crd_names.append(axisname)
            clist = [(cn, NPZDataWrapper(self.fname, cn)) for cn in crd_names]
            crds = coordinate.wrap_crds("nonuniform_cartesian", clist)
            g.set_crds(crds)
            for c in clist:
                # we should be sure by now that the keys exist
                fld_names.remove(c[0])

            # try to get field names from arrays of nc, cc, ec, fc
            # fields
            for fld_center, names_key in self._KEY_FLDS.items():
                try:
                    names = f[names_key]
                    fld_names.remove(names_key)
                except KeyError:
                    names = []

                for name in names:
                    fld = self._wrap_lazy_field(g, self.fname, name, crds,
                                                fld_center)
                    g.add_field(fld)
                    fld_names.remove(name)

            # load any remaining fields as though they were node centered
            for name in fld_names:
                fld = self._wrap_lazy_field(g, self.fname, name, crds, "Node")
                g.add_field(fld)

        self.add(g)
        self.activate(0)
Example #16
0
    def _parse(self):
        g = self._make_grid(self, **self._grid_opts)

        with np.load(self.fname) as f:
            fld_names = f.keys()

            crd_names = []
            # try to get crds names from an array of strings called _KEY_CRDS
            # else, assume it's x, y, z and see if that works
            try:
                clist = [(ax, f[ax]) for ax in f[self._KEY_CRDS]]
                crd_names = f[self._KEY_CRDS]
                fld_names.remove(self._KEY_CRDS)
            except KeyError:
                for axisname in "xyz":
                    if axisname in f:
                        crd_names.append(axisname)
            clist = [(cn, NPZDataWrapper(self.fname, cn)) for cn in crd_names]
            crds = coordinate.wrap_crds("nonuniform_cartesian", clist)
            g.set_crds(crds)
            for c in clist:
                # we should be sure by now that the keys exist
                fld_names.remove(c[0])

            # try to get field names from arrays of nc, cc, ec, fc
            # fields
            for fld_center, names_key in self._KEY_FLDS.items():
                try:
                    names = f[names_key]
                    fld_names.remove(names_key)
                except KeyError:
                    names = []

                for name in names:
                    fld = self._wrap_lazy_field(g, self.fname, name, crds,
                                                fld_center)
                    g.add_field(fld)
                    fld_names.remove(name)

            # load any remaining fields as though they were node centered
            for name in fld_names:
                fld = self._wrap_lazy_field(g, self.fname, name, crds, "Node")
                g.add_field(fld)

        self.add(g)
        self.activate(0)
Example #17
0
    def _parse(self):
        # get field names from header
        with open(self.fname, 'r') as f:
            line = f.readline()
            line = f.readline().lstrip("#").strip()
            fld_names = re.split(r"\[[0-9]+\]=", line)[1:]
            fld_names = [fn.strip() for fn in fld_names]

        # crds here are really times
        dat = np.loadtxt(self.fname, unpack=True)
        t = dat[0]
        crds = coordinate.wrap_crds("nonuniform_cartesian", [('t', t)])

        g = self._make_grid(self, name="AthenaHstGrid")
        g.set_crds(crds)
        g.time = 0
        for i in range(1, len(fld_names)):
            fld = self._make_field(g, "Scalar", fld_names[i], crds, dat[i],
                                   center="Node")
            g.add_field(fld)
        self.add(g)
        self.activate(0)
Example #18
0
def _fld_xform_common(fld, base, target, unit, crd_xform, dat_xform, raw=False):
    dcrd, _ = _get_axinds(fld, base)

    unit_xform = _make_transform_unit_func(fld.crds.get_unit(base), unit)
    if not unit:
        unit = fld.crds.get_unit(base)

    xforms = (unit_xform, crd_xform, dat_xform)
    if base == target and all(f is arr_noop for f in xforms):
        return fld
    else:
        clist = fld.get_clist()
        clist[dcrd][0] = target
        if fld.crds.is_uniform() and not raw:
            clist[dcrd][1][:2] = crd_xform(unit_xform(clist[dcrd][1][:2]))
        else:
            clist[dcrd][1] = crd_xform(unit_xform(clist[dcrd][1]))

        units = list(fld.crds.units)
        units[dcrd] = unit
        crds = wrap_crds(fld.crds.crdtype, clist, dtype=fld.crds.dtype, units=units)
        ctx = dict(crds=crds)
        return fld.wrap(dat_xform(fld.data), context=ctx)
Example #19
0
 def _make_crds(self, filename):
     fw = AthenaBinFileWrapper(filename, keep_crd_clist=True,
                               float_type_name=self.float_type_name,
                               var_type=self.var_type)
     with fw as f:
         crd_clist = f.crd_clist
         new_clist = []
         dxmin = np.inf
         for c in crd_clist:
             if len(c[1]) > 1:
                 dxmin = np.min([dxmin, np.min(c[1][1:] - c[1][:-1])])
         for i, cli in enumerate(crd_clist):
             cc = cli[1]
             try:
                 hd = 0.5 * (cc[1:] - cc[:-1])
                 nc = np.hstack([cc[0] - hd[0],
                                 cc[:-1] + hd,
                                 cc[-1] + hd[-1]])
             except IndexError:
                 dxminh = 0.5 * dxmin
                 nc = np.array([cc[0] - dxminh, cc[0] + dxminh])
             new_clist.append([crd_clist[i][0], nc])
         crds = coordinate.wrap_crds("nonuniform_cartesian", new_clist[::-1])
     return crds
Example #20
0
    def _parse_geometry(self, geo, topoattrs):
        """ geo is the element tree item, returns Coordinate object and
            xml attributes """
        geoattrs = self._fill_attrs(geo)
        # crds = None
        crdlist = None
        crdtype = None
        crdkwargs = {}

        topotype = topoattrs["TopologyType"]

        # parse geometry into crds
        geotype = geoattrs["GeometryType"]
        if geotype.upper() == "XYZ":
            data, attrs = self._parse_dataitem(geo.find("./DataItem"),
                                               keep_flat=True)
            # x = data[0::3]
            # y = data[1::3]
            # z = data[2::3]
            # crdlist = (('z', z), ('y', y), ('x', x))
            # quietly do nothing... we don't support unstructured grids
            # or 3d spherical yet, and 2d spherical can be figured out
            # if we assume the grid spans the whole sphere
            crdlist = None

        elif geotype.upper() == "XY":
            data, attrs = self._parse_dataitem(geo.find("./DataItem"),
                                               keep_flat=True)
            # x = data[0::2]
            # y = data[1::2]
            # z = np.zeros(len(x))
            # crdlist = (('z', z), ('y', y), ('x', x))
            # quietly do nothing... we don't support unstructured grids
            # or 3d spherical yet, and 2d spherical can be figured out
            # if we assume the grid spans the whole sphere
            crdlist = None

        elif geotype.upper() == "X_Y_Z":
            crdlookup = {'x': 0, 'y': 1, 'z': 2}
            crdlist = [['x', None], ['y', None], ['z', None]]
            # can't use ./DataItem[@Name='X'] so python2.6 works
            dataitems = geo.findall("./DataItem")
            for di in dataitems:
                crd_name = di.attrib["Name"].lower()
                data, attrs = self._parse_dataitem(di, keep_flat=True)
                crdlist[crdlookup.pop(crd_name)][1] = data
            if len(crdlookup) > 0:
                raise RuntimeError("XDMF format error: Coords not specified "
                                   "for {0} dimesions"
                                   "".format(list(crdlookup.keys())))
            crdkwargs["full_arrays"] = True

        elif geotype.upper() == "VXVYVZ":
            crdlookup = {'x': 0, 'y': 1, 'z': 2}
            crdlist = [['x', None], ['y', None], ['z', None]]
            # can't use ./DataItem[@Name='VX'] so python2.6 works
            dataitems = geo.findall("./DataItem")
            for di in dataitems:
                crd_name = di.attrib["Name"].lstrip('V').lower()
                data, attrs = self._parse_dataitem(di, keep_flat=True)
                crdlist[crdlookup.pop(crd_name)][1] = data
            if len(crdlookup) > 0:
                raise RuntimeError("XDMF format error: Coords not specified "
                                   "for {0} dimesions"
                                   "".format(list(crdlookup.keys())))
            crdkwargs["full_arrays"] = True

        elif geotype.upper() == "ORIGIN_DXDYDZ":
            # this is for grids with uniform spacing
            dataitems = geo.findall("./DataItem")
            data_o, _ = self._parse_dataitem(dataitems[0])
            data_dx, _ = self._parse_dataitem(dataitems[1])
            dtyp = data_o.dtype
            nstr = None
            if topoattrs["Dimensions"]:
                nstr = topoattrs["Dimensions"]
            elif topoattrs["NumberOfElements"]:
                nstr = topoattrs["NumberOfElements"]
            else:
                raise ValueError("ORIGIN_DXDYDZ has no number of elements...")
            n = [int(num) for num in nstr.split()]
            # FIXME: OpenGGCM output uses ZYX ordering even though the xdmf
            # website says it should be XYZ, BUT, the file opens correctly
            # in Paraview with zyx, so... I guess i need to do this [::-1]
            # nonsense here
            data_o, data_dx, n = data_o[::-1], data_dx[::-1], n[::-1]
            crdlist = [None] * 3
            for i, crd in enumerate(['x', 'y', 'z']):
                n_nc, n_cc = n[i], n[i] - 1
                crd_arr = [data_o[i], data_o[i] + (n_cc * data_dx[i]), n_nc]
                crdlist[i] = (crd, crd_arr)
            crdkwargs["dtype"] = dtyp
            crdkwargs["full_arrays"] = False
        else:
            logger.warn("Invalid GeometryType: %s", geotype)

        if topotype in ['3DCoRectMesh', '2DCoRectMesh']:
            crdtype = "uniform_cartesian"
        elif topotype in ['3DRectMesh', '2DRectMesh']:
            if crdkwargs.get("full_arrays", True):
                crdtype = "nonuniform_cartesian"
            else:  # HACK, hopefully not used ever
                crdtype = "uniform_cartesian"
        elif topotype in ['2DSMesh']:
            crdtype = "uniform_spherical"  # HACK!
            ######## this doesn't quite work, but it's too heavy to be useful
            ######## anyway... if we assume a 2d spherical grid spans the
            ######## whole sphere, and radius doesnt matter, all we need are
            ######## the nr_phis / nr_thetas, so let's just do that
            # # this asserts that attrs["Dimensions"] will have the xyz
            # # dimensions
            # # turn x, y, z -> phi, theta, r
            # dims = [int(s) for
            #         s in reversed(topoattrs["Dimensions"].split(' '))]
            # dims = [1] * (3 - len(dims)) + dims
            # nr, ntheta, nphi = [d for d in dims]
            # # dtype = crdlist[0][1].dtype
            # # phi, theta, r = [np.empty((n,), dtype=dtype) for n in dims]
            # x, y, z = (crdlist[i][1].reshape(dims) for i in range(3))
            # nphitheta = nphi * ntheta
            # r = np.sqrt(x[::nphitheta, 0, 0]**2 + y[::nphitheta, 0, 0]**2 +
            #             z[::nphitheta, 0, 0]**2)
            # ir = nr // 2  # things get squirrly near the extrema
            # theta = (180.0 / np.pi) * \
            #         (np.arccos(z[ir, :, ::nphi] / r[ir]).reshape(-1))
            # itheta = ntheta // 2
            # phi = (180.0 / np.pi) * \
            #       np.arctan2(y[ir, itheta, :], x[ir, itheta, :])
            # print(dims, nr, ntheta, nphi)
            # print("r:", r.shape, r)
            # print("theta:", theta.shape, theta)
            # print("phi:", phi.shape, phi)
            # raise RuntimeError()
            ######## general names in spherical crds
            # ntheta, nphi = [int(s) for s in topoattrs["Dimensions"].split(' ')]
            # crdlist = [['theta', [0.0, 180.0, ntheta]],
            #            ['phi', [0.0, 360.0, nphi]]]
            ######## names on a map
            ntheta, nphi = [int(s) for s in topoattrs["Dimensions"].split(' ')]
            crdlist = [['phi', [0.0, 360.0, nphi]],
                       ['theta', [0.0, 180.0, ntheta]]]
            crdkwargs["full_arrays"] = False
            crdkwargs["units"] = 'deg'

        elif topotype in ['3DSMesh']:
            raise NotImplementedError("3D spherical grids not yet supported")
        else:
            raise NotImplementedError("Unstructured grids not yet supported")

        crds = coordinate.wrap_crds(crdtype, crdlist, **crdkwargs)
        return crds, geoattrs
Example #21
0
def main():
    xl, xh, nx = -1.0, 1.0, 41
    yl, yh, ny = -1.5, 1.5, 41
    zl, zh, nz = -2.0, 2.0, 41
    x = np.linspace(xl, xh, nx)
    y = np.linspace(yl, yh, ny)
    z = np.linspace(zl, zh, nz)
    crds = coordinate.wrap_crds("nonuniform_cartesian", [('z', z), ('y', y),
                                                         ('x', x)])
    bx = field.empty(crds, name="$B_x$", center="Node")
    by = field.empty(crds, name="$B_y$", center="Node")
    bz = field.empty(crds, name="$B_z$", center="Node")
    fld = field.empty(crds,
                      name="B",
                      nr_comps=3,
                      center="Node",
                      layout="interlaced")
    X, Y, Z = crds.get_crds(shaped=True)

    x01, y01, z01 = 0.5, 0.5, 0.5
    x02, y02, z02 = 0.5, 0.5, 0.5
    x03, y03, z03 = 0.5, 0.5, 0.5

    bx[:] = 0.0 + 1.0 * (X - x01) + 1.0 * (Y - y01) + 1.0 * (Z - z01) + \
              1.0 * (X - x01) * (Y - y01) + 1.0 * (Y - y01) * (Z - z01) + \
              1.0 * (X - x01) * (Y - y01) * (Z - z01)
    by[:] = 0.0 + 1.0 * (X - x02) - 1.0 * (Y - y02) + 1.0 * (Z - z02) + \
              1.0 * (X - x02) * (Y - y02) + 1.0 * (Y - y02) * (Z - z02) - \
              1.0 * (X - x02) * (Y - y02) * (Z - z02)
    bz[:] = 0.0 + 1.0 * (X - x03) + 1.0 * (Y - y03) - 1.0 * (Z - z03) + \
              1.0 * (X - x03) * (Y - y03) + 1.0 * (Y - y03) * (Z - z03) + \
              1.0 * (X - x03) * (Y - y03) * (Z - z03)
    fld[..., 0] = bx
    fld[..., 1] = by
    fld[..., 2] = bz

    fig = mlab.figure(size=(1150, 850),
                      bgcolor=(1.0, 1.0, 1.0),
                      fgcolor=(0.0, 0.0, 0.0))
    f1_src = vlab.add_field(bx)
    f2_src = vlab.add_field(by)
    f3_src = vlab.add_field(bz)
    mlab.pipeline.iso_surface(f1_src,
                              contours=[0.0],
                              opacity=1.0,
                              color=(1.0, 0.0, 0.0))
    mlab.pipeline.iso_surface(f2_src,
                              contours=[0.0],
                              opacity=1.0,
                              color=(0.0, 1.0, 0.0))
    mlab.pipeline.iso_surface(f3_src,
                              contours=[0.0],
                              opacity=1.0,
                              color=(0.0, 0.0, 1.0))
    mlab.axes()
    mlab.show()

    nullpt = cycalc.interp_trilin(fld, [(0.5, 0.5, 0.5)])
    print("f(0.5, 0.5, 0.5):", nullpt)

    ax1 = plt.subplot2grid((4, 3), (0, 0))
    all_roots = []
    positive_roots = []
    ix = iy = iz = 0

    for di, d in enumerate([0, -1]):
        #### XY face
        a1 = bx[iz + d, iy, ix]
        b1 = bx[iz + d, iy, ix - 1] - a1
        c1 = bx[iz + d, iy - 1, ix] - a1
        d1 = bx[iz + d, iy - 1, ix - 1] - c1 - b1 - a1

        a2 = by[iz + d, iy, ix]
        b2 = by[iz + d, iy, ix - 1] - a2
        c2 = by[iz + d, iy - 1, ix] - a2
        d2 = by[iz + d, iy - 1, ix - 1] - c2 - b2 - a2

        a3 = bz[iz + d, iy, ix]
        b3 = bz[iz + d, iy, ix - 1] - a3
        c3 = bz[iz + d, iy - 1, ix] - a3
        d3 = bz[iz + d, iy - 1, ix - 1] - c3 - b3 - a3

        roots1, roots2 = find_roots_face(a1, b1, c1, d1, a2, b2, c2, d2)

        # for rt1, rt2 in zip(roots1, roots2):
        #     print("=")
        #     print("fx", a1 + b1 * rt1 + c1 * rt2 + d1 * rt1 * rt2)
        #     print("fy", a2 + b2 * rt1 + c2 * rt2 + d2 * rt1 * rt2)
        #     print("=")

        # find f3 at the root points
        f3 = np.empty_like(roots1)
        markers = [None] * len(f3)
        for i, rt1, rt2 in zip(count(), roots1, roots2):
            f3[i] = a3 + b3 * rt1 + c3 * rt2 + d3 * rt1 * rt2
            all_roots.append((rt1, rt2, d))  # switch order here
            if f3[i] >= 0.0:
                markers[i] = 'k^'
                positive_roots.append((rt1, rt2, d))  # switch order here
            else:
                markers[i] = 'w^'

        # rescale the roots to the original domain
        roots1 = (xh - xl) * roots1 + xl
        roots2 = (yh - yl) * roots2 + yl

        xp = np.linspace(0.0, 1.0, nx)

        # plt.subplot(121)
        plt.subplot2grid((4, 3), (0 + 2 * di, 0), sharex=ax1, sharey=ax1)
        vlt.plot(fld['x'],
                 "z={0}i".format(d),
                 plot_opts="x={0}_{1},y={2}_{3},lin_-10_10".format(
                     xl, xh, yl, yh))
        y1 = -(a1 + b1 * xp) / (c1 + d1 * xp)
        plt.plot(x, (yh - yl) * y1 + yl, 'k')
        for i, xrt, yrt in zip(count(), roots1, roots2):
            plt.plot(xrt, yrt, markers[i])

        # plt.subplot(122)
        plt.subplot2grid((4, 3), (1 + 2 * di, 0), sharex=ax1, sharey=ax1)
        vlt.plot(fld['y'],
                 "z={0}i".format(d),
                 plot_opts="x={0}_{1},y={2}_{3},lin_-10_10".format(
                     xl, xh, yl, yh))
        y2 = -(a2 + b2 * xp) / (c2 + d2 * xp)
        plt.plot(x, (yh - yl) * y2 + yl, 'k')
        for xrt, yrt in zip(roots1, roots2):
            plt.plot(xrt, yrt, markers[i])

        #### YZ face
        a1 = bx[iz, iy, ix + d]
        b1 = bx[iz, iy - 1, ix + d] - a1
        c1 = bx[iz - 1, iy, ix + d] - a1
        d1 = bx[iz - 1, iy - 1, ix + d] - c1 - b1 - a1

        a2 = by[iz, iy, ix + d]
        b2 = by[iz, iy - 1, ix + d] - a2
        c2 = by[iz - 1, iy, ix + d] - a2
        d2 = by[iz - 1, iy - 1, ix + d] - c2 - b2 - a2

        a3 = bz[iz, iy, ix + d]
        b3 = bz[iz, iy - 1, ix + d] - a3
        c3 = bz[iz - 1, iy, ix + d] - a3
        d3 = bz[iz - 1, iy - 1, ix + d] - c3 - b3 - a3

        roots1, roots2 = find_roots_face(a1, b1, c1, d1, a2, b2, c2, d2)

        # for rt1, rt2 in zip(roots1, roots2):
        #     print("=")
        #     print("fx", a1 + b1 * rt1 + c1 * rt2 + d1 * rt1 * rt2)
        #     print("fy", a2 + b2 * rt1 + c2 * rt2 + d2 * rt1 * rt2)
        #     print("=")

        # find f3 at the root points
        f3 = np.empty_like(roots1)
        markers = [None] * len(f3)
        for i, rt1, rt2 in zip(count(), roots1, roots2):
            f3[i] = a3 + b3 * rt1 + c3 * rt2 + d3 * rt1 * rt2
            all_roots.append((d, rt1, rt2))  # switch order here
            if f3[i] >= 0.0:
                markers[i] = 'k^'
                positive_roots.append((d, rt1, rt2))  # switch order here
            else:
                markers[i] = 'w^'

        # rescale the roots to the original domain
        roots1 = (yh - yl) * roots1 + yl
        roots2 = (zh - zl) * roots2 + zl

        yp = np.linspace(0.0, 1.0, ny)

        # plt.subplot(121)
        plt.subplot2grid((4, 3), (0 + 2 * di, 1), sharex=ax1, sharey=ax1)
        vlt.plot(fld['x'],
                 "x={0}i".format(d),
                 plot_opts="x={0}_{1},y={2}_{3},lin_-10_10".format(
                     yl, yh, zl, zh))
        z1 = -(a1 + b1 * yp) / (c1 + d1 * yp)
        plt.plot(y, (zh - zl) * z1 + zl, 'k')
        for i, yrt, zrt in zip(count(), roots1, roots2):
            plt.plot(yrt, zrt, markers[i])

        # plt.subplot(122)
        plt.subplot2grid((4, 3), (1 + 2 * di, 1), sharex=ax1, sharey=ax1)
        vlt.plot(fld['y'],
                 "x={0}i".format(d),
                 plot_opts="x={0}_{1},y={2}_{3},lin_-10_10".format(
                     yl, yh, zl, zh))
        z1 = -(a2 + b2 * yp) / (c2 + d2 * yp)
        plt.plot(y, (zh - zl) * z1 + zl, 'k')
        for i, yrt, zrt in zip(count(), roots1, roots2):
            plt.plot(yrt, zrt, markers[i])

        #### ZX face
        a1 = bx[iz, iy + d, ix]
        b1 = bx[iz - 1, iy + d, ix] - a1
        c1 = bx[iz, iy + d, ix - 1] - a1
        d1 = bx[iz - 1, iy + d, ix - 1] - c1 - b1 - a1

        a2 = by[iz, iy + d, ix]
        b2 = by[iz - 1, iy + d, ix] - a2
        c2 = by[iz, iy + d, ix - 1] - a2
        d2 = by[iz - 1, iy + d, ix - 1] - c2 - b2 - a2

        a3 = bz[iz, iy + d, ix]
        b3 = bz[iz - 1, iy + d, ix] - a3
        c3 = bz[iz, iy + d, ix - 1] - a3
        d3 = bz[iz - 1, iy + d, ix - 1] - c3 - b3 - a3

        roots1, roots2 = find_roots_face(a1, b1, c1, d1, a2, b2, c2, d2)

        # for rt1, rt2 in zip(roots1, roots2):
        #     print("=")
        #     print("fx", a1 + b1 * rt1 + c1 * rt2 + d1 * rt1 * rt2)
        #     print("fy", a2 + b2 * rt1 + c2 * rt2 + d2 * rt1 * rt2)
        #     print("=")

        # find f3 at the root points
        f3 = np.empty_like(roots1)
        markers = [None] * len(f3)
        for i, rt1, rt2 in zip(count(), roots1, roots2):
            f3[i] = a3 + b3 * rt1 + c3 * rt2 + d3 * rt1 * rt2
            all_roots.append((rt2, d, rt1))  # switch order here
            if f3[i] >= 0.0:
                markers[i] = 'k^'
                positive_roots.append((rt2, d, rt1))  # switch order here
            else:
                markers[i] = 'w^'

        # rescale the roots to the original domain
        roots1 = (zh - zl) * roots1 + zl
        roots2 = (xh - xl) * roots2 + xl

        zp = np.linspace(0.0, 1.0, nz)

        # plt.subplot(121)
        plt.subplot2grid((4, 3), (0 + 2 * di, 2), sharex=ax1, sharey=ax1)
        vlt.plot(fld['x'],
                 "y={0}i".format(d),
                 plot_opts="x={0}_{1},y={2}_{3},lin_-10_10".format(
                     xl, xh, zl, zh))
        x1 = -(a1 + b1 * zp) / (c1 + d1 * zp)
        plt.plot(z, (xh - xl) * x1 + xl, 'k')
        for i, zrt, xrt in zip(count(), roots1, roots2):
            plt.plot(xrt, zrt, markers[i])

        # plt.subplot(121)
        plt.subplot2grid((4, 3), (1 + 2 * di, 2), sharex=ax1, sharey=ax1)
        vlt.plot(fld['y'],
                 "y={0}i".format(d),
                 plot_opts="x={0}_{1},y={2}_{3},lin_-10_10".format(
                     xl, xh, zl, zh))
        x1 = -(a2 + b2 * zp) / (c2 + d2 * zp)
        plt.plot(z, (xh - xl) * x1 + xl, 'k')
        for i, zrt, xrt in zip(count(), roots1, roots2):
            plt.plot(xrt, zrt, markers[i])

    print("all:", len(all_roots), "positive:", len(positive_roots))
    if len(all_roots) % 2 == 1:
        print("something is fishy, there are an odd number of root points "
              "on the surface of your cube, there is probably a degenerate "
              "line or surface of nulls")
    print("Null Point?", (len(positive_roots) % 2 == 1))

    plt.show()
Example #22
0
    def _parse_geometry(self, geo, topoattrs):
        """ geo is the element tree item, returns Coordinate object and
            xml attributes """
        geoattrs = self._fill_attrs(geo)
        # crds = None
        crdlist = None
        crdtype = None
        crdkwargs = {}

        topotype = topoattrs["TopologyType"]

        # parse geometry into crds
        geotype = geoattrs["GeometryType"]
        if geotype.upper() == "XYZ":
            data, attrs = self._parse_dataitem(geo.find("./DataItem"),
                                               keep_flat=True)
            # x = data[0::3]
            # y = data[1::3]
            # z = data[2::3]
            # crdlist = (('z', z), ('y', y), ('x', x))
            # quietly do nothing... we don't support unstructured grids
            # or 3d spherical yet, and 2d spherical can be figured out
            # if we assume the grid spans the whole sphere
            crdlist = None

        elif geotype.upper() == "XY":
            data, attrs = self._parse_dataitem(geo.find("./DataItem"),
                                               keep_flat=True)
            # x = data[0::2]
            # y = data[1::2]
            # z = np.zeros(len(x))
            # crdlist = (('z', z), ('y', y), ('x', x))
            # quietly do nothing... we don't support unstructured grids
            # or 3d spherical yet, and 2d spherical can be figured out
            # if we assume the grid spans the whole sphere
            crdlist = None

        elif geotype.upper() == "X_Y_Z":
            crdlookup = {'x': 0, 'y': 1, 'z': 2}
            crdlist = [['x', None], ['y', None], ['z', None]]
            # can't use ./DataItem[@Name='X'] so python2.6 works
            dataitems = geo.findall("./DataItem")
            for di in dataitems:
                crd_name = di.attrib["Name"].lower()
                data, attrs = self._parse_dataitem(di, keep_flat=True)
                crdlist[crdlookup.pop(crd_name)][1] = data
            if len(crdlookup) > 0:
                raise RuntimeError("XDMF format error: Coords not specified "
                                   "for {0} dimesions"
                                   "".format(list(crdlookup.keys())))
            crdkwargs["full_arrays"] = True

        elif geotype.upper() == "VXVYVZ":
            crdlookup = {'x': 0, 'y': 1, 'z': 2}
            crdlist = [['x', None], ['y', None], ['z', None]]
            # can't use ./DataItem[@Name='VX'] so python2.6 works
            dataitems = geo.findall("./DataItem")
            for di in dataitems:
                crd_name = di.attrib["Name"].lstrip('V').lower()
                data, attrs = self._parse_dataitem(di, keep_flat=True)
                crdlist[crdlookup.pop(crd_name)][1] = data
            if len(crdlookup) > 0:
                raise RuntimeError("XDMF format error: Coords not specified "
                                   "for {0} dimesions"
                                   "".format(list(crdlookup.keys())))
            crdkwargs["full_arrays"] = True

        elif geotype.upper() == "ORIGIN_DXDYDZ":
            # this is for grids with uniform spacing
            dataitems = geo.findall("./DataItem")
            data_o, _ = self._parse_dataitem(dataitems[0])
            data_dx, _ = self._parse_dataitem(dataitems[1])
            dtyp = data_o.dtype
            nstr = None
            if topoattrs["Dimensions"]:
                nstr = topoattrs["Dimensions"]
            elif topoattrs["NumberOfElements"]:
                nstr = topoattrs["NumberOfElements"]
            else:
                raise ValueError("ORIGIN_DXDYDZ has no number of elements...")
            n = [int(num) for num in nstr.split()]
            # FIXME: OpenGGCM output uses ZYX ordering even though the xdmf
            # website says it should be XYZ, BUT, the file opens correctly
            # in Paraview with zyx, so... I guess i need to do this [::-1]
            # nonsense here
            data_o, data_dx, n = data_o[::-1], data_dx[::-1], n[::-1]
            crdlist = [None] * 3
            for i, crd in enumerate(['x', 'y', 'z']):
                n_nc, n_cc = n[i], n[i] - 1
                crd_arr = [data_o[i], data_o[i] + (n_cc * data_dx[i]), n_nc]
                crdlist[i] = (crd, crd_arr)
            crdkwargs["dtype"] = dtyp
            crdkwargs["full_arrays"] = False
        else:
            logger.warn("Invalid GeometryType: %s", geotype)

        if topotype in ['3DCoRectMesh', '2DCoRectMesh']:
            crdtype = "uniform_cartesian"
        elif topotype in ['3DRectMesh', '2DRectMesh']:
            if crdkwargs.get("full_arrays", True):
                crdtype = "nonuniform_cartesian"
            else:  # HACK, hopefully not used ever
                crdtype = "uniform_cartesian"
        elif topotype in ['2DSMesh']:
            crdtype = "uniform_spherical"  # HACK!
            ######## this doesn't quite work, but it's too heavy to be useful
            ######## anyway... if we assume a 2d spherical grid spans the
            ######## whole sphere, and radius doesnt matter, all we need are
            ######## the nr_phis / nr_thetas, so let's just do that
            # # this asserts that attrs["Dimensions"] will have the xyz
            # # dimensions
            # # turn x, y, z -> phi, theta, r
            # dims = [int(s) for
            #         s in reversed(topoattrs["Dimensions"].split(' '))]
            # dims = [1] * (3 - len(dims)) + dims
            # nr, ntheta, nphi = [d for d in dims]
            # # dtype = crdlist[0][1].dtype
            # # phi, theta, r = [np.empty((n,), dtype=dtype) for n in dims]
            # x, y, z = (crdlist[i][1].reshape(dims) for i in range(3))
            # nphitheta = nphi * ntheta
            # r = np.sqrt(x[::nphitheta, 0, 0]**2 + y[::nphitheta, 0, 0]**2 +
            #             z[::nphitheta, 0, 0]**2)
            # ir = nr // 2  # things get squirrly near the extrema
            # theta = (180.0 / np.pi) * \
            #         (np.arccos(z[ir, :, ::nphi] / r[ir]).reshape(-1))
            # itheta = ntheta // 2
            # phi = (180.0 / np.pi) * \
            #       np.arctan2(y[ir, itheta, :], x[ir, itheta, :])
            # print(dims, nr, ntheta, nphi)
            # print("r:", r.shape, r)
            # print("theta:", theta.shape, theta)
            # print("phi:", phi.shape, phi)
            # raise RuntimeError()
            ######## general names in spherical crds
            # ntheta, nphi = [int(s) for s in topoattrs["Dimensions"].split(' ')]
            # crdlist = [['theta', [0.0, 180.0, ntheta]],
            #            ['phi', [0.0, 360.0, nphi]]]
            ######## names on a map
            ntheta, nphi = [int(s) for s in topoattrs["Dimensions"].split(' ')]
            crdlist = [['phi', [0.0, 360.0, nphi]],
                       ['theta', [0.0, 180.0, ntheta]]]
            crdkwargs["full_arrays"] = False
            crdkwargs["units"] = 'deg'

        elif topotype in ['3DSMesh']:
            raise NotImplementedError("3D spherical grids not yet supported")
        else:
            raise NotImplementedError("Unstructured grids not yet supported")

        crds = coordinate.wrap_crds(crdtype, crdlist, **crdkwargs)
        return crds, geoattrs
Example #23
0
def as_polar_mapfield(fld, bounding_lat=None, hemisphere='north',
                      make_periodic=False):
    """Prepare a theta/phi or lat/lon field for polar projection

    Args:
        fld (Field): Some scalar or vector field
        bounding_lat (float, optional): Used to slice the field, i.e.,
            gives data from the pole to bounding_lat degrees
            equator-ward of the pole
        hemisphere (str, optional): 'north' or 'south'

    Returns:
        Field: a field that can be mapfield plotted on polar axes

    Raises:
        ValueError: on bad hemisphere
    """
    hemisphere = hemisphere.strip().lower()

    mfld = as_mapfield(fld, order=('lon', 'lat'), units='rad')

    # set a sensible default for bounding_lat... full spheres get cut off
    # at 40 deg, but hemispheres or smaller are shown in full
    if bounding_lat is None:
        if abs(mfld.xh[1] - mfld.xl[1]) >= 1.01 * np.pi:
            bounding_lat = 40.0
        else:
            bounding_lat = 90.0

    bounding_lat = (np.pi / 180.0) * bounding_lat
    abs_bounding_lat = abs(bounding_lat)

    if hemisphere in ("north", 'n'):
        if np.all(mfld.get_crd('lat') < abs_bounding_lat):
            raise ValueError("fld {0} contains no values north of bounding lat "
                             "{1:g} deg"
                             "".format(fld.name, bounding_lat * 180 / np.pi))
        # mfld = mfld["lat=:{0}j:-1".format(abs_bounding_lat)]
        mfld = mfld.loc[:, :np.pi / 2 - abs_bounding_lat:-1]
    elif hemisphere in ("south", 's'):
        if np.all(mfld.get_crd('lat') > -abs_bounding_lat):
            raise ValueError("fld {0} contains no values south of bounding lat "
                             "{1:g} deg"
                             "".format(fld.name, bounding_lat * 180 / np.pi))
        # mfld = mfld["lat=:{0}j".format(-abs_bounding_lat)]
        mfld = mfld.loc[:, :-np.pi / 2 + abs_bounding_lat]
    else:
        raise ValueError("hemisphere should be either north or south")

    clist = mfld.get_clist()
    offset = np.pi / 2
    scale = -1 if hemisphere in ('north', 'n') else 1

    if mfld.crds.is_uniform():
        for i in range(2):
            clist[1][1][i] = scale * clist[1][1][i] + offset
    else:
        clist[1][1] = scale * clist[1][1] + offset

    mfld_dat = mfld.data
    if make_periodic:
        if mfld.crds.is_uniform():
            phi_diff = clist[0][1][1] - clist[0][1][0]
        else:
            phi_diff = clist[0][1][-1] - clist[0][1][0]

        if phi_diff < 2 * np.pi - 1e-5:
            if mfld.crds.is_uniform():
                clist[0][1][1] += phi_diff / clist[0][1][2]
                if not np.isclose(clist[0][1][1] - clist[0][1][0], 2 * np.pi):
                    viscid.logger.warning("Tried unsuccessfully to make uniform "
                                          "polar mapfield periodic: {0:g}"
                                          "".format(clist[0][1][1] - clist[0][1][0]))
            else:
                clist[0][1] = np.concatenate([clist[0][1],
                                              [clist[0][1][0] + 2 * np.pi]])
            mfld_dat = np.concatenate([mfld_dat, mfld_dat[0:1, :]], axis=0)

    crds = wrap_crds(mfld.crds.crdtype, clist, dtype=mfld.crds.dtype)
    ctx = dict(crds=crds)
    return mfld.wrap(mfld_dat, context=ctx)
Example #24
0
def as_polar_mapfield(fld,
                      bounding_lat=None,
                      hemisphere='north',
                      make_periodic=False):
    """Prepare a theta/phi or lat/lon field for polar projection

    Args:
        fld (Field): Some scalar or vector field
        bounding_lat (float, optional): Used to slice the field, i.e.,
            gives data from the pole to bounding_lat degrees
            equator-ward of the pole
        hemisphere (str, optional): 'north' or 'south'

    Returns:
        Field: a field that can be mapfield plotted on polar axes

    Raises:
        ValueError: on bad hemisphere
    """
    hemisphere = hemisphere.strip().lower()

    mfld = as_mapfield(fld, order=('lon', 'lat'), units='rad')

    # set a sensible default for bounding_lat... full spheres get cut off
    # at 40 deg, but hemispheres or smaller are shown in full
    if bounding_lat is None:
        if abs(mfld.xh[1] - mfld.xl[1]) >= 1.01 * np.pi:
            bounding_lat = 40.0
        else:
            bounding_lat = 90.0

    bounding_lat = (np.pi / 180.0) * bounding_lat
    abs_bounding_lat = abs(bounding_lat)

    if hemisphere in ("north", 'n'):
        if np.all(mfld.get_crd('lat') < abs_bounding_lat):
            raise ValueError(
                "fld {0} contains no values north of bounding lat "
                "{1:g} deg"
                "".format(fld.name, bounding_lat * 180 / np.pi))
        # mfld = mfld["lat=:{0}j:-1".format(abs_bounding_lat)]
        mfld = mfld.loc[:, :np.pi / 2 - abs_bounding_lat:-1]
    elif hemisphere in ("south", 's'):
        if np.all(mfld.get_crd('lat') > -abs_bounding_lat):
            raise ValueError(
                "fld {0} contains no values south of bounding lat "
                "{1:g} deg"
                "".format(fld.name, bounding_lat * 180 / np.pi))
        # mfld = mfld["lat=:{0}j".format(-abs_bounding_lat)]
        mfld = mfld.loc[:, :-np.pi / 2 + abs_bounding_lat]
    else:
        raise ValueError("hemisphere should be either north or south")

    clist = mfld.get_clist()
    offset = np.pi / 2
    scale = -1 if hemisphere in ('north', 'n') else 1

    if mfld.crds.is_uniform():
        for i in range(2):
            clist[1][1][i] = scale * clist[1][1][i] + offset
    else:
        clist[1][1] = scale * clist[1][1] + offset

    mfld_dat = mfld.data
    if make_periodic:
        if mfld.crds.is_uniform():
            phi_diff = clist[0][1][1] - clist[0][1][0]
        else:
            phi_diff = clist[0][1][-1] - clist[0][1][0]

        if phi_diff < 2 * np.pi - 1e-5:
            if mfld.crds.is_uniform():
                clist[0][1][1] += phi_diff / clist[0][1][2]
                if not np.isclose(clist[0][1][1] - clist[0][1][0], 2 * np.pi):
                    viscid.logger.warning(
                        "Tried unsuccessfully to make uniform "
                        "polar mapfield periodic: {0:g}"
                        "".format(clist[0][1][1] - clist[0][1][0]))
            else:
                clist[0][1] = np.concatenate(
                    [clist[0][1], [clist[0][1][0] + 2 * np.pi]])
            mfld_dat = np.concatenate([mfld_dat, mfld_dat[0:1, :]], axis=0)

    crds = wrap_crds(mfld.crds.crdtype, clist, dtype=mfld.crds.dtype)
    ctx = dict(crds=crds)
    return mfld.wrap(mfld_dat, context=ctx)
Example #25
0
def main():
    xl, xh, nx = -1.0, 1.0, 41
    yl, yh, ny = -1.5, 1.5, 41
    zl, zh, nz = -2.0, 2.0, 41
    x = np.linspace(xl, xh, nx)
    y = np.linspace(yl, yh, ny)
    z = np.linspace(zl, zh, nz)
    crds = coordinate.wrap_crds("nonuniform_cartesian",
                                [('z', z), ('y', y), ('x', x)])
    bx = field.empty(crds, name="$B_x$", center="Node")
    by = field.empty(crds, name="$B_y$", center="Node")
    bz = field.empty(crds, name="$B_z$", center="Node")
    fld = field.empty(crds, name="B", nr_comps=3, center="Node",
                      layout="interlaced")
    X, Y, Z = crds.get_crds(shaped=True)

    x01, y01, z01 = 0.5, 0.5, 0.5
    x02, y02, z02 = 0.5, 0.5, 0.5
    x03, y03, z03 = 0.5, 0.5, 0.5

    bx[:] = 0.0 + 1.0 * (X - x01) + 1.0 * (Y - y01) + 1.0 * (Z - z01) + \
              1.0 * (X - x01) * (Y - y01) + 1.0 * (Y - y01) * (Z - z01) + \
              1.0 * (X - x01) * (Y - y01) * (Z - z01)
    by[:] = 0.0 + 1.0 * (X - x02) - 1.0 * (Y - y02) + 1.0 * (Z - z02) + \
              1.0 * (X - x02) * (Y - y02) + 1.0 * (Y - y02) * (Z - z02) - \
              1.0 * (X - x02) * (Y - y02) * (Z - z02)
    bz[:] = 0.0 + 1.0 * (X - x03) + 1.0 * (Y - y03) - 1.0 * (Z - z03) + \
              1.0 * (X - x03) * (Y - y03) + 1.0 * (Y - y03) * (Z - z03) + \
              1.0 * (X - x03) * (Y - y03) * (Z - z03)
    fld[..., 0] = bx
    fld[..., 1] = by
    fld[..., 2] = bz

    fig = mlab.figure(size=(1150, 850),
                      bgcolor=(1.0, 1.0, 1.0),
                      fgcolor=(0.0, 0.0, 0.0))
    f1_src = vlab.add_field(bx)
    f2_src = vlab.add_field(by)
    f3_src = vlab.add_field(bz)
    mlab.pipeline.iso_surface(f1_src, contours=[0.0],
                              opacity=1.0, color=(1.0, 0.0, 0.0))
    mlab.pipeline.iso_surface(f2_src, contours=[0.0],
                              opacity=1.0, color=(0.0, 1.0, 0.0))
    mlab.pipeline.iso_surface(f3_src, contours=[0.0],
                              opacity=1.0, color=(0.0, 0.0, 1.0))
    mlab.axes()
    mlab.show()

    nullpt = cycalc.interp_trilin(fld, [(0.5, 0.5, 0.5)])
    print("f(0.5, 0.5, 0.5):", nullpt)

    _, axes = plt.subplots(4, 3, sharex=True, sharey=True)
    all_roots = []
    positive_roots = []
    ix = iy = iz = 0

    for di, d in enumerate([0, -1]):
        #### XY face
        a1 = bx[iz + d, iy, ix]
        b1 = bx[iz + d, iy, ix - 1] - a1
        c1 = bx[iz + d, iy - 1, ix] - a1
        d1 = bx[iz + d, iy - 1, ix - 1] - c1 - b1 - a1

        a2 = by[iz + d, iy, ix]
        b2 = by[iz + d, iy, ix - 1] - a2
        c2 = by[iz + d, iy - 1, ix] - a2
        d2 = by[iz + d, iy - 1, ix - 1] - c2 - b2 - a2

        a3 = bz[iz + d, iy, ix]
        b3 = bz[iz + d, iy, ix - 1] - a3
        c3 = bz[iz + d, iy - 1, ix] - a3
        d3 = bz[iz + d, iy - 1, ix - 1] - c3 - b3 - a3

        roots1, roots2 = find_roots_face(a1, b1, c1, d1, a2, b2, c2, d2)

        # for rt1, rt2 in zip(roots1, roots2):
        #     print("=")
        #     print("fx", a1 + b1 * rt1 + c1 * rt2 + d1 * rt1 * rt2)
        #     print("fy", a2 + b2 * rt1 + c2 * rt2 + d2 * rt1 * rt2)
        #     print("=")

        # find f3 at the root points
        f3 = np.empty_like(roots1)
        markers = [None] * len(f3)
        for i, rt1, rt2 in zip(count(), roots1, roots2):
            f3[i] = a3 + b3 * rt1 + c3 * rt2 + d3 * rt1 * rt2
            all_roots.append((rt1, rt2, d))  # switch order here
            if f3[i] >= 0.0:
                markers[i] = 'k^'
                positive_roots.append((rt1, rt2, d))  # switch order here
            else:
                markers[i] = 'w^'

        # rescale the roots to the original domain
        roots1 = (xh - xl) * roots1 + xl
        roots2 = (yh - yl) * roots2 + yl

        xp = np.linspace(0.0, 1.0, nx)

        vlt.plot(fld['x'], "z={0}i".format(d), ax=axes[0 + 2 * di, 0],
                 plot_opts="x={0}_{1},y={2}_{3},lin_-10_10".format(xl, xh, yl, yh))
        y1 = - (a1 + b1 * xp) / (c1 + d1 * xp)
        plt.plot(x, (yh - yl) * y1 + yl, 'k')
        for i, xrt, yrt in zip(count(), roots1, roots2):
            plt.plot(xrt, yrt, markers[i])

        vlt.plot(fld['y'], "z={0}i".format(d), ax=axes[1 + 2 * di, 0],
                 plot_opts="x={0}_{1},y={2}_{3},lin_-10_10".format(xl, xh, yl, yh))
        y2 = - (a2 + b2 * xp) / (c2 + d2 * xp)
        plt.plot(x, (yh - yl) * y2 + yl, 'k')
        for xrt, yrt in zip(roots1, roots2):
            plt.plot(xrt, yrt, markers[i])

        #### YZ face
        a1 = bx[iz, iy, ix + d]
        b1 = bx[iz, iy - 1, ix + d] - a1
        c1 = bx[iz - 1, iy, ix + d] - a1
        d1 = bx[iz - 1, iy - 1, ix + d] - c1 - b1 - a1

        a2 = by[iz, iy, ix + d]
        b2 = by[iz, iy - 1, ix + d] - a2
        c2 = by[iz - 1, iy, ix + d] - a2
        d2 = by[iz - 1, iy - 1, ix + d] - c2 - b2 - a2

        a3 = bz[iz, iy, ix + d]
        b3 = bz[iz, iy - 1, ix + d] - a3
        c3 = bz[iz - 1, iy, ix + d] - a3
        d3 = bz[iz - 1, iy - 1, ix + d] - c3 - b3 - a3

        roots1, roots2 = find_roots_face(a1, b1, c1, d1, a2, b2, c2, d2)

        # for rt1, rt2 in zip(roots1, roots2):
        #     print("=")
        #     print("fx", a1 + b1 * rt1 + c1 * rt2 + d1 * rt1 * rt2)
        #     print("fy", a2 + b2 * rt1 + c2 * rt2 + d2 * rt1 * rt2)
        #     print("=")

        # find f3 at the root points
        f3 = np.empty_like(roots1)
        markers = [None] * len(f3)
        for i, rt1, rt2 in zip(count(), roots1, roots2):
            f3[i] = a3 + b3 * rt1 + c3 * rt2 + d3 * rt1 * rt2
            all_roots.append((d, rt1, rt2))  # switch order here
            if f3[i] >= 0.0:
                markers[i] = 'k^'
                positive_roots.append((d, rt1, rt2))  # switch order here
            else:
                markers[i] = 'w^'

        # rescale the roots to the original domain
        roots1 = (yh - yl) * roots1 + yl
        roots2 = (zh - zl) * roots2 + zl

        yp = np.linspace(0.0, 1.0, ny)

        # plt.subplot(121)
        vlt.plot(fld['x'], "x={0}i".format(d), ax=axes[0 + 2 * di, 1],
                 plot_opts="x={0}_{1},y={2}_{3},lin_-10_10".format(yl, yh, zl, zh))
        z1 = - (a1 + b1 * yp) / (c1 + d1 * yp)
        plt.plot(y, (zh - zl) * z1 + zl, 'k')
        for i, yrt, zrt in zip(count(), roots1, roots2):
            plt.plot(yrt, zrt, markers[i])

        # plt.subplot(122)
        vlt.plot(fld['y'], "x={0}i".format(d), ax=axes[1 + 2 * di, 1],
                 plot_opts="x={0}_{1},y={2}_{3},lin_-10_10".format(yl, yh, zl, zh))
        z1 = - (a2 + b2 * yp) / (c2 + d2 * yp)
        plt.plot(y, (zh - zl) * z1 + zl, 'k')
        for i, yrt, zrt in zip(count(), roots1, roots2):
            plt.plot(yrt, zrt, markers[i])

        #### ZX face
        a1 = bx[iz, iy + d, ix]
        b1 = bx[iz - 1, iy + d, ix] - a1
        c1 = bx[iz, iy + d, ix - 1] - a1
        d1 = bx[iz - 1, iy + d, ix - 1] - c1 - b1 - a1

        a2 = by[iz, iy + d, ix]
        b2 = by[iz - 1, iy + d, ix] - a2
        c2 = by[iz, iy + d, ix - 1] - a2
        d2 = by[iz - 1, iy + d, ix - 1] - c2 - b2 - a2

        a3 = bz[iz, iy + d, ix]
        b3 = bz[iz - 1, iy + d, ix] - a3
        c3 = bz[iz, iy + d, ix - 1] - a3
        d3 = bz[iz - 1, iy + d, ix - 1] - c3 - b3 - a3

        roots1, roots2 = find_roots_face(a1, b1, c1, d1, a2, b2, c2, d2)

        # for rt1, rt2 in zip(roots1, roots2):
        #     print("=")
        #     print("fx", a1 + b1 * rt1 + c1 * rt2 + d1 * rt1 * rt2)
        #     print("fy", a2 + b2 * rt1 + c2 * rt2 + d2 * rt1 * rt2)
        #     print("=")

        # find f3 at the root points
        f3 = np.empty_like(roots1)
        markers = [None] * len(f3)
        for i, rt1, rt2 in zip(count(), roots1, roots2):
            f3[i] = a3 + b3 * rt1 + c3 * rt2 + d3 * rt1 * rt2
            all_roots.append((rt2, d, rt1))  # switch order here
            if f3[i] >= 0.0:
                markers[i] = 'k^'
                positive_roots.append((rt2, d, rt1))  # switch order here
            else:
                markers[i] = 'w^'

        # rescale the roots to the original domain
        roots1 = (zh - zl) * roots1 + zl
        roots2 = (xh - xl) * roots2 + xl

        zp = np.linspace(0.0, 1.0, nz)

        # plt.subplot(121)
        vlt.plot(fld['x'], "y={0}i".format(d), ax=axes[0 + 2 * di, 2],
                 plot_opts="x={0}_{1},y={2}_{3},lin_-10_10".format(xl, xh, zl, zh))
        x1 = - (a1 + b1 * zp) / (c1 + d1 * zp)
        plt.plot(z, (xh - xl) * x1 + xl, 'k')
        for i, zrt, xrt in zip(count(), roots1, roots2):
            plt.plot(xrt, zrt, markers[i])

        # plt.subplot(121)
        vlt.plot(fld['y'], "y={0}i".format(d), ax=axes[1 + 2 * di, 2],
                 plot_opts="x={0}_{1},y={2}_{3},lin_-10_10".format(xl, xh, zl, zh))
        x1 = - (a2 + b2 * zp) / (c2 + d2 * zp)
        plt.plot(z, (xh - xl) * x1 + xl, 'k')
        for i, zrt, xrt in zip(count(), roots1, roots2):
            plt.plot(xrt, zrt, markers[i])

    print("all:", len(all_roots), "positive:", len(positive_roots))
    if len(all_roots) % 2 == 1:
        print("something is fishy, there are an odd number of root points "
              "on the surface of your cube, there is probably a degenerate "
              "line or surface of nulls")
    print("Null Point?", (len(positive_roots) % 2 == 1))

    plt.show()