[yt-svn] commit/yt: 8 new changesets

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Fri Jun 2 10:59:09 PDT 2017


8 new commits in yt:

https://bitbucket.org/yt_analysis/yt/commits/f6f35670997e/
Changeset:   f6f35670997e
User:        ngoldbaum
Date:        2017-06-01 20:12:55+00:00
Summary:     Replace string checks for GridSelector with isinstance
Affected #:  7 files

diff -r 4b22085ba0b75e00f4176024e555d459c8f0451d -r f6f35670997ecb63a3b6296efdf0c9435c29bcdd yt/frontends/boxlib/io.py
--- a/yt/frontends/boxlib/io.py
+++ b/yt/frontends/boxlib/io.py
@@ -21,6 +21,7 @@
     BaseIOHandler
 from yt.funcs import mylog
 from yt.frontends.chombo.io import parse_orion_sinks
+from yt.geometry.selection_routines import GridSelector
 
 def _remove_raw(all_fields, raw_fields):
     centered_fields = set(all_fields)
@@ -232,7 +233,7 @@
         rv = {}
         chunks = list(chunks)
 
-        if selector.__class__.__name__ == "GridSelector":
+        if isinstance(selector, GridSelector):
 
             if not (len(chunks) == len(chunks[0].objs) == 1):
                 raise RuntimeError

diff -r 4b22085ba0b75e00f4176024e555d459c8f0451d -r f6f35670997ecb63a3b6296efdf0c9435c29bcdd yt/frontends/chombo/io.py
--- a/yt/frontends/chombo/io.py
+++ b/yt/frontends/chombo/io.py
@@ -15,8 +15,10 @@
 
 import re
 import numpy as np
-from yt.utilities.logger import ytLogger as mylog
-
+from yt.geometry.selection_routines import \
+    GridSelector
+from yt.utilities.logger import \
+    ytLogger as mylog
 from yt.utilities.io_handler import \
     BaseIOHandler
 
@@ -116,7 +118,7 @@
         rv = {}
         chunks = list(chunks)
         fields.sort(key=lambda a: self.field_dict[a[1]])
-        if selector.__class__.__name__ == "GridSelector":
+        if isinstance(selector, GridSelector):
             if not (len(chunks) == len(chunks[0].objs) == 1):
                 raise RuntimeError
             grid = chunks[0].objs[0]
@@ -149,7 +151,7 @@
         rv = {}
         chunks = list(chunks)
 
-        if selector.__class__.__name__ == "GridSelector":
+        if isinstance(selector, GridSelector):
 
             if not (len(chunks) == len(chunks[0].objs) == 1):
                 raise RuntimeError

diff -r 4b22085ba0b75e00f4176024e555d459c8f0451d -r f6f35670997ecb63a3b6296efdf0c9435c29bcdd yt/frontends/enzo/io.py
--- a/yt/frontends/enzo/io.py
+++ b/yt/frontends/enzo/io.py
@@ -18,7 +18,7 @@
 from yt.utilities.logger import ytLogger as mylog
 from yt.extern.six import b, iteritems
 from yt.utilities.on_demand_imports import _h5py as h5py
-
+from yt.geometry.selection_routines import GridSelector
 import numpy as np
 
 
@@ -212,7 +212,7 @@
         rv = {}
         # Now we have to do something unpleasant
         chunks = list(chunks)
-        if selector.__class__.__name__ == "GridSelector":
+        if isinstance(selector, GridSelector):
             if not (len(chunks) == len(chunks[0].objs) == 1):
                 raise RuntimeError
             g = chunks[0].objs[0]
@@ -294,7 +294,7 @@
         rv = {}
         # Now we have to do something unpleasant
         chunks = list(chunks)
-        if selector.__class__.__name__ == "GridSelector":
+        if isinstance(selector, GridSelector):
             if not (len(chunks) == len(chunks[0].objs) == 1):
                 raise RuntimeError
             g = chunks[0].objs[0]

diff -r 4b22085ba0b75e00f4176024e555d459c8f0451d -r f6f35670997ecb63a3b6296efdf0c9435c29bcdd yt/frontends/gdf/io.py
--- a/yt/frontends/gdf/io.py
+++ b/yt/frontends/gdf/io.py
@@ -17,6 +17,7 @@
 from yt.utilities.on_demand_imports import _h5py as h5py
 from yt.funcs import \
     mylog
+from yt.geometry.selection_routines import GridSelector
 from yt.utilities.io_handler import \
     BaseIOHandler
 
@@ -40,7 +41,7 @@
         rv = {}
         chunks = list(chunks)
 
-        if selector.__class__.__name__ == "GridSelector":
+        if isinstance(selector, GridSelector):
             if not (len(chunks) == len(chunks[0].objs) == 1):
                 raise RuntimeError
             grid = chunks[0].objs[0]

diff -r 4b22085ba0b75e00f4176024e555d459c8f0451d -r f6f35670997ecb63a3b6296efdf0c9435c29bcdd yt/frontends/open_pmd/io.py
--- a/yt/frontends/open_pmd/io.py
+++ b/yt/frontends/open_pmd/io.py
@@ -22,6 +22,7 @@
 from yt.frontends.open_pmd.misc import \
     is_const_component, \
     get_component
+from yt.geometry.selection_routines import GridSelector
 from yt.utilities.io_handler import BaseIOHandler
 
 
@@ -178,7 +179,7 @@
         rv = {}
         ind = {}
 
-        if selector.__class__.__name__ == "GridSelector":
+        if isinstance(selector, GridSelector):
             if not (len(chunks) == len(chunks[0].objs) == 1):
                 raise RuntimeError
 

diff -r 4b22085ba0b75e00f4176024e555d459c8f0451d -r f6f35670997ecb63a3b6296efdf0c9435c29bcdd yt/frontends/ytdata/io.py
--- a/yt/frontends/ytdata/io.py
+++ b/yt/frontends/ytdata/io.py
@@ -20,6 +20,8 @@
     u
 from yt.funcs import \
     mylog
+from yt.geometry.selection_routines import \
+    GridSelector
 from yt.utilities.exceptions import \
     YTDomainOverflow
 from yt.utilities.io_handler import \
@@ -36,7 +38,7 @@
 
     def _read_fluid_selection(self, g, selector, fields):
         rv = {}
-        if selector.__class__.__name__ == "GridSelector":
+        if isinstance(selector, GridSelector):
             if g.id in self._cached_fields:
                 gf = self._cached_fields[g.id]
                 rv.update(gf)
@@ -68,7 +70,7 @@
         rv = {}
         # Now we have to do something unpleasant
         chunks = list(chunks)
-        if selector.__class__.__name__ == "GridSelector":
+        if isinstance(selector, GridSelector):
             if not (len(chunks) == len(chunks[0].objs) == 1):
                 raise RuntimeError
             g = chunks[0].objs[0]

diff -r 4b22085ba0b75e00f4176024e555d459c8f0451d -r f6f35670997ecb63a3b6296efdf0c9435c29bcdd yt/utilities/io_handler.py
--- a/yt/utilities/io_handler.py
+++ b/yt/utilities/io_handler.py
@@ -22,6 +22,7 @@
 from yt.extern.six import add_metaclass
 from yt.utilities.lru_cache import \
     local_lru_cache, _make_key
+from yt.geometry.selection_routines import GridSelector
 
 _axis_ids = {0:2,1:1,2:0}
 
@@ -128,8 +129,9 @@
         rv = {field: np.empty(size, dtype="=f8") for field in fields} 
         ind = {field: 0 for field in fields}
         for field, obj, data in self.io_iter(chunks, fields):
-            if data is None: continue
-            if selector.__class__.__name__ == "GridSelector":
+            if data is None:
+                continue
+            if selector.__class__ is GridSelector and field not in nodal_fields:
                 ind[field] += data.size
                 rv[field] = data.copy()
                 continue


https://bitbucket.org/yt_analysis/yt/commits/5555667bd5fa/
Changeset:   5555667bd5fa
User:        ngoldbaum
Date:        2017-06-01 20:15:40+00:00
Summary:     Add support for face-centered Enzo MHDCT fields. Closes #1087
Affected #:  4 files

diff -r f6f35670997ecb63a3b6296efdf0c9435c29bcdd -r 5555667bd5fa759b5ca60b75773264952fac728e yt/frontends/enzo/fields.py
--- a/yt/frontends/enzo/fields.py
+++ b/yt/frontends/enzo/fields.py
@@ -13,6 +13,7 @@
 # The full license is in the file COPYING.txt, distributed with this software.
 #-----------------------------------------------------------------------------
 
+import numpy as np
 from yt.fields.field_info_container import \
     FieldInfoContainer
 from yt.utilities.physical_constants import \
@@ -20,6 +21,7 @@
     mp
 
 b_units = "code_magnetic"
+e_units = "code_magnetic/c"
 ra_units = "code_length / code_time**2"
 rho_units = "code_mass / code_length**3"
 vel_units = "code_velocity"
@@ -49,6 +51,18 @@
     'OIX'     : 'O_p8',
 }
 
+NODAL_FLAGS = {
+    'BxF': [1, 0, 0],
+    'ByF': [0, 1, 0],
+    'BzF': [0, 0, 1],
+    'Ex': [0, 1, 1],
+    'Ey': [1, 0, 1],
+    'Ez': [1, 1, 0],
+    'AvgElec0': [0, 1, 1],
+    'AvgElec1': [1, 0, 1],
+    'AvgElec2': [1, 1, 0],
+}
+
 class EnzoFieldInfo(FieldInfoContainer):
     known_other_fields = (
         ("Cooling_Time", ("s", ["cooling_time"], None)),
@@ -63,6 +77,15 @@
         ("Bx", (b_units, [], None)),
         ("By", (b_units, [], None)),
         ("Bz", (b_units, [], None)),
+        ("BxF", (b_units, [], None)),
+        ("ByF", (b_units, [], None)),
+        ("BzF", (b_units, [], None)),
+        ("Ex", (e_units, [], None)),
+        ("Ey", (e_units, [], None)),
+        ("Ez", (e_units, [], None)),
+        ("AvgElec0", (e_units, [], None)),
+        ("AvgElec1", (e_units, [], None)),
+        ("AvgElec2", (e_units, [], None)),
         ("RadAccel1", (ra_units, ["radiation_acceleration_x"], None)),
         ("RadAccel2", (ra_units, ["radiation_acceleration_y"], None)),
         ("RadAccel3", (ra_units, ["radiation_acceleration_z"], None)),
@@ -116,6 +139,15 @@
         slice_info = (sl_left, sl_right, div_fac)
         super(EnzoFieldInfo, self).__init__(ds, field_list, slice_info)
 
+        # setup nodal flag information
+        for field in NODAL_FLAGS:
+            try:
+                finfo = self['enzo', field]
+                finfo.nodal_flag = np.array(NODAL_FLAGS[field])
+            except KeyError:
+                pass
+
+
     def add_species_field(self, species):
         # This is currently specific to Enzo.  Hopefully in the future we will
         # have deeper integration with other systems, such as Dengo, to provide

diff -r f6f35670997ecb63a3b6296efdf0c9435c29bcdd -r 5555667bd5fa759b5ca60b75773264952fac728e yt/frontends/enzo/io.py
--- a/yt/frontends/enzo/io.py
+++ b/yt/frontends/enzo/io.py
@@ -129,13 +129,18 @@
                         fid.close()
                     fid = h5py.h5f.open(b(obj.filename), h5py.h5f.ACC_RDONLY)
                     filename = obj.filename
-                data = np.empty(obj.ActiveDimensions[::-1], dtype=h5_dtype)
                 for field in fields:
-                    yield field, obj, self._read_obj_field(obj, field, (fid, data))
+                    nodal_flag = self.ds.field_info[field].nodal_flag
+                    dims = obj.ActiveDimensions[::-1].copy()
+                    if np.any(nodal_flag):
+                        dims += nodal_flag[::-1]
+                    data = np.empty(dims, dtype=h5_dtype)
+                    yield field, obj, self._read_obj_field(
+                        obj, field, (fid, data))
         if fid is not None:
             fid.close()
         
-    def _read_obj_field(self, obj, field, fid_data = None):
+    def _read_obj_field(self, obj, field, fid_data):
         if fid_data is None: fid_data = (None, None)
         fid, data = fid_data
         if fid is None:

diff -r f6f35670997ecb63a3b6296efdf0c9435c29bcdd -r 5555667bd5fa759b5ca60b75773264952fac728e yt/frontends/enzo/tests/test_outputs.py
--- a/yt/frontends/enzo/tests/test_outputs.py
+++ b/yt/frontends/enzo/tests/test_outputs.py
@@ -29,6 +29,7 @@
     AnalyticHaloMassFunctionTest, \
     SimulatedHaloMassFunctionTest
 from yt.frontends.enzo.api import EnzoDataset
+from yt.frontends.enzo.fields import NODAL_FLAGS
 
 _fields = ("temperature", "density", "velocity_magnitude",
            "velocity_divergence")
@@ -40,6 +41,7 @@
 enzotiny = "enzo_tiny_cosmology/DD0046/DD0046"
 toro1d = "ToroShockTube/DD0001/data0001"
 kh2d = "EnzoKelvinHelmholtz/DD0011/DD0011"
+mhdctot = "MHDCTOrszagTang/DD0004/data0004"
 
 def check_color_conservation(ds):
     species_names = ds.field_info.species_names
@@ -172,3 +174,20 @@
 
     assert_equal(apcos.particle_type_counts,
                  {'CenOstriker': 899755, 'DarkMatter': 32768})
+
+ at requires_file(mhdctot)
+def test_face_centered_mhdct_fields():
+    ds = data_dir_load(mhdctot)
+
+    ad = ds.all_data()
+    grid = ds.index.grids[0]
+
+    for field, flag in NODAL_FLAGS.items():
+        dims = ds.domain_dimensions
+        assert_equal(ad[field].shape, (dims.prod(), 2*sum(flag)))
+        assert_equal(grid[field].shape, tuple(dims) + (2*sum(flag),))
+
+    # Average of face-centered fields should be the same as cell-centered field
+    assert (ad['BxF'].sum(axis=-1)/2 == ad['Bx']).all()
+    assert (ad['ByF'].sum(axis=-1)/2 == ad['By']).all()
+    assert (ad['BzF'].sum(axis=-1)/2 == ad['Bz']).all()

diff -r f6f35670997ecb63a3b6296efdf0c9435c29bcdd -r 5555667bd5fa759b5ca60b75773264952fac728e yt/utilities/io_handler.py
--- a/yt/utilities/io_handler.py
+++ b/yt/utilities/io_handler.py
@@ -126,7 +126,17 @@
         # rewrite a whole bunch of IO handlers all at once, and to allow a
         # better abstraction for grid-based frontends, we're now defining it in
         # the base class.
-        rv = {field: np.empty(size, dtype="=f8") for field in fields} 
+        rv = {}
+        nodal_fields = []
+        for field in fields:
+            finfo = self.ds.field_info[field]
+            nodal_flag = finfo.nodal_flag
+            if np.any(nodal_flag):
+                num_nodes = 2**sum(nodal_flag)
+                rv[field] = np.empty((size, num_nodes), dtype="=f8")
+                nodal_fields.append(field)
+            else:
+                rv[field] = np.empty(size, dtype="=f8")
         ind = {field: 0 for field in fields}
         for field, obj, data in self.io_iter(chunks, fields):
             if data is None:
@@ -134,8 +144,8 @@
             if selector.__class__ is GridSelector and field not in nodal_fields:
                 ind[field] += data.size
                 rv[field] = data.copy()
-                continue
-            ind[field] += obj.select(selector, data, rv[field], ind[field])
+            else:
+                ind[field] += obj.select(selector, data, rv[field], ind[field])
         return rv
 
     def _read_data_slice(self, grid, field, axis, coord):


https://bitbucket.org/yt_analysis/yt/commits/c1b8ebcae43d/
Changeset:   c1b8ebcae43d
User:        ngoldbaum
Date:        2017-06-01 20:22:24+00:00
Summary:     add documentation
Affected #:  1 file

diff -r 5555667bd5fa759b5ca60b75773264952fac728e -r c1b8ebcae43ddf11512a8a6778017c3c48c1c2a6 doc/source/examining/loading_data.rst
--- a/doc/source/examining/loading_data.rst
+++ b/doc/source/examining/loading_data.rst
@@ -440,6 +440,43 @@
   of length 1.0 in "code length" which may produce strange results for volume
   quantities.
 
+
+Enzo MHDCT data
+^^^^^^^^^^^^^^^
+
+The electric and magnetic fields for Enzo MHDCT simulations are not
+face-centered. In yt, we call fields like this "nodal".  We define a field to be
+"nodal" in a given direction if the field data is defined at the "low" and
+"high" sides of the cell in that direction, rather than at the cell center.
+Instead of returning one field value per cell selected, nodal fields return a
+number of values, depending on their centering. This centering is marked by a
+`nodal_flag` that describes whether the fields is nodal in each dimension.
+``nodal_flag = [0, 0, 0]`` means that the field is cell-centered, while
+``nodal_flag = [0, 0, 1]`` means that the field is nodal in the z direction and
+cell centered in the others, i.e. it is defined on the z faces of each cell.
+``nodal_flag = [1, 1, 0]`` would mean that the field is centered in the z
+direction, but nodal in the other two, i.e. it lives on the four cell edges that
+are normal to the z direction.
+
+..code-block:: python
+    ad = ds.all_data()
+    print(ds.field_info[('enzo', 'Ex')].nodal_flag)
+    print(ad['raw', 'Ex'].shape)
+    print(ds.field_info[('enzo', 'BxF')].nodal_flag)
+    print(ad['raw', 'Bx'].shape)
+    print(ds.field_info[('enzo', 'Bx')].nodal_flag)
+    print(ad['boxlib', 'Bx'].shape)
+
+Here, the field ``('enzo', 'Ex')`` is nodal in two directions, so four values
+per cell are returned, corresponding to the four edges in each cell on which the
+variable is defined. ``('enzo', 'BxF')`` is nodal in one direction, so two
+values are returned per cell. The standard, non-nodal field ``('enzo', 'Bx')``
+is also available.
+
+Currently, slices and data selection are implemented for nodal
+fields. Projections, volume rendering, and many of the analysis modules will not
+work.
+
 .. _loading-exodusii-data:
 
 Exodus II Data


https://bitbucket.org/yt_analysis/yt/commits/f96c4dda87bd/
Changeset:   f96c4dda87bd
User:        ngoldbaum
Date:        2017-06-01 20:36:25+00:00
Summary:     fix sphinx syntax
Affected #:  1 file

diff -r c1b8ebcae43ddf11512a8a6778017c3c48c1c2a6 -r f96c4dda87bd1b4ca1d5856afce9b0af793ace37 doc/source/examining/loading_data.rst
--- a/doc/source/examining/loading_data.rst
+++ b/doc/source/examining/loading_data.rst
@@ -358,7 +358,8 @@
 but nodal in the other two, i.e. it lives on the four cell edges that are normal
 to the z direction.
 
-..code-block:: python
+.. code-block:: python
+
     ad = ds.all_data()
     print(ds.field_info[('raw', 'Ex')].nodal_flag)
     print(ad['raw', 'Ex'].shape)
@@ -458,7 +459,8 @@
 direction, but nodal in the other two, i.e. it lives on the four cell edges that
 are normal to the z direction.
 
-..code-block:: python
+.. code-block:: python
+
     ad = ds.all_data()
     print(ds.field_info[('enzo', 'Ex')].nodal_flag)
     print(ad['raw', 'Ex'].shape)


https://bitbucket.org/yt_analysis/yt/commits/52d4fc449452/
Changeset:   52d4fc449452
User:        ngoldbaum
Date:        2017-06-01 20:50:16+00:00
Summary:     responding to kacper comments
Affected #:  3 files

diff -r f96c4dda87bd1b4ca1d5856afce9b0af793ace37 -r 52d4fc44945238dfa4e1f732b77612f376e8d784 doc/source/examining/loading_data.rst
--- a/doc/source/examining/loading_data.rst
+++ b/doc/source/examining/loading_data.rst
@@ -360,6 +360,7 @@
 
 .. code-block:: python
 
+    ds.index
     ad = ds.all_data()
     print(ds.field_info[('raw', 'Ex')].nodal_flag)
     print(ad['raw', 'Ex'].shape)
@@ -461,6 +462,7 @@
 
 .. code-block:: python
 
+    ds.index
     ad = ds.all_data()
     print(ds.field_info[('enzo', 'Ex')].nodal_flag)
     print(ad['raw', 'Ex'].shape)

diff -r f96c4dda87bd1b4ca1d5856afce9b0af793ace37 -r 52d4fc44945238dfa4e1f732b77612f376e8d784 yt/frontends/enzo/io.py
--- a/yt/frontends/enzo/io.py
+++ b/yt/frontends/enzo/io.py
@@ -131,9 +131,7 @@
                     filename = obj.filename
                 for field in fields:
                     nodal_flag = self.ds.field_info[field].nodal_flag
-                    dims = obj.ActiveDimensions[::-1].copy()
-                    if np.any(nodal_flag):
-                        dims += nodal_flag[::-1]
+                    dims = obj.ActiveDimensions[::-1] + nodal_flag[::-1]
                     data = np.empty(dims, dtype=h5_dtype)
                     yield field, obj, self._read_obj_field(
                         obj, field, (fid, data))

diff -r f96c4dda87bd1b4ca1d5856afce9b0af793ace37 -r 52d4fc44945238dfa4e1f732b77612f376e8d784 yt/utilities/io_handler.py
--- a/yt/utilities/io_handler.py
+++ b/yt/utilities/io_handler.py
@@ -141,7 +141,7 @@
         for field, obj, data in self.io_iter(chunks, fields):
             if data is None:
                 continue
-            if selector.__class__ is GridSelector and field not in nodal_fields:
+            if isinstance(selector, GridSelector) and field not in nodal_fields:
                 ind[field] += data.size
                 rv[field] = data.copy()
             else:


https://bitbucket.org/yt_analysis/yt/commits/d42a44001c65/
Changeset:   d42a44001c65
User:        ngoldbaum
Date:        2017-06-02 14:30:31+00:00
Summary:     don't use try/except when setting nodal flag
Affected #:  1 file

diff -r 52d4fc44945238dfa4e1f732b77612f376e8d784 -r d42a44001c65ffed6fecef209a654cc2d06fa959 yt/frontends/enzo/fields.py
--- a/yt/frontends/enzo/fields.py
+++ b/yt/frontends/enzo/fields.py
@@ -141,12 +141,9 @@
 
         # setup nodal flag information
         for field in NODAL_FLAGS:
-            try:
+            if ('enzo', field) in self:
                 finfo = self['enzo', field]
                 finfo.nodal_flag = np.array(NODAL_FLAGS[field])
-            except KeyError:
-                pass
-
 
     def add_species_field(self, species):
         # This is currently specific to Enzo.  Hopefully in the future we will


https://bitbucket.org/yt_analysis/yt/commits/af2ab51ff9a6/
Changeset:   af2ab51ff9a6
User:        ngoldbaum
Date:        2017-06-02 14:33:49+00:00
Summary:     tweak doc language
Affected #:  1 file

diff -r d42a44001c65ffed6fecef209a654cc2d06fa959 -r af2ab51ff9a67b73ba330bbbe00fbe69f28e3101 doc/source/examining/loading_data.rst
--- a/doc/source/examining/loading_data.rst
+++ b/doc/source/examining/loading_data.rst
@@ -446,19 +446,20 @@
 Enzo MHDCT data
 ^^^^^^^^^^^^^^^
 
-The electric and magnetic fields for Enzo MHDCT simulations are not
-face-centered. In yt, we call fields like this "nodal".  We define a field to be
-"nodal" in a given direction if the field data is defined at the "low" and
-"high" sides of the cell in that direction, rather than at the cell center.
-Instead of returning one field value per cell selected, nodal fields return a
-number of values, depending on their centering. This centering is marked by a
-`nodal_flag` that describes whether the fields is nodal in each dimension.
-``nodal_flag = [0, 0, 0]`` means that the field is cell-centered, while
-``nodal_flag = [0, 0, 1]`` means that the field is nodal in the z direction and
-cell centered in the others, i.e. it is defined on the z faces of each cell.
-``nodal_flag = [1, 1, 0]`` would mean that the field is centered in the z
-direction, but nodal in the other two, i.e. it lives on the four cell edges that
-are normal to the z direction.
+The electric and magnetic fields for Enzo MHDCT simulations are defined on cell
+faces, unlike other Enzo fields which are defined at cell centers. In yt, we
+call face-centered fields like this "nodal".  We define a field to be nodal in
+a given direction if the field data is defined at the "low" and "high" sides of
+the cell in that direction, rather than at the cell center.  Instead of
+returning one field value per cell selected, nodal fields return a number of
+values, depending on their centering. This centering is marked by a `nodal_flag`
+that describes whether the fields is nodal in each dimension.  ``nodal_flag =
+[0, 0, 0]`` means that the field is cell-centered, while ``nodal_flag = [0, 0,
+1]`` means that the field is nodal in the z direction and cell centered in the
+others, i.e. it is defined on the z faces of each cell.  ``nodal_flag = [1, 1,
+0]`` would mean that the field is centered in the z direction, but nodal in the
+other two, i.e. it lives on the four cell edges that are normal to the z
+direction.
 
 .. code-block:: python
 


https://bitbucket.org/yt_analysis/yt/commits/f2925547d940/
Changeset:   f2925547d940
User:        MatthewTurk
Date:        2017-06-02 17:58:39+00:00
Summary:     Merge pull request #1438 from ngoldbaum/enzo-mhdct-fields

Add support for Enzo MHDCT fields
Affected #:  10 files

diff -r c831eed47a1848eb77ea608c2b55671485793851 -r f2925547d940ca97bca52843c31b0293cf35453c doc/source/examining/loading_data.rst
--- a/doc/source/examining/loading_data.rst
+++ b/doc/source/examining/loading_data.rst
@@ -358,7 +358,9 @@
 but nodal in the other two, i.e. it lives on the four cell edges that are normal
 to the z direction.
 
-..code-block:: python
+.. code-block:: python
+
+    ds.index
     ad = ds.all_data()
     print(ds.field_info[('raw', 'Ex')].nodal_flag)
     print(ad['raw', 'Ex'].shape)
@@ -440,6 +442,46 @@
   of length 1.0 in "code length" which may produce strange results for volume
   quantities.
 
+
+Enzo MHDCT data
+^^^^^^^^^^^^^^^
+
+The electric and magnetic fields for Enzo MHDCT simulations are defined on cell
+faces, unlike other Enzo fields which are defined at cell centers. In yt, we
+call face-centered fields like this "nodal".  We define a field to be nodal in
+a given direction if the field data is defined at the "low" and "high" sides of
+the cell in that direction, rather than at the cell center.  Instead of
+returning one field value per cell selected, nodal fields return a number of
+values, depending on their centering. This centering is marked by a `nodal_flag`
+that describes whether the fields is nodal in each dimension.  ``nodal_flag =
+[0, 0, 0]`` means that the field is cell-centered, while ``nodal_flag = [0, 0,
+1]`` means that the field is nodal in the z direction and cell centered in the
+others, i.e. it is defined on the z faces of each cell.  ``nodal_flag = [1, 1,
+0]`` would mean that the field is centered in the z direction, but nodal in the
+other two, i.e. it lives on the four cell edges that are normal to the z
+direction.
+
+.. code-block:: python
+
+    ds.index
+    ad = ds.all_data()
+    print(ds.field_info[('enzo', 'Ex')].nodal_flag)
+    print(ad['raw', 'Ex'].shape)
+    print(ds.field_info[('enzo', 'BxF')].nodal_flag)
+    print(ad['raw', 'Bx'].shape)
+    print(ds.field_info[('enzo', 'Bx')].nodal_flag)
+    print(ad['boxlib', 'Bx'].shape)
+
+Here, the field ``('enzo', 'Ex')`` is nodal in two directions, so four values
+per cell are returned, corresponding to the four edges in each cell on which the
+variable is defined. ``('enzo', 'BxF')`` is nodal in one direction, so two
+values are returned per cell. The standard, non-nodal field ``('enzo', 'Bx')``
+is also available.
+
+Currently, slices and data selection are implemented for nodal
+fields. Projections, volume rendering, and many of the analysis modules will not
+work.
+
 .. _loading-exodusii-data:
 
 Exodus II Data

diff -r c831eed47a1848eb77ea608c2b55671485793851 -r f2925547d940ca97bca52843c31b0293cf35453c yt/frontends/boxlib/io.py
--- a/yt/frontends/boxlib/io.py
+++ b/yt/frontends/boxlib/io.py
@@ -21,6 +21,7 @@
     BaseIOHandler
 from yt.funcs import mylog
 from yt.frontends.chombo.io import parse_orion_sinks
+from yt.geometry.selection_routines import GridSelector
 
 def _remove_raw(all_fields, raw_fields):
     centered_fields = set(all_fields)
@@ -232,7 +233,7 @@
         rv = {}
         chunks = list(chunks)
 
-        if selector.__class__.__name__ == "GridSelector":
+        if isinstance(selector, GridSelector):
 
             if not (len(chunks) == len(chunks[0].objs) == 1):
                 raise RuntimeError

diff -r c831eed47a1848eb77ea608c2b55671485793851 -r f2925547d940ca97bca52843c31b0293cf35453c yt/frontends/chombo/io.py
--- a/yt/frontends/chombo/io.py
+++ b/yt/frontends/chombo/io.py
@@ -15,8 +15,10 @@
 
 import re
 import numpy as np
-from yt.utilities.logger import ytLogger as mylog
-
+from yt.geometry.selection_routines import \
+    GridSelector
+from yt.utilities.logger import \
+    ytLogger as mylog
 from yt.utilities.io_handler import \
     BaseIOHandler
 
@@ -116,7 +118,7 @@
         rv = {}
         chunks = list(chunks)
         fields.sort(key=lambda a: self.field_dict[a[1]])
-        if selector.__class__.__name__ == "GridSelector":
+        if isinstance(selector, GridSelector):
             if not (len(chunks) == len(chunks[0].objs) == 1):
                 raise RuntimeError
             grid = chunks[0].objs[0]
@@ -149,7 +151,7 @@
         rv = {}
         chunks = list(chunks)
 
-        if selector.__class__.__name__ == "GridSelector":
+        if isinstance(selector, GridSelector):
 
             if not (len(chunks) == len(chunks[0].objs) == 1):
                 raise RuntimeError

diff -r c831eed47a1848eb77ea608c2b55671485793851 -r f2925547d940ca97bca52843c31b0293cf35453c yt/frontends/enzo/fields.py
--- a/yt/frontends/enzo/fields.py
+++ b/yt/frontends/enzo/fields.py
@@ -13,6 +13,7 @@
 # The full license is in the file COPYING.txt, distributed with this software.
 #-----------------------------------------------------------------------------
 
+import numpy as np
 from yt.fields.field_info_container import \
     FieldInfoContainer
 from yt.utilities.physical_constants import \
@@ -20,6 +21,7 @@
     mp
 
 b_units = "code_magnetic"
+e_units = "code_magnetic/c"
 ra_units = "code_length / code_time**2"
 rho_units = "code_mass / code_length**3"
 vel_units = "code_velocity"
@@ -49,6 +51,18 @@
     'OIX'     : 'O_p8',
 }
 
+NODAL_FLAGS = {
+    'BxF': [1, 0, 0],
+    'ByF': [0, 1, 0],
+    'BzF': [0, 0, 1],
+    'Ex': [0, 1, 1],
+    'Ey': [1, 0, 1],
+    'Ez': [1, 1, 0],
+    'AvgElec0': [0, 1, 1],
+    'AvgElec1': [1, 0, 1],
+    'AvgElec2': [1, 1, 0],
+}
+
 class EnzoFieldInfo(FieldInfoContainer):
     known_other_fields = (
         ("Cooling_Time", ("s", ["cooling_time"], None)),
@@ -63,6 +77,15 @@
         ("Bx", (b_units, [], None)),
         ("By", (b_units, [], None)),
         ("Bz", (b_units, [], None)),
+        ("BxF", (b_units, [], None)),
+        ("ByF", (b_units, [], None)),
+        ("BzF", (b_units, [], None)),
+        ("Ex", (e_units, [], None)),
+        ("Ey", (e_units, [], None)),
+        ("Ez", (e_units, [], None)),
+        ("AvgElec0", (e_units, [], None)),
+        ("AvgElec1", (e_units, [], None)),
+        ("AvgElec2", (e_units, [], None)),
         ("RadAccel1", (ra_units, ["radiation_acceleration_x"], None)),
         ("RadAccel2", (ra_units, ["radiation_acceleration_y"], None)),
         ("RadAccel3", (ra_units, ["radiation_acceleration_z"], None)),
@@ -116,6 +139,12 @@
         slice_info = (sl_left, sl_right, div_fac)
         super(EnzoFieldInfo, self).__init__(ds, field_list, slice_info)
 
+        # setup nodal flag information
+        for field in NODAL_FLAGS:
+            if ('enzo', field) in self:
+                finfo = self['enzo', field]
+                finfo.nodal_flag = np.array(NODAL_FLAGS[field])
+
     def add_species_field(self, species):
         # This is currently specific to Enzo.  Hopefully in the future we will
         # have deeper integration with other systems, such as Dengo, to provide

diff -r c831eed47a1848eb77ea608c2b55671485793851 -r f2925547d940ca97bca52843c31b0293cf35453c yt/frontends/enzo/io.py
--- a/yt/frontends/enzo/io.py
+++ b/yt/frontends/enzo/io.py
@@ -18,7 +18,7 @@
 from yt.utilities.logger import ytLogger as mylog
 from yt.extern.six import b, iteritems
 from yt.utilities.on_demand_imports import _h5py as h5py
-
+from yt.geometry.selection_routines import GridSelector
 import numpy as np
 
 
@@ -129,13 +129,16 @@
                         fid.close()
                     fid = h5py.h5f.open(b(obj.filename), h5py.h5f.ACC_RDONLY)
                     filename = obj.filename
-                data = np.empty(obj.ActiveDimensions[::-1], dtype=h5_dtype)
                 for field in fields:
-                    yield field, obj, self._read_obj_field(obj, field, (fid, data))
+                    nodal_flag = self.ds.field_info[field].nodal_flag
+                    dims = obj.ActiveDimensions[::-1] + nodal_flag[::-1]
+                    data = np.empty(dims, dtype=h5_dtype)
+                    yield field, obj, self._read_obj_field(
+                        obj, field, (fid, data))
         if fid is not None:
             fid.close()
         
-    def _read_obj_field(self, obj, field, fid_data = None):
+    def _read_obj_field(self, obj, field, fid_data):
         if fid_data is None: fid_data = (None, None)
         fid, data = fid_data
         if fid is None:
@@ -212,7 +215,7 @@
         rv = {}
         # Now we have to do something unpleasant
         chunks = list(chunks)
-        if selector.__class__.__name__ == "GridSelector":
+        if isinstance(selector, GridSelector):
             if not (len(chunks) == len(chunks[0].objs) == 1):
                 raise RuntimeError
             g = chunks[0].objs[0]
@@ -294,7 +297,7 @@
         rv = {}
         # Now we have to do something unpleasant
         chunks = list(chunks)
-        if selector.__class__.__name__ == "GridSelector":
+        if isinstance(selector, GridSelector):
             if not (len(chunks) == len(chunks[0].objs) == 1):
                 raise RuntimeError
             g = chunks[0].objs[0]

diff -r c831eed47a1848eb77ea608c2b55671485793851 -r f2925547d940ca97bca52843c31b0293cf35453c yt/frontends/enzo/tests/test_outputs.py
--- a/yt/frontends/enzo/tests/test_outputs.py
+++ b/yt/frontends/enzo/tests/test_outputs.py
@@ -29,6 +29,7 @@
     AnalyticHaloMassFunctionTest, \
     SimulatedHaloMassFunctionTest
 from yt.frontends.enzo.api import EnzoDataset
+from yt.frontends.enzo.fields import NODAL_FLAGS
 
 _fields = ("temperature", "density", "velocity_magnitude",
            "velocity_divergence")
@@ -40,6 +41,7 @@
 enzotiny = "enzo_tiny_cosmology/DD0046/DD0046"
 toro1d = "ToroShockTube/DD0001/data0001"
 kh2d = "EnzoKelvinHelmholtz/DD0011/DD0011"
+mhdctot = "MHDCTOrszagTang/DD0004/data0004"
 
 def check_color_conservation(ds):
     species_names = ds.field_info.species_names
@@ -172,3 +174,20 @@
 
     assert_equal(apcos.particle_type_counts,
                  {'CenOstriker': 899755, 'DarkMatter': 32768})
+
+ at requires_file(mhdctot)
+def test_face_centered_mhdct_fields():
+    ds = data_dir_load(mhdctot)
+
+    ad = ds.all_data()
+    grid = ds.index.grids[0]
+
+    for field, flag in NODAL_FLAGS.items():
+        dims = ds.domain_dimensions
+        assert_equal(ad[field].shape, (dims.prod(), 2*sum(flag)))
+        assert_equal(grid[field].shape, tuple(dims) + (2*sum(flag),))
+
+    # Average of face-centered fields should be the same as cell-centered field
+    assert (ad['BxF'].sum(axis=-1)/2 == ad['Bx']).all()
+    assert (ad['ByF'].sum(axis=-1)/2 == ad['By']).all()
+    assert (ad['BzF'].sum(axis=-1)/2 == ad['Bz']).all()

diff -r c831eed47a1848eb77ea608c2b55671485793851 -r f2925547d940ca97bca52843c31b0293cf35453c yt/frontends/gdf/io.py
--- a/yt/frontends/gdf/io.py
+++ b/yt/frontends/gdf/io.py
@@ -17,6 +17,7 @@
 from yt.utilities.on_demand_imports import _h5py as h5py
 from yt.funcs import \
     mylog
+from yt.geometry.selection_routines import GridSelector
 from yt.utilities.io_handler import \
     BaseIOHandler
 
@@ -40,7 +41,7 @@
         rv = {}
         chunks = list(chunks)
 
-        if selector.__class__.__name__ == "GridSelector":
+        if isinstance(selector, GridSelector):
             if not (len(chunks) == len(chunks[0].objs) == 1):
                 raise RuntimeError
             grid = chunks[0].objs[0]

diff -r c831eed47a1848eb77ea608c2b55671485793851 -r f2925547d940ca97bca52843c31b0293cf35453c yt/frontends/open_pmd/io.py
--- a/yt/frontends/open_pmd/io.py
+++ b/yt/frontends/open_pmd/io.py
@@ -22,6 +22,7 @@
 from yt.frontends.open_pmd.misc import \
     is_const_component, \
     get_component
+from yt.geometry.selection_routines import GridSelector
 from yt.utilities.io_handler import BaseIOHandler
 
 
@@ -178,7 +179,7 @@
         rv = {}
         ind = {}
 
-        if selector.__class__.__name__ == "GridSelector":
+        if isinstance(selector, GridSelector):
             if not (len(chunks) == len(chunks[0].objs) == 1):
                 raise RuntimeError
 

diff -r c831eed47a1848eb77ea608c2b55671485793851 -r f2925547d940ca97bca52843c31b0293cf35453c yt/frontends/ytdata/io.py
--- a/yt/frontends/ytdata/io.py
+++ b/yt/frontends/ytdata/io.py
@@ -20,6 +20,8 @@
     u
 from yt.funcs import \
     mylog
+from yt.geometry.selection_routines import \
+    GridSelector
 from yt.utilities.exceptions import \
     YTDomainOverflow
 from yt.utilities.io_handler import \
@@ -36,7 +38,7 @@
 
     def _read_fluid_selection(self, g, selector, fields):
         rv = {}
-        if selector.__class__.__name__ == "GridSelector":
+        if isinstance(selector, GridSelector):
             if g.id in self._cached_fields:
                 gf = self._cached_fields[g.id]
                 rv.update(gf)
@@ -68,7 +70,7 @@
         rv = {}
         # Now we have to do something unpleasant
         chunks = list(chunks)
-        if selector.__class__.__name__ == "GridSelector":
+        if isinstance(selector, GridSelector):
             if not (len(chunks) == len(chunks[0].objs) == 1):
                 raise RuntimeError
             g = chunks[0].objs[0]

diff -r c831eed47a1848eb77ea608c2b55671485793851 -r f2925547d940ca97bca52843c31b0293cf35453c yt/utilities/io_handler.py
--- a/yt/utilities/io_handler.py
+++ b/yt/utilities/io_handler.py
@@ -22,6 +22,7 @@
 from yt.extern.six import add_metaclass
 from yt.utilities.lru_cache import \
     local_lru_cache, _make_key
+from yt.geometry.selection_routines import GridSelector
 
 _axis_ids = {0:2,1:1,2:0}
 
@@ -125,15 +126,26 @@
         # rewrite a whole bunch of IO handlers all at once, and to allow a
         # better abstraction for grid-based frontends, we're now defining it in
         # the base class.
-        rv = {field: np.empty(size, dtype="=f8") for field in fields} 
+        rv = {}
+        nodal_fields = []
+        for field in fields:
+            finfo = self.ds.field_info[field]
+            nodal_flag = finfo.nodal_flag
+            if np.any(nodal_flag):
+                num_nodes = 2**sum(nodal_flag)
+                rv[field] = np.empty((size, num_nodes), dtype="=f8")
+                nodal_fields.append(field)
+            else:
+                rv[field] = np.empty(size, dtype="=f8")
         ind = {field: 0 for field in fields}
         for field, obj, data in self.io_iter(chunks, fields):
-            if data is None: continue
-            if selector.__class__.__name__ == "GridSelector":
+            if data is None:
+                continue
+            if isinstance(selector, GridSelector) and field not in nodal_fields:
                 ind[field] += data.size
                 rv[field] = data.copy()
-                continue
-            ind[field] += obj.select(selector, data, rv[field], ind[field])
+            else:
+                ind[field] += obj.select(selector, data, rv[field], ind[field])
         return rv
 
     def _read_data_slice(self, grid, field, axis, coord):

Repository URL: https://bitbucket.org/yt_analysis/yt/

--

This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.


More information about the yt-svn mailing list