From 46f666e7dfc22625c24430b1513745271ae51ff5 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Sun, 26 Jun 2022 16:04:35 -0700 Subject: [PATCH 01/45] remove setup.py in favor of setup.cfg and pyproject.toml --- src/addon/ESMPy/.gitignore | 2 ++ src/addon/ESMPy/pyproject.toml | 24 ++++++++++++++ src/addon/ESMPy/setup.cfg | 32 +++++++++++++++++++ src/addon/ESMPy/{setup.py => setup.py.old} | 0 .../ESMPy/src/ESMF/interface/loadESMF.py | 32 ++++++++++++++----- 5 files changed, 82 insertions(+), 8 deletions(-) create mode 100644 src/addon/ESMPy/pyproject.toml create mode 100644 src/addon/ESMPy/setup.cfg rename src/addon/ESMPy/{setup.py => setup.py.old} (100%) diff --git a/src/addon/ESMPy/.gitignore b/src/addon/ESMPy/.gitignore index 238fdcd5b7..15e6c72411 100644 --- a/src/addon/ESMPy/.gitignore +++ b/src/addon/ESMPy/.gitignore @@ -28,8 +28,10 @@ PET* # ESMPy build and docs # ######################## build +dist doc/esmpy_doc src/ESMF/interface/esmfmkfile.py +src/ESMPy.egg-info examples/data src/ESMF/test/data examples/notebooks/ESMPy-data diff --git a/src/addon/ESMPy/pyproject.toml b/src/addon/ESMPy/pyproject.toml new file mode 100644 index 0000000000..894c1b3a35 --- /dev/null +++ b/src/addon/ESMPy/pyproject.toml @@ -0,0 +1,24 @@ +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +# [project] +# name = "ESMPy" +# description = "ESMF Python interface" +# license = {text = "University of Illinois-NCSA"} +# readme = "README.md" +# # dynamic = ["version"] +# dependencies = [ +# "numpy", +# ] +# +# [tool.setuptools.packages.find] +# where = ["src"] +# exclude = [ +# "ESMPy.doc*", +# "ESMPy.example*", +# "ESMPy.test*", +# ] +# +# [tool.setuptools.dynamic] +# version = {attr = "ESMPy.VERSION"} diff --git a/src/addon/ESMPy/setup.cfg b/src/addon/ESMPy/setup.cfg new file mode 100644 index 0000000000..ccbdd01a94 --- /dev/null +++ b/src/addon/ESMPy/setup.cfg @@ -0,0 +1,32 @@ +[metadata] +name = ESMPy +version = 8.4.0 +description = ESMF Python interface +long_description = file: README.md, LICENSE +license = University of Illinois-NCSA +author = University Corporation for Atmospheric Research, + Massachusetts Institute of Technology, + Geophysical Fluid Dynamics Laboratory, + University of Michigan, + National Centers for Environmental Prediction, + Los Alamos National Laboratory, + Argonne National Laboratory, + NASA Goddard Space Flight Center +author_email = "esmf_support@ucar.edu", +url="http://earthsystemmodeling.org/esmpy/", + + +[options] +zip_safe = False +include_package_data = True +packages = find: +install_requires = + numpy + + +[options.packages.find] +where=src +exclude = + doc* + examples* + test* diff --git a/src/addon/ESMPy/setup.py b/src/addon/ESMPy/setup.py.old similarity index 100% rename from src/addon/ESMPy/setup.py rename to src/addon/ESMPy/setup.py.old diff --git a/src/addon/ESMPy/src/ESMF/interface/loadESMF.py b/src/addon/ESMPy/src/ESMF/interface/loadESMF.py index c10bd60fbc..ca5395f4a3 100644 --- a/src/addon/ESMPy/src/ESMF/interface/loadESMF.py +++ b/src/addon/ESMPy/src/ESMF/interface/loadESMF.py @@ -8,21 +8,37 @@ import ESMF.api.constants as constants -try: - from ESMF.interface.esmfmkfile import ESMFMKFILE as esmfmk -except: - raise ImportError('The ESMFMKFILE cannot be found!') - try: import numpy as np except: - raise ImportError('The Numpy library cannot be found!') + raise ImportError('The Numpy library cannot be found.') # this library is loaded here so that it can be pulled back up without sys try: import ctypes as ct except: - raise ImportError('The CTypes library cannot be found!') + raise ImportError('The CTypes library cannot be found.') + +esmfmk = None +mked = False +esmfmkfile_local = os.path.join(os.getcwd(),"src/ESMF/interface/esmfmkfile.py") +try: + + if os.path.isfile(esmfmkfile_local): + from ESMF.interface.esmfmkfile import ESMFMKFILE as esmfmk + mked = True +except: + raise ImportError('The esmf.mk file could not be loaded.') +else: + if not mked: + esmfmk = os.getenv("ESMFMKFILE") + if not esmfmk: + raise ImportError('The ESMFMKFILE was not set in the build, nor is it available as an environment variable.') + else: + with open(esmfmkfile_local, 'w') as emfl: + emfl.write('ESMFMKFILE = "'+esmfmk+'"') + emfl.close() + #### INVESTIGATE esmf.mk ###################################################### @@ -134,4 +150,4 @@ mode=ct.RTLD_GLOBAL) except: traceback.print_exc(file=sys.stdout) - raise ImportError('The ESMF shared library did not load properly.') \ No newline at end of file + raise ImportError('The ESMF shared library did not load properly.') From 9c6ea6096a19683eaa2a7a8f267cfb6135e70015 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Sun, 26 Jun 2022 16:04:49 -0700 Subject: [PATCH 02/45] remove setup.py in favor of setup.cfg and pyproject.toml --- src/addon/ESMPy/setup.cfg | 3 +++ src/addon/ESMPy/src/ESMF/test/test_api/test_grid.py | 1 - src/addon/ESMPy/src/ESMF/util/decorators.py | 1 - 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/addon/ESMPy/setup.cfg b/src/addon/ESMPy/setup.cfg index ccbdd01a94..f6e962c30e 100644 --- a/src/addon/ESMPy/setup.cfg +++ b/src/addon/ESMPy/setup.cfg @@ -30,3 +30,6 @@ exclude = doc* examples* test* + +[nosetests] +attr=!slow,!data diff --git a/src/addon/ESMPy/src/ESMF/test/test_api/test_grid.py b/src/addon/ESMPy/src/ESMF/test/test_api/test_grid.py index d70e8f6a9f..0c6fff2995 100644 --- a/src/addon/ESMPy/src/ESMF/test/test_api/test_grid.py +++ b/src/addon/ESMPy/src/ESMF/test/test_api/test_grid.py @@ -862,4 +862,3 @@ def test_grid_create_from_file_scrip_decomp_cyclic_cyclic(self): reg_decomp=reg_decomp, decompflag=decompflag) except: raise NameError('grid_create_from_file_scrip_cyclic_cyclic failed!') - diff --git a/src/addon/ESMPy/src/ESMF/util/decorators.py b/src/addon/ESMPy/src/ESMF/util/decorators.py index 8d1b351e4e..2c98ad8cd2 100644 --- a/src/addon/ESMPy/src/ESMF/util/decorators.py +++ b/src/addon/ESMPy/src/ESMF/util/decorators.py @@ -95,4 +95,3 @@ def new_func(*args, **kwargs): raise NetCDFMissing("This function requires ESMF to have been built with NetCDF.") return new_func - From 89566eed513d2f7c8c11f3341537910e0a57d0c1 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Fri, 8 Jul 2022 10:13:50 -0600 Subject: [PATCH 03/45] fix pip build for ESMPy on Cheyenne --- src/addon/ESMPy/setup.cfg | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/addon/ESMPy/setup.cfg b/src/addon/ESMPy/setup.cfg index f6e962c30e..b15f9fb68c 100644 --- a/src/addon/ESMPy/setup.cfg +++ b/src/addon/ESMPy/setup.cfg @@ -19,6 +19,8 @@ url="http://earthsystemmodeling.org/esmpy/", [options] zip_safe = False include_package_data = True +package_dir= + =src packages = find: install_requires = numpy From 12fcb3f7a81d72dd6e6b80ca6884521a637ecdc1 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Thu, 21 Jul 2022 10:12:22 -0700 Subject: [PATCH 04/45] modify doc to reflect pip installation process --- src/addon/ESMPy/doc/install.rst | 34 ++++++++------------------------- 1 file changed, 8 insertions(+), 26 deletions(-) diff --git a/src/addon/ESMPy/doc/install.rst b/src/addon/ESMPy/doc/install.rst index 7c767bcccd..aec7b904b6 100644 --- a/src/addon/ESMPy/doc/install.rst +++ b/src/addon/ESMPy/doc/install.rst @@ -17,7 +17,7 @@ The following packages are *optional*: * ESMF installation with NetCDF - required to create :class:`Grids ` and :class:`Meshes ` from file - NetCDF must be built as a shared library for ESMPy installation to succeed * `mpi4py `_- python bindings to MPI, needed to run some of the parallel regridding examples -* `nose `_ - for nose testing +* `nose2 `_ - for nose testing ---------------- Getting the code @@ -59,40 +59,24 @@ Development versions can be found in the ``esmpy_dev`` channel: Installing ESMPy from Source ---------------------------- -When installing from source, ESMPy requires a pointer to a file named esmf.mk -that is generated during an ESMF installation. The path of this file is: +When installing from source, ESMPy uses `pip `_ +to build and install the package. This requires setting an environment variable +pointing to a file named esmf.mk that is generated during an ESMF installation. +The path of this file is: .. code:: /lib/libO>//esmf.mk -If the ``ESMFMKFILE`` flag is set when building ESMPy then it will not need to be -referenced again. If not, an environment variable of the same name must be set -with the path to the esmf.mk file every time a new shell is initiated. - -ESMPy can be installed in a custom location using the -``--prefix``, ``--home``, or ``--install-base`` flags to the install command. If this -is done, then this location needs to be added to the ``PYTHONPATH`` environment -variable every time a new shell is initiated. If a -custom install location is not specified, ESMPy will be installed in the -standard Python package installation directory on that particular machine. +If ``ESMFMKFILE`` is set when building ESMPy then it will not need to be +referenced again. An installation of ESMPy in the default location for Python packages can be done with the following command issued from the top level ESMPy directory: .. code:: - python setup.py build --ESMFMKFILE=/esmf.mk install - -- custom install location: - -.. code:: - - python setup.py build --ESMFMKFILE=/esmf.mk - - python setup.py install --prefix= - - setenv PYTHONPATH /lib/\*/site_packages + pip install . Please contact esmf_support@ucar.edu with any questions. @@ -172,5 +156,3 @@ Testing related: - Nightly regression testing is limited to a small subset of the ESMF test platforms, including Darwin and Linux running gfortran with openMPI. - - From 1bd8b61908321b7966a7018ca9ea3609851fed2d Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Thu, 21 Jul 2022 10:13:27 -0700 Subject: [PATCH 05/45] temporarily remove slow tests and add unittest.expected_failure tags --- src/addon/ESMPy/examples/exampletest.py | 2 +- src/addon/ESMPy/setup.cfg | 2 +- .../src/ESMF/test/test_api/test_field.py | 6 +++--- .../ESMPy/src/ESMF/test/test_api/test_grid.py | 19 ++++++++++--------- .../src/ESMF/test/test_api/test_locstream.py | 6 ++++-- .../ESMPy/src/ESMF/test/test_api/test_mesh.py | 4 +++- .../ESMPy/src/ESMF/test/test_cbindings.py | 5 +++-- 7 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/addon/ESMPy/examples/exampletest.py b/src/addon/ESMPy/examples/exampletest.py index 5bfbf8d32f..a6f57047a6 100644 --- a/src/addon/ESMPy/examples/exampletest.py +++ b/src/addon/ESMPy/examples/exampletest.py @@ -60,7 +60,7 @@ def test_regrid_from_file(self): # only example, not in documentation @attr('slow') - def test_tripole_regrid(self): + def _tripole_regrid(self): from . import tripole_regrid # only example, not in documentation diff --git a/src/addon/ESMPy/setup.cfg b/src/addon/ESMPy/setup.cfg index b15f9fb68c..c492282869 100644 --- a/src/addon/ESMPy/setup.cfg +++ b/src/addon/ESMPy/setup.cfg @@ -24,7 +24,7 @@ package_dir= packages = find: install_requires = numpy - + nose2 [options.packages.find] where=src diff --git a/src/addon/ESMPy/src/ESMF/test/test_api/test_field.py b/src/addon/ESMPy/src/ESMF/test/test_api/test_field.py index e69d2baa5f..e06c28c1f6 100644 --- a/src/addon/ESMPy/src/ESMF/test/test_api/test_field.py +++ b/src/addon/ESMPy/src/ESMF/test/test_api/test_field.py @@ -100,7 +100,7 @@ def test_numpy_funcs(self): @attr('serial') @attr('slow') #nosetests src/ESMF/test/test_api/test_field.py:TestField.test_field_create_2d_grid - def test_field_create_2d_grid(self): + def _field_create_2d_grid(self): keywords = dict( # periodic specifies all valid combos of [num_peri_dims, periodic_dim, pole_dim] periodic=[[None, None, None], [None, None, 0], [None, None, 1], @@ -150,7 +150,7 @@ def test_field_create_2d_grid(self): @attr('serial') @attr('slow') - def test_field_create_3d_grid(self): + def _field_create_3d_grid(self): keywords = dict( # periodic specifies all valid combos of [num_peri_dims, periodic_dim, pole_dim] periodic=[[None, None, None], [None, None, 0], [None, None, 1], [None, None, 2], @@ -201,7 +201,7 @@ def test_field_create_3d_grid(self): "The following combinations of parameters failed to create a proper Field: " + str(len(fail))) @attr('slow') - def test_field_create_2d_mesh(self): + def _field_create_2d_mesh(self): parallel = False if pet_count() > 1: parallel = True diff --git a/src/addon/ESMPy/src/ESMF/test/test_api/test_grid.py b/src/addon/ESMPy/src/ESMF/test/test_api/test_grid.py index 0c6fff2995..11cca7fe5d 100644 --- a/src/addon/ESMPy/src/ESMF/test/test_api/test_grid.py +++ b/src/addon/ESMPy/src/ESMF/test/test_api/test_grid.py @@ -11,6 +11,7 @@ import numpy as np import os import inspect +import unittest class TestGrid(TestBase): @@ -179,7 +180,7 @@ def test_grid_periodic(self): @attr('serial') @attr('slow') - def test_grid_create_2d(self): + def _grid_create_2d(self): keywords = dict( # periodic specifies all valid combos of [pole_kind, num_peri_dims, periodic_dim, pole_dim] pole_kind=[[PoleKind.NONE, PoleKind.NONE], @@ -225,7 +226,7 @@ def test_grid_create_2d(self): @attr('serial') @attr('slow') - def test_grid_create_3d(self): + def _grid_create_3d(self): keywords = dict( # periodic specifies all valid combos of [num_peri_dims, periodic_dim, pole_dim] periodic=[[None, None, None], [None, None, 0], [None, None, 1], [None, None, 2], @@ -688,7 +689,7 @@ def test_grid_create_from_file_scrip_decomp_balanced_restlast(self): raise NameError('grid_create_from_file_scrip_balanced_restlast failed!') @attr('data') - @expected_failure + @unittest.expectedFailure def test_grid_create_from_file_scrip_decomp_balanced_cyclic(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.BALANCED, DecompFlag.CYCLIC], @@ -741,7 +742,7 @@ def test_grid_create_from_file_scrip_decomp_restfirst_restlast(self): raise NameError('grid_create_from_file_scrip_restfirst_restlast failed!') @attr('data') - @expected_failure + @unittest.expectedFailure def test_grid_create_from_file_scrip_decomp_restfirst_cyclic(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.RESTFIRST, DecompFlag.CYCLIC], @@ -794,7 +795,7 @@ def test_grid_create_from_file_scrip_decomp_restlast_restlast(self): raise NameError('grid_create_from_file_scrip_restlast_restlast failed!') @attr('data') - @expected_failure + @unittest.expectedFailure def test_grid_create_from_file_scrip_decomp_restlast_cyclic(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.RESTLAST, DecompFlag.CYCLIC], @@ -808,7 +809,7 @@ def test_grid_create_from_file_scrip_decomp_restlast_cyclic(self): raise NameError('grid_create_from_file_scrip_restlast_cyclic failed!') @attr('data') - @expected_failure + @unittest.expectedFailure def test_grid_create_from_file_scrip_decomp_cyclic_balanced(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.CYCLIC, DecompFlag.BALANCED], @@ -822,7 +823,7 @@ def test_grid_create_from_file_scrip_decomp_cyclic_balanced(self): raise NameError('grid_create_from_file_scrip_cyclic_balanced failed!') @attr('data') - @expected_failure + @unittest.expectedFailure def test_grid_create_from_file_scrip_decomp_cyclic_restfirst(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.CYCLIC, DecompFlag.RESTFIRST], @@ -836,7 +837,7 @@ def test_grid_create_from_file_scrip_decomp_cyclic_restfirst(self): raise NameError('grid_create_from_file_scrip_cyclic_restfirst failed!') @attr('data') - @expected_failure + @unittest.expectedFailure def test_grid_create_from_file_scrip_decomp_cyclic_restlast(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.CYCLIC, DecompFlag.RESTLAST], @@ -850,7 +851,7 @@ def test_grid_create_from_file_scrip_decomp_cyclic_restlast(self): raise NameError('grid_create_from_file_scrip_cyclic_restlast failed!') @attr('data') - @expected_failure + @unittest.expectedFailure def test_grid_create_from_file_scrip_decomp_cyclic_cyclic(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.CYCLIC, DecompFlag.CYCLIC], diff --git a/src/addon/ESMPy/src/ESMF/test/test_api/test_locstream.py b/src/addon/ESMPy/src/ESMF/test/test_api/test_locstream.py index 2df9f027a9..03c799b19d 100644 --- a/src/addon/ESMPy/src/ESMF/test/test_api/test_locstream.py +++ b/src/addon/ESMPy/src/ESMF/test/test_api/test_locstream.py @@ -7,6 +7,8 @@ from ESMF.interface.cbindings import * from ESMF.test.base import TestBase, attr +import unittest + class TestLocStream(TestBase): def test_create(self): @@ -67,7 +69,7 @@ def test_slice(self): assert(np.all(locstream["ESMF:X"] == np.array([0, 1, 2, 3, 4]))) - @expected_failure + @unittest.expectedFailure def test_pickle(self): locstream = LocStream(10, name="Test LocStream") @@ -75,7 +77,7 @@ def test_pickle(self): pickle.dumps(locstream) - @expected_failure + @unittest.expectedFailure def test_properties(self): locstream = LocStream(10, name="Test LocStream") locstream["ESMF:X"] = (1, 2, 3, 4, 5) diff --git a/src/addon/ESMPy/src/ESMF/test/test_api/test_mesh.py b/src/addon/ESMPy/src/ESMF/test/test_api/test_mesh.py index 590ea363ab..18204e71e0 100644 --- a/src/addon/ESMPy/src/ESMF/test/test_api/test_mesh.py +++ b/src/addon/ESMPy/src/ESMF/test/test_api/test_mesh.py @@ -8,6 +8,8 @@ except ImportError: from nose import SkipTest +import unittest + import os import inspect @@ -304,7 +306,7 @@ def test_slice_mesh_created_from_file_esmfmesh(self): @attr('data') @attr('serial') - @expected_failure + @unittest.expectedFailure #TODO: remove expected failure once we have a smaller data file with mesh element coordinates to use # TODO: have to define slicing for mesh element coordinates as well.. def test_slice_mesh_created_from_file_elem_coords(self): diff --git a/src/addon/ESMPy/src/ESMF/test/test_cbindings.py b/src/addon/ESMPy/src/ESMF/test/test_cbindings.py index f6dcca5022..a7369977d5 100644 --- a/src/addon/ESMPy/src/ESMF/test/test_cbindings.py +++ b/src/addon/ESMPy/src/ESMF/test/test_cbindings.py @@ -10,6 +10,7 @@ import numpy as np +import unittest class TestCbindings(TestBase): @@ -33,7 +34,7 @@ def test_interfaceint(self): interfaceint = ESMP_InterfaceInt(Narray) - @expected_failure + @unittest.expectedFailure def test_interfaceint2(self): # This test should fail try: @@ -43,7 +44,7 @@ def test_interfaceint2(self): except: raise TypeError('FAIL: tuples cannot be used in place of numpy.array') - @expected_failure + @unittest.expectedFailure def test_interfaceint3(self): # This test should fail try: From 88bff8a5deabb62ec62ec47cf6586bdc4aad5873 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Fri, 19 Aug 2022 10:10:29 -0700 Subject: [PATCH 06/45] reactivate setup.py for ESMPy testing up through Python 3.9 --- src/addon/ESMPy/{setup.py.old => setup.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/addon/ESMPy/{setup.py.old => setup.py} (100%) diff --git a/src/addon/ESMPy/setup.py.old b/src/addon/ESMPy/setup.py similarity index 100% rename from src/addon/ESMPy/setup.py.old rename to src/addon/ESMPy/setup.py From 8c9a3e7b1bf386b23ed244cc00548fefa488bf96 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Mon, 22 Aug 2022 11:52:40 -0700 Subject: [PATCH 07/45] Convert ESMPy testing from nose to pytest --- src/addon/ESMPy/Makefile | 53 +++++++++++++++ src/addon/ESMPy/examples/exampletest.py | 32 ++++++---- src/addon/ESMPy/examples/exampletestdryrun.py | 15 +++++ src/addon/ESMPy/pyproject.toml | 14 ++++ src/addon/ESMPy/setup.cfg | 7 +- src/addon/ESMPy/{setup.py => setup.py.old} | 0 src/addon/ESMPy/src/ESMF/__init__.py | 5 -- src/addon/ESMPy/src/ESMF/api/constants.py | 3 + src/addon/ESMPy/src/ESMF/api/esmpymanager.py | 12 +++- .../ESMPy/src/ESMF/interface/cbindings.py | 2 +- src/addon/ESMPy/src/ESMF/test/base.py | 1 - src/addon/ESMPy/src/ESMF/test/base_test.py | 3 +- .../read_test_cases_from_control_file.py | 4 +- .../src/ESMF/test/regrid_from_file/rfftest.py | 18 ++++++ .../test/regrid_from_file/rfftestdryrun.py | 14 ++++ .../run_regrid_from_file_dryrun.py | 24 +++---- .../src/ESMF/test/test_api/test_field.py | 33 +++++----- .../ESMPy/src/ESMF/test/test_api/test_grid.py | 64 +++++++------------ .../src/ESMF/test/test_api/test_locstream.py | 3 +- .../ESMPy/src/ESMF/test/test_api/test_mesh.py | 22 ++----- .../src/ESMF/test/test_api/test_regrid.py | 55 ++++++++-------- .../ESMPy/src/ESMF/test/test_api/test_vm.py | 6 +- src/addon/ESMPy/src/ESMF/util/decorators.py | 22 ------- src/addon/ESMPy/src/ESMF/util/exceptions.py | 13 ++-- 24 files changed, 243 insertions(+), 182 deletions(-) create mode 100644 src/addon/ESMPy/Makefile create mode 100644 src/addon/ESMPy/examples/exampletestdryrun.py rename src/addon/ESMPy/{setup.py => setup.py.old} (100%) create mode 100644 src/addon/ESMPy/src/ESMF/test/regrid_from_file/rfftest.py create mode 100644 src/addon/ESMPy/src/ESMF/test/regrid_from_file/rfftestdryrun.py diff --git a/src/addon/ESMPy/Makefile b/src/addon/ESMPy/Makefile new file mode 100644 index 0000000000..78eeea3042 --- /dev/null +++ b/src/addon/ESMPy/Makefile @@ -0,0 +1,53 @@ +.PHONY: clean install test test_int test_all uninstall + +clean: + rm -rf build + rm -rf dist + rm -rf *.egg-info + # find . -name "*.pyc" -exec rm -f {} \;') + # find . -name "*ESMF_LogFile*" -exec rm -f {} \;') + # find . -name "*.log" -exec rm -f {} \;') + # find . -name "*.vtk" -exec rm -f {} \;') + # rm src/ESMF/interface/esmfmkfile.py') + # rm -rf build') + # rm -rf dist') + # rm -rf src/ESMF/test/regrid_from_file/data') + # rm -rf examples/data') + + +install: + pip install . + +test_unit: + pytest -m="not parallel" + +test_unit_parallel: + mpirun -n 4 python -m pytest -m="not serial" + +test_examples_dryrun: + pytest -vs examples/exampletestdryrun.py + +test_examples: + pytest -m="not parallel" examples/exampletest.py + +test_examples_parallel: + mpirun -n 4 python -m pytest -m="not serial" examples/exampletest.py + +test_regrid_from_file_dryrun: + pytest -vs src/ESMF/test/regrid_from_file/rfftestdryrun.py + +test_regrid_from_file: + pytest -vs src/ESMF/test/regrid_from_file/rfftest.py + +test_regrid_from_file_parallel: + pytest -vs src/ESMF/test/regrid_from_file/rfftestdryrun.py + mpirun -n 4 python -m pytest -vs src/ESMF/test/regrid_from_file/rfftest.py + +test_all: test_unit test_parallel test_examples_dryrun test_examples test_examples_parallel + +test: test_unit test_unit_parallel test_examples test_examples_parallel + +test_uni: test_unit test_examples + +uninstall: + pip uninstall ESMPy diff --git a/src/addon/ESMPy/examples/exampletest.py b/src/addon/ESMPy/examples/exampletest.py index a6f57047a6..a48a59480d 100644 --- a/src/addon/ESMPy/examples/exampletest.py +++ b/src/addon/ESMPy/examples/exampletest.py @@ -3,25 +3,29 @@ """ examples test file """ -try: - from unittest import SkipTest -except ImportError: - from nose import SkipTest + +import pytest from ESMF.test.base import TestBase, attr import ESMF.api.constants as constants class TestExamples(TestBase): + + # '0' in the name is so it is run first + def test_0_examples_dryrun(self): + from ESMF.util.cache_data import cache_data_files + cache_data_files() def test_helloworld(self): from . import hello_world - # # ESMF IO does not work in mpiuni mode - # def test_cubed_sphere_to_mesh_regrid(self): - # if constants._ESMF_COMM == constants._ESMF_COMM_MPIUNI: - # raise SkipTest('ESMF must be built with MPI for test') - # else: - # from . import cubed_sphere_to_mesh_regrid + # ESMF IO does not work in mpiuni mode + @pytest.mark.parallel + def test_cubed_sphere_to_mesh_regrid(self): + if constants._ESMF_COMM == constants._ESMF_COMM_MPIUNI: + raise SkipTest('ESMF must be built with MPI for test') + else: + from . import cubed_sphere_to_mesh_regrid # ESMF IO does not work in mpiuni mode # only example, not in documentation @@ -58,10 +62,10 @@ def test_regrid_from_file(self): else: from . import regrid_from_file - # only example, not in documentation - @attr('slow') - def _tripole_regrid(self): - from . import tripole_regrid + # # only example, not in documentation, datafile missing from repo + # @pytest.mark.slow + # def test_tripole_regrid(self): + # from . import tripole_regrid # only example, not in documentation def test_ugrid_latlon_regrid(self): diff --git a/src/addon/ESMPy/examples/exampletestdryrun.py b/src/addon/ESMPy/examples/exampletestdryrun.py new file mode 100644 index 0000000000..8484ede406 --- /dev/null +++ b/src/addon/ESMPy/examples/exampletestdryrun.py @@ -0,0 +1,15 @@ +# $Id$ + +""" +examples dryrun test file +""" + +import pytest + +from ESMF.test.base import TestBase, attr + +class TestExamplesDryrun(TestBase): + + def test_examples_dryrun(self): + from ESMF.util.cache_data import cache_data_files + cache_data_files() diff --git a/src/addon/ESMPy/pyproject.toml b/src/addon/ESMPy/pyproject.toml index 894c1b3a35..044b8d7bc3 100644 --- a/src/addon/ESMPy/pyproject.toml +++ b/src/addon/ESMPy/pyproject.toml @@ -22,3 +22,17 @@ build-backend = "setuptools.build_meta" # # [tool.setuptools.dynamic] # version = {attr = "ESMPy.VERSION"} +# + +[tool.pytest.ini_options] +markers = [ + "dryrun: marks a function that will only download test data files (deselect with '-m \"not parallel\"')", + "parallel: marks a test which requires mpi (deselect with '-m \"not parallel\"')", + "serial: marks a test which should be run on one core (deselect with '-m \"not serial\"')" +] +filterwarnings = [ + # "ignore:DeprecationWarning", + # note the use of single quote below to denote "raw" strings in TOML + # 'ignore:DeprecationWarning: Call to deprecated function ESMP_FieldRegridStoreFile', + # 'ignore:DeprecationWarning: Call to deprecated function ESMP_FieldSMMStore', +] diff --git a/src/addon/ESMPy/setup.cfg b/src/addon/ESMPy/setup.cfg index c492282869..1bbcf9f332 100644 --- a/src/addon/ESMPy/setup.cfg +++ b/src/addon/ESMPy/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = ESMPy -version = 8.4.0 +version = 8.4.0beta description = ESMF Python interface long_description = file: README.md, LICENSE license = University of Illinois-NCSA @@ -24,7 +24,7 @@ package_dir= packages = find: install_requires = numpy - nose2 + pytest [options.packages.find] where=src @@ -32,6 +32,3 @@ exclude = doc* examples* test* - -[nosetests] -attr=!slow,!data diff --git a/src/addon/ESMPy/setup.py b/src/addon/ESMPy/setup.py.old similarity index 100% rename from src/addon/ESMPy/setup.py rename to src/addon/ESMPy/setup.py.old diff --git a/src/addon/ESMPy/src/ESMF/__init__.py b/src/addon/ESMPy/src/ESMF/__init__.py index 9aee630788..a82ce63453 100644 --- a/src/addon/ESMPy/src/ESMF/__init__.py +++ b/src/addon/ESMPy/src/ESMF/__init__.py @@ -76,9 +76,6 @@ from ESMF.util.helpers import * from ESMF.api.constants import _ESMF_VERSION -# for testing -from ESMF.util.decorators import expected_failure - #### SET UP SOME INFO ######################################################### __name__ = "ESMF" @@ -94,5 +91,3 @@ __license__ = "University of Illinois-NCSA" __release__ = _ESMF_VERSION __version__ = _ESMF_VERSION - - diff --git a/src/addon/ESMPy/src/ESMF/api/constants.py b/src/addon/ESMPy/src/ESMF/api/constants.py index 98fa1c2fc8..b76a69d47d 100644 --- a/src/addon/ESMPy/src/ESMF/api/constants.py +++ b/src/addon/ESMPy/src/ESMF/api/constants.py @@ -4,6 +4,9 @@ from ESMF.util.enum import IntEnum +# Test exhaustive parameter +esmpy_test_exhaustive=False + # error message _errmsg = 'Please check the log files (named "*ESMF_LogFile").' _ESMP_SUCCESS = 0 diff --git a/src/addon/ESMPy/src/ESMF/api/esmpymanager.py b/src/addon/ESMPy/src/ESMF/api/esmpymanager.py index be1e72608f..286121effe 100644 --- a/src/addon/ESMPy/src/ESMF/api/esmpymanager.py +++ b/src/addon/ESMPy/src/ESMF/api/esmpymanager.py @@ -75,9 +75,14 @@ class Manager(object): will always be called prior to exiting Python. Calling __init__ explicitly results in a no-op. - The Manager can be used to enable the + The :class:`~ESMF.api.esmpymanager.Manager` can be used to enable the `MOAB `_ - mesh backend to the Mesh. This is done by calling ``set_moab()`` with ``moab_on=True``. + mesh backend to the :class:`~ESMF.api.esmpymanager.Mesh`. This is done by calling ``set_moab()`` with ``moab_on=True``. + + The :class:`~ESMF.api.esmpymanager.Manager` has a `test_exhaustive` member + variable that can be enabled to run + combinatorial expansions of :class:`~ESMF.api.esmpymanager.Grid` and + :class:`~ESMF.api.esmpymanager.Field` creation parameters. :param bool debug: outputs logging information to ESMF logfiles. If ``None``, defaults to False. @@ -126,6 +131,9 @@ def __init__(self, debug=False): # set up to use the ESMF native mesh backend by default self._moab = False + + # exhaustive testing set to False by default + self._test_exhaustive = False return diff --git a/src/addon/ESMPy/src/ESMF/interface/cbindings.py b/src/addon/ESMPy/src/ESMF/interface/cbindings.py index a7a7e3acf4..4adaea4f83 100644 --- a/src/addon/ESMPy/src/ESMF/interface/cbindings.py +++ b/src/addon/ESMPy/src/ESMF/interface/cbindings.py @@ -1943,6 +1943,7 @@ def ESMP_FieldPrint(field): Py3Char, ct.c_uint, ct.c_uint] +@netcdf def ESMP_FieldRead(field, filename, variablename, timeslice, iofmt=1): #TODO: C doc says it defaults to NETCDF(1), but actually defaults to BIN(0) """ @@ -2160,7 +2161,6 @@ def ESMP_FieldRegridStore(srcField, OptionalBool, OptionalField, OptionalField] -@deprecated def ESMP_FieldRegridStoreFile(srcField, dstField, filename, srcMaskValues=None, dstMaskValues=None, regridmethod=None, diff --git a/src/addon/ESMPy/src/ESMF/test/base.py b/src/addon/ESMPy/src/ESMF/test/base.py index 54344429dc..c54a9dd952 100644 --- a/src/addon/ESMPy/src/ESMF/test/base.py +++ b/src/addon/ESMPy/src/ESMF/test/base.py @@ -113,4 +113,3 @@ def wrap_ob(ob): return ob return wrap_ob - diff --git a/src/addon/ESMPy/src/ESMF/test/base_test.py b/src/addon/ESMPy/src/ESMF/test/base_test.py index 1a8fff0c7e..27a249db30 100644 --- a/src/addon/ESMPy/src/ESMF/test/base_test.py +++ b/src/addon/ESMPy/src/ESMF/test/base_test.py @@ -8,6 +8,7 @@ class Test(TestBase): def setup(self): mg = Manager() + mg.test_exhaustive = False # mg.barrier() def test_assertNumpyAll_bad_mask(self): @@ -25,4 +26,4 @@ def tearDown(self): # mg.barrier() if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/src/addon/ESMPy/src/ESMF/test/regrid_from_file/read_test_cases_from_control_file.py b/src/addon/ESMPy/src/ESMF/test/regrid_from_file/read_test_cases_from_control_file.py index 6dca02d866..313a76e63f 100644 --- a/src/addon/ESMPy/src/ESMF/test/regrid_from_file/read_test_cases_from_control_file.py +++ b/src/addon/ESMPy/src/ESMF/test/regrid_from_file/read_test_cases_from_control_file.py @@ -18,9 +18,9 @@ def read_control_file(): # Parse each test case line from the control file. test_cases = [] for line in open(os.path.join(TEST_REGRID_DIR, CONTROL_FNAME), 'r'): - if line[0] != '#' and re.match('(\s*.+\s*:){3}', line): + if line[0] != '#' and re.match(r'(\s*.+\s*:){3}', line): (src_fname, dst_fname, regrid_method, options, mean_err_str, - max_err_str, max_area_err_str) = re.split('\s*:\s*', line) + max_err_str, max_area_err_str) = re.split(r'\s*:\s*', line) test_cases.append([src_fname, dst_fname, regrid_method, options, float(mean_err_str), float(max_err_str), float(max_area_err_str)]) diff --git a/src/addon/ESMPy/src/ESMF/test/regrid_from_file/rfftest.py b/src/addon/ESMPy/src/ESMF/test/regrid_from_file/rfftest.py new file mode 100644 index 0000000000..788408c105 --- /dev/null +++ b/src/addon/ESMPy/src/ESMF/test/regrid_from_file/rfftest.py @@ -0,0 +1,18 @@ +# $Id$ + +""" +examples test file +""" + +import pytest + +from ESMF.test.base import TestBase, attr + +class TestRFF(TestBase): + + # # '0' in the name is so it is run first + # def test_0_regrid_from_file_dryrun(self): + # from ESMF.test.regrid_from_file import run_regrid_from_file_dryrun + + def test_regrid_from_file(self): + from ESMF.test.regrid_from_file import run_regrid_from_file diff --git a/src/addon/ESMPy/src/ESMF/test/regrid_from_file/rfftestdryrun.py b/src/addon/ESMPy/src/ESMF/test/regrid_from_file/rfftestdryrun.py new file mode 100644 index 0000000000..dc8e40e123 --- /dev/null +++ b/src/addon/ESMPy/src/ESMF/test/regrid_from_file/rfftestdryrun.py @@ -0,0 +1,14 @@ +# $Id$ + +""" +examples test file +""" + +import pytest + +from ESMF.test.base import TestBase, attr + +class TestRFFDryrun(TestBase): + + def test_regrid_from_file_dryrun(self): + from ESMF.test.regrid_from_file import run_regrid_from_file_dryrun diff --git a/src/addon/ESMPy/src/ESMF/test/regrid_from_file/run_regrid_from_file_dryrun.py b/src/addon/ESMPy/src/ESMF/test/regrid_from_file/run_regrid_from_file_dryrun.py index fdc512551f..88ac6ee8a4 100644 --- a/src/addon/ESMPy/src/ESMF/test/regrid_from_file/run_regrid_from_file_dryrun.py +++ b/src/addon/ESMPy/src/ESMF/test/regrid_from_file/run_regrid_from_file_dryrun.py @@ -36,18 +36,12 @@ def cache_data_files_for_test_cases(test_cases): break return status_ok -# Main program: Retrieve data files from a remote server if they do not exist -# locally for each test read from a control file. -def main(): - # Read the test case parameters from the control file. - test_cases = read_control_file() - - # Retrieve the data files needed for the test cases from the remote server. - status_ok = cache_data_files_for_test_cases(test_cases) - if status_ok: - print ('RESULT: PASS - regrid_from_file_dryrun ok\n\n') - else: - print ('RESULT: FAIL - regrid_from_file_dryrun error\n\n') - -if __name__ == '__main__': - sys.exit(main()) +# Read the test case parameters from the control file. +test_cases = read_control_file() + +# Retrieve the data files needed for the test cases from the remote server. +status_ok = cache_data_files_for_test_cases(test_cases) +if status_ok: + print ('RESULT: PASS - regrid_from_file_dryrun ok\n\n') +else: + print ('RESULT: FAIL - regrid_from_file_dryrun error\n\n') diff --git a/src/addon/ESMPy/src/ESMF/test/test_api/test_field.py b/src/addon/ESMPy/src/ESMF/test/test_api/test_field.py index e06c28c1f6..4ffb5ae7da 100644 --- a/src/addon/ESMPy/src/ESMF/test/test_api/test_field.py +++ b/src/addon/ESMPy/src/ESMF/test/test_api/test_field.py @@ -2,10 +2,7 @@ field unit test file """ -try: - from unittest import SkipTest -except ImportError: - from nose import SkipTest +import pytest from ESMF import * from ESMF.interface.cbindings import * @@ -14,6 +11,10 @@ class TestField(TestBase): + + mg = Manager(debug=True) + mg.test_exhaustive = False + # this is for the documentation, do not modify def create_field(grid_or_mesh, name): ''' @@ -71,7 +72,7 @@ def test_meta_del(self): del (self.field) assert (not hasattr(self, 'field')) - @attr('serial') + @pytest.mark.serial def test_numpy_funcs(self): field = self.make_field(np.array([10, 10], dtype=np.int32)) @@ -97,8 +98,8 @@ def test_numpy_funcs(self): - @attr('serial') - @attr('slow') + @pytest.mark.serial + @pytest.mark.skipif(mg.test_exhaustive==False, reason="only run in exhaustive mode") #nosetests src/ESMF/test/test_api/test_field.py:TestField.test_field_create_2d_grid def _field_create_2d_grid(self): keywords = dict( @@ -148,8 +149,8 @@ def _field_create_2d_grid(self): raise ValueError( "The following combinations of parameters failed to create a proper Field: " + str(fail)) - @attr('serial') - @attr('slow') + @pytest.mark.serial + @pytest.mark.skipif(mg.test_exhaustive==False, reason="only run in exhaustive mode") def _field_create_3d_grid(self): keywords = dict( # periodic specifies all valid combos of [num_peri_dims, periodic_dim, pole_dim] @@ -200,7 +201,7 @@ def _field_create_3d_grid(self): raise ValueError( "The following combinations of parameters failed to create a proper Field: " + str(len(fail))) - @attr('slow') + @pytest.mark.skipif(mg.test_exhaustive==False, reason="only run in exhaustive mode") def _field_create_2d_mesh(self): parallel = False if pet_count() > 1: @@ -315,7 +316,7 @@ def test_field_uniqueness(self): assert (field.struct.ptr != field2.struct.ptr) - @attr('serial') + @pytest.mark.serial def test_field_area(self): grid = Grid(np.array([3, 4]), staggerloc=[StaggerLoc.CENTER, StaggerLoc.CORNER], coord_sys=CoordSys.SPH_DEG, num_peri_dims=1, @@ -431,7 +432,7 @@ def test_field_extradims_mesh(self): field2.data[...] = 10 self.examine_field_attributes(field2) - @attr('serial') + @pytest.mark.serial def test_field_slice_grid(self): typekind = TypeKind.R8 grid = Grid(np.array([100, 100]), coord_sys=CoordSys.CART, @@ -471,7 +472,7 @@ def test_field_slice_grid(self): assert (field3.grid.upper_bounds[0].tolist() == [2, 2]) # slicing is disabled in parallel - @attr('serial') + @pytest.mark.serial def test_field_slice_mesh(self): parallel = False if pet_count() > 1: @@ -510,7 +511,7 @@ def test_field_slice_mesh(self): assert (field2.grid.size[0] == 5) assert (field3.grid.size[0] == 2) - @attr('serial') + @pytest.mark.serial def test_field_slice_grid_extraindices(self): n = 10 grid = Grid(np.array([n,n]), coord_sys=CoordSys.CART, staggerloc=StaggerLoc.CENTER) @@ -548,7 +549,7 @@ def test_field_slice_grid_extraindices(self): assert (field2.grid.upper_bounds[0].tolist() == [5, 5]) assert (field3.grid.upper_bounds[0].tolist() == [2, 2]) - @attr('serial') + @pytest.mark.serial def disable_est_field_slice_mesh_extraindices(self): parallel = False if pet_count() > 1: @@ -584,7 +585,7 @@ def disable_est_field_slice_mesh_extraindices(self): assert field2.data.shape == (5, 2, 1) assert field3.data.shape == (2, 1, 1) - @attr('serial') + @pytest.mark.serial def test_field_reshape(self): field = self.make_field(np.array([10, 10], dtype=np.int32), ndbounds=False) diff --git a/src/addon/ESMPy/src/ESMF/test/test_api/test_grid.py b/src/addon/ESMPy/src/ESMF/test/test_api/test_grid.py index 11cca7fe5d..03e1ea73d8 100644 --- a/src/addon/ESMPy/src/ESMF/test/test_api/test_grid.py +++ b/src/addon/ESMPy/src/ESMF/test/test_api/test_grid.py @@ -11,11 +11,12 @@ import numpy as np import os import inspect -import unittest +import pytest class TestGrid(TestBase): - Manager(debug=True) + mg = Manager(debug=True) + mg.test_exhaustive = False def examine_grid_attributes(self, grid): # ~~~~~~~~~~~~~~~~~~~~~~ STAGGER LOCATIONS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -178,9 +179,9 @@ def test_grid_periodic(self): grid,_,_ = self.make_grid_periodic() self.examine_grid_attributes(grid) - @attr('serial') - @attr('slow') - def _grid_create_2d(self): + @pytest.mark.serial + @pytest.mark.skipif(mg.test_exhaustive==False, reason="only run in exhaustive mode") + def test_grid_create_2d(self): keywords = dict( # periodic specifies all valid combos of [pole_kind, num_peri_dims, periodic_dim, pole_dim] pole_kind=[[PoleKind.NONE, PoleKind.NONE], @@ -224,9 +225,9 @@ def _grid_create_2d(self): raise ValueError( "The following combinations of Grid parameters failed to create a proper Grid: " + str(fail)) - @attr('serial') - @attr('slow') - def _grid_create_3d(self): + @pytest.mark.serial + @pytest.mark.skipif(mg.test_exhaustive==False, reason="only run in exhaustive mode") + def test_grid_create_3d(self): keywords = dict( # periodic specifies all valid combos of [num_peri_dims, periodic_dim, pole_dim] periodic=[[None, None, None], [None, None, 0], [None, None, 1], [None, None, 2], @@ -259,7 +260,7 @@ def _grid_create_3d(self): raise ValueError( "The following combinations of Grid parameters failed to create a proper Grid: " + str(fail)) - @attr('serial') + @pytest.mark.serial def test_grid_create_cubed_sphere(self): # keywords = dict( # periodic specifies all valid combos of [num_peri_dims, periodic_dim, pole_dim] @@ -297,7 +298,7 @@ def test_grid_create_cubed_sphere(self): grid.destroy() # grid2.destroy() - @attr('serial') + @pytest.mark.serial def test_grid_slice_2d(self): grid = self.make_grid_2d() @@ -317,7 +318,7 @@ def test_grid_slice_2d(self): assert grid3.coords[StaggerLoc.CENTER][0].shape == (2, 1) assert grid3.upper_bounds[StaggerLoc.CENTER].tolist() == [2, 1] - @attr('serial') + @pytest.mark.serial def test_grid_slice_2d_corners(self): grid = self.make_grid_2d() @@ -348,7 +349,7 @@ def test_grid_slice_2d_corners(self): assert grid3.upper_bounds[StaggerLoc.CORNER].tolist() == [3, 2] - @attr('serial') + @pytest.mark.serial def test_grid_slice_3d(self): grid = self.make_grid_3d() @@ -368,7 +369,7 @@ def test_grid_slice_3d(self): assert grid3.coords[StaggerLoc.CENTER][0].shape == (2, 1, 2) assert grid3.upper_bounds[StaggerLoc.CENTER].tolist() == [2, 1, 2] - @attr('serial') + @pytest.mark.serial def test_grid_slice_3d_corners(self): grid = self.make_grid_3d() @@ -403,7 +404,7 @@ def test_grid_slice_3d_corners(self): assert grid3.coords[cvf][0].shape == (3, 2, 3) assert grid3.upper_bounds[cvf].tolist() == [3, 2, 3] - @attr('serial') + @pytest.mark.serial def test_grid_slice_periodic(self): grid, x, y = self.make_grid_periodic() @@ -429,8 +430,7 @@ def test_grid_slice_periodic(self): assert grid3.coords[StaggerLoc.CORNER][0].shape == (3, 2) assert grid3.upper_bounds[StaggerLoc.CORNER].tolist() == [3, 2] - @attr('data') - @attr('serial') + @pytest.mark.serial def test_slice_grid_created_from_file_scrip(self): reg_decomp = [pet_count(), 1] try: @@ -629,7 +629,6 @@ def test_grid_area_3D(self): area[:] = areavals assert(np.all(area[...] == 12*np.ones([10, 20, 30]))) - @attr('data') def test_grid_create_from_file_gridspec1D(self): esmfdir = os.path.dirname(inspect.getfile(ESMF)) grid = Grid(filename=os.path.join(esmfdir, "test/data/gridspec1Dcoords.nc"), @@ -638,7 +637,6 @@ def test_grid_create_from_file_gridspec1D(self): self.examine_grid_attributes(grid) - @attr('data') def test_grid_create_from_file_scrip(self): reg_decomp = [pet_count(), 1] try: @@ -649,7 +647,6 @@ def test_grid_create_from_file_scrip(self): except: raise NameError('grid_create_from_file_scrip failed!') - @attr('data') def test_grid_create_from_file_scrip_decomp_balanced_balanced(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.BALANCED, DecompFlag.BALANCED], @@ -662,7 +659,6 @@ def test_grid_create_from_file_scrip_decomp_balanced_balanced(self): except: raise NameError('grid_create_from_file_scrip_balanced_balanced failed!') - @attr('data') def test_grid_create_from_file_scrip_decomp_balanced_restfirst(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.BALANCED, DecompFlag.RESTFIRST], @@ -675,7 +671,6 @@ def test_grid_create_from_file_scrip_decomp_balanced_restfirst(self): except: raise NameError('grid_create_from_file_scrip_balanced_restfirst failed!') - @attr('data') def test_grid_create_from_file_scrip_decomp_balanced_restlast(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.BALANCED, DecompFlag.RESTLAST], @@ -688,8 +683,7 @@ def test_grid_create_from_file_scrip_decomp_balanced_restlast(self): except: raise NameError('grid_create_from_file_scrip_balanced_restlast failed!') - @attr('data') - @unittest.expectedFailure + @pytest.mark.xfail def test_grid_create_from_file_scrip_decomp_balanced_cyclic(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.BALANCED, DecompFlag.CYCLIC], @@ -702,7 +696,6 @@ def test_grid_create_from_file_scrip_decomp_balanced_cyclic(self): except: raise NameError('grid_create_from_file_scrip_balanced_cyclic failed!') - @attr('data') def test_grid_create_from_file_scrip_decomp_restfirst_balanced(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.RESTFIRST, DecompFlag.BALANCED], @@ -715,7 +708,6 @@ def test_grid_create_from_file_scrip_decomp_restfirst_balanced(self): except: raise NameError('grid_create_from_file_scrip_restfirst_balanced failed!') - @attr('data') def test_grid_create_from_file_scrip_decomp_restfirst_restfirst(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.RESTFIRST, DecompFlag.RESTFIRST], @@ -728,7 +720,6 @@ def test_grid_create_from_file_scrip_decomp_restfirst_restfirst(self): except: raise NameError('grid_create_from_file_scrip_restfirst_restfirst failed!') - @attr('data') def test_grid_create_from_file_scrip_decomp_restfirst_restlast(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.RESTFIRST, DecompFlag.RESTLAST], @@ -741,8 +732,7 @@ def test_grid_create_from_file_scrip_decomp_restfirst_restlast(self): except: raise NameError('grid_create_from_file_scrip_restfirst_restlast failed!') - @attr('data') - @unittest.expectedFailure + @pytest.mark.xfail def test_grid_create_from_file_scrip_decomp_restfirst_cyclic(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.RESTFIRST, DecompFlag.CYCLIC], @@ -755,7 +745,6 @@ def test_grid_create_from_file_scrip_decomp_restfirst_cyclic(self): except: raise NameError('grid_create_from_file_scrip_restfirst_cyclic failed!') - @attr('data') def test_grid_create_from_file_scrip_decomp_restlast_balanced(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.RESTLAST, DecompFlag.BALANCED], @@ -768,7 +757,6 @@ def test_grid_create_from_file_scrip_decomp_restlast_balanced(self): except: raise NameError('grid_create_from_file_scrip_restlast_balanced failed!') - @attr('data') def test_grid_create_from_file_scrip_decomp_restlast_restfirst(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.RESTLAST, DecompFlag.RESTFIRST], @@ -781,7 +769,6 @@ def test_grid_create_from_file_scrip_decomp_restlast_restfirst(self): except: raise NameError('grid_create_from_file_scrip_restlast_restfirst failed!') - @attr('data') def test_grid_create_from_file_scrip_decomp_restlast_restlast(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.RESTLAST, DecompFlag.RESTLAST], @@ -794,8 +781,7 @@ def test_grid_create_from_file_scrip_decomp_restlast_restlast(self): except: raise NameError('grid_create_from_file_scrip_restlast_restlast failed!') - @attr('data') - @unittest.expectedFailure + @pytest.mark.xfail def test_grid_create_from_file_scrip_decomp_restlast_cyclic(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.RESTLAST, DecompFlag.CYCLIC], @@ -808,8 +794,7 @@ def test_grid_create_from_file_scrip_decomp_restlast_cyclic(self): except: raise NameError('grid_create_from_file_scrip_restlast_cyclic failed!') - @attr('data') - @unittest.expectedFailure + @pytest.mark.xfail def test_grid_create_from_file_scrip_decomp_cyclic_balanced(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.CYCLIC, DecompFlag.BALANCED], @@ -822,8 +807,7 @@ def test_grid_create_from_file_scrip_decomp_cyclic_balanced(self): except: raise NameError('grid_create_from_file_scrip_cyclic_balanced failed!') - @attr('data') - @unittest.expectedFailure + @pytest.mark.xfail def test_grid_create_from_file_scrip_decomp_cyclic_restfirst(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.CYCLIC, DecompFlag.RESTFIRST], @@ -836,8 +820,7 @@ def test_grid_create_from_file_scrip_decomp_cyclic_restfirst(self): except: raise NameError('grid_create_from_file_scrip_cyclic_restfirst failed!') - @attr('data') - @unittest.expectedFailure + @pytest.mark.xfail def test_grid_create_from_file_scrip_decomp_cyclic_restlast(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.CYCLIC, DecompFlag.RESTLAST], @@ -850,8 +833,7 @@ def test_grid_create_from_file_scrip_decomp_cyclic_restlast(self): except: raise NameError('grid_create_from_file_scrip_cyclic_restlast failed!') - @attr('data') - @unittest.expectedFailure + @pytest.mark.xfail def test_grid_create_from_file_scrip_decomp_cyclic_cyclic(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.CYCLIC, DecompFlag.CYCLIC], diff --git a/src/addon/ESMPy/src/ESMF/test/test_api/test_locstream.py b/src/addon/ESMPy/src/ESMF/test/test_api/test_locstream.py index 03c799b19d..1cdcb3dbdf 100644 --- a/src/addon/ESMPy/src/ESMF/test/test_api/test_locstream.py +++ b/src/addon/ESMPy/src/ESMF/test/test_api/test_locstream.py @@ -8,6 +8,7 @@ from ESMF.test.base import TestBase, attr import unittest +import pytest class TestLocStream(TestBase): @@ -52,7 +53,7 @@ def test_copy(self): assert np.all(l2["ESMF:X"] == [0, 1, 2, 3, 4]) - @attr('serial') + @pytest.mark.serial def test_slice(self): locstream = LocStream(5, name="Test LocStream") diff --git a/src/addon/ESMPy/src/ESMF/test/test_api/test_mesh.py b/src/addon/ESMPy/src/ESMF/test/test_api/test_mesh.py index 18204e71e0..6bd06f4cf0 100644 --- a/src/addon/ESMPy/src/ESMF/test/test_api/test_mesh.py +++ b/src/addon/ESMPy/src/ESMF/test/test_api/test_mesh.py @@ -3,12 +3,7 @@ mesh unit test file """ -try: - from unittest import SkipTest -except ImportError: - from nose import SkipTest - -import unittest +import pytest import os import inspect @@ -181,7 +176,6 @@ def test_mesh_50_mask_area(self): self.assertNumpyAll(mesh.area, elemArea) - @attr('data') def test_mesh_create_from_file_scrip(self): try: esmfdir = os.path.dirname(inspect.getfile(ESMF)) @@ -190,7 +184,6 @@ def test_mesh_create_from_file_scrip(self): except: raise NameError('mesh_create_from_file_scrip failed!') - @attr('data') def test_mesh_create_from_file_esmfmesh(self): try: esmfdir = os.path.dirname(inspect.getfile(ESMF)) @@ -221,7 +214,7 @@ def test_mesh_copy(self): self.check_mesh(mesh2, nodeCoord, nodeOwner) # slicing is disabled in parallel - @attr('serial') + @pytest.mark.serial def test_mesh_slicing(self): parallel = False if pet_count() > 1: @@ -257,8 +250,7 @@ def test_mesh_slicing(self): assert mesh3.size == [2, None] assert mesh3.size_owned == [2, None] - @attr('data') - @attr('serial') + @pytest.mark.serial def test_slice_mesh_created_from_file_scrip(self): try: esmfdir = os.path.dirname(inspect.getfile(ESMF)) @@ -281,8 +273,7 @@ def test_slice_mesh_created_from_file_scrip(self): assert mesh2.size == [5, None] assert mesh2.size_owned == [5, None] - @attr('data') - @attr('serial') + @pytest.mark.serial def test_slice_mesh_created_from_file_esmfmesh(self): try: esmfdir = os.path.dirname(inspect.getfile(ESMF)) @@ -304,9 +295,8 @@ def test_slice_mesh_created_from_file_esmfmesh(self): assert mesh2.size_owned == [5, None] - @attr('data') - @attr('serial') - @unittest.expectedFailure + @pytest.mark.serial + @pytest.mark.xfail #TODO: remove expected failure once we have a smaller data file with mesh element coordinates to use # TODO: have to define slicing for mesh element coordinates as well.. def test_slice_mesh_created_from_file_elem_coords(self): diff --git a/src/addon/ESMPy/src/ESMF/test/test_api/test_regrid.py b/src/addon/ESMPy/src/ESMF/test/test_api/test_regrid.py index 2e82f7b650..cacf811154 100644 --- a/src/addon/ESMPy/src/ESMF/test/test_api/test_regrid.py +++ b/src/addon/ESMPy/src/ESMF/test/test_api/test_regrid.py @@ -2,10 +2,7 @@ regrid unit test file """ -try: - from unittest import SkipTest -except ImportError: - from nose import SkipTest +import pytest import os @@ -84,7 +81,7 @@ def test_field_regrid(self): line_type=LineType.CART, factors=False) _ = rh(srcfield, dstfield) - @attr('serial') + @pytest.mark.serial def test_field_regrid_factor_retrieval(self): # Test retrieving factors from a route handle. @@ -187,7 +184,7 @@ def test_field_regrid_factor_retrieval(self): rh.destroy() - @attr('parallel') + @pytest.mark.parallel def test_field_regrid_file1(self): mgr = Manager() @@ -241,7 +238,7 @@ def test_field_regrid_file1(self): if os.path.isfile(path): os.remove(path) - @attr('parallel') + @pytest.mark.parallel def test_field_regrid_file2(self): mgr = Manager() filename = 'esmpy_test_field_regrid_file2.nc' @@ -312,7 +309,7 @@ def test_field_regrid_file2(self): if os.path.isfile(path): os.remove(path) - @attr('parallel') + @pytest.mark.parallel # remove this test for 8.2.0 due to unexplained segv def tet_field_regrid_file_withaux(self): import os @@ -377,7 +374,7 @@ def tet_field_regrid_file_withaux(self): if os.path.isfile(path): os.remove(path) - @attr('parallel') + @pytest.mark.parallel def test_field_regrid_file3(self): mgr = Manager() filename = 'esmpy_test_field_from_file.nc' @@ -472,7 +469,7 @@ def test_field_regrid_file3(self): os.remove(path) - @attr('parallel') + @pytest.mark.parallel def test_field_regrid_file4(self): mgr = Manager() filename = 'routehandlefile.nc' @@ -611,7 +608,7 @@ def test_field_regrid_gridmesh(self): rh = Regrid(srcfield, dstfield, regrid_method=RegridMethod.CONSERVE) dstfield = rh(srcfield, dstfield) - @attr('parallel') + @pytest.mark.parallel def test_field_regrid_zeroregion(self): parallel = False if pet_count() > 1: @@ -658,7 +655,7 @@ def test_field_regrid_zeroregion(self): if dstfield.grid.mask[StaggerLoc.CENTER][i, j] == 0: assert(dstfield[i, j] == 0) - @attr('parallel') + @pytest.mark.parallel def test_field_regrid_zeroregion_select_ndbounds(self): # Test zero region select during a sparse matrix multiplication # having undistributed dimensions. @@ -710,7 +707,7 @@ def test_field_regrid_zeroregion_select_ndbounds(self): if os.path.exists(filename): os.remove(filename) - @attr('parallel') + @pytest.mark.parallel def test_field_regrid_area(self): parallel = False if pet_count() > 1: @@ -752,7 +749,7 @@ def test_field_regrid_area(self): if (dstarea.data[i] != 0.25): assert (dstarea.data[i] == 0.125) - @attr('parallel') + @pytest.mark.parallel def test_field_regrid_periodic(self): parallel = False if pet_count() > 1: @@ -802,7 +799,7 @@ def test_field_regrid_periodic(self): self.assertAlmostEqual(meanrel, 0.0016447124122954575) self.assertAlmostEqual(csrvrel, 0.0) - @attr('parallel') + @pytest.mark.parallel def test_grid_grid_3d_bilinear_cartesian(self): # RO: This test creates the same Grid on every processor, it could be improved @@ -832,7 +829,7 @@ def test_grid_grid_3d_bilinear_cartesian(self): self.assertAlmostEqual(meanrel, 0.00215601743167) self.assertAlmostEqual(csrvrel, 0.0) - @attr('parallel') + @pytest.mark.parallel def test_grid_grid_3d_bilinear_spherical(self): # RO: This test creates the same Grid on every processor, it could be improved @@ -862,7 +859,7 @@ def test_grid_grid_3d_bilinear_spherical(self): self.assertAlmostEqual(meanrel, 0.00061587737764545617) self.assertAlmostEqual(csrvrel, 0.0) - @attr('parallel') + @pytest.mark.parallel def test_grid_grid_regrid_csrv_mask_3D(self): # RO: This test creates the same Grid on every processor, it could be improved @@ -903,7 +900,7 @@ def test_grid_grid_regrid_csrv_mask_3D(self): self.assertAlmostEqual(meanrel, 0.0021560174316746865) self.assertAlmostEqual(csrvrel, 0.0) - @attr('parallel') + @pytest.mark.parallel def test_grid_grid_regrid_csrv_mask(self): # RO: This test creates the same Grid on every processor, it could be improved @@ -945,7 +942,7 @@ def test_grid_grid_regrid_csrv_mask(self): self.assertAlmostEqual(meanrel, 0.0024803189848013785) self.assertAlmostEqual(csrvrel, 0.0) - @attr('parallel') + @pytest.mark.parallel def test_grid_grid_regrid_csrv_2nd_mask(self): # RO: This test creates the same Grid on every processor, it could be improved @@ -987,7 +984,7 @@ def test_grid_grid_regrid_csrv_2nd_mask(self): self.assertAlmostEqual(meanrel, 0.0020296891000258252) self.assertAlmostEqual(csrvrel, 0.0) - @attr('parallel') + @pytest.mark.parallel def test_grid_grid_regrid_srcmask_types(self): # NOTE: this tests an old issue where the items of a grid were not properly set when # the grid coord_typekind differed from the field typekind. @@ -1033,7 +1030,7 @@ def test_grid_grid_regrid_srcmask_types(self): self.assertAlmostEqual(meanrel, 0.0024803189848013785) self.assertAlmostEqual(csrvrel, 0.0) - @attr('parallel') + @pytest.mark.parallel def test_grid_mesh_regrid_csrv_mask(self): parallel = False if pet_count() > 1: @@ -1091,7 +1088,7 @@ def test_grid_mesh_regrid_csrv_mask(self): self.assertAlmostEqual(meanrel, 0.038806630051265847) self.assertAlmostEqual(csrvrel, 0.0) - @attr('parallel') + @pytest.mark.parallel def test_grid_mesh_regrid_csrv(self): parallel = False if pet_count() > 1: @@ -1147,7 +1144,7 @@ def test_grid_mesh_regrid_csrv(self): self.assertAlmostEqual(meanrel, 0.037733241800767432) self.assertAlmostEqual(csrvrel, 0.0) - @attr('parallel') + @pytest.mark.parallel def test_grid_mesh_regrid_mask(self): parallel = False if pet_count() > 1: @@ -1192,7 +1189,7 @@ def test_grid_mesh_regrid_mask(self): self.assertAlmostEqual(meanrel, 0.0) self.assertAlmostEqual(csrvrel, 0.0) - @attr('parallel') + @pytest.mark.parallel def test_grid_mesh_regrid(self): parallel = False if pet_count() > 1: @@ -1236,7 +1233,7 @@ def test_grid_mesh_regrid(self): self.assertAlmostEqual(meanrel, 0.0) self.assertAlmostEqual(csrvrel, 0.0) - @attr('parallel') + @pytest.mark.parallel def test_field_regrid_extrapolation(self): parallel = False if pet_count() > 1: @@ -1283,7 +1280,7 @@ def test_field_regrid_extrapolation(self): self.assertAlmostEqual(meanrel, 0.0) self.assertAlmostEqual(csrvrel, 0.0) - @attr('parallel') + @pytest.mark.parallel def test_field_regrid_extrapolation_creepfill(self): parallel = False if pet_count() > 1: @@ -1328,7 +1325,7 @@ def test_field_regrid_extrapolation_creepfill(self): self.assertAlmostEqual(meanrel, 0.0) self.assertAlmostEqual(csrvrel, 0.0) - @attr('parallel') + @pytest.mark.parallel def test_mesh_mesh_regrid(self): parallel = False if pet_count() > 1: @@ -1388,7 +1385,7 @@ def test_mesh_mesh_regrid(self): self.assertAlmostEqual(meanrel, 0.037109375) self.assertAlmostEqual(csrvrel, 0.0) - @attr('parallel') + @pytest.mark.parallel def est_grid_mesh_pentatri_regrid_csrv(self): parallel = False if pet_count() > 1: @@ -1497,7 +1494,7 @@ def est_grid_mesh_pentatri_regrid_csrv_simple(self): assert (meanrel < 10E-2) assert (csrvrel < 10E-14) - @attr('parallel') + @pytest.mark.parallel def test_grid_mesh_pentatri_regrid_bilinear(self): parallel = False if pet_count() > 1: diff --git a/src/addon/ESMPy/src/ESMF/test/test_api/test_vm.py b/src/addon/ESMPy/src/ESMF/test/test_api/test_vm.py index e8c7223d4d..52234f2b25 100644 --- a/src/addon/ESMPy/src/ESMF/test/test_api/test_vm.py +++ b/src/addon/ESMPy/src/ESMF/test/test_api/test_vm.py @@ -6,8 +6,10 @@ from ESMF.interface.cbindings import * from ESMF.test.base import TestBase, attr +import pytest + class TestVM(TestBase): - @attr('parallel') + @pytest.mark.parallel def test_vm_broadcast(self): mg = Manager() @@ -27,7 +29,7 @@ def test_vm_broadcast(self): mg.barrier() - @attr('parallel') + @pytest.mark.parallel def test_vm_reduce(self): send = np.ones(4, dtype=np.float64) recv = np.zeros(4, dtype=np.float64) diff --git a/src/addon/ESMPy/src/ESMF/util/decorators.py b/src/addon/ESMPy/src/ESMF/util/decorators.py index 2c98ad8cd2..b3a297d9c9 100644 --- a/src/addon/ESMPy/src/ESMF/util/decorators.py +++ b/src/addon/ESMPy/src/ESMF/util/decorators.py @@ -12,28 +12,6 @@ from ESMF.api.constants import LogKind, _ESMF_NETCDF from ESMF.util.exceptions import NetCDFMissing -try: - import nose - - def expected_failure(test): - @functools.wraps(test) - def inner(*args, **kwargs): - try: - test(*args, **kwargs) - except Exception: - raise nose.SkipTest - return inner -except: - def expected_failure(test): - @functools.wraps(test) - def inner(*args, **kwargs): - try: - test(*args, **kwargs) - except: - raise AssertionError('SkipTest: Failure expected') - return inner - - def beta(func): '''This is a decorator that can be used to mark functions as beta. Other decorators must be upper.''' diff --git a/src/addon/ESMPy/src/ESMF/util/exceptions.py b/src/addon/ESMPy/src/ESMF/util/exceptions.py index 4075087fc8..0ecb885176 100644 --- a/src/addon/ESMPy/src/ESMF/util/exceptions.py +++ b/src/addon/ESMPy/src/ESMF/util/exceptions.py @@ -26,6 +26,10 @@ class SerialMethod(ESMPyException): """This method is not safe to run in parallel!""" pass +class SkipTest(ESMPyException): + """This test is skipped for some reason.""" + pass + class GridException(ESMPyException): @@ -79,12 +83,3 @@ class FieldDOError(FieldException): """Raised when an attempt is made to build a Field on an undefined discretization object (e.g. not a Grid or a Mesh)""" pass - -class TestException(ESMPyException): - """Base class for errors in the ESMPy testing.""" - pass - -class TestGridWriteBeforeCoords(TestException): - """Raised when an attempt is made to write a Grid before c - coordinates have been specified""" - pass From aead97d6220044c540e89028184f8d6e3cebdc88 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Mon, 22 Aug 2022 14:37:06 -0600 Subject: [PATCH 08/45] Cheyenne adjustments --- src/addon/ESMPy/Makefile | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/addon/ESMPy/Makefile b/src/addon/ESMPy/Makefile index 78eeea3042..770c6634c0 100644 --- a/src/addon/ESMPy/Makefile +++ b/src/addon/ESMPy/Makefile @@ -14,34 +14,33 @@ clean: # rm -rf src/ESMF/test/regrid_from_file/data') # rm -rf examples/data') - install: - pip install . + python3 -m pip install --user . test_unit: - pytest -m="not parallel" + python3 -m pytest -m="not parallel" test_unit_parallel: - mpirun -n 4 python -m pytest -m="not serial" + mpirun -n 4 python3 -m pytest -m="not serial" test_examples_dryrun: - pytest -vs examples/exampletestdryrun.py + python3 -m pytest -vs examples/exampletestdryrun.py test_examples: - pytest -m="not parallel" examples/exampletest.py + python3 -m pytest -vs -m="not parallel" examples/exampletest.py test_examples_parallel: - mpirun -n 4 python -m pytest -m="not serial" examples/exampletest.py + mpirun -n 4 python3 -vs -m pytest -m="not serial" examples/exampletest.py test_regrid_from_file_dryrun: - pytest -vs src/ESMF/test/regrid_from_file/rfftestdryrun.py + python3 -m pytest -vs src/ESMF/test/regrid_from_file/rfftestdryrun.py test_regrid_from_file: - pytest -vs src/ESMF/test/regrid_from_file/rfftest.py + python3 -m pytest -vs src/ESMF/test/regrid_from_file/rfftest.py test_regrid_from_file_parallel: - pytest -vs src/ESMF/test/regrid_from_file/rfftestdryrun.py - mpirun -n 4 python -m pytest -vs src/ESMF/test/regrid_from_file/rfftest.py + python3 -m pytest -vs src/ESMF/test/regrid_from_file/rfftestdryrun.py + mpirun -n 4 python3 -m pytest -vs src/ESMF/test/regrid_from_file/rfftest.py test_all: test_unit test_parallel test_examples_dryrun test_examples test_examples_parallel @@ -50,4 +49,5 @@ test: test_unit test_unit_parallel test_examples test_examples_parallel test_uni: test_unit test_examples uninstall: - pip uninstall ESMPy + python3 -m pip uninstall ESMPy + From 84cf0c115f1daabd965549de2d3aef1d9e703de2 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Mon, 22 Aug 2022 13:37:43 -0700 Subject: [PATCH 09/45] remove more unittest usage --- src/addon/ESMPy/examples/grid_locstream_regrid.py | 5 ----- src/addon/ESMPy/examples/locstream_grid_regrid.py | 5 ----- src/addon/ESMPy/examples/mesh_locstream_regrid.py | 5 ----- src/addon/ESMPy/src/ESMF/test/base_test.py | 5 ----- src/addon/ESMPy/src/ESMF/test/test_api/test_locstream.py | 5 ++--- src/addon/ESMPy/src/ESMF/test/test_cbindings.py | 6 ++---- 6 files changed, 4 insertions(+), 27 deletions(-) diff --git a/src/addon/ESMPy/examples/grid_locstream_regrid.py b/src/addon/ESMPy/examples/grid_locstream_regrid.py index ffcdf7b535..bd64c03c5f 100644 --- a/src/addon/ESMPy/examples/grid_locstream_regrid.py +++ b/src/addon/ESMPy/examples/grid_locstream_regrid.py @@ -9,11 +9,6 @@ # from ESMF.util.cache_data import cache_data_file # cache_data_file(os.path.join(DD, "ll1deg_grid.nc")) -try: - from unittest import SkipTest -except ImportError: - from nose import SkipTest - import ESMF import numpy diff --git a/src/addon/ESMPy/examples/locstream_grid_regrid.py b/src/addon/ESMPy/examples/locstream_grid_regrid.py index e09db8956b..534f89a4cf 100644 --- a/src/addon/ESMPy/examples/locstream_grid_regrid.py +++ b/src/addon/ESMPy/examples/locstream_grid_regrid.py @@ -9,11 +9,6 @@ # from ESMF.util.cache_data import cache_data_file # cache_data_file(os.path.join(DD, "ll1deg_grid.nc")) -try: - from unittest import SkipTest -except ImportError: - from nose import SkipTest - import ESMF import numpy diff --git a/src/addon/ESMPy/examples/mesh_locstream_regrid.py b/src/addon/ESMPy/examples/mesh_locstream_regrid.py index c707a6c56e..a5f218ff0c 100644 --- a/src/addon/ESMPy/examples/mesh_locstream_regrid.py +++ b/src/addon/ESMPy/examples/mesh_locstream_regrid.py @@ -1,10 +1,5 @@ # This example demonstrates how to regrid between a mesh and a locstream. -try: - from unittest import SkipTest -except ImportError: - from nose import SkipTest - import ESMF import numpy diff --git a/src/addon/ESMPy/src/ESMF/test/base_test.py b/src/addon/ESMPy/src/ESMF/test/base_test.py index 27a249db30..ba7bfd7a3c 100644 --- a/src/addon/ESMPy/src/ESMF/test/base_test.py +++ b/src/addon/ESMPy/src/ESMF/test/base_test.py @@ -1,9 +1,7 @@ -import unittest from ESMF.test.base import TestBase import numpy as np from ESMF import Manager - class Test(TestBase): def setup(self): @@ -24,6 +22,3 @@ def test_assertNumpyAll_type_differs(self): def tearDown(self): mg = Manager() # mg.barrier() - -if __name__ == "__main__": - unittest.main() diff --git a/src/addon/ESMPy/src/ESMF/test/test_api/test_locstream.py b/src/addon/ESMPy/src/ESMF/test/test_api/test_locstream.py index 1cdcb3dbdf..92a3af7c45 100644 --- a/src/addon/ESMPy/src/ESMF/test/test_api/test_locstream.py +++ b/src/addon/ESMPy/src/ESMF/test/test_api/test_locstream.py @@ -7,7 +7,6 @@ from ESMF.interface.cbindings import * from ESMF.test.base import TestBase, attr -import unittest import pytest class TestLocStream(TestBase): @@ -70,7 +69,7 @@ def test_slice(self): assert(np.all(locstream["ESMF:X"] == np.array([0, 1, 2, 3, 4]))) - @unittest.expectedFailure + @pytest.mark.xfail def test_pickle(self): locstream = LocStream(10, name="Test LocStream") @@ -78,7 +77,7 @@ def test_pickle(self): pickle.dumps(locstream) - @unittest.expectedFailure + @pytest.mark.xfail def test_properties(self): locstream = LocStream(10, name="Test LocStream") locstream["ESMF:X"] = (1, 2, 3, 4, 5) diff --git a/src/addon/ESMPy/src/ESMF/test/test_cbindings.py b/src/addon/ESMPy/src/ESMF/test/test_cbindings.py index a7369977d5..391c9ff91b 100644 --- a/src/addon/ESMPy/src/ESMF/test/test_cbindings.py +++ b/src/addon/ESMPy/src/ESMF/test/test_cbindings.py @@ -10,8 +10,6 @@ import numpy as np -import unittest - class TestCbindings(TestBase): def test_log(self): @@ -34,7 +32,7 @@ def test_interfaceint(self): interfaceint = ESMP_InterfaceInt(Narray) - @unittest.expectedFailure + @pytest.mark.xfail def test_interfaceint2(self): # This test should fail try: @@ -44,7 +42,7 @@ def test_interfaceint2(self): except: raise TypeError('FAIL: tuples cannot be used in place of numpy.array') - @unittest.expectedFailure + @pytest.mark.xfail def test_interfaceint3(self): # This test should fail try: From 05591045414eb892b1ef6111ad4029f65169e638 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Mon, 22 Aug 2022 15:20:16 -0600 Subject: [PATCH 10/45] add pytest import to test_cbindings --- src/addon/ESMPy/src/ESMF/test/test_cbindings.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/addon/ESMPy/src/ESMF/test/test_cbindings.py b/src/addon/ESMPy/src/ESMF/test/test_cbindings.py index 391c9ff91b..2099857328 100644 --- a/src/addon/ESMPy/src/ESMF/test/test_cbindings.py +++ b/src/addon/ESMPy/src/ESMF/test/test_cbindings.py @@ -4,6 +4,8 @@ unit test file """ +import pytest + from ESMF import * from ESMF.interface.cbindings import * from ESMF.test.base import TestBase, attr From 31e0ccfbbddc227a18a0724562e3d2e9e6a4cf90 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Mon, 22 Aug 2022 14:47:14 -0700 Subject: [PATCH 11/45] use unittest.SkipTest, cleanup some warnings, more adjustments to makefile targets --- src/addon/ESMPy/Makefile | 27 +++++---- src/addon/ESMPy/examples/exampletest.py | 2 +- .../ESMPy/examples/grid_locstream_regrid.py | 1 + .../ESMPy/examples/locstream_grid_regrid.py | 1 + .../ESMPy/examples/mesh_locstream_regrid.py | 1 + src/addon/ESMPy/src/ESMF/test/base.py | 1 + .../src/ESMF/test/test_api/test_field.py | 2 +- .../ESMPy/src/ESMF/test/test_api/test_mesh.py | 2 +- .../src/ESMF/test/test_api/test_regrid.py | 2 +- src/addon/ESMPy/src/ESMF/util/exceptions.py | 5 -- .../ESMPy/src/ESMF/util/grid_utilities.py | 20 +++---- .../ESMPy/src/ESMF/util/mesh_utilities.py | 56 +++++++++---------- 12 files changed, 59 insertions(+), 61 deletions(-) diff --git a/src/addon/ESMPy/Makefile b/src/addon/ESMPy/Makefile index 770c6634c0..caa773d0c3 100644 --- a/src/addon/ESMPy/Makefile +++ b/src/addon/ESMPy/Makefile @@ -3,16 +3,16 @@ clean: rm -rf build rm -rf dist - rm -rf *.egg-info - # find . -name "*.pyc" -exec rm -f {} \;') - # find . -name "*ESMF_LogFile*" -exec rm -f {} \;') - # find . -name "*.log" -exec rm -f {} \;') - # find . -name "*.vtk" -exec rm -f {} \;') - # rm src/ESMF/interface/esmfmkfile.py') - # rm -rf build') - # rm -rf dist') - # rm -rf src/ESMF/test/regrid_from_file/data') - # rm -rf examples/data') + find . -name "*.egg-info" -exec rm -rf {} \; + find . -name "*.pyc" -exec rm -f {} \; + find . -name "*ESMF_LogFile*" -exec rm -f {} \; + find . -name "*.log" -exec rm -f {} \; + find . -name "*.vtk" -exec rm -f {} \; + find . -name "*.pytest_cache" -exec rm -rf {} \; + find . -name "*.python-version" -exec rm -f {} \; + rm -rf src/ESMF/test/regrid_from_file/data + rm -rf examples/data + rm src/ESMF/interface/esmfmkfile.py install: python3 -m pip install --user . @@ -30,7 +30,7 @@ test_examples: python3 -m pytest -vs -m="not parallel" examples/exampletest.py test_examples_parallel: - mpirun -n 4 python3 -vs -m pytest -m="not serial" examples/exampletest.py + mpirun -n 4 python3 -m pytest -vs -m="not serial" examples/exampletest.py test_regrid_from_file_dryrun: python3 -m pytest -vs src/ESMF/test/regrid_from_file/rfftestdryrun.py @@ -42,12 +42,11 @@ test_regrid_from_file_parallel: python3 -m pytest -vs src/ESMF/test/regrid_from_file/rfftestdryrun.py mpirun -n 4 python3 -m pytest -vs src/ESMF/test/regrid_from_file/rfftest.py -test_all: test_unit test_parallel test_examples_dryrun test_examples test_examples_parallel +test_all: test_unit test_parallel test_examples test_examples_parallel -test: test_unit test_unit_parallel test_examples test_examples_parallel +test_parallel: test_unit_parallel test_examples_dryrun test_examples_parallel test_uni: test_unit test_examples uninstall: python3 -m pip uninstall ESMPy - diff --git a/src/addon/ESMPy/examples/exampletest.py b/src/addon/ESMPy/examples/exampletest.py index a48a59480d..d82f2e56ad 100644 --- a/src/addon/ESMPy/examples/exampletest.py +++ b/src/addon/ESMPy/examples/exampletest.py @@ -6,7 +6,7 @@ import pytest -from ESMF.test.base import TestBase, attr +from ESMF.test.base import TestBase, attr, SkipTest import ESMF.api.constants as constants class TestExamples(TestBase): diff --git a/src/addon/ESMPy/examples/grid_locstream_regrid.py b/src/addon/ESMPy/examples/grid_locstream_regrid.py index bd64c03c5f..164d5c9211 100644 --- a/src/addon/ESMPy/examples/grid_locstream_regrid.py +++ b/src/addon/ESMPy/examples/grid_locstream_regrid.py @@ -14,6 +14,7 @@ import ESMF.util.helpers as helpers import ESMF.api.constants as constants +from ESMF.test.base import SkipTest # This call enables debug logging ESMF.Manager(debug=True) diff --git a/src/addon/ESMPy/examples/locstream_grid_regrid.py b/src/addon/ESMPy/examples/locstream_grid_regrid.py index 534f89a4cf..4d1019b409 100644 --- a/src/addon/ESMPy/examples/locstream_grid_regrid.py +++ b/src/addon/ESMPy/examples/locstream_grid_regrid.py @@ -14,6 +14,7 @@ import ESMF.util.helpers as helpers import ESMF.api.constants as constants +from ESMF.test.base import TestBase, attr, SkipTest # This call enables debug logging ESMF.Manager(debug=True) diff --git a/src/addon/ESMPy/examples/mesh_locstream_regrid.py b/src/addon/ESMPy/examples/mesh_locstream_regrid.py index a5f218ff0c..e88425410c 100644 --- a/src/addon/ESMPy/examples/mesh_locstream_regrid.py +++ b/src/addon/ESMPy/examples/mesh_locstream_regrid.py @@ -5,6 +5,7 @@ import ESMF.util.helpers as helpers import ESMF.api.constants as constants +from ESMF.test.base import TestBase, attr, SkipTest # This call enables debug logging # ESMF.Manager(debug=True) diff --git a/src/addon/ESMPy/src/ESMF/test/base.py b/src/addon/ESMPy/src/ESMF/test/base.py index c54a9dd952..e0ad849d30 100644 --- a/src/addon/ESMPy/src/ESMF/test/base.py +++ b/src/addon/ESMPy/src/ESMF/test/base.py @@ -3,6 +3,7 @@ import ESMF from ESMF.util.itester import iter_product_keywords +from unittest import SkipTest class TestBase(unittest.TestCase): diff --git a/src/addon/ESMPy/src/ESMF/test/test_api/test_field.py b/src/addon/ESMPy/src/ESMF/test/test_api/test_field.py index 4ffb5ae7da..a77fa63dfb 100644 --- a/src/addon/ESMPy/src/ESMF/test/test_api/test_field.py +++ b/src/addon/ESMPy/src/ESMF/test/test_api/test_field.py @@ -6,7 +6,7 @@ from ESMF import * from ESMF.interface.cbindings import * -from ESMF.test.base import TestBase, attr +from ESMF.test.base import TestBase, attr, SkipTest from ESMF.util.mesh_utilities import mesh_create_50, mesh_create_50_parallel diff --git a/src/addon/ESMPy/src/ESMF/test/test_api/test_mesh.py b/src/addon/ESMPy/src/ESMF/test/test_api/test_mesh.py index 6bd06f4cf0..2faa246899 100644 --- a/src/addon/ESMPy/src/ESMF/test/test_api/test_mesh.py +++ b/src/addon/ESMPy/src/ESMF/test/test_api/test_mesh.py @@ -10,7 +10,7 @@ import ESMF from ESMF import * -from ESMF.test.base import TestBase, attr +from ESMF.test.base import TestBase, attr, SkipTest from ESMF.util.mesh_utilities import * class TestMesh(TestBase): diff --git a/src/addon/ESMPy/src/ESMF/test/test_api/test_regrid.py b/src/addon/ESMPy/src/ESMF/test/test_api/test_regrid.py index cacf811154..aaac4f78cd 100644 --- a/src/addon/ESMPy/src/ESMF/test/test_api/test_regrid.py +++ b/src/addon/ESMPy/src/ESMF/test/test_api/test_regrid.py @@ -7,7 +7,7 @@ import os from ESMF import * -from ESMF.test.base import TestBase, attr +from ESMF.test.base import TestBase, attr, SkipTest from ESMF.util.field_utilities import compare_fields from ESMF.util.grid_utilities import * from ESMF.util.mesh_utilities import * diff --git a/src/addon/ESMPy/src/ESMF/util/exceptions.py b/src/addon/ESMPy/src/ESMF/util/exceptions.py index 0ecb885176..3924539904 100644 --- a/src/addon/ESMPy/src/ESMF/util/exceptions.py +++ b/src/addon/ESMPy/src/ESMF/util/exceptions.py @@ -26,11 +26,6 @@ class SerialMethod(ESMPyException): """This method is not safe to run in parallel!""" pass -class SkipTest(ESMPyException): - """This test is skipped for some reason.""" - pass - - class GridException(ESMPyException): """Base class for errors in the Grid class.""" diff --git a/src/addon/ESMPy/src/ESMF/util/grid_utilities.py b/src/addon/ESMPy/src/ESMF/util/grid_utilities.py index cf2492a432..2227f3bb62 100644 --- a/src/addon/ESMPy/src/ESMF/util/grid_utilities.py +++ b/src/addon/ESMPy/src/ESMF/util/grid_utilities.py @@ -401,12 +401,12 @@ def grid_create_from_coordinates_periodic_3d(longitudes, latitudes, heights, return grid def initialize_field_grid(field, domask=False, doarea=False): - ''' + """ PRECONDITIONS: A Field has been created. POSTCONDITIONS: The 'field' has been initialized to an analytic field. RETURN VALUES: \n Field :: field \n - ''' + """ if domask: mask = field.grid.get_item(ESMF.GridItem.MASK) @@ -423,14 +423,14 @@ def initialize_field_grid(field, domask=False, doarea=False): return field def initialize_field_grid_periodic(field): - ''' + """ PRECONDITIONS: A Field has been created as 'field' with a 'grid' where coordinates have been set on both the center and corner stagger locations. \n POSTCONDITIONS: The 'field' has been initialized to an analytic field.\n RETURN VALUES: \n Field :: field \n - ''' + """ DEG2RAD = 3.141592653589793/180.0 # get the coordinate pointers and set the coordinates @@ -444,14 +444,14 @@ def initialize_field_grid_periodic(field): return field def initialize_field_grid_periodic_3d(field): - ''' + """ PRECONDITIONS: A Field has been created as 'field' with a 'grid' where coordinates have been set on both the center and corner stagger locations. \n POSTCONDITIONS: The 'field' has been initialized to an analytic field.\n RETURN VALUES: \n Field :: field \n - ''' + """ DEG2RAD = 3.141592653589793/180.0 # get the coordinate pointers and set the coordinates @@ -467,12 +467,12 @@ def initialize_field_grid_periodic_3d(field): return field def initialize_field_grid_3d(field, domask=False): - ''' + """ PRECONDITIONS: A Field has been created. POSTCONDITIONS: The 'field' has been initialized to an analytic field. RETURN VALUES: \n Field :: field \n - ''' + """ if domask: mask = field.grid.get_item(ESMF.GridItem.MASK) @@ -491,14 +491,14 @@ def initialize_field_grid_3d(field, domask=False): def compute_mass_grid(valuefield, dofrac=False, fracfield=None, uninitval=422397696.): - ''' + """ PRECONDITIONS: 'fracfield' contains the fractions of each cell which contributed to a regridding operation involving 'valuefield. 'dofrac' is a boolean value that gives the option to not use the 'fracfield'.\n POSTCONDITIONS: The mass of the data field is computed.\n RETURN VALUES: float :: mass \n - ''' + """ mass = 0.0 areafield = ESMF.Field(valuefield.grid, name='areafield') areafield.get_area() diff --git a/src/addon/ESMPy/src/ESMF/util/mesh_utilities.py b/src/addon/ESMPy/src/ESMF/util/mesh_utilities.py index 40b2cc030d..f9ff990b16 100644 --- a/src/addon/ESMPy/src/ESMF/util/mesh_utilities.py +++ b/src/addon/ESMPy/src/ESMF/util/mesh_utilities.py @@ -19,7 +19,7 @@ def mesh_create_5_pentahexa(coord_sys=None): - ''' + """ PRECONDITIONS: None POSTCONDITIONS: A 5 element Mesh has been created. RETURN VALUES: \n Mesh :: mesh \n @@ -43,7 +43,7 @@ def mesh_create_5_pentahexa(coord_sys=None): Element Ids in centers Note: This mesh is not parallel, it can only be used in serial - ''' + """ # Two parametric dimensions, and two spatial dimensions mesh = ESMF.Mesh(parametric_dim=2, spatial_dim=2, coord_sys=coord_sys) @@ -91,7 +91,7 @@ def mesh_create_5_pentahexa(coord_sys=None): return mesh, nodeCoord, nodeOwner, elemType, elemConn def mesh_create_4_ngons(): - ''' + """ PRECONDITIONS: None POSTCONDITIONS: A 4 element Mesh has been created. RETURN VALUES: \n Mesh :: mesh \n @@ -113,7 +113,7 @@ def mesh_create_4_ngons(): Element Ids in centers Note: This mesh is not parallel, it can only be used in serial - ''' + """ # Two parametric dimensions, and two spatial dimensions mesh = ESMF.Mesh(parametric_dim=2, spatial_dim=2) @@ -149,7 +149,7 @@ def mesh_create_4_ngons(): return mesh, nodeCoord, nodeOwner, elemType, elemConn def mesh_create_5(): - ''' + """ PRECONDITIONS: None POSTCONDITIONS: A 5 element Mesh has been created. RETURN VALUES: \n Mesh :: mesh \n @@ -170,7 +170,7 @@ def mesh_create_5(): Element Ids in centers Note: This mesh is not parallel, it can only be used in serial - ''' + """ # Two parametric dimensions, and two spatial dimensions mesh = ESMF.Mesh(parametric_dim=2, spatial_dim=2) @@ -212,7 +212,7 @@ def mesh_create_5(): return mesh, nodeCoord, nodeOwner, elemType, elemConn, elemCoord def mesh_create_10(): - ''' + """ PRECONDITIONS: None POSTCONDITIONS: A 10 element Mesh has been created. RETURN VALUES: \n Mesh :: mesh \n @@ -237,7 +237,7 @@ def mesh_create_10(): Element Ids in centers Note: This mesh is not parallel, it can only be used in serial - ''' + """ # Two parametric dimensions, and two spatial dimensions mesh = ESMF.Mesh(parametric_dim=2, spatial_dim=2) @@ -281,7 +281,7 @@ def mesh_create_10(): return mesh, nodeCoord, nodeOwner, elemType, elemConn, elemCoord def mesh_create_50(domask=False, doarea=False): - ''' + """ PRECONDITIONS: None POSTCONDITIONS: A 50 element Mesh has been created. RETURN VALUES: \n Mesh :: mesh \n @@ -322,7 +322,7 @@ def mesh_create_50(domask=False, doarea=False): Element Ids in centers Note: This mesh is not parallel, it can only be used in serial - ''' + """ # Two parametric dimensions, and two spatial dimensions mesh = ESMF.Mesh(parametric_dim=2, spatial_dim=2) @@ -397,7 +397,7 @@ def mesh_create_50(domask=False, doarea=False): return mesh, nodeCoord, nodeOwner, elemType, elemConn, elemCoord def mesh_create_50_ngons(domask=False, doarea=False): - ''' + """ PRECONDITIONS: None POSTCONDITIONS: A 50 element Mesh has been created. RETURN VALUES: \n Mesh :: mesh \n @@ -443,7 +443,7 @@ def mesh_create_50_ngons(domask=False, doarea=False): Element Ids in centers Note: This mesh is not parallel, it can only be used in serial - ''' + """ # Two parametric dimensions, and two spatial dimensions mesh = ESMF.Mesh(parametric_dim=2, spatial_dim=2) @@ -524,7 +524,7 @@ def mesh_create_50_ngons(domask=False, doarea=False): return mesh, nodeCoord, nodeOwner, elemType, elemConn def mesh_create_4_ngons(domask=False, doarea=False): - ''' + """ PRECONDITIONS: None POSTCONDITIONS: A 4 element Mesh has been created. RETURN VALUES: \n Mesh :: mesh \n @@ -546,7 +546,7 @@ def mesh_create_4_ngons(domask=False, doarea=False): Element Ids in centers Note: This mesh is not parallel, it can only be used in serial - ''' + """ # Two parametric dimensions, and two spatial dimensions mesh = ESMF.Mesh(parametric_dim=2, spatial_dim=2) @@ -592,7 +592,7 @@ def mesh_create_4_ngons(domask=False, doarea=False): return mesh, nodeCoord, nodeOwner, elemType, elemConn def mesh_create_5_parallel (): - ''' + """ PRECONDITIONS: None POSTCONDITIONS: A 5 element Mesh has been created in parallel. RETURN VALUES: \n Mesh :: mesh \n @@ -620,7 +620,7 @@ def mesh_create_5_parallel (): # # Node Id labels at corners # Element Id labels in centers - ''' + """ # Two parametric dimensions, and two spatial dimensions mesh = ESMF.Mesh(parametric_dim=2, spatial_dim=2) @@ -702,7 +702,7 @@ def mesh_create_5_parallel (): return mesh, nodeCoord, nodeOwner, elemType, elemConn def mesh_create_5_pentahexa_parallel (): - ''' + """ PRECONDITIONS: None POSTCONDITIONS: A 5 element Mesh has been created in parallel. RETURN VALUES: \n Mesh :: mesh \n @@ -733,7 +733,7 @@ def mesh_create_5_pentahexa_parallel (): # # Node Id labels at corners # Element Id labels in centers - ''' + """ # Two parametric dimensions, and two spatial dimensions mesh = ESMF.Mesh(parametric_dim=2, spatial_dim=2) @@ -821,7 +821,7 @@ def mesh_create_5_pentahexa_parallel (): return mesh, nodeCoord, nodeOwner, elemType, elemConn def mesh_create_10_parallel (): - ''' + """ PRECONDITIONS: None POSTCONDITIONS: A 10 element Mesh has been created in parallel. RETURN VALUES: \n Mesh :: mesh \n @@ -855,7 +855,7 @@ def mesh_create_10_parallel (): # # Node Id labels at corners # Element Id labels in centers - ''' + """ if ESMF.pet_count() > 1: if ESMF.pet_count() != 4: raise NameError('MPI rank must be 4 to build this mesh!') @@ -947,7 +947,7 @@ def mesh_create_10_parallel (): return mesh, nodeCoord, nodeOwner, elemType, elemConn def mesh_create_50_parallel(domask=False, doarea=False): - ''' + """ PRECONDITIONS: None POSTCONDITIONS: A 50 element Mesh has been created in parallel. RETURN VALUES: \n Mesh :: mesh \n @@ -993,7 +993,7 @@ def mesh_create_50_parallel(domask=False, doarea=False): Node Ids at corners Element Ids in centers - ''' + """ if ESMF.pet_count() > 1: if ESMF.pet_count() != 4: raise NameError('MPI rank must be 4 to build this mesh!') @@ -1137,7 +1137,7 @@ def mesh_create_50_parallel(domask=False, doarea=False): return mesh, nodeCoord, nodeOwner, elemType, elemConn def mesh_create_50_ngons_parallel(domask=False, doarea=False): - ''' + """ PRECONDITIONS: None POSTCONDITIONS: A 50 element Mesh has been created in parallel. RETURN VALUES: \n Mesh :: mesh \n @@ -1188,7 +1188,7 @@ def mesh_create_50_ngons_parallel(domask=False, doarea=False): Node Ids at corners Element Ids in centers - ''' + """ if ESMF.pet_count() > 1: if ESMF.pet_count() != 4: raise NameError('MPI rank must be 4 to build this mesh!') @@ -1337,12 +1337,12 @@ def mesh_create_50_ngons_parallel(domask=False, doarea=False): def initialize_field_mesh(field, nodeCoord, nodeOwner, elemType, elemConn, domask=False, elemMask=None): - ''' + """ PRECONDITIONS: A Field has been created on the elements of a Mesh. POSTCONDITIONS: The Field has been initialized to an analytic field. RETURN VALUES: \n Field :: field \n - ''' + """ [node, element] = [0,1] @@ -1404,14 +1404,14 @@ def initialize_field_mesh(field, nodeCoord, nodeOwner, elemType, elemConn, def compute_mass_mesh(valuefield, dofrac=False, fracfield=None, uninitval=422397696.): - ''' + """ PRECONDITIONS: 'fracfield' contains the fractions of each cell which contributed to a regridding operation involving 'valuefield. 'dofrac' is a boolean value that gives the option to not use the 'fracfield'.\n POSTCONDITIONS: The mass of the data field is computed.\n RETURN VALUES: float :: mass \n - ''' + """ mass = 0.0 # mesh area field must be built on elements areafield = ESMF.Field(valuefield.grid, name='areafield', From 512b56a4aae41ec8badcc1a3647bd47874d386f1 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Tue, 23 Aug 2022 16:59:50 -0700 Subject: [PATCH 12/45] update ESMPy docs with pytest commands --- src/addon/ESMPy/doc/install.rst | 39 ++++++++++++++------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/src/addon/ESMPy/doc/install.rst b/src/addon/ESMPy/doc/install.rst index aec7b904b6..40a02896ff 100644 --- a/src/addon/ESMPy/doc/install.rst +++ b/src/addon/ESMPy/doc/install.rst @@ -17,7 +17,7 @@ The following packages are *optional*: * ESMF installation with NetCDF - required to create :class:`Grids ` and :class:`Meshes ` from file - NetCDF must be built as a shared library for ESMPy installation to succeed * `mpi4py `_- python bindings to MPI, needed to run some of the parallel regridding examples -* `nose2 `_ - for nose testing +* `pytest `_ - for testing ---------------- Getting the code @@ -76,7 +76,7 @@ with the following command issued from the top level ESMPy directory: .. code:: - pip install . + python3 -m pip install . Please contact esmf_support@ucar.edu with any questions. @@ -94,22 +94,29 @@ To use ESMPy in an external program, import it with: Validation ---------- -The ESMPy testing is done with the nose package, both in serial and -parallel. The nose commands are wrapped in the following ESMPy targets: +The ESMPy testing is done with the pytest package, both in serial and +parallel. Basic unit tests can be run with the following command: .. code:: - python setup.py test + python3 -m pytest + +There are a few other pytest targets available for a wider range of testing if +greater test coverage is desired: - python setup.py test_examples +.. code:: + + make test_unit + + make test_examples - python setup.py test_regrid_from_file + make test_regrid_from_file - python setup.py test_parallel + make test_unit_parallel - python setup.py test_examples_parallel + make test_examples_parallel - python setup.py test_regrid_from_file_parallel + make test_regrid_from_file_parallel .. Note:: @@ -118,18 +125,6 @@ parallel. The nose commands are wrapped in the following ESMPy targets: files without actually running them (allowing the stress on the machine to be applied to bandwidth first, and then memory). -Alternatively, individual tests can be run with nose using the following format: - -.. code:: - - nosetests : - -e.g. - -.. code:: - - nosetests src/ESMF/test/test_api/test_regrid.py:TestRegrid.test_field_regrid - ----------- Limitations ----------- From d808ee9846f95e630afd7dd212de65602ed6ed73 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Wed, 24 Aug 2022 12:26:12 -0700 Subject: [PATCH 13/45] remove the old esmfmkfile.py strategy from ESMPy --- src/addon/ESMPy/.gitignore | 1 - src/addon/ESMPy/Makefile | 1 - .../ESMPy/src/ESMF/interface/loadESMF.py | 19 ++----------------- 3 files changed, 2 insertions(+), 19 deletions(-) diff --git a/src/addon/ESMPy/.gitignore b/src/addon/ESMPy/.gitignore index 15e6c72411..c427f66ad7 100644 --- a/src/addon/ESMPy/.gitignore +++ b/src/addon/ESMPy/.gitignore @@ -30,7 +30,6 @@ PET* build dist doc/esmpy_doc -src/ESMF/interface/esmfmkfile.py src/ESMPy.egg-info examples/data src/ESMF/test/data diff --git a/src/addon/ESMPy/Makefile b/src/addon/ESMPy/Makefile index caa773d0c3..d0018c2723 100644 --- a/src/addon/ESMPy/Makefile +++ b/src/addon/ESMPy/Makefile @@ -12,7 +12,6 @@ clean: find . -name "*.python-version" -exec rm -f {} \; rm -rf src/ESMF/test/regrid_from_file/data rm -rf examples/data - rm src/ESMF/interface/esmfmkfile.py install: python3 -m pip install --user . diff --git a/src/addon/ESMPy/src/ESMF/interface/loadESMF.py b/src/addon/ESMPy/src/ESMF/interface/loadESMF.py index ca5395f4a3..dfed9ae412 100644 --- a/src/addon/ESMPy/src/ESMF/interface/loadESMF.py +++ b/src/addon/ESMPy/src/ESMF/interface/loadESMF.py @@ -20,25 +20,10 @@ raise ImportError('The CTypes library cannot be found.') esmfmk = None -mked = False -esmfmkfile_local = os.path.join(os.getcwd(),"src/ESMF/interface/esmfmkfile.py") try: - - if os.path.isfile(esmfmkfile_local): - from ESMF.interface.esmfmkfile import ESMFMKFILE as esmfmk - mked = True + esmfmk = os.environ["ESMFMKFILE"] except: - raise ImportError('The esmf.mk file could not be loaded.') -else: - if not mked: - esmfmk = os.getenv("ESMFMKFILE") - if not esmfmk: - raise ImportError('The ESMFMKFILE was not set in the build, nor is it available as an environment variable.') - else: - with open(esmfmkfile_local, 'w') as emfl: - emfl.write('ESMFMKFILE = "'+esmfmk+'"') - emfl.close() - + raise ImportError('The ESMFMKFILE environment variable is not available.') #### INVESTIGATE esmf.mk ###################################################### From f82e1ddf432e414eaa34794448a2bec50856da3d Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Wed, 24 Aug 2022 12:27:03 -0700 Subject: [PATCH 14/45] remove --user from ESMPy pip install target --- src/addon/ESMPy/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/addon/ESMPy/Makefile b/src/addon/ESMPy/Makefile index d0018c2723..2fd15cb6ee 100644 --- a/src/addon/ESMPy/Makefile +++ b/src/addon/ESMPy/Makefile @@ -14,7 +14,7 @@ clean: rm -rf examples/data install: - python3 -m pip install --user . + python3 -m pip install . test_unit: python3 -m pytest -m="not parallel" From 8e1b807dfae9b60773f634d96cce6f217f32cbfc Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Wed, 24 Aug 2022 12:29:33 -0700 Subject: [PATCH 15/45] add || : to allow clean target of ESMPy to continue if files labeled for removal do not exist --- src/addon/ESMPy/Makefile | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/addon/ESMPy/Makefile b/src/addon/ESMPy/Makefile index 2fd15cb6ee..08b852bbfb 100644 --- a/src/addon/ESMPy/Makefile +++ b/src/addon/ESMPy/Makefile @@ -1,17 +1,17 @@ .PHONY: clean install test test_int test_all uninstall clean: - rm -rf build - rm -rf dist - find . -name "*.egg-info" -exec rm -rf {} \; - find . -name "*.pyc" -exec rm -f {} \; - find . -name "*ESMF_LogFile*" -exec rm -f {} \; - find . -name "*.log" -exec rm -f {} \; - find . -name "*.vtk" -exec rm -f {} \; - find . -name "*.pytest_cache" -exec rm -rf {} \; - find . -name "*.python-version" -exec rm -f {} \; - rm -rf src/ESMF/test/regrid_from_file/data - rm -rf examples/data + rm -rf build || : + rm -rf dist || : + find . -name "*.egg-info" -exec rm -rf {} \; || : + find . -name "*.pyc" -exec rm -f {} \; || : + find . -name "*ESMF_LogFile*" -exec rm -f {} \; || : + find . -name "*.log" -exec rm -f {} \; || : + find . -name "*.vtk" -exec rm -f {} \; || : + find . -name "*.pytest_cache" -exec rm -rf {} \; || : + find . -name "*.python-version" -exec rm -f {} \; || : + rm -rf src/ESMF/test/regrid_from_file/data || : + rm -rf examples/data || : install: python3 -m pip install . From a5b56ebbdba4ce8dfb177f5ea329a6bfcdd62505 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Thu, 25 Aug 2022 17:36:36 -0700 Subject: [PATCH 16/45] add proper versions to ESMPy from git tags, and other metadata from setup.cfg --- src/addon/ESMPy/pyproject.toml | 34 +++-------------- src/addon/ESMPy/setup.cfg | 14 ++----- src/addon/ESMPy/src/ESMF/__init__.py | 56 +++++++++++++++++++++------- 3 files changed, 51 insertions(+), 53 deletions(-) diff --git a/src/addon/ESMPy/pyproject.toml b/src/addon/ESMPy/pyproject.toml index 044b8d7bc3..3879856669 100644 --- a/src/addon/ESMPy/pyproject.toml +++ b/src/addon/ESMPy/pyproject.toml @@ -1,28 +1,12 @@ [build-system] -requires = ["setuptools"] +requires = [ "setuptools>=41", "wheel", "setuptools-git-versioning", ] build-backend = "setuptools.build_meta" -# [project] -# name = "ESMPy" -# description = "ESMF Python interface" -# license = {text = "University of Illinois-NCSA"} -# readme = "README.md" -# # dynamic = ["version"] -# dependencies = [ -# "numpy", -# ] -# -# [tool.setuptools.packages.find] -# where = ["src"] -# exclude = [ -# "ESMPy.doc*", -# "ESMPy.example*", -# "ESMPy.test*", -# ] -# -# [tool.setuptools.dynamic] -# version = {attr = "ESMPy.VERSION"} -# +[tool.setuptools-git-versioning] +enabled = true +template = "{tag}" +dev_template = "{tag}" +dirty_template = "{tag}" [tool.pytest.ini_options] markers = [ @@ -30,9 +14,3 @@ markers = [ "parallel: marks a test which requires mpi (deselect with '-m \"not parallel\"')", "serial: marks a test which should be run on one core (deselect with '-m \"not serial\"')" ] -filterwarnings = [ - # "ignore:DeprecationWarning", - # note the use of single quote below to denote "raw" strings in TOML - # 'ignore:DeprecationWarning: Call to deprecated function ESMP_FieldRegridStoreFile', - # 'ignore:DeprecationWarning: Call to deprecated function ESMP_FieldSMMStore', -] diff --git a/src/addon/ESMPy/setup.cfg b/src/addon/ESMPy/setup.cfg index 1bbcf9f332..6a9d5feea2 100644 --- a/src/addon/ESMPy/setup.cfg +++ b/src/addon/ESMPy/setup.cfg @@ -1,19 +1,11 @@ [metadata] name = ESMPy -version = 8.4.0beta description = ESMF Python interface long_description = file: README.md, LICENSE license = University of Illinois-NCSA -author = University Corporation for Atmospheric Research, - Massachusetts Institute of Technology, - Geophysical Fluid Dynamics Laboratory, - University of Michigan, - National Centers for Environmental Prediction, - Los Alamos National Laboratory, - Argonne National Laboratory, - NASA Goddard Space Flight Center -author_email = "esmf_support@ucar.edu", -url="http://earthsystemmodeling.org/esmpy/", +author = University Corporation for Atmospheric Research, Massachusetts Institute of Technology, Geophysical Fluid Dynamics Laboratory, University of Michigan, National Centers for Environmental Prediction, Los Alamos National Laboratory, Argonne National Laboratory, NASA Goddard Space Flight Center +maintainer_email = esmf_support@ucar.edu +url = http://earthsystemmodeling.org/esmpy/ [options] diff --git a/src/addon/ESMPy/src/ESMF/__init__.py b/src/addon/ESMPy/src/ESMF/__init__.py index a82ce63453..0f93b78555 100644 --- a/src/addon/ESMPy/src/ESMF/__init__.py +++ b/src/addon/ESMPy/src/ESMF/__init__.py @@ -74,20 +74,48 @@ from ESMF.api.regrid import * from ESMF.api.constants import * from ESMF.util.helpers import * -from ESMF.api.constants import _ESMF_VERSION #### SET UP SOME INFO ######################################################### -__name__ = "ESMF" -__description__ = "ESMF Python interface" -__author__ = "University Corporation for Atmospheric Research, " + \ - "Massachusetts Institute of Technology, " + \ - "Geophysical Fluid Dynamics Laboratory, " + \ - "University of Michigan, " + \ - "National Centers for Environmental Prediction, " + \ - "Los Alamos National Laboratory, " + \ - "Argonne National Laboratory, " + \ - "NASA Goddard Space Flight Center" -__license__ = "University of Illinois-NCSA" -__release__ = _ESMF_VERSION -__version__ = _ESMF_VERSION +# pre Python 3.8, not sure how far yet +from pkg_resources import get_distribution +pkgInfo = get_distribution('ESMPy').get_metadata('METADATA') + +# parse it using email.Parser +from email import message_from_string +msg = message_from_string(pkgInfo) + +__name__ = msg["Name"] +__version__ = msg["Version"] +__author__ = msg["Author"] +__description__ = msg["Summary"] +__homepage__ = msg["Home-page"] +__email__ = msg["Maintainer-email"] +__license__ = msg["License"] + +# # this requires Python 3.8 or higher +# import importlib.metadata as ilm +# +# md = ilm.metadata("ESMPy") +# +# __name__ = md["Name"] +# __version__ = md["Version"] +# __author__ = md["Author"] +# __description__ = md["Description"] +# __summary__ = md["Summary"] +# __homepage__ = md["Home-page"] + +# # this is the old hardcoded version + +# __name__ = "ESMF" +# __version__ = "" +# __description__ = "ESMF Python interface" +# __author__ = "University Corporation for Atmospheric Research, " + \ +# "Massachusetts Institute of Technology, " + \ +# "Geophysical Fluid Dynamics Laboratory, " + \ +# "University of Michigan, " + \ +# "National Centers for Environmental Prediction, " + \ +# "Los Alamos National Laboratory, " + \ +# "Argonne National Laboratory, " + \ +# "NASA Goddard Space Flight Center" +# __license__ = "University of Illinois-NCSA" From 6b25561eaac96b1739385012fb57bc768a6547b8 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Thu, 25 Aug 2022 17:37:21 -0700 Subject: [PATCH 17/45] remove setup.py --- src/addon/ESMPy/setup.py.old | 278 ----------------------------------- 1 file changed, 278 deletions(-) delete mode 100644 src/addon/ESMPy/setup.py.old diff --git a/src/addon/ESMPy/setup.py.old b/src/addon/ESMPy/setup.py.old deleted file mode 100644 index d4f53c3191..0000000000 --- a/src/addon/ESMPy/setup.py.old +++ /dev/null @@ -1,278 +0,0 @@ -# $Id$ - -import os -import sys -from distutils.core import setup, Command -from distutils.util import get_platform -import subprocess - - -def download_test_data(func): - def wrapper(self): - update_system_path() - from ESMF.util.cache_data import cache_data_files - cache_data_files() - return func(self) - return wrapper - - -def update_system_path(): - if 'src' not in sys.path: - sys.path.insert(0, 'src') - - -class AbstractESMFCommand(Command): - user_options = [] - - def initialize_options(self): - self.cwd = None - - def finalize_options(self): - self.cwd = os.getcwd() - - def _validate_(self): - if os.getcwd() != self.cwd: - raise RuntimeError('Must be in package root: %s' % self.cwd) - - -class AbstractESMFNoseCommand(AbstractESMFCommand): - _nose_attrs = None - _nose_base_attrs = ['!slow'] - _nose_parallel = False - _nose_flags = None - _default_target = os.path.join('src', 'ESMF') - _needs_data = False - - def run(self): - self._validate_() - cmd = self.nosetests_command() - subprocess.check_call(cmd) - - @classmethod - def nosetests_command(cls): - ret = ['nosetests', '-vs', '--with-xunit'] - if not isinstance(cls._nose_attrs, type(None)): - nose_attrs = cls._nose_base_attrs + cls._nose_attrs - nose_attrs = ','.join(nose_attrs) - cmd_nose_attrs = ['-a', nose_attrs] - ret = ret + cmd_nose_attrs - - if cls._nose_parallel: - # Needed for ESMF constants import - sys.path.append('src') - - from ESMF.api import constants - - # -np is used in place of -n for esmf mpirun.srun wrapper - mpisyntax = "-n"; - if "mpirun.srun" in constants._ESMF_MPIRUN: - mpisyntax = "-np"; - mpirun_prefix = [constants._ESMF_MPIRUN, mpisyntax, str(constants._ESMF_MPIRUN_NP)] - ret = mpirun_prefix + ret - - if not isinstance(cls._nose_flags, type(None)): - ret.append(cls._nose_flags) - ret.append(cls._default_target) - return ret - - -class BuildCommand(AbstractESMFCommand): - description = "build: will build the ESMF package" - user_options = [('ESMFMKFILE=', 'e', - "Location of esmf.mk for the ESMF installation")] - - def initialize_options(self): - self.cwd = None - self.ESMFMKFILE = None - SITEDIR = os.system('%s -m site --user-site' % sys.executable) - self.build_base = 'build' - self.build_lib = None - self.plat_name = None - - def finalize_options(self): - self.cwd = os.getcwd() - if isinstance(self.ESMFMKFILE, type(None)): - self.ESMFMKFILE = os.getenv('ESMFMKFILE') - if isinstance(self.build_lib, type(None)): - self.build_lib = os.path.join(self.build_base, 'lib') - if isinstance(self.plat_name, type(None)): - self.plat_name = get_platform() - - def run(self): - assert os.getcwd() == self.cwd, 'Must be in package root: %s' % self.cwd - - # Create "esmfmkfile.py" file holding the path to the ESMF "esmf.mk" file - if not isinstance(self.ESMFMKFILE, type(None)): - f = open(os.path.join('src', 'ESMF', 'interface', 'esmfmkfile.py'), 'w') - f.write('ESMFMKFILE = "%s"' % self.ESMFMKFILE) - f.close() - - # Attempt to load ESMF. - update_system_path() - import ESMF.interface.loadESMF - - -class CleanCommand(AbstractESMFCommand): - description = "clean: will remove all libraries, log and output files" - - def run(self): - assert os.getcwd() == self.cwd, 'Must be in package root: %s' % self.cwd - os.system('find . -name "*.pyc" -exec rm -f {} \;') - os.system('find . -name "*ESMF_LogFile*" -exec rm -f {} \;') - os.system('find . -name "*.log" -exec rm -f {} \;') - os.system('find . -name "*.vtk" -exec rm -f {} \;') - os.system('rm src/ESMF/interface/esmfmkfile.py') - os.system('rm -rf build') - os.system('rm -rf dist') - os.system('rm -rf src/ESMF/test/regrid_from_file/data') - os.system('rm -rf examples/data') - - -class DustCommand(AbstractESMFCommand): - description = "dust: will remove log and output files" - - def run(self): - assert os.getcwd() == self.cwd, 'Must be in package root: %s' % self.cwd - os.system('find . -name "*ESMF_LogFile*" -exec rm -f {} \;') - os.system('find . -name "*.log" -exec rm -f {} \;') - os.system('find . -name "*.vtk" -exec rm -f {} \;') - os.system('find . -name "*.pyc" -exec rm -f {} \;') - - -class TestCommand(AbstractESMFNoseCommand): - description = "run serial tests" - _nose_attrs = ['!parallel'] - - -class TestParallelCommand(AbstractESMFNoseCommand): - description = "run parallel tests" - _nose_attrs = ['!serial'] - _nose_parallel = True - - -class TestRegridCommand(AbstractESMFNoseCommand): - description = "run test_regrid.py" - _default_target = os.path.join('src', 'ESMF', 'test', 'test_api', 'test_regrid.py') - - -class TestRegridParallelCommand(TestRegridCommand): - description = "test regrid parallel" - _nose_attrs = ['!serial'] - _nose_parallel = True - -class TestExamplesCommand(AbstractESMFNoseCommand): - description = "run examples in serial" - _nose_attrs = ['!parallel'] - _default_target = os.path.join('examples', 'exampletest.py') - - @download_test_data - def run(self): - update_system_path() - AbstractESMFNoseCommand.run(self) - -class TestExamplesParallelCommand(TestExamplesCommand): - description = "run examples in parallel" - _nose_attrs = ['!serial'] - _nose_parallel = True - -class TestExamplesDryrunCommand(TestExamplesCommand): - description = "collect example tests only and download data" - _nose_flags = '--collect-only' - - -class TestRegridFromFileCommand(AbstractESMFCommand): - description = "test regrid from file" - _filename = 'run_regrid_from_file.py' - _flags = None - - def run(self): - original_pp = os.environ.get('PYTHONPATH', '') - path = os.path.join(os.getcwd(), 'src') - os.environ['PYTHONPATH'] = '{0}:{1}'.format(path, original_pp) - self._validate_() - target = os.path.join('src', 'ESMF', 'test', 'regrid_from_file', self._filename) - cmd = [sys.executable, target] - if not isinstance(self._flags, type(None)): - cmd.append(self._flags) - subprocess.check_call(cmd) - - -class TestRegridFromFileDryrunCommand(TestRegridFromFileCommand): - description = "test regrid from file dryrun" - _filename = 'run_regrid_from_file_dryrun.py' - - -class TestRegridFromFileParallelCommand(TestRegridFromFileCommand): - description = "test regrid from file parallel" - _filename = 'run_regrid_from_file.py' - _flags = '--parallel' - - def run(self): - TestRegridFromFileCommand.run(self) - - -class TestAllCommand(AbstractESMFCommand): - description = "run serial, parallel, and example tests" - - @download_test_data - def run(self): - self._validate_() - to_run = [TestCommand, TestParallelCommand, TestExamplesCommand, TestExamplesParallelCommand] - for t in to_run: - cmd = t.nosetests_command() - subprocess.check_call(cmd) - - -# Get package structure -def _get_dot_(path, root='src'): - ret = [] - path_parse = path - while True: - path_parse, tail = os.path.split(path_parse) - if tail == root: - break - else: - ret.append(tail) - ret.reverse() - return '.'.join(ret) - - -src_path = os.path.join('src', 'ESMF') -packages = [] -for dirpath, dirnames, filenames in os.walk(src_path): - if '__init__.py' in filenames: - package = _get_dot_(dirpath) - packages.append(package) - -# TODO: build doc command -# TODO: remove duplicated metadata: here and src/ESMF/__init__.py -setup(name="ESMPy", - version="8.4.0", - description="ESMF Python interface", - author="University Corporation for Atmospheric Research, \ - Massachusetts Institute of Technology, \ - Geophysical Fluid Dynamics Laboratory, \ - University of Michigan, \ - National Centers for Environmental Prediction, \ - Los Alamos National Laboratory, \ - Argonne National Laboratory, \ - NASA Goddard Space Flight Center", - license="University of Illinois-NCSA", - author_email="esmf_support@ucar.edu", - url="http://earthsystemmodeling.org/esmpy/", - packages=packages, - package_dir={'': 'src'}, - cmdclass={'build': BuildCommand, - 'clean': CleanCommand, - 'dust': DustCommand, - 'test': TestCommand, - 'test_all': TestAllCommand, - 'test_parallel': TestParallelCommand, - 'test_examples': TestExamplesCommand, - 'test_examples_dryrun': TestExamplesDryrunCommand, - 'test_examples_parallel': TestExamplesParallelCommand, - 'test_regrid': TestRegridCommand, - 'test_regrid_from_file': TestRegridFromFileCommand, - 'test_regrid_from_file_dryrun': TestRegridFromFileDryrunCommand, - 'test_regrid_parallel': TestRegridParallelCommand, - 'test_regrid_from_file_parallel': TestRegridFromFileParallelCommand}) From 4cb82f5829464fbba828dff617b3956fc54e1bfe Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Fri, 26 Aug 2022 11:33:20 -0600 Subject: [PATCH 18/45] use importlib from Python 3.8 onward, pkg_resources before --- src/addon/ESMPy/src/ESMF/__init__.py | 54 +++++++++++++++------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/src/addon/ESMPy/src/ESMF/__init__.py b/src/addon/ESMPy/src/ESMF/__init__.py index 0f93b78555..0378e67de3 100644 --- a/src/addon/ESMPy/src/ESMF/__init__.py +++ b/src/addon/ESMPy/src/ESMF/__init__.py @@ -77,33 +77,37 @@ #### SET UP SOME INFO ######################################################### -# pre Python 3.8, not sure how far yet -from pkg_resources import get_distribution -pkgInfo = get_distribution('ESMPy').get_metadata('METADATA') +import sys -# parse it using email.Parser -from email import message_from_string -msg = message_from_string(pkgInfo) +if (sys.version_info >= (3,8)): + # this requires Python 3.8 or higher + import importlib.metadata as ilm + + md = ilm.metadata("ESMPy") + + __name__ = md["Name"] + __version__ = md["Version"] + __author__ = md["Author"] + __description__ = md["Description"] + __summary__ = md["Summary"] + __homepage__ = md["Home-page"] -__name__ = msg["Name"] -__version__ = msg["Version"] -__author__ = msg["Author"] -__description__ = msg["Summary"] -__homepage__ = msg["Home-page"] -__email__ = msg["Maintainer-email"] -__license__ = msg["License"] - -# # this requires Python 3.8 or higher -# import importlib.metadata as ilm -# -# md = ilm.metadata("ESMPy") -# -# __name__ = md["Name"] -# __version__ = md["Version"] -# __author__ = md["Author"] -# __description__ = md["Description"] -# __summary__ = md["Summary"] -# __homepage__ = md["Home-page"] +else: + # pre Python 3.8, not sure how far yet + from pkg_resources import get_distribution + pkgInfo = get_distribution('ESMPy').get_metadata('METADATA') + + # parse it using email.Parser + from email import message_from_string + msg = message_from_string(pkgInfo) + + __name__ = msg["Name"] + __version__ = msg["Version"] + __author__ = msg["Author"] + __description__ = msg["Summary"] + __homepage__ = msg["Home-page"] + __email__ = msg["Maintainer-email"] + __license__ = msg["License"] # # this is the old hardcoded version From 692b6daf271ae28d9f036ca1f397d742e78cb698 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Mon, 29 Aug 2022 14:48:10 -0700 Subject: [PATCH 19/45] enable pyproject.toml and remove setup.cfg, add starting_version to git-versioning --- src/addon/ESMPy/{setup.cfg => old.setup.cfg} | 5 ++- src/addon/ESMPy/pyproject.toml | 22 +++++++++++ src/addon/ESMPy/src/ESMF/__init__.py | 40 +++++++++++--------- 3 files changed, 48 insertions(+), 19 deletions(-) rename src/addon/ESMPy/{setup.cfg => old.setup.cfg} (91%) diff --git a/src/addon/ESMPy/setup.cfg b/src/addon/ESMPy/old.setup.cfg similarity index 91% rename from src/addon/ESMPy/setup.cfg rename to src/addon/ESMPy/old.setup.cfg index 6a9d5feea2..48cdbf3ff0 100644 --- a/src/addon/ESMPy/setup.cfg +++ b/src/addon/ESMPy/old.setup.cfg @@ -1,12 +1,13 @@ [metadata] name = ESMPy description = ESMF Python interface -long_description = file: README.md, LICENSE license = University of Illinois-NCSA author = University Corporation for Atmospheric Research, Massachusetts Institute of Technology, Geophysical Fluid Dynamics Laboratory, University of Michigan, National Centers for Environmental Prediction, Los Alamos National Laboratory, Argonne National Laboratory, NASA Goddard Space Flight Center maintainer_email = esmf_support@ucar.edu url = http://earthsystemmodeling.org/esmpy/ - +obsoletes = ESMF +requires = numpy +python_requires = '>=3.7', [options] zip_safe = False diff --git a/src/addon/ESMPy/pyproject.toml b/src/addon/ESMPy/pyproject.toml index 3879856669..00e35c5c30 100644 --- a/src/addon/ESMPy/pyproject.toml +++ b/src/addon/ESMPy/pyproject.toml @@ -2,11 +2,33 @@ requires = [ "setuptools>=41", "wheel", "setuptools-git-versioning", ] build-backend = "setuptools.build_meta" +[project] +name = "ESMPy" +description = "ESMF Python interface" +# readme = "README.md" +maintainers = [{author = "ESMF Core Team", email = "esmf_support@ucar.edu"}] +requires-python = ">=3.7" +license = {text = "University of Illinois-NCSA"} +dependencies = [ + "numpy", + 'importlib-metadata; python_version<"3.8"', +] +dynamic = ["version"] + [tool.setuptools-git-versioning] enabled = true template = "{tag}" dev_template = "{tag}" dirty_template = "{tag}" +starting_version = "8.4.0" # this is a backup for pip <= 22.0 where git-versioning doesn't work + +[tool.dynamic] +version = "placeholder" # this is a placeholder for the version pulled with git-versioning + + +[tool.setuptools.packages.find] +where = ["src"] +exclude = ["doc*", "examples*", "test*"] [tool.pytest.ini_options] markers = [ diff --git a/src/addon/ESMPy/src/ESMF/__init__.py b/src/addon/ESMPy/src/ESMF/__init__.py index 0378e67de3..a69935ab09 100644 --- a/src/addon/ESMPy/src/ESMF/__init__.py +++ b/src/addon/ESMPy/src/ESMF/__init__.py @@ -79,35 +79,41 @@ import sys +msg = "" + if (sys.version_info >= (3,8)): # this requires Python 3.8 or higher import importlib.metadata as ilm - md = ilm.metadata("ESMPy") - - __name__ = md["Name"] - __version__ = md["Version"] - __author__ = md["Author"] - __description__ = md["Description"] - __summary__ = md["Summary"] - __homepage__ = md["Home-page"] + msg = ilm.metadata("ESMPy") else: # pre Python 3.8, not sure how far yet from pkg_resources import get_distribution - pkgInfo = get_distribution('ESMPy').get_metadata('METADATA') + try: + pkgInfo = get_distribution('ESMPy').get_metadata('METADATA') + except: + try: + pkgInfo = get_distribution('ESMPy').get_metadata('PKG-INFO') + except: + raise ImportError("Could not find METADATA or PKG-INFO for ESMPy") # parse it using email.Parser from email import message_from_string msg = message_from_string(pkgInfo) - - __name__ = msg["Name"] - __version__ = msg["Version"] - __author__ = msg["Author"] - __description__ = msg["Summary"] - __homepage__ = msg["Home-page"] - __email__ = msg["Maintainer-email"] - __license__ = msg["License"] + +# set the private metadata +__name__ = msg["Name"] +__version__ = msg["Version"] +__license__ = msg["License"] +__email__ = msg["Maintainer-email"] +__description__ = msg["Summary"] +__requires__ = msg["Requires-Dist"] +__requires_python__ = msg["Requires-Python"] +# these don't seem to work with setuptools pyproject.toml +__author__ = msg["Author"] +__homepage__ = msg["Home-page"] +__obsoletes__ = msg["obsoletes"] # # this is the old hardcoded version From 277ef668804c7f16cc6d82d7ebf6551986c75644 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Tue, 30 Aug 2022 10:29:39 -0700 Subject: [PATCH 20/45] change module name ESMF to esmpy --- src/addon/ESMPy/.gitignore | 15 +- src/addon/ESMPy/Makefile | 10 +- src/addon/ESMPy/doc/CoordSys.rst | 2 +- src/addon/ESMPy/doc/ExtrapMethod.rst | 2 +- src/addon/ESMPy/doc/FileFormat.rst | 2 +- src/addon/ESMPy/doc/FileMode.rst | 2 +- src/addon/ESMPy/doc/GridItem.rst | 2 +- src/addon/ESMPy/doc/LineType.rst | 2 +- src/addon/ESMPy/doc/LogKind.rst | 2 +- src/addon/ESMPy/doc/MeshElemType.rst | 2 +- src/addon/ESMPy/doc/MeshLoc.rst | 2 +- src/addon/ESMPy/doc/NormType.rst | 2 +- src/addon/ESMPy/doc/PoleKind.rst | 2 +- src/addon/ESMPy/doc/PoleMethod.rst | 2 +- src/addon/ESMPy/doc/Region.rst | 2 +- src/addon/ESMPy/doc/RegridMethod.rst | 2 +- src/addon/ESMPy/doc/StaggerLoc.rst | 2 +- src/addon/ESMPy/doc/TypeKind.rst | 2 +- src/addon/ESMPy/doc/UnmappedAction.rst | 2 +- src/addon/ESMPy/doc/api.rst | 487 +++++++++--------- src/addon/ESMPy/doc/conf.py | 4 +- src/addon/ESMPy/doc/examples.rst | 32 +- src/addon/ESMPy/doc/field.rst | 2 +- src/addon/ESMPy/doc/grid.rst | 2 +- src/addon/ESMPy/doc/install.rst | 26 +- src/addon/ESMPy/doc/intro.rst | 3 +- src/addon/ESMPy/doc/locstream.rst | 2 +- src/addon/ESMPy/doc/manager.rst | 2 +- src/addon/ESMPy/doc/mesh.rst | 2 +- src/addon/ESMPy/doc/regrid.rst | 2 +- src/addon/ESMPy/doc/regridfromfile.rst | 2 +- .../examples/cubed_sphere_to_mesh_regrid.py | 48 +- src/addon/ESMPy/examples/exampletest.py | 6 +- src/addon/ESMPy/examples/exampletestdryrun.py | 4 +- src/addon/ESMPy/examples/field_read.py | 22 +- .../examples/grid_create_peridim_mask.py | 40 +- .../ESMPy/examples/grid_locstream_regrid.py | 42 +- src/addon/ESMPy/examples/hello_world.py | 6 +- .../ESMPy/examples/locstream_grid_regrid.py | 42 +- .../ESMPy/examples/mesh_locstream_regrid.py | 30 +- src/addon/ESMPy/examples/mpi_spawn_regrid.py | 36 +- .../notebooks/AdvancedRegridding.ipynb | 40 +- .../examples/notebooks/BasicRegridding.ipynb | 18 +- .../examples/notebooks/GridCellArea.ipynb | 18 +- .../notebooks/GridMeshLocStreamField.ipynb | 50 +- .../ESMPy/examples/notebooks/Periodic.ipynb | 24 +- .../notebooks/ugrid_latlon_regrid.ipynb | 32 +- .../ungridded_dimension_regrid.ipynb | 38 +- .../ESMPy/examples/read_write_weight_file.py | 56 +- src/addon/ESMPy/examples/regrid_from_file.py | 26 +- src/addon/ESMPy/examples/tripole_regrid.py | 46 +- .../ESMPy/examples/ugrid_latlon_regrid.py | 42 +- .../examples/ungridded_dimension_regrid.py | 52 +- .../regrid_from_file_consts.py | 31 -- .../ESMPy/src/{ESMF => esmpy}/__init__.py | 39 +- .../ESMPy/src/{ESMF => esmpy}/api/__init__.py | 0 .../src/{ESMF => esmpy}/api/constants.py | 78 +-- .../src/{ESMF => esmpy}/api/esmpymanager.py | 34 +- .../ESMPy/src/{ESMF => esmpy}/api/field.py | 102 ++-- .../ESMPy/src/{ESMF => esmpy}/api/grid.py | 152 +++--- .../src/{ESMF => esmpy}/api/locstream.py | 60 +-- .../ESMPy/src/{ESMF => esmpy}/api/mesh.py | 134 ++--- .../ESMPy/src/{ESMF => esmpy}/api/regrid.py | 130 ++--- .../fragments/dump_esmf_internal_info.py | 0 .../src/{ESMF => esmpy}/fragments/extras.py | 0 .../src/{ESMF => esmpy}/fragments/remap.py | 0 .../src/{ESMF => esmpy}/interface/__init__.py | 0 .../{ESMF => esmpy}/interface/cbindings.py | 8 +- .../src/{ESMF => esmpy}/interface/loadESMF.py | 2 +- .../src/{ESMF => esmpy}/test/__init__.py | 0 .../ESMPy/src/{ESMF => esmpy}/test/base.py | 4 +- .../src/{ESMF => esmpy}/test/base_test.py | 4 +- .../src/{ESMF => esmpy}/test/data/T42_grid.nc | Bin .../test/data/gridspec1Dcoords.nc | Bin .../{ESMF => esmpy}/test/data/ne4np4-esmf.nc | Bin .../test/data/ne4np4-pentagons.nc | Bin .../test/regrid_from_file/__init__.py | 0 .../read_test_cases_from_control_file.py | 2 +- .../test/regrid_from_file/regrid_check.py | 64 +-- .../regrid_from_file/regrid_check_driver.py | 24 +- .../regrid_from_file_consts.py | 31 ++ .../regrid_from_file/regrid_test_data.txt | 0 .../test/regrid_from_file/rfftest.py | 6 +- .../test/regrid_from_file/rfftestdryrun.py | 4 +- .../regrid_from_file/run_regrid_from_file.py | 4 +- .../run_regrid_from_file_dryrun.py | 6 +- .../{ESMF => esmpy}/test/test_api/__init__.py | 0 .../test/test_api/test_array.py | 8 +- .../test/test_api/test_field.py | 9 +- .../test/test_api/test_grid.py | 64 +-- .../test/test_api/test_locstream.py | 6 +- .../test/test_api/test_mesh.py | 18 +- .../test/test_api/test_regrid.py | 402 +++++++-------- .../{ESMF => esmpy}/test/test_api/test_vm.py | 6 +- .../{ESMF => esmpy}/test/test_cbindings.py | 6 +- .../src/{ESMF => esmpy}/util/__init__.py | 0 .../src/{ESMF => esmpy}/util/cache_data.py | 0 .../src/{ESMF => esmpy}/util/decorators.py | 8 +- .../src/{ESMF => esmpy}/util/enum/LICENSE | 0 .../src/{ESMF => esmpy}/util/enum/README | 0 .../src/{ESMF => esmpy}/util/enum/__init__.py | 0 .../{ESMF => esmpy}/util/enum/doc/enum.pdf | Bin .../{ESMF => esmpy}/util/enum/doc/enum.rst | 0 .../src/{ESMF => esmpy}/util/esmpyarray.py | 8 +- .../src/{ESMF => esmpy}/util/exceptions.py | 0 .../{ESMF => esmpy}/util/field_utilities.py | 18 +- .../{ESMF => esmpy}/util/grid_utilities.py | 144 +++--- .../ESMPy/src/{ESMF => esmpy}/util/helpers.py | 4 +- .../ESMPy/src/{ESMF => esmpy}/util/itester.py | 0 .../util/locstream_utilities.py | 54 +- .../{ESMF => esmpy}/util/mesh_utilities.py | 202 ++++---- .../ESMPy/src/{ESMF => esmpy}/util/slicing.py | 26 +- 112 files changed, 1606 insertions(+), 1639 deletions(-) delete mode 100644 src/addon/ESMPy/src/ESMF/test/regrid_from_file/regrid_from_file_consts.py rename src/addon/ESMPy/src/{ESMF => esmpy}/__init__.py (80%) rename src/addon/ESMPy/src/{ESMF => esmpy}/api/__init__.py (100%) rename src/addon/ESMPy/src/{ESMF => esmpy}/api/constants.py (84%) rename src/addon/ESMPy/src/{ESMF => esmpy}/api/esmpymanager.py (87%) rename src/addon/ESMPy/src/{ESMF => esmpy}/api/field.py (75%) rename src/addon/ESMPy/src/{ESMF => esmpy}/api/grid.py (89%) rename src/addon/ESMPy/src/{ESMF => esmpy}/api/locstream.py (79%) rename src/addon/ESMPy/src/{ESMF => esmpy}/api/mesh.py (81%) rename src/addon/ESMPy/src/{ESMF => esmpy}/api/regrid.py (81%) rename src/addon/ESMPy/src/{ESMF => esmpy}/fragments/dump_esmf_internal_info.py (100%) rename src/addon/ESMPy/src/{ESMF => esmpy}/fragments/extras.py (100%) rename src/addon/ESMPy/src/{ESMF => esmpy}/fragments/remap.py (100%) rename src/addon/ESMPy/src/{ESMF => esmpy}/interface/__init__.py (100%) rename src/addon/ESMPy/src/{ESMF => esmpy}/interface/cbindings.py (99%) rename src/addon/ESMPy/src/{ESMF => esmpy}/interface/loadESMF.py (99%) rename src/addon/ESMPy/src/{ESMF => esmpy}/test/__init__.py (100%) rename src/addon/ESMPy/src/{ESMF => esmpy}/test/base.py (98%) rename src/addon/ESMPy/src/{ESMF => esmpy}/test/base_test.py (91%) rename src/addon/ESMPy/src/{ESMF => esmpy}/test/data/T42_grid.nc (100%) rename src/addon/ESMPy/src/{ESMF => esmpy}/test/data/gridspec1Dcoords.nc (100%) rename src/addon/ESMPy/src/{ESMF => esmpy}/test/data/ne4np4-esmf.nc (100%) rename src/addon/ESMPy/src/{ESMF => esmpy}/test/data/ne4np4-pentagons.nc (100%) rename src/addon/ESMPy/src/{ESMF => esmpy}/test/regrid_from_file/__init__.py (100%) rename src/addon/ESMPy/src/{ESMF => esmpy}/test/regrid_from_file/read_test_cases_from_control_file.py (91%) rename src/addon/ESMPy/src/{ESMF => esmpy}/test/regrid_from_file/regrid_check.py (84%) rename src/addon/ESMPy/src/{ESMF => esmpy}/test/regrid_from_file/regrid_check_driver.py (82%) create mode 100644 src/addon/ESMPy/src/esmpy/test/regrid_from_file/regrid_from_file_consts.py rename src/addon/ESMPy/src/{ESMF => esmpy}/test/regrid_from_file/regrid_test_data.txt (100%) rename src/addon/ESMPy/src/{ESMF => esmpy}/test/regrid_from_file/rfftest.py (52%) rename src/addon/ESMPy/src/{ESMF => esmpy}/test/regrid_from_file/rfftestdryrun.py (51%) rename src/addon/ESMPy/src/{ESMF => esmpy}/test/regrid_from_file/run_regrid_from_file.py (92%) rename src/addon/ESMPy/src/{ESMF => esmpy}/test/regrid_from_file/run_regrid_from_file_dryrun.py (87%) rename src/addon/ESMPy/src/{ESMF => esmpy}/test/test_api/__init__.py (100%) rename src/addon/ESMPy/src/{ESMF => esmpy}/test/test_api/test_array.py (98%) rename src/addon/ESMPy/src/{ESMF => esmpy}/test/test_api/test_field.py (98%) rename src/addon/ESMPy/src/{ESMF => esmpy}/test/test_api/test_grid.py (94%) rename src/addon/ESMPy/src/{ESMF => esmpy}/test/test_api/test_locstream.py (95%) rename src/addon/ESMPy/src/{ESMF => esmpy}/test/test_api/test_mesh.py (95%) rename src/addon/ESMPy/src/{ESMF => esmpy}/test/test_api/test_regrid.py (78%) rename src/addon/ESMPy/src/{ESMF => esmpy}/test/test_api/test_vm.py (89%) rename src/addon/ESMPy/src/{ESMF => esmpy}/test/test_cbindings.py (95%) rename src/addon/ESMPy/src/{ESMF => esmpy}/util/__init__.py (100%) rename src/addon/ESMPy/src/{ESMF => esmpy}/util/cache_data.py (100%) rename src/addon/ESMPy/src/{ESMF => esmpy}/util/decorators.py (91%) rename src/addon/ESMPy/src/{ESMF => esmpy}/util/enum/LICENSE (100%) rename src/addon/ESMPy/src/{ESMF => esmpy}/util/enum/README (100%) rename src/addon/ESMPy/src/{ESMF => esmpy}/util/enum/__init__.py (100%) rename src/addon/ESMPy/src/{ESMF => esmpy}/util/enum/doc/enum.pdf (100%) rename src/addon/ESMPy/src/{ESMF => esmpy}/util/enum/doc/enum.rst (100%) rename src/addon/ESMPy/src/{ESMF => esmpy}/util/esmpyarray.py (97%) rename src/addon/ESMPy/src/{ESMF => esmpy}/util/exceptions.py (100%) rename src/addon/ESMPy/src/{ESMF => esmpy}/util/field_utilities.py (93%) rename src/addon/ESMPy/src/{ESMF => esmpy}/util/grid_utilities.py (78%) rename src/addon/ESMPy/src/{ESMF => esmpy}/util/helpers.py (87%) rename src/addon/ESMPy/src/{ESMF => esmpy}/util/itester.py (100%) rename src/addon/ESMPy/src/{ESMF => esmpy}/util/locstream_utilities.py (77%) rename src/addon/ESMPy/src/{ESMF => esmpy}/util/mesh_utilities.py (92%) rename src/addon/ESMPy/src/{ESMF => esmpy}/util/slicing.py (85%) diff --git a/src/addon/ESMPy/.gitignore b/src/addon/ESMPy/.gitignore index c427f66ad7..b3ed4aefa2 100644 --- a/src/addon/ESMPy/.gitignore +++ b/src/addon/ESMPy/.gitignore @@ -2,11 +2,6 @@ ################### *.pyc -# Nose # -######## -*.noseids -nosetests.xml - # Misc # ######## *~ @@ -19,12 +14,6 @@ PET* *.vtk *.csv -# Eclipse # -########### -*.project -*.pydevproject -*.settings - # ESMPy build and docs # ######################## build @@ -32,9 +21,9 @@ dist doc/esmpy_doc src/ESMPy.egg-info examples/data -src/ESMF/test/data +src/esmpy/test/data examples/notebooks/ESMPy-data -src/ESMF/test/regrid_from_file/data +src/esmpy/test/regrid_from_file/data # notebooks # ############# diff --git a/src/addon/ESMPy/Makefile b/src/addon/ESMPy/Makefile index 08b852bbfb..22c8330913 100644 --- a/src/addon/ESMPy/Makefile +++ b/src/addon/ESMPy/Makefile @@ -10,7 +10,7 @@ clean: find . -name "*.vtk" -exec rm -f {} \; || : find . -name "*.pytest_cache" -exec rm -rf {} \; || : find . -name "*.python-version" -exec rm -f {} \; || : - rm -rf src/ESMF/test/regrid_from_file/data || : + rm -rf src/esmpy/test/regrid_from_file/data || : rm -rf examples/data || : install: @@ -32,14 +32,10 @@ test_examples_parallel: mpirun -n 4 python3 -m pytest -vs -m="not serial" examples/exampletest.py test_regrid_from_file_dryrun: - python3 -m pytest -vs src/ESMF/test/regrid_from_file/rfftestdryrun.py + python3 -m pytest -vs src/esmpy/test/regrid_from_file/rfftestdryrun.py test_regrid_from_file: - python3 -m pytest -vs src/ESMF/test/regrid_from_file/rfftest.py - -test_regrid_from_file_parallel: - python3 -m pytest -vs src/ESMF/test/regrid_from_file/rfftestdryrun.py - mpirun -n 4 python3 -m pytest -vs src/ESMF/test/regrid_from_file/rfftest.py + python3 -m pytest -vs src/esmpy/test/regrid_from_file/rfftest.py test_all: test_unit test_parallel test_examples test_examples_parallel diff --git a/src/addon/ESMPy/doc/CoordSys.rst b/src/addon/ESMPy/doc/CoordSys.rst index b3d321f566..c60b52ca6b 100644 --- a/src/addon/ESMPy/doc/CoordSys.rst +++ b/src/addon/ESMPy/doc/CoordSys.rst @@ -2,6 +2,6 @@ CoordSys ~~~~~~~~ -.. autoclass:: ESMF.api.constants.CoordSys +.. autoclass:: esmpy.api.constants.CoordSys :members: :exclude-members: __new__ diff --git a/src/addon/ESMPy/doc/ExtrapMethod.rst b/src/addon/ESMPy/doc/ExtrapMethod.rst index ec65fb1edd..203eb2e679 100644 --- a/src/addon/ESMPy/doc/ExtrapMethod.rst +++ b/src/addon/ESMPy/doc/ExtrapMethod.rst @@ -2,6 +2,6 @@ ExtrapMethod ~~~~~~~~~~~~ -.. autoclass:: ESMF.api.constants.ExtrapMethod +.. autoclass:: esmpy.api.constants.ExtrapMethod :members: :exclude-members: __new__ diff --git a/src/addon/ESMPy/doc/FileFormat.rst b/src/addon/ESMPy/doc/FileFormat.rst index 7a66198768..0d7c5864bf 100755 --- a/src/addon/ESMPy/doc/FileFormat.rst +++ b/src/addon/ESMPy/doc/FileFormat.rst @@ -2,6 +2,6 @@ FileFormat ~~~~~~~~~~ -.. autoclass:: ESMF.api.constants.FileFormat +.. autoclass:: esmpy.api.constants.FileFormat :members: :exclude-members: __new__ diff --git a/src/addon/ESMPy/doc/FileMode.rst b/src/addon/ESMPy/doc/FileMode.rst index 28b075b6be..1d2ec75a6d 100644 --- a/src/addon/ESMPy/doc/FileMode.rst +++ b/src/addon/ESMPy/doc/FileMode.rst @@ -2,6 +2,6 @@ FileMode ~~~~~~~~ -.. autoclass:: ESMF.api.constants.FileMode +.. autoclass:: esmpy.api.constants.FileMode :members: :exclude-members: __new__ diff --git a/src/addon/ESMPy/doc/GridItem.rst b/src/addon/ESMPy/doc/GridItem.rst index 22690888c7..dcb838c55c 100755 --- a/src/addon/ESMPy/doc/GridItem.rst +++ b/src/addon/ESMPy/doc/GridItem.rst @@ -2,6 +2,6 @@ GridItem ~~~~~~~~ -.. autoclass:: ESMF.api.constants.GridItem +.. autoclass:: esmpy.api.constants.GridItem :members: :exclude-members: __new__ \ No newline at end of file diff --git a/src/addon/ESMPy/doc/LineType.rst b/src/addon/ESMPy/doc/LineType.rst index e0c37fd9d8..11cd684536 100644 --- a/src/addon/ESMPy/doc/LineType.rst +++ b/src/addon/ESMPy/doc/LineType.rst @@ -2,6 +2,6 @@ LineType ~~~~~~~~ -.. autoclass:: ESMF.api.constants.LineType +.. autoclass:: esmpy.api.constants.LineType :members: :exclude-members: __new__ \ No newline at end of file diff --git a/src/addon/ESMPy/doc/LogKind.rst b/src/addon/ESMPy/doc/LogKind.rst index e9a329f9bc..721ef17565 100755 --- a/src/addon/ESMPy/doc/LogKind.rst +++ b/src/addon/ESMPy/doc/LogKind.rst @@ -2,6 +2,6 @@ LogKind ~~~~~~~ -.. autoclass:: ESMF.api.constants.LogKind +.. autoclass:: esmpy.api.constants.LogKind :members: :exclude-members: __new__ \ No newline at end of file diff --git a/src/addon/ESMPy/doc/MeshElemType.rst b/src/addon/ESMPy/doc/MeshElemType.rst index 9338f22562..34357fe187 100755 --- a/src/addon/ESMPy/doc/MeshElemType.rst +++ b/src/addon/ESMPy/doc/MeshElemType.rst @@ -2,6 +2,6 @@ MeshElemType ~~~~~~~~~~~~ -.. autoclass:: ESMF.api.constants.MeshElemType +.. autoclass:: esmpy.api.constants.MeshElemType :members: :exclude-members: __new__ \ No newline at end of file diff --git a/src/addon/ESMPy/doc/MeshLoc.rst b/src/addon/ESMPy/doc/MeshLoc.rst index 05f3ae3ab5..888c3672a4 100755 --- a/src/addon/ESMPy/doc/MeshLoc.rst +++ b/src/addon/ESMPy/doc/MeshLoc.rst @@ -2,6 +2,6 @@ MeshLoc ~~~~~~~ -.. autoclass:: ESMF.api.constants.MeshLoc +.. autoclass:: esmpy.api.constants.MeshLoc :members: :exclude-members: __new__ \ No newline at end of file diff --git a/src/addon/ESMPy/doc/NormType.rst b/src/addon/ESMPy/doc/NormType.rst index 4a80e66d62..d4b6cbaa06 100644 --- a/src/addon/ESMPy/doc/NormType.rst +++ b/src/addon/ESMPy/doc/NormType.rst @@ -2,6 +2,6 @@ NormType ~~~~~~~~ -.. autoclass:: ESMF.api.constants.NormType +.. autoclass:: esmpy.api.constants.NormType :members: :exclude-members: __new__ \ No newline at end of file diff --git a/src/addon/ESMPy/doc/PoleKind.rst b/src/addon/ESMPy/doc/PoleKind.rst index 20206874d2..590cc25d30 100644 --- a/src/addon/ESMPy/doc/PoleKind.rst +++ b/src/addon/ESMPy/doc/PoleKind.rst @@ -2,6 +2,6 @@ PoleKind ~~~~~~~~ -.. autoclass:: ESMF.api.constants.PoleKind +.. autoclass:: esmpy.api.constants.PoleKind :members: :exclude-members: __new__ \ No newline at end of file diff --git a/src/addon/ESMPy/doc/PoleMethod.rst b/src/addon/ESMPy/doc/PoleMethod.rst index 4be0362658..6d59b56e33 100644 --- a/src/addon/ESMPy/doc/PoleMethod.rst +++ b/src/addon/ESMPy/doc/PoleMethod.rst @@ -2,6 +2,6 @@ PoleMethod ~~~~~~~~~~ -.. autoclass:: ESMF.api.constants.PoleMethod +.. autoclass:: esmpy.api.constants.PoleMethod :members: :exclude-members: __new__ \ No newline at end of file diff --git a/src/addon/ESMPy/doc/Region.rst b/src/addon/ESMPy/doc/Region.rst index 620d792092..b905f434e8 100755 --- a/src/addon/ESMPy/doc/Region.rst +++ b/src/addon/ESMPy/doc/Region.rst @@ -2,6 +2,6 @@ Region ~~~~~~ -.. autoclass:: ESMF.api.constants.Region +.. autoclass:: esmpy.api.constants.Region :members: :exclude-members: __new__ \ No newline at end of file diff --git a/src/addon/ESMPy/doc/RegridMethod.rst b/src/addon/ESMPy/doc/RegridMethod.rst index acef1267c5..fc2e5027d0 100755 --- a/src/addon/ESMPy/doc/RegridMethod.rst +++ b/src/addon/ESMPy/doc/RegridMethod.rst @@ -2,6 +2,6 @@ RegridMethod ~~~~~~~~~~~~ -.. autoclass:: ESMF.api.constants.RegridMethod +.. autoclass:: esmpy.api.constants.RegridMethod :members: :exclude-members: __new__ \ No newline at end of file diff --git a/src/addon/ESMPy/doc/StaggerLoc.rst b/src/addon/ESMPy/doc/StaggerLoc.rst index 2e09ba247f..7eac7ae404 100755 --- a/src/addon/ESMPy/doc/StaggerLoc.rst +++ b/src/addon/ESMPy/doc/StaggerLoc.rst @@ -2,6 +2,6 @@ StaggerLoc ~~~~~~~~~~ -.. autoclass:: ESMF.api.constants.StaggerLoc +.. autoclass:: esmpy.api.constants.StaggerLoc :members: :exclude-members: __new__ \ No newline at end of file diff --git a/src/addon/ESMPy/doc/TypeKind.rst b/src/addon/ESMPy/doc/TypeKind.rst index 3b4c5e944c..378973d3e2 100755 --- a/src/addon/ESMPy/doc/TypeKind.rst +++ b/src/addon/ESMPy/doc/TypeKind.rst @@ -2,6 +2,6 @@ TypeKind ~~~~~~~~ -.. autoclass:: ESMF.api.constants.TypeKind +.. autoclass:: esmpy.api.constants.TypeKind :members: :exclude-members: __new__ \ No newline at end of file diff --git a/src/addon/ESMPy/doc/UnmappedAction.rst b/src/addon/ESMPy/doc/UnmappedAction.rst index a9fe04f401..c09ffaf6f8 100755 --- a/src/addon/ESMPy/doc/UnmappedAction.rst +++ b/src/addon/ESMPy/doc/UnmappedAction.rst @@ -2,6 +2,6 @@ UnmappedAction ~~~~~~~~~~~~~~ -.. autoclass:: ESMF.api.constants.UnmappedAction +.. autoclass:: esmpy.api.constants.UnmappedAction :members: :exclude-members: __new__ \ No newline at end of file diff --git a/src/addon/ESMPy/doc/api.rst b/src/addon/ESMPy/doc/api.rst index c6db0bc048..2daf88a531 100644 --- a/src/addon/ESMPy/doc/api.rst +++ b/src/addon/ESMPy/doc/api.rst @@ -6,25 +6,25 @@ API Classes ------- -ESMPy uses a :class:`~ESMF.api.field.Field` object to represent data variables +ESMPy uses a :class:`~esmpy.api.field.Field` object to represent data variables built on an underlying spatial discretization, which is represented by a -:class:`~ESMF.api.grid.Grid`, :class:`~ESMF.api.mesh.Mesh` or -:class:`~ESMF.api.locstream.LocStream`. -Regridding between :class:`Fields ` is accomplished with the -:class:`~ESMF.api.regrid.Regrid` class. All of these classes are explained in +:class:`~esmpy.api.grid.Grid`, :class:`~esmpy.api.mesh.Mesh` or +:class:`~esmpy.api.locstream.LocStream`. +Regridding between :class:`Fields ` is accomplished with the +:class:`~esmpy.api.regrid.Regrid` class. All of these classes are explained in more detail in the sections provided by the links in the following table. -======================================== ============================================================================== -Class Description -======================================== ============================================================================== -:class:`~ESMF.api.esmpymanager.Manager` A manager class to initialize and finalize ESMF -:class:`~ESMF.api.field.Field` A data field built on a :class:`~ESMF.api.grid.Grid`, :class:`~ESMF.api.mesh.Mesh`, or :class:`~ESMF.api.locstream.LocStream` -:class:`~ESMF.api.grid.Grid` A class to represent a logically rectangular grid -:class:`~ESMF.api.mesh.Mesh` A class to represent an unstructured grid -:class:`~ESMF.api.locstream.LocStream` A class to represent observational data as a collection of disconnected points -:class:`~ESMF.api.regrid.Regrid` The regridding utility -:class:`~ESMF.api.regrid.RegridFromFile` The from file regridding utility -======================================== ============================================================================== +========================================= ============================================================================== +Class Description +========================================= ============================================================================== +:class:`~esmpy.api.esmpymanager.Manager` A manager class to initialize and finalize ESMF +:class:`~esmpy.api.field.Field` A data field built on a :class:`~esmpy.api.grid.Grid`, :class:`~esmpy.api.mesh.Mesh`, or :class:`~esmpy.api.locstream.LocStream` +:class:`~esmpy.api.grid.Grid` A class to represent a logically rectangular grid +:class:`~esmpy.api.mesh.Mesh` A class to represent an unstructured grid +:class:`~esmpy.api.locstream.LocStream` A class to represent observational data as a collection of disconnected points +:class:`~esmpy.api.regrid.Regrid` The regridding utility +:class:`~esmpy.api.regrid.RegridFromFile` The from file regridding utility +========================================= ============================================================================== --------------- @@ -36,33 +36,33 @@ available options for parameters that expect a variety of specific inputs. The following table lists the available named constants and provides links to pages that further explain the available values. -=========================================================== ============================== -Named constants Description -=========================================================== ============================== -:class:`CoordSys` Specify the coordinate system of a :class:`~ESMF.api.grid.Grid` -:class:`ExtrapMethod` Specify the extrapolation method -:class:`FileFormat` Specify the format of a data file -:class:`FileMode` Specify the mode of a data file -:class:`GridItem` Specify a mask or area item on a :class:`~ESMF.api.grid.Grid` -:class:`LineType` Specify the type of line that connects two points on a sphere -:class:`LogKind` Specify how much logging should be done -:class:`MeshElemType` Specify the type of the :class:`~ESMF.api.mesh.Mesh` elements -:class:`MeshLoc` Specify a nodal or elemental :class:`~ESMF.api.mesh.Mesh` -:class:`NormType` Specify the type of normalization to use for conservative regridding weights -:class:`PoleKind` Specify the type of connection that appears at the poles of the :class:`~ESMF.api.grid.Grid` -:class:`PoleMethod` Specify which type of artificial pole to construct on the source :class:`~ESMF.api.grid.Grid` for regridding -:class:`Region` Specify various regions in the data layout of -:class:`RegridMethod` Specify which interpolation method to use regridding -:class:`StaggerLoc` Specify the position for data in a :class:`~ESMF.api.grid.Grid` cell -:class:`TypeKind` Specify the type and kind of data -:class:`UnmappedAction` Specify which action to take with respect to unmapped destination points -=========================================================== ============================== +============================================================ ============================== +Named constants Description +============================================================ ============================== +:class:`CoordSys` Specify the coordinate system of a :class:`~esmpy.api.grid.Grid` +:class:`ExtrapMethod` Specify the extrapolation method +:class:`FileFormat` Specify the format of a data file +:class:`FileMode` Specify the mode of a data file +:class:`GridItem` Specify a mask or area item on a :class:`~esmpy.api.grid.Grid` +:class:`LineType` Specify the type of line that connects two points on a sphere +:class:`LogKind` Specify how much logging should be done +:class:`MeshElemType` Specify the type of the :class:`~esmpy.api.mesh.Mesh` elements +:class:`MeshLoc` Specify a nodal or elemental :class:`~esmpy.api.mesh.Mesh` +:class:`NormType` Specify the type of normalization to use for conservative regridding weights +:class:`PoleKind` Specify the type of connection that appears at the poles of the :class:`~esmpy.api.grid.Grid` +:class:`PoleMethod` Specify which type of artificial pole to construct on the source :class:`~esmpy.api.grid.Grid` for regridding +:class:`Region` Specify various regions in the data layout of +:class:`RegridMethod` Specify which interpolation method to use regridding +:class:`StaggerLoc` Specify the position for data in a :class:`~esmpy.api.grid.Grid` cell +:class:`TypeKind` Specify the type and kind of data +:class:`UnmappedAction` Specify which action to take with respect to unmapped destination points +============================================================ ============================== ------- Manager ------- -The :class:`~ESMF.api.esmpymanager.Manager` is used by ESMPy to simplify a +The :class:`~esmpy.api.esmpymanager.Manager` is used by ESMPy to simplify a number of low-level calls used by the underlying ESMF framework to allocate resources, enable logging, and control garbage collection. @@ -78,11 +78,11 @@ allocates computational resources in the form of system threads with a lifetime of at least that of the ESMPy execution. In the simplest, and most common case, a PET is equivalent to an MPI process. The number of PETs and the current PET can be queried from the -:class:`~ESMF.api.esmpymanager.Manager`: +:class:`~esmpy.api.esmpymanager.Manager`: .. code:: - mg = ESMF.Manager() + mg = esmpy.Manager() pet_count = mg.pet_count() local_pet = mg.local_pet() @@ -94,11 +94,11 @@ for more information. Logging ~~~~~~~ -The :class:`~ESMF.api.esmpymanager.Manager` is also used to enable logging: +The :class:`~esmpy.api.esmpymanager.Manager` is also used to enable logging: .. code:: - mg = ESMF.Manager(debug=True) + mg = esmpy.Manager(debug=True) local_pet = mg.local_pet The output will be logged in files named PET.ESMF_LogFile. @@ -109,10 +109,10 @@ Memory management The underlying ESMF framework needs to be initialized and finalized once and only once per execution. This is handled internally by the -:class:`~ESMF.api.esmpymanager.Manager` and **does not** require any explicit +:class:`~esmpy.api.esmpymanager.Manager` and **does not** require any explicit user intervention. However, the ESMF garbage collection feature is not triggered until the finalization routine is invoked, which may not happen until the -:class:`~ESMF.api.esmpymanager.Manager` goes out of scope at the end of the +:class:`~esmpy.api.esmpymanager.Manager` goes out of scope at the end of the program execution. If memory deallocation of ESMPy @@ -121,12 +121,12 @@ objects is required *prior* to the end of the program, the class level .. code:: - mg = ESMF.Manager() + mg = esmpy.Manager() mg.destroy() -This is commonly required when reusing a :class:`~ESMF.api.regrid.Regrid` object -to interpolate data between many :class:`~ESMF.api.field.Field` pairs. +This is commonly required when reusing a :class:`~esmpy.api.regrid.Regrid` object +to interpolate data between many :class:`~esmpy.api.field.Field` pairs. ~~~~~~~~~~~~~~~~~ MOAB Mesh backend @@ -147,9 +147,9 @@ Spatial Discretization Objects ------------------------------ There are three different objects used for spatial coordinate representation: -:class:`~ESMF.api.grid.Grid`, :class:`~ESMF.api.mesh.Mesh`, and :class:`~ESMF.api.locstream.LocStream`. :class:`Grids ` are used to represent logically rectangular -grids, :class:`Meshes ` are used for unstructured collections of polygons, and -:class:`LocStreams ` are used for unstructured collections of individual points. These +:class:`~esmpy.api.grid.Grid`, :class:`~esmpy.api.mesh.Mesh`, and :class:`~esmpy.api.locstream.LocStream`. :class:`Grids ` are used to represent logically rectangular +grids, :class:`Meshes ` are used for unstructured collections of polygons, and +:class:`LocStreams ` are used for unstructured collections of individual points. These objects are nearly identical counterparts to the objects of the same name in ESMF, with some simplifications for ease of use in the Python environment. @@ -157,9 +157,9 @@ ESMF, with some simplifications for ease of use in the Python environment. Grid ~~~~ -The :class:`~ESMF.api.grid.Grid` is used to represent the geometry and discretization of logically -rectangular physical grids. The :class:`~ESMF.api.grid.Grid` can also hold information that can used in -calculations involving the :class:`~ESMF.api.grid.Grid`, like a mask or the cell areas. Refer to the Grid Class of the +The :class:`~esmpy.api.grid.Grid` is used to represent the geometry and discretization of logically +rectangular physical grids. The :class:`~esmpy.api.grid.Grid` can also hold information that can used in +calculations involving the :class:`~esmpy.api.grid.Grid`, like a mask or the cell areas. Refer to the Grid Class of the `ESMF Reference Manual `_ for more information. ++++++++++ @@ -169,103 +169,103 @@ Staggering Staggering is a finite difference technique in which the values of different physical quantities are placed at different locations within a grid cell. -The ESMF :class:`~ESMF.api.grid.Grid` class supports a variety of stagger locations, including cell +The ESMF :class:`~esmpy.api.grid.Grid` class supports a variety of stagger locations, including cell centers, corners, and edge centers. The default stagger location in ESMF is the -cell center, and cell counts in :class:`~ESMF.api.grid.Grid` are based on this assumption. Combinations +cell center, and cell counts in :class:`~esmpy.api.grid.Grid` are based on this assumption. Combinations of the 2D ESMF stagger locations are sufficient to specify any of the Arakawa staggers. ESMF also supports staggering in 3D and higher dimensions. There are shortcuts for standard staggers, and interfaces through which users can create custom staggers. -As a default the ESMF :class:`~ESMF.api.grid.Grid` class provides symmetric staggering, so that cell +As a default the ESMF :class:`~esmpy.api.grid.Grid` class provides symmetric staggering, so that cell centers are enclosed by cell perimeter (e.g. corner) stagger locations. This means the coordinate arrays for stagger locations other than the center will have an additional element of padding in order to enclose the cell center locations. However, to achieve other types of staggering, the user may alter or eliminate this padding by using the appropriate options when adding coordinates -to a :class:`~ESMF.api.grid.Grid`. +to a :class:`~esmpy.api.grid.Grid`. -:class:`~ESMF.api.grid.Grid` staggers are indicated using -:class:`StaggerLoc`. +:class:`~esmpy.api.grid.Grid` staggers are indicated using +:class:`StaggerLoc`. .. code:: - grid = ESMF.Grid(np.array([3,4]), staggerloc=ESMF.StaggerLoc.CENTER) + grid = esmpy.Grid(np.array([3,4]), staggerloc=esmpy.StaggerLoc.CENTER) +++++++++++++++++++++ Spherical Coordinates +++++++++++++++++++++ -In the case that the :class:`~ESMF.api.grid.Grid` is on a sphere (coord_sys = :class:`ESMF.api.constants.CoordSys.SPH_DEG` or -:class:`ESMF.api.constants.CoordSys.SPH_RAD`) then the coordinates given in the :class:`~ESMF.api.grid.Grid` are interpreted +In the case that the :class:`~esmpy.api.grid.Grid` is on a sphere (coord_sys = :class:`esmpy.api.constants.CoordSys.SPH_DEG` or +:class:`esmpy.api.constants.CoordSys.SPH_RAD`) then the coordinates given in the :class:`~esmpy.api.grid.Grid` are interpreted as latitude and longitude values. The coordinates can either be in degrees or -radians as indicated by the ``coord_sys`` flag set during :class:`~ESMF.api.grid.Grid` creation. As is +radians as indicated by the ``coord_sys`` flag set during :class:`~esmpy.api.grid.Grid` creation. As is true with many global models, this application currently assumes the latitude and longitude refer to positions on a perfect sphere. -The :class:`~ESMF.api.grid.Grid` coordinate system is represented using -:class:`CoordSys`. +The :class:`~esmpy.api.grid.Grid` coordinate system is represented using +:class:`CoordSys`. .. code:: - grid = ESMF.Grid(np.array([3,4]), staggerloc=ESMF.StaggerLoc.CENTER, - coord_sys=ESMF.CoordSys.SPH_DEG) + grid = esmpy.Grid(np.array([3,4]), staggerloc=esmpy.StaggerLoc.CENTER, + coord_sys=esmpy.CoordSys.SPH_DEG) +++++++++++ Periodicity +++++++++++ -A periodic connection can be specified when building :class:`Grids ` in spherical +A periodic connection can be specified when building :class:`Grids ` in spherical coordinates. The ``num_peri_dims`` parameter indicates the total number of periodic dimensions and ``periodic_dim`` is used to identify which dimensions should be considered periodic. There must always be at least one non-periodic -dimension. For example, to create a global latitude-longitude :class:`~ESMF.api.grid.Grid` there would +dimension. For example, to create a global latitude-longitude :class:`~esmpy.api.grid.Grid` there would be one periodic dimension, dimension 0 (longitude). .. code:: - grid = ESMF.Grid(np.array([3,4]), staggerloc=ESMF.StaggerLoc.CENTER, - coord_sys=ESMF.CoordSys.SPH_DEG, + grid = esmpy.Grid(np.array([3,4]), staggerloc=esmpy.StaggerLoc.CENTER, + coord_sys=esmpy.CoordSys.SPH_DEG, num_peri_dims=1, periodic_dim=0) +++++++++++++++ Pole Generation +++++++++++++++ -The :class:`~ESMF.api.grid.Grid` can generate an artificial pole by using the ``pole_dim`` parameter. This +The :class:`~esmpy.api.grid.Grid` can generate an artificial pole by using the ``pole_dim`` parameter. This can be helpful for regridding operations to smooth out the interpolated values in the polar region. For the example of creating a global latitude-longitude -:class:`~ESMF.api.grid.Grid`, the pole dimension would be 1 (latitude). +:class:`~esmpy.api.grid.Grid`, the pole dimension would be 1 (latitude). .. code:: - grid = ESMF.Grid(np.array([3,4]), staggerloc=ESMF.StaggerLoc.CENTER, - coord_sys=ESMF.CoordSys.SPH_DEG, + grid = esmpy.Grid(np.array([3,4]), staggerloc=esmpy.StaggerLoc.CENTER, + coord_sys=esmpy.CoordSys.SPH_DEG, num_peri_dims=1, periodic_dim=0, pole_dim=1) +++++++ Masking +++++++ -Masking is the process used to mark parts of a :class:`~ESMF.api.grid.Grid` to be ignored during an -operation. Marking :class:`~ESMF.api.grid.Grid` cells as masked can affect the :class:`~ESMF.api.field.Field` values that are +Masking is the process used to mark parts of a :class:`~esmpy.api.grid.Grid` to be ignored during an +operation. Marking :class:`~esmpy.api.grid.Grid` cells as masked can affect the :class:`~esmpy.api.field.Field` values that are represented by those cells. Masking is specified by assigning an integer value -to a :class:`~ESMF.api.grid.Grid` cell. This allows many different masks to be defined on the same :class:`~ESMF.api.grid.Grid`, -any combination of which may be also activated on the :class:`~ESMF.api.field.Field` by specifying the -corresponding integer values. The activation of :class:`~ESMF.api.field.Field` masks with respect to the -underlying :class:`~ESMF.api.grid.Grid` mask is handled by :class:`~ESMF.api.regrid.Regrid`, and a more +to a :class:`~esmpy.api.grid.Grid` cell. This allows many different masks to be defined on the same :class:`~esmpy.api.grid.Grid`, +any combination of which may be also activated on the :class:`~esmpy.api.field.Field` by specifying the +corresponding integer values. The activation of :class:`~esmpy.api.field.Field` masks with respect to the +underlying :class:`~esmpy.api.grid.Grid` mask is handled by :class:`~esmpy.api.regrid.Regrid`, and a more general discussion of masking is covered in the :ref:`masking ` section. .. code:: In [1]: import numpy as np - ...: import ESMF - ...: grid = ESMF.Grid(np.array([3,4]), staggerloc=ESMF.StaggerLoc.CENTER, - ...: coord_sys=ESMF.CoordSys.SPH_DEG, + ...: import esmpy + ...: grid = esmpy.Grid(np.array([3,4]), staggerloc=esmpy.StaggerLoc.CENTER, + ...: coord_sys=esmpy.CoordSys.SPH_DEG, ...: num_peri_dims=1, periodic_dim=0, pole_dim=1) ...: - ...: mask = grid.add_item(ESMF.GridItem.MASK, staggerloc=ESMF.StaggerLoc.CENTER) + ...: mask = grid.add_item(esmpy.GridItem.MASK, staggerloc=esmpy.StaggerLoc.CENTER) ...: mask ...: Out[1]: @@ -277,29 +277,29 @@ section. Cell Areas ++++++++++ -:class:`~ESMF.api.grid.Grid` cell areas can be calculated by ESMPy. Space must first be allocated for +:class:`~esmpy.api.grid.Grid` cell areas can be calculated by ESMPy. Space must first be allocated for this calculation by adding an -:class:`~ESMF.api.constants.GridItem.AREA` item to the :class:`~ESMF.api.grid.Grid`. -Then a :class:`~ESMF.api.field.Field` must be created, and the -:class:`~ESMF.api.field.Field.get_area()` function called. +:class:`~esmpy.api.constants.GridItem.AREA` item to the :class:`~esmpy.api.grid.Grid`. +Then a :class:`~esmpy.api.field.Field` must be created, and the +:class:`~esmpy.api.field.Field.get_area()` function called. -.. Note:: The :class:`~ESMF.api.grid.Grid` area calculation assumes the :class:`~ESMF.api.grid.Grid` is a unit sphere. +.. Note:: The :class:`~esmpy.api.grid.Grid` area calculation assumes the :class:`~esmpy.api.grid.Grid` is a unit sphere. -:class:`~ESMF.api.grid.Grid` cell areas may also be set to user-defined values -after the :class:`~ESMF.api.constants.GridItem.AREA` item has -been allocated and retrieved using :class:`~ESMF.api.grid.Grid.get_item()`. +:class:`~esmpy.api.grid.Grid` cell areas may also be set to user-defined values +after the :class:`~esmpy.api.constants.GridItem.AREA` item has +been allocated and retrieved using :class:`~esmpy.api.grid.Grid.get_item()`. .. code:: - In [1]: grid = ESMF.Grid(np.array([3,4]), staggerloc=[ESMF.StaggerLoc.CENTER, ESMF.StaggerLoc.CORNER], - ...: coord_sys=ESMF.CoordSys.SPH_DEG, + In [1]: grid = esmpy.Grid(np.array([3,4]), staggerloc=[esmpy.StaggerLoc.CENTER, esmpy.StaggerLoc.CORNER], + ...: coord_sys=esmpy.CoordSys.SPH_DEG, ...: num_peri_dims=1, periodic_dim=0, pole_dim=1) ...: ...: ...: gridLon = grid.get_coords(0) ...: gridLat = grid.get_coords(1) - ...: gridLonCorner = grid.get_coords(0, staggerloc=ESMF.StaggerLoc.CORNER) - ...: gridLatCorner = grid.get_coords(1, staggerloc=ESMF.StaggerLoc.CORNER) + ...: gridLonCorner = grid.get_coords(0, staggerloc=esmpy.StaggerLoc.CORNER) + ...: gridLatCorner = grid.get_coords(1, staggerloc=esmpy.StaggerLoc.CORNER) ...: ...: lon = np.linspace(-120,120,3) ...: lat = np.linspace(-67.5, 67.5,4) @@ -314,7 +314,7 @@ been allocated and retrieved using :class:`~ESMF.api.grid.Grid.get_item()`. ...: gridLonCorner[:] = lonm_corner ...: gridLatCorner[:] = latm_corner ...: - ...: field = ESMF.Field(grid) + ...: field = esmpy.Field(grid) ...: field.get_area() ...: field.data ...: @@ -327,101 +327,101 @@ been allocated and retrieved using :class:`~ESMF.api.grid.Grid.get_item()`. Mesh ~~~~ -A :class:`~ESMF.api.mesh.Mesh` is an object for representing unstructured grids. +A :class:`~esmpy.api.mesh.Mesh` is an object for representing unstructured grids. Refer to the Mesh Class of the `ESMF Reference Manual `_ for more information. -A :class:`~ESMF.api.mesh.Mesh` is constructed of *nodes* and *elements*. A node, also known as a vertex -or corner, is a part of a :class:`~ESMF.api.mesh.Mesh` which represents a single point. An element, -also known as a cell, is a part of a :class:`~ESMF.api.mesh.Mesh` which represents a small +A :class:`~esmpy.api.mesh.Mesh` is constructed of *nodes* and *elements*. A node, also known as a vertex +or corner, is a part of a :class:`~esmpy.api.mesh.Mesh` which represents a single point. An element, +also known as a cell, is a part of a :class:`~esmpy.api.mesh.Mesh` which represents a small region of space. Elements are described in terms of a connected set of nodes which represent locations along their boundaries. -:class:`~ESMF.api.field.Field` data may be located on either the nodes or elements of a :class:`~ESMF.api.mesh.Mesh`. :class:`Fields ` -created on a :class:`~ESMF.api.mesh.Mesh` can also be used as either the source or destination or both +:class:`~esmpy.api.field.Field` data may be located on either the nodes or elements of a :class:`~esmpy.api.mesh.Mesh`. :class:`Fields ` +created on a :class:`~esmpy.api.mesh.Mesh` can also be used as either the source or destination or both of a regridding operation. -The dimension of a :class:`~ESMF.api.mesh.Mesh` in ESMF is specified with two parameters: the +The dimension of a :class:`~esmpy.api.mesh.Mesh` in ESMF is specified with two parameters: the *parametric* dimension and the *spatial* dimension. -The parametric dimension of a :class:`~ESMF.api.mesh.Mesh` is the dimension of the topology of the :class:`~ESMF.api.mesh.Mesh`. -This can be thought of as the dimension of the elements which make up the :class:`~ESMF.api.mesh.Mesh`. -For example, a :class:`~ESMF.api.mesh.Mesh` composed of triangles would have a parametric dimension of -2, and a :class:`~ESMF.api.mesh.Mesh` composed of tetrahedra would have a parametric dimension of 3. +The parametric dimension of a :class:`~esmpy.api.mesh.Mesh` is the dimension of the topology of the :class:`~esmpy.api.mesh.Mesh`. +This can be thought of as the dimension of the elements which make up the :class:`~esmpy.api.mesh.Mesh`. +For example, a :class:`~esmpy.api.mesh.Mesh` composed of triangles would have a parametric dimension of +2, and a :class:`~esmpy.api.mesh.Mesh` composed of tetrahedra would have a parametric dimension of 3. -The spatial dimension of a :class:`~ESMF.api.mesh.Mesh` is the dimension of the space in which the :class:`~ESMF.api.mesh.Mesh` +The spatial dimension of a :class:`~esmpy.api.mesh.Mesh` is the dimension of the space in which the :class:`~esmpy.api.mesh.Mesh` is embedded. In other words, it is the number of coordinate dimensions needed to -describe the location of the nodes making up the :class:`~ESMF.api.mesh.Mesh`. +describe the location of the nodes making up the :class:`~esmpy.api.mesh.Mesh`. -For example, a :class:`~ESMF.api.mesh.Mesh` constructed of squares on a plane would have a parametric -dimension of 2 and a spatial dimension of 2. If that same :class:`~ESMF.api.mesh.Mesh` were used to -represent the 2D surface of a sphere, then the :class:`~ESMF.api.mesh.Mesh` would still have a +For example, a :class:`~esmpy.api.mesh.Mesh` constructed of squares on a plane would have a parametric +dimension of 2 and a spatial dimension of 2. If that same :class:`~esmpy.api.mesh.Mesh` were used to +represent the 2D surface of a sphere, then the :class:`~esmpy.api.mesh.Mesh` would still have a parametric dimension of 2, but now its spatial dimension would be 3. -Only :class:`Meshes ` whose number of coordinate dimensions (spatial dimension) is 2 or 3 -are supported. The dimension of the elements in a :class:`~ESMF.api.mesh.Mesh` (parametric dimension) must +Only :class:`Meshes ` whose number of coordinate dimensions (spatial dimension) is 2 or 3 +are supported. The dimension of the elements in a :class:`~esmpy.api.mesh.Mesh` (parametric dimension) must be less than or equal to the spatial dimension, but also must be either 2 or 3. -This means that a :class:`~ESMF.api.mesh.Mesh` may be either 2D elements in 2D space, 3D elements in 3D +This means that a :class:`~esmpy.api.mesh.Mesh` may be either 2D elements in 2D space, 3D elements in 3D space, or a manifold constructed of 2D elements embedded in 3D space. For a parametric dimension of 2, the native supported element types are triangles and quadrilaterals. In addition to these, ESMF supports 2D polygons with any number of sides. Internally these are represented as sets of triangles, but to the user should behave like any other element. For a parametric dimension -of 3, the supported element types are tetrahedrons and hexahedrons. The :class:`~ESMF.api.mesh.Mesh` +of 3, the supported element types are tetrahedrons and hexahedrons. The :class:`~esmpy.api.mesh.Mesh` supports any combination of element types within a particular dimension, but -types from different dimensions may not be mixed. For example, a :class:`~ESMF.api.mesh.Mesh` cannot be +types from different dimensions may not be mixed. For example, a :class:`~esmpy.api.mesh.Mesh` cannot be constructed of both quadrilaterals and tetrahedra. +++++++++++++ Mesh Creation +++++++++++++ -To create a :class:`~ESMF.api.mesh.Mesh` we need to set some properties of the :class:`~ESMF.api.mesh.Mesh` as a whole, some -properties of each node in the :class:`~ESMF.api.mesh.Mesh` and then some properties of each element +To create a :class:`~esmpy.api.mesh.Mesh` we need to set some properties of the :class:`~esmpy.api.mesh.Mesh` as a whole, some +properties of each node in the :class:`~esmpy.api.mesh.Mesh` and then some properties of each element which connects the nodes. -For the :class:`~ESMF.api.mesh.Mesh` as a whole we set its parametric dimension and spatial dimension. -A :class:`Mesh's ` parametric dimension can be thought of as the dimension of the elements -which make up the :class:`~ESMF.api.mesh.Mesh`. A :class:`Mesh's ` spatial dimension, on the other hand, is the +For the :class:`~esmpy.api.mesh.Mesh` as a whole we set its parametric dimension and spatial dimension. +A :class:`Mesh's ` parametric dimension can be thought of as the dimension of the elements +which make up the :class:`~esmpy.api.mesh.Mesh`. A :class:`Mesh's ` spatial dimension, on the other hand, is the number of coordinate dimensions needed to describe the location of the nodes -making up the :class:`~ESMF.api.mesh.Mesh`. +making up the :class:`~esmpy.api.mesh.Mesh`. -The structure of the per node and element information used to create a :class:`~ESMF.api.mesh.Mesh` is -influenced by the :class:`~ESMF.api.mesh.Mesh` distribution strategy. The :class:`~ESMF.api.mesh.Mesh` class is distributed by +The structure of the per node and element information used to create a :class:`~esmpy.api.mesh.Mesh` is +influenced by the :class:`~esmpy.api.mesh.Mesh` distribution strategy. The :class:`~esmpy.api.mesh.Mesh` class is distributed by elements. This means that a node must be present on any PET that contains an element associated with that node, but not on any other PET (a node can't be on a PET without an element "home"). Since a node may be used by two or more elements located on different PETs, a node may be duplicated on multiple PETs. When a node is duplicated in this manner, one and only one of the PETs that contain the node must "own" the node. The user sets -this ownership when they define the nodes during :class:`~ESMF.api.mesh.Mesh` -creation. When a :class:`~ESMF.api.field.Field` is created on a -:class:`~ESMF.api.mesh.Mesh` (i.e. on the :class:`~ESMF.api.mesh.Mesh` nodes), -on each PET the :class:`~ESMF.api.field.Field` is only +this ownership when they define the nodes during :class:`~esmpy.api.mesh.Mesh` +creation. When a :class:`~esmpy.api.field.Field` is created on a +:class:`~esmpy.api.mesh.Mesh` (i.e. on the :class:`~esmpy.api.mesh.Mesh` nodes), +on each PET the :class:`~esmpy.api.field.Field` is only created on the nodes which are owned by that PET. This means that the size -of the :class:`~ESMF.api.field.Field` memory on the PET can be smaller than the -number of nodes used to create the :class:`~ESMF.api.mesh.Mesh` on that PET. +of the :class:`~esmpy.api.field.Field` memory on the PET can be smaller than the +number of nodes used to create the :class:`~esmpy.api.mesh.Mesh` on that PET. -Three properties need to be defined for each :class:`~ESMF.api.mesh.Mesh` node: the global id of the node +Three properties need to be defined for each :class:`~esmpy.api.mesh.Mesh` node: the global id of the node (``node_ids``), node coordinates (``node_coords``), and which PET owns the node (``node_owners``). The node id is a unique (across all PETs) integer attached to the particular node. It is used to indicate which nodes are the same when -connecting together pieces of the :class:`~ESMF.api.mesh.Mesh` on different PETs. The node -coordinates indicate the location of a node in space and are used in the :class:`~ESMF.api.regrid.Regrid` +connecting together pieces of the :class:`~esmpy.api.mesh.Mesh` on different PETs. The node +coordinates indicate the location of a node in space and are used in the :class:`~esmpy.api.regrid.Regrid` functionality when interpolating. The node owner indicates which PET is in -charge of the node. This is used when creating a :class:`~ESMF.api.field.Field` on the :class:`~ESMF.api.mesh.Mesh` to indicate -which PET should contain a :class:`~ESMF.api.field.Field` location for the data. +charge of the node. This is used when creating a :class:`~esmpy.api.field.Field` on the :class:`~esmpy.api.mesh.Mesh` to indicate +which PET should contain a :class:`~esmpy.api.field.Field` location for the data. -Three properties need to be defined for each :class:`~ESMF.api.mesh.Mesh` element: the global id of the +Three properties need to be defined for each :class:`~esmpy.api.mesh.Mesh` element: the global id of the element (``element_ids``), the topology type of the element (``element_types``), and which nodes are connected together to form the element (``element_conn``). The element id is a unique (across all PETs) integer attached to the particular element. The element type describes the topology of the element (e.g. a triangle vs. a quadrilateral). The range of choices for the topology of -the elements in a :class:`~ESMF.api.mesh.Mesh` are restricted by the :class:`Mesh's ` parametric dimension (e.g. a -:class:`~ESMF.api.mesh.Mesh` can't contain a 2D element like a triangle, when its parametric dimension +the elements in a :class:`~esmpy.api.mesh.Mesh` are restricted by the :class:`Mesh's ` parametric dimension (e.g. a +:class:`~esmpy.api.mesh.Mesh` can't contain a 2D element like a triangle, when its parametric dimension is 3D), but it can contain any combination of elements appropriate to its dimension. In particular, in 2D ESMF supports two native element types triangle and quadrilateral, but also provides support for polygons with any number of @@ -433,7 +433,7 @@ which nodes are to be connected together to form the element. The number of nodes connected together for each element is implied by the elements topology type (``element_types``). It is IMPORTANT to note, that the entries in this list are NOT the global ids of the nodes, but are indices into the PET local lists -of node info used in the :class:`~ESMF.api.mesh.Mesh` creation. In other words, the element connectivity +of node info used in the :class:`~esmpy.api.mesh.Mesh` creation. In other words, the element connectivity isn't specified in terms of the global list of nodes, but instead is specified in terms of the locally described node info. One other important point about connectivities is that the order of the nodes in the connectivity list of an @@ -441,9 +441,9 @@ element is important. In general, when specifying an element with parametric dimension 2, the nodes should be given in counterclockwise order around the element. -The three step :class:`~ESMF.api.mesh.Mesh` creation process starts with a call to the :class:`~ESMF.api.mesh.Mesh` constructor. -It is then followed by the :class:`~ESMF.api.mesh.Mesh.add_nodes()` call to -specify nodes, and then the :class:`~ESMF.api.mesh.Mesh.add_elements()` call to +The three step :class:`~esmpy.api.mesh.Mesh` creation process starts with a call to the :class:`~esmpy.api.mesh.Mesh` constructor. +It is then followed by the :class:`~esmpy.api.mesh.Mesh.add_nodes()` call to +specify nodes, and then the :class:`~esmpy.api.mesh.Mesh.add_elements()` call to specify elements. .. code:: @@ -466,7 +466,7 @@ specify elements. # Element Ids in centers # Two parametric dimensions, and two spatial dimensions - mesh = ESMF.Mesh(parametric_dim=2, spatial_dim=2, coord_sys=coord_sys) + mesh = esmpy.Mesh(parametric_dim=2, spatial_dim=2, coord_sys=coord_sys) num_node = 12 num_elem = 5 @@ -488,9 +488,9 @@ specify elements. nodeOwner = np.zeros(num_node) elemId = np.array([1,2,3,4,5]) - elemType=np.array([ESMF.MeshElemType.QUAD, - ESMF.MeshElemType.TRI, - ESMF.MeshElemType.TRI, 5, 6]) + elemType=np.array([esmpy.MeshElemType.QUAD, + esmpy.MeshElemType.TRI, + esmpy.MeshElemType.TRI, 5, 6]) elemConn=np.array([0,1,4,3, # elem id 1 1,2,4, # elem id 2 @@ -506,24 +506,24 @@ specify elements. Masking +++++++ -There are two types of masking available in :class:`~ESMF.api.mesh.Mesh`: node masking and element +There are two types of masking available in :class:`~esmpy.api.mesh.Mesh`: node masking and element masking. These both work in a similar manner, but vary slightly in the details -of setting the mask information during :class:`~ESMF.api.mesh.Mesh` creation. +of setting the mask information during :class:`~esmpy.api.mesh.Mesh` creation. For node masking, the mask information is set using the ``node_mask`` parameter. -When a :class:`~ESMF.api.regrid.Regrid` object is created the mask values arguments ``src_mask_values`` and +When a :class:`~esmpy.api.regrid.Regrid` object is created the mask values arguments ``src_mask_values`` and ``dst_mask_values`` can then be used to indicate which particular values set in the ``node_mask`` array indicate that the node should be masked. For example, if -``dst_mask_values`` has been set to 1, then any node in the destination :class:`~ESMF.api.mesh.Mesh` whose +``dst_mask_values`` has been set to 1, then any node in the destination :class:`~esmpy.api.mesh.Mesh` whose corresponding ``node_mask`` value is 1 will be masked out (a node with any other value than 1 will not be masked). For element masking, the mask information is set using the ``element_mask`` -parameter when adding elements to the :class:`~ESMF.api.mesh.Mesh`. In a similar manner to node masking, -the mask values parameters to :class:`~ESMF.api.regrid.Regrid`, ``src_mask_values`` and ``dst_mask_values`` +parameter when adding elements to the :class:`~esmpy.api.mesh.Mesh`. In a similar manner to node masking, +the mask values parameters to :class:`~esmpy.api.regrid.Regrid`, ``src_mask_values`` and ``dst_mask_values`` can then be used to indicate which particular values set in the ``element_mask`` array indicate that the element should be masked. For example, if -``dst_mask_values`` has been set to 1, then any element in the destination :class:`~ESMF.api.mesh.Mesh` +``dst_mask_values`` has been set to 1, then any element in the destination :class:`~esmpy.api.mesh.Mesh` whose corresponding ``element_mask`` value is 1 will be masked out (an element with any other value than 1 will not be masked). @@ -531,21 +531,21 @@ with any other value than 1 will not be masked). Areas +++++ -:class:`~ESMF.api.mesh.Mesh` cell areas can be specified using the ``element_areas`` parameter to -:class:`~ESMF.api.mesh.Mesh.add_elements()`. +:class:`~esmpy.api.mesh.Mesh` cell areas can be specified using the ``element_areas`` parameter to +:class:`~esmpy.api.mesh.Mesh.add_elements()`. If cell areas are not specified by the user they can be calculated by ESMPy -using :class:`~ESMF.api.field.Field.get_area()`. +using :class:`~esmpy.api.field.Field.get_area()`. ~~~~~~~~~ LocStream ~~~~~~~~~ -A :class:`~ESMF.api.locstream.LocStream` can be used to represent the locations of a set of -data points. For example, in the data assimilation world, :class:`LocStreams ` can be used +A :class:`~esmpy.api.locstream.LocStream` can be used to represent the locations of a set of +data points. For example, in the data assimilation world, :class:`LocStreams ` can be used to represent a set of observations. The values of the data points are stored -within a :class:`~ESMF.api.field.Field` created using the :class:`~ESMF.api.locstream.LocStream`. +within a :class:`~esmpy.api.field.Field` created using the :class:`~esmpy.api.locstream.LocStream`. Refer to the LocStream Class of the `ESMF Reference Manual `_ for more information. @@ -556,26 +556,26 @@ called *keys*. A key is essentially a list of point descriptors, one for each da point. They may hold other information besides the coordinates - a mask, for example. They may also hold a second set of coordinates. Keys are referenced by name. Each key must contain the same number of elements as there are data points -in the :class:`~ESMF.api.locstream.LocStream`. While there is no assumption in the ordering of the points, +in the :class:`~esmpy.api.locstream.LocStream`. While there is no assumption in the ordering of the points, the order chosen must be maintained in each of the keys. -A :class:`~ESMF.api.locstream.LocStream` can be very large. Data assimilation systems might use :class:`LocStreams ` -with up to :math:`10^8` observations, so efficiency is critical. :class:`LocStreams ` can be +A :class:`~esmpy.api.locstream.LocStream` can be very large. Data assimilation systems might use :class:`LocStreams ` +with up to :math:`10^8` observations, so efficiency is critical. :class:`LocStreams ` can be created from file. -A :class:`~ESMF.api.locstream.LocStream` is similar to a :class:`~ESMF.api.mesh.Mesh` in that both are collections of irregularly -positioned points. However, the two structures differ because a :class:`~ESMF.api.mesh.Mesh` also has +A :class:`~esmpy.api.locstream.LocStream` is similar to a :class:`~esmpy.api.mesh.Mesh` in that both are collections of irregularly +positioned points. However, the two structures differ because a :class:`~esmpy.api.mesh.Mesh` also has connectivity: each data point represents either a center or corner of a cell. -There is no requirement that the points in a :class:`~ESMF.api.locstream.LocStream` have connectivity, in +There is no requirement that the points in a :class:`~esmpy.api.locstream.LocStream` have connectivity, in fact there is no requirement that any two points have any particular spatial relationship at all. .. code:: - locstream = ESMF.LocStream(16, coord_sys=coord_sys) + locstream = esmpy.LocStream(16, coord_sys=coord_sys) deg_rad = pi - if coord_sys == ESMF.CoordSys.SPH_DEG: + if coord_sys == esmpy.CoordSys.SPH_DEG: deg_rad = 180 locstream["ESMF:Lon"] = [0.0, 0.5*deg_rad, 1.5*deg_rad, 2*deg_rad, 0.0, 0.5*deg_rad, 1.5*deg_rad, 2*deg_rad, 0.0, 0.5*deg_rad, 1.5*deg_rad, 2*deg_rad, 0.0, 0.5*deg_rad, 1.5*deg_rad, 2*deg_rad] @@ -592,17 +592,17 @@ Create a Grid or Mesh from File File Formats ~~~~~~~~~~~~ -ESMPy can create :class:`~ESMF.api.grid.Grid` or :class:`~ESMF.api.mesh.Mesh` objects from NetCDF files in a variety -of formats. A :class:`~ESMF.api.mesh.Mesh` can be created from files in :class:`~ESMF.api.constants.FileFormat.SCRIP`, :class:`~ESMF.api.constants.FileFormat.ESMFMESH`, and :class:`~ESMF.api.constants.FileFormat.UGRID` -formats. :class:`~ESMF.api.grid.Grid` files can be in :class:`~ESMF.api.constants.FileFormat.SCRIP` and :class:`~ESMF.api.constants.FileFormat.GRIDSPEC` format. +ESMPy can create :class:`~esmpy.api.grid.Grid` or :class:`~esmpy.api.mesh.Mesh` objects from NetCDF files in a variety +of formats. A :class:`~esmpy.api.mesh.Mesh` can be created from files in :class:`~esmpy.api.constants.FileFormat.SCRIP`, :class:`~esmpy.api.constants.FileFormat.ESMFMESH`, and :class:`~esmpy.api.constants.FileFormat.UGRID` +formats. :class:`~esmpy.api.grid.Grid` files can be in :class:`~esmpy.api.constants.FileFormat.SCRIP` and :class:`~esmpy.api.constants.FileFormat.GRIDSPEC` format. +++++ SCRIP +++++ .. _scrip: -This file format is used by the :class:`~ESMF.api.constants.FileFormat.SCRIP` :cite:`ref:SCRIP`, package, grid files that -work with that package should also work here. :class:`~ESMF.api.constants.FileFormat.SCRIP` format files are +This file format is used by the :class:`~esmpy.api.constants.FileFormat.SCRIP` :cite:`ref:SCRIP`, package, grid files that +work with that package should also work here. :class:`~esmpy.api.constants.FileFormat.SCRIP` format files are capable of storing either 2D logically rectangular grids or 2D unstructured grids. More information can be found in the `ESMF Reference Manual `_. @@ -612,10 +612,10 @@ ESMFMESH ++++++++ .. _esmfmesh: -ESMF has a custom unstructured grid file format for describing :class:`Meshes `. -This format is more compatible than the :class:`~ESMF.api.constants.FileFormat.SCRIP` format with the methods -used to create a :class:`~ESMF.api.mesh.Mesh` object, so less conversion needs to be done to -create a :class:`~ESMF.api.mesh.Mesh`. The :class:`~ESMF.api.constants.FileFormat.ESMFMESH` format is thus more efficient than :class:`~ESMF.api.constants.FileFormat.SCRIP` when +ESMF has a custom unstructured grid file format for describing :class:`Meshes `. +This format is more compatible than the :class:`~esmpy.api.constants.FileFormat.SCRIP` format with the methods +used to create a :class:`~esmpy.api.mesh.Mesh` object, so less conversion needs to be done to +create a :class:`~esmpy.api.mesh.Mesh`. The :class:`~esmpy.api.constants.FileFormat.ESMFMESH` format is thus more efficient than :class:`~esmpy.api.constants.FileFormat.SCRIP` when used with ESMPy. More information can be found in the `ESMF Reference Manual `_. @@ -624,9 +624,9 @@ GRIDSPEC ++++++++ .. _gridspec: -:class:`~ESMF.api.constants.FileFormat.GRIDSPEC` is an extension to the Climate and Forecast (CF) metadata +:class:`~esmpy.api.constants.FileFormat.GRIDSPEC` is an extension to the Climate and Forecast (CF) metadata conventions for the representation of gridded data for Earth System -Models. ESMPy supports NetCDF files that follow the CF :class:`~ESMF.api.constants.FileFormat.GRIDSPEC` +Models. ESMPy supports NetCDF files that follow the CF :class:`~esmpy.api.constants.FileFormat.GRIDSPEC` convention to support logically rectangular lat/lon grids. More information can be found in the `ESMF Reference Manual `_. @@ -636,9 +636,9 @@ UGRID +++++ .. _ugrid: -:class:`~ESMF.api.constants.FileFormat.UGRID` is an extension to the CF metadata +:class:`~esmpy.api.constants.FileFormat.UGRID` is an extension to the CF metadata conventions for the unstructured grid data model. ESMPy support -NetCDF files that follow the CF :class:`~ESMF.api.constants.FileFormat.UGRID` convention for unstructured grids. +NetCDF files that follow the CF :class:`~esmpy.api.constants.FileFormat.UGRID` convention for unstructured grids. More information can be found in the `ESMF Reference Manual `_. @@ -646,18 +646,18 @@ More information can be found in the Meshes from File ~~~~~~~~~~~~~~~~ -When creating a :class:`~ESMF.api.mesh.Mesh` from a :class:`~ESMF.api.constants.FileFormat.SCRIP` format file, there are a number of -options to control the output :class:`~ESMF.api.mesh.Mesh`. The data is located at the center -of the grid cell in a :class:`~ESMF.api.constants.FileFormat.SCRIP` grid. Therefore, when the :class:`~ESMF.api.mesh.Mesh` will be +When creating a :class:`~esmpy.api.mesh.Mesh` from a :class:`~esmpy.api.constants.FileFormat.SCRIP` format file, there are a number of +options to control the output :class:`~esmpy.api.mesh.Mesh`. The data is located at the center +of the grid cell in a :class:`~esmpy.api.constants.FileFormat.SCRIP` grid. Therefore, when the :class:`~esmpy.api.mesh.Mesh` will be part of a conservative regridding operation, the ``convert_to_dual`` flag must be set to True to properly generate coordinates at the the cell corners. -A :class:`~ESMF.api.mesh.Mesh` may also be created with boolean flags to specify whether or not to -add an area property to the :class:`~ESMF.api.mesh.Mesh` ``add_user_area``, or to add a mask +A :class:`~esmpy.api.mesh.Mesh` may also be created with boolean flags to specify whether or not to +add an area property to the :class:`~esmpy.api.mesh.Mesh` ``add_user_area``, or to add a mask ``add_mask`` held by the NetCDF variable indicated in the optional argument, -``varname``. These argument are only valid for :class:`~ESMF.api.constants.FileFormat.UGRID` formatted files. -The mask generated for a :class:`~ESMF.api.mesh.Mesh` created from file will +``varname``. These argument are only valid for :class:`~esmpy.api.constants.FileFormat.UGRID` formatted files. +The mask generated for a :class:`~esmpy.api.mesh.Mesh` created from file will have 0 for the masked values and 1 for the unmasked values. ~~~~~~~~~~~~~~~ @@ -665,22 +665,22 @@ Grids from File ~~~~~~~~~~~~~~~ A number of optional boolean arguments are also supported to create a -structured :class:`~ESMF.api.grid.Grid` from a file. These include ``is_sphere`` to indicate whether +structured :class:`~esmpy.api.grid.Grid` from a file. These include ``is_sphere`` to indicate whether the grid is spherical or regional, ``add_corner_stagger`` to add the corner -stagger information to the :class:`~ESMF.api.grid.Grid` for conservative regridding, and +stagger information to the :class:`~esmpy.api.grid.Grid` for conservative regridding, and ``add_user_area`` to specify whether to read in the cell area from the NetCDF file or to calculate them. -For :class:`~ESMF.api.constants.FileFormat.GRIDSPEC` formated files +For :class:`~esmpy.api.constants.FileFormat.GRIDSPEC` formated files there is the ``add_mask`` optional argument to add a mask held by the NetCDF variable indicated in optional argument, ``varname``, and the ``coord_names`` argument to specify the longitude -and latitude variable names in a :class:`~ESMF.api.constants.FileFormat.GRIDSPEC` file containing multiple sets of +and latitude variable names in a :class:`~esmpy.api.constants.FileFormat.GRIDSPEC` file containing multiple sets of coordinates. -For :class:`~ESMF.api.constants.FileFormat.SCRIP` formated files the integer array ``grid_imask`` is used to mask out grid cells which should not participate in the regridding. +For :class:`~esmpy.api.constants.FileFormat.SCRIP` formated files the integer array ``grid_imask`` is used to mask out grid cells which should not participate in the regridding. -The mask generated for a :class:`~ESMF.api.grid.Grid` created from +The mask generated for a :class:`~esmpy.api.grid.Grid` created from file (any format) will have 0 for the masked values and 1 for the unmasked values. @@ -694,20 +694,20 @@ More information can be found on these options in the `ESMF Reference Manual `_. -====================================================== =============================================== -Class Description -====================================================== =============================================== -:class:`~ESMF.api.constants.RegridMethod.BILINEAR` Linear regridding in two dimensions -:class:`~ESMF.api.constants.RegridMethod.PATCH` Higher-order least squares method -:class:`~ESMF.api.constants.RegridMethod.NEAREST_STOD` Nearest source point used for each destination -:class:`~ESMF.api.constants.RegridMethod.NEAREST_DTOS` Nearest destination point used for each source -:class:`~ESMF.api.constants.RegridMethod.CONSERVE` First-order conservative -:class:`~ESMF.api.constants.RegridMethod.CONSERVE_2ND` Second-order conservative -:class:`~ESMF.api.constants.NormType` Normalization options for integral conservation -:class:`~ESMF.api.constants.LineType` Line types for spherical and Cartesian space -:class:`~ESMF.api.constants.UnmappedAction` Unmapped destination point handling options -:class:`~ESMF.api.constants.CoordSys` Spherical grids and pole handling -====================================================== =============================================== +======================================================= =============================================== +Class Description +======================================================= =============================================== +:class:`~esmpy.api.constants.RegridMethod.BILINEAR` Linear regridding in two dimensions +:class:`~esmpy.api.constants.RegridMethod.PATCH` Higher-order least squares method +:class:`~esmpy.api.constants.RegridMethod.NEAREST_STOD` Nearest source point used for each destination +:class:`~esmpy.api.constants.RegridMethod.NEAREST_DTOS` Nearest destination point used for each source +:class:`~esmpy.api.constants.RegridMethod.CONSERVE` First-order conservative +:class:`~esmpy.api.constants.RegridMethod.CONSERVE_2ND` Second-order conservative +:class:`~esmpy.api.constants.NormType` Normalization options for integral conservation +:class:`~esmpy.api.constants.LineType` Line types for spherical and Cartesian space +:class:`~esmpy.api.constants.UnmappedAction` Unmapped destination point handling options +:class:`~esmpy.api.constants.CoordSys` Spherical grids and pole handling +======================================================= =============================================== ~~~~~~~~~~~~~~~~~~ Great Circle Cells @@ -737,21 +737,21 @@ Masking ------- .. _masking: -Masking is the process whereby parts of a :class:`~ESMF.api.grid.Grid`, :class:`~ESMF.api.mesh.Mesh` or :class:`~ESMF.api.locstream.LocStream` can be marked to be ignored -during an operation, such as when they are used in regridding. Masking can be used on a :class:`~ESMF.api.field.Field` +Masking is the process whereby parts of a :class:`~esmpy.api.grid.Grid`, :class:`~esmpy.api.mesh.Mesh` or :class:`~esmpy.api.locstream.LocStream` can be marked to be ignored +during an operation, such as when they are used in regridding. Masking can be used on a :class:`~esmpy.api.field.Field` created from a regridding source to indicate that certain portions should not be used to generate regridded data. This is useful, for example, if a portion of the source contains unusable values. -Masking can also be used on a :class:`~ESMF.api.field.Field` created from a regridding destination to indicate that a certain +Masking can also be used on a :class:`~esmpy.api.field.Field` created from a regridding destination to indicate that a certain portion should not receive regridded data. This is useful, for example, when part of the destination isn't being used (e.g. the land portion of an ocean grid). -The user may mask out points in the source :class:`~ESMF.api.field.Field` or destination :class:`~ESMF.api.field.Field` or both. To do masking the user -sets mask information in the :class:`~ESMF.api.grid.Grid`, :class:`~ESMF.api.mesh.Mesh`, or :class:`~ESMF.api.locstream.LocStream` upon -which the :class:`Fields ` passed into the :class:`~ESMF.api.regrid.Regrid` call are built. The ``src_mask_values`` and +The user may mask out points in the source :class:`~esmpy.api.field.Field` or destination :class:`~esmpy.api.field.Field` or both. To do masking the user +sets mask information in the :class:`~esmpy.api.grid.Grid`, :class:`~esmpy.api.mesh.Mesh`, or :class:`~esmpy.api.locstream.LocStream` upon +which the :class:`Fields ` passed into the :class:`~esmpy.api.regrid.Regrid` call are built. The ``src_mask_values`` and ``dst_mask_values`` arguments to that call can then be used to specify which values in that mask information indicate that a location should be masked out. For example, if ``dst_mask_values`` is set to [1,2], then any -location that has a value of 1 or 2 in the mask information of the :class:`~ESMF.api.grid.Grid`, :class:`~ESMF.api.mesh.Mesh` or :class:`~ESMF.api.locstream.LocStream` upon which -the destination :class:`~ESMF.api.field.Field` is built will be masked out. +location that has a value of 1 or 2 in the mask information of the :class:`~esmpy.api.grid.Grid`, :class:`~esmpy.api.mesh.Mesh` or :class:`~esmpy.api.locstream.LocStream` upon which +the destination :class:`~esmpy.api.field.Field` is built will be masked out. Masking behavior differs slightly between regridding methods. For non-conservative regridding methods (e.g. bilinear or high-order patch), masking is done on points. For these methods, masking a destination @@ -763,28 +763,29 @@ Masking a destination cell means that the cell won't participate in regridding. Similarly, masking a source cell means that the cell won't participate in regridding. For any type of interpolation method (conservative or non-conservative) the masking is set on the location upon which the -:class:`Fields ` passed into the regridding call are built. -For example, if :class:`Fields ` built on -:class:`StaggerLoc.CENTER ` are passed into -:class:`~ESMF.api.regrid.Regrid` -then the masking should also be set on :class:`StaggerLoc.CENTER `. - -The mask generated for a :class:`~ESMF.api.grid.Grid`, -:class:`~ESMF.api.mesh.Mesh` or :class:`~ESMF.api.locstream.LocStream` created +:class:`Fields ` passed into the regridding call are built. +For example, if :class:`Fields ` built on +:class:`StaggerLoc.CENTER ` are passed into +:class:`~esmpy.api.regrid.Regrid` +then the masking should also be set on :class:`StaggerLoc.CENTER `. + +The mask generated for a :class:`~esmpy.api.grid.Grid`, +:class:`~esmpy.api.mesh.Mesh` or :class:`~esmpy.api.locstream.LocStream` created from file will have 0 for the masked values and 1 for the unmasked values. -.. Note:: The :class:`Region.SELECT ` flag to the -``zero_region`` parameter of :class:`~ESMF.api.regrid.Regrid` can be used to -maintain :class:`Fields ` values on locations that do not +.. Note:: The :class:`Region.SELECT ` flag to the +``zero_region`` parameter of :class:`~esmpy.api.regrid.Regrid` can be used to +maintain :class:`Fields ` values on locations that do not participate in the regridding operation. This is useful when setting an uninitialized value to help identify masked locations within the -:class:`Fields ` data. +:class:`Fields ` data. + -------------------------- Numpy Slicing and Indexing -------------------------- -Numpy arrays are used to represent :class:`~ESMF.api.grid.Grid`, :class:`~ESMF.api.mesh.Mesh` and :class:`~ESMF.api.locstream.LocStream` coordinates and :class:`~ESMF.api.field.Field` data, +Numpy arrays are used to represent :class:`~esmpy.api.grid.Grid`, :class:`~esmpy.api.mesh.Mesh` and :class:`~esmpy.api.locstream.LocStream` coordinates and :class:`~esmpy.api.field.Field` data, among other things. Standard numpy conventions for array indexing and slicing can be expected. There are some exceptions when it comes to fancy indexing, index arrays, and multi-dimensional slicing. Significant effort has @@ -795,9 +796,9 @@ It is very important to remember that all indexing and slicing operations apply **ONLY** to the ESMPy level objects, and these operations do not propagate down to the lower-level Fortran- and C-based representations of the ESMF objects. One example of where this could come up is when passing -a :class:`~ESMF.api.field.Field` slice into regridding. The entire original :class:`~ESMF.api.field.Field` will still be run +a :class:`~esmpy.api.field.Field` slice into regridding. The entire original :class:`~esmpy.api.field.Field` will still be run through the ESMF regridding engine, and only the appropriate portion of -the :class:`~ESMF.api.field.Field` slice will be updated with the regridded values. +the :class:`~esmpy.api.field.Field` slice will be updated with the regridded values. ~~~~~~~~~~~~~~~~~~ Dimension Ordering @@ -815,9 +816,9 @@ Dimension Ordering .. code:: In [1]: import numpy as np - ...: import ESMF + ...: import esmpy ...: - ...: grid = ESMF.Grid(np.array([3,4]), staggerloc=ESMF.StaggerLoc.CENTER) + ...: grid = esmpy.Grid(np.array([3,4]), staggerloc=esmpy.StaggerLoc.CENTER) ...: ...: gridLon = grid.get_coords(0) ...: gridLat = grid.get_coords(1) @@ -831,7 +832,7 @@ Dimension Ordering ...: gridLat[:] = latm ...: - In [2]: grid.coords[ESMF.StaggerLoc.CENTER][0].shape + In [2]: grid.coords[esmpy.StaggerLoc.CENTER][0].shape Out[2]: (3, 4) In [3]: lon.shape @@ -840,19 +841,19 @@ Dimension Ordering In [4]: lat.shape Out[4]: (4,) - In [5]: grid.coords[ESMF.StaggerLoc.CENTER][0] + In [5]: grid.coords[esmpy.StaggerLoc.CENTER][0] Out[5]: array([[-120., -120., -120., -120.], [ 0., 0., 0., 0.], [ 120., 120., 120., 120.]]) - In [6]: grid.coords[ESMF.StaggerLoc.CENTER][1] + In [6]: grid.coords[esmpy.StaggerLoc.CENTER][1] Out[6]: array([[-67.5, -22.5, 22.5, 67.5], [-67.5, -22.5, 22.5, 67.5], [-67.5, -22.5, 22.5, 67.5]]) - In [7]: field = ESMF.Field(grid, ndbounds=[10]) # create a Field with a time dimension + In [7]: field = esmpy.Field(grid, ndbounds=[10]) # create a Field with a time dimension In [8]: field.data.shape Out[8]: (3, 4, 10) @@ -870,15 +871,15 @@ environment to be utilized by the ESMPy user with little use of specialized parallel programming techniques. ESMPy objects will be distributed across the available computing resources with -no additional parameters required. The :class:`~ESMF.api.grid.Grid`, :class:`~ESMF.api.mesh.Mesh`, :class:`~ESMF.api.locstream.LocStream`, and :class:`~ESMF.api.field.Field` classes +no additional parameters required. The :class:`~esmpy.api.grid.Grid`, :class:`~esmpy.api.mesh.Mesh`, :class:`~esmpy.api.locstream.LocStream`, and :class:`~esmpy.api.field.Field` classes will all be transparently "parallelized" with no need for user calls to a -message passing interface. Likewise, the :class:`~ESMF.api.regrid.Regrid` class will compute and apply +message passing interface. Likewise, the :class:`~esmpy.api.regrid.Regrid` class will compute and apply the interpolation weights using all available computing resources with no need for user intervention. -However, it is useful to remember that resulting :class:`~ESMF.api.field.Field` values will only be +However, it is useful to remember that resulting :class:`~esmpy.api.field.Field` values will only be accessible on certain PETs. The mpi4py package may be necessary for post -processing tasks that require access to global :class:`~ESMF.api.field.Field` values. +processing tasks that require access to global :class:`~esmpy.api.field.Field` values. ~~~~~~~~~~~~~~~~~~~~ mpirun vs. MPI.Spawn diff --git a/src/addon/ESMPy/doc/conf.py b/src/addon/ESMPy/doc/conf.py index f14df17791..3d482edae5 100644 --- a/src/addon/ESMPy/doc/conf.py +++ b/src/addon/ESMPy/doc/conf.py @@ -18,7 +18,7 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. sys.path.insert(0, os.path.abspath('../src')) -import ESMF +import esmpy # -- General configuration ----------------------------------------------------- @@ -58,7 +58,7 @@ # built documents. # # The full version, including alpha/beta/rc tags. -release = ESMF.__release__ +release = esmpy.__version__ # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/src/addon/ESMPy/doc/examples.rst b/src/addon/ESMPy/doc/examples.rst index 4363274b6a..06e8c522ec 100644 --- a/src/addon/ESMPy/doc/examples.rst +++ b/src/addon/ESMPy/doc/examples.rst @@ -13,57 +13,57 @@ Regridding Helper Functions --------------------------- The following code snippets demonstrate how to build all of the pieces -necessary to regrid data between :class:`Fields ` built on -:class:`Grids `, :class:`Meshes ` -and :class:`LocStreams `. +necessary to regrid data between :class:`Fields ` built on +:class:`Grids `, :class:`Meshes ` +and :class:`LocStreams `. ~~~~~~~~~~~~~~~~ LocStream Create ~~~~~~~~~~~~~~~~ -.. literalinclude:: ../src/ESMF/util/locstream_utilities.py +.. literalinclude:: ../src/esmpy/util/locstream_utilities.py :pyobject: create_locstream_spherical_16 ~~~~~~~~~~~~~~~~~~~~~~~~~ LocStream Create Parallel ~~~~~~~~~~~~~~~~~~~~~~~~~ -.. literalinclude:: ../src/ESMF/util/locstream_utilities.py +.. literalinclude:: ../src/esmpy/util/locstream_utilities.py :pyobject: create_locstream_spherical_16_parallel ~~~~~~~~~~~~~~~~ Create a 2D Grid ~~~~~~~~~~~~~~~~ - .. literalinclude:: ../src/ESMF/util/grid_utilities.py + .. literalinclude:: ../src/esmpy/util/grid_utilities.py :pyobject: grid_create_from_coordinates ~~~~~~~~~~~~~~~~ Create a 3D Grid ~~~~~~~~~~~~~~~~ - .. literalinclude:: ../src/ESMF/util/grid_utilities.py + .. literalinclude:: ../src/esmpy/util/grid_utilities.py :pyobject: grid_create_from_coordinates_3d ~~~~~~~~~~~~~~~~~~~~~~ Create a Periodic Grid ~~~~~~~~~~~~~~~~~~~~~~ - .. literalinclude:: ../src/ESMF/util/grid_utilities.py + .. literalinclude:: ../src/esmpy/util/grid_utilities.py :pyobject: grid_create_from_coordinates_periodic ~~~~~~~~~~~~~~~~~~~~~~~ Create a 5 Element Mesh ~~~~~~~~~~~~~~~~~~~~~~~ - .. literalinclude:: ../src/ESMF/util/mesh_utilities.py + .. literalinclude:: ../src/esmpy/util/mesh_utilities.py :pyobject: mesh_create_5 ~~~~~~~~~~~~~~ Create a Field ~~~~~~~~~~~~~~ - .. literalinclude:: ../src/ESMF/test/test_api/test_field.py + .. literalinclude:: ../src/esmpy/test/test_api/test_field.py :pyobject: TestField.create_field @@ -71,7 +71,7 @@ Create a Field Initialize an Analytic Field ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - .. literalinclude:: ../src/ESMF/util/grid_utilities.py + .. literalinclude:: ../src/esmpy/util/grid_utilities.py :pyobject: initialize_field_grid_periodic @@ -79,7 +79,7 @@ Initialize an Analytic Field Run ESMPy Regridding ~~~~~~~~~~~~~~~~~~~~ - .. literalinclude:: ../src/ESMF/test/test_api/test_regrid.py + .. literalinclude:: ../src/esmpy/test/test_api/test_regrid.py :pyobject: TestRegrid.run_regridding @@ -87,7 +87,7 @@ Run ESMPy Regridding Compute Field Mass ~~~~~~~~~~~~~~~~~~ - .. literalinclude:: ../src/ESMF/util/grid_utilities.py + .. literalinclude:: ../src/esmpy/util/grid_utilities.py :pyobject: compute_mass_grid @@ -96,9 +96,9 @@ Regridding ---------- The following stand alone scripts demonstrate how to use regridding between -:class:`Fields ` built on -:class:`Grids `, :class:`Meshes ` -and :class:`LocStreams `. These scripts +:class:`Fields ` built on +:class:`Grids `, :class:`Meshes ` +and :class:`LocStreams `. These scripts can be run in serial or parallel with no modification. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/addon/ESMPy/doc/field.rst b/src/addon/ESMPy/doc/field.rst index 6b1f42fc60..f1644ce199 100644 --- a/src/addon/ESMPy/doc/field.rst +++ b/src/addon/ESMPy/doc/field.rst @@ -2,7 +2,7 @@ Field ~~~~~ -.. autoclass:: ESMF.api.field.Field +.. autoclass:: esmpy.api.field.Field :members: copy, destroy, get_area, read, data, grid, lower_bounds, name, ndbounds, rank, staggerloc, type, upper_bounds, xd diff --git a/src/addon/ESMPy/doc/grid.rst b/src/addon/ESMPy/doc/grid.rst index f6f0b4249f..e399592494 100644 --- a/src/addon/ESMPy/doc/grid.rst +++ b/src/addon/ESMPy/doc/grid.rst @@ -2,7 +2,7 @@ Grid ~~~~ -.. autoclass:: ESMF.api.grid.Grid +.. autoclass:: esmpy.api.grid.Grid :members: add_coords, add_item, copy, destroy, get_coords, get_item, area, areatype, coords, coord_sys, has_corners, lower_bounds, mask, max_index, num_peri_dims, periodic_dim, pole_dim, diff --git a/src/addon/ESMPy/doc/install.rst b/src/addon/ESMPy/doc/install.rst index 40a02896ff..dbd79dd29a 100644 --- a/src/addon/ESMPy/doc/install.rst +++ b/src/addon/ESMPy/doc/install.rst @@ -9,12 +9,12 @@ Requirements The following packages are *required* to work with ESMPy: * `ESMF installation `_ -* `python `_ +* `python `_, minimum version 3.7 * `numpy `_ The following packages are *optional*: -* ESMF installation with NetCDF - required to create :class:`Grids ` and :class:`Meshes ` from file +* ESMF installation with NetCDF - required to create :class:`Grids ` and :class:`Meshes ` from file - NetCDF must be built as a shared library for ESMPy installation to succeed * `mpi4py `_- python bindings to MPI, needed to run some of the parallel regridding examples * `pytest `_ - for testing @@ -27,7 +27,7 @@ The ESMPy source code can be downloaded from the `ESMF git repository `_. The `ESMF User's Guide `_ -contains information on building and installing ESMF. +contains information on building and installing esmpy. The `ESMF Reference Manual `_ contains information on the architecture of ESMF, example code, and details of the API (Application Programming @@ -88,7 +88,7 @@ To use ESMPy in an external program, import it with: .. code:: - import ESMF + import esmpy ---------- Validation @@ -110,13 +110,11 @@ greater test coverage is desired: make test_examples - make test_regrid_from_file - make test_unit_parallel make test_examples_parallel - - make test_regrid_from_file_parallel + + make test_regrid_from_file .. Note:: @@ -136,16 +134,16 @@ to ESMF offline and integrated regridding capabilities. - ESMPy cannot use an ESMF installation that is built with external LAPACK support. - Coordinates cannot be retrieved from the elements of a - :class:`~ESMF.api.mesh.Mesh`. This can affect the ability to set - :class:`~ESMF.api.field.Field` values on a source :class:`~ESMF.api.mesh.Mesh` + :class:`~esmpy.api.mesh.Mesh`. This can affect the ability to set + :class:`~esmpy.api.field.Field` values on a source :class:`~esmpy.api.mesh.Mesh` created from file when using conservative regridding. -- Multi-tile :class:`~ESMF.api.grid.Grid` support is limited to cubed-sphere +- Multi-tile :class:`~esmpy.api.grid.Grid` support is limited to cubed-sphere grids created on 6 processors. A cubed-sphere grid can be created on any number of processors, but only when it is created on 6 processors will the coordinates be retrievable for the entire object. A - :class:`~ESMF.api.field.Field` created from a cubed-sphere - :class:`~ESMF.api.grid.Grid` cannot be written to file in parallel. -- There is no ``FieldBundle`` class, only single :class:`Fields `. + :class:`~esmpy.api.field.Field` created from a cubed-sphere + :class:`~esmpy.api.grid.Grid` cannot be written to file in parallel. +- There is no ``FieldBundle`` class, only single :class:`Fields `. Testing related: diff --git a/src/addon/ESMPy/doc/intro.rst b/src/addon/ESMPy/doc/intro.rst index dd618cfc8c..ce4ee2b2ca 100644 --- a/src/addon/ESMPy/doc/intro.rst +++ b/src/addon/ESMPy/doc/intro.rst @@ -2,7 +2,7 @@ Overview -------- -.. automodule:: ESMF +.. automodule:: esmpy --------------- Important Links @@ -28,4 +28,3 @@ Information on these can be found in the `_. Please contact esmf_support@ucar.edu with any questions or problems. - diff --git a/src/addon/ESMPy/doc/locstream.rst b/src/addon/ESMPy/doc/locstream.rst index 1a0f414a12..79a784a206 100644 --- a/src/addon/ESMPy/doc/locstream.rst +++ b/src/addon/ESMPy/doc/locstream.rst @@ -2,5 +2,5 @@ LocStream ~~~~~~~~~ -.. autoclass:: ESMF.api.locstream.LocStream +.. autoclass:: esmpy.api.locstream.LocStream :members: copy, destroy, lower_bounds, name, rank, size, upper_bounds diff --git a/src/addon/ESMPy/doc/manager.rst b/src/addon/ESMPy/doc/manager.rst index fc28fd9656..5b3fa31648 100644 --- a/src/addon/ESMPy/doc/manager.rst +++ b/src/addon/ESMPy/doc/manager.rst @@ -2,5 +2,5 @@ Manager ~~~~~~~ -.. autoclass:: ESMF.api.esmpymanager.Manager +.. autoclass:: esmpy.api.esmpymanager.Manager :members: local_pet, moab, pet_count, barrier, set_moab \ No newline at end of file diff --git a/src/addon/ESMPy/doc/mesh.rst b/src/addon/ESMPy/doc/mesh.rst index 28b6a4f546..7c2b38399e 100644 --- a/src/addon/ESMPy/doc/mesh.rst +++ b/src/addon/ESMPy/doc/mesh.rst @@ -2,6 +2,6 @@ Mesh ~~~~ -.. autoclass:: ESMF.api.mesh.Mesh +.. autoclass:: esmpy.api.mesh.Mesh :members: copy, destroy, add_elements, add_nodes, free_memory, get_coords, area, coords, coord_sys, mask, rank, size, size_owned \ No newline at end of file diff --git a/src/addon/ESMPy/doc/regrid.rst b/src/addon/ESMPy/doc/regrid.rst index 9fe086690f..f647deb5cf 100644 --- a/src/addon/ESMPy/doc/regrid.rst +++ b/src/addon/ESMPy/doc/regrid.rst @@ -2,5 +2,5 @@ Regrid ~~~~~~ -.. autoclass:: ESMF.api.regrid.Regrid +.. autoclass:: esmpy.api.regrid.Regrid :members: copy, destroy, __call__, get_factors, get_weights_dict diff --git a/src/addon/ESMPy/doc/regridfromfile.rst b/src/addon/ESMPy/doc/regridfromfile.rst index 66d9ea9705..ed5af263f9 100644 --- a/src/addon/ESMPy/doc/regridfromfile.rst +++ b/src/addon/ESMPy/doc/regridfromfile.rst @@ -2,5 +2,5 @@ RegridFromFile ~~~~~~~~~~~~~~ -.. autoclass:: ESMF.api.regrid.RegridFromFile +.. autoclass:: esmpy.api.regrid.RegridFromFile :members: copy, destroy, __call__ diff --git a/src/addon/ESMPy/examples/cubed_sphere_to_mesh_regrid.py b/src/addon/ESMPy/examples/cubed_sphere_to_mesh_regrid.py index c5cc0a3672..0544e036dc 100644 --- a/src/addon/ESMPy/examples/cubed_sphere_to_mesh_regrid.py +++ b/src/addon/ESMPy/examples/cubed_sphere_to_mesh_regrid.py @@ -7,46 +7,46 @@ # DD = os.path.join(os.getcwd(), "examples/data") # if not os.path.isdir(DD): # os.makedirs(DD) -# from ESMF.util.cache_data import cache_data_file +# from esmpy.util.cache_data import cache_data_file # cache_data_file(os.path.join(DD, "ll1deg_grid.nc")) -import ESMF +import esmpy import numpy -import ESMF.util.helpers as helpers -import ESMF.api.constants as constants +import esmpy.util.helpers as helpers +import esmpy.api.constants as constants # This call enables debug logging when debug=True -mg = ESMF.Manager(debug=False) +mg = esmpy.Manager(debug=False) -# if ESMF.pet_count() != 6: +# if esmpy.pet_count() != 6: # print ("ESMPy cubed sphere regridding example requires 6 processors") # import sys; sys.exit(0) grid1 = "examples/data/ll1deg_grid.nc" # Create a cubed sphere grid with 20 elements per tile -srcgrid = ESMF.Grid(tilesize=20, name="cubed_sphere") +srcgrid = esmpy.Grid(tilesize=20, name="cubed_sphere") # create an regular lat lon grid from file -dstgrid = ESMF.Grid(filename=grid1, filetype=ESMF.FileFormat.SCRIP) +dstgrid = esmpy.Grid(filename=grid1, filetype=esmpy.FileFormat.SCRIP) # create a field on the center stagger locations of the source grid -srcfield = ESMF.Field(srcgrid, name='srcfield', staggerloc=ESMF.StaggerLoc.CENTER) -srcfracfield = ESMF.Field(srcgrid, name='srcfracfield', staggerloc=ESMF.StaggerLoc.CENTER) +srcfield = esmpy.Field(srcgrid, name='srcfield', staggerloc=esmpy.StaggerLoc.CENTER) +srcfracfield = esmpy.Field(srcgrid, name='srcfracfield', staggerloc=esmpy.StaggerLoc.CENTER) # create a field on the center stagger locations of the destination grid -dstfield = ESMF.Field(dstgrid, name='dstfield', staggerloc=ESMF.StaggerLoc.CENTER) -xctfield = ESMF.Field(dstgrid, name='xctfield', staggerloc=ESMF.StaggerLoc.CENTER) -dstfracfield = ESMF.Field(dstgrid, name='dstfracfield', staggerloc=ESMF.StaggerLoc.CENTER) +dstfield = esmpy.Field(dstgrid, name='dstfield', staggerloc=esmpy.StaggerLoc.CENTER) +xctfield = esmpy.Field(dstgrid, name='xctfield', staggerloc=esmpy.StaggerLoc.CENTER) +dstfracfield = esmpy.Field(dstgrid, name='dstfracfield', staggerloc=esmpy.StaggerLoc.CENTER) # initialize the fields [lon,lat] = [0, 1] deg2rad = 3.14/180. -gridLon = srcfield.grid.get_coords(lon, ESMF.StaggerLoc.CENTER) -gridLat = srcfield.grid.get_coords(lat, ESMF.StaggerLoc.CENTER) +gridLon = srcfield.grid.get_coords(lon, esmpy.StaggerLoc.CENTER) +gridLat = srcfield.grid.get_coords(lat, esmpy.StaggerLoc.CENTER) x = numpy.cos(numpy.radians(gridLon))*numpy.sin(numpy.radians(90-gridLat)) y = numpy.sin(numpy.radians(gridLon))*numpy.sin(numpy.radians(90-gridLat)) @@ -54,8 +54,8 @@ srcfield.data[...] = 200.0 + x + y + z -gridLon = xctfield.grid.get_coords(lon, ESMF.StaggerLoc.CENTER) -gridLat = xctfield.grid.get_coords(lat, ESMF.StaggerLoc.CENTER) +gridLon = xctfield.grid.get_coords(lon, esmpy.StaggerLoc.CENTER) +gridLat = xctfield.grid.get_coords(lat, esmpy.StaggerLoc.CENTER) x = numpy.cos(numpy.radians(gridLon))*numpy.sin(numpy.radians(90-gridLat)) y = numpy.sin(numpy.radians(gridLon))*numpy.sin(numpy.radians(90-gridLat)) @@ -68,18 +68,18 @@ # write regridding weights to file import os filename = "esmpy_example_weight_file_cs.nc" -if ESMF.local_pet() == 0: +if esmpy.local_pet() == 0: if os.path.isfile(os.path.join(os.getcwd(), filename)): os.remove(os.path.join(os.getcwd(), filename)) mg.barrier() -regrid = ESMF.Regrid(srcfield, dstfield, filename=filename, - regrid_method=ESMF.RegridMethod.BILINEAR, - unmapped_action=ESMF.UnmappedAction.ERROR) +regrid = esmpy.Regrid(srcfield, dstfield, filename=filename, + regrid_method=esmpy.RegridMethod.BILINEAR, + unmapped_action=esmpy.UnmappedAction.ERROR) mg.barrier() -regrid = ESMF.RegridFromFile(srcfield, dstfield, filename=filename) +regrid = esmpy.RegridFromFile(srcfield, dstfield, filename=filename) # do the regridding from source to destination field mg.barrier() @@ -97,13 +97,13 @@ maxrelerr = numpy.max(numpy.abs(dstfield.data - xctfield.data) / numpy.abs(xctfield.data)) # handle the parallel case -if ESMF.pet_count() > 1: +if esmpy.pet_count() > 1: relerr = helpers.reduce_val(relerr, op=constants.Reduce.SUM) maxrelerr = helpers.reduce_val(maxrelerr, op=constants.Reduce.MAX) num_nodes = helpers.reduce_val(num_nodes, op=constants.Reduce.SUM) # output the results from one processor only -if ESMF.local_pet() == 0: +if esmpy.local_pet() == 0: meanrelerr = relerr / num_nodes print ("ESMPy cubed sphere regridding example") print (" interpolation mean relative error = {0}".format(meanrelerr)) diff --git a/src/addon/ESMPy/examples/exampletest.py b/src/addon/ESMPy/examples/exampletest.py index d82f2e56ad..7ec3c92018 100644 --- a/src/addon/ESMPy/examples/exampletest.py +++ b/src/addon/ESMPy/examples/exampletest.py @@ -6,14 +6,14 @@ import pytest -from ESMF.test.base import TestBase, attr, SkipTest -import ESMF.api.constants as constants +from esmpy.test.base import TestBase, attr, SkipTest +import esmpy.api.constants as constants class TestExamples(TestBase): # '0' in the name is so it is run first def test_0_examples_dryrun(self): - from ESMF.util.cache_data import cache_data_files + from esmpy.util.cache_data import cache_data_files cache_data_files() def test_helloworld(self): diff --git a/src/addon/ESMPy/examples/exampletestdryrun.py b/src/addon/ESMPy/examples/exampletestdryrun.py index 8484ede406..7e8e5e304b 100644 --- a/src/addon/ESMPy/examples/exampletestdryrun.py +++ b/src/addon/ESMPy/examples/exampletestdryrun.py @@ -6,10 +6,10 @@ import pytest -from ESMF.test.base import TestBase, attr +from esmpy.test.base import TestBase, attr class TestExamplesDryrun(TestBase): def test_examples_dryrun(self): - from ESMF.util.cache_data import cache_data_files + from esmpy.util.cache_data import cache_data_files cache_data_files() diff --git a/src/addon/ESMPy/examples/field_read.py b/src/addon/ESMPy/examples/field_read.py index c69060e989..d09e536606 100644 --- a/src/addon/ESMPy/examples/field_read.py +++ b/src/addon/ESMPy/examples/field_read.py @@ -7,45 +7,45 @@ # DD = os.path.join(os.getcwd(), "examples/data") # if not os.path.isdir(DD): # os.makedirs(DD) -# from ESMF.util.cache_data import cache_data_file +# from esmpy.util.cache_data import cache_data_file # cache_data_file(os.path.join(DD, "so_Omon_GISS-E2.nc")) # cache_data_file(os.path.join(DD, "ll1deg_grid.nc")) -import ESMF +import esmpy # This call enables debug logging -esmpy = ESMF.Manager(debug=True) +esmpy.Manager(debug=True) datafile = "examples/data/so_Omon_GISS-E2.nc" gridfile = "examples/data/ll1deg_grid.nc" # Create a grid from a GRIDSPEC formatted file -srcgrid = ESMF.Grid(filename=datafile, filetype=ESMF.FileFormat.GRIDSPEC) +srcgrid = esmpy.Grid(filename=datafile, filetype=esmpy.FileFormat.GRIDSPEC) # Create a field on the center stagger locations of the source grid with # ungridded dimensions large enough to receive the data from file # dimensions follow Fortran index order: lon, lat, level, time -srcfield = ESMF.Field(srcgrid, staggerloc=ESMF.StaggerLoc.CENTER, ndbounds=[33, 2]) +srcfield = esmpy.Field(srcgrid, staggerloc=esmpy.StaggerLoc.CENTER, ndbounds=[33, 2]) # Read the field data into the data structure srcfield.read(filename=datafile, variable="so", timeslice=2) # Create a 1 degree latlon grid -dstgrid = ESMF.Grid(filename=gridfile, filetype=ESMF.FileFormat.SCRIP) +dstgrid = esmpy.Grid(filename=gridfile, filetype=esmpy.FileFormat.SCRIP) # Create a field on the center stagger locations of the latlon grid, also with # ungridded dimensions large enough to recieve the data from the source field -dstfield = ESMF.Field(dstgrid, name='dstfield', meshloc=ESMF.StaggerLoc.CENTER, +dstfield = esmpy.Field(dstgrid, name='dstfield', meshloc=esmpy.StaggerLoc.CENTER, ndbounds=[33, 2]) dstfield.data[...] = 1e20 # Create an object to regrid data from the source to the destination field -regrid = ESMF.Regrid(srcfield, dstfield, - regrid_method=ESMF.RegridMethod.BILINEAR, - unmapped_action=ESMF.UnmappedAction.IGNORE) +regrid = esmpy.Regrid(srcfield, dstfield, + regrid_method=esmpy.RegridMethod.BILINEAR, + unmapped_action=esmpy.UnmappedAction.IGNORE) # Do the regridding from source to destination field dstfield = regrid(srcfield, dstfield) # Output the results from one processor only -if ESMF.local_pet() == 0: print ("ESMPy Field Data Regridding Example Finished Successfully") \ No newline at end of file +if esmpy.local_pet() == 0: print ("ESMPy Field Data Regridding Example Finished Successfully") diff --git a/src/addon/ESMPy/examples/grid_create_peridim_mask.py b/src/addon/ESMPy/examples/grid_create_peridim_mask.py index bae26f869d..04553bf3b2 100644 --- a/src/addon/ESMPy/examples/grid_create_peridim_mask.py +++ b/src/addon/ESMPy/examples/grid_create_peridim_mask.py @@ -7,19 +7,19 @@ # DD = os.path.join(os.getcwd(), "examples/data") # if not os.path.isdir(DD): # os.makedirs(DD) -# from ESMF.util.cache_data import cache_data_file +# from esmpy.util.cache_data import cache_data_file # cache_data_file(os.path.join(DD, "ll2.5deg_grid.nc")) -import ESMF +import esmpy import numpy -import ESMF.util.helpers as helpers -import ESMF.api.constants as constants +import esmpy.util.helpers as helpers +import esmpy.api.constants as constants gridfile = "examples/data/ll2.5deg_grid.nc" # This call enables debug logging -# esmpy = ESMF.Manager(debug=True) +# esmpy = esmpy.Manager(debug=True) # Create the source grid from memory with periodic dimension specified. [lat,lon] = [1,0] @@ -27,51 +27,51 @@ lats = numpy.arange( 0, 360, 360./70.) lons = numpy.arange(-90., 90.1, 180./140.) max_index = numpy.array([lons.size, lats.size]) -srcgrid = ESMF.Grid(max_index, coord_sys=ESMF.CoordSys.SPH_DEG, coord_typekind=ESMF.TypeKind.R4, +srcgrid = esmpy.Grid(max_index, coord_sys=esmpy.CoordSys.SPH_DEG, coord_typekind=esmpy.TypeKind.R4, num_peri_dims=1, periodic_dim=1, pole_dim=0) # Add coordinates to the source grid. -srcgrid.add_coords(staggerloc=[ESMF.StaggerLoc.CENTER]) +srcgrid.add_coords(staggerloc=[esmpy.StaggerLoc.CENTER]) # Get and set the source grid coordinates. gridCoordLat = srcgrid.get_coords(lat) gridCoordLon = srcgrid.get_coords(lon) -lons_par = lons[srcgrid.lower_bounds[ESMF.StaggerLoc.CENTER][0]:srcgrid.upper_bounds[ESMF.StaggerLoc.CENTER][0]] -lats_par = lats[srcgrid.lower_bounds[ESMF.StaggerLoc.CENTER][1]:srcgrid.upper_bounds[ESMF.StaggerLoc.CENTER][1]] +lons_par = lons[srcgrid.lower_bounds[esmpy.StaggerLoc.CENTER][0]:srcgrid.upper_bounds[esmpy.StaggerLoc.CENTER][0]] +lats_par = lats[srcgrid.lower_bounds[esmpy.StaggerLoc.CENTER][1]:srcgrid.upper_bounds[esmpy.StaggerLoc.CENTER][1]] gridCoordLat[...] = lats_par.reshape(1, lats_par.size) gridCoordLon[...] = lons_par.reshape(lons_par.size, 1) # Add a mask to the source grid -mask = srcgrid.add_item(ESMF.GridItem.MASK) +mask = srcgrid.add_item(esmpy.GridItem.MASK) dx=gridCoordLon-max_index[0]/2.0 dy=gridCoordLat-max_index[1]/2.0 mask[...] = 0 mask[numpy.where(numpy.sqrt(dx*dx+dy*dy) < 10.0)] = 2 # Create a field on the centers of the source grid with the mask applied. -srcfield = ESMF.Field(srcgrid, name="srcfield", staggerloc=ESMF.StaggerLoc.CENTER) +srcfield = esmpy.Field(srcgrid, name="srcfield", staggerloc=esmpy.StaggerLoc.CENTER) srcfield.data[...] = 0 # Create a destination grid from a SCRIP formatted file. -dstgrid = ESMF.Grid(filename=gridfile, - filetype=ESMF.FileFormat.SCRIP) +dstgrid = esmpy.Grid(filename=gridfile, + filetype=esmpy.FileFormat.SCRIP) # Create a field on the centers of the destination grid. -dstfield = ESMF.Field(dstgrid, name="dstfield", staggerloc=ESMF.StaggerLoc.CENTER) +dstfield = esmpy.Field(dstgrid, name="dstfield", staggerloc=esmpy.StaggerLoc.CENTER) missing_val = 1000 dstfield.data[...] = missing_val # Regrid from source grid to destination grid. -regridSrc2Dst = ESMF.Regrid(srcfield, dstfield, +regridSrc2Dst = esmpy.Regrid(srcfield, dstfield, src_mask_values=numpy.array([2], dtype=numpy.int32), - regrid_method=ESMF.RegridMethod.BILINEAR, - unmapped_action=ESMF.UnmappedAction.IGNORE) + regrid_method=esmpy.RegridMethod.BILINEAR, + unmapped_action=esmpy.UnmappedAction.IGNORE) -dstfield = regridSrc2Dst(srcfield, dstfield, zero_region=ESMF.Region.SELECT) +dstfield = regridSrc2Dst(srcfield, dstfield, zero_region=esmpy.Region.SELECT) dgridCoordLat = dstgrid.get_coords(lat) dstmaskedlats = dgridCoordLat[numpy.where(dstfield.data == missing_val)] @@ -79,9 +79,9 @@ masked_values = dstmaskedlats.size # handle the parallel case -if ESMF.pet_count() > 1: +if esmpy.pet_count() > 1: masked_values = helpers.reduce_val(dstmaskedlats.size, op=constants.Reduce.SUM) -if ESMF.local_pet() == 0: +if esmpy.local_pet() == 0: assert (masked_values > 0) print ("Successfully created a grid with masking and switched periodic dimensions for regridding!") diff --git a/src/addon/ESMPy/examples/grid_locstream_regrid.py b/src/addon/ESMPy/examples/grid_locstream_regrid.py index 164d5c9211..5c2b6e3720 100644 --- a/src/addon/ESMPy/examples/grid_locstream_regrid.py +++ b/src/addon/ESMPy/examples/grid_locstream_regrid.py @@ -6,23 +6,23 @@ # DD = os.path.join(os.getcwd(), "examples/data") # if not os.path.isdir(DD): # os.makedirs(DD) -# from ESMF.util.cache_data import cache_data_file +# from esmpy.util.cache_data import cache_data_file # cache_data_file(os.path.join(DD, "ll1deg_grid.nc")) -import ESMF +import esmpy import numpy -import ESMF.util.helpers as helpers -import ESMF.api.constants as constants -from ESMF.test.base import SkipTest +import esmpy.util.helpers as helpers +import esmpy.api.constants as constants +from esmpy.test.base import SkipTest # This call enables debug logging -ESMF.Manager(debug=True) +esmpy.Manager(debug=True) -from ESMF.util.locstream_utilities import create_locstream_spherical_16, create_locstream_spherical_16_parallel -coord_sys=ESMF.CoordSys.SPH_DEG +from esmpy.util.locstream_utilities import create_locstream_spherical_16, create_locstream_spherical_16_parallel +coord_sys=esmpy.CoordSys.SPH_DEG domask=True -if ESMF.pet_count() == 1: +if esmpy.pet_count() == 1: locstream = create_locstream_spherical_16(coord_sys=coord_sys, domask=domask) else: if constants._ESMF_MPIRUN_NP != 4: @@ -31,13 +31,13 @@ locstream = create_locstream_spherical_16_parallel(coord_sys=coord_sys, domask=domask) grid1 = "examples/data/ll1deg_grid.nc" -grid = ESMF.Grid(filename=grid1, filetype=ESMF.FileFormat.SCRIP) +grid = esmpy.Grid(filename=grid1, filetype=esmpy.FileFormat.SCRIP) # create a field -srcfield = ESMF.Field(grid, name='srcfield') +srcfield = esmpy.Field(grid, name='srcfield') -dstfield = ESMF.Field(locstream, name='dstfield') -xctfield = ESMF.Field(locstream, name='xctfield') +dstfield = esmpy.Field(locstream, name='dstfield') +xctfield = esmpy.Field(locstream, name='xctfield') # initialize the fields [x, y] = [0, 1] @@ -49,9 +49,9 @@ gridXCoord = locstream["ESMF:Lon"] gridYCoord = locstream["ESMF:Lat"] -if coord_sys == ESMF.CoordSys.SPH_DEG: +if coord_sys == esmpy.CoordSys.SPH_DEG: xctfield.data[...] = 10.0 + numpy.cos(gridXCoord * deg2rad) ** 2 + numpy.cos(2 * gridYCoord * deg2rad) -elif coord_sys == ESMF.CoordSys.SPH_RAD: +elif coord_sys == esmpy.CoordSys.SPH_RAD: xctfield.data[...] = 10.0 + numpy.cos(gridXCoord) ** 2 + numpy.cos(2 * gridYCoord) else: raise ValueError("coordsys value does not work in this example") @@ -63,13 +63,13 @@ if domask: dst_mask_values=numpy.array([0]) -regrid = ESMF.Regrid(srcfield, dstfield, - regrid_method=ESMF.RegridMethod.BILINEAR, - unmapped_action=ESMF.UnmappedAction.ERROR, +regrid = esmpy.Regrid(srcfield, dstfield, + regrid_method=esmpy.RegridMethod.BILINEAR, + unmapped_action=esmpy.UnmappedAction.ERROR, dst_mask_values=dst_mask_values) # do the regridding from source to destination field -dstfield = regrid(srcfield, dstfield, zero_region=ESMF.Region.SELECT) +dstfield = regrid(srcfield, dstfield, zero_region=esmpy.Region.SELECT) # compute the mean relative error num_nodes = numpy.prod(xctfield.data.shape[:]) @@ -85,12 +85,12 @@ meanrelerr = relerr / num_nodes # handle the parallel case -if ESMF.pet_count() > 1: +if esmpy.pet_count() > 1: relerr = helpers.reduce_val(relerr, op=constants.Reduce.SUM) num_nodes = helpers.reduce_val(num_nodes, op=constants.Reduce.SUM) # output the results from one processor only -if ESMF.local_pet() == 0: +if esmpy.local_pet() == 0: meanrelerr = relerr / num_nodes print ("ESMPy Grid LocStream Regridding Example") print (" interpolation mean relative error = {0}".format(meanrelerr)) diff --git a/src/addon/ESMPy/examples/hello_world.py b/src/addon/ESMPy/examples/hello_world.py index c5fa2dc174..412da2e2f3 100644 --- a/src/addon/ESMPy/examples/hello_world.py +++ b/src/addon/ESMPy/examples/hello_world.py @@ -1,6 +1,6 @@ -import ESMF +import esmpy # This call enables debug logging -# esmpy = ESMF.Manager(debug=True) +# esmpy = esmpy.Manager(debug=True) -print ("Hello ESMPy World from PET (processor) {0}!".format(ESMF.local_pet())) \ No newline at end of file +print ("Hello ESMPy World from PET (processor) {0}!".format(esmpy.local_pet())) \ No newline at end of file diff --git a/src/addon/ESMPy/examples/locstream_grid_regrid.py b/src/addon/ESMPy/examples/locstream_grid_regrid.py index 4d1019b409..159fcac2d4 100644 --- a/src/addon/ESMPy/examples/locstream_grid_regrid.py +++ b/src/addon/ESMPy/examples/locstream_grid_regrid.py @@ -6,26 +6,26 @@ # DD = os.path.join(os.getcwd(), "examples/data") # if not os.path.isdir(DD): # os.makedirs(DD) -# from ESMF.util.cache_data import cache_data_file +# from esmpy.util.cache_data import cache_data_file # cache_data_file(os.path.join(DD, "ll1deg_grid.nc")) -import ESMF +import esmpy import numpy -import ESMF.util.helpers as helpers -import ESMF.api.constants as constants -from ESMF.test.base import TestBase, attr, SkipTest +import esmpy.util.helpers as helpers +import esmpy.api.constants as constants +from esmpy.test.base import TestBase, attr, SkipTest # This call enables debug logging -ESMF.Manager(debug=True) +esmpy.Manager(debug=True) grid1 = "examples/data/ll1deg_grid.nc" -grid = ESMF.Grid(filename=grid1, filetype=ESMF.FileFormat.SCRIP) +grid = esmpy.Grid(filename=grid1, filetype=esmpy.FileFormat.SCRIP) -from ESMF.util.locstream_utilities import create_locstream_spherical_16, create_locstream_spherical_16_parallel -coord_sys=ESMF.CoordSys.SPH_DEG +from esmpy.util.locstream_utilities import create_locstream_spherical_16, create_locstream_spherical_16_parallel +coord_sys=esmpy.CoordSys.SPH_DEG domask=True -if ESMF.pet_count() == 1: +if esmpy.pet_count() == 1: locstream = create_locstream_spherical_16(coord_sys=coord_sys, domask=domask) else: if constants._ESMF_MPIRUN_NP != 4: @@ -34,10 +34,10 @@ locstream = create_locstream_spherical_16_parallel(coord_sys=coord_sys, domask=domask) # create a field -srcfield = ESMF.Field(locstream, name='srcfield') +srcfield = esmpy.Field(locstream, name='srcfield') -dstfield = ESMF.Field(grid, name='dstfield') -xctfield = ESMF.Field(grid, name='xctfield') +dstfield = esmpy.Field(grid, name='dstfield') +xctfield = esmpy.Field(grid, name='xctfield') # initialize the fields [x, y] = [0, 1] @@ -45,9 +45,9 @@ gridXCoord = locstream["ESMF:Lon"] gridYCoord = locstream["ESMF:Lat"] -if coord_sys == ESMF.CoordSys.SPH_DEG: +if coord_sys == esmpy.CoordSys.SPH_DEG: srcfield.data[...] = 10.0 + numpy.cos(gridXCoord * deg2rad) ** 2 + numpy.cos(2 * gridYCoord * deg2rad) -elif coord_sys == ESMF.CoordSys.SPH_RAD: +elif coord_sys == esmpy.CoordSys.SPH_RAD: srcfield.data[...] = 10.0 + numpy.cos(gridXCoord) ** 2 + numpy.cos(2 * gridYCoord) else: raise ValueError("coordsys value does not apply in this example") @@ -64,13 +64,13 @@ if domask: mask_values=numpy.array([0]) -regrid = ESMF.Regrid(srcfield, dstfield, - regrid_method=ESMF.RegridMethod.NEAREST_DTOS, - unmapped_action=ESMF.UnmappedAction.ERROR, +regrid = esmpy.Regrid(srcfield, dstfield, + regrid_method=esmpy.RegridMethod.NEAREST_DTOS, + unmapped_action=esmpy.UnmappedAction.ERROR, src_mask_values=mask_values) # do the regridding from source to destination field -dstfield = regrid(srcfield, dstfield, zero_region=ESMF.Region.SELECT) +dstfield = regrid(srcfield, dstfield, zero_region=esmpy.Region.SELECT) # compute the mean relative error from operator import mul @@ -87,12 +87,12 @@ meanrelerr = relerr / num_nodes # handle the parallel case -if ESMF.pet_count() > 1: +if esmpy.pet_count() > 1: relerr = helpers.reduce_val(relerr, op=constants.Reduce.SUM) num_nodes = helpers.reduce_val(num_nodes, op=constants.Reduce.SUM) # output the results from one processor only -if ESMF.local_pet() == 0: +if esmpy.local_pet() == 0: meanrelerr = relerr / num_nodes print ("ESMPy LocStream Grid Regridding Example") print (" interpolation mean relative error = {0}".format(meanrelerr)) diff --git a/src/addon/ESMPy/examples/mesh_locstream_regrid.py b/src/addon/ESMPy/examples/mesh_locstream_regrid.py index e88425410c..e0841d06ca 100644 --- a/src/addon/ESMPy/examples/mesh_locstream_regrid.py +++ b/src/addon/ESMPy/examples/mesh_locstream_regrid.py @@ -1,18 +1,18 @@ # This example demonstrates how to regrid between a mesh and a locstream. -import ESMF +import esmpy import numpy -import ESMF.util.helpers as helpers -import ESMF.api.constants as constants -from ESMF.test.base import TestBase, attr, SkipTest +import esmpy.util.helpers as helpers +import esmpy.api.constants as constants +from esmpy.test.base import TestBase, attr, SkipTest # This call enables debug logging -# ESMF.Manager(debug=True) +# esmpy.Manager(debug=True) -from ESMF.util.mesh_utilities import mesh_create_5, mesh_create_5_parallel -from ESMF.util.locstream_utilities import create_locstream_16, create_locstream_16_parallel -if ESMF.pet_count() == 1: +from esmpy.util.mesh_utilities import mesh_create_5, mesh_create_5_parallel +from esmpy.util.locstream_utilities import create_locstream_16, create_locstream_16_parallel +if esmpy.pet_count() == 1: mesh, _, _, _, _, _ = mesh_create_5() locstream = create_locstream_16() else: @@ -23,11 +23,11 @@ locstream = create_locstream_16_parallel() # create a field -srcfield = ESMF.Field(mesh, name='srcfield')#, meshloc=ESMF.MeshLoc.ELEMENT) +srcfield = esmpy.Field(mesh, name='srcfield')#, meshloc=esmpy.MeshLoc.ELEMENT) # create a field on the locstream -dstfield = ESMF.Field(locstream, name='dstfield') -xctfield = ESMF.Field(locstream, name='xctfield') +dstfield = esmpy.Field(locstream, name='dstfield') +xctfield = esmpy.Field(locstream, name='xctfield') # initialize the fields [x, y] = [0, 1] @@ -45,8 +45,8 @@ # create an object to regrid data from the source to the destination field # TODO: this example seems to fail occasionally with UnmappedAction.ERROR, probably due to a tolerance issue - ask Bob -regrid = ESMF.Regrid(srcfield=srcfield, dstfield=dstfield, regrid_method=ESMF.RegridMethod.BILINEAR, - unmapped_action=ESMF.UnmappedAction.IGNORE) +regrid = esmpy.Regrid(srcfield=srcfield, dstfield=dstfield, regrid_method=esmpy.RegridMethod.BILINEAR, + unmapped_action=esmpy.UnmappedAction.IGNORE) # do the regridding from source to destination field dstfield = regrid(srcfield, dstfield) @@ -61,12 +61,12 @@ meanrelerr = relerr / num_nodes # handle the parallel case -if ESMF.pet_count() > 1: +if esmpy.pet_count() > 1: relerr = helpers.reduce_val(relerr, op=constants.Reduce.SUM) num_nodes = helpers.reduce_val(num_nodes, op=constants.Reduce.SUM) # output the results from one processor only -if ESMF.local_pet() == 0: +if esmpy.local_pet() == 0: meanrelerr = relerr / num_nodes print ("ESMPy Grid Mesh Regridding Example") print (" interpolation mean relative error = {0}".format(meanrelerr)) diff --git a/src/addon/ESMPy/examples/mpi_spawn_regrid.py b/src/addon/ESMPy/examples/mpi_spawn_regrid.py index 9541f15ccd..ea838a121f 100644 --- a/src/addon/ESMPy/examples/mpi_spawn_regrid.py +++ b/src/addon/ESMPy/examples/mpi_spawn_regrid.py @@ -11,7 +11,7 @@ # DD = os.path.join(os.getcwd(), "examples/data") # if not os.path.isdir(DD): # os.makedirs(DD) -# from ESMF.util.cache_data import cache_data_file +# from esmpy.util.cache_data import cache_data_file # cache_data_file(os.path.join(DD, "ll1deg_grid.nc")) # cache_data_file(os.path.join(DD, "mpas_uniform_10242_dual_counterclockwise.nc")) @@ -21,7 +21,7 @@ def regrid(): try: - import ESMF + import esmpy except: raise ImportError("ESMF is not available on this machine") @@ -29,45 +29,45 @@ def regrid(): grid2 = "examples/data/mpas_uniform_10242_dual_counterclockwise.nc" # Create a uniform global latlon grid from a SCRIP formatted file - grid = ESMF.Grid(filename=grid1, filetype=ESMF.FileFormat.SCRIP) + grid = esmpy.Grid(filename=grid1, filetype=esmpy.FileFormat.SCRIP) # NOTE: corners are needed for conservative regridding - # grid = ESMF.Grid(filename=grid1, filetype=ESMF.FileFormat.SCRIP, + # grid = esmpy.Grid(filename=grid1, filetype=esmpy.FileFormat.SCRIP, # add_corner_stagger=True) # create a field on the center stagger locations of the source grid - srcfield = ESMF.Field(grid, name='srcfield', - staggerloc=ESMF.StaggerLoc.CENTER) + srcfield = esmpy.Field(grid, name='srcfield', + staggerloc=esmpy.StaggerLoc.CENTER) # create an ESMF formatted unstructured mesh with clockwise cells removed - mesh = ESMF.Mesh(filename=grid2, filetype=ESMF.FileFormat.ESMFMESH) + mesh = esmpy.Mesh(filename=grid2, filetype=esmpy.FileFormat.ESMFMESH) # create a field on the nodes of the destination mesh - dstfield = ESMF.Field(mesh, name='dstfield', meshloc=ESMF.MeshLoc.NODE) - xctfield = ESMF.Field(mesh, name='xctfield', meshloc=ESMF.MeshLoc.NODE) + dstfield = esmpy.Field(mesh, name='dstfield', meshloc=esmpy.MeshLoc.NODE) + xctfield = esmpy.Field(mesh, name='xctfield', meshloc=esmpy.MeshLoc.NODE) # NOTE: Field must be built on elements of Mesh for conservative regridding - # dstfield = ESMF.Field(mesh, name='dstfield', meshloc=ESMF.MeshLoc.ELEMENT) - # xctfield = ESMF.Field(mesh, name='xctfield', meshloc=ESMF.MeshLoc.ELEMENT) + # dstfield = esmpy.Field(mesh, name='dstfield', meshloc=esmpy.MeshLoc.ELEMENT) + # xctfield = esmpy.Field(mesh, name='xctfield', meshloc=esmpy.MeshLoc.ELEMENT) # initialize the fields [lon, lat] = [0, 1] deg2rad = 3.14159 / 180 - gridXCoord = srcfield.grid.get_coords(lon, ESMF.StaggerLoc.CENTER) - gridYCoord = srcfield.grid.get_coords(lat, ESMF.StaggerLoc.CENTER) + gridXCoord = srcfield.grid.get_coords(lon, esmpy.StaggerLoc.CENTER) + gridYCoord = srcfield.grid.get_coords(lat, esmpy.StaggerLoc.CENTER) srcfield.data[...] = 10.0 + (gridXCoord * deg2rad) ** 2 + ( gridYCoord * deg2rad) ** 2 - gridXCoord = xctfield.grid.get_coords(lon, ESMF.StaggerLoc.CENTER) - gridYCoord = xctfield.grid.get_coords(lat, ESMF.StaggerLoc.CENTER) + gridXCoord = xctfield.grid.get_coords(lon, esmpy.StaggerLoc.CENTER) + gridYCoord = xctfield.grid.get_coords(lat, esmpy.StaggerLoc.CENTER) xctfield.data[...] = 10.0 + (gridXCoord * deg2rad) ** 2 + ( gridYCoord * deg2rad) ** 2 dstfield.data[...] = 1e20 # create an object to regrid data from the source to the destination field - regrid = ESMF.Regrid(srcfield, dstfield, - regrid_method=ESMF.RegridMethod.BILINEAR, - unmapped_action=ESMF.UnmappedAction.ERROR) + regrid = esmpy.Regrid(srcfield, dstfield, + regrid_method=esmpy.RegridMethod.BILINEAR, + unmapped_action=esmpy.UnmappedAction.ERROR) # do the regridding from source to destination field dstfield = regrid(srcfield, dstfield) diff --git a/src/addon/ESMPy/examples/notebooks/AdvancedRegridding.ipynb b/src/addon/ESMPy/examples/notebooks/AdvancedRegridding.ipynb index 3a827a6134..dad0644086 100644 --- a/src/addon/ESMPy/examples/notebooks/AdvancedRegridding.ipynb +++ b/src/addon/ESMPy/examples/notebooks/AdvancedRegridding.ipynb @@ -22,11 +22,11 @@ "metadata": {}, "outputs": [], "source": [ - "import ESMF\n", + "import esmpy\n", "import numpy as np\n", "\n", "# pull in some extra ESMF symbols for the sake of brevity\n", - "from ESMF import Grid, Mesh, LocStream, Field, Regrid, RegridFromFile" + "from esmpy import Grid, Mesh, LocStream, Field, Regrid, RegridFromFile" ] }, { @@ -51,7 +51,7 @@ "DD = os.path.join(os.getcwd(), \"ESMPy-data\")\n", "if not os.path.isdir(DD):\n", " os.makedirs(DD)\n", - "from ESMF.util.cache_data import cache_data_file\n", + "from esmpy.util.cache_data import cache_data_file\n", "cache_data_file(os.path.join(DD, \"ll1deg_grid.nc\"))\n", "cache_data_file(os.path.join(DD, \"tas_day_CanCM4_decadal2000_r2i1p1_20010101-20101231.nc\"))" ] @@ -67,7 +67,7 @@ "gridfile = os.path.join(DD, \"ll1deg_grid.nc\")\n", "\n", "# Create a grid from a SCRIP formatted file\n", - "grid = Grid(filename=gridfile, filetype=ESMF.FileFormat.SCRIP, add_corner_stagger=True)" + "grid = Grid(filename=gridfile, filetype=esmpy.FileFormat.SCRIP, add_corner_stagger=True)" ] }, { @@ -84,11 +84,11 @@ "outputs": [], "source": [ "# Environment Canada CMIP5 climate data\n", - "grid_CanCM = ESMF.Grid(filename=os.path.join(DD, \"tas_day_CanCM4_decadal2000_r2i1p1_20010101-20101231.nc\"),\n", - " filetype=ESMF.FileFormat.GRIDSPEC, add_corner_stagger=True, add_mask=True, varname=\"tas\")\n", + "grid_CanCM = esmpy.Grid(filename=os.path.join(DD, \"tas_day_CanCM4_decadal2000_r2i1p1_20010101-20101231.nc\"),\n", + " filetype=esmpy.FileFormat.GRIDSPEC, add_corner_stagger=True, add_mask=True, varname=\"tas\")\n", "\n", "timeslice = 12\n", - "field = ESMF.Field(grid_CanCM, ndbounds=[timeslice])\n", + "field = esmpy.Field(grid_CanCM, ndbounds=[timeslice])\n", "\n", "field.read(filename=os.path.join(DD, \"tas_day_CanCM4_decadal2000_r2i1p1_20010101-20101231.nc\"), \n", " variable=\"tas\", timeslice=timeslice)" @@ -101,7 +101,7 @@ "outputs": [], "source": [ "# create a target field on latlon 1 degree grid, with space for time dimension\n", - "target_field = ESMF.Field(grid, ndbounds=[timeslice])" + "target_field = esmpy.Field(grid, ndbounds=[timeslice])" ] }, { @@ -125,8 +125,8 @@ "outputs": [], "source": [ "# generate weights, note that masks read from file generally use 0 to represent masked values and 1 for non masked\n", - "regrid = ESMF.Regrid(field, target_field, regrid_method=ESMF.RegridMethod.CONSERVE, \n", - " unmapped_action=ESMF.UnmappedAction.IGNORE, dst_mask_values=[0])" + "regrid = esmpy.Regrid(field, target_field, regrid_method=esmpy.RegridMethod.CONSERVE, \n", + " unmapped_action=esmpy.UnmappedAction.IGNORE, dst_mask_values=[0])" ] }, { @@ -136,8 +136,8 @@ "outputs": [], "source": [ "# also generation a reverse Regrid to bring the data back to the original grid (for error measurement)\n", - "regrid_T= ESMF.Regrid(target_field, field, regrid_method=ESMF.RegridMethod.CONSERVE, \n", - " unmapped_action=ESMF.UnmappedAction.IGNORE, src_mask_values=[0])" + "regrid_T= esmpy.Regrid(target_field, field, regrid_method=esmpy.RegridMethod.CONSERVE, \n", + " unmapped_action=esmpy.UnmappedAction.IGNORE, src_mask_values=[0])" ] }, { @@ -154,8 +154,8 @@ "outputs": [], "source": [ "# Apply the weights in the Regrid/Regrid_T to regrid data from field to target_field and then back to field\n", - "target_field = regrid(field, target_field, zero_region=ESMF.Region.SELECT)\n", - "solution_CanCM = regrid_T(target_field, field, zero_region=ESMF.Region.SELECT)" + "target_field = regrid(field, target_field, zero_region=esmpy.Region.SELECT)\n", + "solution_CanCM = regrid_T(target_field, field, zero_region=esmpy.Region.SELECT)" ] }, { @@ -248,8 +248,8 @@ "!{cmd}\n", "\n", "# generate weights and output them to a file\n", - "rf1 = ESMF.Regrid(field, target_field, regrid_method=ESMF.RegridMethod.CONSERVE, \n", - " unmapped_action=ESMF.UnmappedAction.IGNORE, filename=weightfile)" + "rf1 = esmpy.Regrid(field, target_field, regrid_method=esmpy.RegridMethod.CONSERVE, \n", + " unmapped_action=esmpy.UnmappedAction.IGNORE, filename=weightfile)" ] }, { @@ -292,8 +292,8 @@ "source": [ "# generate weights and output them to a file \n", "routehandlefile = \"CanCMtoLatLon1deg.rh\"\n", - "rf2 = ESMF.Regrid(field, target_field, regrid_method=ESMF.RegridMethod.CONSERVE, \n", - " unmapped_action=ESMF.UnmappedAction.IGNORE, rh_filename=routehandlefile)" + "rf2 = esmpy.Regrid(field, target_field, regrid_method=esmpy.RegridMethod.CONSERVE, \n", + " unmapped_action=esmpy.UnmappedAction.IGNORE, rh_filename=routehandlefile)" ] }, { @@ -302,8 +302,8 @@ "metadata": {}, "outputs": [], "source": [ - "rf1 = ESMF.RegridFromFile(field, target_field, filename=weightfile)\n", - "rf2 = ESMF.RegridFromFile(field, target_field, rh_filename=routehandlefile)" + "rf1 = esmpy.RegridFromFile(field, target_field, filename=weightfile)\n", + "rf2 = esmpy.RegridFromFile(field, target_field, rh_filename=routehandlefile)" ] }, { diff --git a/src/addon/ESMPy/examples/notebooks/BasicRegridding.ipynb b/src/addon/ESMPy/examples/notebooks/BasicRegridding.ipynb index 1786e289ba..24836d9864 100644 --- a/src/addon/ESMPy/examples/notebooks/BasicRegridding.ipynb +++ b/src/addon/ESMPy/examples/notebooks/BasicRegridding.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "import ESMF\n", + "import esmpy\n", "import numpy as np" ] }, @@ -55,7 +55,7 @@ "DD = os.path.join(os.getcwd(), \"ESMPy-data\")\n", "if not os.path.isdir(DD):\n", " os.makedirs(DD)\n", - "from ESMF.util.cache_data import cache_data_file\n", + "from esmpy.util.cache_data import cache_data_file\n", "cache_data_file(os.path.join(DD, \"ll1deg_grid.nc\"))\n", "cache_data_file(os.path.join(DD, \"ll2.5deg_grid.nc\"))" ] @@ -73,10 +73,10 @@ "metadata": {}, "outputs": [], "source": [ - "srcgrid = ESMF.Grid(filename=os.path.join(DD, \"ll1deg_grid.nc\"),\n", - " filetype=ESMF.FileFormat.SCRIP, add_corner_stagger=True)\n", - "dstgrid = ESMF.Grid(filename=os.path.join(DD, \"ll2.5deg_grid.nc\"), \n", - " filetype=ESMF.FileFormat.SCRIP, add_corner_stagger=True)" + "srcgrid = esmpy.Grid(filename=os.path.join(DD, \"ll1deg_grid.nc\"),\n", + " filetype=esmpy.FileFormat.SCRIP, add_corner_stagger=True)\n", + "dstgrid = esmpy.Grid(filename=os.path.join(DD, \"ll2.5deg_grid.nc\"), \n", + " filetype=esmpy.FileFormat.SCRIP, add_corner_stagger=True)" ] }, { @@ -92,8 +92,8 @@ "metadata": {}, "outputs": [], "source": [ - "srcfield = ESMF.Field(srcgrid)\n", - "dstfield = ESMF.Field(dstgrid)" + "srcfield = esmpy.Field(srcgrid)\n", + "dstfield = esmpy.Field(dstgrid)" ] }, { @@ -125,7 +125,7 @@ "metadata": {}, "outputs": [], "source": [ - "regridS2D = ESMF.Regrid(srcfield, dstfield)" + "regridS2D = esmpy.Regrid(srcfield, dstfield)" ] }, { diff --git a/src/addon/ESMPy/examples/notebooks/GridCellArea.ipynb b/src/addon/ESMPy/examples/notebooks/GridCellArea.ipynb index cb2363b691..529a3b28df 100644 --- a/src/addon/ESMPy/examples/notebooks/GridCellArea.ipynb +++ b/src/addon/ESMPy/examples/notebooks/GridCellArea.ipynb @@ -25,8 +25,8 @@ ], "source": [ "import numpy as np\n", - "import ESMF\n", - "ESMF.__version__" + "import esmpy\n", + "esmpy.__version__" ] }, { @@ -84,9 +84,9 @@ "metadata": {}, "outputs": [], "source": [ - "sourcegrid = ESMF.Grid(np.array([20,20]), \n", - " staggerloc = ESMF.StaggerLoc.CENTER,\n", - " coord_sys = ESMF.CoordSys.SPH_DEG)\n", + "sourcegrid = esmpy.Grid(np.array([20,20]), \n", + " staggerloc = esmpy.StaggerLoc.CENTER,\n", + " coord_sys = esmpy.CoordSys.SPH_DEG)\n", "\n", "source_lon = sourcegrid.get_coords(0)\n", "source_lat = sourcegrid.get_coords(1)\n", @@ -106,12 +106,12 @@ "metadata": {}, "outputs": [], "source": [ - "sourcegrid.add_coords(staggerloc = ESMF.StaggerLoc.CORNER_VCENTER)\n", + "sourcegrid.add_coords(staggerloc = esmpy.StaggerLoc.CORNER_VCENTER)\n", "\n", "source_lat_b = sourcegrid.get_coords(coord_dim = 1, \n", - " staggerloc = ESMF.StaggerLoc.CORNER)\n", + " staggerloc = esmpy.StaggerLoc.CORNER)\n", "source_lon_b = sourcegrid.get_coords(coord_dim = 0, \n", - " staggerloc = ESMF.StaggerLoc.CORNER)\n", + " staggerloc = esmpy.StaggerLoc.CORNER)\n", "\n", "source_lon_b[...], source_lat_b[...] = np.meshgrid(lon_b, lat_b)" ] @@ -221,7 +221,7 @@ } ], "source": [ - "sourcegridareafield = ESMF.Field(sourcegrid)\n", + "sourcegridareafield = esmpy.Field(sourcegrid)\n", "sourcegridareafield.get_area()\n", "sourcegridareafield.data" ] diff --git a/src/addon/ESMPy/examples/notebooks/GridMeshLocStreamField.ipynb b/src/addon/ESMPy/examples/notebooks/GridMeshLocStreamField.ipynb index 26dfe8c341..ed244bfe6e 100644 --- a/src/addon/ESMPy/examples/notebooks/GridMeshLocStreamField.ipynb +++ b/src/addon/ESMPy/examples/notebooks/GridMeshLocStreamField.ipynb @@ -24,7 +24,7 @@ "metadata": {}, "outputs": [], "source": [ - "import ESMF\n", + "import esmpy\n", "import numpy as np" ] }, @@ -50,7 +50,7 @@ "DD = os.path.join(os.getcwd(), \"ESMPy-data\")\n", "if not os.path.isdir(DD):\n", " os.makedirs(DD)\n", - "from ESMF.util.cache_data import cache_data_file\n", + "from esmpy.util.cache_data import cache_data_file\n", "cache_data_file(os.path.join(DD, \"ll1deg_grid.nc\"))\n", "cache_data_file(os.path.join(DD, \"ne30np4_esmf.nc\"))\n", "cache_data_file(os.path.join(DD, \"so_Omon_GISS-E2.nc\"))" @@ -77,8 +77,8 @@ } ], "source": [ - "ESMF.Manager(debug=True)\n", - "print(ESMF.local_pet(), ESMF.pet_count())" + "esmpy.Manager(debug=True)\n", + "print(esmpy.local_pet(), esmpy.pet_count())" ] }, { @@ -105,8 +105,8 @@ "outputs": [], "source": [ "gridfile = \"ll1deg_grid.nc\"\n", - "grid = ESMF.Grid(filename=os.path.join(DD, gridfile),\n", - " filetype=ESMF.FileFormat.SCRIP, add_corner_stagger=True)" + "grid = esmpy.Grid(filename=os.path.join(DD, gridfile),\n", + " filetype=esmpy.FileFormat.SCRIP, add_corner_stagger=True)" ] }, { @@ -126,7 +126,7 @@ "# ESMPy follows ESMF/Fortran/Mathematics convention for indices in order lon, lat\n", "lon = 0\n", "lat = 1\n", - "print (grid.coords[ESMF.StaggerLoc.CENTER][lon].shape)" + "print (grid.coords[esmpy.StaggerLoc.CENTER][lon].shape)" ] }, { @@ -160,9 +160,9 @@ ], "source": [ "# Coordinates are stored as numpy arrays, basic slicing capabilites are available\n", - "print (type(grid.coords[ESMF.StaggerLoc.CENTER][lon]))\n", + "print (type(grid.coords[esmpy.StaggerLoc.CENTER][lon]))\n", "\n", - "print (grid.coords[ESMF.StaggerLoc.CENTER][lon][2:4])\n" + "print (grid.coords[esmpy.StaggerLoc.CENTER][lon][2:4])\n" ] }, { @@ -219,11 +219,11 @@ "outputs": [], "source": [ "max_index = np.array([360, 179])\n", - "grid = ESMF.Grid(max_index, staggerloc=[ESMF.StaggerLoc.CENTER, ESMF.StaggerLoc.EDGE1, ESMF.StaggerLoc.EDGE2, ESMF.StaggerLoc.CORNER], \n", - " coord_sys=ESMF.CoordSys.SPH_DEG, \n", - " coord_typekind=ESMF.TypeKind.R4, \n", + "grid = esmpy.Grid(max_index, staggerloc=[esmpy.StaggerLoc.CENTER, esmpy.StaggerLoc.EDGE1, esmpy.StaggerLoc.EDGE2, esmpy.StaggerLoc.CORNER], \n", + " coord_sys=esmpy.CoordSys.SPH_DEG, \n", + " coord_typekind=esmpy.TypeKind.R4, \n", " num_peri_dims = 1,\n", - " pole_kind=[ESMF.PoleKind.MONOPOLE, ESMF.PoleKind.BIPOLE])\n", + " pole_kind=[esmpy.PoleKind.MONOPOLE, esmpy.PoleKind.BIPOLE])\n", "\n", "gridLonCenter = grid.get_coords(0)\n", "gridLatCenter = grid.get_coords(1)\n", @@ -291,7 +291,7 @@ "source": [ "# cubed-sphere grid is represented as an unstructured Mesh\n", "meshfile = \"ne30np4_esmf.nc\"\n", - "mesh = ESMF.Mesh(filename=os.path.join(DD, meshfile), filetype=ESMF.FileFormat.ESMFMESH)\n", + "mesh = esmpy.Mesh(filename=os.path.join(DD, meshfile), filetype=esmpy.FileFormat.ESMFMESH)\n", "# print(mesh)" ] }, @@ -358,7 +358,7 @@ "metadata": {}, "outputs": [], "source": [ - "meshinmem = ESMF.Mesh(parametric_dim=2, spatial_dim=2)\n", + "meshinmem = esmpy.Mesh(parametric_dim=2, spatial_dim=2)\n", "\n", "num_node = 12\n", "num_elem = 5\n", @@ -369,8 +369,8 @@ "nodeOwner = np.zeros(num_node)\n", "\n", "elemId = np.array([1,2,3,4,5])\n", - "elemType=np.array([ESMF.MeshElemType.QUAD,ESMF.MeshElemType.TRI,\n", - " ESMF.MeshElemType.TRI, 5, 6])\n", + "elemType=np.array([esmpy.MeshElemType.QUAD,esmpy.MeshElemType.TRI,\n", + " esmpy.MeshElemType.TRI, 5, 6])\n", " \n", "elemConn=np.array([0,1,4,3, 1,2,4, 2,5,4, 3,4,8,7,6, 4,5,11,10,9,8])\n", "\n", @@ -443,7 +443,7 @@ ], "source": [ "# locstreams can currently only be created in memory\n", - "locstream = ESMF.LocStream(16)\n", + "locstream = esmpy.LocStream(16)\n", "\n", "locstream[\"ESMF:X\"] = [0.0, 1.5, 2.5, 4.0, 0.0, 1.5, 2.5, 4.0, 0.0, 1.5, 2.5, 4.0, 0.0, 1.5, 2.5, 4.0]\n", "locstream[\"ESMF:Y\"] = [0.0, 0.0, 0.0, 0.0, 1.5, 1.5, 1.5, 1.5, 2.5, 2.5, 2.5, 2.5, 4.0, 4.0, 4.0, 4.0]\n", @@ -504,7 +504,7 @@ } ], "source": [ - "locstream = ESMF.LocStream(10, coord_sys=ESMF.CoordSys.SPH_RAD)\n", + "locstream = esmpy.LocStream(10, coord_sys=esmpy.CoordSys.SPH_RAD)\n", "\n", "locstream[\"ESMF:Lon\"] = np.linspace(0, 2*np.pi, 10).tolist()\n", "locstream[\"ESMF:Lat\"] = np.linspace(np.pi/-2.0, np.pi/2.0, 10).tolist()\n", @@ -596,9 +596,9 @@ } ], "source": [ - "field_grid = ESMF.Field(grid, name=\"field_grid\", typekind=ESMF.TypeKind.I8, staggerloc=ESMF.StaggerLoc.CORNER)\n", - "field_mesh = ESMF.Field(mesh, name=\"field_mesh\", typekind=ESMF.TypeKind.R4, meshloc=ESMF.MeshLoc.ELEMENT)\n", - "field_locs = ESMF.Field(locstream, name=\"field_locs\", typekind=ESMF.TypeKind.R4)\n", + "field_grid = esmpy.Field(grid, name=\"field_grid\", typekind=esmpy.TypeKind.I8, staggerloc=esmpy.StaggerLoc.CORNER)\n", + "field_mesh = esmpy.Field(mesh, name=\"field_mesh\", typekind=esmpy.TypeKind.R4, meshloc=esmpy.MeshLoc.ELEMENT)\n", + "field_locs = esmpy.Field(locstream, name=\"field_locs\", typekind=esmpy.TypeKind.R4)\n", "print(field_locs)" ] }, @@ -616,11 +616,11 @@ "outputs": [], "source": [ "# NASA-GISS sea water salinity data with 33 vertical layers and 2 timesteps\n", - "grid_so = ESMF.Grid(filename=os.path.join(DD, \"so_Omon_GISS-E2.nc\"),\n", - " filetype=ESMF.FileFormat.GRIDSPEC, add_corner_stagger=True, add_mask=True, varname=\"so\")\n", + "grid_so = esmpy.Grid(filename=os.path.join(DD, \"so_Omon_GISS-E2.nc\"),\n", + " filetype=esmpy.FileFormat.GRIDSPEC, add_corner_stagger=True, add_mask=True, varname=\"so\")\n", "\n", "timeslice = 12\n", - "field_so = ESMF.Field(grid_so, ndbounds=[33, 2])\n", + "field_so = esmpy.Field(grid_so, ndbounds=[33, 2])\n", "\n", "field_so.read(filename=os.path.join(DD, \"so_Omon_GISS-E2.nc\"), \n", " variable=\"so\", timeslice=2)" diff --git a/src/addon/ESMPy/examples/notebooks/Periodic.ipynb b/src/addon/ESMPy/examples/notebooks/Periodic.ipynb index d25ea1f429..05c74f2ed6 100644 --- a/src/addon/ESMPy/examples/notebooks/Periodic.ipynb +++ b/src/addon/ESMPy/examples/notebooks/Periodic.ipynb @@ -16,7 +16,7 @@ "%matplotlib inline\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", - "import ESMF" + "import esmpy" ] }, { @@ -118,9 +118,9 @@ "metadata": {}, "outputs": [], "source": [ - "sourcegrid = ESMF.Grid(np.array([lon_in.size, lat_in.size]), \n", - " staggerloc = [ESMF.StaggerLoc.CENTER],\n", - " coord_sys = ESMF.CoordSys.SPH_DEG,\n", + "sourcegrid = esmpy.Grid(np.array([lon_in.size, lat_in.size]), \n", + " staggerloc = [esmpy.StaggerLoc.CENTER],\n", + " coord_sys = esmpy.CoordSys.SPH_DEG,\n", " num_peri_dims = 1)\n", "\n", "source_lon = sourcegrid.get_coords(0)\n", @@ -155,9 +155,9 @@ "metadata": {}, "outputs": [], "source": [ - "destgrid = ESMF.Grid(np.array([lon_out.size, lat_out.size]), \n", - " staggerloc = [ESMF.StaggerLoc.CENTER],\n", - " coord_sys = ESMF.CoordSys.SPH_DEG,\n", + "destgrid = esmpy.Grid(np.array([lon_out.size, lat_out.size]), \n", + " staggerloc = [esmpy.StaggerLoc.CENTER],\n", + " coord_sys = esmpy.CoordSys.SPH_DEG,\n", " num_peri_dims = 1)\n", "\n", "\n", @@ -173,8 +173,8 @@ "metadata": {}, "outputs": [], "source": [ - "sourcefield = ESMF.Field(sourcegrid)\n", - "destfield = ESMF.Field(destgrid)" + "sourcefield = esmpy.Field(sourcegrid)\n", + "destfield = esmpy.Field(destgrid)" ] }, { @@ -183,9 +183,9 @@ "metadata": {}, "outputs": [], "source": [ - "regrid_bi = ESMF.Regrid(sourcefield, destfield, \n", - " regrid_method = ESMF.RegridMethod.BILINEAR, \n", - " unmapped_action = ESMF.UnmappedAction.ERROR)" + "regrid_bi = esmpy.Regrid(sourcefield, destfield, \n", + " regrid_method = esmpy.RegridMethod.BILINEAR, \n", + " unmapped_action = esmpy.UnmappedAction.ERROR)" ] }, { diff --git a/src/addon/ESMPy/examples/notebooks/ugrid_latlon_regrid.ipynb b/src/addon/ESMPy/examples/notebooks/ugrid_latlon_regrid.ipynb index 5286787a27..88feeb6d8c 100644 --- a/src/addon/ESMPy/examples/notebooks/ugrid_latlon_regrid.ipynb +++ b/src/addon/ESMPy/examples/notebooks/ugrid_latlon_regrid.ipynb @@ -31,7 +31,7 @@ "metadata": {}, "outputs": [], "source": [ - "import ESMF\n", + "import esmpy\n", "import numpy" ] }, @@ -60,7 +60,7 @@ "DD = os.path.join(os.getcwd(), \"ESMPy-data\")\n", "if not os.path.isdir(DD):\n", " os.makedirs(DD)\n", - "from ESMF.util.cache_data import cache_data_file\n", + "from esmpy.util.cache_data import cache_data_file\n", "cache_data_file(os.path.join(DD, \"ll1deg_grid.nc\"))\n", "# cache_data_file(os.path.join(DD, \"aggregAtlanticESTOFS.nc\"))\n", "os.system(\"wget https://www.dropbox.com/s/ke5mdukbjwyqaru/aggregAtlanticESTOFS.nc\")\n", @@ -82,7 +82,7 @@ "outputs": [], "source": [ "gridfile = \"ESMPy-data/ll1deg_grid.nc\"\n", - "grid = ESMF.Grid(filename=gridfile, filetype=ESMF.FileFormat.SCRIP, is_sphere=True)" + "grid = esmpy.Grid(filename=gridfile, filetype=esmpy.FileFormat.SCRIP, is_sphere=True)" ] }, { @@ -99,7 +99,7 @@ "outputs": [], "source": [ "meshfile = \"ESMPy-data/aggregAtlanticESTOFS.nc\"\n", - "mesh = ESMF.Mesh(filename=meshfile, filetype=ESMF.FileFormat.UGRID, meshname='adcirc_mesh')" + "mesh = esmpy.Mesh(filename=meshfile, filetype=esmpy.FileFormat.UGRID, meshname='adcirc_mesh')" ] }, { @@ -115,20 +115,20 @@ "metadata": {}, "outputs": [], "source": [ - "srcfield = ESMF.Field(mesh, name='srcfield', meshloc=ESMF.MeshLoc.NODE)\n", + "srcfield = esmpy.Field(mesh, name='srcfield', meshloc=esmpy.MeshLoc.NODE)\n", "\n", - "dstfield = ESMF.Field(grid, name='dstfield', staggerloc=ESMF.StaggerLoc.CENTER)\n", - "xctfield = ESMF.Field(grid, name='xctfield', staggerloc=ESMF.StaggerLoc.CENTER)\n", + "dstfield = esmpy.Field(grid, name='dstfield', staggerloc=esmpy.StaggerLoc.CENTER)\n", + "xctfield = esmpy.Field(grid, name='xctfield', staggerloc=esmpy.StaggerLoc.CENTER)\n", "\n", "[lon, lat] = [0, 1]\n", "\n", - "srcgridXCoord = srcfield.grid.get_coords(lon, meshloc=ESMF.MeshLoc.NODE)\n", - "srcgridYCoord = srcfield.grid.get_coords(lat, meshloc=ESMF.MeshLoc.NODE)\n", + "srcgridXCoord = srcfield.grid.get_coords(lon, meshloc=esmpy.MeshLoc.NODE)\n", + "srcgridYCoord = srcfield.grid.get_coords(lat, meshloc=esmpy.MeshLoc.NODE)\n", "srcfield.data[...] = 2.0 + numpy.cos(numpy.radians(srcgridYCoord)[...])**2 * \\\n", " numpy.cos(2.0*numpy.radians(srcgridXCoord)[...])\n", "\n", - "dstgridXCoord = xctfield.grid.get_coords(lon, ESMF.StaggerLoc.CENTER)\n", - "dstgridYCoord = xctfield.grid.get_coords(lat, ESMF.StaggerLoc.CENTER)\n", + "dstgridXCoord = xctfield.grid.get_coords(lon, esmpy.StaggerLoc.CENTER)\n", + "dstgridYCoord = xctfield.grid.get_coords(lat, esmpy.StaggerLoc.CENTER)\n", "xctfield.data[...] = 2.0 + numpy.cos(numpy.radians(dstgridYCoord)[...])**2 * \\\n", " numpy.cos(2.0*numpy.radians(dstgridXCoord)[...])\n", "\n", @@ -149,11 +149,11 @@ "metadata": {}, "outputs": [], "source": [ - "regrid = ESMF.Regrid(srcfield, dstfield,\n", - " regrid_method=ESMF.RegridMethod.BILINEAR,\n", - " unmapped_action=ESMF.UnmappedAction.IGNORE)\n", + "regrid = esmpy.Regrid(srcfield, dstfield,\n", + " regrid_method=esmpy.RegridMethod.BILINEAR,\n", + " unmapped_action=esmpy.UnmappedAction.IGNORE)\n", "\n", - "dstfield = regrid(srcfield, dstfield, zero_region=ESMF.Region.SELECT)" + "dstfield = regrid(srcfield, dstfield, zero_region=esmpy.Region.SELECT)" ] }, { @@ -258,7 +258,7 @@ "source": [ "dstfield.data[...] = uninitval\n", "\n", - "dstfield = regrid(srcfield, dstfield, zero_region=ESMF.Region.SELECT)" + "dstfield = regrid(srcfield, dstfield, zero_region=esmpy.Region.SELECT)" ] }, { diff --git a/src/addon/ESMPy/examples/notebooks/ungridded_dimension_regrid.ipynb b/src/addon/ESMPy/examples/notebooks/ungridded_dimension_regrid.ipynb index b31881f6b4..c5cf86c2a1 100644 --- a/src/addon/ESMPy/examples/notebooks/ungridded_dimension_regrid.ipynb +++ b/src/addon/ESMPy/examples/notebooks/ungridded_dimension_regrid.ipynb @@ -31,7 +31,7 @@ "metadata": {}, "outputs": [], "source": [ - "import ESMF\n", + "import esmpy\n", "import numpy" ] }, @@ -60,7 +60,7 @@ "DD = os.path.join(os.getcwd(), \"ESMPy-data\")\n", "if not os.path.isdir(DD):\n", " os.makedirs(DD)\n", - "from ESMF.util.cache_data import cache_data_file\n", + "from esmpy.util.cache_data import cache_data_file\n", "cache_data_file(os.path.join(DD, \"ll2.5deg_grid.nc\"))\n", "cache_data_file(os.path.join(DD, \"T42_grid.nc\"))\n", "print('Done.')" @@ -96,11 +96,11 @@ "metadata": {}, "outputs": [], "source": [ - "srcgrid = ESMF.Grid(filename=\"ESMPy-data/ll2.5deg_grid.nc\", \n", - " filetype=ESMF.FileFormat.SCRIP,\n", + "srcgrid = esmpy.Grid(filename=\"ESMPy-data/ll2.5deg_grid.nc\", \n", + " filetype=esmpy.FileFormat.SCRIP,\n", " add_corner_stagger=True)\n", - "dstgrid = ESMF.Grid(filename=\"ESMPy-data/T42_grid.nc\", \n", - " filetype=ESMF.FileFormat.SCRIP,\n", + "dstgrid = esmpy.Grid(filename=\"ESMPy-data/T42_grid.nc\", \n", + " filetype=esmpy.FileFormat.SCRIP,\n", " add_corner_stagger=True)" ] }, @@ -117,14 +117,14 @@ "metadata": {}, "outputs": [], "source": [ - "srcfield = ESMF.Field(srcgrid, name='srcfield',\n", - " staggerloc=ESMF.StaggerLoc.CENTER,\n", + "srcfield = esmpy.Field(srcgrid, name='srcfield',\n", + " staggerloc=esmpy.StaggerLoc.CENTER,\n", " ndbounds=[levels, time])\n", - "dstfield = ESMF.Field(dstgrid, name='dstfield',\n", - " staggerloc=ESMF.StaggerLoc.CENTER,\n", + "dstfield = esmpy.Field(dstgrid, name='dstfield',\n", + " staggerloc=esmpy.StaggerLoc.CENTER,\n", " ndbounds=[levels, time])\n", - "xctfield = ESMF.Field(dstgrid, name='xctfield',\n", - " staggerloc=ESMF.StaggerLoc.CENTER,\n", + "xctfield = esmpy.Field(dstgrid, name='xctfield',\n", + " staggerloc=esmpy.StaggerLoc.CENTER,\n", " ndbounds=[levels, time])" ] }, @@ -142,8 +142,8 @@ "outputs": [], "source": [ "[lon,lat] = [0, 1]\n", - "gridXCoord = srcfield.grid.get_coords(lon, ESMF.StaggerLoc.CENTER)\n", - "gridYCoord = srcfield.grid.get_coords(lat, ESMF.StaggerLoc.CENTER)\n", + "gridXCoord = srcfield.grid.get_coords(lon, esmpy.StaggerLoc.CENTER)\n", + "gridYCoord = srcfield.grid.get_coords(lat, esmpy.StaggerLoc.CENTER)\n", "\n", "deg2rad = 3.14159/180\n", "\n", @@ -169,8 +169,8 @@ "metadata": {}, "outputs": [], "source": [ - "gridXCoord = xctfield.grid.get_coords(lon, ESMF.StaggerLoc.CENTER)\n", - "gridYCoord = xctfield.grid.get_coords(lat, ESMF.StaggerLoc.CENTER)\n", + "gridXCoord = xctfield.grid.get_coords(lon, esmpy.StaggerLoc.CENTER)\n", + "gridYCoord = xctfield.grid.get_coords(lat, esmpy.StaggerLoc.CENTER)\n", "\n", "for timestep in range(time):\n", " for level in range(levels):\n", @@ -196,9 +196,9 @@ "metadata": {}, "outputs": [], "source": [ - "regrid = ESMF.Regrid(srcfield, dstfield,\n", - " regrid_method=ESMF.RegridMethod.CONSERVE,\n", - " unmapped_action=ESMF.UnmappedAction.ERROR)" + "regrid = esmpy.Regrid(srcfield, dstfield,\n", + " regrid_method=esmpy.RegridMethod.CONSERVE,\n", + " unmapped_action=esmpy.UnmappedAction.ERROR)" ] }, { diff --git a/src/addon/ESMPy/examples/read_write_weight_file.py b/src/addon/ESMPy/examples/read_write_weight_file.py index 4c779e72ec..836a2267ba 100644 --- a/src/addon/ESMPy/examples/read_write_weight_file.py +++ b/src/addon/ESMPy/examples/read_write_weight_file.py @@ -6,18 +6,18 @@ # DD = os.path.join(os.getcwd(), "examples/data") # if not os.path.isdir(DD): # os.makedirs(DD) -# from ESMF.util.cache_data import cache_data_file +# from esmpy.util.cache_data import cache_data_file # cache_data_file(os.path.join(DD, "ll2.5deg_grid.nc")) # cache_data_file(os.path.join(DD, "mpas_uniform_10242_dual_counterclockwise.nc")) -import ESMF +import esmpy import numpy -import ESMF.util.helpers as helpers -import ESMF.api.constants as constants +import esmpy.util.helpers as helpers +import esmpy.api.constants as constants # This call enables debug logging -mg = ESMF.Manager(debug=True) +mg = esmpy.Manager(debug=True) # ESMPy uses Fortran style dimension ordering (as of November 2017) [lat,lon] = [1,0] @@ -25,17 +25,17 @@ # Create the source grid from memory with periodic dimension specified. lons = numpy.arange(5, 350.1, 10) lats = numpy.arange(-85, 85.1, 10) -srcgrid = ESMF.Grid(numpy.array([lons.size, lats.size]), - coord_sys=ESMF.CoordSys.SPH_DEG, - staggerloc=ESMF.StaggerLoc.CENTER, +srcgrid = esmpy.Grid(numpy.array([lons.size, lats.size]), + coord_sys=esmpy.CoordSys.SPH_DEG, + staggerloc=esmpy.StaggerLoc.CENTER, num_peri_dims=1, periodic_dim=0, pole_dim=1) # Get and set the source grid coordinates. srcGridCoordLon = srcgrid.get_coords(lon) srcGridCoordLat = srcgrid.get_coords(lat) -slons_par = lons[srcgrid.lower_bounds[ESMF.StaggerLoc.CENTER][0]:srcgrid.upper_bounds[ESMF.StaggerLoc.CENTER][0]] -slats_par = lats[srcgrid.lower_bounds[ESMF.StaggerLoc.CENTER][1]:srcgrid.upper_bounds[ESMF.StaggerLoc.CENTER][1]] +slons_par = lons[srcgrid.lower_bounds[esmpy.StaggerLoc.CENTER][0]:srcgrid.upper_bounds[esmpy.StaggerLoc.CENTER][0]] +slats_par = lats[srcgrid.lower_bounds[esmpy.StaggerLoc.CENTER][1]:srcgrid.upper_bounds[esmpy.StaggerLoc.CENTER][1]] # make sure to use indexing='ij' as ESMPy backend uses matrix indexing (not Cartesian) lonm, latm = numpy.meshgrid(slons_par, slats_par, indexing='ij') @@ -46,17 +46,17 @@ # Create the dest grid from memory with periodic dimension specified. lons = numpy.arange(2.5, 357.6, 5) lats = numpy.arange(-87.5, 87.6, 5) -dstgrid = ESMF.Grid(numpy.array([lons.size, lats.size]), - coord_sys=ESMF.CoordSys.SPH_DEG, - staggerloc=ESMF.StaggerLoc.CENTER, +dstgrid = esmpy.Grid(numpy.array([lons.size, lats.size]), + coord_sys=esmpy.CoordSys.SPH_DEG, + staggerloc=esmpy.StaggerLoc.CENTER, num_peri_dims=1, periodic_dim=1, pole_dim=0) # Get and set the source grid coordinates. dstGridCoordLat = dstgrid.get_coords(lat) dstGridCoordLon = dstgrid.get_coords(lon) -dlons_par = lons[dstgrid.lower_bounds[ESMF.StaggerLoc.CENTER][0]:dstgrid.upper_bounds[ESMF.StaggerLoc.CENTER][0]] -dlats_par = lats[dstgrid.lower_bounds[ESMF.StaggerLoc.CENTER][1]:dstgrid.upper_bounds[ESMF.StaggerLoc.CENTER][1]] +dlons_par = lons[dstgrid.lower_bounds[esmpy.StaggerLoc.CENTER][0]:dstgrid.upper_bounds[esmpy.StaggerLoc.CENTER][0]] +dlats_par = lats[dstgrid.lower_bounds[esmpy.StaggerLoc.CENTER][1]:dstgrid.upper_bounds[esmpy.StaggerLoc.CENTER][1]] # make sure to use indexing='ij' as ESMPy backend uses matrix indexing (not Cartesian) lonm, latm = numpy.meshgrid(dlons_par, dlats_par, indexing='ij') @@ -65,14 +65,14 @@ dstGridCoordLat[:] = latm # Create a field on the centers of the source grid with the mask applied. -srcfield = ESMF.Field(srcgrid, name="srcfield", staggerloc=ESMF.StaggerLoc.CENTER) +srcfield = esmpy.Field(srcgrid, name="srcfield", staggerloc=esmpy.StaggerLoc.CENTER) # Create a field on the centers of the source grid with the mask applied. -dstfield = ESMF.Field(dstgrid, name="dstfield", staggerloc=ESMF.StaggerLoc.CENTER) -xctfield = ESMF.Field(dstgrid, name="xctfield", staggerloc=ESMF.StaggerLoc.CENTER) +dstfield = esmpy.Field(dstgrid, name="dstfield", staggerloc=esmpy.StaggerLoc.CENTER) +xctfield = esmpy.Field(dstgrid, name="xctfield", staggerloc=esmpy.StaggerLoc.CENTER) -gridLon = srcfield.grid.get_coords(lon, ESMF.StaggerLoc.CENTER) -gridLat = srcfield.grid.get_coords(lat, ESMF.StaggerLoc.CENTER) +gridLon = srcfield.grid.get_coords(lon, esmpy.StaggerLoc.CENTER) +gridLat = srcfield.grid.get_coords(lat, esmpy.StaggerLoc.CENTER) # wave = lambda x,k: numpy.sin(x*k*numpy.pi/180.0) # srcfield.data[...] = numpy.outer(wave(slons_par,3), wave(slats_par,3)) + 2 @@ -90,20 +90,20 @@ # write regridding weights to file filename = "esmpy_example_weight_file.nc" -if ESMF.local_pet() == 0: +if esmpy.local_pet() == 0: import os if os.path.isfile( os.path.join(os.getcwd(), filename)): os.remove(os.path.join(os.getcwd(), filename)) mg.barrier() -regrid = ESMF.Regrid(srcfield, dstfield, filename=filename, - regrid_method=ESMF.RegridMethod.BILINEAR, - unmapped_action=ESMF.UnmappedAction.IGNORE) +regrid = esmpy.Regrid(srcfield, dstfield, filename=filename, + regrid_method=esmpy.RegridMethod.BILINEAR, + unmapped_action=esmpy.UnmappedAction.IGNORE) # # create a regrid object from file -regrid = ESMF.RegridFromFile(srcfield, dstfield, filename) +regrid = esmpy.RegridFromFile(srcfield, dstfield, filename) # calculate the regridding from source to destination field dstfield = regrid(srcfield, dstfield) @@ -118,12 +118,12 @@ meanrelerr = relerr / num_nodes # handle the parallel case -if ESMF.pet_count() > 1: +if esmpy.pet_count() > 1: relerr = helpers.reduce_val(relerr, op=constants.Reduce.SUM) num_nodes = helpers.reduce_val(num_nodes, op=constants.Reduce.SUM) # output the results from one processor only -if ESMF.local_pet() == 0: +if esmpy.local_pet() == 0: meanrelerr = relerr / num_nodes print ("ESMPy Grid Mesh Regridding Example") print (" interpolation mean relative error = {0}".format(meanrelerr)) @@ -132,7 +132,7 @@ os.remove(os.path.join(os.getcwd(), filename)) # set to 1 to output results -# if ESMF.pet_count() == 0: +# if esmpy.pet_count() == 0: # import matplotlib.pyplot as plt # fig = plt.figure(1, (15, 6)) # fig.suptitle('ESMPy Periodic Grids', fontsize=14, fontweight='bold') diff --git a/src/addon/ESMPy/examples/regrid_from_file.py b/src/addon/ESMPy/examples/regrid_from_file.py index 0af92b238f..f68fb8edb2 100644 --- a/src/addon/ESMPy/examples/regrid_from_file.py +++ b/src/addon/ESMPy/examples/regrid_from_file.py @@ -7,46 +7,46 @@ # DD = os.path.join(os.getcwd(), "examples/data") # if not os.path.isdir(DD): # os.makedirs(DD) -# from ESMF.util.cache_data import cache_data_file +# from esmpy.util.cache_data import cache_data_file # cache_data_file(os.path.join(DD, "so_Omon_GISS-E2.nc")) # cache_data_file(os.path.join(DD, "mpas_uniform_10242_dual_counterclockwise.nc")) import os -import ESMF +import esmpy # This call enables debug logging -# ESMF.Manager(debug=True) +# esmpy.Manager(debug=True) # Set up the DATADIR DATADIR = os.path.join(os.getcwd(), "examples/data") # Create a global grid from a GRIDSPEC formatted file -grid = ESMF.Grid(filename=os.path.join(DATADIR, "so_Omon_GISS-E2.nc"), - filetype=ESMF.FileFormat.GRIDSPEC) +grid = esmpy.Grid(filename=os.path.join(DATADIR, "so_Omon_GISS-E2.nc"), + filetype=esmpy.FileFormat.GRIDSPEC) # Create a field on the centers of the grid, with extra dimensions -srcfield = ESMF.Field(grid, staggerloc=ESMF.StaggerLoc.CENTER, ndbounds=[33, 2]) +srcfield = esmpy.Field(grid, staggerloc=esmpy.StaggerLoc.CENTER, ndbounds=[33, 2]) # Read the field data from file srcfield.read(filename=os.path.join(DATADIR, "so_Omon_GISS-E2.nc"), variable="so", timeslice=2) # Create an ESMF formatted unstructured mesh with clockwise cells removed -mesh = ESMF.Mesh(filename=os.path.join(DATADIR, "mpas_uniform_10242_dual_counterclockwise.nc"), - filetype=ESMF.FileFormat.ESMFMESH) +mesh = esmpy.Mesh(filename=os.path.join(DATADIR, "mpas_uniform_10242_dual_counterclockwise.nc"), + filetype=esmpy.FileFormat.ESMFMESH) # Create a field on the nodes of the mesh -dstfield = ESMF.Field(mesh, meshloc=ESMF.MeshLoc.NODE, ndbounds=[33, 2]) +dstfield = esmpy.Field(mesh, meshloc=esmpy.MeshLoc.NODE, ndbounds=[33, 2]) dstfield.data[:] = 1e20 # compute the weight matrix for regridding -regrid = ESMF.Regrid(srcfield, dstfield, - regrid_method=ESMF.RegridMethod.BILINEAR, - unmapped_action=ESMF.UnmappedAction.IGNORE) +regrid = esmpy.Regrid(srcfield, dstfield, + regrid_method=esmpy.RegridMethod.BILINEAR, + unmapped_action=esmpy.UnmappedAction.IGNORE) # calculate the regridding from source to destination field dstfield = regrid(srcfield, dstfield) -if ESMF.local_pet() == 0: +if esmpy.local_pet() == 0: print ("Fields created from file regridded successfully :)") diff --git a/src/addon/ESMPy/examples/tripole_regrid.py b/src/addon/ESMPy/examples/tripole_regrid.py index 9fd4371d45..5afdb72101 100644 --- a/src/addon/ESMPy/examples/tripole_regrid.py +++ b/src/addon/ESMPy/examples/tripole_regrid.py @@ -7,47 +7,47 @@ # DD = os.path.join(os.getcwd(), "examples/data") # if not os.path.isdir(DD): # os.makedirs(DD) -# from ESMF.util.cache_data import cache_data_file +# from esmpy.util.cache_data import cache_data_file # cache_data_file(os.path.join(DD, "GRIDSPEC_ACCESS1.nc")) # cache_data_file(os.path.join(DD, "tx0.1v2_070911.nc")) -import ESMF +import esmpy import numpy -import ESMF.util.helpers as helpers -import ESMF.api.constants as constants +import esmpy.util.helpers as helpers +import esmpy.api.constants as constants # This call enables debug logging -# esmpy = ESMF.Manager(debug=True) +# esmpy = esmpy.Manager(debug=True) grid1 = "examples/data/GRIDSPEC_ACCESS1.nc" grid2 = "examples/data/tx0.1v2_070911.nc" # Create a grid from a GRIDSPEC formatted file -grid = ESMF.Grid(filename=grid1, filetype=ESMF.FileFormat.GRIDSPEC, +grid = esmpy.Grid(filename=grid1, filetype=esmpy.FileFormat.GRIDSPEC, add_corner_stagger=True, add_mask=True, varname="so") # create a field on the center stagger locations of the source grid -srcfield = ESMF.Field(grid, name='srcfield', staggerloc=ESMF.StaggerLoc.CENTER) +srcfield = esmpy.Field(grid, name='srcfield', staggerloc=esmpy.StaggerLoc.CENTER) # create a tripole grid -tripole = ESMF.Grid(filename=grid2, filetype=ESMF.FileFormat.SCRIP, +tripole = esmpy.Grid(filename=grid2, filetype=esmpy.FileFormat.SCRIP, add_corner_stagger=True, add_mask=True, varname="grid_imask") # create fields on the center stagger locations of the tripole grid -dstfield = ESMF.Field(tripole, name='dstfield', meshloc=ESMF.StaggerLoc.CENTER) -xctfield = ESMF.Field(tripole, name='xctfield', meshloc=ESMF.StaggerLoc.CENTER) +dstfield = esmpy.Field(tripole, name='dstfield', meshloc=esmpy.StaggerLoc.CENTER) +xctfield = esmpy.Field(tripole, name='xctfield', meshloc=esmpy.StaggerLoc.CENTER) # create fields needed to analyze accuracy of conservative regridding -srcfracfield = ESMF.Field(grid, name='srcfracfield') -dstfracfield = ESMF.Field(tripole, name='dstfracfield') -srcareafield = ESMF.Field(grid, name='srcareafield') -dstareafield = ESMF.Field(tripole, name='dstareafield') +srcfracfield = esmpy.Field(grid, name='srcfracfield') +dstfracfield = esmpy.Field(tripole, name='dstfracfield') +srcareafield = esmpy.Field(grid, name='srcareafield') +dstareafield = esmpy.Field(tripole, name='dstareafield') # get the coordinate pointers and set the coordinates [lon,lat] = [0, 1] -gridXCoord = srcfield.grid.get_coords(lon, ESMF.StaggerLoc.CENTER) -gridYCoord = srcfield.grid.get_coords(lat, ESMF.StaggerLoc.CENTER) +gridXCoord = srcfield.grid.get_coords(lon, esmpy.StaggerLoc.CENTER) +gridYCoord = srcfield.grid.get_coords(lat, esmpy.StaggerLoc.CENTER) deg2rad = 3.14159/180 @@ -55,8 +55,8 @@ # get the coordinate pointers and set the coordinates [lon,lat] = [0, 1] -gridXCoord = xctfield.grid.get_coords(lon, ESMF.StaggerLoc.CENTER) -gridYCoord = xctfield.grid.get_coords(lat, ESMF.StaggerLoc.CENTER) +gridXCoord = xctfield.grid.get_coords(lon, esmpy.StaggerLoc.CENTER) +gridYCoord = xctfield.grid.get_coords(lat, esmpy.StaggerLoc.CENTER) xctfield.data[...] = 10.0 + (gridXCoord*deg2rad)**2 + (gridYCoord*deg2rad)**2 @@ -64,9 +64,9 @@ # create an object to regrid data from the source to the destination field # NOTE: this example requires the unmapped_action flag to be set to IGNORE missing values due to masking -regrid = ESMF.Regrid(srcfield, dstfield, - regrid_method=ESMF.RegridMethod.CONSERVE, - unmapped_action=ESMF.UnmappedAction.IGNORE, +regrid = esmpy.Regrid(srcfield, dstfield, + regrid_method=esmpy.RegridMethod.CONSERVE, + unmapped_action=esmpy.UnmappedAction.IGNORE, src_mask_values=numpy.array([0]), dst_mask_values=numpy.array([0]), src_frac_field=srcfracfield, @@ -96,14 +96,14 @@ meanrelerr = relerr / num_nodes # handle the parallel case -if ESMF.pet_count() > 1: +if esmpy.pet_count() > 1: relerr = helpers.reduce_val(relerr, op=constants.Reduce.SUM) num_nodes = helpers.reduce_val(num_nodes, op=constants.Reduce.SUM) srcmass = helpers.reduce_val(srcmass, op=constants.Reduce.SUM) dstmass = helpers.reduce_val(dstmass, op=constants.Reduce.SUM) # output the results from one processor only -if ESMF.local_pet() == 0: +if esmpy.local_pet() == 0: meanrelerr = relerr / num_nodes csrverr = numpy.abs(srcmass - dstmass) / dstmass diff --git a/src/addon/ESMPy/examples/ugrid_latlon_regrid.py b/src/addon/ESMPy/examples/ugrid_latlon_regrid.py index 47476e0417..89716d8906 100644 --- a/src/addon/ESMPy/examples/ugrid_latlon_regrid.py +++ b/src/addon/ESMPy/examples/ugrid_latlon_regrid.py @@ -6,12 +6,12 @@ # DD = os.path.join(os.getcwd(), "examples/data") # if not os.path.isdir(DD): # os.makedirs(DD) -# from ESMF.util.cache_data import cache_data_file +# from esmpy.util.cache_data import cache_data_file # cache_data_file(os.path.join(DD, "ll1deg_grid.nc")) # cache_data_file(os.path.join(DD, "ne30np4-t2UGRID_nodual.nc")) # cache_data_file(os.path.join(DD, "aggregAtlanticESTOFS.nc")) -import ESMF +import esmpy import numpy def plot_error(field1, field2, uninitval): @@ -90,35 +90,35 @@ def plot_field(field2, uninitval): plt.show() # This call enables debug logging -# esmpy = ESMF.Manager(debug=True) +# esmpy = esmpy.Manager(debug=True) # these are for a new test using opendap, dataset has periodic failures.. # meshfile = "http://coastalmodeldev.data.noaa.gov/thredds/dodsC/aggregAtlanticESTOFS" meshfile = "examples/data/aggregAtlanticESTOFS.nc" -mesh = ESMF.Mesh(filename=meshfile, filetype=ESMF.FileFormat.UGRID, meshname='adcirc_mesh') +mesh = esmpy.Mesh(filename=meshfile, filetype=esmpy.FileFormat.UGRID, meshname='adcirc_mesh') # Create a global latlon grid from a SCRIP formatted file gridfile = "examples/data/ll1deg_grid.nc" -grid = ESMF.Grid(filename=gridfile, filetype=ESMF.FileFormat.SCRIP, +grid = esmpy.Grid(filename=gridfile, filetype=esmpy.FileFormat.SCRIP, add_corner_stagger=True, is_sphere=True) # create a field on the element locations of the source mesh -srcfield = ESMF.Field(mesh, name='srcfield', meshloc=ESMF.MeshLoc.NODE) +srcfield = esmpy.Field(mesh, name='srcfield', meshloc=esmpy.MeshLoc.NODE) # create a field on the centers of the destination grid -dstfield = ESMF.Field(grid, name='dstfield', staggerloc=ESMF.StaggerLoc.CENTER) -xctfield = ESMF.Field(grid, name='xctfield', staggerloc=ESMF.StaggerLoc.CENTER) +dstfield = esmpy.Field(grid, name='dstfield', staggerloc=esmpy.StaggerLoc.CENTER) +xctfield = esmpy.Field(grid, name='xctfield', staggerloc=esmpy.StaggerLoc.CENTER) # initialize the fields [lon,lat] = [0, 1] -srcgridXCoord = srcfield.grid.get_coords(lon, meshloc=ESMF.MeshLoc.NODE) -srcgridYCoord = srcfield.grid.get_coords(lat, meshloc=ESMF.MeshLoc.NODE) +srcgridXCoord = srcfield.grid.get_coords(lon, meshloc=esmpy.MeshLoc.NODE) +srcgridYCoord = srcfield.grid.get_coords(lat, meshloc=esmpy.MeshLoc.NODE) srcfield.data[...] = 2.0 + numpy.cos(numpy.radians(srcgridYCoord)[...])**2 * \ numpy.cos(2.0*numpy.radians(srcgridXCoord)[...]) -dstgridXCoord = xctfield.grid.get_coords(lon, ESMF.StaggerLoc.CENTER) -dstgridYCoord = xctfield.grid.get_coords(lat, ESMF.StaggerLoc.CENTER) +dstgridXCoord = xctfield.grid.get_coords(lon, esmpy.StaggerLoc.CENTER) +dstgridYCoord = xctfield.grid.get_coords(lat, esmpy.StaggerLoc.CENTER) xctfield.data[...] = 2.0 + numpy.cos(numpy.radians(dstgridYCoord)[...])**2 * \ numpy.cos(2.0*numpy.radians(dstgridXCoord)[...]) @@ -126,15 +126,15 @@ def plot_field(field2, uninitval): dstfield.data[...] = uninitval # create an object to regrid data from the source to the destination field -regrid = ESMF.Regrid(srcfield, dstfield, - regrid_method=ESMF.RegridMethod.BILINEAR, - unmapped_action=ESMF.UnmappedAction.IGNORE) +regrid = esmpy.Regrid(srcfield, dstfield, + regrid_method=esmpy.RegridMethod.BILINEAR, + unmapped_action=esmpy.UnmappedAction.IGNORE) # do the regridding from source to destination field -dstfield = regrid(srcfield, dstfield, zero_region=ESMF.Region.SELECT) +dstfield = regrid(srcfield, dstfield, zero_region=esmpy.Region.SELECT) # output the results from one processor only -if ESMF.local_pet() == 0: +if esmpy.local_pet() == 0: print ("ESMPy UGRID to LatLon Regridding Example") # plot_error(xctfield, dstfield, uninitval=uninitval) @@ -154,11 +154,11 @@ def plot_field(field2, uninitval): # dstfield.data[...] = uninitval # # create an object to regrid data from the source to the destination field -# regrid = ESMF.Regrid(srcfield, dstfield, -# regrid_method=ESMF.RegridMethod.BILINEAR, -# unmapped_action=ESMF.UnmappedAction.IGNORE) +# regrid = esmpy.Regrid(srcfield, dstfield, +# regrid_method=esmpy.RegridMethod.BILINEAR, +# unmapped_action=esmpy.UnmappedAction.IGNORE) # # # do the regridding from source to destination field -# dstfield = regrid(srcfield, dstfield, zero_region=ESMF.Region.SELECT) +# dstfield = regrid(srcfield, dstfield, zero_region=esmpy.Region.SELECT) # # plot_field(dstfield, uninitval=uninitval) \ No newline at end of file diff --git a/src/addon/ESMPy/examples/ungridded_dimension_regrid.py b/src/addon/ESMPy/examples/ungridded_dimension_regrid.py index 41f21e3d49..f4ab910df0 100644 --- a/src/addon/ESMPy/examples/ungridded_dimension_regrid.py +++ b/src/addon/ESMPy/examples/ungridded_dimension_regrid.py @@ -7,18 +7,18 @@ # DD = os.path.join(os.getcwd(), "examples/data") # if not os.path.isdir(DD): # os.makedirs(DD) -# from ESMF.util.cache_data import cache_data_file +# from esmpy.util.cache_data import cache_data_file # cache_data_file(os.path.join(DD, "ll2.5deg_grid.nc")) # cache_data_file(os.path.join(DD, "T42_grid.nc")) -import ESMF +import esmpy import numpy -import ESMF.util.helpers as helpers -import ESMF.api.constants as constants +import esmpy.util.helpers as helpers +import esmpy.api.constants as constants # This call enables debug logging -# esmpy = ESMF.Manager(debug=True) +# esmpy = esmpy.Manager(debug=True) grid1 = "examples/data/ll2.5deg_grid.nc" grid2 = "examples/data/T42_grid.nc" @@ -28,39 +28,39 @@ time = 5 # Create a uniform global latlon grid from a SCRIP formatted file -srcgrid = ESMF.Grid(filename=grid1, filetype=ESMF.FileFormat.SCRIP, +srcgrid = esmpy.Grid(filename=grid1, filetype=esmpy.FileFormat.SCRIP, add_corner_stagger=True) # Create a uniform global latlon grid from a SCRIP formatted file -dstgrid = ESMF.Grid(filename=grid2, filetype=ESMF.FileFormat.SCRIP, +dstgrid = esmpy.Grid(filename=grid2, filetype=esmpy.FileFormat.SCRIP, add_corner_stagger=True) # Create a field on the center stagger locations of the source grid -srcfield = ESMF.Field(srcgrid, name='srcfield', - staggerloc=ESMF.StaggerLoc.CENTER, +srcfield = esmpy.Field(srcgrid, name='srcfield', + staggerloc=esmpy.StaggerLoc.CENTER, ndbounds=[levels, time]) # Create a field on the center stagger locations of the destination grid -dstfield = ESMF.Field(dstgrid, name='dstfield', - staggerloc=ESMF.StaggerLoc.CENTER, +dstfield = esmpy.Field(dstgrid, name='dstfield', + staggerloc=esmpy.StaggerLoc.CENTER, ndbounds=[levels, time]) # Create a field on the center stagger locations of the destination grid -xctfield = ESMF.Field(dstgrid, name='xctfield', - staggerloc=ESMF.StaggerLoc.CENTER, +xctfield = esmpy.Field(dstgrid, name='xctfield', + staggerloc=esmpy.StaggerLoc.CENTER, ndbounds=[levels, time]) # Create fields needed to analyze accuracy of conservative regridding -srcfracfield = ESMF.Field(srcgrid, name='srcfracfield') -dstfracfield = ESMF.Field(dstgrid, name='dstfracfield') -srcareafield = ESMF.Field(srcgrid, name='srcareafield') -dstareafield = ESMF.Field(dstgrid, name='dstareafield') +srcfracfield = esmpy.Field(srcgrid, name='srcfracfield') +dstfracfield = esmpy.Field(dstgrid, name='dstfracfield') +srcareafield = esmpy.Field(srcgrid, name='srcareafield') +dstareafield = esmpy.Field(dstgrid, name='dstareafield') # Get the coordinate pointers and initialize the source field [lon,lat] = [0, 1] -gridXCoord = srcfield.grid.get_coords(lon, ESMF.StaggerLoc.CENTER) -gridYCoord = srcfield.grid.get_coords(lat, ESMF.StaggerLoc.CENTER) +gridXCoord = srcfield.grid.get_coords(lon, esmpy.StaggerLoc.CENTER) +gridYCoord = srcfield.grid.get_coords(lat, esmpy.StaggerLoc.CENTER) deg2rad = 3.14159/180 @@ -73,8 +73,8 @@ (gridYCoord*deg2rad)**2 # Get the coordinate pointers and initialize the exact solution -gridXCoord = xctfield.grid.get_coords(lon, ESMF.StaggerLoc.CENTER) -gridYCoord = xctfield.grid.get_coords(lat, ESMF.StaggerLoc.CENTER) +gridXCoord = xctfield.grid.get_coords(lon, esmpy.StaggerLoc.CENTER) +gridYCoord = xctfield.grid.get_coords(lat, esmpy.StaggerLoc.CENTER) for level in range(levels): for timestep in range(time): @@ -87,9 +87,9 @@ dstfield.data[...] = 1e20 # Create an object to regrid data from the source to the destination field -regrid = ESMF.Regrid(srcfield, dstfield, - regrid_method=ESMF.RegridMethod.CONSERVE, - unmapped_action=ESMF.UnmappedAction.ERROR, +regrid = esmpy.Regrid(srcfield, dstfield, + regrid_method=esmpy.RegridMethod.CONSERVE, + unmapped_action=esmpy.UnmappedAction.ERROR, src_frac_field=srcfracfield, dst_frac_field=dstfracfield) @@ -126,14 +126,14 @@ csrverr = numpy.abs(srcmass - dstmass) / dstmass # Handle the parallel case -if ESMF.pet_count() > 1: +if esmpy.pet_count() > 1: relerr = helpers.reduce_val(relerr, op=constants.Reduce.SUM) num_nodes = helpers.reduce_val(num_nodes, op=constants.Reduce.SUM) srcmass = helpers.reduce_val(srcmass, op=constants.Reduce.SUM) dstmass = helpers.reduce_val(dstmass, op=constants.Reduce.SUM) # Output the results from one processor only -if ESMF.local_pet() == 0: +if esmpy.local_pet() == 0: meanrelerr = relerr / num_nodes csrverr = numpy.abs(srcmass - dstmass) / dstmass diff --git a/src/addon/ESMPy/src/ESMF/test/regrid_from_file/regrid_from_file_consts.py b/src/addon/ESMPy/src/ESMF/test/regrid_from_file/regrid_from_file_consts.py deleted file mode 100644 index 3c4277dad2..0000000000 --- a/src/addon/ESMPy/src/ESMF/test/regrid_from_file/regrid_from_file_consts.py +++ /dev/null @@ -1,31 +0,0 @@ -""" -Constants required for the regrid from file tests. -""" -import os -try: - import ESMF -except: - raise ImportError('The ESMF library cannot be found!') -# -TEST_REGRID_DIR = 'src/ESMF/test/regrid_from_file/' -CONTROL_FNAME = 'regrid_test_data.txt' -DATA_SUBDIR = os.path.join(TEST_REGRID_DIR,'data/') -DATA_URL_ROOT = 'http://data.earthsystemmodeling.org/download/data/' -UNINITVAL = 422397696. -EPSILON = 1E-30 -# -regrid_method_map = {"bilinear" : ESMF.RegridMethod.BILINEAR, - "patch" : ESMF.RegridMethod.PATCH, - "conserve" : ESMF.RegridMethod.CONSERVE, - "neareststod" : ESMF.RegridMethod.NEAREST_STOD, - "nearestdtos" : ESMF.RegridMethod.NEAREST_DTOS} -file_type_map = {"VTK" : ESMF.FileFormat.VTK, - "SCRIP" : ESMF.FileFormat.SCRIP, - "ESMF" : ESMF.FileFormat.ESMFMESH, - "ESMFMESH" : ESMF.FileFormat.ESMFMESH, - "ESMFGRID" : ESMF.FileFormat.ESMFGRID, - "UGRID" : ESMF.FileFormat.UGRID, - "GRIDSPEC" : ESMF.FileFormat.GRIDSPEC} -pole_method_map = {"none" : ESMF.PoleMethod.NONE, - "all" : ESMF.PoleMethod.ALLAVG, - "teeth" : ESMF.PoleMethod.TEETH} diff --git a/src/addon/ESMPy/src/ESMF/__init__.py b/src/addon/ESMPy/src/esmpy/__init__.py similarity index 80% rename from src/addon/ESMPy/src/ESMF/__init__.py rename to src/addon/ESMPy/src/esmpy/__init__.py index a69935ab09..ec5f90f4bd 100644 --- a/src/addon/ESMPy/src/ESMF/__init__.py +++ b/src/addon/ESMPy/src/esmpy/__init__.py @@ -15,9 +15,9 @@ can be found in the `ESMF Reference Manual `_. -ESMPy provides a :class:`~ESMF.api.grid.Grid` to represent single-tile logically -rectangular coordinate data, a :class:`~ESMF.api.mesh.Mesh` for unstructured -coordinates, and a :class:`~ESMF.api.locstream.LocStream` for collections of +ESMPy provides a :class:`~esmpy.api.grid.Grid` to represent single-tile logically +rectangular coordinate data, a :class:`~esmpy.api.mesh.Mesh` for unstructured +coordinates, and a :class:`~esmpy.api.locstream.LocStream` for collections of unconnected points like observational data streams. ESMPy supports bilinear, nearest neighbor, higher order patch recovery, first-order conservative and second-order conservative regridding. There is @@ -26,7 +26,7 @@ spherical coordinates and extrapolate data to points outside of the destination domain. Regridding on the sphere takes place in 3D Cartesian space, so the pole problem is not an issue as it commonly is with many Earth system grid remapping -softwares. :class:`~ESMF.api.grid.Grid` and :class:`~ESMF.api.mesh.Mesh` +softwares. :class:`~esmpy.api.grid.Grid` and :class:`~esmpy.api.mesh.Mesh` objects can be created in 2D or 3D space, and 3D conservative regridding is fully supported. @@ -66,14 +66,14 @@ #### IMPORT LIBRARIES ######################################################### -from ESMF.api.esmpymanager import * -from ESMF.api.grid import * -from ESMF.api.mesh import * -from ESMF.api.locstream import * -from ESMF.api.field import * -from ESMF.api.regrid import * -from ESMF.api.constants import * -from ESMF.util.helpers import * +from esmpy.api.esmpymanager import * +from esmpy.api.grid import * +from esmpy.api.mesh import * +from esmpy.api.locstream import * +from esmpy.api.field import * +from esmpy.api.regrid import * +from esmpy.api.constants import * +from esmpy.util.helpers import * #### SET UP SOME INFO ######################################################### @@ -114,18 +114,3 @@ __author__ = msg["Author"] __homepage__ = msg["Home-page"] __obsoletes__ = msg["obsoletes"] - -# # this is the old hardcoded version - -# __name__ = "ESMF" -# __version__ = "" -# __description__ = "ESMF Python interface" -# __author__ = "University Corporation for Atmospheric Research, " + \ -# "Massachusetts Institute of Technology, " + \ -# "Geophysical Fluid Dynamics Laboratory, " + \ -# "University of Michigan, " + \ -# "National Centers for Environmental Prediction, " + \ -# "Los Alamos National Laboratory, " + \ -# "Argonne National Laboratory, " + \ -# "NASA Goddard Space Flight Center" -# __license__ = "University of Illinois-NCSA" diff --git a/src/addon/ESMPy/src/ESMF/api/__init__.py b/src/addon/ESMPy/src/esmpy/api/__init__.py similarity index 100% rename from src/addon/ESMPy/src/ESMF/api/__init__.py rename to src/addon/ESMPy/src/esmpy/api/__init__.py diff --git a/src/addon/ESMPy/src/ESMF/api/constants.py b/src/addon/ESMPy/src/esmpy/api/constants.py similarity index 84% rename from src/addon/ESMPy/src/ESMF/api/constants.py rename to src/addon/ESMPy/src/esmpy/api/constants.py index b76a69d47d..4094e2901e 100644 --- a/src/addon/ESMPy/src/ESMF/api/constants.py +++ b/src/addon/ESMPy/src/esmpy/api/constants.py @@ -2,7 +2,7 @@ import numpy as np -from ESMF.util.enum import IntEnum +from esmpy.util.enum import IntEnum # Test exhaustive parameter esmpy_test_exhaustive=False @@ -57,33 +57,33 @@ # CoordSys class CoordSys(IntEnum): """ - This flag indicates the coordinate system of a :class:`~ESMF.api.grid.Grid`. This value is + This flag indicates the coordinate system of a :class:`~esmpy.api.grid.Grid`. This value is useful both to indicate to other users the type of the coordinates, but also to control how the coordinates are interpreted in - regridding methods (e.g. :class:`~ESMF.api.regrid.Regrid`). + regridding methods (e.g. :class:`~esmpy.api.regrid.Regrid`). """ INVALID = -2 UNINIT = -1 CART = 0 """ Cartesian coordinate system. In this system, the Cartesian - coordinates are mapped to the :class:`~ESMF.api.grid.Grid` coordinate dimensions in the + coordinates are mapped to the :class:`~esmpy.api.grid.Grid` coordinate dimensions in the following order: x, y, z. (e.g. using coord_dim=1 in - :class:`~ESMF.api.grid.Grid.get_coords()` references the y dimension) + :class:`~esmpy.api.grid.Grid.get_coords()` references the y dimension) """ SPH_DEG = 1 """ Spherical coordinates in degrees. In this system, the spherical - coordinates are mapped to the :class:`~ESMF.api.grid.Grid` coordinate dimensions in the + coordinates are mapped to the :class:`~esmpy.api.grid.Grid` coordinate dimensions in the following order: longitude, latitude, radius. (E.g. using - coord_dim=1 in :class:`~ESMF.api.grid.:class:`~ESMF.api.grid.Grid.get_coords()`` references the latitude dimension). + coord_dim=1 in :class:`~esmpy.api.grid.:class:`~esmpy.api.grid.Grid.get_coords()`` references the latitude dimension). """ SPH_RAD = 2 """ Spherical coordinates in radians. In this system, the spherical - coordinates are mapped to the :class:`~ESMF.api.grid.Grid` coordinate dimensions in the + coordinates are mapped to the :class:`~esmpy.api.grid.Grid` coordinate dimensions in the following order: longitude, latitude, radius. (E.g. using - coord_dim=1 in :class:`~ESMF.api.grid.Grid.get_coords()` references the latitude dimension). + coord_dim=1 in :class:`~esmpy.api.grid.Grid.get_coords()` references the latitude dimension). """ # DecompFlag @@ -156,7 +156,7 @@ class ExtrapMethod(IntEnum): # FileFormat class FileFormat(IntEnum): """ - The :class:`~ESMF.api.grid.Grid` and :class:`~ESMF.api.mesh.Mesh` objects + The :class:`~esmpy.api.grid.Grid` and :class:`~esmpy.api.mesh.Mesh` objects may be created from specifications in a NetCDF data file. This flag indicates the format of the data file. """ @@ -203,9 +203,9 @@ class FileMode(IntEnum): # GridItem class GridItem(IntEnum): """ - The :class:`~ESMF.api.grid.Grid` can contain other kinds of data besides coordinates. This - data is referred to as :class:`~ESMF.api.grid.Grid` "items". Some items may be used - for calculations involving the :class:`~ESMF.api.grid.Grid`. + The :class:`~esmpy.api.grid.Grid` can contain other kinds of data besides coordinates. This + data is referred to as :class:`~esmpy.api.grid.Grid` "items". Some items may be used + for calculations involving the :class:`~esmpy.api.grid.Grid`. """ INVALID = -2 UNINIT = -1 @@ -263,11 +263,11 @@ class LogKind(IntEnum): # MeshElemType class MeshElemType(IntEnum): """ - A :class:`~ESMF.api.mesh.Mesh` can be constructed from a combination of different elements. - The type of elements that can be used in a :class:`~ESMF.api.mesh.Mesh` depends on the - parametric dimension of the :class:`~ESMF.api.mesh.Mesh`, which is set during :class:`~ESMF.api.mesh.Mesh` - creation. The following are the valid :class:`~ESMF.api.mesh.Mesh` element types for each - valid :class:`~ESMF.api.mesh.Mesh` parametric dimension (2D or 3D). + A :class:`~esmpy.api.mesh.Mesh` can be constructed from a combination of different elements. + The type of elements that can be used in a :class:`~esmpy.api.mesh.Mesh` depends on the + parametric dimension of the :class:`~esmpy.api.mesh.Mesh`, which is set during :class:`~esmpy.api.mesh.Mesh` + creation. The following are the valid :class:`~esmpy.api.mesh.Mesh` element types for each + valid :class:`~esmpy.api.mesh.Mesh` parametric dimension (2D or 3D). """ TRI = 3 """ @@ -289,15 +289,15 @@ class MeshElemType(IntEnum): # MeshLoc class MeshLoc(IntEnum): """ - The :class:`~ESMF.api.mesh.Mesh` location used to hold :class:`~ESMF.api.field.Field` data. + The :class:`~esmpy.api.mesh.Mesh` location used to hold :class:`~esmpy.api.field.Field` data. """ NODE = 0 """ - The nodes of the :class:`~ESMF.api.mesh.Mesh`. + The nodes of the :class:`~esmpy.api.mesh.Mesh`. """ ELEMENT = 1 """ - The elements of the :class:`~ESMF.api.mesh.Mesh`. + The elements of the :class:`~esmpy.api.mesh.Mesh`. """ # NormType @@ -326,7 +326,7 @@ class NormType(IntEnum): class PoleKind(IntEnum): """ This type describes the type of connection that occurs at the pole of a - :class:`~ESMF.api.grid.Grid`. + :class:`~esmpy.api.grid.Grid`. """ NONE = 0 """ @@ -346,12 +346,12 @@ class PoleKind(IntEnum): class PoleMethod(IntEnum): """ Indicates which type of artificial pole to construct on the source - :class:`~ESMF.api.grid.Grid` for regridding. + :class:`~esmpy.api.grid.Grid` for regridding. """ NONE = 0 """ No pole. Destination points which lie above the top or below the bottom row - of the source :class:`~ESMF.api.grid.Grid` won't be mapped. + of the source :class:`~esmpy.api.grid.Grid` won't be mapped. """ ALLAVG = 1 """ @@ -374,11 +374,11 @@ class PoleMethod(IntEnum): TEETH = 3 """ No new pole point is constructed, instead the holes at the poles are filled - by constructing triangles across the top and bottom row of the source :class:`~ESMF.api.grid.Grid`. + by constructing triangles across the top and bottom row of the source :class:`~esmpy.api.grid.Grid`. This can be useful because no averaging occurs, however, because the top and bottom of the sphere are now flat, for a big enough mismatch between the size of the destination and source pole holes, some destination points may - still not be able to be mapped to the source :class:`~ESMF.api.grid.Grid`. + still not be able to be mapped to the source :class:`~esmpy.api.grid.Grid`. """ # Region @@ -402,7 +402,7 @@ class Reduce(IntEnum): # Region class Region(IntEnum): """ - Specify various regions in the data layout of a :class:`~ESMF.api.field.Field` object. + Specify various regions in the data layout of a :class:`~esmpy.api.field.Field` object. """ TOTAL = 0 """ @@ -411,7 +411,7 @@ class Region(IntEnum): SELECT = 1 """ An operation applies to a select portion of the domain. One use of this is - to specify that the portions of a :class:`~ESMF.api.field.Field` that are not mapped in a regridding + to specify that the portions of a :class:`~esmpy.api.field.Field` that are not mapped in a regridding operation should retain their original value (as opposed to being initialized to 0). """ @@ -451,10 +451,10 @@ class RegridMethod(IntEnum): is calculated as the weighted sum of the values of the source cells that it overlaps. The weights are determined by the amount the source cell overlaps the destination cell. This method requires corner coordinate values to be - provided in the :class:`~ESMF.api.grid.Grid`. It currently only works for - :class:`Fields `s created on the - :class:`~ESMF.api.grid.Grid` center stagger or - the :class:`~ESMF.api.mesh.Mesh` element location. + provided in the :class:`~esmpy.api.grid.Grid`. It currently only works for + :class:`Fields `s created on the + :class:`~esmpy.api.grid.Grid` center stagger or + the :class:`~esmpy.api.mesh.Mesh` element location. """ NEAREST_STOD = 3 """ @@ -485,18 +485,18 @@ class RegridMethod(IntEnum): mininum value in the source field is 0.0, then it's possible that after regridding with the second-order method, the destination field will contain values less than 0.0. This method requires corner coordinate values to be - provided in the :class:`~ESMF.api.grid.Grid`. It currently only works for - :class:`Fields `s created on the - :class:`~ESMF.api.grid.Grid` center stagger or - the :class:`~ESMF.api.mesh.Mesh` element location. + provided in the :class:`~esmpy.api.grid.Grid`. It currently only works for + :class:`Fields `s created on the + :class:`~esmpy.api.grid.Grid` center stagger or + the :class:`~esmpy.api.mesh.Mesh` element location. """ # StaggerLoc class StaggerLoc(IntEnum): """ - In the :class:`~ESMF.api.grid.Grid` class, data can be located at different positions in a - :class:`~ESMF.api.grid.Grid` cell. When setting or retrieving coordinate data the stagger - location is specified to tell the :class:`~ESMF.api.grid.Grid` method from where in the + In the :class:`~esmpy.api.grid.Grid` class, data can be located at different positions in a + :class:`~esmpy.api.grid.Grid` cell. When setting or retrieving coordinate data the stagger + location is specified to tell the :class:`~esmpy.api.grid.Grid` method from where in the cell to get the data. """ INVALID = -2 diff --git a/src/addon/ESMPy/src/ESMF/api/esmpymanager.py b/src/addon/ESMPy/src/esmpy/api/esmpymanager.py similarity index 87% rename from src/addon/ESMPy/src/ESMF/api/esmpymanager.py rename to src/addon/ESMPy/src/esmpy/api/esmpymanager.py index 286121effe..ddf8f481c0 100644 --- a/src/addon/ESMPy/src/ESMF/api/esmpymanager.py +++ b/src/addon/ESMPy/src/esmpy/api/esmpymanager.py @@ -6,10 +6,10 @@ #### IMPORT LIBRARIES ######################################################### -from ESMF.api.constants import * -from ESMF.util.exceptions import * -from ESMF.interface.cbindings import * -from ESMF.util.decorators import initialize +from esmpy.api.constants import * +from esmpy.util.exceptions import * +from esmpy.interface.cbindings import * +from esmpy.util.decorators import initialize import re @@ -46,28 +46,28 @@ class Manager(object): ''' This singleton class is designed to ensure that ESMF is properly initialized and finalized. ESMF is initialized at - :class:`~ESMF.api.esmpymanager.Manager` creation, and the __del__ + :class:`~esmpy.api.esmpymanager.Manager` creation, and the __del__ method is registered with atexit to ensure ESMF is always finalized prior to exiting Python. If the object is copied, the copy will always be an alias - to the original :class:`~ESMF.api.esmpymanager.Manager` object. The - :class:`~ESMF.api.esmpymanager.Manager` will be created when the first + to the original :class:`~esmpy.api.esmpymanager.Manager` object. The + :class:`~esmpy.api.esmpymanager.Manager` will be created when the first ESMPy object is created if it is not created explicitly by the user. - Explicit creation of a :class:`~ESMF.api.esmpymanager.Manager` object allows + Explicit creation of a :class:`~esmpy.api.esmpymanager.Manager` object allows for setting a flag which results in the output of debug information from the ESMF logging capability during the application runtime. The output log files are named PET.ESMF_LogFile. The PET rank (local_pet) and total number of PETs (pet_count) - can also be retrieved from the :class:`~ESMF.api.esmpymanager.Manager` + can also be retrieved from the :class:`~esmpy.api.esmpymanager.Manager` using the following calls:: - ESMF.local_pet() - ESMF.pet_count() + esmpy.local_pet() + esmpy.pet_count() ``local_pet`` and ``pet_count`` are also properties of the - :class:`~ESMF.api.esmpymanager.Manager`. + :class:`~esmpy.api.esmpymanager.Manager`. Calls ESMP_Initialize and registers __del__ with atexit when called the first time. Subsequent calls only return whether or not ESMF is @@ -75,14 +75,14 @@ class Manager(object): will always be called prior to exiting Python. Calling __init__ explicitly results in a no-op. - The :class:`~ESMF.api.esmpymanager.Manager` can be used to enable the + The :class:`~esmpy.api.esmpymanager.Manager` can be used to enable the `MOAB `_ - mesh backend to the :class:`~ESMF.api.esmpymanager.Mesh`. This is done by calling ``set_moab()`` with ``moab_on=True``. + mesh backend to the :class:`~esmpy.api.esmpymanager.Mesh`. This is done by calling ``set_moab()`` with ``moab_on=True``. - The :class:`~ESMF.api.esmpymanager.Manager` has a `test_exhaustive` member + The :class:`~esmpy.api.esmpymanager.Manager` has a `test_exhaustive` member variable that can be enabled to run - combinatorial expansions of :class:`~ESMF.api.esmpymanager.Grid` and - :class:`~ESMF.api.esmpymanager.Field` creation parameters. + combinatorial expansions of :class:`~esmpy.api.esmpymanager.Grid` and + :class:`~esmpy.api.esmpymanager.Field` creation parameters. :param bool debug: outputs logging information to ESMF logfiles. If ``None``, defaults to False. diff --git a/src/addon/ESMPy/src/ESMF/api/field.py b/src/addon/ESMPy/src/esmpy/api/field.py similarity index 75% rename from src/addon/ESMPy/src/ESMF/api/field.py rename to src/addon/ESMPy/src/esmpy/api/field.py index 1b19d37724..9704a419ed 100755 --- a/src/addon/ESMPy/src/ESMF/api/field.py +++ b/src/addon/ESMPy/src/esmpy/api/field.py @@ -6,63 +6,63 @@ #### IMPORT LIBRARIES ######################################################### -from ESMF.api.grid import * -from ESMF.api.mesh import * -from ESMF.api.locstream import * -from ESMF.util.esmpyarray import * +from esmpy.api.grid import * +from esmpy.api.mesh import * +from esmpy.api.locstream import * +from esmpy.util.esmpyarray import * #### Field class ############################################################## [node, element] = [0, 1] class Field(object): """ - The :class:`~ESMF.api.field.Field` class is a Python wrapper object for the ESMF Field. + The :class:`~esmpy.api.field.Field` class is a Python wrapper object for the ESMF Field. The individual values of all data arrays are referenced to those of the underlying Fortran ESMF object. - A :class:`~ESMF.api.field.Field` represents a physical field, such as temperature. The :class:`~ESMF.api.field.Field` class + A :class:`~esmpy.api.field.Field` represents a physical field, such as temperature. The :class:`~esmpy.api.field.Field` class contains distributed and discretized field data, a reference to its - associated grid, and metadata. The :class:`~ESMF.api.field.Field` class stores the grid staggering + associated grid, and metadata. The :class:`~esmpy.api.field.Field` class stores the grid staggering for that physical field. This is the relationship of how the data array of a field maps onto a grid (e.g. one item per cell located at the cell center, one item per cell located at the NW corner, one item per cell vertex, etc.). - This means that different :class:`Fields ` which are on the same underlying :class:`~ESMF.api.grid.Grid` but - have different staggerings can share the same :class:`~ESMF.api.grid.Grid` object without needing to + This means that different :class:`Fields ` which are on the same underlying :class:`~esmpy.api.grid.Grid` but + have different staggerings can share the same :class:`~esmpy.api.grid.Grid` object without needing to replicate it multiple times. Refer to the Field Class of the `ESMF Reference Manual `_ for more information. - The following parameters are used to create a :class:`~ESMF.api.field.Field` - from a :class:`~ESMF.api.grid.Grid`, :class:`~ESMF.api.mesh.Mesh` or - :class:`~ESMF.api.locstream.LocStream`. + The following parameters are used to create a :class:`~esmpy.api.field.Field` + from a :class:`~esmpy.api.grid.Grid`, :class:`~esmpy.api.mesh.Mesh` or + :class:`~esmpy.api.locstream.LocStream`. *REQUIRED:* - :param :class:`~ESMF.api.grid.Grid`/Mesh/:class:`~ESMF.api.locstream.LocStream` grid: A :class:`~ESMF.api.grid.Grid`, - :class:`~ESMF.api.mesh.Mesh` or :class:`~ESMF.api.locstream.LocStream` + :param :class:`~esmpy.api.grid.Grid`/Mesh/:class:`~esmpy.api.locstream.LocStream` grid: A :class:`~esmpy.api.grid.Grid`, + :class:`~esmpy.api.mesh.Mesh` or :class:`~esmpy.api.locstream.LocStream` with coordinates allocated on at least one stagger location. *OPTIONAL:* :param str name: An optional user friendly name for the - :class:`~ESMF.api.field.Field`. - :param TypeKind typekind: Type of the :class:`~ESMF.api.field.Field` - data. If ``None``, defaults to :attr:`~ESMF.api.constants.TypeKind.R8`. + :class:`~esmpy.api.field.Field`. + :param TypeKind typekind: Type of the :class:`~esmpy.api.field.Field` + data. If ``None``, defaults to :attr:`~esmpy.api.constants.TypeKind.R8`. :param StaggerLoc staggerloc: The stagger location of the - :class:`~ESMF.api.field.Field` data, only specify this argument when - using a :class:`~ESMF.api.grid.Grid`. - If ``None``, defaults to :attr:`~ESMF.api.constants.StaggerLoc.CENTER` - in 2D and :attr:`~ESMF.api.constants.StaggerLoc.CENTER_VCENTER` in 3D. + :class:`~esmpy.api.field.Field` data, only specify this argument when + using a :class:`~esmpy.api.grid.Grid`. + If ``None``, defaults to :attr:`~esmpy.api.constants.StaggerLoc.CENTER` + in 2D and :attr:`~esmpy.api.constants.StaggerLoc.CENTER_VCENTER` in 3D. :param MeshLoc meshloc: The mesh location of the - :class:`~ESMF.api.field.Field` data, only specify this argument when - using a :class:`~ESMF.api.mesh.Mesh` - if ``None``, defaults to :attr:`~ESMF.api.constants.MeshLoc.NODE`. + :class:`~esmpy.api.field.Field` data, only specify this argument when + using a :class:`~esmpy.api.mesh.Mesh` + if ``None``, defaults to :attr:`~esmpy.api.constants.MeshLoc.NODE`. :param tuple ndbounds: The number of entries in an extra - :class:`~ESMF.api.field.Field` dimension. This is represented as a + :class:`~esmpy.api.field.Field` dimension. This is represented as a single value, a list or a tuple containing the number of entries for - each desired extra dimension of the :class:`~ESMF.api.field.Field`. The + each desired extra dimension of the :class:`~esmpy.api.field.Field`. The time dimension must be last, following Fortran indexing conventions. """ @@ -222,8 +222,8 @@ def __repr__(self): @property def data(self): """ - :rtype: :attr:`~ESMF.api.constants.TypeKind` - :return: The data of the :class:`~ESMF.api.field.Field` + :rtype: :attr:`~esmpy.api.constants.TypeKind` + :return: The data of the :class:`~esmpy.api.field.Field` """ return self._data @@ -240,10 +240,10 @@ def finalized(self): @property def grid(self): """ - :rtype: :class:`~ESMF.api.grid.Grid`, :class:`~ESMF.api.mesh.Mesh`, or - :class:`~ESMF.api.locstream.LocStream` + :rtype: :class:`~esmpy.api.grid.Grid`, :class:`~esmpy.api.mesh.Mesh`, or + :class:`~esmpy.api.locstream.LocStream` :return: The discretization object upon which the - :class:`~ESMF.api.field.Field` is built. + :class:`~esmpy.api.field.Field` is built. """ return self._grid @@ -251,7 +251,7 @@ def grid(self): def lower_bounds(self): """ :rtype: ndarray - :return: The lower bounds of the :class:`~ESMF.api.field.Field`. + :return: The lower bounds of the :class:`~esmpy.api.field.Field`. """ return self._lower_bounds @@ -267,7 +267,7 @@ def meta(self): def name(self): """ :rtype: str - :return: the name of the :class:`~ESMF.api.field.Field`. + :return: the name of the :class:`~esmpy.api.field.Field`. """ return self._name @@ -276,7 +276,7 @@ def ndbounds(self): """ :rtype: list :return: The bounds of the extra dimensions in the - :class:`~ESMF.api.field.Field`. + :class:`~esmpy.api.field.Field`. """ return self._ndbounds @@ -284,16 +284,16 @@ def ndbounds(self): def rank(self): """ :rtype: int - :return: The rank of the :class:`~ESMF.api.field.Field`. + :return: The rank of the :class:`~esmpy.api.field.Field`. """ return self._rank @property def staggerloc(self): """ - :rtype: :attr:`~ESMF.api.constants.StaggerLoc` or - :attr:`~ESMF.api.constants.MeshLoc` - :return: The location upon which the :class:`~ESMF.api.field.Field` + :rtype: :attr:`~esmpy.api.constants.StaggerLoc` or + :attr:`~esmpy.api.constants.MeshLoc` + :return: The location upon which the :class:`~esmpy.api.field.Field` is built. """ return self._staggerloc @@ -303,15 +303,15 @@ def struct(self): """ :rtype: pointer :return: A pointer to the underlying ESMF allocation for this - :class:`~ESMF.api.field.Field`. + :class:`~esmpy.api.field.Field`. """ return self._struct @property def type(self): """ - :rtype: :attr:`~ESMF.api.constants.TypeKind` - :return: The type of the data in the :class:`~ESMF.api.field.Field`. + :rtype: :attr:`~esmpy.api.constants.TypeKind` + :return: The type of the data in the :class:`~esmpy.api.field.Field`. """ return self._type @@ -319,7 +319,7 @@ def type(self): def upper_bounds(self): """ :rtype: ndarray - :return: The upper bounds of the :class:`~ESMF.api.field.Field`. + :return: The upper bounds of the :class:`~esmpy.api.field.Field`. """ return self._upper_bounds @@ -328,15 +328,15 @@ def xd(self): """ :rtype: int :return: The number of extra (ungridded) dimensions of the - :class:`~ESMF.api.field.Field`. + :class:`~esmpy.api.field.Field`. """ return self._xd def copy(self): """ - Copy a :class:`~ESMF.api.field.Field` in an ESMF-safe manner. + Copy a :class:`~esmpy.api.field.Field` in an ESMF-safe manner. - :return: A :class:`~ESMF.api.field.Field` shallow copy. + :return: A :class:`~esmpy.api.field.Field` shallow copy. """ # shallow copy ret = copy(self) @@ -347,7 +347,7 @@ def copy(self): def destroy(self): """ - Release the memory associated with a :class:`~ESMF.api.field.Field`. + Release the memory associated with a :class:`~esmpy.api.field.Field`. """ if hasattr(self, '_finalized'): if self._finalized == False: @@ -356,9 +356,9 @@ def destroy(self): def get_area(self): """ - Initialize an existing :class:`~ESMF.api.field.Field` with the areas of - the cells of the underlying :class:`~ESMF.api.grid.Grid` or - :class:`~ESMF.api.mesh.Mesh`. + Initialize an existing :class:`~esmpy.api.field.Field` with the areas of + the cells of the underlying :class:`~esmpy.api.grid.Grid` or + :class:`~esmpy.api.mesh.Mesh`. """ # call into the ctypes layer @@ -366,7 +366,7 @@ def get_area(self): def read(self, filename, variable, timeslice=None): """ - Read data into an existing :class:`~ESMF.api.field.Field` from a + Read data into an existing :class:`~esmpy.api.field.Field` from a CF-compliant NetCDF file. :note: This interface is not supported when ESMF is built with @@ -385,7 +385,7 @@ def read(self, filename, variable, timeslice=None): :param int timeslice: The number of timeslices to read. """ - import ESMF.api.constants as constants + import esmpy.api.constants as constants if constants._ESMF_COMM == constants._ESMF_COMM_MPIUNI: raise ImportError("Field.Read() requires PIO and does not work if ESMF has not been built with MPI support") diff --git a/src/addon/ESMPy/src/ESMF/api/grid.py b/src/addon/ESMPy/src/esmpy/api/grid.py similarity index 89% rename from src/addon/ESMPy/src/ESMF/api/grid.py rename to src/addon/ESMPy/src/esmpy/api/grid.py index 299900f4d1..dda0bb53fe 100755 --- a/src/addon/ESMPy/src/ESMF/api/grid.py +++ b/src/addon/ESMPy/src/esmpy/api/grid.py @@ -9,25 +9,25 @@ import warnings from copy import copy -from ESMF.api.esmpymanager import * -from ESMF.util.esmpyarray import ndarray_from_esmf -import ESMF.api.constants as constants -from ESMF.util.slicing import get_formatted_slice, get_none_or_slice, get_none_or_bound, get_none_or_ssslice +from esmpy.api.esmpymanager import * +from esmpy.util.esmpyarray import ndarray_from_esmf +import esmpy.api.constants as constants +from esmpy.util.slicing import get_formatted_slice, get_none_or_slice, get_none_or_bound, get_none_or_ssslice #### Grid class ######################################################### class Grid(object): """ - The :class:`~ESMF.api.grid.Grid` class is a Python wrapper object for the ESMF Grid. The individual + The :class:`~esmpy.api.grid.Grid` class is a Python wrapper object for the ESMF Grid. The individual values of all coordinate and mask arrays are referenced to those of the underlying Fortran ESMF object. - The :class:`~ESMF.api.grid.Grid` class is used to describe the geometry and + The :class:`~esmpy.api.grid.Grid` class is used to describe the geometry and discretization of logically rectangular physical grids. It also contains the description of the underlying topology and decomposition of the physical grid across the available computational resources. The most frequent use of - the :class:`~ESMF.api.grid.Grid` class is to describe physical grids in user + the :class:`~esmpy.api.grid.Grid` class is to describe physical grids in user code so that sufficient information is available to perform regridding operations. @@ -35,9 +35,9 @@ class Grid(object): `ESMF Reference Manual `_ for more information. - A :class:`~ESMF.api.grid.Grid` can be created in two different ways, as a - :class:`~ESMF.api.grid.Grid` in memory, or from SCRIP formatted or CF compliant GRIDSPEC file. The - arguments for each type of :class:`~ESMF.api.grid.Grid` creation are + A :class:`~esmpy.api.grid.Grid` can be created in two different ways, as a + :class:`~esmpy.api.grid.Grid` in memory, or from SCRIP formatted or CF compliant GRIDSPEC file. The + arguments for each type of :class:`~esmpy.api.grid.Grid` creation are outlined below. **Created in-memory:** @@ -56,30 +56,30 @@ class Grid(object): :param int pole_dim: The pole dimension ``0`` or ``1``. If ``None``, defaults to ``1``. :param CoordSys coord_sys: Coordinate system for the - :class:`~ESMF.api.grid.Grid`. - If ``None``, defaults to :attr:`~ESMF.api.constants.CoordSys.SPH_DEG`. - :param TypeKind coord_typekind: Type of the :class:`~ESMF.api.grid.Grid` + :class:`~esmpy.api.grid.Grid`. + If ``None``, defaults to :attr:`~esmpy.api.constants.CoordSys.SPH_DEG`. + :param TypeKind coord_typekind: Type of the :class:`~esmpy.api.grid.Grid` coordinates. - If ``None``, defaults to :attr:`~ESMF.api.constants.TypeKind.R8`. + If ``None``, defaults to :attr:`~esmpy.api.constants.TypeKind.R8`. **Created either from file or in-memory:** :param StaggerLoc staggerloc: The stagger location of the coordinate values. - If ``None``, defaults to :attr:`~ESMF.api.constants.StaggerLoc.CENTER` - in 2D and :attr:`~ESMF.api.constants.StaggerLoc.CENTER_VCENTER` in 3D. + If ``None``, defaults to :attr:`~esmpy.api.constants.StaggerLoc.CENTER` + in 2D and :attr:`~esmpy.api.constants.StaggerLoc.CENTER_VCENTER` in 3D. :param PoleKind pole_kind: Two item list which specifies the type of connection which occurs at the pole. The first value specifies the connection that occurs at the minimum end of the pole dimension. The second value specifies the connection that occurs at the maximum end of the pole dimension. - If ``None``, defaults to :attr:`~ESMF.api.constants.PoleKind.MONOPOLE`. + If ``None``, defaults to :attr:`~esmpy.api.constants.PoleKind.MONOPOLE`. **Created from file:** *REQUIRED:* :param str filename: The name of the NetCDF grid file. - :param FileFormat filetype: The grid :attr:`~ESMF.api.constants.FileFormat`. + :param FileFormat filetype: The grid :attr:`~esmpy.api.constants.FileFormat`. *OPTIONAL:* @@ -94,7 +94,7 @@ class Grid(object): :param bool add_mask: Set to ``True`` to generate the mask using the ``missing_value`` attribute defined in ``varname``. This argument is only supported with filetype - :attr:`~ESMF.api.constants.FileFormat.GRIDSPEC`. + :attr:`~esmpy.api.constants.FileFormat.GRIDSPEC`. Defaults to ``False``. :param str varname: If add_mask is ``True``, provide a variable name stored in the grid file and the mask will be generated using the missing value @@ -102,12 +102,12 @@ class Grid(object): variable has to be the longitude and the latitude dimension and the mask is derived from the first 2D values of this variable even if this data is a 3D, or 4D array. This argument is only supported with - filetype :attr:`~ESMF.api.constants.FileFormat.GRIDSPEC`. + filetype :attr:`~esmpy.api.constants.FileFormat.GRIDSPEC`. Defaults to ``None``. :param list coord_names: A two-element array containing the longitude and latitude variable names in a GRIDSPEC file if there are multiple coordinates defined in the file. This argument is only supported with - filetype :attr:`~ESMF.api.constants.FileFormat.GRIDSPEC`. + filetype :attr:`~esmpy.api.constants.FileFormat.GRIDSPEC`. Defaults to ``None``. **Cubed sphere:** @@ -130,7 +130,7 @@ class Grid(object): PET count. For instance, if the total PET count is 16, the total DE count will be 12 with each tile decomposed into 1x2 blocks. The 12 DEs are mapped to the first 12 PETs and the remaining 4 PETs have no DEs locally. - :param str name: The name of the :class:`~ESMF.api.grid.Grid`. + :param str name: The name of the :class:`~esmpy.api.grid.Grid`. """ # :param list decompFlagPTile: # :param list deLabelList: @@ -561,8 +561,8 @@ def __repr__(self): def area(self): """ :rtype: A list of numpy arrays with an entry for every stagger location - of the :class:`~ESMF.api.grid.Grid`. - :return: The :class:`~ESMF.api.grid.Grid` cell areas represented as + of the :class:`~esmpy.api.grid.Grid`. + :return: The :class:`~esmpy.api.grid.Grid` cell areas represented as numpy arrays of floats of size given by ``upper_bounds - lower_bounds``. """ @@ -572,8 +572,8 @@ def area(self): @property def areatype(self): """ - :rtype: :attr:`~ESMF.api.constants.TypeKind` - :return: The ESMF typekind of the :class:`~ESMF.api.grid.Grid` cell + :rtype: :attr:`~esmpy.api.constants.TypeKind` + :return: The ESMF typekind of the :class:`~esmpy.api.grid.Grid` cell areas. """ @@ -584,10 +584,10 @@ def coords(self): """ :rtype: 2D list of numpy arrays of size given by ``upper_bounds - lower_bounds``, where the first index represents - the stagger locations of the :class:`~ESMF.api.grid.Grid` and the + the stagger locations of the :class:`~esmpy.api.grid.Grid` and the second index represent the coordinate dimensions of the - :class:`~ESMF.api.grid.Grid`. - :return: The coordinates of the :class:`~ESMF.api.grid.Grid`. + :class:`~esmpy.api.grid.Grid`. + :return: The coordinates of the :class:`~esmpy.api.grid.Grid`. """ return self._coords @@ -595,8 +595,8 @@ def coords(self): @property def coord_sys(self): """ - :rtype: :attr:`~ESMF.api.constants.CoordSys` - :return: The coordinate system of the :class:`~ESMF.api.grid.Grid`. + :rtype: :attr:`~esmpy.api.constants.CoordSys` + :return: The coordinate system of the :class:`~esmpy.api.grid.Grid`. """ return self._coord_sys @@ -615,7 +615,7 @@ def finalized(self): def has_corners(self): """ :rtype: bool - :return: A boolean value to tell if the :class:`~ESMF.api.grid.Grid` + :return: A boolean value to tell if the :class:`~esmpy.api.grid.Grid` has corners allocated. """ @@ -625,8 +625,8 @@ def has_corners(self): def lower_bounds(self): """ :rtype: A list of numpy arrays with an entry for every stagger location - of the :class:`~ESMF.api.grid.Grid`. - :return: The lower bounds of the :class:`~ESMF.api.grid.Grid` + of the :class:`~esmpy.api.grid.Grid`. + :return: The lower bounds of the :class:`~esmpy.api.grid.Grid` represented as numpy arrays of ints of size given by ``upper_bounds - lower_bounds``. """ @@ -637,8 +637,8 @@ def lower_bounds(self): def mask(self): """ :rtype: A list of numpy arrays with an entry for every stagger location - of the :class:`~ESMF.api.grid.Grid`. - :return: The mask of the :class:`~ESMF.api.grid.Grid` represented as + of the :class:`~esmpy.api.grid.Grid`. + :return: The mask of the :class:`~esmpy.api.grid.Grid` represented as numpy arrays of ints of size given by ` `upper_bounds - lower_bounds``. """ @@ -649,8 +649,8 @@ def mask(self): def max_index(self): """ :rtype: A numpy array with as many values as the - :class:`~ESMF.api.grid.Grid` rank. - :return: The number of :class:`~ESMF.api.grid.Grid` cells in each + :class:`~esmpy.api.grid.Grid` rank. + :return: The number of :class:`~esmpy.api.grid.Grid` cells in each dimension of the grid. """ @@ -669,7 +669,7 @@ def meta(self): def name(self): """ :rtype: str - :return: The name of the :class:`~ESMF.api.grid.Grid`. + :return: The name of the :class:`~esmpy.api.grid.Grid`. """ return self._name @@ -679,7 +679,7 @@ def ndims(self): """ :rtype: int :return: The rank of the coordinate arrays of the - :class:`~ESMF.api.grid.Grid`. + :class:`~esmpy.api.grid.Grid`. """ return self._ndims @@ -689,7 +689,7 @@ def num_peri_dims(self): """ :rtype: int :return: The total number of periodic dimensions in the - :class:`~ESMF.api.grid.Grid`. + :class:`~esmpy.api.grid.Grid`. """ return self._num_peri_dims @@ -699,7 +699,7 @@ def decount(self): """ :rtype: int :return: The total number of tiles in the - :class:`~ESMF.api.grid.Grid`. + :class:`~esmpy.api.grid.Grid`. """ return self._decount @@ -708,7 +708,7 @@ def decount(self): def periodic_dim(self): """ :rtype: int - :return: The periodic dimension of the :class:`~ESMF.api.grid.Grid` + :return: The periodic dimension of the :class:`~esmpy.api.grid.Grid` (e.g. ``0`` for ``x`` or ``longitude``, ``1`` for ``y`` or ``latitude``, etc.). """ @@ -719,7 +719,7 @@ def periodic_dim(self): def pole_dim(self): """ :rtype: int - :return: The pole dimension of the :class:`~ESMF.api.grid.Grid` + :return: The pole dimension of the :class:`~esmpy.api.grid.Grid` (e.g. ``0`` for ``x`` or ``longitude``, ``1`` for ``y`` or ``latitude``, etc.). """ @@ -730,8 +730,8 @@ def pole_dim(self): def pole_kind(self): """ :rtype: A numpy array with as many values as the - :class:`~ESMF.api.grid.Grid` has poles. - :return: The number of connections at each pole of the :class:`~ESMF.api.grid.Grid`. + :class:`~esmpy.api.grid.Grid` has poles. + :return: The number of connections at each pole of the :class:`~esmpy.api.grid.Grid`. """ return self._pole_kind @@ -740,7 +740,7 @@ def pole_kind(self): def rank(self): """ :rtype: int - :return: The rank of the :class:`~ESMF.api.grid.Grid`. + :return: The rank of the :class:`~esmpy.api.grid.Grid`. """ return self._rank @@ -749,8 +749,8 @@ def rank(self): def size(self): """ :rtype: A list of numpy arrays with an entry for every stagger location - of the :class:`~ESMF.api.grid.Grid`. - :return: The size of the :class:`~ESMF.api.grid.Grid` represented as + of the :class:`~esmpy.api.grid.Grid`. + :return: The size of the :class:`~esmpy.api.grid.Grid` represented as numpy arrays of ints of size given by ``upper_bounds - lower_bounds``. """ @@ -762,7 +762,7 @@ def staggerloc(self): """ :rtype: list of bools :return: The stagger locations that have been allocated for the - :class:`~ESMF.api.grid.Grid`. + :class:`~esmpy.api.grid.Grid`. """ return self._staggerloc @@ -772,7 +772,7 @@ def struct(self): """ :rtype: pointer :return: A pointer to the underlying ESMF allocation for the - :class:`~ESMF.api.grid.Grid`. + :class:`~esmpy.api.grid.Grid`. """ return self._struct @@ -780,8 +780,8 @@ def struct(self): @property def type(self): """ - :rtype: :attr:`~ESMF.api.constants.TypeKind` - :return: The ESMF typekind of the :class:`~ESMF.api.grid.Grid` + :rtype: :attr:`~esmpy.api.constants.TypeKind` + :return: The ESMF typekind of the :class:`~esmpy.api.grid.Grid` coordinates. """ return self._type @@ -790,8 +790,8 @@ def type(self): def upper_bounds(self): """ :rtype: A list of numpy arrays with an entry for every stagger location - of the :class:`~ESMF.api.grid.Grid`. - :return: The upper bounds of the :class:`~ESMF.api.grid.Grid` + of the :class:`~esmpy.api.grid.Grid`. + :return: The upper bounds of the :class:`~esmpy.api.grid.Grid` represented as numpy arrays of ints of size given by ``upper_bounds - lower_bounds``. """ @@ -799,20 +799,20 @@ def upper_bounds(self): def add_coords(self, staggerloc=None, coord_dim=None, from_file=False): """ - Add coordinates to the :class:`~ESMF.api.grid.Grid` at the specified + Add coordinates to the :class:`~esmpy.api.grid.Grid` at the specified stagger location. :param StaggerLoc staggerloc: The stagger location of the coordinate values. If ``None``, defaults to - :attr:`~ESMF.api.constants.StaggerLoc.CENTER` - in 2D and :attr:`~ESMF.api.constants.StaggerLoc.CENTER_VCENTER` in + :attr:`~esmpy.api.constants.StaggerLoc.CENTER` + in 2D and :attr:`~esmpy.api.constants.StaggerLoc.CENTER_VCENTER` in 3D. :param int coord_dim: The dimension number of the coordinates to return e.g. ``[x, y, z] = (0, 1, 2)``, or ``[lon, lat] = (0, 1)`` (coordinates will not be returned if coord_dim is not specified and staggerlocs is a list with more than one element). :param bool from_file: Boolean for internal use to determine whether the - :class:`~ESMF.api.grid.Grid` has already been created from file. + :class:`~esmpy.api.grid.Grid` has already been created from file. :return: A numpy array of coordinate values if staggerloc and coord_dim are specified, otherwise return None. @@ -844,23 +844,23 @@ def add_coords(self, staggerloc=None, coord_dim=None, from_file=False): def add_item(self, item, staggerloc=None, from_file=False): """ - Allocate space for a :class:`~ESMF.api.grid.Grid` item (mask or areas) + Allocate space for a :class:`~esmpy.api.grid.Grid` item (mask or areas) at a specified stagger location. *REQUIRED:* - :param GridItem item: The :attr:`~ESMF.api.constants.GridItem` to + :param GridItem item: The :attr:`~esmpy.api.constants.GridItem` to allocate. *OPTIONAL:* :param StaggerLoc staggerloc: The stagger location of the item values. If ``None``, defaults to - :attr:`~ESMF.api.constants.StaggerLoc.CENTER` - in 2D and :attr:`~ESMF.api.constants.StaggerLoc.CENTER_VCENTER` in + :attr:`~esmpy.api.constants.StaggerLoc.CENTER` + in 2D and :attr:`~esmpy.api.constants.StaggerLoc.CENTER_VCENTER` in 3D. :param bool from_file: Boolean for internal use to determine whether the - :class:`~ESMF.api.grid.Grid` has already been created from file. + :class:`~esmpy.api.grid.Grid` has already been created from file. :return: A numpy array of the mask or area values if a single staggerloc is given, otherwise return None. @@ -905,9 +905,9 @@ def add_item(self, item, staggerloc=None, from_file=False): def copy(self): """ - Copy a :class:`~ESMF.api.grid.Grid` in an ESMF-safe manner. + Copy a :class:`~esmpy.api.grid.Grid` in an ESMF-safe manner. - :return: A :class:`~ESMF.api.grid.Grid` shallow copy. + :return: A :class:`~esmpy.api.grid.Grid` shallow copy. """ # shallow copy ret = copy(self) @@ -918,7 +918,7 @@ def copy(self): def destroy(self): """ - Release the memory associated with a :class:`~ESMF.api.grid.Grid`. + Release the memory associated with a :class:`~esmpy.api.grid.Grid`. """ if hasattr(self, '_finalized'): if not self._finalized: @@ -929,7 +929,7 @@ def get_coords(self, coord_dim, staggerloc=None): """ Return a numpy array of coordinates at a specified stagger location. The returned array is NOT a copy, it is - directly aliased to the underlying memory allocated by ESMF. + directly aliased to the underlying memory allocated by esmpy. *REQUIRED:* @@ -942,8 +942,8 @@ def get_coords(self, coord_dim, staggerloc=None): :param StaggerLoc staggerloc: The stagger location of the coordinate values. If ``None``, defaults to - :attr:`~ESMF.api.constants.StaggerLoc.CENTER` - in 2D and :attr:`~ESMF.api.constants.StaggerLoc.CENTER_VCENTER` in + :attr:`~esmpy.api.constants.StaggerLoc.CENTER` + in 2D and :attr:`~esmpy.api.constants.StaggerLoc.CENTER_VCENTER` in 3D. :return: A numpy array of coordinate values at the specified staggerloc. @@ -967,19 +967,19 @@ def get_item(self, item, staggerloc=None): """ Return a numpy array of item values at a specified stagger location. The returned array is NOT a copy, it is - directly aliased to the underlying memory allocated by ESMF. + directly aliased to the underlying memory allocated by esmpy. *REQUIRED:* - :param GridItem item: The :attr:`~ESMF.api.constants.GridItem` to + :param GridItem item: The :attr:`~esmpy.api.constants.GridItem` to return. *OPTIONAL:* :param StaggerLoc staggerloc: The stagger location of the item values. If ``None``, defaults to - :attr:`~ESMF.api.constants.StaggerLoc.CENTER` in 2D and - :attr:`~ESMF.api.constants.StaggerLoc.CENTER_VCENTER` in 3D. + :attr:`~esmpy.api.constants.StaggerLoc.CENTER` in 2D and + :attr:`~esmpy.api.constants.StaggerLoc.CENTER_VCENTER` in 3D. :return: A numpy array of mask or area values at the specified staggerloc. """ @@ -1177,8 +1177,8 @@ def _write_(self, filename, staggerloc=None): :param StaggerLoc staggerloc: The stagger location of the item values. If ``None``, defaults to - :attr:`~ESMF.api.constants.StaggerLoc.CENTER` in 2D and - :attr:`~ESMF.api.constants.StaggerLoc.CENTER_VCENTER` in 3D. + :attr:`~esmpy.api.constants.StaggerLoc.CENTER` in 2D and + :attr:`~esmpy.api.constants.StaggerLoc.CENTER_VCENTER` in 3D. """ # handle the default case diff --git a/src/addon/ESMPy/src/ESMF/api/locstream.py b/src/addon/ESMPy/src/esmpy/api/locstream.py similarity index 79% rename from src/addon/ESMPy/src/ESMF/api/locstream.py rename to src/addon/ESMPy/src/esmpy/api/locstream.py index 07a10a472d..e5d5982140 100644 --- a/src/addon/ESMPy/src/ESMF/api/locstream.py +++ b/src/addon/ESMPy/src/esmpy/api/locstream.py @@ -6,25 +6,25 @@ #### IMPORT LIBRARIES ######################################################### -from ESMF.api.esmpymanager import * -from ESMF.util.esmpyarray import ndarray_from_esmf -import ESMF.api.constants as constants -from ESMF.util.slicing import get_formatted_slice +from esmpy.api.esmpymanager import * +from esmpy.util.esmpyarray import ndarray_from_esmf +import esmpy.api.constants as constants +from esmpy.util.slicing import get_formatted_slice #### LocStream class ######################################################### class LocStream(dict): """ - The :class:`~ESMF.api.locstream.LocStream` class is a Python wrapper object for the ESMF LocStream. - :class:`~ESMF.api.locstream.LocStream` is a derived type of a Python dictionary. + The :class:`~esmpy.api.locstream.LocStream` class is a Python wrapper object for the ESMF LocStream. + :class:`~esmpy.api.locstream.LocStream` is a derived type of a Python dictionary. The individual values of all key arrays are referenced to those of the underlying Fortran ESMF object. - A :class:`~ESMF.api.locstream.LocStream` is used to represent the locations of a + A :class:`~esmpy.api.locstream.LocStream` is used to represent the locations of a set of data points. The values of the data points are stored within a - :class:`~ESMF.api.field.Field` created using the :class:`~ESMF.api.locstream.LocStream`. + :class:`~esmpy.api.field.Field` created using the :class:`~esmpy.api.locstream.LocStream`. In the data assimilation world, location streams can be thought of as a set of observations. Their locations are generally described using Cartesian @@ -38,7 +38,7 @@ class LocStream(dict): `ESMF Reference Manual `_ for more information. - :class:`~ESMF.api.locstream.LocStream` follows standard dictionary syntax. For example: + :class:`~esmpy.api.locstream.LocStream` follows standard dictionary syntax. For example: >>> locstream["ESMF:X"] = [1, 2, 3] >>> x = locstream["ESMF:X"] @@ -54,29 +54,29 @@ class LocStream(dict): .. note:: - Mask must be of type :attr:`~ESMF.api.constants.TypeKind.I4`, - and coordinates must by of type :attr:`~ESMF.api.constants.TypeKind.R8`. + Mask must be of type :attr:`~esmpy.api.constants.TypeKind.I4`, + and coordinates must by of type :attr:`~esmpy.api.constants.TypeKind.R8`. - For ESMF to be able to recognize coordinates specified in a :class:`~ESMF.api.locstream.LocStream` key + For ESMF to be able to recognize coordinates specified in a :class:`~esmpy.api.locstream.LocStream` key they need to be named with the appropriate identifiers. The particular identifiers depend on the coordinate system (i.e. ``coord_sys`` argument) - used to create the :class:`~ESMF.api.locstream.LocStream`. + used to create the :class:`~esmpy.api.locstream.LocStream`. The valid values are: ============================================ =========== =========== =========== Coordinate System dimension 1 dimension 2 dimension 3 ============================================ =========== =========== =========== - :attr:`~ESMF.api.constants.CoordSys.SPH_DEG` ESMF:Lon ESMF:Lat ESMF:Radius - :attr:`~ESMF.api.constants.CoordSys.SPH_RAD` ESMF:Lon ESMF:Lat ESMF:Radius - :attr:`~ESMF.api.constants.CoordSys.CART` ESMF:X ESMF:Y ESMF:Z + :attr:`~esmpy.api.constants.CoordSys.SPH_DEG` ESMF:Lon ESMF:Lat ESMF:Radius + :attr:`~esmpy.api.constants.CoordSys.SPH_RAD` ESMF:Lon ESMF:Lat ESMF:Radius + :attr:`~esmpy.api.constants.CoordSys.CART` ESMF:X ESMF:Y ESMF:Z ============================================ =========== =========== =========== :param int location_count: The number of points in this stream. :param CoordSys coord_sys: Coordinate system for the location stream. - If ``None``, defaults to :attr:`~ESMF.api.constants.CoordSys.SPH_DEG`. + If ``None``, defaults to :attr:`~esmpy.api.constants.CoordSys.SPH_DEG`. :param str name: Optional name for the location stream. - :param bool esmf: Internal parameter controlling shallow copying by ESMF. + :param bool esmf: Internal parameter controlling shallow copying by esmpy. """ @initialize @@ -189,7 +189,7 @@ def finalized(self): def lower_bounds(self): """ :rtype: int - :return: The lower bounds of the :class:`~ESMF.api.locstream.LocStream`. + :return: The lower bounds of the :class:`~esmpy.api.locstream.LocStream`. """ return self._lower_bounds @@ -198,7 +198,7 @@ def lower_bounds(self): def mask(self): """ :rtype: list - :return: The mask of the :class:`~ESMF.api.locstream.LocStream`. + :return: The mask of the :class:`~esmpy.api.locstream.LocStream`. """ return self.get("ESMF:Mask") @@ -216,7 +216,7 @@ def meta(self): def name(self): """ :rtype: str - :return: The name of the :class:`~ESMF.api.locstream.LocStream`. + :return: The name of the :class:`~esmpy.api.locstream.LocStream`. """ return self._name @@ -225,7 +225,7 @@ def name(self): def rank(self): """ :rtype: int - :return: The rank of the :class:`~ESMF.api.locstream.LocStream`. + :return: The rank of the :class:`~esmpy.api.locstream.LocStream`. """ return self._rank @@ -235,7 +235,7 @@ def singlestagger(self): """ :rtype: bool :return: A boolean value to tell if this - :class:`~ESMF.api.locstream.LocStream` has been sliced. + :class:`~esmpy.api.locstream.LocStream` has been sliced. """ return self._singlestagger @@ -244,7 +244,7 @@ def singlestagger(self): def size(self): """ :rtype: int - :return: The size of the :class:`~ESMF.api.locstream.LocStream`. + :return: The size of the :class:`~esmpy.api.locstream.LocStream`. """ return self._size @@ -254,7 +254,7 @@ def struct(self): """ :rtype: pointer :return: A pointer to the underlying ESMF allocation for this - :class:`~ESMF.api.locstream.LocStream`. + :class:`~esmpy.api.locstream.LocStream`. """ return self._struct @@ -263,16 +263,16 @@ def struct(self): def upper_bounds(self): """ :rtype: int - :return: The upper bounds of the :class:`~ESMF.api.locstream.LocStream`. + :return: The upper bounds of the :class:`~esmpy.api.locstream.LocStream`. """ return self._upper_bounds def copy(self): """ - Copy a :class:`~ESMF.api.locstream.LocStream` in an ESMF-safe manner. + Copy a :class:`~esmpy.api.locstream.LocStream` in an ESMF-safe manner. - :return: A :class:`~ESMF.api.locstream.LocStream` shallow copy. + :return: A :class:`~esmpy.api.locstream.LocStream` shallow copy. """ # shallow copy ret = LocStream(self._size, name=self._name, esmf=False) @@ -292,7 +292,7 @@ def copy(self): def destroy(self): """ Release the memory associated with a - :class:`~ESMF.api.locstream.LocStream`. + :class:`~esmpy.api.locstream.LocStream`. """ if hasattr(self, '_finalized'): @@ -310,4 +310,4 @@ def _add_(self, key_name, typekind=None): # create a numpy array out of the pointer keyvals = ndarray_from_esmf(key_ptr, typekind, (self.size,)) - return keyvals \ No newline at end of file + return keyvals diff --git a/src/addon/ESMPy/src/ESMF/api/mesh.py b/src/addon/ESMPy/src/esmpy/api/mesh.py similarity index 81% rename from src/addon/ESMPy/src/ESMF/api/mesh.py rename to src/addon/ESMPy/src/esmpy/api/mesh.py index a2ff3e9e12..7bfc1cdbff 100755 --- a/src/addon/ESMPy/src/ESMF/api/mesh.py +++ b/src/addon/ESMPy/src/esmpy/api/mesh.py @@ -8,12 +8,12 @@ from copy import copy -from ESMF.api.constants import * -from ESMF.interface.cbindings import * -from ESMF.util.decorators import initialize +from esmpy.api.constants import * +from esmpy.interface.cbindings import * +from esmpy.util.decorators import initialize -from ESMF.api.esmpymanager import * -from ESMF.util.slicing import get_formatted_slice, get_none_or_slice, get_none_or_bound_list +from esmpy.api.esmpymanager import * +from esmpy.util.slicing import get_formatted_slice, get_none_or_slice, get_none_or_bound_list import warnings @@ -22,91 +22,91 @@ class Mesh(object): """ - The :class:`~ESMF.api.mesh.Mesh` class is a Python wrapper object for the ESMF Mesh. + The :class:`~esmpy.api.mesh.Mesh` class is a Python wrapper object for the ESMF Mesh. The individual values of all coordinate and mask arrays are referenced to those of the underlying Fortran ESMF object. The ESMF library provides a class for representing unstructured grids called - the :class:`~ESMF.api.mesh.Mesh`. :class:`Fields ` can be created on a :class:`~ESMF.api.mesh.Mesh` to hold data. :class:`Fields ` created on a - :class:`~ESMF.api.mesh.Mesh` can also be used as either the source or destination or both of a + the :class:`~esmpy.api.mesh.Mesh`. :class:`Fields ` can be created on a :class:`~esmpy.api.mesh.Mesh` to hold data. :class:`Fields ` created on a + :class:`~esmpy.api.mesh.Mesh` can also be used as either the source or destination or both of a regrididng operation which allows data to be moved between unstructured - grids. A :class:`~ESMF.api.mesh.Mesh` is constructed of nodes and elements. A node, also known as - a vertex or corner, is a part of a :class:`~ESMF.api.mesh.Mesh` which represents a single point. + grids. A :class:`~esmpy.api.mesh.Mesh` is constructed of nodes and elements. A node, also known as + a vertex or corner, is a part of a :class:`~esmpy.api.mesh.Mesh` which represents a single point. Coordinate information is set in a node. An element, also known as a cell, is a part of a mesh which represents a small region of space. Elements are described in terms of a connected set of nodes which represent locations - along their boundaries. :class:`~ESMF.api.field.Field` data may be located on either the nodes or - elements of a :class:`~ESMF.api.mesh.Mesh`. + along their boundaries. :class:`~esmpy.api.field.Field` data may be located on either the nodes or + elements of a :class:`~esmpy.api.mesh.Mesh`. Refer to the Mesh Class of the `ESMF Reference Manual `_ for more information. - An unstructured :class:`~ESMF.api.mesh.Mesh` can be created in two different ways, as a :class:`~ESMF.api.mesh.Mesh` in + An unstructured :class:`~esmpy.api.mesh.Mesh` can be created in two different ways, as a :class:`~esmpy.api.mesh.Mesh` in memory, or from a SCRIP formatted or CF compliant UGRID file. The arguments - for each type of :class:`~ESMF.api.mesh.Mesh` creation are outlined below. + for each type of :class:`~esmpy.api.mesh.Mesh` creation are outlined below. **Created in-memory:** - The in-memory :class:`~ESMF.api.mesh.Mesh` can be created manually in 3 steps: - 1. create the :class:`~ESMF.api.mesh.Mesh` (specifying ``parametric_dim`` and ``spatial_dim``), + The in-memory :class:`~esmpy.api.mesh.Mesh` can be created manually in 3 steps: + 1. create the :class:`~esmpy.api.mesh.Mesh` (specifying ``parametric_dim`` and ``spatial_dim``), 2. add nodes, 3. add elements. *REQUIRED:* :param int parametric_dim: the dimension of the topology of the - :class:`~ESMF.api.mesh.Mesh` (e.g. a :class:`~ESMF.api.mesh.Mesh` composed of squares would have a - parametric dimension of 2 and a :class:`~ESMF.api.mesh.Mesh` composed of cubes + :class:`~esmpy.api.mesh.Mesh` (e.g. a :class:`~esmpy.api.mesh.Mesh` composed of squares would have a + parametric dimension of 2 and a :class:`~esmpy.api.mesh.Mesh` composed of cubes would have a parametric dimension of 3). :param int spatial_dim: the number of coordinate dimensions needed to describe the locations of the nodes making up the - :class:`~ESMF.api.mesh.Mesh`. For a manifold the spatial dimension can be larger + :class:`~esmpy.api.mesh.Mesh`. For a manifold the spatial dimension can be larger than the parametric dimension (e.g. the 2D surface of a sphere in 3D space), but it cannot be smaller. *OPTIONAL:* :param CoordSys coord_sys: Coordinate system for the - :class:`~ESMF.api.mesh.Mesh`. - If ``None``, defaults to :attr:`~ESMF.api.constants.CoordSys.SPH_DEG`. + :class:`~esmpy.api.mesh.Mesh`. + If ``None``, defaults to :attr:`~esmpy.api.constants.CoordSys.SPH_DEG`. **Created from file:** - Note that :class:`Meshes ` created from file do not use the ``parametric_dim`` and + Note that :class:`Meshes ` created from file do not use the ``parametric_dim`` and ``spatial_dim`` parameters. *REQUIRED:* - :param str filename: the name of NetCDF file containing the :class:`~ESMF.api.mesh.Mesh`. + :param str filename: the name of NetCDF file containing the :class:`~esmpy.api.mesh.Mesh`. :param FileFormat filetype: the input - :attr:`~ESMF.api.constants.FileFormat` of the :class:`~ESMF.api.mesh.Mesh`. + :attr:`~esmpy.api.constants.FileFormat` of the :class:`~esmpy.api.mesh.Mesh`. *OPTIONAL:* :param bool convert_to_dual: a boolean value to specify if the - dual :class:`~ESMF.api.mesh.Mesh` should be calculated. Defaults to False. This + dual :class:`~esmpy.api.mesh.Mesh` should be calculated. Defaults to False. This argument is only supported with - :attr:`~ESMF.api.constants.FileFormat.SCRIP`. + :attr:`~esmpy.api.constants.FileFormat.SCRIP`. :param bool add_user_area: a boolean value to specify if an area property should be added to the mesh. This argument is only - supported for :attr:`~ESMF.api.constants.FileFormat.SCRIP` - or :attr:`~ESMF.api.constants.FileFormat.ESMFMESH`. + supported for :attr:`~esmpy.api.constants.FileFormat.SCRIP` + or :attr:`~esmpy.api.constants.FileFormat.ESMFMESH`. If ``None``, defaults to False. - :param str meshname: the name of the :class:`~ESMF.api.mesh.Mesh` metadata variable in + :param str meshname: the name of the :class:`~esmpy.api.mesh.Mesh` metadata variable in a UGRID file. This argument is only supported with - :attr:`~ESMF.api.constants.FileFormat.UGRID`. + :attr:`~esmpy.api.constants.FileFormat.UGRID`. If ``None``, defaults to the empty string. :param MeshLoc mask_flag: an enumerated integer that, if specified, tells whether a mask in a UGRID file should be - defined on the :attr:`~ESMF.api.constants.MeshLoc.NODE`s, or - :attr:`~ESMF.api.constants.MeshLoc.ELEMENT`s of the :class:`~ESMF.api.mesh.Mesh`. + defined on the :attr:`~esmpy.api.constants.MeshLoc.NODE`s, or + :attr:`~esmpy.api.constants.MeshLoc.ELEMENT`s of the :class:`~esmpy.api.mesh.Mesh`. This argument is only supported with - :attr:`~ESMF.api.constants.FileFormat.UGRID`. + :attr:`~esmpy.api.constants.FileFormat.UGRID`. If ``None``, defaults to no masking. :param str varname: a variable name for the mask in a UGRID file if mask_flag is specified. This argument is only supported - for :attr:`~ESMF.api.constants.FileFormat.UGRID`. + for :attr:`~esmpy.api.constants.FileFormat.UGRID`. If ``None``, defaults to the empty string. """ @@ -255,9 +255,9 @@ def __repr__(self): def area(self): """ :rtype: A two element list of numpy arrays to hold values for the nodes - and elements of the :class:`~ESMF.api.mesh.Mesh`. - :return: The :class:`~ESMF.api.mesh.Mesh` area represented as a numpy - array of floats of the same number of entries as :class:`~ESMF.api.mesh.Mesh` elements. + and elements of the :class:`~esmpy.api.mesh.Mesh`. + :return: The :class:`~esmpy.api.mesh.Mesh` area represented as a numpy + array of floats of the same number of entries as :class:`~esmpy.api.mesh.Mesh` elements. """ return self._area @@ -265,18 +265,18 @@ def area(self): def coords(self): """ :rtype: A two element list of numpy arrays to hold values for the nodes - and elements of the :class:`~ESMF.api.mesh.Mesh`. + and elements of the :class:`~esmpy.api.mesh.Mesh`. :return: The coordinates represented as a numpy array of floats - with a value for each node and/or element of the :class:`~ESMF.api.mesh.Mesh` - :class:`~ESMF.api.mesh.Mesh`. + with a value for each node and/or element of the :class:`~esmpy.api.mesh.Mesh` + :class:`~esmpy.api.mesh.Mesh`. """ return self._coords @property def coord_sys(self): """ - :rtype: :attr:`~ESMF.api.constants.CoordSys` - :return: The coordinate system of the :class:`~ESMF.api.mesh.Mesh`. + :rtype: :attr:`~esmpy.api.constants.CoordSys` + :return: The coordinate system of the :class:`~esmpy.api.mesh.Mesh`. """ return self._coord_sys @@ -321,9 +321,9 @@ def finalized(self): def mask(self): """ :rtype: A two element list of numpy arrays to hold values for the nodes - and elements of the :class:`~ESMF.api.mesh.Mesh`. + and elements of the :class:`~esmpy.api.mesh.Mesh`. :return: The masked values on the nodes and elements of the - :class:`~ESMF.api.mesh.Mesh`. + :class:`~esmpy.api.mesh.Mesh`. """ return self._mask @@ -367,7 +367,7 @@ def rank(self): def size(self): """ :rtype: A two element list of integers. - :return: The number of nodes and elements in the :class:`~ESMF.api.mesh.Mesh` on the current + :return: The number of nodes and elements in the :class:`~esmpy.api.mesh.Mesh` on the current processor. """ return self._size @@ -376,7 +376,7 @@ def size(self): def size_owned(self): """ :rtype: A two element list of integers. - :return: The number of owned nodes and elements in the :class:`~ESMF.api.mesh.Mesh` on the + :return: The number of owned nodes and elements in the :class:`~esmpy.api.mesh.Mesh` on the current processor. """ return self._size_owned @@ -390,7 +390,7 @@ def struct(self): """ :rtype: pointer :return: A pointer to the underlying ESMF allocation for this - :class:`~ESMF.api.mesh.Mesh`. + :class:`~esmpy.api.mesh.Mesh`. """ return self._struct @@ -402,19 +402,19 @@ def add_elements(self, element_count, element_area=None, element_coords=None): """ - Add elements to a :class:`~ESMF.api.mesh.Mesh`, this must be done after adding nodes. + Add elements to a :class:`~esmpy.api.mesh.Mesh`, this must be done after adding nodes. *REQUIRED:* - :param int element_count: the number of elements to add to the :class:`~ESMF.api.mesh.Mesh`. + :param int element_count: the number of elements to add to the :class:`~esmpy.api.mesh.Mesh`. :param ndarray element_ids: a numpy array of of shape ``(element_count, 1)`` to specify the element ids. :param ndarray element_types: a numpy array of - :attr:`~ESMF.api.constants.MeshElemType`s of shape + :attr:`~esmpy.api.constants.MeshElemType`s of shape ``(element_count, 1)`` to specify the element types. :param ndarray element_conn: a numpy array of shape ``sum(element_types[:], 1)`` to specify the connectivity of the - :class:`~ESMF.api.mesh.Mesh`. The connectivity array is constructed by concatenating the + :class:`~esmpy.api.mesh.Mesh`. The connectivity array is constructed by concatenating the tuples that correspond to the element_ids. The connectivity tuples are constructed by listing the node_ids of each element in **COUNTERCLOCKWISE** order. @@ -424,7 +424,7 @@ def add_elements(self, element_count, :param ndarray element_mask: a numpy array of shape ``(element_count, 1)`` containing integer values to specify masked elements. The specific values that are masked are specified in the - :class:`~ESMF.api.regrid.Regrid` constructor. + :class:`~esmpy.api.regrid.Regrid` constructor. :param ndarray element_area: a numpy array of shape ``(element_count, 1)`` to specify the areas of the elements. :param ndarray element_coords: a numpy array of shape @@ -483,13 +483,13 @@ def add_nodes(self, node_count, node_coords, node_owners): """ - Add nodes to a :class:`~ESMF.api.mesh.Mesh`, this must be done before adding elements. + Add nodes to a :class:`~esmpy.api.mesh.Mesh`, this must be done before adding elements. - :param int node_count: the number of nodes to add to the :class:`~ESMF.api.mesh.Mesh`. + :param int node_count: the number of nodes to add to the :class:`~esmpy.api.mesh.Mesh`. :param ndarray node_ids: a numpy array of shape (node_count, 1) to specify the node_ids. :param ndarray node_coords: a numpy array of shape - (spatial_dim*node_count, 1) to specify the coordinates of the :class:`~ESMF.api.mesh.Mesh`. + (spatial_dim*node_count, 1) to specify the coordinates of the :class:`~esmpy.api.mesh.Mesh`. The array should be constructed by concatenating the coordinate tuples into a numpy array that correspond to node_ids. :param ndarray node_owners: a numpy array of shape (node_count, 1) to @@ -517,9 +517,9 @@ def add_nodes(self, node_count, def copy(self): """ - Copy a :class:`~ESMF.api.mesh.Mesh` in an ESMF-safe manner. + Copy a :class:`~esmpy.api.mesh.Mesh` in an ESMF-safe manner. - :return: A :class:`~ESMF.api.mesh.Mesh` shallow copy. + :return: A :class:`~esmpy.api.mesh.Mesh` shallow copy. """ # shallow copy ret = copy(self) @@ -531,7 +531,7 @@ def copy(self): def destroy(self): """ - Release the memory associated with a :class:`~ESMF.api.mesh.Mesh`. + Release the memory associated with a :class:`~esmpy.api.mesh.Mesh`. """ if hasattr(self, '_finalized'): if not self._finalized: @@ -541,7 +541,7 @@ def destroy(self): def free_memory(self): """ Free memory associated with the creation of a - :class:`~ESMF.api.mesh.Mesh` which is no longer needed for ongoing + :class:`~esmpy.api.mesh.Mesh` which is no longer needed for ongoing operations. """ # call into ctypes layer @@ -549,11 +549,11 @@ def free_memory(self): def get_coords(self, coord_dim, meshloc=MeshLoc.NODE): """ - Return a numpy array of coordinates at a specified :class:`~ESMF.api.mesh.Mesh` - location (coordinates can only be returned for the :class:`~ESMF.api.mesh.Mesh` - :attr:`~ESMF.api.constants.MeshLoc.NODE`\s + Return a numpy array of coordinates at a specified :class:`~esmpy.api.mesh.Mesh` + location (coordinates can only be returned for the :class:`~esmpy.api.mesh.Mesh` + :attr:`~esmpy.api.constants.MeshLoc.NODE` at this time). The returned array is NOT a copy, it is - directly aliased to the underlying memory allocated by ESMF. + directly aliased to the underlying memory allocated by esmpy. *REQUIRED:* @@ -562,12 +562,12 @@ def get_coords(self, coord_dim, meshloc=MeshLoc.NODE): *OPTIONAL:* - :param MeshLoc meshloc: the :attr:`~ESMF.api.constants.MeshLoc` of the + :param MeshLoc meshloc: the :attr:`~esmpy.api.constants.MeshLoc` of the coordinates. If ``None``, defaults to - :attr:`~ESMF.api.constants.MeshLoc.NODE`. + :attr:`~esmpy.api.constants.MeshLoc.NODE`. :return: A numpy array of coordinate values at the specified - :attr:`~ESMF.api.constants.MeshLoc`. + :attr:`~esmpy.api.constants.MeshLoc`. """ ret = None @@ -619,7 +619,7 @@ def _link_coords_(self): def _write_(self, filename): """ - Write the :class:`~ESMF.api.mesh.Mesh` to a vtk formatted file. + Write the :class:`~esmpy.api.mesh.Mesh` to a vtk formatted file. :param str filename: the name of the output file, .vtk will be appended. """ diff --git a/src/addon/ESMPy/src/ESMF/api/regrid.py b/src/addon/ESMPy/src/esmpy/api/regrid.py similarity index 81% rename from src/addon/ESMPy/src/ESMF/api/regrid.py rename to src/addon/ESMPy/src/esmpy/api/regrid.py index 7552960306..b63f6f59ca 100644 --- a/src/addon/ESMPy/src/ESMF/api/regrid.py +++ b/src/addon/ESMPy/src/esmpy/api/regrid.py @@ -3,32 +3,32 @@ """ The Regrid API """ -from ESMF.api import constants -from ESMF.api.field import * +from esmpy.api import constants +from esmpy.api.field import * class Regrid(object): """ - The :class:`~ESMF.api.regrid.Regrid` object represents a regridding operator between two :class:`Fields `. The + The :class:`~esmpy.api.regrid.Regrid` object represents a regridding operator between two :class:`Fields `. The creation of this object is analogous to ESMF_FieldRegridStore(), and calling this object corresponds to ESMF_FieldRegrid(). - ESMF_FieldRegridRelease() is called when the :class:`~ESMF.api.regrid.Regrid` object goes out of - scope (this only happens when the :class:`~ESMF.api.esmpymanager.Manager` goes out of scope, there is a - destroy() call for explicit deallocation of the :class:`~ESMF.api.regrid.Regrid`). + ESMF_FieldRegridRelease() is called when the :class:`~esmpy.api.regrid.Regrid` object goes out of + scope (this only happens when the :class:`~esmpy.api.esmpymanager.Manager` goes out of scope, there is a + destroy() call for explicit deallocation of the :class:`~esmpy.api.regrid.Regrid`). Refer to the ESMF_FieldRegrid methods in the `ESMF Reference Manual `_ for more information. The following arguments are used to create a handle to a Regridding - operation between two :class:`Fields `. + operation between two :class:`Fields `. *REQUIRED:* - :param Field srcfield: source :class:`~ESMF.api.field.Field` associated with an underlying :class:`~ESMF.api.grid.Grid`, - :class:`~ESMF.api.mesh.Mesh` or :class:`~ESMF.api.locstream.LocStream`. - :param Field dstfield: destination :class:`~ESMF.api.field.Field` associated with an underlying - :class:`~ESMF.api.grid.Grid`, :class:`~ESMF.api.mesh.Mesh` or :class:`~ESMF.api.locstream.LocStream`. The data in this :class:`~ESMF.api.field.Field` may be overwritten + :param Field srcfield: source :class:`~esmpy.api.field.Field` associated with an underlying :class:`~esmpy.api.grid.Grid`, + :class:`~esmpy.api.mesh.Mesh` or :class:`~esmpy.api.locstream.LocStream`. + :param Field dstfield: destination :class:`~esmpy.api.field.Field` associated with an underlying + :class:`~esmpy.api.grid.Grid`, :class:`~esmpy.api.mesh.Mesh` or :class:`~esmpy.api.locstream.LocStream`. The data in this :class:`~esmpy.api.field.Field` may be overwritten by this call. *OPTIONAL:* @@ -36,65 +36,65 @@ class Regrid(object): :param string filename: path to the output netCDF weight file. :param string rh_filename: path to the output RouteHandle file. :param ndarray src_mask_values: a numpy array of values that should be - considered masked value on the source :class:`~ESMF.api.field.Field`. + considered masked value on the source :class:`~esmpy.api.field.Field`. :param ndarray dst_mask_values: a numpy array of values that should be - considered masked value on the destination :class:`~ESMF.api.field.Field`. + considered masked value on the destination :class:`~esmpy.api.field.Field`. :param RegridMethod regrid_method: specifies which - :attr:`~ESMF.api.constants.RegridMethod` to use. If ``None``, defaults - to :attr:`~ESMF.api.constants.RegridMethod.BILINEAR`. + :attr:`~esmpy.api.constants.RegridMethod` to use. If ``None``, defaults + to :attr:`~esmpy.api.constants.RegridMethod.BILINEAR`. :param PoleMethod pole_method: specifies which type of artificial pole - to construct on the source :class:`~ESMF.api.grid.Grid` for regridding. If - ``None``, defaults to: :attr:`~ESMF.api.constants.PoleMethod.NONE` for - regridmethod == :attr:`~ESMF.api.constants.RegridMethod.CONSERVE`, or - :attr:`~ESMF.api.constants.PoleMethod.ALLAVG` for - regridmethod != :attr:`~ESMF.api.constants.RegridMethod.CONSERVE`. + to construct on the source :class:`~esmpy.api.grid.Grid` for regridding. If + ``None``, defaults to: :attr:`~esmpy.api.constants.PoleMethod.NONE` for + regridmethod == :attr:`~esmpy.api.constants.RegridMethod.CONSERVE`, or + :attr:`~esmpy.api.constants.PoleMethod.ALLAVG` for + regridmethod != :attr:`~esmpy.api.constants.RegridMethod.CONSERVE`. :param int regrid_pole_npoints: specifies how many points to average over - if polemethod == :attr:`~ESMF.api.constants.PoleMethod.ALLAVG`. + if polemethod == :attr:`~esmpy.api.constants.PoleMethod.ALLAVG`. :param LineType line_type: select the path of the line that connects two points on the surface of a sphere. This in turn controls the path along which distances are calculated and the shape of the edges that make up a cell. If ``None``, defaults to: - :attr:`~ESMF.api.constants.LineType.GREAT_CIRCLE` for - regridmethod == :attr:`~ESMF.api.constants.RegridMethod.CONSERVE`, or - :attr:`~ESMF.api.constants.LineType.CART` for - regridmethod != :attr:`~ESMF.api.constants.RegridMethod.CONSERVE`. + :attr:`~esmpy.api.constants.LineType.GREAT_CIRCLE` for + regridmethod == :attr:`~esmpy.api.constants.RegridMethod.CONSERVE`, or + :attr:`~esmpy.api.constants.LineType.CART` for + regridmethod != :attr:`~esmpy.api.constants.RegridMethod.CONSERVE`. :param NormType norm_type: control which type of normalization to do when generating conservative regridding weights. If ``None``, defaults to - :attr:`~ESMF.api.constants.NormType.DSTAREA`. + :attr:`~esmpy.api.constants.NormType.DSTAREA`. :param ExtrapMethod extrap_method: Specify which extrapolation method to use on unmapped destination points after regridding. :param int extrap_num_src_pnts: The number of source points to use for the extrapolation methods that use more than one source point - (e.g. :attr:`~ESMF.api.constants.ExtrapMethod.NEAREST_IDAVG`). If not + (e.g. :attr:`~esmpy.api.constants.ExtrapMethod.NEAREST_IDAVG`). If not specified, defaults to 8. :param float extrap_dist_exponent: The exponent to raise the distance to when - calculating weights for the :attr:`~ESMF.api.constants.ExtrapMethod.NEAREST_IDAVG` + calculating weights for the :attr:`~esmpy.api.constants.ExtrapMethod.NEAREST_IDAVG` extrapolation method. A higher value reduces the influence of more distant points. If not specified, defaults to ``2.0``. :param int extrap_num_levels: The number of levels to output for the extrapolation - methods that fill levels (e.g. :attr:`~ESMF.api.constants.ExtrapMethod.CREEP`). + methods that fill levels (e.g. :attr:`~esmpy.api.constants.ExtrapMethod.CREEP`). When a method is used that requires this, then an error will be returned if it is not specified. :param UnmappedAction unmapped_action: specifies which action to take if a destination point is found which does not map to any source point. If - ``None``, defaults to :attr:`~ESMF.api.constants.UnmappedAction.ERROR`. + ``None``, defaults to :attr:`~esmpy.api.constants.UnmappedAction.ERROR`. :param bool ignore_degenerate: Ignore degenerate cells when checking the - input :class:`Grids ` or :class:`Meshes ` + input :class:`Grids ` or :class:`Meshes ` for errors. If this is set to True, then the regridding proceeds, but degenerate cells will be skipped. If set to False, a degenerate cell produces - an error. This currently only applies to :attr:`~ESMF.api.constants.RegridMethod.CONSERVE`, + an error. This currently only applies to :attr:`~esmpy.api.constants.RegridMethod.CONSERVE`, other regrid methods currently always skip degenerate cells. If ``None``, defaults to ``False``. :param ndarray src_frac_field: return a numpy array of values containing - weights corresponding to the amount of each :class:`~ESMF.api.field.Field` - value which contributes to the total mass of the :class:`~ESMF.api.field.Field`. + weights corresponding to the amount of each :class:`~esmpy.api.field.Field` + value which contributes to the total mass of the :class:`~esmpy.api.field.Field`. :param ndarray dst_frac_field: return a numpy array of values containing - weights corresponding to the amount of each :class:`~ESMF.api.field.Field` - value which contributes to the total mass of the :class:`~ESMF.api.field.Field`. + weights corresponding to the amount of each :class:`~esmpy.api.field.Field` + value which contributes to the total mass of the :class:`~esmpy.api.field.Field`. :param bool factors: If ``True``, return the factor and factor index list when calling into ``ESMF``'s regrid store method. These lists are converted to NumPy arrays and attached to the regrid object. The factor arrays - are retrievable via :meth:`~ESMF.api.regrid.get_factors` or :meth:`~ESMF.api.regrid.get_weights_dict`. + are retrievable via :meth:`~esmpy.api.regrid.get_factors` or :meth:`~esmpy.api.regrid.get_weights_dict`. See the respective documentation on those methods for additional information. For more information on how ``ESMF`` treats factor retrieval see the ESMF_FieldRegridStore interface in the @@ -247,15 +247,15 @@ def __call__(self, srcfield, dstfield, zero_region=None): *REQUIRED:* - :param Field srcfield: the :class:`~ESMF.api.field.Field` of source data to regrid. - :param Field dstfield: the :class:`~ESMF.api.field.Field` to hold the regridded data. + :param Field srcfield: the :class:`~esmpy.api.field.Field` of source data to regrid. + :param Field dstfield: the :class:`~esmpy.api.field.Field` to hold the regridded data. *OPTIONAL:* :param Region zero_region: specify which region of the field indices will be zeroed out before adding the values resulting from the interpolation. If ``None``, defaults to - :attr:`~ESMF.api.constants.Region.TOTAL`. + :attr:`~esmpy.api.constants.Region.TOTAL`. :return: dstfield """ @@ -390,7 +390,7 @@ def struct(self): """ :rtype: pointer :return: A pointer to the underlying ESMF allocation for this - :class:`~ESMF.api.regrid.Regrid`. + :class:`~esmpy.api.regrid.Regrid`. """ return self.struct @@ -401,9 +401,9 @@ def unmapped_action(self): def copy(self): """ - Copy a :class:`~ESMF.api.regrid.Regrid` in an ESMF-safe manner. + Copy a :class:`~esmpy.api.regrid.Regrid` in an ESMF-safe manner. - :return: A :class:`~ESMF.api.regrid.Regrid` shallow copy. + :return: A :class:`~esmpy.api.regrid.Regrid` shallow copy. """ # shallow copy @@ -415,7 +415,7 @@ def copy(self): def destroy(self): """ - Release the memory associated with a :class:`~ESMF.api.regrid.Regrid`. + Release the memory associated with a :class:`~esmpy.api.regrid.Regrid`. """ # This detects if the object has made it through initialization @@ -459,7 +459,7 @@ def get_factors(self, deep_copy=False): .. note:: If ``deep_copy=True``, array memory is C contiguous according to NumPy array flags (``.flags``). - .. warning:: Remember to call :meth:`~ESMF.api.regrid.destroy` to deallocate + .. warning:: Remember to call :meth:`~esmpy.api.regrid.destroy` to deallocate memory associated with a regrid operation. This will be called by the Python garbage collector. However, if numerous regridding operations are called in a tight loop, a memory leak will occur without a call @@ -481,7 +481,7 @@ def get_factors(self, deep_copy=False): def get_weights_dict(self, deep_copy=False): """ Return a dictionary mapping that is more user-friendly for weight/factor - retrieval. Please read the documentation for :meth:`~ESMF.api.regrid.get_factors` + retrieval. Please read the documentation for :meth:`~esmpy.api.regrid.get_factors` before using this function. =========== ======================= @@ -549,30 +549,30 @@ def _handle_factors_(self, fil, fl, num_factors): class RegridFromFile(object): """ - The :class:`~ESMF.api.regrid.RegridFromFile` object represents a regridding - operator between two :class:`Fields ` that is read + The :class:`~esmpy.api.regrid.RegridFromFile` object represents a regridding + operator between two :class:`Fields ` that is read from a file. The creation of this object is analogous to= ESMF_FieldSMMStore(), and calling this object corresponds to ESMF_FieldRegrid(). ESMF_FieldRegridRelease() - is called when the :class:`~ESMF.api.regrid.RegridFromFile` object goes - out of scope (this only happens when the :class:`~ESMF.api.esmpymanager.Manager` + is called when the :class:`~esmpy.api.regrid.RegridFromFile` object goes + out of scope (this only happens when the :class:`~esmpy.api.esmpymanager.Manager` goes out of scope, there is a destroy() call for explicit deallocation of - the :class:`~ESMF.api.regrid.RegridFromFile`). + the :class:`~esmpy.api.regrid.RegridFromFile`). For more information about the ESMF Regridding functionality, please see the ESMF_FieldRegrid methods in the `ESMF Reference Manual `_. The following arguments are used to create a handle to a regridding - operation between two :class:`Fields `. + operation between two :class:`Fields `. *REQUIRED:* - :param Field srcfield: source :class:`~ESMF.api.field.Field` associated - with an underlying :class:`~ESMF.api.grid.Grid`, :class:`~ESMF.api.mesh.Mesh` - or :class:`~ESMF.api.locstream.LocStream`. - :param Field dstfield: destination :class:`~ESMF.api.field.Field` associated - with an underlying :class:`~ESMF.api.grid.Grid`, :class:`~ESMF.api.mesh.Mesh` - or :class:`~ESMF.api.locstream.LocStream`. The data in this :class:`~ESMF.api.field.Field` + :param Field srcfield: source :class:`~esmpy.api.field.Field` associated + with an underlying :class:`~esmpy.api.grid.Grid`, :class:`~esmpy.api.mesh.Mesh` + or :class:`~esmpy.api.locstream.LocStream`. + :param Field dstfield: destination :class:`~esmpy.api.field.Field` associated + with an underlying :class:`~esmpy.api.grid.Grid`, :class:`~esmpy.api.mesh.Mesh` + or :class:`~esmpy.api.locstream.LocStream`. The data in this :class:`~esmpy.api.field.Field` may be overwritten by this call. :param string filename: the name of the file from which to retrieve the weights. @@ -607,15 +607,15 @@ def __call__(self, srcfield, dstfield, zero_region=None): *REQUIRED:* - :param Field srcfield: the :class:`~ESMF.api.field.Field` of source data to regrid. - :param Field dstfield: the :class:`~ESMF.api.field.Field` to hold the regridded data. + :param Field srcfield: the :class:`~esmpy.api.field.Field` of source data to regrid. + :param Field dstfield: the :class:`~esmpy.api.field.Field` to hold the regridded data. *OPTIONAL:* :param Region zero_region: specify which region of the field indices will be zeroed out before adding the values resulting from the interpolation. If ``None``, defaults to - :attr:`~ESMF.api.constants.Region.TOTAL`. + :attr:`~esmpy.api.constants.Region.TOTAL`. :return: dstfield """ @@ -664,16 +664,16 @@ def struct(self): """ :rtype: pointer :return: A pointer to the underlying ESMF allocation for this - :class:`~ESMF.api.regrid.Regrid`. + :class:`~esmpy.api.regrid.Regrid`. """ return self.struct def copy(self): """ - Copy a :class:`~ESMF.api.regrid.Regrid` in an ESMF-safe manner. + Copy a :class:`~esmpy.api.regrid.Regrid` in an ESMF-safe manner. - :return: A :class:`~ESMF.api.regrid.Regrid` shallow copy. + :return: A :class:`~esmpy.api.regrid.Regrid` shallow copy. """ # shallow copy @@ -685,7 +685,7 @@ def copy(self): def destroy(self): """ - Release the memory associated with the :class:`~ESMF.api.regrid.RegridFromFile` + Release the memory associated with the :class:`~esmpy.api.regrid.RegridFromFile` object. """ diff --git a/src/addon/ESMPy/src/ESMF/fragments/dump_esmf_internal_info.py b/src/addon/ESMPy/src/esmpy/fragments/dump_esmf_internal_info.py similarity index 100% rename from src/addon/ESMPy/src/ESMF/fragments/dump_esmf_internal_info.py rename to src/addon/ESMPy/src/esmpy/fragments/dump_esmf_internal_info.py diff --git a/src/addon/ESMPy/src/ESMF/fragments/extras.py b/src/addon/ESMPy/src/esmpy/fragments/extras.py similarity index 100% rename from src/addon/ESMPy/src/ESMF/fragments/extras.py rename to src/addon/ESMPy/src/esmpy/fragments/extras.py diff --git a/src/addon/ESMPy/src/ESMF/fragments/remap.py b/src/addon/ESMPy/src/esmpy/fragments/remap.py similarity index 100% rename from src/addon/ESMPy/src/ESMF/fragments/remap.py rename to src/addon/ESMPy/src/esmpy/fragments/remap.py diff --git a/src/addon/ESMPy/src/ESMF/interface/__init__.py b/src/addon/ESMPy/src/esmpy/interface/__init__.py similarity index 100% rename from src/addon/ESMPy/src/ESMF/interface/__init__.py rename to src/addon/ESMPy/src/esmpy/interface/__init__.py diff --git a/src/addon/ESMPy/src/ESMF/interface/cbindings.py b/src/addon/ESMPy/src/esmpy/interface/cbindings.py similarity index 99% rename from src/addon/ESMPy/src/ESMF/interface/cbindings.py rename to src/addon/ESMPy/src/esmpy/interface/cbindings.py index 4adaea4f83..c344b48d37 100644 --- a/src/addon/ESMPy/src/ESMF/interface/cbindings.py +++ b/src/addon/ESMPy/src/esmpy/interface/cbindings.py @@ -8,9 +8,9 @@ import numpy as np import sys -import ESMF.api.constants as constants -from ESMF.util.decorators import deprecated, netcdf, beta -from ESMF.interface.loadESMF import _ESMF +import esmpy.api.constants as constants +from esmpy.util.decorators import deprecated, netcdf, beta +from esmpy.interface.loadESMF import _ESMF def copy_struct(src): @@ -20,7 +20,7 @@ def copy_struct(src): def handle_esmf_error(rc, esmf_name): - from ESMF.api import constants + from esmpy.api import constants if rc != constants._ESMP_SUCCESS: msg = esmf_name + ' failed with rc = ' + str(rc) + '. ' + constants._errmsg raise ValueError(msg) diff --git a/src/addon/ESMPy/src/ESMF/interface/loadESMF.py b/src/addon/ESMPy/src/esmpy/interface/loadESMF.py similarity index 99% rename from src/addon/ESMPy/src/ESMF/interface/loadESMF.py rename to src/addon/ESMPy/src/esmpy/interface/loadESMF.py index dfed9ae412..803134ccc4 100644 --- a/src/addon/ESMPy/src/ESMF/interface/loadESMF.py +++ b/src/addon/ESMPy/src/esmpy/interface/loadESMF.py @@ -6,7 +6,7 @@ import sys import traceback -import ESMF.api.constants as constants +import esmpy.api.constants as constants try: import numpy as np diff --git a/src/addon/ESMPy/src/ESMF/test/__init__.py b/src/addon/ESMPy/src/esmpy/test/__init__.py similarity index 100% rename from src/addon/ESMPy/src/ESMF/test/__init__.py rename to src/addon/ESMPy/src/esmpy/test/__init__.py diff --git a/src/addon/ESMPy/src/ESMF/test/base.py b/src/addon/ESMPy/src/esmpy/test/base.py similarity index 98% rename from src/addon/ESMPy/src/ESMF/test/base.py rename to src/addon/ESMPy/src/esmpy/test/base.py index e0ad849d30..2d655206dc 100644 --- a/src/addon/ESMPy/src/ESMF/test/base.py +++ b/src/addon/ESMPy/src/esmpy/test/base.py @@ -1,7 +1,7 @@ import unittest import numpy as np -import ESMF -from ESMF.util.itester import iter_product_keywords +import esmpy +from esmpy.util.itester import iter_product_keywords from unittest import SkipTest diff --git a/src/addon/ESMPy/src/ESMF/test/base_test.py b/src/addon/ESMPy/src/esmpy/test/base_test.py similarity index 91% rename from src/addon/ESMPy/src/ESMF/test/base_test.py rename to src/addon/ESMPy/src/esmpy/test/base_test.py index ba7bfd7a3c..b95a9313d2 100644 --- a/src/addon/ESMPy/src/ESMF/test/base_test.py +++ b/src/addon/ESMPy/src/esmpy/test/base_test.py @@ -1,6 +1,6 @@ -from ESMF.test.base import TestBase +from esmpy.test.base import TestBase import numpy as np -from ESMF import Manager +from esmpy import Manager class Test(TestBase): diff --git a/src/addon/ESMPy/src/ESMF/test/data/T42_grid.nc b/src/addon/ESMPy/src/esmpy/test/data/T42_grid.nc similarity index 100% rename from src/addon/ESMPy/src/ESMF/test/data/T42_grid.nc rename to src/addon/ESMPy/src/esmpy/test/data/T42_grid.nc diff --git a/src/addon/ESMPy/src/ESMF/test/data/gridspec1Dcoords.nc b/src/addon/ESMPy/src/esmpy/test/data/gridspec1Dcoords.nc similarity index 100% rename from src/addon/ESMPy/src/ESMF/test/data/gridspec1Dcoords.nc rename to src/addon/ESMPy/src/esmpy/test/data/gridspec1Dcoords.nc diff --git a/src/addon/ESMPy/src/ESMF/test/data/ne4np4-esmf.nc b/src/addon/ESMPy/src/esmpy/test/data/ne4np4-esmf.nc similarity index 100% rename from src/addon/ESMPy/src/ESMF/test/data/ne4np4-esmf.nc rename to src/addon/ESMPy/src/esmpy/test/data/ne4np4-esmf.nc diff --git a/src/addon/ESMPy/src/ESMF/test/data/ne4np4-pentagons.nc b/src/addon/ESMPy/src/esmpy/test/data/ne4np4-pentagons.nc similarity index 100% rename from src/addon/ESMPy/src/ESMF/test/data/ne4np4-pentagons.nc rename to src/addon/ESMPy/src/esmpy/test/data/ne4np4-pentagons.nc diff --git a/src/addon/ESMPy/src/ESMF/test/regrid_from_file/__init__.py b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/__init__.py similarity index 100% rename from src/addon/ESMPy/src/ESMF/test/regrid_from_file/__init__.py rename to src/addon/ESMPy/src/esmpy/test/regrid_from_file/__init__.py diff --git a/src/addon/ESMPy/src/ESMF/test/regrid_from_file/read_test_cases_from_control_file.py b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/read_test_cases_from_control_file.py similarity index 91% rename from src/addon/ESMPy/src/ESMF/test/regrid_from_file/read_test_cases_from_control_file.py rename to src/addon/ESMPy/src/esmpy/test/regrid_from_file/read_test_cases_from_control_file.py index 313a76e63f..a07eec5913 100644 --- a/src/addon/ESMPy/src/ESMF/test/regrid_from_file/read_test_cases_from_control_file.py +++ b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/read_test_cases_from_control_file.py @@ -10,7 +10,7 @@ import os import re -from ESMF.test.regrid_from_file.regrid_from_file_consts import TEST_REGRID_DIR, CONTROL_FNAME +from esmpy.test.regrid_from_file.regrid_from_file_consts import TEST_REGRID_DIR, CONTROL_FNAME def read_control_file(): diff --git a/src/addon/ESMPy/src/ESMF/test/regrid_from_file/regrid_check.py b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/regrid_check.py similarity index 84% rename from src/addon/ESMPy/src/ESMF/test/regrid_from_file/regrid_check.py rename to src/addon/ESMPy/src/esmpy/test/regrid_from_file/regrid_check.py index 4a7582b869..0714009da0 100644 --- a/src/addon/ESMPy/src/ESMF/test/regrid_from_file/regrid_check.py +++ b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/regrid_check.py @@ -16,21 +16,21 @@ raise ImportError('The Numpy library cannot be found!') try: - import ESMF + import esmpy except: raise ImportError('The ESMF library cannot be found!') -from ESMF.test.regrid_from_file.regrid_from_file_consts import regrid_method_map, file_type_map, pole_method_map, UNINITVAL -from ESMF.util.grid_utilities import compute_mass_grid -from ESMF.util.mesh_utilities import compute_mass_mesh -from ESMF.util.field_utilities import compare_fields +from esmpy.test.regrid_from_file.regrid_from_file_consts import regrid_method_map, file_type_map, pole_method_map, UNINITVAL +from esmpy.util.grid_utilities import compute_mass_grid +from esmpy.util.mesh_utilities import compute_mass_mesh +from esmpy.util.field_utilities import compare_fields def nc_is_mesh(filename, filetype): is_mesh = False - if (filetype == ESMF.FileFormat.UGRID) or (filetype == ESMF.FileFormat.ESMFMESH): + if (filetype == esmpy.FileFormat.UGRID) or (filetype == esmpy.FileFormat.ESMFMESH): is_mesh = True - elif filetype == ESMF.FileFormat.SCRIP: - grid_rank, dims = ESMF.ESMP_ScripInq(filename) + elif filetype == esmpy.FileFormat.SCRIP: + grid_rank, dims = esmpy.ESMP_ScripInq(filename) if grid_rank == 1: is_mesh = True return is_mesh @@ -42,7 +42,7 @@ def create_grid_or_mesh_from_file(filename, filetype, meshname=None, missingvalue=None): is_mesh = False if nc_is_mesh(filename, filetype): - grid_or_mesh = ESMF.Mesh(filename=filename, + grid_or_mesh = esmpy.Mesh(filename=filename, filetype=filetype, meshname=meshname, convert_to_dual=convert_to_dual) @@ -50,7 +50,7 @@ def create_grid_or_mesh_from_file(filename, filetype, meshname=None, add_mask = False else: add_mask = (missingvalue is not None) and (len(missingvalue) > 0) - grid_or_mesh = ESMF.Grid(filename=filename, filetype=filetype, + grid_or_mesh = esmpy.Grid(filename=filename, filetype=filetype, add_corner_stagger=add_corner_stagger, is_sphere=isSphere, add_mask=add_mask, varname=missingvalue) @@ -59,16 +59,16 @@ def create_grid_or_mesh_from_file(filename, filetype, meshname=None, def get_coords_from_grid_or_mesh(grid_or_mesh, is_mesh, regrid_method): if is_mesh: # Mesh - if regrid_method == ESMF.RegridMethod.CONSERVE: - lons = grid_or_mesh.get_coords(0, meshloc=ESMF.element) - lats = grid_or_mesh.get_coords(1, meshloc=ESMF.element) + if regrid_method == esmpy.RegridMethod.CONSERVE: + lons = grid_or_mesh.get_coords(0, meshloc=esmpy.element) + lats = grid_or_mesh.get_coords(1, meshloc=esmpy.element) else: - lons = grid_or_mesh.get_coords(0, meshloc=ESMF.node) - lats = grid_or_mesh.get_coords(1, meshloc=ESMF.node) + lons = grid_or_mesh.get_coords(0, meshloc=esmpy.node) + lats = grid_or_mesh.get_coords(1, meshloc=esmpy.node) else: # Grid - lons = grid_or_mesh.get_coords(0, staggerloc=ESMF.StaggerLoc.CENTER) - lats = grid_or_mesh.get_coords(1, staggerloc=ESMF.StaggerLoc.CENTER) + lons = grid_or_mesh.get_coords(0, staggerloc=esmpy.StaggerLoc.CENTER) + lats = grid_or_mesh.get_coords(1, staggerloc=esmpy.StaggerLoc.CENTER) # Convert to radians lons = np.radians(lons) lats = np.radians(lats) @@ -80,13 +80,13 @@ def create_field(grid, name, regrid_method=None): will be used to initialize the name of a new Field. POSTCONDITIONS: A Field has been created. ''' - if isinstance(grid,ESMF.Mesh): - if regrid_method == ESMF.RegridMethod.CONSERVE: - field = ESMF.Field(grid, name=name, meshloc=ESMF.MeshLoc.ELEMENT) + if isinstance(grid,esmpy.Mesh): + if regrid_method == esmpy.RegridMethod.CONSERVE: + field = esmpy.Field(grid, name=name, meshloc=esmpy.MeshLoc.ELEMENT) else: - field = ESMF.Field(grid, name=name, meshloc=ESMF.MeshLoc.NODE) + field = esmpy.Field(grid, name=name, meshloc=esmpy.MeshLoc.NODE) else: - field = ESMF.Field(grid, name=name) + field = esmpy.Field(grid, name=name) return field @@ -121,7 +121,7 @@ def run_regridding(srcfield, dstfield, src_mask, dst_mask, if dst_mask: dst_mask_vals = np.array([0]) - regridSrc2Dst = ESMF.Regrid(srcfield, dstfield, + regridSrc2Dst = esmpy.Regrid(srcfield, dstfield, src_mask_values=src_mask_vals, dst_mask_values=dst_mask_vals, regrid_method=regrid_method, @@ -130,7 +130,7 @@ def run_regridding(srcfield, dstfield, src_mask, dst_mask, dst_frac_field=dstfracfield, pole_method=pole_method, regrid_pole_npoints=regrid_pole_npoints) - dstfield = regridSrc2Dst(srcfield, dstfield, zero_region=ESMF.Region.SELECT) + dstfield = regridSrc2Dst(srcfield, dstfield, zero_region=esmpy.Region.SELECT) regridSrc2Dst.destroy() return dstfield @@ -148,7 +148,7 @@ def parse_options(options): src_meshname = "Undefined" dst_meshname = "Undefined" pole_method_str = None - unmapped_action = ESMF.UnmappedAction.ERROR + unmapped_action = esmpy.UnmappedAction.ERROR src_regional = False dst_regional = False src_missingvalue = "" @@ -163,7 +163,7 @@ def parse_options(options): elif opt == '--dst_meshname': dst_meshname = arg elif opt == '-i' or opt == '--ignore_unmapped': - unmapped_action = ESMF.UnmappedAction.IGNORE + unmapped_action = esmpy.UnmappedAction.IGNORE elif opt == '-t': src_type_str = arg dst_type_str = arg @@ -190,7 +190,7 @@ def regrid_check(src_fname, dst_fname, regrid_method, options, # print ("\nregrid_weight_gen_check.py: mesh_check()") parallel = False - if ESMF.pet_count() > 1: + if esmpy.pet_count() > 1: parallel = True # Settings for regrid @@ -200,8 +200,8 @@ def regrid_check(src_fname, dst_fname, regrid_method, options, src_type = file_type_map[src_type_str] dst_type = file_type_map[dst_type_str] regrid_method = regrid_method_map[regrid_method] - convert_to_dual = (regrid_method != ESMF.RegridMethod.CONSERVE) - add_corner_stagger = (regrid_method == ESMF.RegridMethod.CONSERVE) + convert_to_dual = (regrid_method != esmpy.RegridMethod.CONSERVE) + add_corner_stagger = (regrid_method == esmpy.RegridMethod.CONSERVE) src_is_sphere = not src_regional dst_is_sphere = not dst_regional pole_method = None @@ -210,7 +210,7 @@ def regrid_check(src_fname, dst_fname, regrid_method, options, if pole_method_str in pole_method_map: pole_method = pole_method_map[pole_method_str] else: - pole_method = ESMF.PoleMethod.NPNTAVG + pole_method = esmpy.PoleMethod.NPNTAVG pole_method_npntavg = int(pole_method_str) src_mask = False @@ -259,7 +259,7 @@ def regrid_check(src_fname, dst_fname, regrid_method, options, srcmass = None dstmass = None - if regrid_method == ESMF.RegridMethod.CONSERVE: + if regrid_method == esmpy.RegridMethod.CONSERVE: if src_is_mesh: srcmass = compute_mass_mesh(srcfield, dofrac=True, fracfield=srcfracfield) @@ -290,7 +290,7 @@ def regrid_check(src_fname, dst_fname, regrid_method, options, srcfield.destroy() dstfield.destroy() dstfield2.destroy() - if regrid_method == ESMF.RegridMethod.CONSERVE: + if regrid_method == esmpy.RegridMethod.CONSERVE: srcfracfield.destroy() dstfracfield.destroy() srcgrid.destroy() diff --git a/src/addon/ESMPy/src/ESMF/test/regrid_from_file/regrid_check_driver.py b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/regrid_check_driver.py similarity index 82% rename from src/addon/ESMPy/src/ESMF/test/regrid_from_file/regrid_check_driver.py rename to src/addon/ESMPy/src/esmpy/test/regrid_from_file/regrid_check_driver.py index c11335bf6a..25edc3e0d3 100644 --- a/src/addon/ESMPy/src/ESMF/test/regrid_from_file/regrid_check_driver.py +++ b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/regrid_check_driver.py @@ -14,29 +14,29 @@ import traceback try: - import ESMF + import esmpy except: raise ImportError('The ESMF library cannot be found!') -from ESMF.test.regrid_from_file.regrid_from_file_consts import DATA_SUBDIR -from ESMF.test.regrid_from_file.run_regrid_from_file_dryrun import cache_data_files_for_test_cases -from ESMF.test.regrid_from_file.regrid_check import regrid_check -from ESMF.test.regrid_from_file.read_test_cases_from_control_file import read_control_file +from esmpy.test.regrid_from_file.regrid_from_file_consts import DATA_SUBDIR +from esmpy.test.regrid_from_file.run_regrid_from_file_dryrun import cache_data_files_for_test_cases +from esmpy.test.regrid_from_file.regrid_check import regrid_check +from esmpy.test.regrid_from_file.read_test_cases_from_control_file import read_control_file # Start up ESMF and run regrid test for each line of options # read from a control file. Retrieve data files for each test from a remote # server if they do not exist locally. -# Start up ESMF. -mg = ESMF.Manager(debug=True) +# Start up esmpy. +mg = esmpy.Manager(debug=True) parallel = False -if ESMF.pet_count() > 1: +if esmpy.pet_count() > 1: parallel = True # Read the test case parameters from the control file. print('Reading control file...') test_cases = read_control_file() -if (ESMF.local_pet() == 0): +if (esmpy.local_pet() == 0): # Retrieve the data files needed for the test cases from the remote server. print('Retrieving regrid_from_file data...') status_ok = cache_data_files_for_test_cases(test_cases) @@ -66,7 +66,7 @@ traceback.print_exc(file=sys.stdout) skip = False - for i in range(ESMF.pet_count()): + for i in range(esmpy.pet_count()): for line in open("PET"+str(i)+".ESMF_LogFile"): if "ESMF_NETCDF not defined when lib was compiled" in line or \ "File format is not supported" in line: @@ -80,10 +80,10 @@ print (line) # clean the log files - for i in range(ESMF.pet_count()): + for i in range(esmpy.pet_count()): os.system("echo ' ' > PET"+str(i)+".ESMF_LogFile") - print ("\nPET: " + str(ESMF.local_pet()) + " - " + test_str + " - FINISH\n") + print ("\nPET: " + str(esmpy.local_pet()) + " - " + test_str + " - FINISH\n") if skip: print ('RESULT: SKIP\n\n') diff --git a/src/addon/ESMPy/src/esmpy/test/regrid_from_file/regrid_from_file_consts.py b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/regrid_from_file_consts.py new file mode 100644 index 0000000000..8e0b7fcc6f --- /dev/null +++ b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/regrid_from_file_consts.py @@ -0,0 +1,31 @@ +""" +Constants required for the regrid from file tests. +""" +import os +try: + import esmpy +except: + raise ImportError('The ESMF library cannot be found!') +# +TEST_REGRID_DIR = 'src/esmpy/test/regrid_from_file/' +CONTROL_FNAME = 'regrid_test_data.txt' +DATA_SUBDIR = os.path.join(TEST_REGRID_DIR,'data/') +DATA_URL_ROOT = 'http://data.earthsystemmodeling.org/download/data/' +UNINITVAL = 422397696. +EPSILON = 1E-30 +# +regrid_method_map = {"bilinear" : esmpy.RegridMethod.BILINEAR, + "patch" : esmpy.RegridMethod.PATCH, + "conserve" : esmpy.RegridMethod.CONSERVE, + "neareststod" : esmpy.RegridMethod.NEAREST_STOD, + "nearestdtos" : esmpy.RegridMethod.NEAREST_DTOS} +file_type_map = {"VTK" : esmpy.FileFormat.VTK, + "SCRIP" : esmpy.FileFormat.SCRIP, + "ESMF" : esmpy.FileFormat.ESMFMESH, + "ESMFMESH" : esmpy.FileFormat.ESMFMESH, + "ESMFGRID" : esmpy.FileFormat.ESMFGRID, + "UGRID" : esmpy.FileFormat.UGRID, + "GRIDSPEC" : esmpy.FileFormat.GRIDSPEC} +pole_method_map = {"none" : esmpy.PoleMethod.NONE, + "all" : esmpy.PoleMethod.ALLAVG, + "teeth" : esmpy.PoleMethod.TEETH} diff --git a/src/addon/ESMPy/src/ESMF/test/regrid_from_file/regrid_test_data.txt b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/regrid_test_data.txt similarity index 100% rename from src/addon/ESMPy/src/ESMF/test/regrid_from_file/regrid_test_data.txt rename to src/addon/ESMPy/src/esmpy/test/regrid_from_file/regrid_test_data.txt diff --git a/src/addon/ESMPy/src/ESMF/test/regrid_from_file/rfftest.py b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/rfftest.py similarity index 52% rename from src/addon/ESMPy/src/ESMF/test/regrid_from_file/rfftest.py rename to src/addon/ESMPy/src/esmpy/test/regrid_from_file/rfftest.py index 788408c105..4c19cf6dfe 100644 --- a/src/addon/ESMPy/src/ESMF/test/regrid_from_file/rfftest.py +++ b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/rfftest.py @@ -6,13 +6,13 @@ import pytest -from ESMF.test.base import TestBase, attr +from esmpy.test.base import TestBase, attr class TestRFF(TestBase): # # '0' in the name is so it is run first # def test_0_regrid_from_file_dryrun(self): - # from ESMF.test.regrid_from_file import run_regrid_from_file_dryrun + # from esmpy.test.regrid_from_file import run_regrid_from_file_dryrun def test_regrid_from_file(self): - from ESMF.test.regrid_from_file import run_regrid_from_file + from esmpy.test.regrid_from_file import run_regrid_from_file diff --git a/src/addon/ESMPy/src/ESMF/test/regrid_from_file/rfftestdryrun.py b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/rfftestdryrun.py similarity index 51% rename from src/addon/ESMPy/src/ESMF/test/regrid_from_file/rfftestdryrun.py rename to src/addon/ESMPy/src/esmpy/test/regrid_from_file/rfftestdryrun.py index dc8e40e123..2ee122f2ac 100644 --- a/src/addon/ESMPy/src/ESMF/test/regrid_from_file/rfftestdryrun.py +++ b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/rfftestdryrun.py @@ -6,9 +6,9 @@ import pytest -from ESMF.test.base import TestBase, attr +from esmpy.test.base import TestBase, attr class TestRFFDryrun(TestBase): def test_regrid_from_file_dryrun(self): - from ESMF.test.regrid_from_file import run_regrid_from_file_dryrun + from esmpy.test.regrid_from_file import run_regrid_from_file_dryrun diff --git a/src/addon/ESMPy/src/ESMF/test/regrid_from_file/run_regrid_from_file.py b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file.py similarity index 92% rename from src/addon/ESMPy/src/ESMF/test/regrid_from_file/run_regrid_from_file.py rename to src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file.py index e219c1d865..67b82288c2 100644 --- a/src/addon/ESMPy/src/ESMF/test/regrid_from_file/run_regrid_from_file.py +++ b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file.py @@ -3,8 +3,8 @@ import os import sys -import ESMF.api.constants as constants -from ESMF.test.regrid_from_file.regrid_from_file_consts import TEST_REGRID_DIR +import esmpy.api.constants as constants +from esmpy.test.regrid_from_file.regrid_from_file_consts import TEST_REGRID_DIR parallel = False diff --git a/src/addon/ESMPy/src/ESMF/test/regrid_from_file/run_regrid_from_file_dryrun.py b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file_dryrun.py similarity index 87% rename from src/addon/ESMPy/src/ESMF/test/regrid_from_file/run_regrid_from_file_dryrun.py rename to src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file_dryrun.py index 88ac6ee8a4..5b7ca181b3 100644 --- a/src/addon/ESMPy/src/ESMF/test/regrid_from_file/run_regrid_from_file_dryrun.py +++ b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file_dryrun.py @@ -11,9 +11,9 @@ import sys import os -from ESMF.test.regrid_from_file.regrid_from_file_consts import DATA_SUBDIR, DATA_URL_ROOT -from ESMF.util.cache_data import cache_data_file -from ESMF.test.regrid_from_file.read_test_cases_from_control_file import read_control_file +from esmpy.test.regrid_from_file.regrid_from_file_consts import DATA_SUBDIR, DATA_URL_ROOT +from esmpy.util.cache_data import cache_data_file +from esmpy.test.regrid_from_file.read_test_cases_from_control_file import read_control_file def cache_data_files_for_test_cases(test_cases): # Create data subdirectory if it doesn't exist. diff --git a/src/addon/ESMPy/src/ESMF/test/test_api/__init__.py b/src/addon/ESMPy/src/esmpy/test/test_api/__init__.py similarity index 100% rename from src/addon/ESMPy/src/ESMF/test/test_api/__init__.py rename to src/addon/ESMPy/src/esmpy/test/test_api/__init__.py diff --git a/src/addon/ESMPy/src/ESMF/test/test_api/test_array.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_array.py similarity index 98% rename from src/addon/ESMPy/src/ESMF/test/test_api/test_array.py rename to src/addon/ESMPy/src/esmpy/test/test_api/test_array.py index 7787555af3..3e4f1dfb43 100644 --- a/src/addon/ESMPy/src/ESMF/test/test_api/test_array.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_array.py @@ -3,9 +3,9 @@ unit test file """ -from ESMF import * -from ESMF.interface.cbindings import * -from ESMF.test.base import TestBase +from esmpy import * +from esmpy.interface.cbindings import * +from esmpy.test.base import TestBase import numpy as np @@ -59,7 +59,7 @@ def make_maskedarray(self, array, type=TypeKind.R8): :param array: maxindices of a 2- or 3d array :type array: np.array of dtype=np.int32 :param type: the type of the esmf buffer - :type type: ESMF.TypeKind + :type type: esmpy.TypeKind ''' # create manager because we are doing some lower level stuff here without automatic initialization Manager() diff --git a/src/addon/ESMPy/src/ESMF/test/test_api/test_field.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_field.py similarity index 98% rename from src/addon/ESMPy/src/ESMF/test/test_api/test_field.py rename to src/addon/ESMPy/src/esmpy/test/test_api/test_field.py index a77fa63dfb..8f46dd69de 100644 --- a/src/addon/ESMPy/src/ESMF/test/test_api/test_field.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_field.py @@ -4,10 +4,10 @@ import pytest -from ESMF import * -from ESMF.interface.cbindings import * -from ESMF.test.base import TestBase, attr, SkipTest -from ESMF.util.mesh_utilities import mesh_create_50, mesh_create_50_parallel +from esmpy import * +from esmpy.interface.cbindings import * +from esmpy.test.base import TestBase, attr, SkipTest +from esmpy.util.mesh_utilities import mesh_create_50, mesh_create_50_parallel class TestField(TestBase): @@ -100,7 +100,6 @@ def test_numpy_funcs(self): @pytest.mark.serial @pytest.mark.skipif(mg.test_exhaustive==False, reason="only run in exhaustive mode") - #nosetests src/ESMF/test/test_api/test_field.py:TestField.test_field_create_2d_grid def _field_create_2d_grid(self): keywords = dict( # periodic specifies all valid combos of [num_peri_dims, periodic_dim, pole_dim] diff --git a/src/addon/ESMPy/src/ESMF/test/test_api/test_grid.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_grid.py similarity index 94% rename from src/addon/ESMPy/src/ESMF/test/test_api/test_grid.py rename to src/addon/ESMPy/src/esmpy/test/test_api/test_grid.py index 03e1ea73d8..37a9b57ace 100644 --- a/src/addon/ESMPy/src/ESMF/test/test_api/test_grid.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_grid.py @@ -3,10 +3,10 @@ grid unit test file """ -import ESMF -from ESMF import * -from ESMF.interface.cbindings import * -from ESMF.test.base import TestBase, attr +import esmpy +from esmpy import * +from esmpy.interface.cbindings import * +from esmpy.test.base import TestBase, attr import numpy as np import os @@ -140,28 +140,28 @@ def make_grid_periodic(self): assert lon.size == 100 assert lat.size == 100 - grid = ESMF.Grid(np.array([lon.size, lat.size], 'int32'), + grid = esmpy.Grid(np.array([lon.size, lat.size], 'int32'), num_peri_dims=1, staggerloc=[StaggerLoc.CENTER, StaggerLoc.CORNER]) - gridXCorner = grid.get_coords(0, staggerloc=ESMF.StaggerLoc.CORNER) - lon_par = lon[grid.lower_bounds[ESMF.StaggerLoc.CORNER][0]:grid.upper_bounds[ESMF.StaggerLoc.CORNER][0]] + gridXCorner = grid.get_coords(0, staggerloc=esmpy.StaggerLoc.CORNER) + lon_par = lon[grid.lower_bounds[esmpy.StaggerLoc.CORNER][0]:grid.upper_bounds[esmpy.StaggerLoc.CORNER][0]] gridXCorner[...] = lon_par.reshape((lon_par.size, 1)) - gridYCorner = grid.get_coords(1, staggerloc=ESMF.StaggerLoc.CORNER) + gridYCorner = grid.get_coords(1, staggerloc=esmpy.StaggerLoc.CORNER) lat_corner = np.linspace(90, -90, lat.size + 1) - lat_par = lat_corner[grid.lower_bounds[ESMF.StaggerLoc.CORNER][1]:grid.upper_bounds[ESMF.StaggerLoc.CORNER][1]] + lat_par = lat_corner[grid.lower_bounds[esmpy.StaggerLoc.CORNER][1]:grid.upper_bounds[esmpy.StaggerLoc.CORNER][1]] gridYCorner[...] = lat_par.reshape((1, lat_par.size)) offset_lon = 360. / lon.size / 2. lon -= offset_lon gridXCenter = grid.get_coords(0) - lon_par = lon[grid.lower_bounds[ESMF.StaggerLoc.CENTER][0]:grid.upper_bounds[ESMF.StaggerLoc.CENTER][0]] + lon_par = lon[grid.lower_bounds[esmpy.StaggerLoc.CENTER][0]:grid.upper_bounds[esmpy.StaggerLoc.CENTER][0]] gridXCenter[...] = lon_par.reshape((lon_par.size, 1)) offset_lat = 180. / (lat.size) / 2. lat = np.linspace(90 - offset_lat, -90 + offset_lat, lat.size) gridYCenter = grid.get_coords(1) - lat_par = lat[grid.lower_bounds[ESMF.StaggerLoc.CENTER][1]:grid.upper_bounds[ESMF.StaggerLoc.CENTER][1]] + lat_par = lat[grid.lower_bounds[esmpy.StaggerLoc.CENTER][1]:grid.upper_bounds[esmpy.StaggerLoc.CENTER][1]] gridYCenter[...] = lat_par.reshape((1, lat_par.size)) @@ -283,7 +283,7 @@ def test_grid_create_cubed_sphere(self): # [DecompFlag.DEFAULT, 6]], dtype=np.int32) # deLabelList = np.array([11,12,13,14,15,16], dtype=np.int32) - ESMF.Manager(debug=True) + esmpy.Manager(debug=True) grid = Grid(tilesize = 45, regDecompPTile = regDecompPTile, #decompFlagPTile = decompFlagPTile, @@ -322,7 +322,7 @@ def test_grid_slice_2d(self): def test_grid_slice_2d_corners(self): grid = self.make_grid_2d() - grid.add_coords(staggerloc=ESMF.StaggerLoc.CORNER) + grid.add_coords(staggerloc=esmpy.StaggerLoc.CORNER) grid_row = grid.get_coords(0, staggerloc=StaggerLoc.CORNER) grid_col = grid.get_coords(1, staggerloc=StaggerLoc.CORNER) @@ -434,7 +434,7 @@ def test_grid_slice_periodic(self): def test_slice_grid_created_from_file_scrip(self): reg_decomp = [pet_count(), 1] try: - esmfdir = os.path.dirname(inspect.getfile(ESMF)) + esmfdir = os.path.dirname(inspect.getfile(esmpy)) grid = Grid(filename=os.path.join(esmfdir, "test/data/T42_grid.nc"), filetype=FileFormat.SCRIP, pole_kind=[PoleKind.MONOPOLE, PoleKind.BIPOLE], @@ -630,7 +630,7 @@ def test_grid_area_3D(self): assert(np.all(area[...] == 12*np.ones([10, 20, 30]))) def test_grid_create_from_file_gridspec1D(self): - esmfdir = os.path.dirname(inspect.getfile(ESMF)) + esmfdir = os.path.dirname(inspect.getfile(esmpy)) grid = Grid(filename=os.path.join(esmfdir, "test/data/gridspec1Dcoords.nc"), filetype=FileFormat.GRIDSPEC, add_corner_stagger=True, coord_names=["longitude", "latitude"]) @@ -640,7 +640,7 @@ def test_grid_create_from_file_gridspec1D(self): def test_grid_create_from_file_scrip(self): reg_decomp = [pet_count(), 1] try: - esmfdir = os.path.dirname(inspect.getfile(ESMF)) + esmfdir = os.path.dirname(inspect.getfile(esmpy)) grid_from_file = Grid(filename=os.path.join(esmfdir, "test/data/T42_grid.nc"), filetype=FileFormat.SCRIP, reg_decomp=reg_decomp) @@ -652,7 +652,7 @@ def test_grid_create_from_file_scrip_decomp_balanced_balanced(self): decompflag = np.array([DecompFlag.BALANCED, DecompFlag.BALANCED], dtype=np.int32) try: - esmfdir = os.path.dirname(inspect.getfile(ESMF)) + esmfdir = os.path.dirname(inspect.getfile(esmpy)) grid_from_file = Grid(filename=os.path.join(esmfdir, "test/data/T42_grid.nc"), filetype=FileFormat.SCRIP, reg_decomp=reg_decomp, decompflag=decompflag) @@ -664,7 +664,7 @@ def test_grid_create_from_file_scrip_decomp_balanced_restfirst(self): decompflag = np.array([DecompFlag.BALANCED, DecompFlag.RESTFIRST], dtype=np.int32) try: - esmfdir = os.path.dirname(inspect.getfile(ESMF)) + esmfdir = os.path.dirname(inspect.getfile(esmpy)) grid_from_file = Grid(filename=os.path.join(esmfdir, "test/data/T42_grid.nc"), filetype=FileFormat.SCRIP, reg_decomp=reg_decomp, decompflag=decompflag) @@ -676,7 +676,7 @@ def test_grid_create_from_file_scrip_decomp_balanced_restlast(self): decompflag = np.array([DecompFlag.BALANCED, DecompFlag.RESTLAST], dtype=np.int32) try: - esmfdir = os.path.dirname(inspect.getfile(ESMF)) + esmfdir = os.path.dirname(inspect.getfile(esmpy)) grid_from_file = Grid(filename=os.path.join(esmfdir, "test/data/T42_grid.nc"), filetype=FileFormat.SCRIP, reg_decomp=reg_decomp, decompflag=decompflag) @@ -689,7 +689,7 @@ def test_grid_create_from_file_scrip_decomp_balanced_cyclic(self): decompflag = np.array([DecompFlag.BALANCED, DecompFlag.CYCLIC], dtype=np.int32) try: - esmfdir = os.path.dirname(inspect.getfile(ESMF)) + esmfdir = os.path.dirname(inspect.getfile(esmpy)) grid_from_file = Grid(filename=os.path.join(esmfdir, "test/data/T42_grid.nc"), filetype=FileFormat.SCRIP, reg_decomp=reg_decomp, decompflag=decompflag) @@ -701,7 +701,7 @@ def test_grid_create_from_file_scrip_decomp_restfirst_balanced(self): decompflag = np.array([DecompFlag.RESTFIRST, DecompFlag.BALANCED], dtype=np.int32) try: - esmfdir = os.path.dirname(inspect.getfile(ESMF)) + esmfdir = os.path.dirname(inspect.getfile(esmpy)) grid_from_file = Grid(filename=os.path.join(esmfdir, "test/data/T42_grid.nc"), filetype=FileFormat.SCRIP, reg_decomp=reg_decomp, decompflag=decompflag) @@ -713,7 +713,7 @@ def test_grid_create_from_file_scrip_decomp_restfirst_restfirst(self): decompflag = np.array([DecompFlag.RESTFIRST, DecompFlag.RESTFIRST], dtype=np.int32) try: - esmfdir = os.path.dirname(inspect.getfile(ESMF)) + esmfdir = os.path.dirname(inspect.getfile(esmpy)) grid_from_file = Grid(filename=os.path.join(esmfdir, "test/data/T42_grid.nc"), filetype=FileFormat.SCRIP, reg_decomp=reg_decomp, decompflag=decompflag) @@ -725,7 +725,7 @@ def test_grid_create_from_file_scrip_decomp_restfirst_restlast(self): decompflag = np.array([DecompFlag.RESTFIRST, DecompFlag.RESTLAST], dtype=np.int32) try: - esmfdir = os.path.dirname(inspect.getfile(ESMF)) + esmfdir = os.path.dirname(inspect.getfile(esmpy)) grid_from_file = Grid(filename=os.path.join(esmfdir, "test/data/T42_grid.nc"), filetype=FileFormat.SCRIP, reg_decomp=reg_decomp, decompflag=decompflag) @@ -738,7 +738,7 @@ def test_grid_create_from_file_scrip_decomp_restfirst_cyclic(self): decompflag = np.array([DecompFlag.RESTFIRST, DecompFlag.CYCLIC], dtype=np.int32) try: - esmfdir = os.path.dirname(inspect.getfile(ESMF)) + esmfdir = os.path.dirname(inspect.getfile(esmpy)) grid_from_file = Grid(filename=os.path.join(esmfdir, "test/data/T42_grid.nc"), filetype=FileFormat.SCRIP, reg_decomp=reg_decomp, decompflag=decompflag) @@ -750,7 +750,7 @@ def test_grid_create_from_file_scrip_decomp_restlast_balanced(self): decompflag = np.array([DecompFlag.RESTLAST, DecompFlag.BALANCED], dtype=np.int32) try: - esmfdir = os.path.dirname(inspect.getfile(ESMF)) + esmfdir = os.path.dirname(inspect.getfile(esmpy)) grid_from_file = Grid(filename=os.path.join(esmfdir, "test/data/T42_grid.nc"), filetype=FileFormat.SCRIP, reg_decomp=reg_decomp, decompflag=decompflag) @@ -762,7 +762,7 @@ def test_grid_create_from_file_scrip_decomp_restlast_restfirst(self): decompflag = np.array([DecompFlag.RESTLAST, DecompFlag.RESTFIRST], dtype=np.int32) try: - esmfdir = os.path.dirname(inspect.getfile(ESMF)) + esmfdir = os.path.dirname(inspect.getfile(esmpy)) grid_from_file = Grid(filename=os.path.join(esmfdir, "test/data/T42_grid.nc"), filetype=FileFormat.SCRIP, reg_decomp=reg_decomp, decompflag=decompflag) @@ -774,7 +774,7 @@ def test_grid_create_from_file_scrip_decomp_restlast_restlast(self): decompflag = np.array([DecompFlag.RESTLAST, DecompFlag.RESTLAST], dtype=np.int32) try: - esmfdir = os.path.dirname(inspect.getfile(ESMF)) + esmfdir = os.path.dirname(inspect.getfile(esmpy)) grid_from_file = Grid(filename=os.path.join(esmfdir, "test/data/T42_grid.nc"), filetype=FileFormat.SCRIP, reg_decomp=reg_decomp, decompflag=decompflag) @@ -787,7 +787,7 @@ def test_grid_create_from_file_scrip_decomp_restlast_cyclic(self): decompflag = np.array([DecompFlag.RESTLAST, DecompFlag.CYCLIC], dtype=np.int32) try: - esmfdir = os.path.dirname(inspect.getfile(ESMF)) + esmfdir = os.path.dirname(inspect.getfile(esmpy)) grid_from_file = Grid(filename=os.path.join(esmfdir, "test/data/T42_grid.nc"), filetype=FileFormat.SCRIP, reg_decomp=reg_decomp, decompflag=decompflag) @@ -800,7 +800,7 @@ def test_grid_create_from_file_scrip_decomp_cyclic_balanced(self): decompflag = np.array([DecompFlag.CYCLIC, DecompFlag.BALANCED], dtype=np.int32) try: - esmfdir = os.path.dirname(inspect.getfile(ESMF)) + esmfdir = os.path.dirname(inspect.getfile(esmpy)) grid_from_file = Grid(filename=os.path.join(esmfdir, "test/data/T42_grid.nc"), filetype=FileFormat.SCRIP, reg_decomp=reg_decomp, decompflag=decompflag) @@ -813,7 +813,7 @@ def test_grid_create_from_file_scrip_decomp_cyclic_restfirst(self): decompflag = np.array([DecompFlag.CYCLIC, DecompFlag.RESTFIRST], dtype=np.int32) try: - esmfdir = os.path.dirname(inspect.getfile(ESMF)) + esmfdir = os.path.dirname(inspect.getfile(esmpy)) grid_from_file = Grid(filename=os.path.join(esmfdir, "test/data/T42_grid.nc"), filetype=FileFormat.SCRIP, reg_decomp=reg_decomp, decompflag=decompflag) @@ -826,7 +826,7 @@ def test_grid_create_from_file_scrip_decomp_cyclic_restlast(self): decompflag = np.array([DecompFlag.CYCLIC, DecompFlag.RESTLAST], dtype=np.int32) try: - esmfdir = os.path.dirname(inspect.getfile(ESMF)) + esmfdir = os.path.dirname(inspect.getfile(esmpy)) grid_from_file = Grid(filename=os.path.join(esmfdir, "test/data/T42_grid.nc"), filetype=FileFormat.SCRIP, reg_decomp=reg_decomp, decompflag=decompflag) @@ -839,7 +839,7 @@ def test_grid_create_from_file_scrip_decomp_cyclic_cyclic(self): decompflag = np.array([DecompFlag.CYCLIC, DecompFlag.CYCLIC], dtype=np.int32) try: - esmfdir = os.path.dirname(inspect.getfile(ESMF)) + esmfdir = os.path.dirname(inspect.getfile(esmpy)) grid_from_file = Grid(filename=os.path.join(esmfdir, "test/data/T42_grid.nc"), filetype=FileFormat.SCRIP, reg_decomp=reg_decomp, decompflag=decompflag) diff --git a/src/addon/ESMPy/src/ESMF/test/test_api/test_locstream.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_locstream.py similarity index 95% rename from src/addon/ESMPy/src/ESMF/test/test_api/test_locstream.py rename to src/addon/ESMPy/src/esmpy/test/test_api/test_locstream.py index 92a3af7c45..c1b1dbf508 100644 --- a/src/addon/ESMPy/src/ESMF/test/test_api/test_locstream.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_locstream.py @@ -3,9 +3,9 @@ locstream unit test file """ -from ESMF import * -from ESMF.interface.cbindings import * -from ESMF.test.base import TestBase, attr +from esmpy import * +from esmpy.interface.cbindings import * +from esmpy.test.base import TestBase, attr import pytest diff --git a/src/addon/ESMPy/src/ESMF/test/test_api/test_mesh.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_mesh.py similarity index 95% rename from src/addon/ESMPy/src/ESMF/test/test_api/test_mesh.py rename to src/addon/ESMPy/src/esmpy/test/test_api/test_mesh.py index 2faa246899..7ca0a9c9aa 100644 --- a/src/addon/ESMPy/src/ESMF/test/test_api/test_mesh.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_mesh.py @@ -8,10 +8,10 @@ import os import inspect -import ESMF -from ESMF import * -from ESMF.test.base import TestBase, attr, SkipTest -from ESMF.util.mesh_utilities import * +import esmpy +from esmpy import * +from esmpy.test.base import TestBase, attr, SkipTest +from esmpy.util.mesh_utilities import * class TestMesh(TestBase): mg = Manager(debug=True) @@ -178,7 +178,7 @@ def test_mesh_50_mask_area(self): def test_mesh_create_from_file_scrip(self): try: - esmfdir = os.path.dirname(inspect.getfile(ESMF)) + esmfdir = os.path.dirname(inspect.getfile(esmpy)) mesh_from_file = Mesh(filename=os.path.join(esmfdir, "test/data/ne4np4-pentagons.nc"), filetype=FileFormat.SCRIP) except: @@ -186,7 +186,7 @@ def test_mesh_create_from_file_scrip(self): def test_mesh_create_from_file_esmfmesh(self): try: - esmfdir = os.path.dirname(inspect.getfile(ESMF)) + esmfdir = os.path.dirname(inspect.getfile(esmpy)) mesh_from_file = Mesh(filename=os.path.join(esmfdir, "test/data/ne4np4-esmf.nc"), filetype=FileFormat.ESMFMESH) except: @@ -253,7 +253,7 @@ def test_mesh_slicing(self): @pytest.mark.serial def test_slice_mesh_created_from_file_scrip(self): try: - esmfdir = os.path.dirname(inspect.getfile(ESMF)) + esmfdir = os.path.dirname(inspect.getfile(esmpy)) mesh = Mesh(filename=os.path.join(esmfdir, "test/data/ne4np4-pentagons.nc"), filetype=FileFormat.SCRIP, convert_to_dual=True) @@ -276,7 +276,7 @@ def test_slice_mesh_created_from_file_scrip(self): @pytest.mark.serial def test_slice_mesh_created_from_file_esmfmesh(self): try: - esmfdir = os.path.dirname(inspect.getfile(ESMF)) + esmfdir = os.path.dirname(inspect.getfile(esmpy)) mesh = Mesh(filename=os.path.join(esmfdir, "test/data/ne4np4-esmf.nc"), filetype=FileFormat.ESMFMESH) except: @@ -301,7 +301,7 @@ def test_slice_mesh_created_from_file_esmfmesh(self): # TODO: have to define slicing for mesh element coordinates as well.. def test_slice_mesh_created_from_file_elem_coords(self): try: - esmfdir = os.path.dirname(inspect.getfile(ESMF)) + esmfdir = os.path.dirname(inspect.getfile(esmpy)) mesh = Mesh(filename=os.path.join(esmfdir, "test/data/ne30np4-t2.nc"), filetype=FileFormat.SCRIP) except: diff --git a/src/addon/ESMPy/src/ESMF/test/test_api/test_regrid.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_regrid.py similarity index 78% rename from src/addon/ESMPy/src/ESMF/test/test_api/test_regrid.py rename to src/addon/ESMPy/src/esmpy/test/test_api/test_regrid.py index aaac4f78cd..d25f712cc4 100644 --- a/src/addon/ESMPy/src/ESMF/test/test_api/test_regrid.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_regrid.py @@ -6,11 +6,11 @@ import os -from ESMF import * -from ESMF.test.base import TestBase, attr, SkipTest -from ESMF.util.field_utilities import compare_fields -from ESMF.util.grid_utilities import * -from ESMF.util.mesh_utilities import * +from esmpy import * +from esmpy.test.base import TestBase, attr, SkipTest +from esmpy.util.field_utilities import compare_fields +from esmpy.util.grid_utilities import * +from esmpy.util.mesh_utilities import * class TestRegrid(TestBase): @@ -31,9 +31,9 @@ def run_regridding(srcfield, dstfield, srcfracfield, dstfracfield): Field :: dstfracfield \n ''' # call the regridding functions - regridSrc2Dst = ESMF.Regrid(srcfield, dstfield, - regrid_method=ESMF.RegridMethod.CONSERVE, - unmapped_action=ESMF.UnmappedAction.ERROR, + regridSrc2Dst = esmpy.Regrid(srcfield, dstfield, + regrid_method=esmpy.RegridMethod.CONSERVE, + unmapped_action=esmpy.UnmappedAction.ERROR, src_frac_field=srcfracfield, dst_frac_field=dstfracfield) dstfield = regridSrc2Dst(srcfield, dstfield) @@ -248,9 +248,9 @@ def test_field_regrid_file2(self): os.remove(path) mgr.barrier() - srcgrid = ESMF.Grid(np.array([20, 20]), - staggerloc=ESMF.StaggerLoc.CENTER, - coord_sys=ESMF.CoordSys.SPH_DEG) + srcgrid = esmpy.Grid(np.array([20, 20]), + staggerloc=esmpy.StaggerLoc.CENTER, + coord_sys=esmpy.CoordSys.SPH_DEG) # Get and set the source grid coordinates. srcGridCoordLon = srcgrid.get_coords(0) @@ -260,8 +260,8 @@ def test_field_regrid_file2(self): lats = np.linspace(-60, 60, 20) # parallel coordinates - slons_par = lons[srcgrid.lower_bounds[ESMF.StaggerLoc.CENTER][0]:srcgrid.upper_bounds[ESMF.StaggerLoc.CENTER][0]] - slats_par = lats[srcgrid.lower_bounds[ESMF.StaggerLoc.CENTER][1]:srcgrid.upper_bounds[ESMF.StaggerLoc.CENTER][1]] + slons_par = lons[srcgrid.lower_bounds[esmpy.StaggerLoc.CENTER][0]:srcgrid.upper_bounds[esmpy.StaggerLoc.CENTER][0]] + slats_par = lats[srcgrid.lower_bounds[esmpy.StaggerLoc.CENTER][1]:srcgrid.upper_bounds[esmpy.StaggerLoc.CENTER][1]] # make sure to use indexing='ij' as ESMPy backend uses matrix indexing (not Cartesian) lonm, latm = np.meshgrid(slons_par, slats_par, indexing='ij') @@ -269,9 +269,9 @@ def test_field_regrid_file2(self): srcGridCoordLon[:] = lonm srcGridCoordLat[:] = latm - dstgrid = ESMF.Grid(np.array([10, 10]), - staggerloc=ESMF.StaggerLoc.CENTER, - coord_sys=ESMF.CoordSys.SPH_DEG) + dstgrid = esmpy.Grid(np.array([10, 10]), + staggerloc=esmpy.StaggerLoc.CENTER, + coord_sys=esmpy.CoordSys.SPH_DEG) # Get and set the source grid coordinates. dstGridCoordLon = dstgrid.get_coords(0) @@ -281,8 +281,8 @@ def test_field_regrid_file2(self): lats = np.linspace(-60, 60, 10) # parallel coordinates - dlons_par = lons[dstgrid.lower_bounds[ESMF.StaggerLoc.CENTER][0]:dstgrid.upper_bounds[ESMF.StaggerLoc.CENTER][0]] - dlats_par = lats[dstgrid.lower_bounds[ESMF.StaggerLoc.CENTER][1]:dstgrid.upper_bounds[ESMF.StaggerLoc.CENTER][1]] + dlons_par = lons[dstgrid.lower_bounds[esmpy.StaggerLoc.CENTER][0]:dstgrid.upper_bounds[esmpy.StaggerLoc.CENTER][0]] + dlats_par = lats[dstgrid.lower_bounds[esmpy.StaggerLoc.CENTER][1]:dstgrid.upper_bounds[esmpy.StaggerLoc.CENTER][1]] # make sure to use indexing='ij' as ESMPy backend uses matrix indexing (not Cartesian) lonm, latm = np.meshgrid(dlons_par, dlats_par, indexing='ij') @@ -290,12 +290,12 @@ def test_field_regrid_file2(self): dstGridCoordLon[:] = lonm dstGridCoordLat[:] = latm - srcfield = ESMF.Field(srcgrid) - dstfield = ESMF.Field(dstgrid) + srcfield = esmpy.Field(srcgrid) + dstfield = esmpy.Field(dstgrid) - _ = ESMF.Regrid(srcfield, dstfield, filename=filename, - regrid_method=ESMF.RegridMethod.BILINEAR, - unmapped_action=ESMF.UnmappedAction.IGNORE) + _ = esmpy.Regrid(srcfield, dstfield, filename=filename, + regrid_method=esmpy.RegridMethod.BILINEAR, + unmapped_action=esmpy.UnmappedAction.IGNORE) mgr.barrier() self.assertTrue(os.path.exists(filename)) @@ -316,7 +316,7 @@ def tet_field_regrid_file_withaux(self): DD = os.path.join(os.getcwd(), "test/data") if not os.path.isdir(DD): os.makedirs(DD) - from ESMF.util.cache_data import cache_data_file + from esmpy.util.cache_data import cache_data_file cache_data_file(os.path.join(DD, "ll2.5deg_grid.nc")) cache_data_file(os.path.join(DD, "T42_grid.nc")) @@ -329,21 +329,21 @@ def tet_field_regrid_file_withaux(self): mgr.barrier() grid1 = "test/data/ll2.5deg_grid.nc" - srcgrid = ESMF.Grid(filename=grid1, filetype=ESMF.FileFormat.SCRIP, add_corner_stagger=True) + srcgrid = esmpy.Grid(filename=grid1, filetype=esmpy.FileFormat.SCRIP, add_corner_stagger=True) grid2 = "test/data/T42_grid.nc" - dstgrid = ESMF.Grid(filename=grid2, filetype=ESMF.FileFormat.SCRIP, add_corner_stagger=True) + dstgrid = esmpy.Grid(filename=grid2, filetype=esmpy.FileFormat.SCRIP, add_corner_stagger=True) - srcfield = ESMF.Field(srcgrid) - dstfield = ESMF.Field(dstgrid) + srcfield = esmpy.Field(srcgrid) + dstfield = esmpy.Field(dstgrid) - _ = ESMF.Regrid(srcfield, dstfield, filename=filename, - regrid_method=ESMF.RegridMethod.BILINEAR, - unmapped_action=ESMF.UnmappedAction.IGNORE, - filemode=ESMF.FileMode.WITHAUX, + _ = esmpy.Regrid(srcfield, dstfield, filename=filename, + regrid_method=esmpy.RegridMethod.BILINEAR, + unmapped_action=esmpy.UnmappedAction.IGNORE, + filemode=esmpy.FileMode.WITHAUX, src_file=grid1, dst_file=grid2, - src_file_type=ESMF.FileFormat.SCRIP, - dst_file_type=ESMF.FileFormat.SCRIP) + src_file_type=esmpy.FileFormat.SCRIP, + dst_file_type=esmpy.FileFormat.SCRIP) mgr.barrier() self.assertTrue(os.path.exists(filename)) @@ -385,9 +385,9 @@ def test_field_regrid_file3(self): os.remove(path) mgr.barrier() - srcgrid = ESMF.Grid(np.array([20, 20]), - staggerloc=ESMF.StaggerLoc.CENTER, - coord_sys=ESMF.CoordSys.CART) + srcgrid = esmpy.Grid(np.array([20, 20]), + staggerloc=esmpy.StaggerLoc.CENTER, + coord_sys=esmpy.CoordSys.CART) # Get and set the source grid coordinates. srcGridCoordLon = srcgrid.get_coords(0) @@ -397,8 +397,8 @@ def test_field_regrid_file3(self): lats = np.linspace(-60, 60, 20) # parallel coordinates - slons_par = lons[srcgrid.lower_bounds[ESMF.StaggerLoc.CENTER][0]:srcgrid.upper_bounds[ESMF.StaggerLoc.CENTER][0]] - slats_par = lats[srcgrid.lower_bounds[ESMF.StaggerLoc.CENTER][1]:srcgrid.upper_bounds[ESMF.StaggerLoc.CENTER][1]] + slons_par = lons[srcgrid.lower_bounds[esmpy.StaggerLoc.CENTER][0]:srcgrid.upper_bounds[esmpy.StaggerLoc.CENTER][0]] + slats_par = lats[srcgrid.lower_bounds[esmpy.StaggerLoc.CENTER][1]:srcgrid.upper_bounds[esmpy.StaggerLoc.CENTER][1]] # make sure to use indexing='ij' as ESMPy backend uses matrix indexing (not Cartesian) lonm, latm = np.meshgrid(slons_par, slats_par, indexing='ij') @@ -406,9 +406,9 @@ def test_field_regrid_file3(self): srcGridCoordLon[:] = lonm srcGridCoordLat[:] = latm - dstgrid = ESMF.Grid(np.array([10, 10]), - staggerloc=ESMF.StaggerLoc.CENTER, - coord_sys=ESMF.CoordSys.CART) + dstgrid = esmpy.Grid(np.array([10, 10]), + staggerloc=esmpy.StaggerLoc.CENTER, + coord_sys=esmpy.CoordSys.CART) # Get and set the source grid coordinates. dstGridCoordLon = dstgrid.get_coords(0) @@ -418,8 +418,8 @@ def test_field_regrid_file3(self): lats = np.linspace(-60, 60, 10) # parallel coordinates - dlons_par = lons[dstgrid.lower_bounds[ESMF.StaggerLoc.CENTER][0]:dstgrid.upper_bounds[ESMF.StaggerLoc.CENTER][0]] - dlats_par = lats[dstgrid.lower_bounds[ESMF.StaggerLoc.CENTER][1]:dstgrid.upper_bounds[ESMF.StaggerLoc.CENTER][1]] + dlons_par = lons[dstgrid.lower_bounds[esmpy.StaggerLoc.CENTER][0]:dstgrid.upper_bounds[esmpy.StaggerLoc.CENTER][0]] + dlats_par = lats[dstgrid.lower_bounds[esmpy.StaggerLoc.CENTER][1]:dstgrid.upper_bounds[esmpy.StaggerLoc.CENTER][1]] # make sure to use indexing='ij' as ESMPy backend uses matrix indexing (not Cartesian) lonm, latm = np.meshgrid(dlons_par, dlats_par, indexing='ij') @@ -428,9 +428,9 @@ def test_field_regrid_file3(self): dstGridCoordLat[:] = latm - srcfield = ESMF.Field(srcgrid) - dstfield = ESMF.Field(dstgrid) - xctfield = ESMF.Field(dstgrid) + srcfield = esmpy.Field(srcgrid) + dstfield = esmpy.Field(dstgrid) + xctfield = esmpy.Field(dstgrid) srcfield.data[:,:] = 24 xctfield.data[:,:] = 24 @@ -439,9 +439,9 @@ def test_field_regrid_file3(self): self.assertTrue(np.all(srcfield.data[:,:] == 24)) self.assertTrue(np.all(dstfield.data[:,:] == 0)) - regridS2D = ESMF.Regrid(srcfield, dstfield, filename=filename, - regrid_method=ESMF.RegridMethod.BILINEAR, - unmapped_action=ESMF.UnmappedAction.ERROR, + regridS2D = esmpy.Regrid(srcfield, dstfield, filename=filename, + regrid_method=esmpy.RegridMethod.BILINEAR, + unmapped_action=esmpy.UnmappedAction.ERROR, create_rh=True, ignore_degenerate=False) mgr.barrier() @@ -451,7 +451,7 @@ def test_field_regrid_file3(self): self.assertTrue(np.all(srcfield.data[:,:] == 24)) self.assertNumpyAllClose(xctfield.data, dstfield.data) - regridS2D = ESMF.RegridFromFile(srcfield, dstfield, filename) + regridS2D = esmpy.RegridFromFile(srcfield, dstfield, filename) mgr.barrier() self.assertTrue(np.all(srcfield.data[:,:] == 24)) @@ -480,9 +480,9 @@ def test_field_regrid_file4(self): os.remove(path) mgr.barrier() - srcgrid = ESMF.Grid(np.array([20, 20]), - staggerloc=ESMF.StaggerLoc.CENTER, - coord_sys=ESMF.CoordSys.CART) + srcgrid = esmpy.Grid(np.array([20, 20]), + staggerloc=esmpy.StaggerLoc.CENTER, + coord_sys=esmpy.CoordSys.CART) # Get and set the source grid coordinates. srcGridCoordLon = srcgrid.get_coords(0) @@ -492,8 +492,8 @@ def test_field_regrid_file4(self): lats = np.linspace(-60, 60, 20) # parallel coordinates - slons_par = lons[srcgrid.lower_bounds[ESMF.StaggerLoc.CENTER][0]:srcgrid.upper_bounds[ESMF.StaggerLoc.CENTER][0]] - slats_par = lats[srcgrid.lower_bounds[ESMF.StaggerLoc.CENTER][1]:srcgrid.upper_bounds[ESMF.StaggerLoc.CENTER][1]] + slons_par = lons[srcgrid.lower_bounds[esmpy.StaggerLoc.CENTER][0]:srcgrid.upper_bounds[esmpy.StaggerLoc.CENTER][0]] + slats_par = lats[srcgrid.lower_bounds[esmpy.StaggerLoc.CENTER][1]:srcgrid.upper_bounds[esmpy.StaggerLoc.CENTER][1]] # make sure to use indexing='ij' as ESMPy backend uses matrix indexing (not Cartesian) lonm, latm = np.meshgrid(slons_par, slats_par, indexing='ij') @@ -501,9 +501,9 @@ def test_field_regrid_file4(self): srcGridCoordLon[:] = lonm srcGridCoordLat[:] = latm - dstgrid = ESMF.Grid(np.array([10, 10]), - staggerloc=ESMF.StaggerLoc.CENTER, - coord_sys=ESMF.CoordSys.CART) + dstgrid = esmpy.Grid(np.array([10, 10]), + staggerloc=esmpy.StaggerLoc.CENTER, + coord_sys=esmpy.CoordSys.CART) # Get and set the source grid coordinates. dstGridCoordLon = dstgrid.get_coords(0) @@ -513,8 +513,8 @@ def test_field_regrid_file4(self): lats = np.linspace(-60, 60, 10) # parallel coordinates - dlons_par = lons[dstgrid.lower_bounds[ESMF.StaggerLoc.CENTER][0]:dstgrid.upper_bounds[ESMF.StaggerLoc.CENTER][0]] - dlats_par = lats[dstgrid.lower_bounds[ESMF.StaggerLoc.CENTER][1]:dstgrid.upper_bounds[ESMF.StaggerLoc.CENTER][1]] + dlons_par = lons[dstgrid.lower_bounds[esmpy.StaggerLoc.CENTER][0]:dstgrid.upper_bounds[esmpy.StaggerLoc.CENTER][0]] + dlats_par = lats[dstgrid.lower_bounds[esmpy.StaggerLoc.CENTER][1]:dstgrid.upper_bounds[esmpy.StaggerLoc.CENTER][1]] # make sure to use indexing='ij' as ESMPy backend uses matrix indexing (not Cartesian) lonm, latm = np.meshgrid(dlons_par, dlats_par, indexing='ij') @@ -523,9 +523,9 @@ def test_field_regrid_file4(self): dstGridCoordLat[:] = latm - srcfield = ESMF.Field(srcgrid) - dstfield = ESMF.Field(dstgrid) - xctfield = ESMF.Field(dstgrid) + srcfield = esmpy.Field(srcgrid) + dstfield = esmpy.Field(dstgrid) + xctfield = esmpy.Field(dstgrid) srcfield.data[:,:] = 24 xctfield.data[:,:] = 24 @@ -534,10 +534,10 @@ def test_field_regrid_file4(self): self.assertTrue(np.all(srcfield.data[:,:] == 24)) self.assertTrue(np.all(dstfield.data[:,:] == 0)) - regridS2D = ESMF.Regrid(srcfield, dstfield, + regridS2D = esmpy.Regrid(srcfield, dstfield, rh_filename=filename, - regrid_method=ESMF.RegridMethod.BILINEAR, - unmapped_action=ESMF.UnmappedAction.ERROR, + regrid_method=esmpy.RegridMethod.BILINEAR, + unmapped_action=esmpy.UnmappedAction.ERROR, create_rh=True, ignore_degenerate=False) mgr.barrier() @@ -547,7 +547,7 @@ def test_field_regrid_file4(self): self.assertTrue(np.all(srcfield.data[:,:] == 24)) self.assertNumpyAllClose(xctfield.data, dstfield.data) - regridS2D = ESMF.RegridFromFile(srcfield, dstfield, rh_filename=filename) + regridS2D = esmpy.RegridFromFile(srcfield, dstfield, rh_filename=filename) mgr.barrier() self.assertTrue(np.all(srcfield.data[:,:] == 24)) @@ -697,13 +697,13 @@ def test_field_regrid_zeroregion_select_ndbounds(self): # Compute the regrid from file route handle rh2 = RegridFromFile(srcfield, dstfield, filename=filename) self.assertTrue(np.all(dstfield.data == -999)) - dstfield = rh2(srcfield, dstfield, zero_region=ESMF.Region.SELECT) + dstfield = rh2(srcfield, dstfield, zero_region=esmpy.Region.SELECT) # Assert fill values are retained self.assertGreater(np.sum(dstfield.data == 33.33), 10) self.assertGreater(np.sum(dstfield.data == -999), 10) - if (ESMF.local_pet() == 0): + if (esmpy.local_pet() == 0): if os.path.exists(filename): os.remove(filename) @@ -764,23 +764,23 @@ def test_field_regrid_periodic(self): dstgrid = grid_create_from_bounds_periodic(55, 28, corners=True) # create the Fields - srcfield = ESMF.Field(srcgrid, name='srcfield') - dstfield = ESMF.Field(dstgrid, name='dstfield') - exactfield = ESMF.Field(dstgrid, name='exactfield') + srcfield = esmpy.Field(srcgrid, name='srcfield') + dstfield = esmpy.Field(dstgrid, name='dstfield') + exactfield = esmpy.Field(dstgrid, name='exactfield') # create the fraction fields - srcfracfield = ESMF.Field(srcgrid, name='srcfracfield') - dstfracfield = ESMF.Field(dstgrid, name='dstfracfield') + srcfracfield = esmpy.Field(srcgrid, name='srcfracfield') + dstfracfield = esmpy.Field(dstgrid, name='dstfracfield') # initialize the Fields to an analytic function srcfield = initialize_field_grid_periodic(srcfield) exact_field = initialize_field_grid_periodic(exactfield) # run the ESMF regridding - regridSrc2Dst = ESMF.Regrid(srcfield, dstfield, + regridSrc2Dst = esmpy.Regrid(srcfield, dstfield, src_mask_values=np.array([0]), - regrid_method=ESMF.RegridMethod.CONSERVE, - unmapped_action=ESMF.UnmappedAction.ERROR, + regrid_method=esmpy.RegridMethod.CONSERVE, + unmapped_action=esmpy.UnmappedAction.ERROR, src_frac_field=srcfracfield, dst_frac_field=dstfracfield) dstfield = regridSrc2Dst(srcfield, dstfield) @@ -808,18 +808,18 @@ def test_grid_grid_3d_bilinear_cartesian(self): dstgrid = grid_create_from_bounds_3d([0.5, 19.5], [0.5, 19.5], [0.5, 19.5], 19, 19, 19, corners=False) # create Field objects on the Meshes - srcfield = ESMF.Field(srcgrid, name='srcfield') - dstfield = ESMF.Field(dstgrid, name='dstfield') - exactfield = ESMF.Field(dstgrid, name='exactfield') + srcfield = esmpy.Field(srcgrid, name='srcfield') + dstfield = esmpy.Field(dstgrid, name='dstfield') + exactfield = esmpy.Field(dstgrid, name='exactfield') # initialize the Fields to an analytic function srcfield = initialize_field_grid_3d(srcfield) exactfield = initialize_field_grid_3d(exactfield) # run the ESMF regridding - regridSrc2Dst = ESMF.Regrid(srcfield, dstfield, - regrid_method=ESMF.RegridMethod.BILINEAR, - unmapped_action=ESMF.UnmappedAction.ERROR) + regridSrc2Dst = esmpy.Regrid(srcfield, dstfield, + regrid_method=esmpy.RegridMethod.BILINEAR, + unmapped_action=esmpy.UnmappedAction.ERROR) dstfield = regridSrc2Dst(srcfield, dstfield) # compare results and output PASS or FAIL @@ -838,18 +838,18 @@ def test_grid_grid_3d_bilinear_spherical(self): dstgrid = grid_create_from_bounds_periodic_3d(50, 50, 11, corners=False) # create Field objects on the Meshes - srcfield = ESMF.Field(srcgrid, name='srcfield') - dstfield = ESMF.Field(dstgrid, name='dstfield') - exactfield = ESMF.Field(dstgrid, name='exactfield') + srcfield = esmpy.Field(srcgrid, name='srcfield') + dstfield = esmpy.Field(dstgrid, name='dstfield') + exactfield = esmpy.Field(dstgrid, name='exactfield') # initialize the Fields to an analytic function srcfield = initialize_field_grid_periodic_3d(srcfield) exactfield = initialize_field_grid_periodic_3d(exactfield) # run the ESMF regridding - regridSrc2Dst = ESMF.Regrid(srcfield, dstfield, - regrid_method=ESMF.RegridMethod.BILINEAR, - unmapped_action=ESMF.UnmappedAction.IGNORE) + regridSrc2Dst = esmpy.Regrid(srcfield, dstfield, + regrid_method=esmpy.RegridMethod.BILINEAR, + unmapped_action=esmpy.UnmappedAction.IGNORE) dstfield = regridSrc2Dst(srcfield, dstfield) # compare results and output PASS or FAIL @@ -868,20 +868,20 @@ def test_grid_grid_regrid_csrv_mask_3D(self): dstgrid = grid_create_from_bounds_3d([0.5, 19.5], [0.5, 19.5], [0.5, 19.5], 19, 19, 19, corners=True) # create Field objects on the Meshes - srcfield = ESMF.Field(srcgrid, name='srcfield') - srcfracfield = ESMF.Field(srcgrid, name='srcfracfield') - dstfield = ESMF.Field(dstgrid, name='dstfield') - dstfracfield = ESMF.Field(dstgrid, name='dstfracfield') - exactfield = ESMF.Field(dstgrid, name='exactfield') + srcfield = esmpy.Field(srcgrid, name='srcfield') + srcfracfield = esmpy.Field(srcgrid, name='srcfracfield') + dstfield = esmpy.Field(dstgrid, name='dstfield') + dstfracfield = esmpy.Field(dstgrid, name='dstfracfield') + exactfield = esmpy.Field(dstgrid, name='exactfield') # initialize the Fields to an analytic function srcfield = initialize_field_grid_3d(srcfield) exactfield = initialize_field_grid_3d(exactfield) # run the ESMF regridding - regridSrc2Dst = ESMF.Regrid(srcfield, dstfield, - regrid_method=ESMF.RegridMethod.CONSERVE, - unmapped_action=ESMF.UnmappedAction.ERROR, + regridSrc2Dst = esmpy.Regrid(srcfield, dstfield, + regrid_method=esmpy.RegridMethod.CONSERVE, + unmapped_action=esmpy.UnmappedAction.ERROR, src_frac_field=srcfracfield, dst_frac_field=dstfracfield) dstfield = regridSrc2Dst(srcfield, dstfield) @@ -909,21 +909,21 @@ def test_grid_grid_regrid_csrv_mask(self): dstgrid = grid_create_from_bounds([0.5, 19.5], [0.5, 19.5], 19, 19, corners=True) # create Field objects on the Meshes - srcfield = ESMF.Field(srcgrid, name='srcfield') - srcfracfield = ESMF.Field(srcgrid, name='srcfracfield') - dstfield = ESMF.Field(dstgrid, name='dstfield') - dstfracfield = ESMF.Field(dstgrid, name='dstfracfield') - exactfield = ESMF.Field(dstgrid, name='exactfield') + srcfield = esmpy.Field(srcgrid, name='srcfield') + srcfracfield = esmpy.Field(srcgrid, name='srcfracfield') + dstfield = esmpy.Field(dstgrid, name='dstfield') + dstfracfield = esmpy.Field(dstgrid, name='dstfracfield') + exactfield = esmpy.Field(dstgrid, name='exactfield') # initialize the Fields to an analytic function srcfield = initialize_field_grid(srcfield) dstfield2 = initialize_field_grid(exactfield) # run the ESMF regridding - regridSrc2Dst = ESMF.Regrid(srcfield, dstfield, + regridSrc2Dst = esmpy.Regrid(srcfield, dstfield, src_mask_values=np.array([0]), - regrid_method=ESMF.RegridMethod.CONSERVE, - unmapped_action=ESMF.UnmappedAction.ERROR, + regrid_method=esmpy.RegridMethod.CONSERVE, + unmapped_action=esmpy.UnmappedAction.ERROR, src_frac_field=srcfracfield, dst_frac_field=dstfracfield) dstfield = regridSrc2Dst(srcfield, dstfield) @@ -951,21 +951,21 @@ def test_grid_grid_regrid_csrv_2nd_mask(self): dstgrid = grid_create_from_bounds([0.5, 19.5], [0.5, 19.5], 19, 19, corners=True) # create Field objects on the Meshes - srcfield = ESMF.Field(srcgrid, name='srcfield') - srcfracfield = ESMF.Field(srcgrid, name='srcfracfield') - dstfield = ESMF.Field(dstgrid, name='dstfield') - dstfracfield = ESMF.Field(dstgrid, name='dstfracfield') - exactfield = ESMF.Field(dstgrid, name='exactfield') + srcfield = esmpy.Field(srcgrid, name='srcfield') + srcfracfield = esmpy.Field(srcgrid, name='srcfracfield') + dstfield = esmpy.Field(dstgrid, name='dstfield') + dstfracfield = esmpy.Field(dstgrid, name='dstfracfield') + exactfield = esmpy.Field(dstgrid, name='exactfield') # initialize the Fields to an analytic function srcfield = initialize_field_grid(srcfield) dstfield2 = initialize_field_grid(exactfield) # run the ESMF regridding - regridSrc2Dst = ESMF.Regrid(srcfield, dstfield, + regridSrc2Dst = esmpy.Regrid(srcfield, dstfield, src_mask_values=np.array([0]), - regrid_method=ESMF.RegridMethod.CONSERVE_2ND, - unmapped_action=ESMF.UnmappedAction.ERROR, + regrid_method=esmpy.RegridMethod.CONSERVE_2ND, + unmapped_action=esmpy.UnmappedAction.ERROR, src_frac_field=srcfracfield, dst_frac_field=dstfracfield) dstfield = regridSrc2Dst(srcfield, dstfield) @@ -993,25 +993,25 @@ def test_grid_grid_regrid_srcmask_types(self): # create two unique Grid objects srcgrid = grid_create_from_bounds([0, 21], [0, 21], 21, 21, corners=True, domask=True, - ctk=ESMF.TypeKind.R4) + ctk=esmpy.TypeKind.R4) dstgrid = grid_create_from_bounds([0.5, 19.5], [0.5, 19.5], 19, 19, corners=True) # create Field objects on the Meshes - srcfield = ESMF.Field(srcgrid, name='srcfield') - srcfracfield = ESMF.Field(srcgrid, name='srcfracfield') - dstfield = ESMF.Field(dstgrid, name='dstfield') - dstfracfield = ESMF.Field(dstgrid, name='dstfracfield') - exactfield = ESMF.Field(dstgrid, name='exactfield') + srcfield = esmpy.Field(srcgrid, name='srcfield') + srcfracfield = esmpy.Field(srcgrid, name='srcfracfield') + dstfield = esmpy.Field(dstgrid, name='dstfield') + dstfracfield = esmpy.Field(dstgrid, name='dstfracfield') + exactfield = esmpy.Field(dstgrid, name='exactfield') # initialize the Fields to an analytic function srcfield = initialize_field_grid(srcfield) dstfield2 = initialize_field_grid(exactfield) # run the ESMF regridding - regridSrc2Dst = ESMF.Regrid(srcfield, dstfield, + regridSrc2Dst = esmpy.Regrid(srcfield, dstfield, src_mask_values=[0], - regrid_method=ESMF.RegridMethod.CONSERVE, - unmapped_action=ESMF.UnmappedAction.ERROR, + regrid_method=esmpy.RegridMethod.CONSERVE, + unmapped_action=esmpy.UnmappedAction.ERROR, src_frac_field=srcfracfield, dst_frac_field=dstfracfield) dstfield = regridSrc2Dst(srcfield, dstfield) @@ -1052,13 +1052,13 @@ def test_grid_mesh_regrid_csrv_mask(self): grid = grid_create_from_bounds([0, 4], [0, 4], 8, 8, corners=True, doarea=True) # create Field objects on the Meshes - srcfield = ESMF.Field(mesh, name='srcfield', meshloc=ESMF.MeshLoc.ELEMENT) - srcfracfield = ESMF.Field(mesh, name='srcfracfield', meshloc=ESMF.MeshLoc.ELEMENT) + srcfield = esmpy.Field(mesh, name='srcfield', meshloc=esmpy.MeshLoc.ELEMENT) + srcfracfield = esmpy.Field(mesh, name='srcfracfield', meshloc=esmpy.MeshLoc.ELEMENT) # make gridded fields - exactfield = ESMF.Field(grid, name='exactfield') - dstfield = ESMF.Field(grid, name='dstfield') - dstfracfield = ESMF.Field(grid, name='dstfracfield') + exactfield = esmpy.Field(grid, name='exactfield') + dstfield = esmpy.Field(grid, name='dstfield') + dstfracfield = esmpy.Field(grid, name='dstfracfield') # initialize the Fields to an analytic function srcfield = initialize_field_mesh(srcfield, nodeCoord, nodeOwner, elemType, elemConn, @@ -1066,10 +1066,10 @@ def test_grid_mesh_regrid_csrv_mask(self): exactfield = initialize_field_grid(exactfield) # run the ESMF regridding - regridSrc2Dst = ESMF.Regrid(srcfield, dstfield, + regridSrc2Dst = esmpy.Regrid(srcfield, dstfield, src_mask_values=np.array([0]), - regrid_method=ESMF.RegridMethod.CONSERVE, - unmapped_action=ESMF.UnmappedAction.ERROR, + regrid_method=esmpy.RegridMethod.CONSERVE, + unmapped_action=esmpy.UnmappedAction.ERROR, src_frac_field=srcfracfield, dst_frac_field=dstfracfield) dstfield = regridSrc2Dst(srcfield, dstfield) @@ -1110,21 +1110,21 @@ def test_grid_mesh_regrid_csrv(self): grid = grid_create_from_bounds([0, 4], [0, 4], 8, 8, corners=True) # create Fields - srcfield = ESMF.Field(mesh, name='srcfield', meshloc=ESMF.MeshLoc.ELEMENT) - srcfracfield = ESMF.Field(mesh, name='srcfracfield', meshloc=ESMF.MeshLoc.ELEMENT) - dstfield = ESMF.Field(grid, name='dstfield') - dstfracfield = ESMF.Field(grid, name='dstfracfield') - exactfield = ESMF.Field(grid, name='exactfield') + srcfield = esmpy.Field(mesh, name='srcfield', meshloc=esmpy.MeshLoc.ELEMENT) + srcfracfield = esmpy.Field(mesh, name='srcfracfield', meshloc=esmpy.MeshLoc.ELEMENT) + dstfield = esmpy.Field(grid, name='dstfield') + dstfracfield = esmpy.Field(grid, name='dstfracfield') + exactfield = esmpy.Field(grid, name='exactfield') # initialize the Fields to an analytic function srcfield = initialize_field_mesh(srcfield, nodeCoord, nodeOwner, elemType, elemConn) exactfield = initialize_field_grid(exactfield) # run the ESMF regridding - regridSrc2Dst = ESMF.Regrid(srcfield, dstfield, - regrid_method=ESMF.RegridMethod.CONSERVE, - norm_type=ESMF.NormType.FRACAREA, - unmapped_action=ESMF.UnmappedAction.ERROR, + regridSrc2Dst = esmpy.Regrid(srcfield, dstfield, + regrid_method=esmpy.RegridMethod.CONSERVE, + norm_type=esmpy.NormType.FRACAREA, + unmapped_action=esmpy.UnmappedAction.ERROR, src_frac_field=srcfracfield, dst_frac_field=dstfracfield) dstfield = regridSrc2Dst(srcfield, dstfield) @@ -1166,25 +1166,25 @@ def test_grid_mesh_regrid_mask(self): mesh_create_50() # create Field objects - srcfield = ESMF.Field(mesh, name='srcfield') - dstfield = ESMF.Field(grid, name='dstfield') - exactfield = ESMF.Field(grid, name='exactfield') + srcfield = esmpy.Field(mesh, name='srcfield') + dstfield = esmpy.Field(grid, name='dstfield') + exactfield = esmpy.Field(grid, name='exactfield') # initialize the Fields to an analytic function srcfield = initialize_field_mesh(srcfield, nodeCoord, nodeOwner, elemType, elemConn) exactfield = initialize_field_grid(exactfield, domask=True) # run the ESMF regridding - regridSrc2Dst = ESMF.Regrid(srcfield, dstfield, + regridSrc2Dst = esmpy.Regrid(srcfield, dstfield, dst_mask_values=np.array([0]), - regrid_method=ESMF.RegridMethod.BILINEAR, - unmapped_action=ESMF.UnmappedAction.IGNORE) + regrid_method=esmpy.RegridMethod.BILINEAR, + unmapped_action=esmpy.UnmappedAction.IGNORE) dstfield = regridSrc2Dst(srcfield, dstfield) # compare results and output PASS or FAIL meanrel, csrvrel, correct = compare_fields(dstfield, exactfield, 20E-1, 20E-1, 10E-16, - regrid_method=ESMF.RegridMethod.BILINEAR) + regrid_method=esmpy.RegridMethod.BILINEAR) self.assertAlmostEqual(meanrel, 0.0) self.assertAlmostEqual(csrvrel, 0.0) @@ -1211,24 +1211,24 @@ def test_grid_mesh_regrid(self): mesh_create_50() # create Field objects - srcfield = ESMF.Field(mesh, name='srcfield') - dstfield = ESMF.Field(grid, name='dstfield') - exactfield = ESMF.Field(grid, name='exactfield') + srcfield = esmpy.Field(mesh, name='srcfield') + dstfield = esmpy.Field(grid, name='dstfield') + exactfield = esmpy.Field(grid, name='exactfield') # initialize the Fields to an analytic function srcfield = initialize_field_mesh(srcfield, nodeCoord, nodeOwner, elemType, elemConn) exactfield = initialize_field_grid(exactfield) # run the ESMF regridding - regridSrc2Dst = ESMF.Regrid(srcfield, dstfield, - regrid_method=ESMF.RegridMethod.BILINEAR, - unmapped_action=ESMF.UnmappedAction.ERROR) + regridSrc2Dst = esmpy.Regrid(srcfield, dstfield, + regrid_method=esmpy.RegridMethod.BILINEAR, + unmapped_action=esmpy.UnmappedAction.ERROR) dstfield = regridSrc2Dst(srcfield, dstfield) # compare results and output PASS or FAIL meanrel, csrvrel, correct = compare_fields(dstfield, exactfield, 40E-2, 40E-2, 10E-16, - regrid_method=ESMF.RegridMethod.BILINEAR) + regrid_method=esmpy.RegridMethod.BILINEAR) self.assertAlmostEqual(meanrel, 0.0) self.assertAlmostEqual(csrvrel, 0.0) @@ -1255,27 +1255,27 @@ def test_field_regrid_extrapolation(self): mesh_create_50() # create Field objects - srcfield = ESMF.Field(grid, name='srcfield') - dstfield = ESMF.Field(mesh, name='dstfield') - exactfield = ESMF.Field(mesh, name='exactfield') + srcfield = esmpy.Field(grid, name='srcfield') + dstfield = esmpy.Field(mesh, name='dstfield') + exactfield = esmpy.Field(mesh, name='exactfield') # initialize the Fields to an analytic function srcfield = initialize_field_grid(srcfield) exactfield = initialize_field_mesh(exactfield, nodeCoord, nodeOwner, elemType, elemConn) # run the ESMF regridding - regridSrc2Dst = ESMF.Regrid(srcfield, dstfield, - regrid_method=ESMF.RegridMethod.BILINEAR, - extrap_method=ESMF.ExtrapMethod.NEAREST_IDAVG, + regridSrc2Dst = esmpy.Regrid(srcfield, dstfield, + regrid_method=esmpy.RegridMethod.BILINEAR, + extrap_method=esmpy.ExtrapMethod.NEAREST_IDAVG, extrap_num_src_pnts=10, extrap_dist_exponent=1.2, - unmapped_action=ESMF.UnmappedAction.ERROR) + unmapped_action=esmpy.UnmappedAction.ERROR) dstfield = regridSrc2Dst(srcfield, dstfield) # compare results and output PASS or FAIL meanrel, csrvrel, correct = compare_fields(dstfield, exactfield, 40E-2, 40E-2, 10E-16, - regrid_method=ESMF.RegridMethod.BILINEAR) + regrid_method=esmpy.RegridMethod.BILINEAR) self.assertAlmostEqual(meanrel, 0.0) self.assertAlmostEqual(csrvrel, 0.0) @@ -1302,25 +1302,25 @@ def test_field_regrid_extrapolation_creepfill(self): mesh_create_50() # create Field objects - srcfield = ESMF.Field(mesh, name='dstfield') - dstfield = ESMF.Field(grid, name='srcfield') - exactfield = ESMF.Field(grid, name='exactfield') + srcfield = esmpy.Field(mesh, name='dstfield') + dstfield = esmpy.Field(grid, name='srcfield') + exactfield = esmpy.Field(grid, name='exactfield') # initialize the Fields to an analytic function srcfield = initialize_field_mesh(srcfield, nodeCoord, nodeOwner, elemType, elemConn) exactfield = initialize_field_grid(exactfield) # run the ESMF regridding - regridSrc2Dst = ESMF.Regrid(srcfield, dstfield, - regrid_method=ESMF.RegridMethod.BILINEAR, - extrap_method=ESMF.ExtrapMethod.CREEP_FILL, + regridSrc2Dst = esmpy.Regrid(srcfield, dstfield, + regrid_method=esmpy.RegridMethod.BILINEAR, + extrap_method=esmpy.ExtrapMethod.CREEP_FILL, extrap_num_levels=100) dstfield = regridSrc2Dst(srcfield, dstfield) # compare results and output PASS or FAIL meanrel, csrvrel, correct = compare_fields(dstfield, exactfield, 40E-2, 40E-2, 10E-16, - regrid_method=ESMF.RegridMethod.BILINEAR) + regrid_method=esmpy.RegridMethod.BILINEAR) self.assertAlmostEqual(meanrel, 0.0) self.assertAlmostEqual(csrvrel, 0.0) @@ -1348,11 +1348,11 @@ def test_mesh_mesh_regrid(self): mesh_create_10() # create ESMP_Field objects on the Meshes - srcfield = ESMF.Field(srcmesh, name='srcfield', meshloc=ESMF.MeshLoc.ELEMENT) - srcfracfield = ESMF.Field(srcmesh, name='srcfracfield', meshloc=ESMF.MeshLoc.ELEMENT) - dstfield = ESMF.Field(dstmesh, name='dstfield', meshloc=ESMF.MeshLoc.ELEMENT) - dstfracfield = ESMF.Field(dstmesh, name='dstfracfield', meshloc=ESMF.MeshLoc.ELEMENT) - exactfield = ESMF.Field(dstmesh, name='exactfield', meshloc=ESMF.MeshLoc.ELEMENT) + srcfield = esmpy.Field(srcmesh, name='srcfield', meshloc=esmpy.MeshLoc.ELEMENT) + srcfracfield = esmpy.Field(srcmesh, name='srcfracfield', meshloc=esmpy.MeshLoc.ELEMENT) + dstfield = esmpy.Field(dstmesh, name='dstfield', meshloc=esmpy.MeshLoc.ELEMENT) + dstfracfield = esmpy.Field(dstmesh, name='dstfracfield', meshloc=esmpy.MeshLoc.ELEMENT) + exactfield = esmpy.Field(dstmesh, name='exactfield', meshloc=esmpy.MeshLoc.ELEMENT) # initialize the Fields to an analytic function srcfield = initialize_field_mesh(srcfield, nodeCoordSrc, nodeOwnerSrc, @@ -1361,10 +1361,10 @@ def test_mesh_mesh_regrid(self): elemTypeDst, elemConnDst) # run the ESMF regridding - regridSrc2Dst = ESMF.Regrid(srcfield, dstfield, - regrid_method=ESMF.RegridMethod.CONSERVE, - norm_type=ESMF.NormType.FRACAREA, - unmapped_action=ESMF.UnmappedAction.ERROR, + regridSrc2Dst = esmpy.Regrid(srcfield, dstfield, + regrid_method=esmpy.RegridMethod.CONSERVE, + norm_type=esmpy.NormType.FRACAREA, + unmapped_action=esmpy.UnmappedAction.ERROR, ignore_degenerate=True, src_frac_field=srcfracfield, dst_frac_field=dstfracfield) @@ -1407,13 +1407,13 @@ def est_grid_mesh_pentatri_regrid_csrv(self): grid = grid_create_from_bounds([0, 4], [0, 4], 8, 8, corners=True, doarea=True) # create Field objects on the Meshes - srcfield = ESMF.Field(mesh, name='srcfield', meshloc=ESMF.MeshLoc.ELEMENT) - srcfracfield = ESMF.Field(mesh, name='srcfracfield', meshloc=ESMF.MeshLoc.ELEMENT) + srcfield = esmpy.Field(mesh, name='srcfield', meshloc=esmpy.MeshLoc.ELEMENT) + srcfracfield = esmpy.Field(mesh, name='srcfracfield', meshloc=esmpy.MeshLoc.ELEMENT) # make gridded fields - exactfield = ESMF.Field(grid, name='exactfield') - dstfield = ESMF.Field(grid, name='dstfield') - dstfracfield = ESMF.Field(grid, name='dstfracfield') + exactfield = esmpy.Field(grid, name='exactfield') + dstfield = esmpy.Field(grid, name='dstfield') + dstfracfield = esmpy.Field(grid, name='dstfracfield') # initialize the Fields to an analytic function # srcfield = initialize_field_mesh(srcfield, nodeCoord, nodeOwner, elemType, elemConn) @@ -1423,9 +1423,9 @@ def est_grid_mesh_pentatri_regrid_csrv(self): exactfield.data[...] = 25. # run the ESMF regridding - regridSrc2Dst = ESMF.Regrid(srcfield, dstfield, - regrid_method=ESMF.RegridMethod.CONSERVE, - unmapped_action=ESMF.UnmappedAction.ERROR, + regridSrc2Dst = esmpy.Regrid(srcfield, dstfield, + regrid_method=esmpy.RegridMethod.CONSERVE, + unmapped_action=esmpy.UnmappedAction.ERROR, src_frac_field=srcfracfield, dst_frac_field=dstfracfield) dstfield = regridSrc2Dst(srcfield, dstfield) @@ -1446,7 +1446,7 @@ def est_grid_mesh_pentatri_regrid_csrv(self): # TODO: this test is disable, I don't remember why def est_grid_mesh_pentatri_regrid_csrv_simple(self): - if ESMF.pet_count() > 1: + if esmpy.pet_count() > 1: raise NameError('This test can only be run in serial!') # create a Mesh @@ -1457,13 +1457,13 @@ def est_grid_mesh_pentatri_regrid_csrv_simple(self): grid = grid_create_from_bounds([0, 4], [0, 4], 8, 8, corners=True, doarea=True) # create Field objects on the Meshes - srcfield = ESMF.Field(mesh, name='srcfield', meshloc=ESMF.MeshLoc.ELEMENT) - srcfracfield = ESMF.Field(mesh, name='srcfracfield', meshloc=ESMF.MeshLoc.ELEMENT) + srcfield = esmpy.Field(mesh, name='srcfield', meshloc=esmpy.MeshLoc.ELEMENT) + srcfracfield = esmpy.Field(mesh, name='srcfracfield', meshloc=esmpy.MeshLoc.ELEMENT) # make gridded fields - exactfield = ESMF.Field(grid, name='exactfield') - dstfield = ESMF.Field(grid, name='dstfield') - dstfracfield = ESMF.Field(grid, name='dstfracfield') + exactfield = esmpy.Field(grid, name='exactfield') + dstfield = esmpy.Field(grid, name='dstfield') + dstfracfield = esmpy.Field(grid, name='dstfracfield') # initialize the Fields to an analytic function # srcfield = initialize_field_mesh(srcfield, nodeCoord, nodeOwner, elemType, elemConn) @@ -1473,9 +1473,9 @@ def est_grid_mesh_pentatri_regrid_csrv_simple(self): exactfield.data[...] = 25. # run the ESMF regridding - regridSrc2Dst = ESMF.Regrid(srcfield, dstfield, - regrid_method=ESMF.RegridMethod.CONSERVE, - unmapped_action=ESMF.UnmappedAction.ERROR, + regridSrc2Dst = esmpy.Regrid(srcfield, dstfield, + regrid_method=esmpy.RegridMethod.CONSERVE, + unmapped_action=esmpy.UnmappedAction.ERROR, src_frac_field=srcfracfield, dst_frac_field=dstfracfield) dstfield = regridSrc2Dst(srcfield, dstfield) @@ -1516,11 +1516,11 @@ def test_grid_mesh_pentatri_regrid_bilinear(self): grid = grid_create_from_bounds([0, 4], [0, 4], 8, 8, corners=True, doarea=True) # create Field objects on the Meshes - srcfield = ESMF.Field(mesh, name='srcfield', meshloc=ESMF.MeshLoc.NODE) + srcfield = esmpy.Field(mesh, name='srcfield', meshloc=esmpy.MeshLoc.NODE) # make gridded fields - exactfield = ESMF.Field(grid, name='exactfield') - dstfield = ESMF.Field(grid, name='dstfield') + exactfield = esmpy.Field(grid, name='exactfield') + dstfield = esmpy.Field(grid, name='dstfield') # initialize the Fields to an analytic function # srcfield = initialize_field_mesh(srcfield, nodeCoord, nodeOwner, elemType, elemConn) @@ -1530,9 +1530,9 @@ def test_grid_mesh_pentatri_regrid_bilinear(self): exactfield.data[...] = 25. # run the ESMF regridding - regridSrc2Dst = ESMF.Regrid(srcfield, dstfield, - regrid_method=ESMF.RegridMethod.BILINEAR, - unmapped_action=ESMF.UnmappedAction.ERROR) + regridSrc2Dst = esmpy.Regrid(srcfield, dstfield, + regrid_method=esmpy.RegridMethod.BILINEAR, + unmapped_action=esmpy.UnmappedAction.ERROR) dstfield = regridSrc2Dst(srcfield, dstfield) # compare results and output PASS or FAIL diff --git a/src/addon/ESMPy/src/ESMF/test/test_api/test_vm.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_vm.py similarity index 89% rename from src/addon/ESMPy/src/ESMF/test/test_api/test_vm.py rename to src/addon/ESMPy/src/esmpy/test/test_api/test_vm.py index 52234f2b25..4f3a544a18 100644 --- a/src/addon/ESMPy/src/ESMF/test/test_api/test_vm.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_vm.py @@ -2,9 +2,9 @@ vm unit test file """ -from ESMF import * -from ESMF.interface.cbindings import * -from ESMF.test.base import TestBase, attr +from esmpy import * +from esmpy.interface.cbindings import * +from esmpy.test.base import TestBase, attr import pytest diff --git a/src/addon/ESMPy/src/ESMF/test/test_cbindings.py b/src/addon/ESMPy/src/esmpy/test/test_cbindings.py similarity index 95% rename from src/addon/ESMPy/src/ESMF/test/test_cbindings.py rename to src/addon/ESMPy/src/esmpy/test/test_cbindings.py index 2099857328..30185967c2 100644 --- a/src/addon/ESMPy/src/ESMF/test/test_cbindings.py +++ b/src/addon/ESMPy/src/esmpy/test/test_cbindings.py @@ -6,9 +6,9 @@ import pytest -from ESMF import * -from ESMF.interface.cbindings import * -from ESMF.test.base import TestBase, attr +from esmpy import * +from esmpy.interface.cbindings import * +from esmpy.test.base import TestBase, attr import numpy as np diff --git a/src/addon/ESMPy/src/ESMF/util/__init__.py b/src/addon/ESMPy/src/esmpy/util/__init__.py similarity index 100% rename from src/addon/ESMPy/src/ESMF/util/__init__.py rename to src/addon/ESMPy/src/esmpy/util/__init__.py diff --git a/src/addon/ESMPy/src/ESMF/util/cache_data.py b/src/addon/ESMPy/src/esmpy/util/cache_data.py similarity index 100% rename from src/addon/ESMPy/src/ESMF/util/cache_data.py rename to src/addon/ESMPy/src/esmpy/util/cache_data.py diff --git a/src/addon/ESMPy/src/ESMF/util/decorators.py b/src/addon/ESMPy/src/esmpy/util/decorators.py similarity index 91% rename from src/addon/ESMPy/src/ESMF/util/decorators.py rename to src/addon/ESMPy/src/esmpy/util/decorators.py index b3a297d9c9..c6ceea769c 100644 --- a/src/addon/ESMPy/src/ESMF/util/decorators.py +++ b/src/addon/ESMPy/src/esmpy/util/decorators.py @@ -9,8 +9,8 @@ import warnings import functools -from ESMF.api.constants import LogKind, _ESMF_NETCDF -from ESMF.util.exceptions import NetCDFMissing +from esmpy.api.constants import LogKind, _ESMF_NETCDF +from esmpy.util.exceptions import NetCDFMissing def beta(func): '''This is a decorator that can be used to mark functions @@ -53,7 +53,7 @@ def initialize(func): @functools.wraps(func) def new_func(*args, **kwargs): - from ESMF.api import esmpymanager + from esmpy.api import esmpymanager esmp = esmpymanager.Manager(debug = False) return func(*args, **kwargs) @@ -65,7 +65,7 @@ def netcdf(func): @functools.wraps(func) def new_func(*args, **kwargs): - from ESMF.api.constants import _ESMF_NETCDF + from esmpy.api.constants import _ESMF_NETCDF if _ESMF_NETCDF: return func(*args, **kwargs) diff --git a/src/addon/ESMPy/src/ESMF/util/enum/LICENSE b/src/addon/ESMPy/src/esmpy/util/enum/LICENSE similarity index 100% rename from src/addon/ESMPy/src/ESMF/util/enum/LICENSE rename to src/addon/ESMPy/src/esmpy/util/enum/LICENSE diff --git a/src/addon/ESMPy/src/ESMF/util/enum/README b/src/addon/ESMPy/src/esmpy/util/enum/README similarity index 100% rename from src/addon/ESMPy/src/ESMF/util/enum/README rename to src/addon/ESMPy/src/esmpy/util/enum/README diff --git a/src/addon/ESMPy/src/ESMF/util/enum/__init__.py b/src/addon/ESMPy/src/esmpy/util/enum/__init__.py similarity index 100% rename from src/addon/ESMPy/src/ESMF/util/enum/__init__.py rename to src/addon/ESMPy/src/esmpy/util/enum/__init__.py diff --git a/src/addon/ESMPy/src/ESMF/util/enum/doc/enum.pdf b/src/addon/ESMPy/src/esmpy/util/enum/doc/enum.pdf similarity index 100% rename from src/addon/ESMPy/src/ESMF/util/enum/doc/enum.pdf rename to src/addon/ESMPy/src/esmpy/util/enum/doc/enum.pdf diff --git a/src/addon/ESMPy/src/ESMF/util/enum/doc/enum.rst b/src/addon/ESMPy/src/esmpy/util/enum/doc/enum.rst similarity index 100% rename from src/addon/ESMPy/src/ESMF/util/enum/doc/enum.rst rename to src/addon/ESMPy/src/esmpy/util/enum/doc/enum.rst diff --git a/src/addon/ESMPy/src/ESMF/util/esmpyarray.py b/src/addon/ESMPy/src/esmpy/util/esmpyarray.py similarity index 97% rename from src/addon/ESMPy/src/ESMF/util/esmpyarray.py rename to src/addon/ESMPy/src/esmpy/util/esmpyarray.py index 0683eae8fc..9bb7605c17 100755 --- a/src/addon/ESMPy/src/ESMF/util/esmpyarray.py +++ b/src/addon/ESMPy/src/esmpy/util/esmpyarray.py @@ -5,7 +5,7 @@ """ #### IMPORT LIBRARIES ######################################################### -import ESMF.api.constants as constants +import esmpy.api.constants as constants import numpy as np import numpy.ma as ma import ctypes as ct @@ -16,7 +16,7 @@ def ndarray_from_esmf(data, dtype, shape): :param data: buffer of fortran allocated ESMF array :type data: ctypes void_p :param dtype: the type of the esmf buffer - :type dtype: ESMF.TypeKind + :type dtype: esmpy.TypeKind :param shape: N-D Python shape corresponding to 1D ESMF allocation :type shape: list or tuple :return: numpy array representing the data with dtype and shape @@ -50,7 +50,7 @@ def __new__(cls, data, mask, dtype, shape): :param mask: mask corresponding to the fortran allocated ESMF array :type mask: list :param dtype: the type of the esmf buffer - :type dtype: ESMF.TypeKind + :type dtype: esmpy.TypeKind :param shape: N-D Python shape corresponding to 1D ESMF allocation :type shape: list or tuple :return: MaskedArray object @@ -93,7 +93,7 @@ def __new__(cls, data, dtype, shape): :param data: buffer of fortran allocated ESMF array :type data: ctypes void_p :param dtype: the type of the esmf buffer - :type dtype: ESMF.TypeKind + :type dtype: esmpy.TypeKind :param shape: N-D Python shape corresponding to 1D ESMF allocation :type shape: list or tuple :return: Array object diff --git a/src/addon/ESMPy/src/ESMF/util/exceptions.py b/src/addon/ESMPy/src/esmpy/util/exceptions.py similarity index 100% rename from src/addon/ESMPy/src/ESMF/util/exceptions.py rename to src/addon/ESMPy/src/esmpy/util/exceptions.py diff --git a/src/addon/ESMPy/src/ESMF/util/field_utilities.py b/src/addon/ESMPy/src/esmpy/util/field_utilities.py similarity index 93% rename from src/addon/ESMPy/src/ESMF/util/field_utilities.py rename to src/addon/ESMPy/src/esmpy/util/field_utilities.py index af85c5977f..122526cfc1 100644 --- a/src/addon/ESMPy/src/ESMF/util/field_utilities.py +++ b/src/addon/ESMPy/src/esmpy/util/field_utilities.py @@ -3,14 +3,14 @@ """ import numpy as np -import ESMF +import esmpy -import ESMF.util.helpers as helpers -import ESMF.api.constants as constants +import esmpy.util.helpers as helpers +import esmpy.api.constants as constants def compare_fields(field1, field2, itrp_mean_tol, itrp_max_tol, csrv_tol, dstfracfield=None, mass1=None, mass2=None, - regrid_method=ESMF.RegridMethod.CONSERVE, + regrid_method=esmpy.RegridMethod.CONSERVE, uninitval=422397696., mask_values=[0]): """ Compare the values of two fields to verify the accuracy of a Regrid. The @@ -32,7 +32,7 @@ def compare_fields(field1, field2, itrp_mean_tol, itrp_max_tol, csrv_tol, import numpy.ma as ma parallel = False - if ESMF.pet_count() > 1: + if esmpy.pet_count() > 1: parallel = True correct = False @@ -54,7 +54,7 @@ def compare_fields(field1, field2, itrp_mean_tol, itrp_max_tol, csrv_tol, field2_flat = np.ravel(field2.data) dstfracfield_flat = np.ravel(dstfracfield.data) # setup mask, no Mask on a Mesh (yet) so need to look at the type first - if (isinstance(field2.grid, ESMF.Grid)) and \ + if (isinstance(field2.grid, esmpy.Grid)) and \ (not isinstance(field2.grid.mask[field2.staggerloc], type(None))): if not isinstance(field2.grid.mask[field2.staggerloc], type(None)): field2mask_flat = [True if x in mask_values else False for x in field2.grid.mask[field2.staggerloc].flatten().tolist()] @@ -105,7 +105,7 @@ def compare_fields(field1, field2, itrp_mean_tol, itrp_max_tol, csrv_tol, itrp_mean = False itrp_max = False csrv = False - if ESMF.local_pet() == 0: + if esmpy.local_pet() == 0: if mass1_global == 0.: csrv_error_global = abs(mass2_global - mass1_global) else: @@ -140,9 +140,9 @@ def compare_fields(field1, field2, itrp_mean_tol, itrp_max_tol, csrv_tol, # print pass or fail if (itrp_mean and itrp_max and csrv): - print ("PET{0} - PASS".format(ESMF.local_pet())) + print ("PET{0} - PASS".format(esmpy.local_pet())) correct = True else: - print ("PET{0} - FAIL".format(ESMF.local_pet())) + print ("PET{0} - FAIL".format(esmpy.local_pet())) return total_error_global, csrv_error_global, correct \ No newline at end of file diff --git a/src/addon/ESMPy/src/ESMF/util/grid_utilities.py b/src/addon/ESMPy/src/esmpy/util/grid_utilities.py similarity index 78% rename from src/addon/ESMPy/src/ESMF/util/grid_utilities.py rename to src/addon/ESMPy/src/esmpy/util/grid_utilities.py index 2227f3bb62..83597f85ca 100644 --- a/src/addon/ESMPy/src/ESMF/util/grid_utilities.py +++ b/src/addon/ESMPy/src/esmpy/util/grid_utilities.py @@ -10,11 +10,11 @@ raise ImportError('The Numpy library cannot be found!') try: - import ESMF + import esmpy except: raise ImportError('The ESMF library cannot be found!') -def grid_create_from_bounds(xdom, ydom, nx, ny, corners=False, domask=False, doarea=False, ctk=ESMF.TypeKind.R8): +def grid_create_from_bounds(xdom, ydom, nx, ny, corners=False, domask=False, doarea=False, ctk=esmpy.TypeKind.R8): """ Create a 2 dimensional Grid using the bounds of the domain defined in the `xdom` and `ydom` lists. The parameters `nx` and `ny` are used to define the number coordinate points between the bounds of the domain. @@ -45,7 +45,7 @@ def grid_create_from_bounds(xdom, ydom, nx, ny, corners=False, domask=False, doa return grid -def grid_create_from_coordinates(xcoords, ycoords, xcorners=False, ycorners=False, corners=False, domask=False, doarea=False, ctk=ESMF.TypeKind.R8): +def grid_create_from_coordinates(xcoords, ycoords, xcorners=False, ycorners=False, corners=False, domask=False, doarea=False, ctk=esmpy.TypeKind.R8): """ Create a 2 dimensional Grid using the bounds of the x and y coordiantes. :param xcoords: The 1st dimension or 'x' coordinates at cell centers, as a Python list or numpy Array @@ -62,45 +62,45 @@ def grid_create_from_coordinates(xcoords, ycoords, xcorners=False, ycorners=Fals # create a grid given the number of grid cells in each dimension, the center stagger location is allocated, the # Cartesian coordinate system and type of the coordinates are specified max_index = np.array([len(xcoords), len(ycoords)]) - grid = ESMF.Grid(max_index, staggerloc=[ESMF.StaggerLoc.CENTER], coord_sys=ESMF.CoordSys.CART, coord_typekind=ctk) + grid = esmpy.Grid(max_index, staggerloc=[esmpy.StaggerLoc.CENTER], coord_sys=esmpy.CoordSys.CART, coord_typekind=ctk) # set the grid coordinates using numpy arrays, parallel case is handled using grid bounds gridXCenter = grid.get_coords(x) - x_par = xcoords[grid.lower_bounds[ESMF.StaggerLoc.CENTER][x]:grid.upper_bounds[ESMF.StaggerLoc.CENTER][x]] + x_par = xcoords[grid.lower_bounds[esmpy.StaggerLoc.CENTER][x]:grid.upper_bounds[esmpy.StaggerLoc.CENTER][x]] gridXCenter[...] = x_par.reshape((x_par.size, 1)) gridYCenter = grid.get_coords(y) - y_par = ycoords[grid.lower_bounds[ESMF.StaggerLoc.CENTER][y]:grid.upper_bounds[ESMF.StaggerLoc.CENTER][y]] + y_par = ycoords[grid.lower_bounds[esmpy.StaggerLoc.CENTER][y]:grid.upper_bounds[esmpy.StaggerLoc.CENTER][y]] gridYCenter[...] = y_par.reshape((1, y_par.size)) # create grid corners in a slightly different manner to account for the bounds format common in CF-like files if corners: - grid.add_coords([ESMF.StaggerLoc.CORNER]) - lbx = grid.lower_bounds[ESMF.StaggerLoc.CORNER][x] - ubx = grid.upper_bounds[ESMF.StaggerLoc.CORNER][x] - lby = grid.lower_bounds[ESMF.StaggerLoc.CORNER][y] - uby = grid.upper_bounds[ESMF.StaggerLoc.CORNER][y] + grid.add_coords([esmpy.StaggerLoc.CORNER]) + lbx = grid.lower_bounds[esmpy.StaggerLoc.CORNER][x] + ubx = grid.upper_bounds[esmpy.StaggerLoc.CORNER][x] + lby = grid.lower_bounds[esmpy.StaggerLoc.CORNER][y] + uby = grid.upper_bounds[esmpy.StaggerLoc.CORNER][y] - gridXCorner = grid.get_coords(x, staggerloc=ESMF.StaggerLoc.CORNER) + gridXCorner = grid.get_coords(x, staggerloc=esmpy.StaggerLoc.CORNER) for i0 in range(ubx - lbx - 1): gridXCorner[i0, :] = xcorners[i0+lbx, 0] gridXCorner[i0 + 1, :] = xcorners[i0+lbx, 1] - gridYCorner = grid.get_coords(y, staggerloc=ESMF.StaggerLoc.CORNER) + gridYCorner = grid.get_coords(y, staggerloc=esmpy.StaggerLoc.CORNER) for i1 in range(uby - lby - 1): gridYCorner[:, i1] = ycorners[i1+lby, 0] gridYCorner[:, i1 + 1] = ycorners[i1+lby, 1] # add an arbitrary mask if domask: - mask = grid.add_item(ESMF.GridItem.MASK) + mask = grid.add_item(esmpy.GridItem.MASK) mask[:] = 1 mask[np.where((1.75 <= gridXCenter.any() < 2.25) & (1.75 <= gridYCenter.any() < 2.25))] = 0 # add arbitrary areas values if doarea: - area = grid.add_item(ESMF.GridItem.AREA) + area = grid.add_item(esmpy.GridItem.AREA) area[:] = 5.0 return grid @@ -147,38 +147,38 @@ def grid_create_from_coordinates_periodic(longitudes, latitudes, lon_corners=Fal # create a grid given the number of grid cells in each dimension the center stagger location is allocated max_index = np.array([len(longitudes), len(latitudes)]) - grid = ESMF.Grid(max_index, num_peri_dims=1, staggerloc=[ESMF.StaggerLoc.CENTER]) + grid = esmpy.Grid(max_index, num_peri_dims=1, staggerloc=[esmpy.StaggerLoc.CENTER]) # set the grid coordinates using numpy arrays, parallel case is handled using grid bounds gridXCenter = grid.get_coords(lon) - lon_par = longitudes[grid.lower_bounds[ESMF.StaggerLoc.CENTER][lon]:grid.upper_bounds[ESMF.StaggerLoc.CENTER][lon]] + lon_par = longitudes[grid.lower_bounds[esmpy.StaggerLoc.CENTER][lon]:grid.upper_bounds[esmpy.StaggerLoc.CENTER][lon]] gridXCenter[...] = lon_par.reshape((lon_par.size, 1)) gridYCenter = grid.get_coords(lat) - lat_par = latitudes[grid.lower_bounds[ESMF.StaggerLoc.CENTER][lat]:grid.upper_bounds[ESMF.StaggerLoc.CENTER][lat]] + lat_par = latitudes[grid.lower_bounds[esmpy.StaggerLoc.CENTER][lat]:grid.upper_bounds[esmpy.StaggerLoc.CENTER][lat]] gridYCenter[...] = lat_par.reshape((1, lat_par.size)) # create grid corners in a slightly different manner to account for the bounds format common in CF-like files if corners: - grid.add_coords([ESMF.StaggerLoc.CORNER]) - lbx = grid.lower_bounds[ESMF.StaggerLoc.CORNER][lon] - ubx = grid.upper_bounds[ESMF.StaggerLoc.CORNER][lon] - lby = grid.lower_bounds[ESMF.StaggerLoc.CORNER][lat] - uby = grid.upper_bounds[ESMF.StaggerLoc.CORNER][lat] + grid.add_coords([esmpy.StaggerLoc.CORNER]) + lbx = grid.lower_bounds[esmpy.StaggerLoc.CORNER][lon] + ubx = grid.upper_bounds[esmpy.StaggerLoc.CORNER][lon] + lby = grid.lower_bounds[esmpy.StaggerLoc.CORNER][lat] + uby = grid.upper_bounds[esmpy.StaggerLoc.CORNER][lat] - gridXCorner = grid.get_coords(lon, staggerloc=ESMF.StaggerLoc.CORNER) + gridXCorner = grid.get_coords(lon, staggerloc=esmpy.StaggerLoc.CORNER) for i0 in range(ubx - lbx - 1): gridXCorner[i0, :] = lon_corners[i0+lbx, 0] gridXCorner[i0 + 1, :] = lon_corners[i0+lbx, 1] - gridYCorner = grid.get_coords(lat, staggerloc=ESMF.StaggerLoc.CORNER) + gridYCorner = grid.get_coords(lat, staggerloc=esmpy.StaggerLoc.CORNER) for i1 in range(uby - lby - 1): gridYCorner[:, i1] = lat_corners[i1+lby, 0] gridYCorner[:, i1 + 1] = lat_corners[i1+lby, 1] # add an arbitrary mask if domask: - mask = grid.add_item(ESMF.GridItem.MASK) + mask = grid.add_item(esmpy.GridItem.MASK) mask[:] = 1 mask[np.where((1.75 <= gridXCenter.any() < 2.25) & (1.75 <= gridYCenter.any() < 2.25))] = 0 @@ -242,49 +242,49 @@ def grid_create_from_coordinates_3d(xcoords, ycoords, zcoords, xcorners=False, y # create a grid given the number of grid cells in each dimension, the center stagger location is allocated and the # Cartesian coordinate system is specified max_index = np.array([len(xcoords), len(ycoords), len(zcoords)]) - grid = ESMF.Grid(max_index, staggerloc=[ESMF.StaggerLoc.CENTER_VCENTER], coord_sys=ESMF.CoordSys.CART) + grid = esmpy.Grid(max_index, staggerloc=[esmpy.StaggerLoc.CENTER_VCENTER], coord_sys=esmpy.CoordSys.CART) # set the grid coordinates using numpy arrays, parallel case is handled using grid bounds gridXCenter = grid.get_coords(x) - x_par = xcoords[grid.lower_bounds[ESMF.StaggerLoc.CENTER_VCENTER][x]:grid.upper_bounds[ESMF.StaggerLoc.CENTER_VCENTER][x]] + x_par = xcoords[grid.lower_bounds[esmpy.StaggerLoc.CENTER_VCENTER][x]:grid.upper_bounds[esmpy.StaggerLoc.CENTER_VCENTER][x]] gridXCenter[...] = x_par.reshape(x_par.size, 1, 1) gridYCenter = grid.get_coords(y) - y_par = ycoords[grid.lower_bounds[ESMF.StaggerLoc.CENTER_VCENTER][y]:grid.upper_bounds[ESMF.StaggerLoc.CENTER_VCENTER][y]] + y_par = ycoords[grid.lower_bounds[esmpy.StaggerLoc.CENTER_VCENTER][y]:grid.upper_bounds[esmpy.StaggerLoc.CENTER_VCENTER][y]] gridYCenter[...] = y_par.reshape(1, y_par.size, 1) gridZCenter = grid.get_coords(z) - z_par = zcoords[grid.lower_bounds[ESMF.StaggerLoc.CENTER_VCENTER][z]:grid.upper_bounds[ESMF.StaggerLoc.CENTER_VCENTER][z]] + z_par = zcoords[grid.lower_bounds[esmpy.StaggerLoc.CENTER_VCENTER][z]:grid.upper_bounds[esmpy.StaggerLoc.CENTER_VCENTER][z]] gridZCenter[...] = z_par.reshape(1, 1, z_par.size) # create grid corners in a slightly different manner to account for the bounds format common in CF-like files if corners: - grid.add_coords([ESMF.StaggerLoc.CORNER_VFACE]) - lbx = grid.lower_bounds[ESMF.StaggerLoc.CORNER_VFACE][x] - ubx = grid.upper_bounds[ESMF.StaggerLoc.CORNER_VFACE][x] - lby = grid.lower_bounds[ESMF.StaggerLoc.CORNER_VFACE][y] - uby = grid.upper_bounds[ESMF.StaggerLoc.CORNER_VFACE][y] - lbz = grid.lower_bounds[ESMF.StaggerLoc.CORNER_VFACE][z] - ubz = grid.upper_bounds[ESMF.StaggerLoc.CORNER_VFACE][z] - - gridXCorner = grid.get_coords(x, staggerloc=ESMF.StaggerLoc.CORNER_VFACE) + grid.add_coords([esmpy.StaggerLoc.CORNER_VFACE]) + lbx = grid.lower_bounds[esmpy.StaggerLoc.CORNER_VFACE][x] + ubx = grid.upper_bounds[esmpy.StaggerLoc.CORNER_VFACE][x] + lby = grid.lower_bounds[esmpy.StaggerLoc.CORNER_VFACE][y] + uby = grid.upper_bounds[esmpy.StaggerLoc.CORNER_VFACE][y] + lbz = grid.lower_bounds[esmpy.StaggerLoc.CORNER_VFACE][z] + ubz = grid.upper_bounds[esmpy.StaggerLoc.CORNER_VFACE][z] + + gridXCorner = grid.get_coords(x, staggerloc=esmpy.StaggerLoc.CORNER_VFACE) for i0 in range(ubx - lbx - 1): gridXCorner[i0, :, :] = xcorners[i0+lbx, 0] gridXCorner[i0 + 1, :, :] = xcorners[i0+lbx, 1] - gridYCorner = grid.get_coords(y, staggerloc=ESMF.StaggerLoc.CORNER_VFACE) + gridYCorner = grid.get_coords(y, staggerloc=esmpy.StaggerLoc.CORNER_VFACE) for i1 in range(uby - lby - 1): gridYCorner[:, i1, :] = ycorners[i1+lby, 0] gridYCorner[:, i1 + 1, :] = ycorners[i1+lby, 1] - gridZCorner = grid.get_coords(z, staggerloc=ESMF.StaggerLoc.CORNER_VFACE) + gridZCorner = grid.get_coords(z, staggerloc=esmpy.StaggerLoc.CORNER_VFACE) for i2 in range(ubz - lbz - 1): gridZCorner[:, :, i2] = zcorners[i2+lbz, 0] gridZCorner[:, :, i2 + 1] = zcorners[i2+lbz, 1] # add an arbitrary mask if domask: - mask = grid.add_item(ESMF.GridItem.MASK) + mask = grid.add_item(esmpy.GridItem.MASK) mask[:] = 1 mask[np.where((1.75 < gridXCenter.data < 2.25) & (1.75 < gridYCenter.data < 2.25) & @@ -292,7 +292,7 @@ def grid_create_from_coordinates_3d(xcoords, ycoords, zcoords, xcorners=False, y # add arbitrary areas values if doarea: - area = grid.add_item(ESMF.GridItem.AREA) + area = grid.add_item(esmpy.GridItem.AREA) area[:] = 5.0 return grid @@ -350,49 +350,49 @@ def grid_create_from_coordinates_periodic_3d(longitudes, latitudes, heights, # create a grid given the number of grid cells in each dimension the center stagger location is allocated max_index = np.array([len(longitudes), len(latitudes), len(heights)]) - grid = ESMF.Grid(max_index, num_peri_dims=1, staggerloc=[ESMF.StaggerLoc.CENTER]) + grid = esmpy.Grid(max_index, num_peri_dims=1, staggerloc=[esmpy.StaggerLoc.CENTER]) # set the grid coordinates using numpy arrays, parallel case is handled using grid bounds gridXCenter = grid.get_coords(lon) - lon_par = longitudes[grid.lower_bounds[ESMF.StaggerLoc.CENTER][lon]:grid.upper_bounds[ESMF.StaggerLoc.CENTER][lon]] + lon_par = longitudes[grid.lower_bounds[esmpy.StaggerLoc.CENTER][lon]:grid.upper_bounds[esmpy.StaggerLoc.CENTER][lon]] gridXCenter[...] = lon_par.reshape((lon_par.size, 1, 1)) gridYCenter = grid.get_coords(lat) - lat_par = latitudes[grid.lower_bounds[ESMF.StaggerLoc.CENTER][lat]:grid.upper_bounds[ESMF.StaggerLoc.CENTER][lat]] + lat_par = latitudes[grid.lower_bounds[esmpy.StaggerLoc.CENTER][lat]:grid.upper_bounds[esmpy.StaggerLoc.CENTER][lat]] gridYCenter[...] = lat_par.reshape((1, lat_par.size, 1)) gridZCenter = grid.get_coords(z) - z_par = heights[grid.lower_bounds[ESMF.StaggerLoc.CENTER][z]:grid.upper_bounds[ESMF.StaggerLoc.CENTER][z]] + z_par = heights[grid.lower_bounds[esmpy.StaggerLoc.CENTER][z]:grid.upper_bounds[esmpy.StaggerLoc.CENTER][z]] gridZCenter[...] = z_par.reshape((1, 1, z_par.size)) # create grid corners in a slightly different manner to account for the bounds format common in CF-like files if corners: - grid.add_coords([ESMF.StaggerLoc.CORNER]) - lbx = grid.lower_bounds[ESMF.StaggerLoc.CORNER][lon] - ubx = grid.upper_bounds[ESMF.StaggerLoc.CORNER][lon] - lby = grid.lower_bounds[ESMF.StaggerLoc.CORNER][lat] - uby = grid.upper_bounds[ESMF.StaggerLoc.CORNER][lat] - lbz = grid.lower_bounds[ESMF.StaggerLoc.CORNER][z] - ubz = grid.upper_bounds[ESMF.StaggerLoc.CORNER][z] - - gridXCorner = grid.get_coords(lon, staggerloc=ESMF.StaggerLoc.CORNER) + grid.add_coords([esmpy.StaggerLoc.CORNER]) + lbx = grid.lower_bounds[esmpy.StaggerLoc.CORNER][lon] + ubx = grid.upper_bounds[esmpy.StaggerLoc.CORNER][lon] + lby = grid.lower_bounds[esmpy.StaggerLoc.CORNER][lat] + uby = grid.upper_bounds[esmpy.StaggerLoc.CORNER][lat] + lbz = grid.lower_bounds[esmpy.StaggerLoc.CORNER][z] + ubz = grid.upper_bounds[esmpy.StaggerLoc.CORNER][z] + + gridXCorner = grid.get_coords(lon, staggerloc=esmpy.StaggerLoc.CORNER) for i0 in range(ubx - lbx - 1): gridXCorner[i0, :, :] = lon_corners[i0+lbx, 0] gridXCorner[i0 + 1, :, :] = lon_corners[i0+lbx, 1] - gridYCorner = grid.get_coords(lat, staggerloc=ESMF.StaggerLoc.CORNER) + gridYCorner = grid.get_coords(lat, staggerloc=esmpy.StaggerLoc.CORNER) for i1 in range(uby - lby - 1): gridYCorner[:, i1, :] = lat_corners[i1+lby, 0] gridYCorner[:, i1 + 1, :] = lat_corners[i1+lby, 1] - gridZCorner = grid.get_coords(z, staggerloc=ESMF.StaggerLoc.CORNER) + gridZCorner = grid.get_coords(z, staggerloc=esmpy.StaggerLoc.CORNER) for i2 in range(ubz - lbz - 1): gridZCorner[:, :, i2] = z_corners[i2+lbz, 0] gridZCorner[:, :, i2 + 1] = z_corners[i2+lbz, 1] # add an arbitrary mask if domask: - mask = grid.add_item(ESMF.GridItem.MASK) + mask = grid.add_item(esmpy.GridItem.MASK) mask[:] = 1 mask[np.where((1.75 <= gridXCenter.data < 2.25) & (1.75 <= gridYCenter.data < 2.25) & @@ -408,12 +408,12 @@ def initialize_field_grid(field, domask=False, doarea=False): RETURN VALUES: \n Field :: field \n """ if domask: - mask = field.grid.get_item(ESMF.GridItem.MASK) + mask = field.grid.get_item(esmpy.GridItem.MASK) # get the coordinate pointers and set the coordinates [x,y] = [0, 1] - gridXCoord = field.grid.get_coords(0, ESMF.StaggerLoc.CENTER) - gridYCoord = field.grid.get_coords(1, ESMF.StaggerLoc.CENTER) + gridXCoord = field.grid.get_coords(0, esmpy.StaggerLoc.CENTER) + gridYCoord = field.grid.get_coords(1, esmpy.StaggerLoc.CENTER) field.data[:] = 20.0 + gridXCoord**2 + gridXCoord*gridYCoord + gridYCoord**2 @@ -435,8 +435,8 @@ def initialize_field_grid_periodic(field): # get the coordinate pointers and set the coordinates [x,y] = [0, 1] - gridXCoord = field.grid.get_coords(x, ESMF.StaggerLoc.CENTER) - gridYCoord = field.grid.get_coords(y, ESMF.StaggerLoc.CENTER) + gridXCoord = field.grid.get_coords(x, esmpy.StaggerLoc.CENTER) + gridYCoord = field.grid.get_coords(y, esmpy.StaggerLoc.CENTER) field.data[:] = 2.0 + np.cos(DEG2RAD*gridXCoord)**2 * \ np.cos(2.0*DEG2RAD*(90.0 - gridYCoord)) @@ -456,9 +456,9 @@ def initialize_field_grid_periodic_3d(field): # get the coordinate pointers and set the coordinates [x,y,z] = [0, 1, 2] - gridXCoord = field.grid.get_coords(x, ESMF.StaggerLoc.CENTER) - gridYCoord = field.grid.get_coords(y, ESMF.StaggerLoc.CENTER) - gridZCoord = field.grid.get_coords(z, ESMF.StaggerLoc.CENTER) + gridXCoord = field.grid.get_coords(x, esmpy.StaggerLoc.CENTER) + gridYCoord = field.grid.get_coords(y, esmpy.StaggerLoc.CENTER) + gridZCoord = field.grid.get_coords(z, esmpy.StaggerLoc.CENTER) field.data[:] = 2.0 + np.cos(DEG2RAD*gridXCoord)**2 * \ np.cos(2.0*DEG2RAD*(90.0 - gridYCoord)) + \ @@ -474,13 +474,13 @@ def initialize_field_grid_3d(field, domask=False): RETURN VALUES: \n Field :: field \n """ if domask: - mask = field.grid.get_item(ESMF.GridItem.MASK) + mask = field.grid.get_item(esmpy.GridItem.MASK) # get the coordinate pointers and set the coordinates [x,y,z] = [0,1,2] - gridXCoord = field.grid.get_coords(x, ESMF.StaggerLoc.CENTER_VCENTER) - gridYCoord = field.grid.get_coords(y, ESMF.StaggerLoc.CENTER_VCENTER) - gridZCoord = field.grid.get_coords(z, ESMF.StaggerLoc.CENTER_VCENTER) + gridXCoord = field.grid.get_coords(x, esmpy.StaggerLoc.CENTER_VCENTER) + gridYCoord = field.grid.get_coords(y, esmpy.StaggerLoc.CENTER_VCENTER) + gridZCoord = field.grid.get_coords(z, esmpy.StaggerLoc.CENTER_VCENTER) field.data[:]=20.0 + gridXCoord**2 + gridXCoord*gridYCoord + gridZCoord**2 @@ -500,7 +500,7 @@ def compute_mass_grid(valuefield, dofrac=False, fracfield=None, RETURN VALUES: float :: mass \n """ mass = 0.0 - areafield = ESMF.Field(valuefield.grid, name='areafield') + areafield = esmpy.Field(valuefield.grid, name='areafield') areafield.get_area() ind = np.where(valuefield.data != uninitval) diff --git a/src/addon/ESMPy/src/ESMF/util/helpers.py b/src/addon/ESMPy/src/esmpy/util/helpers.py similarity index 87% rename from src/addon/ESMPy/src/ESMF/util/helpers.py rename to src/addon/ESMPy/src/esmpy/util/helpers.py index 98e4973689..a7087de0e6 100644 --- a/src/addon/ESMPy/src/ESMF/util/helpers.py +++ b/src/addon/ESMPy/src/esmpy/util/helpers.py @@ -1,5 +1,5 @@ -from ESMF import Manager -from ESMF.api.constants import Reduce +from esmpy import Manager +from esmpy.api.constants import Reduce import numpy as np diff --git a/src/addon/ESMPy/src/ESMF/util/itester.py b/src/addon/ESMPy/src/esmpy/util/itester.py similarity index 100% rename from src/addon/ESMPy/src/ESMF/util/itester.py rename to src/addon/ESMPy/src/esmpy/util/itester.py diff --git a/src/addon/ESMPy/src/ESMF/util/locstream_utilities.py b/src/addon/ESMPy/src/esmpy/util/locstream_utilities.py similarity index 77% rename from src/addon/ESMPy/src/ESMF/util/locstream_utilities.py rename to src/addon/ESMPy/src/esmpy/util/locstream_utilities.py index dac2b07bb1..9dda92df3c 100644 --- a/src/addon/ESMPy/src/ESMF/util/locstream_utilities.py +++ b/src/addon/ESMPy/src/esmpy/util/locstream_utilities.py @@ -10,7 +10,7 @@ raise ImportError('The Numpy library cannot be found!') try: - import ESMF + import esmpy except: raise ImportError('The ESMF library cannot be found!') @@ -22,10 +22,10 @@ def create_locstream_16(domask=False): :param domask: a boolean to tell whether or not to add a mask :return: LocStream """ - if ESMF.pet_count() != 1: + if esmpy.pet_count() != 1: raise ValueError("processor count must be 1 to use this function") - locstream = ESMF.LocStream(16) + locstream = esmpy.LocStream(16) locstream["ESMF:X"] = [0.0, 1.5, 2.5, 4.0, 0.0, 1.5, 2.5, 4.0, 0.0, 1.5, 2.5, 4.0, 0.0, 1.5, 2.5, 4.0] locstream["ESMF:Y"] = [0.0, 0.0, 0.0, 0.0, 1.5, 1.5, 1.5, 1.5, 2.5, 2.5, 2.5, 2.5, 4.0, 4.0, 4.0, 4.0] @@ -39,30 +39,30 @@ def create_locstream_16_parallel(domask=False): :param domask: a boolean to tell whether or not to add a mask :return: LocStream """ - if ESMF.pet_count() != 4: + if esmpy.pet_count() != 4: raise ValueError("processor count must be 4 to use this function") locstream = None - if ESMF.local_pet() == 0: - locstream = ESMF.LocStream(4) + if esmpy.local_pet() == 0: + locstream = esmpy.LocStream(4) locstream["ESMF:X"] = [0.0, 1.5, 0.0, 1.5] locstream["ESMF:Y"] = [0.0, 0.0, 1.5, 1.5] if domask: locstream["ESMF:Mask"] = [1, 0, 0, 1] - elif ESMF.local_pet() == 1: - locstream = ESMF.LocStream(4) + elif esmpy.local_pet() == 1: + locstream = esmpy.LocStream(4) locstream["ESMF:X"] = [2.5, 4.0, 2.5, 4.0] locstream["ESMF:Y"] = [0.0, 0.0, 1.5, 1.5] if domask: locstream["ESMF:Mask"] = [1, 1, 1, 1] - elif ESMF.local_pet() == 2: - locstream = ESMF.LocStream(4) + elif esmpy.local_pet() == 2: + locstream = esmpy.LocStream(4) locstream["ESMF:X"] = [0.0, 1.5, 0.0, 1.5] locstream["ESMF:Y"] = [2.5, 2.5, 4.0, 4.0] if domask: locstream["ESMF:Mask"] = [1, 1, 1, 1] - elif ESMF.local_pet() == 3: - locstream = ESMF.LocStream(4) + elif esmpy.local_pet() == 3: + locstream = esmpy.LocStream(4) locstream["ESMF:X"] = [2.5, 4.0, 2.5, 4.0] locstream["ESMF:Y"] = [2.5, 2.5, 4.0, 4.0] if domask: @@ -70,19 +70,19 @@ def create_locstream_16_parallel(domask=False): return locstream -def create_locstream_spherical_16(coord_sys=ESMF.CoordSys.SPH_DEG, domask=False): +def create_locstream_spherical_16(coord_sys=esmpy.CoordSys.SPH_DEG, domask=False): """ :param coord_sys: the coordinate system of the LocStream :param domask: a boolean to tell whether or not to add a mask :return: LocStream """ - if ESMF.pet_count() != 1: + if esmpy.pet_count() != 1: raise ValueError("processor count must be 1 to use this function") - locstream = ESMF.LocStream(16, coord_sys=coord_sys) + locstream = esmpy.LocStream(16, coord_sys=coord_sys) deg_rad = pi - if coord_sys == ESMF.CoordSys.SPH_DEG: + if coord_sys == esmpy.CoordSys.SPH_DEG: deg_rad = 180 locstream["ESMF:Lon"] = [0.0, 0.5*deg_rad, 1.5*deg_rad, 2*deg_rad, 0.0, 0.5*deg_rad, 1.5*deg_rad, 2*deg_rad, 0.0, 0.5*deg_rad, 1.5*deg_rad, 2*deg_rad, 0.0, 0.5*deg_rad, 1.5*deg_rad, 2*deg_rad] @@ -92,40 +92,40 @@ def create_locstream_spherical_16(coord_sys=ESMF.CoordSys.SPH_DEG, domask=False) return locstream -def create_locstream_spherical_16_parallel(coord_sys=ESMF.CoordSys.SPH_DEG, domask=False): +def create_locstream_spherical_16_parallel(coord_sys=esmpy.CoordSys.SPH_DEG, domask=False): """ :param coord_sys: the coordinate system of the LocStream :param domask: a boolean to tell whether or not to add a mask :return: LocStream """ - if ESMF.pet_count() != 4: + if esmpy.pet_count() != 4: raise ValueError("processor count must be 4 to use this function") deg_rad = pi - if coord_sys == ESMF.CoordSys.SPH_DEG: + if coord_sys == esmpy.CoordSys.SPH_DEG: deg_rad = 180.0 locstream = None - if ESMF.local_pet() == 0: - locstream = ESMF.LocStream(4, coord_sys=coord_sys) + if esmpy.local_pet() == 0: + locstream = esmpy.LocStream(4, coord_sys=coord_sys) locstream["ESMF:Lon"] = [0.0, 0.5*deg_rad, 0.0, 0.5*deg_rad] locstream["ESMF:Lat"] = [deg_rad/-2.0, deg_rad/-2.0, -0.25*deg_rad, -0.25*deg_rad] if domask: locstream["ESMF:Mask"] = np.array([1, 0, 1, 1], dtype=np.int32) - elif ESMF.local_pet() == 1: - locstream = ESMF.LocStream(4, coord_sys=coord_sys) + elif esmpy.local_pet() == 1: + locstream = esmpy.LocStream(4, coord_sys=coord_sys) locstream["ESMF:Lon"] = [1.5*deg_rad, 2*deg_rad, 1.5*deg_rad, 2*deg_rad] locstream["ESMF:Lat"] = [deg_rad/-2.0, deg_rad/-2.0, -0.25*deg_rad, -0.25*deg_rad] if domask: locstream["ESMF:Mask"] = np.array([0, 1, 1, 1], dtype=np.int32) - elif ESMF.local_pet() == 2: - locstream = ESMF.LocStream(4, coord_sys=coord_sys) + elif esmpy.local_pet() == 2: + locstream = esmpy.LocStream(4, coord_sys=coord_sys) locstream["ESMF:Lon"] = [0.0, 0.5*deg_rad, 0.0, 0.5*deg_rad] locstream["ESMF:Lat"] = [0.25*deg_rad, 0.25*deg_rad, deg_rad/2.0, deg_rad/2.0] if domask: locstream["ESMF:Mask"] = np.array([1, 1, 1, 1], dtype=np.int32) - elif ESMF.local_pet() == 3: - locstream = ESMF.LocStream(4, coord_sys=coord_sys) + elif esmpy.local_pet() == 3: + locstream = esmpy.LocStream(4, coord_sys=coord_sys) locstream["ESMF:Lon"] = [1.5*deg_rad, 2*deg_rad, 1.5*deg_rad, 2*deg_rad] locstream["ESMF:Lat"] = [0.25*deg_rad, 0.25*deg_rad, deg_rad/2.0, deg_rad/2.0] if domask: diff --git a/src/addon/ESMPy/src/ESMF/util/mesh_utilities.py b/src/addon/ESMPy/src/esmpy/util/mesh_utilities.py similarity index 92% rename from src/addon/ESMPy/src/ESMF/util/mesh_utilities.py rename to src/addon/ESMPy/src/esmpy/util/mesh_utilities.py index f9ff990b16..76ab3e664d 100644 --- a/src/addon/ESMPy/src/ESMF/util/mesh_utilities.py +++ b/src/addon/ESMPy/src/esmpy/util/mesh_utilities.py @@ -10,7 +10,7 @@ raise ImportError('The Numpy library cannot be found!') try: - import ESMF + import esmpy except: raise ImportError('The ESMF library cannot be found!') @@ -45,7 +45,7 @@ def mesh_create_5_pentahexa(coord_sys=None): Note: This mesh is not parallel, it can only be used in serial """ # Two parametric dimensions, and two spatial dimensions - mesh = ESMF.Mesh(parametric_dim=2, spatial_dim=2, coord_sys=coord_sys) + mesh = esmpy.Mesh(parametric_dim=2, spatial_dim=2, coord_sys=coord_sys) num_node = 12 num_elem = 5 @@ -67,9 +67,9 @@ def mesh_create_5_pentahexa(coord_sys=None): nodeOwner = np.zeros(num_node) elemId = np.array([1,2,3,4,5]) - elemType=np.array([ESMF.MeshElemType.QUAD, - ESMF.MeshElemType.TRI, - ESMF.MeshElemType.TRI, 5, 6]) + elemType=np.array([esmpy.MeshElemType.QUAD, + esmpy.MeshElemType.TRI, + esmpy.MeshElemType.TRI, 5, 6]) # I believe python connections are 0-based @@ -115,7 +115,7 @@ def mesh_create_4_ngons(): Note: This mesh is not parallel, it can only be used in serial """ # Two parametric dimensions, and two spatial dimensions - mesh = ESMF.Mesh(parametric_dim=2, spatial_dim=2) + mesh = esmpy.Mesh(parametric_dim=2, spatial_dim=2) num_node = 9 num_elem = 4 @@ -172,7 +172,7 @@ def mesh_create_5(): Note: This mesh is not parallel, it can only be used in serial """ # Two parametric dimensions, and two spatial dimensions - mesh = ESMF.Mesh(parametric_dim=2, spatial_dim=2) + mesh = esmpy.Mesh(parametric_dim=2, spatial_dim=2) num_node = 9 num_elem = 5 @@ -189,11 +189,11 @@ def mesh_create_5(): nodeOwner = np.zeros(num_node) elemId = np.array([11,12,21,22,23]) - elemType=np.array([ESMF.MeshElemType.QUAD, - ESMF.MeshElemType.QUAD, - ESMF.MeshElemType.QUAD, - ESMF.MeshElemType.TRI, - ESMF.MeshElemType.TRI]) + elemType=np.array([esmpy.MeshElemType.QUAD, + esmpy.MeshElemType.QUAD, + esmpy.MeshElemType.QUAD, + esmpy.MeshElemType.TRI, + esmpy.MeshElemType.TRI]) elemConn=np.array([0,1,4,3, # element 11 1,2,5,4, # element 12 3,4,7,6, # element 21 @@ -239,7 +239,7 @@ def mesh_create_10(): Note: This mesh is not parallel, it can only be used in serial """ # Two parametric dimensions, and two spatial dimensions - mesh = ESMF.Mesh(parametric_dim=2, spatial_dim=2) + mesh = esmpy.Mesh(parametric_dim=2, spatial_dim=2) num_node = 16 num_elem = 10 @@ -250,16 +250,16 @@ def mesh_create_10(): 0.0,4.0, 1.5,4.0, 2.5,4.0, 4.0,4.0]) nodeOwner = np.zeros(num_node) elemId = np.array([11,12,13,21,22,23,31,32,33,34]) - elemType=np.array([ESMF.MeshElemType.QUAD, - ESMF.MeshElemType.QUAD, - ESMF.MeshElemType.QUAD, - ESMF.MeshElemType.QUAD, - ESMF.MeshElemType.QUAD, - ESMF.MeshElemType.QUAD, - ESMF.MeshElemType.QUAD, - ESMF.MeshElemType.QUAD, - ESMF.MeshElemType.TRI, - ESMF.MeshElemType.TRI]) + elemType=np.array([esmpy.MeshElemType.QUAD, + esmpy.MeshElemType.QUAD, + esmpy.MeshElemType.QUAD, + esmpy.MeshElemType.QUAD, + esmpy.MeshElemType.QUAD, + esmpy.MeshElemType.QUAD, + esmpy.MeshElemType.QUAD, + esmpy.MeshElemType.QUAD, + esmpy.MeshElemType.TRI, + esmpy.MeshElemType.TRI]) elemConn = np.array([0,1,5,4, 1,2,6,5, 2,3,7,6, @@ -324,7 +324,7 @@ def mesh_create_50(domask=False, doarea=False): Note: This mesh is not parallel, it can only be used in serial """ # Two parametric dimensions, and two spatial dimensions - mesh = ESMF.Mesh(parametric_dim=2, spatial_dim=2) + mesh = esmpy.Mesh(parametric_dim=2, spatial_dim=2) num_node = 64 num_elem = 50 @@ -352,8 +352,8 @@ def mesh_create_50(domask=False, doarea=False): 51,52,53,54,55,56,57, 61,62,63,64,65,66,67, 71,72,73,74,75,76,77,78]) - elemType = np.ones(num_elem-2)*ESMF.MeshElemType.QUAD - elemType = np.append(elemType, [ESMF.MeshElemType.TRI, ESMF.MeshElemType.TRI]) + elemType = np.ones(num_elem-2)*esmpy.MeshElemType.QUAD + elemType = np.append(elemType, [esmpy.MeshElemType.TRI, esmpy.MeshElemType.TRI]) elemConn = np.array([11,12,22,21,12,13,23,22,13,14,24,23,14,15,25,24,15,16,26,25,16,17,27,26,17,18,28,27, 21,22,32,31,22,23,33,32,23,24,34,33,24,25,35,34,25,26,36,35,26,27,37,36,27,28,38,37, 31,32,42,41,32,33,43,42,33,34,44,43,34,35,45,44,35,36,46,45,36,37,47,46,37,38,48,47, @@ -446,7 +446,7 @@ def mesh_create_50_ngons(domask=False, doarea=False): """ # Two parametric dimensions, and two spatial dimensions - mesh = ESMF.Mesh(parametric_dim=2, spatial_dim=2) + mesh = esmpy.Mesh(parametric_dim=2, spatial_dim=2) num_node = 65 num_elem = 50 @@ -474,11 +474,11 @@ def mesh_create_50_ngons(domask=False, doarea=False): 51,52,53,54,55,56,57, 61,62,63,64,65,66,67,68, 71,72,73,74,75,76,77]) - elemType = np.ones(num_elem)*ESMF.MeshElemType.QUAD + elemType = np.ones(num_elem)*esmpy.MeshElemType.QUAD elemType[35] = 5 - elemType[36] = ESMF.MeshElemType.TRI + elemType[36] = esmpy.MeshElemType.TRI elemType[37] = 5 - elemType[38] = ESMF.MeshElemType.TRI + elemType[38] = esmpy.MeshElemType.TRI elemConn = np.array([11,12,22,21,12,13,23,22,13,14,24,23,14,15,25,24,15,16,26,25,16,17,27,26,17,18,28,27, 21,22,32,31,22,23,33,32,23,24,34,33,24,25,35,34,25,26,36,35,26,27,37,36,27,28,38,37, 31,32,42,41,32,33,43,42,33,34,44,43,34,35,45,44,35,36,46,45,36,37,47,46,37,38,48,47, @@ -548,7 +548,7 @@ def mesh_create_4_ngons(domask=False, doarea=False): Note: This mesh is not parallel, it can only be used in serial """ # Two parametric dimensions, and two spatial dimensions - mesh = ESMF.Mesh(parametric_dim=2, spatial_dim=2) + mesh = esmpy.Mesh(parametric_dim=2, spatial_dim=2) num_node = 9 num_elem = 4 @@ -560,9 +560,9 @@ def mesh_create_4_ngons(domask=False, doarea=False): elemId = np.array([61,62,63,64]) elemType = np.ones(num_elem) elemType[0] = 5 - elemType[1] = ESMF.MeshElemType.TRI + elemType[1] = esmpy.MeshElemType.TRI elemType[2] = 5 - elemType[3] = ESMF.MeshElemType.TRI + elemType[3] = esmpy.MeshElemType.TRI elemConn = np.array([61, 62, 69, 72, 71, 62, 63, 69, 63, 64, 74, 73, 69, 69, 73, 72]) elemConn = np.array([np.where(a==nodeId) for a in elemConn]).flatten() elemMask = None @@ -622,13 +622,13 @@ def mesh_create_5_parallel (): # Element Id labels in centers """ # Two parametric dimensions, and two spatial dimensions - mesh = ESMF.Mesh(parametric_dim=2, spatial_dim=2) + mesh = esmpy.Mesh(parametric_dim=2, spatial_dim=2) - if ESMF.pet_count() > 1: - if ESMF.pet_count() != 4: + if esmpy.pet_count() > 1: + if esmpy.pet_count() != 4: raise NameError('MPI rank must be 4 to build this mesh!') - if (ESMF.local_pet() == 0): + if (esmpy.local_pet() == 0): num_node=4 num_elem=1 @@ -639,10 +639,10 @@ def mesh_create_5_parallel (): 2.0,2.0 ]) nodeOwner=np.zeros(num_node) elemId=np.array([11]) - elemType=np.array([ESMF.MeshElemType.QUAD]) + elemType=np.array([esmpy.MeshElemType.QUAD]) elemConn=np.array([0,1,3,2]) - elif (ESMF.local_pet() == 1): + elif (esmpy.local_pet() == 1): num_node=4 num_elem=1 @@ -656,10 +656,10 @@ def mesh_create_5_parallel (): 0, 1]) elemId=np.array([12]) - elemType=np.array([ESMF.MeshElemType.QUAD]) + elemType=np.array([esmpy.MeshElemType.QUAD]) elemConn=np.array([0,1,3,2]) - elif (ESMF.local_pet() == 2): + elif (esmpy.local_pet() == 2): num_node=4 num_elem=1 @@ -673,10 +673,10 @@ def mesh_create_5_parallel (): 2, 2]) elemId=np.array([21]) - elemType=np.array([ESMF.MeshElemType.QUAD]) + elemType=np.array([esmpy.MeshElemType.QUAD]) elemConn=np.array([0,1,3,2]) - elif (ESMF.local_pet() == 3): + elif (esmpy.local_pet() == 3): num_node=4 num_elem=2 @@ -690,8 +690,8 @@ def mesh_create_5_parallel (): 2, 3]) elemId=np.array([22,23]) - elemType=np.array([ESMF.MeshElemType.TRI, - ESMF.MeshElemType.TRI]) + elemType=np.array([esmpy.MeshElemType.TRI, + esmpy.MeshElemType.TRI]) elemConn=np.array([0,3,2, 0,1,3]) @@ -736,13 +736,13 @@ def mesh_create_5_pentahexa_parallel (): """ # Two parametric dimensions, and two spatial dimensions - mesh = ESMF.Mesh(parametric_dim=2, spatial_dim=2) + mesh = esmpy.Mesh(parametric_dim=2, spatial_dim=2) - if ESMF.pet_count() > 1: - if ESMF.pet_count() != 4: + if esmpy.pet_count() > 1: + if esmpy.pet_count() != 4: raise NameError('MPI rank must be 4 to build this mesh!') - if (ESMF.local_pet() == 0): + if (esmpy.local_pet() == 0): num_node=4 num_elem=1 @@ -753,10 +753,10 @@ def mesh_create_5_pentahexa_parallel (): 1.0, 1.0 ]) nodeOwner=np.zeros(num_node) elemId=np.array([1]) - elemType=np.array([ESMF.MeshElemType.QUAD]) + elemType=np.array([esmpy.MeshElemType.QUAD]) elemConn=np.array([0, 1, 3, 2 ]) - elif (ESMF.local_pet() == 1): + elif (esmpy.local_pet() == 1): num_node=4 num_elem=2 @@ -770,11 +770,11 @@ def mesh_create_5_pentahexa_parallel (): 0, 1]) elemId=np.array([2, 3]) - elemType=np.array([ESMF.MeshElemType.TRI, ESMF.MeshElemType.TRI]) + elemType=np.array([esmpy.MeshElemType.TRI, esmpy.MeshElemType.TRI]) elemConn=np.array([0, 1, 2, 1, 3, 2]) - elif (ESMF.local_pet() == 2): + elif (esmpy.local_pet() == 2): num_node=5 num_elem=1 @@ -793,7 +793,7 @@ def mesh_create_5_pentahexa_parallel (): elemType=np.array([5]) elemConn=np.array([0, 1, 4, 3, 2]) - elif (ESMF.local_pet() == 3): + elif (esmpy.local_pet() == 3): num_node=6 num_elem=1 @@ -856,14 +856,14 @@ def mesh_create_10_parallel (): # Node Id labels at corners # Element Id labels in centers """ - if ESMF.pet_count() > 1: - if ESMF.pet_count() != 4: + if esmpy.pet_count() > 1: + if esmpy.pet_count() != 4: raise NameError('MPI rank must be 4 to build this mesh!') # Two parametric dimensions, and two spatial dimensions - mesh = ESMF.Mesh(parametric_dim=2, spatial_dim=2) + mesh = esmpy.Mesh(parametric_dim=2, spatial_dim=2) - if (ESMF.local_pet() == 0): + if (esmpy.local_pet() == 0): num_node=9 num_elem=4 @@ -879,16 +879,16 @@ def mesh_create_10_parallel (): 2.5,2.5]) nodeOwner=np.zeros(num_node) elemId=np.array([11,12,21,22]) - elemType=np.array([ESMF.MeshElemType.QUAD, - ESMF.MeshElemType.QUAD, - ESMF.MeshElemType.QUAD, - ESMF.MeshElemType.QUAD]) + elemType=np.array([esmpy.MeshElemType.QUAD, + esmpy.MeshElemType.QUAD, + esmpy.MeshElemType.QUAD, + esmpy.MeshElemType.QUAD]) elemConn=np.array([0,1,4,3, 1,2,5,4, 3,4,7,6, 4,5,8,7]) - elif (ESMF.local_pet() == 1): + elif (esmpy.local_pet() == 1): num_node=6 num_elem=2 @@ -901,12 +901,12 @@ def mesh_create_10_parallel (): 4.0,2.5 ]) nodeOwner=np.array([0,1,0,1,0,1]) elemId=np.array([13,23]) - elemType=np.array([ESMF.MeshElemType.QUAD, - ESMF.MeshElemType.QUAD]) + elemType=np.array([esmpy.MeshElemType.QUAD, + esmpy.MeshElemType.QUAD]) elemConn=np.array([0,1,3,2, 2,3,5,4]) - elif (ESMF.local_pet() == 2): + elif (esmpy.local_pet() == 2): num_node=6 num_elem=2 @@ -919,12 +919,12 @@ def mesh_create_10_parallel (): 2.5,4.0 ]) nodeOwner=np.array([0,0,0,2,2,2]) elemId=np.array([31,32]) - elemType=np.array([ESMF.MeshElemType.QUAD, - ESMF.MeshElemType.QUAD]) + elemType=np.array([esmpy.MeshElemType.QUAD, + esmpy.MeshElemType.QUAD]) elemConn=np.array([0,1,4,3, 1,2,5,4]) - elif (ESMF.local_pet() == 3): + elif (esmpy.local_pet() == 3): num_node=4 num_elem=2 @@ -935,8 +935,8 @@ def mesh_create_10_parallel (): 4.0,4.0 ]) nodeOwner=np.array([0,1,2,3]) elemId=np.array([33,34]) - elemType=np.array([ESMF.MeshElemType.TRI, - ESMF.MeshElemType.TRI]) + elemType=np.array([esmpy.MeshElemType.TRI, + esmpy.MeshElemType.TRI]) elemConn=np.array([0,3,2, 0,1,3]) @@ -994,14 +994,14 @@ def mesh_create_50_parallel(domask=False, doarea=False): Node Ids at corners Element Ids in centers """ - if ESMF.pet_count() > 1: - if ESMF.pet_count() != 4: + if esmpy.pet_count() > 1: + if esmpy.pet_count() != 4: raise NameError('MPI rank must be 4 to build this mesh!') # Two parametric dimensions, and two spatial dimensions - mesh = ESMF.Mesh(parametric_dim=2, spatial_dim=2) + mesh = esmpy.Mesh(parametric_dim=2, spatial_dim=2) - if ESMF.local_pet() == 0: + if esmpy.local_pet() == 0: num_node = 16 num_elem = 9 nodeId = np.array([11,12,13,14, @@ -1016,7 +1016,7 @@ def mesh_create_50_parallel(domask=False, doarea=False): elemId = np.array([11,12,13, 21,22,23, 31,32,33]) - elemType = np.ones(num_elem)*ESMF.MeshElemType.QUAD + elemType = np.ones(num_elem)*esmpy.MeshElemType.QUAD elemConn = np.array([11,12,22,21,12,13,23,22,13,14,24,23, 21,22,32,31,22,23,33,32,23,24,34,33, 31,32,42,41,32,33,43,42,33,34,44,43]) @@ -1029,7 +1029,7 @@ def mesh_create_50_parallel(domask=False, doarea=False): if doarea: elemArea = np.ones(num_elem)*5 - elif ESMF.local_pet() == 1: + elif esmpy.local_pet() == 1: num_node = 20 num_elem = 12 nodeId = np.array([14,15,16,17,18, @@ -1044,7 +1044,7 @@ def mesh_create_50_parallel(domask=False, doarea=False): elemId = np.array([14,15,16,17, 24,25,26,27, 34,35,36,37]) - elemType = np.ones(num_elem)*ESMF.MeshElemType.QUAD + elemType = np.ones(num_elem)*esmpy.MeshElemType.QUAD elemConn = np.array([14,15,25,24,15,16,26,25,16,17,27,26,17,18,28,27, 24,25,35,34,25,26,36,35,26,27,37,36,27,28,38,37, 34,35,45,44,35,36,46,45,36,37,47,46,37,38,48,47]) @@ -1056,7 +1056,7 @@ def mesh_create_50_parallel(domask=False, doarea=False): if doarea: elemArea = np.ones(num_elem)*5 - elif ESMF.local_pet() == 2: + elif esmpy.local_pet() == 2: num_node = 20 num_elem = 12 nodeId = np.array([41,42,43,44, @@ -1074,7 +1074,7 @@ def mesh_create_50_parallel(domask=False, doarea=False): 51,52,53, 61,62,63, 71,72,73]) - elemType = np.ones(num_elem)*ESMF.MeshElemType.QUAD + elemType = np.ones(num_elem)*esmpy.MeshElemType.QUAD elemConn = np.array([41,42,52,51,42,43,53,52,43,44,54,53, 51,52,62,61,52,53,63,62,53,54,64,63, 61,62,72,71,62,63,73,72,63,64,74,73, @@ -1087,7 +1087,7 @@ def mesh_create_50_parallel(domask=False, doarea=False): if doarea: elemArea = np.ones(num_elem)*5 - elif ESMF.local_pet() == 3: + elif esmpy.local_pet() == 3: num_node = 25 num_elem = 17 nodeId = np.array([44,45,46,47,48, @@ -1105,8 +1105,8 @@ def mesh_create_50_parallel(domask=False, doarea=False): 54,55,56,57, 64,65,66,67, 74,75,76,77,78]) - elemType = np.ones(num_elem-2)*ESMF.MeshElemType.QUAD - elemType = np.append(elemType, [ESMF.MeshElemType.TRI, ESMF.MeshElemType.TRI]) + elemType = np.ones(num_elem-2)*esmpy.MeshElemType.QUAD + elemType = np.append(elemType, [esmpy.MeshElemType.TRI, esmpy.MeshElemType.TRI]) elemConn = np.array([44,45,55,54,45,46,56,55,46,47,57,56,47,48,58,57, 54,55,65,64,55,56,66,65,56,57,67,66,57,58,68,67, 64,65,75,74,65,66,76,75,66,67,77,76,67,68,78,77, @@ -1189,14 +1189,14 @@ def mesh_create_50_ngons_parallel(domask=False, doarea=False): Node Ids at corners Element Ids in centers """ - if ESMF.pet_count() > 1: - if ESMF.pet_count() != 4: + if esmpy.pet_count() > 1: + if esmpy.pet_count() != 4: raise NameError('MPI rank must be 4 to build this mesh!') # Two parametric dimensions, and two spatial dimensions - mesh = ESMF.Mesh(parametric_dim=2, spatial_dim=2) + mesh = esmpy.Mesh(parametric_dim=2, spatial_dim=2) - if ESMF.local_pet() == 0: + if esmpy.local_pet() == 0: num_node = 16 num_elem = 9 nodeId = np.array([11,12,13,14, @@ -1211,7 +1211,7 @@ def mesh_create_50_ngons_parallel(domask=False, doarea=False): elemId = np.array([11,12,13, 21,22,23, 31,32,33]) - elemType = np.ones(num_elem)*ESMF.MeshElemType.QUAD + elemType = np.ones(num_elem)*esmpy.MeshElemType.QUAD elemConn = np.array([11,12,22,21,12,13,23,22,13,14,24,23, 21,22,32,31,22,23,33,32,23,24,34,33, 31,32,42,41,32,33,43,42,33,34,44,43]) @@ -1224,7 +1224,7 @@ def mesh_create_50_ngons_parallel(domask=False, doarea=False): if doarea: elemArea = np.ones(num_elem)*5 - elif ESMF.local_pet() == 1: + elif esmpy.local_pet() == 1: num_node = 20 num_elem = 12 nodeId = np.array([14,15,16,17,18, @@ -1239,7 +1239,7 @@ def mesh_create_50_ngons_parallel(domask=False, doarea=False): elemId = np.array([14,15,16,17, 24,25,26,27, 34,35,36,37]) - elemType = np.ones(num_elem)*ESMF.MeshElemType.QUAD + elemType = np.ones(num_elem)*esmpy.MeshElemType.QUAD elemConn = np.array([14,15,25,24,15,16,26,25,16,17,27,26,17,18,28,27, 24,25,35,34,25,26,36,35,26,27,37,36,27,28,38,37, 34,35,45,44,35,36,46,45,36,37,47,46,37,38,48,47]) @@ -1251,7 +1251,7 @@ def mesh_create_50_ngons_parallel(domask=False, doarea=False): if doarea: elemArea = np.ones(num_elem)*5 - elif ESMF.local_pet() == 2: + elif esmpy.local_pet() == 2: num_node = 21 num_elem = 13 nodeId = np.array([41,42,43,44, @@ -1269,11 +1269,11 @@ def mesh_create_50_ngons_parallel(domask=False, doarea=False): 51,52,53, 61,62,63,68, 71,72,73]) - elemType = np.ones(num_elem)*ESMF.MeshElemType.QUAD + elemType = np.ones(num_elem)*esmpy.MeshElemType.QUAD elemType[6] = 5 - elemType[7] = ESMF.MeshElemType.TRI + elemType[7] = esmpy.MeshElemType.TRI elemType[8] = 5 - elemType[9] = ESMF.MeshElemType.TRI + elemType[9] = esmpy.MeshElemType.TRI elemConn = np.array([41,42,52,51,42,43,53,52,43,44,54,53, 51,52,62,61,52,53,63,62,53,54,64,63, 61,62,69,72,71,62,63,69,63,64,74,73,69,69,73,72, @@ -1290,7 +1290,7 @@ def mesh_create_50_ngons_parallel(domask=False, doarea=False): elemArea[8] = 6.25 elemArea[9] = 1.25 - elif ESMF.local_pet() == 3: + elif esmpy.local_pet() == 3: num_node = 25 num_elem = 16 nodeId = np.array([44,45,46,47,48, @@ -1308,7 +1308,7 @@ def mesh_create_50_ngons_parallel(domask=False, doarea=False): 54,55,56,57, 64,65,66,67, 74,75,76,77]) - elemType = np.ones(num_elem)*ESMF.MeshElemType.QUAD + elemType = np.ones(num_elem)*esmpy.MeshElemType.QUAD elemConn = np.array([44,45,55,54,45,46,56,55,46,47,57,56,47,48,58,57, 54,55,65,64,55,56,66,65,56,57,67,66,57,58,68,67, 64,65,75,74,65,66,76,75,66,67,77,76,67,68,78,77, @@ -1349,7 +1349,7 @@ def initialize_field_mesh(field, nodeCoord, nodeOwner, elemType, elemConn, if field.staggerloc == element: offset = 0 for i in range(field.grid.size_owned[element]): - if (elemType[i] == ESMF.MeshElemType.TRI): + if (elemType[i] == esmpy.MeshElemType.TRI): x1 = nodeCoord[(elemConn[offset])*2] x2 = nodeCoord[(elemConn[offset+1])*2] x3 = nodeCoord[(elemConn[offset+2])*2] @@ -1359,7 +1359,7 @@ def initialize_field_mesh(field, nodeCoord, nodeOwner, elemType, elemConn, x = (x1 + x2 + x3) / 3.0 y = (y1 + y2 + y3) / 3.0 offset = offset + 3 - elif (elemType[i] == ESMF.MeshElemType.QUAD): + elif (elemType[i] == esmpy.MeshElemType.QUAD): x1 = nodeCoord[(elemConn[offset])*2] x2 = nodeCoord[(elemConn[offset+1])*2] y1 = nodeCoord[(elemConn[offset+1])*2+1] @@ -1385,7 +1385,7 @@ def initialize_field_mesh(field, nodeCoord, nodeOwner, elemType, elemConn, x = nodeCoord[i*2] y = nodeCoord[i*2+1] - if (nodeOwner[i] == ESMF.local_pet()): + if (nodeOwner[i] == esmpy.local_pet()): if ind > field.grid.size_owned[node]: raise ValueError("Overstepped the mesh bounds!") field.data[ind] = 20.0 + x**2 +x*y + y**2 @@ -1414,8 +1414,8 @@ def compute_mass_mesh(valuefield, dofrac=False, fracfield=None, """ mass = 0.0 # mesh area field must be built on elements - areafield = ESMF.Field(valuefield.grid, name='areafield', - meshloc=ESMF.MeshLoc.ELEMENT) + areafield = esmpy.Field(valuefield.grid, name='areafield', + meshloc=esmpy.MeshLoc.ELEMENT) areafield.get_area() ind = np.where(valuefield.data != uninitval) diff --git a/src/addon/ESMPy/src/ESMF/util/slicing.py b/src/addon/ESMPy/src/esmpy/util/slicing.py similarity index 85% rename from src/addon/ESMPy/src/ESMF/util/slicing.py rename to src/addon/ESMPy/src/esmpy/util/slicing.py index 1f53467948..0bb83864f3 100644 --- a/src/addon/ESMPy/src/ESMF/util/slicing.py +++ b/src/addon/ESMPy/src/esmpy/util/slicing.py @@ -3,7 +3,7 @@ """ import numpy as np -import ESMF +import esmpy #### HELPERS ######################################################### @@ -65,15 +65,15 @@ def get_none_or_ssslice(target, slc, stagger, rank): slc2 = None if rank == 2: assert(len(slc) == 2) - if stagger == ESMF.StaggerLoc.CENTER: + if stagger == esmpy.StaggerLoc.CENTER: slc2 = slc - elif stagger == ESMF.StaggerLoc.EDGE1: + elif stagger == esmpy.StaggerLoc.EDGE1: #slc[0] + 1 slc2 = (slice(slc[0].start, slc[0].stop + 1, slc[0].step), slc[1]) - elif stagger == ESMF.StaggerLoc.EDGE2: + elif stagger == esmpy.StaggerLoc.EDGE2: #slc[1] + 1 slc2 = (slc[0], slice(slc[1].start, slc[1].stop + 1, slc[1].step)) - elif stagger == ESMF.StaggerLoc.CORNER: + elif stagger == esmpy.StaggerLoc.CORNER: #slc[0] + 1 #slc[1] + 1 slc2 = ([slice(slc[i].start, slc[i].stop + 1, slc[i].step) for i in range(len(slc))]) @@ -82,30 +82,30 @@ def get_none_or_ssslice(target, slc, stagger, rank): elif rank == 3: assert (len(slc) == 3) - if stagger == ESMF.StaggerLoc.CENTER_VCENTER: + if stagger == esmpy.StaggerLoc.CENTER_VCENTER: slc2 = slc - elif stagger == ESMF.StaggerLoc.EDGE1_VCENTER: + elif stagger == esmpy.StaggerLoc.EDGE1_VCENTER: #slc[0] + 1 slc2 = (slice(slc[0].start, slc[0].stop + 1, slc[0].step), slc[1], slc[2]) - elif stagger == ESMF.StaggerLoc.EDGE2_VCENTER: + elif stagger == esmpy.StaggerLoc.EDGE2_VCENTER: #slc[1] + 1 slc2 = (slc[0], slice(slc[1].start, slc[1].stop + 1, slc[1].step), slc[2]) - elif stagger == ESMF.StaggerLoc.CORNER_VCENTER: + elif stagger == esmpy.StaggerLoc.CORNER_VCENTER: #slc[0] + 1 #slc[1] + 1 slc2 = (slice(slc[0].start, slc[0].stop + 1, slc[0].step), slice(slc[1].start, slc[1].stop + 1, slc[1].step), slc[2]) - elif stagger == ESMF.StaggerLoc.CENTER_VFACE: + elif stagger == esmpy.StaggerLoc.CENTER_VFACE: #slc[2] + 1 slc2 = (slc[0], slc[1], slice(slc[2].start, slc[2].stop + 1, slc[2].step)) - elif stagger == ESMF.StaggerLoc.EDGE1_VFACE: + elif stagger == esmpy.StaggerLoc.EDGE1_VFACE: #slc[0] + 1 #slc[2] + 1 slc2 = (slice(slc[0].start, slc[0].stop + 1, slc[0].step), slc[1], slice(slc[2].start, slc[2].stop + 1, slc[2].step)) - elif stagger == ESMF.StaggerLoc.EDGE2_VFACE: + elif stagger == esmpy.StaggerLoc.EDGE2_VFACE: #slc[1] + 1 #slc[2] + 1 slc2 = (slc[0], slice(slc[1].start, slc[1].stop + 1, slc[1].step), slice(slc[2].start, slc[2].stop + 1, slc[2].step)) - elif stagger == ESMF.StaggerLoc.CORNER_VFACE: + elif stagger == esmpy.StaggerLoc.CORNER_VFACE: #slc[0] + 1 #slc[1] + 1 #slc[2] + 1 From b7c4e787ba2f0d12ddd74bafb6a7f73cbeb681a4 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Tue, 30 Aug 2022 12:03:59 -0600 Subject: [PATCH 21/45] fix esmpy regrid from file test runner --- .../src/esmpy/test/regrid_from_file/run_regrid_from_file.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file.py b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file.py index 67b82288c2..6742911c76 100644 --- a/src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file.py +++ b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file.py @@ -25,7 +25,7 @@ rtestoutfile='run_regrid_from_file_parallel.log' constants._ESMF_MPIRUN + " -n " -os.system(constants._ESMF_MPIRUN + " -n " + str(constants._ESMF_MPIRUN_NP) + " python " + rtestfile + " > " + rtestoutfile + " 2>&1") +os.system(constants._ESMF_MPIRUN + " -n " + str(constants._ESMF_MPIRUN_NP) + " python3 " + rtestfile + " > " + rtestoutfile + " 2>&1") # traverse output, find number of pass and fail and print report RTEST = open(rtestoutfile) From 1d65e88792958973a3a956243535c40f17f41d27 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Tue, 30 Aug 2022 11:05:58 -0700 Subject: [PATCH 22/45] improve esmpy test targets --- src/addon/ESMPy/Makefile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/addon/ESMPy/Makefile b/src/addon/ESMPy/Makefile index 22c8330913..b0f7e908fc 100644 --- a/src/addon/ESMPy/Makefile +++ b/src/addon/ESMPy/Makefile @@ -37,11 +37,13 @@ test_regrid_from_file_dryrun: test_regrid_from_file: python3 -m pytest -vs src/esmpy/test/regrid_from_file/rfftest.py -test_all: test_unit test_parallel test_examples test_examples_parallel +test_serial: test_unit test_examples -test_parallel: test_unit_parallel test_examples_dryrun test_examples_parallel +test_dryrun: test_examples_dryrun test_regrid_from_file_dryrun -test_uni: test_unit test_examples +test_parallel: test_unit_parallel test_examples_parallel test_regrid_from_file + +test_all: test_unit test_unit_parallel test_examples test_examples_parallel test_regrid_from_file uninstall: python3 -m pip uninstall ESMPy From 95bea1f96f3ba6be0703043e2052f07243406f38 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Tue, 30 Aug 2022 15:01:53 -0700 Subject: [PATCH 23/45] convert ESMPy regrid from file testing to use pytest --- src/addon/ESMPy/Makefile | 27 +++-- src/addon/ESMPy/src/esmpy/api/esmpymanager.py | 2 +- .../regrid_from_file/regrid_check_driver.py | 93 ---------------- .../esmpy/test/regrid_from_file/rfftest.py | 18 --- .../test/regrid_from_file/rfftestdryrun.py | 14 --- .../regrid_from_file/run_regrid_from_file.py | 103 ++++++++---------- .../run_regrid_from_file_dryrun.py | 10 +- .../ESMPy/src/esmpy/util/field_utilities.py | 4 +- 8 files changed, 71 insertions(+), 200 deletions(-) delete mode 100644 src/addon/ESMPy/src/esmpy/test/regrid_from_file/regrid_check_driver.py delete mode 100644 src/addon/ESMPy/src/esmpy/test/regrid_from_file/rfftest.py delete mode 100644 src/addon/ESMPy/src/esmpy/test/regrid_from_file/rfftestdryrun.py diff --git a/src/addon/ESMPy/Makefile b/src/addon/ESMPy/Makefile index b0f7e908fc..32435bdbdc 100644 --- a/src/addon/ESMPy/Makefile +++ b/src/addon/ESMPy/Makefile @@ -17,33 +17,36 @@ install: python3 -m pip install . test_unit: - python3 -m pytest -m="not parallel" + python3 -m pytest -m="not parallel" --json-report --json-report-summary test_unit_parallel: - mpirun -n 4 python3 -m pytest -m="not serial" + mpirun -n 4 python3 -m pytest -m="not serial" --json-report --json-report-summary -test_examples_dryrun: - python3 -m pytest -vs examples/exampletestdryrun.py - test_examples: python3 -m pytest -vs -m="not parallel" examples/exampletest.py test_examples_parallel: mpirun -n 4 python3 -m pytest -vs -m="not serial" examples/exampletest.py +test_examples_dryrun: + python3 -m pytest -vs examples/exampletestdryrun.py + +test_regrid_from_file: + python3 -m pytest -vs src/esmpy/test/regrid_from_file/run_regrid_from_file.py + +test_regrid_from_file_parallel: + mpirun -n 4 python3 -m pytest -vs src/esmpy/test/regrid_from_file/run_regrid_from_file.py + test_regrid_from_file_dryrun: - python3 -m pytest -vs src/esmpy/test/regrid_from_file/rfftestdryrun.py + python3 -m pytest -vs src/esmpy/test/regrid_from_file/run_regrid_from_file_dryrun.py -test_regrid_from_file: - python3 -m pytest -vs src/esmpy/test/regrid_from_file/rfftest.py +test_serial: test_unit test_examples test_regrid_from_file -test_serial: test_unit test_examples +test_parallel: test_unit_parallel test_examples_parallel test_regrid_from_file_parallel test_dryrun: test_examples_dryrun test_regrid_from_file_dryrun -test_parallel: test_unit_parallel test_examples_parallel test_regrid_from_file - -test_all: test_unit test_unit_parallel test_examples test_examples_parallel test_regrid_from_file +test_all: test_unit test_unit_parallel test_examples test_examples_parallel test_regrid_from_file test_regrid_from_file_parallel uninstall: python3 -m pip uninstall ESMPy diff --git a/src/addon/ESMPy/src/esmpy/api/esmpymanager.py b/src/addon/ESMPy/src/esmpy/api/esmpymanager.py index ddf8f481c0..cda53527da 100644 --- a/src/addon/ESMPy/src/esmpy/api/esmpymanager.py +++ b/src/addon/ESMPy/src/esmpy/api/esmpymanager.py @@ -18,7 +18,7 @@ def _preprocess(v, separator, ignorecase): if ignorecase: v = v.lower() return [int(x) if x.isdigit() else [int(y) if y.isdigit() else y for y in - re.findall("\d+|[a-zA-Z]+", x)] for x in v.split(separator)] + re.findall(r"\d+|[a-zA-Z]+", x)] for x in v.split(separator)] def version_compare(a, b, separator = '.', ignorecase = True): a = _preprocess(a, separator, ignorecase) diff --git a/src/addon/ESMPy/src/esmpy/test/regrid_from_file/regrid_check_driver.py b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/regrid_check_driver.py deleted file mode 100644 index 25edc3e0d3..0000000000 --- a/src/addon/ESMPy/src/esmpy/test/regrid_from_file/regrid_check_driver.py +++ /dev/null @@ -1,93 +0,0 @@ -# $Id$ - -""" -Reads each line of a control file where each line corresponds to one test -case. Parses each line and calls a test subroutine that creates meshes from -source and destination NetCDF files, creates an analytic field across the -source mesh, regrids the source mesh to the grid of the destination mesh, -and compares the analytic field of the resulting regridded mesh to that of the -source mesh. -""" - -import sys -import os -import traceback - -try: - import esmpy -except: - raise ImportError('The ESMF library cannot be found!') -from esmpy.test.regrid_from_file.regrid_from_file_consts import DATA_SUBDIR -from esmpy.test.regrid_from_file.run_regrid_from_file_dryrun import cache_data_files_for_test_cases -from esmpy.test.regrid_from_file.regrid_check import regrid_check -from esmpy.test.regrid_from_file.read_test_cases_from_control_file import read_control_file - -# Start up ESMF and run regrid test for each line of options -# read from a control file. Retrieve data files for each test from a remote -# server if they do not exist locally. -# Start up esmpy. -mg = esmpy.Manager(debug=True) - -parallel = False -if esmpy.pet_count() > 1: - parallel = True - -# Read the test case parameters from the control file. - -print('Reading control file...') -test_cases = read_control_file() -if (esmpy.local_pet() == 0): - # Retrieve the data files needed for the test cases from the remote server. - print('Retrieving regrid_from_file data...') - status_ok = cache_data_files_for_test_cases(test_cases) - -# For each test case line from the control file parse the line and call -# the test subroutine. -for ctr, test_case in enumerate(test_cases, start=1): - print('Running {0} of {1} regrid_from_file test cases...'.format(ctr, len(test_cases))) - (src_fname, dst_fname, regrid_method, options, - itrp_mean_err, itrp_max_err, csrv_err) = test_case - test_str = 'Regrid %s to %s as %s with %s itrp_mean_err=%f, itrp_max_err=%f, and csrv_err=%f' % (src_fname, dst_fname, regrid_method, options, itrp_mean_err, itrp_max_err, csrv_err) - print ('\n' + test_str + ' - START\n') - src_fname_full = os.path.join(DATA_SUBDIR, src_fname) - dst_fname_full = os.path.join(DATA_SUBDIR, dst_fname) - - if parallel: - # set a barrier to wait for files to be downloaded - mg.barrier() - - # run the data file retrieval and regridding through try/except - correct = False - try: - correct = regrid_check(src_fname_full, dst_fname_full, regrid_method, - options, itrp_mean_err, itrp_max_err, csrv_err) - except: - print ("Regridding ERROR:\n") - traceback.print_exc(file=sys.stdout) - - skip = False - for i in range(esmpy.pet_count()): - for line in open("PET"+str(i)+".ESMF_LogFile"): - if "ESMF_NETCDF not defined when lib was compiled" in line or \ - "File format is not supported" in line: - # set skip - skip = True - - # print the file - print ('\n***NOTE*** The log files must be deleted in this test case, they are printed below for future reference\n') - if skip: - for line in open("PET"+str(i)+".ESMF_LogFile"): - print (line) - - # clean the log files - for i in range(esmpy.pet_count()): - os.system("echo ' ' > PET"+str(i)+".ESMF_LogFile") - - print ("\nPET: " + str(esmpy.local_pet()) + " - " + test_str + " - FINISH\n") - - if skip: - print ('RESULT: SKIP\n\n') - elif correct: - print ('RESULT: PASS\n\n') - else: - print ('RESULT: FAIL\n\n') diff --git a/src/addon/ESMPy/src/esmpy/test/regrid_from_file/rfftest.py b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/rfftest.py deleted file mode 100644 index 4c19cf6dfe..0000000000 --- a/src/addon/ESMPy/src/esmpy/test/regrid_from_file/rfftest.py +++ /dev/null @@ -1,18 +0,0 @@ -# $Id$ - -""" -examples test file -""" - -import pytest - -from esmpy.test.base import TestBase, attr - -class TestRFF(TestBase): - - # # '0' in the name is so it is run first - # def test_0_regrid_from_file_dryrun(self): - # from esmpy.test.regrid_from_file import run_regrid_from_file_dryrun - - def test_regrid_from_file(self): - from esmpy.test.regrid_from_file import run_regrid_from_file diff --git a/src/addon/ESMPy/src/esmpy/test/regrid_from_file/rfftestdryrun.py b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/rfftestdryrun.py deleted file mode 100644 index 2ee122f2ac..0000000000 --- a/src/addon/ESMPy/src/esmpy/test/regrid_from_file/rfftestdryrun.py +++ /dev/null @@ -1,14 +0,0 @@ -# $Id$ - -""" -examples test file -""" - -import pytest - -from esmpy.test.base import TestBase, attr - -class TestRFFDryrun(TestBase): - - def test_regrid_from_file_dryrun(self): - from esmpy.test.regrid_from_file import run_regrid_from_file_dryrun diff --git a/src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file.py b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file.py index 6742911c76..f8dca3a750 100644 --- a/src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file.py +++ b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file.py @@ -1,58 +1,51 @@ # $Id$ -import os -import sys - -import esmpy.api.constants as constants -from esmpy.test.regrid_from_file.regrid_from_file_consts import TEST_REGRID_DIR - - -parallel = False -if len(sys.argv) > 1: - if "--parallel" in sys.argv[1]: - parallel = True - -# run utests, pipe to file -rtestfile=os.path.join(TEST_REGRID_DIR, 'regrid_check_driver.py') -rtestoutfile='run_regrid_from_file.log' -num_proc = 1 -if parallel: - # make sure we are not in uni mode - if constants._ESMF_COMM == constants._ESMF_COMM_MPIUNI: - raise ValueError("Cannot run parallel tests when ESMF is built with ESMF_COMM=mpiuni") - - # setup the constants - rtestoutfile='run_regrid_from_file_parallel.log' - -constants._ESMF_MPIRUN + " -n " -os.system(constants._ESMF_MPIRUN + " -n " + str(constants._ESMF_MPIRUN_NP) + " python3 " + rtestfile + " > " + rtestoutfile + " 2>&1") +""" +Reads each line of a control file where each line corresponds to one test +case. Parses each line and calls a test subroutine that creates meshes from +source and destination NetCDF files, creates an analytic field across the +source mesh, regrids the source mesh to the grid of the destination mesh, +and compares the analytic field of the resulting regridded mesh to that of the +source mesh. +""" -# traverse output, find number of pass and fail and print report -RTEST = open(rtestoutfile) - -rtpass = 0 -rtfail = 0 -rtskip = 0 - -for line in RTEST: - if 'RESULT: PASS' in line: - rtpass=rtpass+1 - if 'RESULT: FAIL' in line: - rtfail=rtfail+1 - if 'RESULT: SKIP' in line: - rtskip=rtskip+1 - -RTEST.close() - -rtpass = rtpass/num_proc -rtfail = rtfail/num_proc -rtskip = rtskip/num_proc - -print("Regrid from file test results: "+rtestoutfile) -print("PASS = "+str(int(rtpass))) -print("FAIL = "+str(int(rtfail))) -print("SKIP = "+str(int(rtskip))) - -if rtpass == 0 and rtfail == 0 and rtskip == 0: - print(rtestoutfile+":") - os.system("tail "+rtestoutfile) +import sys +import os +import traceback +import pytest + +try: + import esmpy +except: + raise ImportError('The ESMF library cannot be found!') +from esmpy.test.regrid_from_file.regrid_from_file_consts import DATA_SUBDIR +from esmpy.test.regrid_from_file.regrid_check import regrid_check +from esmpy.test.regrid_from_file.read_test_cases_from_control_file import read_control_file + +# Start up esmpy. +mg = esmpy.Manager(debug=True) + +# Read the test case parameters from the control file. +print('Reading control file...') +test_cases = read_control_file() + +# For each test case line from the control file parse the line and call +# the test subroutine. + +@pytest.mark.parametrize('test_case', test_cases) +def test_run_regrid_from_file(test_case): + (src_fname, dst_fname, regrid_method, options, + itrp_mean_err, itrp_max_err, csrv_err) = test_case + test_str = 'Regrid %s to %s as %s with %s itrp_mean_err=%f, itrp_max_err=%f, and csrv_err=%f' % (src_fname, dst_fname, regrid_method, options, itrp_mean_err, itrp_max_err, csrv_err) + if esmpy.local_pet() == 0: + print ('\n' + test_str) + src_fname_full = os.path.join(DATA_SUBDIR, src_fname) + dst_fname_full = os.path.join(DATA_SUBDIR, dst_fname) + + # run the data file retrieval and regridding through try/except + try: + correct = regrid_check(src_fname_full, dst_fname_full, regrid_method, + options, itrp_mean_err, itrp_max_err, csrv_err) + except: + print ("PET {}: Regridding ERROR:{}".format(esmpy.local_pet(), correct)) + traceback.print_exc(file=sys.stdout) diff --git a/src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file_dryrun.py b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file_dryrun.py index 5b7ca181b3..21eb31c7d1 100644 --- a/src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file_dryrun.py +++ b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file_dryrun.py @@ -40,8 +40,8 @@ def cache_data_files_for_test_cases(test_cases): test_cases = read_control_file() # Retrieve the data files needed for the test cases from the remote server. -status_ok = cache_data_files_for_test_cases(test_cases) -if status_ok: - print ('RESULT: PASS - regrid_from_file_dryrun ok\n\n') -else: - print ('RESULT: FAIL - regrid_from_file_dryrun error\n\n') +try: + status_ok = cache_data_files_for_test_cases(test_cases) +except: + print ("Cache data file error: {}\n".format(status_ok)) + traceback.print_exc(file=sys.stdout) diff --git a/src/addon/ESMPy/src/esmpy/util/field_utilities.py b/src/addon/ESMPy/src/esmpy/util/field_utilities.py index 122526cfc1..bda753fa62 100644 --- a/src/addon/ESMPy/src/esmpy/util/field_utilities.py +++ b/src/addon/ESMPy/src/esmpy/util/field_utilities.py @@ -123,7 +123,7 @@ def compare_fields(field1, field2, itrp_mean_tol, itrp_max_tol, csrv_tol, csrv = True # print out diagnostic information - print ("\n Mean relative error = "+str(total_error_global)) + print (" Mean relative error = "+str(total_error_global)) print (" Max relative error = "+str(max_error_global)) print (" Conservation error = "+str(csrv_error_global)) #print (" Min error = "+str(min_error_global)) @@ -145,4 +145,4 @@ def compare_fields(field1, field2, itrp_mean_tol, itrp_max_tol, csrv_tol, else: print ("PET{0} - FAIL".format(esmpy.local_pet())) - return total_error_global, csrv_error_global, correct \ No newline at end of file + return total_error_global, csrv_error_global, correct From 638b5e945b1b83ea01c9c35a141bdff82567caa3 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Tue, 30 Aug 2022 15:06:48 -0700 Subject: [PATCH 24/45] fix the ESMPy cubed sphere example --- src/addon/ESMPy/Makefile | 8 +-- .../examples/cubed_sphere_to_mesh_regrid.py | 3 +- src/addon/ESMPy/examples/exampletest.py | 52 +++++++++++-------- .../src/esmpy/test/test_api/test_grid.py | 1 - 4 files changed, 37 insertions(+), 27 deletions(-) diff --git a/src/addon/ESMPy/Makefile b/src/addon/ESMPy/Makefile index 32435bdbdc..7eec02c873 100644 --- a/src/addon/ESMPy/Makefile +++ b/src/addon/ESMPy/Makefile @@ -17,16 +17,16 @@ install: python3 -m pip install . test_unit: - python3 -m pytest -m="not parallel" --json-report --json-report-summary + python3 -m pytest -m="not parallel" test_unit_parallel: - mpirun -n 4 python3 -m pytest -m="not serial" --json-report --json-report-summary + mpirun -n 4 python3 -m pytest -m="not serial" test_examples: - python3 -m pytest -vs -m="not parallel" examples/exampletest.py + python3 -m pytest -vs examples/exampletest.py test_examples_parallel: - mpirun -n 4 python3 -m pytest -vs -m="not serial" examples/exampletest.py + mpirun -n 4 python3 -m pytest -vs examples/exampletest.py test_examples_dryrun: python3 -m pytest -vs examples/exampletestdryrun.py diff --git a/src/addon/ESMPy/examples/cubed_sphere_to_mesh_regrid.py b/src/addon/ESMPy/examples/cubed_sphere_to_mesh_regrid.py index 0544e036dc..ee54fa2b0b 100644 --- a/src/addon/ESMPy/examples/cubed_sphere_to_mesh_regrid.py +++ b/src/addon/ESMPy/examples/cubed_sphere_to_mesh_regrid.py @@ -26,7 +26,8 @@ grid1 = "examples/data/ll1deg_grid.nc" # Create a cubed sphere grid with 20 elements per tile -srcgrid = esmpy.Grid(tilesize=20, name="cubed_sphere") +regDecompPTile = numpy.array([[2,2,1,1,1,1],[2,2,2,2,2,2]], dtype=numpy.int32) +srcgrid = esmpy.Grid(tilesize=20, regDecompPTile = regDecompPTile, name="cubed_sphere") # create an regular lat lon grid from file dstgrid = esmpy.Grid(filename=grid1, filetype=esmpy.FileFormat.SCRIP) diff --git a/src/addon/ESMPy/examples/exampletest.py b/src/addon/ESMPy/examples/exampletest.py index 7ec3c92018..e3325578ef 100644 --- a/src/addon/ESMPy/examples/exampletest.py +++ b/src/addon/ESMPy/examples/exampletest.py @@ -20,15 +20,6 @@ def test_helloworld(self): from . import hello_world # ESMF IO does not work in mpiuni mode - @pytest.mark.parallel - def test_cubed_sphere_to_mesh_regrid(self): - if constants._ESMF_COMM == constants._ESMF_COMM_MPIUNI: - raise SkipTest('ESMF must be built with MPI for test') - else: - from . import cubed_sphere_to_mesh_regrid - - # ESMF IO does not work in mpiuni mode - # only example, not in documentation def test_field_read(self): if constants._ESMF_COMM == constants._ESMF_COMM_MPIUNI: raise SkipTest('ESMF must be built with MPI for test') @@ -37,13 +28,22 @@ def test_field_read(self): # only example, not in documentation def test_grid_create_peridim_mask(self): - from . import grid_create_peridim_mask + if constants._ESMF_COMM == constants._ESMF_COMM_MPIUNI: + raise SkipTest('ESMF must be built with MPI for test') + else: + from . import grid_create_peridim_mask def test_grid_locstream_regrid(self): - from . import grid_locstream_regrid + if constants._ESMF_COMM == constants._ESMF_COMM_MPIUNI: + raise SkipTest('ESMF must be built with MPI for test') + else: + from . import grid_locstream_regrid def test_locstream_grid_regrid(self): - from . import locstream_grid_regrid + if constants._ESMF_COMM == constants._ESMF_COMM_MPIUNI: + raise SkipTest('ESMF must be built with MPI for test') + else: + from . import locstream_grid_regrid def test_mesh_locstream_regrid(self): from . import mesh_locstream_regrid @@ -62,15 +62,25 @@ def test_regrid_from_file(self): else: from . import regrid_from_file - # # only example, not in documentation, datafile missing from repo - # @pytest.mark.slow - # def test_tripole_regrid(self): - # from . import tripole_regrid - - # only example, not in documentation def test_ugrid_latlon_regrid(self): - from . import ugrid_latlon_regrid + if constants._ESMF_COMM == constants._ESMF_COMM_MPIUNI: + raise SkipTest('ESMF must be built with MPI for test') + else: + from . import ugrid_latlon_regrid - # only example, not in documentation def test_ungridded_dimension_regrid(self): - from . import ungridded_dimension_regrid + if constants._ESMF_COMM == constants._ESMF_COMM_MPIUNI: + raise SkipTest('ESMF must be built with MPI for test') + else: + from . import ungridded_dimension_regrid + + # # ESMF IO does not work in mpiuni mode + # def test_cubed_sphere_to_mesh_regrid(self): + # if constants._ESMF_COMM == constants._ESMF_COMM_MPIUNI: + # raise SkipTest('ESMF must be built with MPI for test') + # else: + # from . import cubed_sphere_to_mesh_regrid + + # # datafile missing from repo + # def test_tripole_regrid(self): + # from . import tripole_regrid diff --git a/src/addon/ESMPy/src/esmpy/test/test_api/test_grid.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_grid.py index 37a9b57ace..f8183b48ef 100644 --- a/src/addon/ESMPy/src/esmpy/test/test_api/test_grid.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_grid.py @@ -260,7 +260,6 @@ def test_grid_create_3d(self): raise ValueError( "The following combinations of Grid parameters failed to create a proper Grid: " + str(fail)) - @pytest.mark.serial def test_grid_create_cubed_sphere(self): # keywords = dict( # periodic specifies all valid combos of [num_peri_dims, periodic_dim, pole_dim] From 505b6a76db00990a886cb63d8c0a089494db0d6a Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Thu, 1 Sep 2022 13:34:37 -0700 Subject: [PATCH 25/45] remove beta decorator from ESMPy GridCreateCubedSphere --- src/addon/ESMPy/src/esmpy/interface/cbindings.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/addon/ESMPy/src/esmpy/interface/cbindings.py b/src/addon/ESMPy/src/esmpy/interface/cbindings.py index c344b48d37..b15f247102 100644 --- a/src/addon/ESMPy/src/esmpy/interface/cbindings.py +++ b/src/addon/ESMPy/src/esmpy/interface/cbindings.py @@ -613,7 +613,6 @@ def ESMP_GridCreateNoPeriDim(maxIndex, coordSys=None, coordTypeKind=None): ct.POINTER(ESMP_InterfaceInt), ct.c_void_p, ct.POINTER(ct.c_int)] -@beta def ESMP_GridCreateCubedSphere(tilesize, regDecompPTile=None, #decompFlagPTile=None, deLabelList=None, staggerLocList=None, name=None): From 7a789662033355c5beee653fa2cc284f9348ca9f Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Tue, 6 Sep 2022 17:28:45 -0700 Subject: [PATCH 26/45] use pytest markers throughout ESMPy for NetCDF, PIO and MPI support --- src/addon/ESMPy/examples/exampletest.py | 77 +++--- src/addon/ESMPy/examples/exampletestdryrun.py | 2 +- .../ESMPy/examples/grid_locstream_regrid.py | 6 +- .../ESMPy/examples/locstream_grid_regrid.py | 6 +- .../ESMPy/examples/mesh_locstream_regrid.py | 8 +- src/addon/ESMPy/pyproject.toml | 10 +- src/addon/ESMPy/src/esmpy/api/constants.py | 3 + src/addon/ESMPy/src/esmpy/api/field.py | 4 - src/addon/ESMPy/src/esmpy/api/regrid.py | 5 - .../ESMPy/src/esmpy/interface/cbindings.py | 6 +- .../ESMPy/src/esmpy/interface/loadESMF.py | 14 +- src/addon/ESMPy/src/esmpy/test/base.py | 32 +-- .../src/esmpy/test/test_api/test_field.py | 89 ++----- .../src/esmpy/test/test_api/test_grid.py | 38 ++- .../src/esmpy/test/test_api/test_locstream.py | 6 +- .../src/esmpy/test/test_api/test_mesh.py | 149 ++++-------- .../src/esmpy/test/test_api/test_regrid.py | 230 +++++------------- .../ESMPy/src/esmpy/test/test_api/test_vm.py | 4 +- .../ESMPy/src/esmpy/test/test_cbindings.py | 2 +- src/addon/ESMPy/src/esmpy/util/decorators.py | 32 ++- src/addon/ESMPy/src/esmpy/util/exceptions.py | 4 + 21 files changed, 270 insertions(+), 457 deletions(-) diff --git a/src/addon/ESMPy/examples/exampletest.py b/src/addon/ESMPy/examples/exampletest.py index e3325578ef..97e9607a13 100644 --- a/src/addon/ESMPy/examples/exampletest.py +++ b/src/addon/ESMPy/examples/exampletest.py @@ -6,11 +6,15 @@ import pytest -from esmpy.test.base import TestBase, attr, SkipTest +from esmpy.test.base import TestBase +from esmpy.api.constants import _ESMF_NETCDF, _ESMF_PIO import esmpy.api.constants as constants +from esmpy.api.esmpymanager import Manager class TestExamples(TestBase): + mg = Manager(debug=True) + # '0' in the name is so it is run first def test_0_examples_dryrun(self): from esmpy.util.cache_data import cache_data_files @@ -19,67 +23,54 @@ def test_0_examples_dryrun(self): def test_helloworld(self): from . import hello_world - # ESMF IO does not work in mpiuni mode + @pytest.mark.skipif(_ESMF_PIO==False, reason="PIO required in ESMF build") + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_field_read(self): - if constants._ESMF_COMM == constants._ESMF_COMM_MPIUNI: - raise SkipTest('ESMF must be built with MPI for test') - else: - from . import field_read + from . import field_read # only example, not in documentation + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_peridim_mask(self): - if constants._ESMF_COMM == constants._ESMF_COMM_MPIUNI: - raise SkipTest('ESMF must be built with MPI for test') - else: - from . import grid_create_peridim_mask + from . import grid_create_peridim_mask + @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_locstream_regrid(self): - if constants._ESMF_COMM == constants._ESMF_COMM_MPIUNI: - raise SkipTest('ESMF must be built with MPI for test') - else: - from . import grid_locstream_regrid + from . import grid_locstream_regrid + @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_locstream_grid_regrid(self): - if constants._ESMF_COMM == constants._ESMF_COMM_MPIUNI: - raise SkipTest('ESMF must be built with MPI for test') - else: - from . import locstream_grid_regrid + from . import locstream_grid_regrid + @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") def test_mesh_locstream_regrid(self): from . import mesh_locstream_regrid - # ESMF IO does not work in mpiuni mode + @pytest.mark.skipif(_ESMF_PIO==False, reason="PIO required in ESMF build") + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_read_write_weight_file(self): - if constants._ESMF_COMM == constants._ESMF_COMM_MPIUNI: - raise SkipTest('ESMF must be built with MPI for test') - else: - from . import read_write_weight_file + from . import read_write_weight_file - # ESMF IO does not work in mpiuni mode + @pytest.mark.skipif(_ESMF_PIO==False, reason="PIO required in ESMF build") + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_regrid_from_file(self): - if constants._ESMF_COMM == constants._ESMF_COMM_MPIUNI: - raise SkipTest('ESMF must be built with MPI for test') - else: - from . import regrid_from_file + from . import regrid_from_file + @pytest.mark.skipif(_ESMF_PIO==False, reason="PIO required in ESMF build") + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_ugrid_latlon_regrid(self): - if constants._ESMF_COMM == constants._ESMF_COMM_MPIUNI: - raise SkipTest('ESMF must be built with MPI for test') - else: - from . import ugrid_latlon_regrid + from . import ugrid_latlon_regrid + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_ungridded_dimension_regrid(self): - if constants._ESMF_COMM == constants._ESMF_COMM_MPIUNI: - raise SkipTest('ESMF must be built with MPI for test') - else: - from . import ungridded_dimension_regrid - - # # ESMF IO does not work in mpiuni mode - # def test_cubed_sphere_to_mesh_regrid(self): - # if constants._ESMF_COMM == constants._ESMF_COMM_MPIUNI: - # raise SkipTest('ESMF must be built with MPI for test') - # else: - # from . import cubed_sphere_to_mesh_regrid + from . import ungridded_dimension_regrid + + # this will currently never run because it isn't yet possible to run pytest with mpiexec + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") + @pytest.mark.skipif(mg.pet_count!=6, reason="test must be run with 6 cores") + def test_cubed_sphere_to_mesh_regrid(self): + from . import cubed_sphere_to_mesh_regrid # # datafile missing from repo # def test_tripole_regrid(self): diff --git a/src/addon/ESMPy/examples/exampletestdryrun.py b/src/addon/ESMPy/examples/exampletestdryrun.py index 7e8e5e304b..348f08431a 100644 --- a/src/addon/ESMPy/examples/exampletestdryrun.py +++ b/src/addon/ESMPy/examples/exampletestdryrun.py @@ -6,7 +6,7 @@ import pytest -from esmpy.test.base import TestBase, attr +from esmpy.test.base import TestBase class TestExamplesDryrun(TestBase): diff --git a/src/addon/ESMPy/examples/grid_locstream_regrid.py b/src/addon/ESMPy/examples/grid_locstream_regrid.py index 5c2b6e3720..a9d58b139f 100644 --- a/src/addon/ESMPy/examples/grid_locstream_regrid.py +++ b/src/addon/ESMPy/examples/grid_locstream_regrid.py @@ -14,7 +14,6 @@ import esmpy.util.helpers as helpers import esmpy.api.constants as constants -from esmpy.test.base import SkipTest # This call enables debug logging esmpy.Manager(debug=True) @@ -25,10 +24,7 @@ if esmpy.pet_count() == 1: locstream = create_locstream_spherical_16(coord_sys=coord_sys, domask=domask) else: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('processor count must be 4 or 1 for this example') - else: - locstream = create_locstream_spherical_16_parallel(coord_sys=coord_sys, domask=domask) + locstream = create_locstream_spherical_16_parallel(coord_sys=coord_sys, domask=domask) grid1 = "examples/data/ll1deg_grid.nc" grid = esmpy.Grid(filename=grid1, filetype=esmpy.FileFormat.SCRIP) diff --git a/src/addon/ESMPy/examples/locstream_grid_regrid.py b/src/addon/ESMPy/examples/locstream_grid_regrid.py index 159fcac2d4..7a53c1273f 100644 --- a/src/addon/ESMPy/examples/locstream_grid_regrid.py +++ b/src/addon/ESMPy/examples/locstream_grid_regrid.py @@ -14,7 +14,6 @@ import esmpy.util.helpers as helpers import esmpy.api.constants as constants -from esmpy.test.base import TestBase, attr, SkipTest # This call enables debug logging esmpy.Manager(debug=True) @@ -28,10 +27,7 @@ if esmpy.pet_count() == 1: locstream = create_locstream_spherical_16(coord_sys=coord_sys, domask=domask) else: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('processor count must be 4 or 1 for this example') - else: - locstream = create_locstream_spherical_16_parallel(coord_sys=coord_sys, domask=domask) + locstream = create_locstream_spherical_16_parallel(coord_sys=coord_sys, domask=domask) # create a field srcfield = esmpy.Field(locstream, name='srcfield') diff --git a/src/addon/ESMPy/examples/mesh_locstream_regrid.py b/src/addon/ESMPy/examples/mesh_locstream_regrid.py index e0841d06ca..69dfb6bc02 100644 --- a/src/addon/ESMPy/examples/mesh_locstream_regrid.py +++ b/src/addon/ESMPy/examples/mesh_locstream_regrid.py @@ -5,7 +5,6 @@ import esmpy.util.helpers as helpers import esmpy.api.constants as constants -from esmpy.test.base import TestBase, attr, SkipTest # This call enables debug logging # esmpy.Manager(debug=True) @@ -16,11 +15,8 @@ mesh, _, _, _, _, _ = mesh_create_5() locstream = create_locstream_16() else: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('processor count must be 4 or 1 for this example') - else: - mesh, _, _, _, _ = mesh_create_5_parallel() - locstream = create_locstream_16_parallel() + mesh, _, _, _, _ = mesh_create_5_parallel() + locstream = create_locstream_16_parallel() # create a field srcfield = esmpy.Field(mesh, name='srcfield')#, meshloc=esmpy.MeshLoc.ELEMENT) diff --git a/src/addon/ESMPy/pyproject.toml b/src/addon/ESMPy/pyproject.toml index 00e35c5c30..7478d31a21 100644 --- a/src/addon/ESMPy/pyproject.toml +++ b/src/addon/ESMPy/pyproject.toml @@ -25,14 +25,12 @@ starting_version = "8.4.0" # this is a backup for pip <= 22.0 where git-versioni [tool.dynamic] version = "placeholder" # this is a placeholder for the version pulled with git-versioning - [tool.setuptools.packages.find] where = ["src"] -exclude = ["doc*", "examples*", "test*"] +exclude = ["doc*"] [tool.pytest.ini_options] -markers = [ - "dryrun: marks a function that will only download test data files (deselect with '-m \"not parallel\"')", - "parallel: marks a test which requires mpi (deselect with '-m \"not parallel\"')", - "serial: marks a test which should be run on one core (deselect with '-m \"not serial\"')" +testpaths = [ + "src/esmpy/test/test_api", + "examples/exampletest.py", ] diff --git a/src/addon/ESMPy/src/esmpy/api/constants.py b/src/addon/ESMPy/src/esmpy/api/constants.py index 4094e2901e..52791233da 100644 --- a/src/addon/ESMPy/src/esmpy/api/constants.py +++ b/src/addon/ESMPy/src/esmpy/api/constants.py @@ -41,6 +41,9 @@ # ESMF_NETCDF _ESMF_NETCDF = False +# ESMF_NETCDF +_ESMF_PIO = False + # ESMF_COMM _ESMF_COMM = None _ESMF_COMM_MPIUNI = -1 diff --git a/src/addon/ESMPy/src/esmpy/api/field.py b/src/addon/ESMPy/src/esmpy/api/field.py index 9704a419ed..978251c104 100755 --- a/src/addon/ESMPy/src/esmpy/api/field.py +++ b/src/addon/ESMPy/src/esmpy/api/field.py @@ -385,10 +385,6 @@ def read(self, filename, variable, timeslice=None): :param int timeslice: The number of timeslices to read. """ - import esmpy.api.constants as constants - if constants._ESMF_COMM == constants._ESMF_COMM_MPIUNI: - raise ImportError("Field.Read() requires PIO and does not work if ESMF has not been built with MPI support") - assert (type(filename) is str) assert (type(variable) is str) diff --git a/src/addon/ESMPy/src/esmpy/api/regrid.py b/src/addon/ESMPy/src/esmpy/api/regrid.py index b63f6f59ca..d5d608425a 100644 --- a/src/addon/ESMPy/src/esmpy/api/regrid.py +++ b/src/addon/ESMPy/src/esmpy/api/regrid.py @@ -143,11 +143,6 @@ def __init__(self, srcfield=None, dstfield=None, filename=None, rh_filename=None # Write weights to file if requested. if not isinstance(filename, type(None)): - if constants._ESMF_COMM == constants._ESMF_COMM_MPIUNI: - msg = "Regrid(filename) requires PIO and does not work if ESMF has " \ - "not been built with MPI support" - raise ImportError(msg) - self._routehandle = ESMP_FieldRegridStoreFile( srcfield, dstfield, diff --git a/src/addon/ESMPy/src/esmpy/interface/cbindings.py b/src/addon/ESMPy/src/esmpy/interface/cbindings.py index b15f247102..b0499f19d0 100644 --- a/src/addon/ESMPy/src/esmpy/interface/cbindings.py +++ b/src/addon/ESMPy/src/esmpy/interface/cbindings.py @@ -9,7 +9,7 @@ import sys import esmpy.api.constants as constants -from esmpy.util.decorators import deprecated, netcdf, beta +from esmpy.util.decorators import * from esmpy.interface.loadESMF import _ESMF @@ -1209,6 +1209,7 @@ def ESMP_MeshCreate(parametricDim, spatialDim, coordSys=None): OptionalNamedConstant, Py3Char] +@pio @netcdf def ESMP_MeshCreateFromFile(filename, fileTypeFlag, convertToDual=None, addUserArea=None, @@ -1942,6 +1943,7 @@ def ESMP_FieldPrint(field): Py3Char, ct.c_uint, ct.c_uint] +@pio @netcdf def ESMP_FieldRead(field, filename, variablename, timeslice, iofmt=1): #TODO: C doc says it defaults to NETCDF(1), but actually defaults to BIN(0) @@ -2160,6 +2162,8 @@ def ESMP_FieldRegridStore(srcField, OptionalBool, OptionalField, OptionalField] +@pio +@netcdf def ESMP_FieldRegridStoreFile(srcField, dstField, filename, srcMaskValues=None, dstMaskValues=None, regridmethod=None, diff --git a/src/addon/ESMPy/src/esmpy/interface/loadESMF.py b/src/addon/ESMPy/src/esmpy/interface/loadESMF.py index 803134ccc4..bf791c0c4d 100644 --- a/src/addon/ESMPy/src/esmpy/interface/loadESMF.py +++ b/src/addon/ESMPy/src/esmpy/interface/loadESMF.py @@ -29,6 +29,7 @@ # TODO: look for various dependecies in the ESMF build log # - NetCDF +# - PIO # - LAPACK # - mpirun # use this information to set variables that can be checked at beginning @@ -42,7 +43,8 @@ esmfabi = None esmfcomm = None esmfversion = None - netcdf = [False, False] + netcdf = False + pio = False use_inmem_factors = False for line in MKFILE: @@ -53,9 +55,7 @@ elif 'ESMF_ABI:' in line: esmfabi = line.split(":")[1] elif 'ESMF_NETCDF:' in line: - netcdf[0] = True - elif 'ESMF_PIO:' in line: - netcdf[1] = True + netcdf = True elif 'ESMF_COMM:' in line: esmfcomm = line.split(":")[1] elif 'ESMF_VERSION_STRING=' in line: @@ -93,9 +93,13 @@ raise ValueError("Unrecognized ESMF_ABI setting!") # set _ESMF_NETCDF -if np.any(netcdf): +if netcdf: constants._ESMF_NETCDF = True +# set _ESMF_PIO +if "mpiuni" not in esmfcomm: + constants._ESMF_PIO = True + # set _ESMF_COMM if "mpiuni" in esmfcomm: constants._ESMF_COMM = constants._ESMF_COMM_MPIUNI diff --git a/src/addon/ESMPy/src/esmpy/test/base.py b/src/addon/ESMPy/src/esmpy/test/base.py index 2d655206dc..1bfcd785e7 100644 --- a/src/addon/ESMPy/src/esmpy/test/base.py +++ b/src/addon/ESMPy/src/esmpy/test/base.py @@ -1,15 +1,24 @@ import unittest import numpy as np -import esmpy from esmpy.util.itester import iter_product_keywords -from unittest import SkipTest - class TestBase(unittest.TestCase): + # mg = None + def __init__(self, *args, **kwds): super(TestBase, self).__init__(*args, **kwds) + # @classmethod + # def setUpClass(cls): + # import esmpy + # cls.mg = esmpy.Manager(debug = True) + # cls.mg.test_exhaustive = False + # + # @classmethod + # def tearDownClass(cls): + # del cls.mg + def assertNumpyAll(self, arr1, arr2, check_fill_value_dtype=True, check_arr_dtype=True): """ :type arr1: :class:`numpy.ndarray` @@ -97,20 +106,3 @@ def assertWeightFileIsRational(self, filename, src_size, dst_size): @staticmethod def iter_product_keywords(keywords, as_namedtuple=True): return iter_product_keywords(keywords, as_namedtuple=as_namedtuple) - - -def attr(*args, **kwargs): - """ - Decorator that adds attributes to classes or functions for use with the Attribute (-a) plugin. - - http://nose.readthedocs.org/en/latest/plugins/attrib.html - """ - - def wrap_ob(ob): - for name in args: - setattr(ob, name, True) - for name, value in kwargs.items(): - setattr(ob, name, value) - return ob - - return wrap_ob diff --git a/src/addon/ESMPy/src/esmpy/test/test_api/test_field.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_field.py index 8f46dd69de..c02e2012e2 100644 --- a/src/addon/ESMPy/src/esmpy/test/test_api/test_field.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_field.py @@ -6,7 +6,7 @@ from esmpy import * from esmpy.interface.cbindings import * -from esmpy.test.base import TestBase, attr, SkipTest +from esmpy.test.base import TestBase from esmpy.util.mesh_utilities import mesh_create_50, mesh_create_50_parallel @@ -72,7 +72,7 @@ def test_meta_del(self): del (self.field) assert (not hasattr(self, 'field')) - @pytest.mark.serial + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def test_numpy_funcs(self): field = self.make_field(np.array([10, 10], dtype=np.int32)) @@ -98,8 +98,8 @@ def test_numpy_funcs(self): - @pytest.mark.serial @pytest.mark.skipif(mg.test_exhaustive==False, reason="only run in exhaustive mode") + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def _field_create_2d_grid(self): keywords = dict( # periodic specifies all valid combos of [num_peri_dims, periodic_dim, pole_dim] @@ -148,8 +148,8 @@ def _field_create_2d_grid(self): raise ValueError( "The following combinations of parameters failed to create a proper Field: " + str(fail)) - @pytest.mark.serial @pytest.mark.skipif(mg.test_exhaustive==False, reason="only run in exhaustive mode") + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def _field_create_3d_grid(self): keywords = dict( # periodic specifies all valid combos of [num_peri_dims, periodic_dim, pole_dim] @@ -201,15 +201,8 @@ def _field_create_3d_grid(self): "The following combinations of parameters failed to create a proper Field: " + str(len(fail))) @pytest.mark.skipif(mg.test_exhaustive==False, reason="only run in exhaustive mode") + @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") def _field_create_2d_mesh(self): - parallel = False - if pet_count() > 1: - parallel = True - - if parallel: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('This test must be run with 4 processors.') - keywords = dict( meshloc=[MeshLoc.NODE, MeshLoc.ELEMENT], typekind_field=[None, TypeKind.I4, TypeKind.I8, TypeKind.R4, TypeKind.R8], @@ -223,7 +216,7 @@ def _field_create_2d_mesh(self): try: # create mesh mesh = None - if parallel: + if (pet_count == 4): mesh, nodeCoord, nodeOwner, elemType, elemConn, elemCoord = \ mesh_create_50_parallel() else: @@ -284,17 +277,10 @@ def create_field(gml, name): return field + @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") def test_field_uniqueness(self): - parallel = False - if pet_count() > 1: - parallel = True - - if parallel: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('This test must be run with 4 processors.') - mesh = None - if parallel: + if (pet_count() == 4): mesh, nodeCoord, nodeOwner, elemType, elemConn = \ mesh_create_50_parallel() else: @@ -315,7 +301,7 @@ def test_field_uniqueness(self): assert (field.struct.ptr != field2.struct.ptr) - @pytest.mark.serial + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def test_field_area(self): grid = Grid(np.array([3, 4]), staggerloc=[StaggerLoc.CENTER, StaggerLoc.CORNER], coord_sys=CoordSys.SPH_DEG, num_peri_dims=1, @@ -351,7 +337,7 @@ def test_field_area(self): assert(np.all(field.data == field2.data)) - + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def test_field_locstream_mask(self): # LocStream creation and simple validation locstream = LocStream(5, name="Test LocStream") @@ -404,18 +390,13 @@ def test_field_extradims_grid(self): field2.data[...] = 10 self.examine_field_attributes(field2) - + @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") def test_field_extradims_mesh(self): - parallel = False - if pet_count() > 1: - parallel = True - - if parallel: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('This test must be run with 4 processors.') - + + print("Pet count {}".format(pet_count())) + mesh = None - if parallel: + if (pet_count() == 4): mesh, nodeCoord, nodeOwner, elemType, elemConn = \ mesh_create_50_parallel() else: @@ -431,7 +412,7 @@ def test_field_extradims_mesh(self): field2.data[...] = 10 self.examine_field_attributes(field2) - @pytest.mark.serial + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def test_field_slice_grid(self): typekind = TypeKind.R8 grid = Grid(np.array([100, 100]), coord_sys=CoordSys.CART, @@ -471,18 +452,10 @@ def test_field_slice_grid(self): assert (field3.grid.upper_bounds[0].tolist() == [2, 2]) # slicing is disabled in parallel - @pytest.mark.serial + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def test_field_slice_mesh(self): - parallel = False - if pet_count() > 1: - parallel = True - - if parallel: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('This test must be run with 4 processors.') - mesh = None - if parallel: + if pet_count() > 1: mesh, nodeCoord, nodeOwner, elemType, elemConn = \ mesh_create_50_parallel() else: @@ -510,7 +483,7 @@ def test_field_slice_mesh(self): assert (field2.grid.size[0] == 5) assert (field3.grid.size[0] == 2) - @pytest.mark.serial + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def test_field_slice_grid_extraindices(self): n = 10 grid = Grid(np.array([n,n]), coord_sys=CoordSys.CART, staggerloc=StaggerLoc.CENTER) @@ -548,23 +521,9 @@ def test_field_slice_grid_extraindices(self): assert (field2.grid.upper_bounds[0].tolist() == [5, 5]) assert (field3.grid.upper_bounds[0].tolist() == [2, 2]) - @pytest.mark.serial + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def disable_est_field_slice_mesh_extraindices(self): - parallel = False - if pet_count() > 1: - parallel = True - - if parallel: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('This test must be run with 4 processors.') - - mesh = None - if parallel: - mesh, nodeCoord, nodeOwner, elemType, elemConn = \ - mesh_create_50_parallel() - else: - mesh, nodeCoord, nodeOwner, elemType, elemConn = \ - mesh_create_50() + mesh, nodeCoord, nodeOwner, elemType, elemConn, elemCoord = mesh_create_50() field = Field(mesh, typekind=TypeKind.R8, meshloc=MeshLoc.NODE, ndbounds=[5, 2]) @@ -572,9 +531,9 @@ def disable_est_field_slice_mesh_extraindices(self): for i in range(5): for j in range(2): - field[:, :, i, j] = i + j + field.data[:, i, j] = i + j - field2 = field[0:5, 0:2, 0:1] + field2 = field[0:4, 0:1, 0:1] self.examine_field_attributes(field2) field3 = field2[2:4, 1:2, 0:1] @@ -584,7 +543,7 @@ def disable_est_field_slice_mesh_extraindices(self): assert field2.data.shape == (5, 2, 1) assert field3.data.shape == (2, 1, 1) - @pytest.mark.serial + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def test_field_reshape(self): field = self.make_field(np.array([10, 10], dtype=np.int32), ndbounds=False) diff --git a/src/addon/ESMPy/src/esmpy/test/test_api/test_grid.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_grid.py index f8183b48ef..3186877b5a 100644 --- a/src/addon/ESMPy/src/esmpy/test/test_api/test_grid.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_grid.py @@ -6,7 +6,8 @@ import esmpy from esmpy import * from esmpy.interface.cbindings import * -from esmpy.test.base import TestBase, attr +from esmpy.test.base import TestBase +from esmpy.api.constants import _ESMF_NETCDF import numpy as np import os @@ -179,8 +180,8 @@ def test_grid_periodic(self): grid,_,_ = self.make_grid_periodic() self.examine_grid_attributes(grid) - @pytest.mark.serial @pytest.mark.skipif(mg.test_exhaustive==False, reason="only run in exhaustive mode") + @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") def test_grid_create_2d(self): keywords = dict( # periodic specifies all valid combos of [pole_kind, num_peri_dims, periodic_dim, pole_dim] @@ -225,8 +226,8 @@ def test_grid_create_2d(self): raise ValueError( "The following combinations of Grid parameters failed to create a proper Grid: " + str(fail)) - @pytest.mark.serial @pytest.mark.skipif(mg.test_exhaustive==False, reason="only run in exhaustive mode") + @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") def test_grid_create_3d(self): keywords = dict( # periodic specifies all valid combos of [num_peri_dims, periodic_dim, pole_dim] @@ -297,7 +298,7 @@ def test_grid_create_cubed_sphere(self): grid.destroy() # grid2.destroy() - @pytest.mark.serial + @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") def test_grid_slice_2d(self): grid = self.make_grid_2d() @@ -317,7 +318,7 @@ def test_grid_slice_2d(self): assert grid3.coords[StaggerLoc.CENTER][0].shape == (2, 1) assert grid3.upper_bounds[StaggerLoc.CENTER].tolist() == [2, 1] - @pytest.mark.serial + @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") def test_grid_slice_2d_corners(self): grid = self.make_grid_2d() @@ -348,7 +349,7 @@ def test_grid_slice_2d_corners(self): assert grid3.upper_bounds[StaggerLoc.CORNER].tolist() == [3, 2] - @pytest.mark.serial + @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") def test_grid_slice_3d(self): grid = self.make_grid_3d() @@ -368,7 +369,7 @@ def test_grid_slice_3d(self): assert grid3.coords[StaggerLoc.CENTER][0].shape == (2, 1, 2) assert grid3.upper_bounds[StaggerLoc.CENTER].tolist() == [2, 1, 2] - @pytest.mark.serial + @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") def test_grid_slice_3d_corners(self): grid = self.make_grid_3d() @@ -403,7 +404,7 @@ def test_grid_slice_3d_corners(self): assert grid3.coords[cvf][0].shape == (3, 2, 3) assert grid3.upper_bounds[cvf].tolist() == [3, 2, 3] - @pytest.mark.serial + @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") def test_grid_slice_periodic(self): grid, x, y = self.make_grid_periodic() @@ -429,7 +430,8 @@ def test_grid_slice_periodic(self): assert grid3.coords[StaggerLoc.CORNER][0].shape == (3, 2) assert grid3.upper_bounds[StaggerLoc.CORNER].tolist() == [3, 2] - @pytest.mark.serial + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") + @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") def test_slice_grid_created_from_file_scrip(self): reg_decomp = [pet_count(), 1] try: @@ -628,6 +630,7 @@ def test_grid_area_3D(self): area[:] = areavals assert(np.all(area[...] == 12*np.ones([10, 20, 30]))) + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_gridspec1D(self): esmfdir = os.path.dirname(inspect.getfile(esmpy)) grid = Grid(filename=os.path.join(esmfdir, "test/data/gridspec1Dcoords.nc"), @@ -636,6 +639,7 @@ def test_grid_create_from_file_gridspec1D(self): self.examine_grid_attributes(grid) + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip(self): reg_decomp = [pet_count(), 1] try: @@ -646,6 +650,7 @@ def test_grid_create_from_file_scrip(self): except: raise NameError('grid_create_from_file_scrip failed!') + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_balanced_balanced(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.BALANCED, DecompFlag.BALANCED], @@ -658,6 +663,7 @@ def test_grid_create_from_file_scrip_decomp_balanced_balanced(self): except: raise NameError('grid_create_from_file_scrip_balanced_balanced failed!') + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_balanced_restfirst(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.BALANCED, DecompFlag.RESTFIRST], @@ -670,6 +676,7 @@ def test_grid_create_from_file_scrip_decomp_balanced_restfirst(self): except: raise NameError('grid_create_from_file_scrip_balanced_restfirst failed!') + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_balanced_restlast(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.BALANCED, DecompFlag.RESTLAST], @@ -683,6 +690,7 @@ def test_grid_create_from_file_scrip_decomp_balanced_restlast(self): raise NameError('grid_create_from_file_scrip_balanced_restlast failed!') @pytest.mark.xfail + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_balanced_cyclic(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.BALANCED, DecompFlag.CYCLIC], @@ -695,6 +703,7 @@ def test_grid_create_from_file_scrip_decomp_balanced_cyclic(self): except: raise NameError('grid_create_from_file_scrip_balanced_cyclic failed!') + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_restfirst_balanced(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.RESTFIRST, DecompFlag.BALANCED], @@ -707,6 +716,7 @@ def test_grid_create_from_file_scrip_decomp_restfirst_balanced(self): except: raise NameError('grid_create_from_file_scrip_restfirst_balanced failed!') + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_restfirst_restfirst(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.RESTFIRST, DecompFlag.RESTFIRST], @@ -719,6 +729,7 @@ def test_grid_create_from_file_scrip_decomp_restfirst_restfirst(self): except: raise NameError('grid_create_from_file_scrip_restfirst_restfirst failed!') + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_restfirst_restlast(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.RESTFIRST, DecompFlag.RESTLAST], @@ -732,6 +743,7 @@ def test_grid_create_from_file_scrip_decomp_restfirst_restlast(self): raise NameError('grid_create_from_file_scrip_restfirst_restlast failed!') @pytest.mark.xfail + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_restfirst_cyclic(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.RESTFIRST, DecompFlag.CYCLIC], @@ -744,6 +756,7 @@ def test_grid_create_from_file_scrip_decomp_restfirst_cyclic(self): except: raise NameError('grid_create_from_file_scrip_restfirst_cyclic failed!') + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_restlast_balanced(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.RESTLAST, DecompFlag.BALANCED], @@ -756,6 +769,7 @@ def test_grid_create_from_file_scrip_decomp_restlast_balanced(self): except: raise NameError('grid_create_from_file_scrip_restlast_balanced failed!') + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_restlast_restfirst(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.RESTLAST, DecompFlag.RESTFIRST], @@ -768,6 +782,7 @@ def test_grid_create_from_file_scrip_decomp_restlast_restfirst(self): except: raise NameError('grid_create_from_file_scrip_restlast_restfirst failed!') + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_restlast_restlast(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.RESTLAST, DecompFlag.RESTLAST], @@ -781,6 +796,7 @@ def test_grid_create_from_file_scrip_decomp_restlast_restlast(self): raise NameError('grid_create_from_file_scrip_restlast_restlast failed!') @pytest.mark.xfail + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_restlast_cyclic(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.RESTLAST, DecompFlag.CYCLIC], @@ -794,6 +810,7 @@ def test_grid_create_from_file_scrip_decomp_restlast_cyclic(self): raise NameError('grid_create_from_file_scrip_restlast_cyclic failed!') @pytest.mark.xfail + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_cyclic_balanced(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.CYCLIC, DecompFlag.BALANCED], @@ -807,6 +824,7 @@ def test_grid_create_from_file_scrip_decomp_cyclic_balanced(self): raise NameError('grid_create_from_file_scrip_cyclic_balanced failed!') @pytest.mark.xfail + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_cyclic_restfirst(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.CYCLIC, DecompFlag.RESTFIRST], @@ -820,6 +838,7 @@ def test_grid_create_from_file_scrip_decomp_cyclic_restfirst(self): raise NameError('grid_create_from_file_scrip_cyclic_restfirst failed!') @pytest.mark.xfail + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_cyclic_restlast(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.CYCLIC, DecompFlag.RESTLAST], @@ -833,6 +852,7 @@ def test_grid_create_from_file_scrip_decomp_cyclic_restlast(self): raise NameError('grid_create_from_file_scrip_cyclic_restlast failed!') @pytest.mark.xfail + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_cyclic_cyclic(self): reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.CYCLIC, DecompFlag.CYCLIC], diff --git a/src/addon/ESMPy/src/esmpy/test/test_api/test_locstream.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_locstream.py index c1b1dbf508..b455acbc04 100644 --- a/src/addon/ESMPy/src/esmpy/test/test_api/test_locstream.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_locstream.py @@ -5,12 +5,14 @@ from esmpy import * from esmpy.interface.cbindings import * -from esmpy.test.base import TestBase, attr +from esmpy.test.base import TestBase import pytest class TestLocStream(TestBase): + mg = Manager(debug=True) + def test_create(self): # LocStream creation and simple validation locstream = LocStream(5, name="Test LocStream") @@ -52,7 +54,7 @@ def test_copy(self): assert np.all(l2["ESMF:X"] == [0, 1, 2, 3, 4]) - @pytest.mark.serial + @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") def test_slice(self): locstream = LocStream(5, name="Test LocStream") diff --git a/src/addon/ESMPy/src/esmpy/test/test_api/test_mesh.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_mesh.py index 7ca0a9c9aa..8d97691b76 100644 --- a/src/addon/ESMPy/src/esmpy/test/test_api/test_mesh.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_mesh.py @@ -10,7 +10,8 @@ import esmpy from esmpy import * -from esmpy.test.base import TestBase, attr, SkipTest +from esmpy.test.base import TestBase +from esmpy.api.constants import _ESMF_NETCDF, _ESMF_PIO from esmpy.util.mesh_utilities import * class TestMesh(TestBase): @@ -47,17 +48,11 @@ def check_mesh(self, mesh, nodeCoord, nodeOwner, elemCoord=None): # this call fails if nodes and elements have not been added first # mesh.free_memory() + @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") def test_mesh_5(self): elemCoord = None parallel = False - if pet_count() > 1: - parallel = True - - if parallel: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('This test must be run with 4 processors.') - - if parallel: + if pet_count() == 4: mesh, nodeCoord, nodeOwner, elemType, elemConn = \ mesh_create_5_parallel() else: @@ -66,17 +61,11 @@ def test_mesh_5(self): self.check_mesh(mesh, nodeCoord, nodeOwner, elemCoord=elemCoord) + @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") def test_mesh_10(self): elemCoord = None parallel = False - if pet_count() > 1: - parallel = True - - if parallel: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('This test must be run with 4 processors.') - - if parallel: + if pet_count() == 4: mesh, nodeCoord, nodeOwner, elemType, elemConn = \ mesh_create_10_parallel() else: @@ -85,17 +74,11 @@ def test_mesh_10(self): self.check_mesh(mesh, nodeCoord, nodeOwner, elemCoord=elemCoord) + @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") def test_mesh_50(self): elemCoord = None parallel = False - if pet_count() > 1: - parallel = True - - if parallel: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('This test must be run with 4 processors.') - - if parallel: + if pet_count() == 4: mesh, nodeCoord, nodeOwner, elemType, elemConn = \ mesh_create_50_parallel() else: @@ -104,22 +87,16 @@ def test_mesh_50(self): self.check_mesh(mesh, nodeCoord, nodeOwner, elemCoord=elemCoord) + @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") def test_mesh_50_moab(self): - # set this mesh to be created with the MOAB backend mg = Manager() mg.set_moab() elemCoord = None parallel = False - if pet_count() > 1: - parallel = True - - if parallel: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('This test must be run with 4 processors.') - if parallel: + if pet_count() == 4: mesh, nodeCoord, nodeOwner, elemType, elemConn = \ mesh_create_50_parallel() else: @@ -135,16 +112,10 @@ def test_mesh_50_moab(self): assert (mg.moab == False) + @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") def test_mesh_50_ngons(self): parallel = False - if pet_count() > 1: - parallel = True - - if parallel: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('This test must be run with 4 processors.') - - if parallel: + if pet_count() == 4: mesh, nodeCoord, nodeOwner, elemType, elemConn = \ mesh_create_50_ngons_parallel() else: @@ -153,17 +124,11 @@ def test_mesh_50_ngons(self): self.check_mesh(mesh, nodeCoord, nodeOwner) + @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") def test_mesh_50_mask_area(self): elemCoord = None parallel = False - if pet_count() > 1: - parallel = True - - if parallel: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('This test must be run with 4 processors.') - - if parallel: + if pet_count() == 4: mesh, nodeCoord, nodeOwner, elemType, elemConn, elemMask, elemArea = \ mesh_create_50_parallel(domask=True, doarea=True) else: @@ -176,32 +141,23 @@ def test_mesh_50_mask_area(self): self.assertNumpyAll(mesh.area, elemArea) + @pytest.mark.skipif(_ESMF_PIO==False, reason="PIO required in ESMF build") + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_mesh_create_from_file_scrip(self): - try: - esmfdir = os.path.dirname(inspect.getfile(esmpy)) - mesh_from_file = Mesh(filename=os.path.join(esmfdir, "test/data/ne4np4-pentagons.nc"), + esmfdir = os.path.dirname(inspect.getfile(esmpy)) + mesh_from_file = Mesh(filename=os.path.join(esmfdir, "test/data/ne4np4-pentagons.nc"), filetype=FileFormat.SCRIP) - except: - raise NameError('mesh_create_from_file_scrip failed!') + @pytest.mark.skipif(_ESMF_PIO==False, reason="PIO required in ESMF build") + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_mesh_create_from_file_esmfmesh(self): - try: - esmfdir = os.path.dirname(inspect.getfile(esmpy)) - mesh_from_file = Mesh(filename=os.path.join(esmfdir, "test/data/ne4np4-esmf.nc"), + esmfdir = os.path.dirname(inspect.getfile(esmpy)) + mesh_from_file = Mesh(filename=os.path.join(esmfdir, "test/data/ne4np4-esmf.nc"), filetype=FileFormat.ESMFMESH) - except: - raise NameError('mesh_create_from_file_scrip failed!') + @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") def test_mesh_copy(self): - parallel = False - if pet_count() > 1: - parallel = True - - if parallel: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('This test must be run with 4 processors.') - - if parallel: + if pet_count() == 4: mesh, nodeCoord, nodeOwner, elemType, elemConn = \ mesh_create_50_ngons_parallel() else: @@ -214,21 +170,9 @@ def test_mesh_copy(self): self.check_mesh(mesh2, nodeCoord, nodeOwner) # slicing is disabled in parallel - @pytest.mark.serial + @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") def test_mesh_slicing(self): - parallel = False - if pet_count() > 1: - parallel = True - - if parallel: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('This test must be run with 4 processors.') - - if parallel: - mesh, nodeCoord, nodeOwner, elemType, elemConn = \ - mesh_create_5_pentahexa_parallel() - else: - mesh, nodeCoord, nodeOwner, elemType, elemConn = \ + mesh, nodeCoord, nodeOwner, elemType, elemConn = \ mesh_create_5_pentahexa() mesh2 = mesh[0:5] @@ -250,15 +194,14 @@ def test_mesh_slicing(self): assert mesh3.size == [2, None] assert mesh3.size_owned == [2, None] - @pytest.mark.serial + @pytest.mark.skipif(_ESMF_PIO==False, reason="PIO required in ESMF build") + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") + @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") def test_slice_mesh_created_from_file_scrip(self): - try: - esmfdir = os.path.dirname(inspect.getfile(esmpy)) - mesh = Mesh(filename=os.path.join(esmfdir, "test/data/ne4np4-pentagons.nc"), - filetype=FileFormat.SCRIP, - convert_to_dual=True) - except: - raise NameError('mesh_create_from_file_scrip failed!') + esmfdir = os.path.dirname(inspect.getfile(esmpy)) + mesh = Mesh(filename=os.path.join(esmfdir, "test/data/ne4np4-pentagons.nc"), + filetype=FileFormat.SCRIP, + convert_to_dual=True) mesh2 = mesh[0:5] @@ -273,14 +216,13 @@ def test_slice_mesh_created_from_file_scrip(self): assert mesh2.size == [5, None] assert mesh2.size_owned == [5, None] - @pytest.mark.serial + @pytest.mark.skipif(_ESMF_PIO==False, reason="PIO required in ESMF build") + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") + @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") def test_slice_mesh_created_from_file_esmfmesh(self): - try: - esmfdir = os.path.dirname(inspect.getfile(esmpy)) - mesh = Mesh(filename=os.path.join(esmfdir, "test/data/ne4np4-esmf.nc"), - filetype=FileFormat.ESMFMESH) - except: - raise NameError('mesh_create_from_file_esmfmesh failed!') + esmfdir = os.path.dirname(inspect.getfile(esmpy)) + mesh = Mesh(filename=os.path.join(esmfdir, "test/data/ne4np4-esmf.nc"), + filetype=FileFormat.ESMFMESH) mesh2 = mesh[0:5] @@ -295,17 +237,16 @@ def test_slice_mesh_created_from_file_esmfmesh(self): assert mesh2.size_owned == [5, None] - @pytest.mark.serial @pytest.mark.xfail + @pytest.mark.skipif(_ESMF_PIO==False, reason="PIO required in ESMF build") + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") + @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") #TODO: remove expected failure once we have a smaller data file with mesh element coordinates to use # TODO: have to define slicing for mesh element coordinates as well.. def test_slice_mesh_created_from_file_elem_coords(self): - try: - esmfdir = os.path.dirname(inspect.getfile(esmpy)) - mesh = Mesh(filename=os.path.join(esmfdir, "test/data/ne30np4-t2.nc"), - filetype=FileFormat.SCRIP) - except: - raise NameError('mesh_create_from_file_elem_coords failed!') + esmfdir = os.path.dirname(inspect.getfile(esmpy)) + mesh = Mesh(filename=os.path.join(esmfdir, "test/data/ne30np4-t2.nc"), + filetype=FileFormat.SCRIP) mesh2 = mesh[0:5] diff --git a/src/addon/ESMPy/src/esmpy/test/test_api/test_regrid.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_regrid.py index d25f712cc4..3a6e1ffefe 100644 --- a/src/addon/ESMPy/src/esmpy/test/test_api/test_regrid.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_regrid.py @@ -7,7 +7,8 @@ import os from esmpy import * -from esmpy.test.base import TestBase, attr, SkipTest +from esmpy.test.base import TestBase +from esmpy.api.constants import _ESMF_NETCDF, _ESMF_PIO from esmpy.util.field_utilities import compare_fields from esmpy.util.grid_utilities import * from esmpy.util.mesh_utilities import * @@ -15,6 +16,9 @@ class TestRegrid(TestBase): + mg = Manager(debug=True) + mg.test_exhaustive = False + def run_regridding(srcfield, dstfield, srcfracfield, dstfracfield): # This is for documentation. Do not modify. ''' @@ -81,7 +85,8 @@ def test_field_regrid(self): line_type=LineType.CART, factors=False) _ = rh(srcfield, dstfield) - @pytest.mark.serial + @pytest.mark.skipif(constants._ESMF_USE_INMEM_FACTORS, reason="compiler does not support in-memory weights") + @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") def test_field_regrid_factor_retrieval(self): # Test retrieving factors from a route handle. @@ -132,17 +137,11 @@ def test_field_regrid_factor_retrieval(self): keywords = dict(deep_copy=[False, True], as_dict=[False, True]) for k in self.iter_product_keywords(keywords): - try: - rh = Regrid(srcfield, dstfield, - regrid_method=RegridMethod.BILINEAR, - line_type=LineType.CART, factors=True, - create_rh=False, - unmapped_action=UnmappedAction.IGNORE) - except RuntimeError: - if constants._ESMF_USE_INMEM_FACTORS: - raise - else: - raise SkipTest("compiler does not support in-memory weights") + rh = Regrid(srcfield, dstfield, + regrid_method=RegridMethod.BILINEAR, + line_type=LineType.CART, factors=True, + create_rh=False, + unmapped_action=UnmappedAction.IGNORE) _ = rh(srcfield, dstfield) fl, fil, fdict = [None] * 3 # Reset at each loop @@ -184,7 +183,8 @@ def test_field_regrid_factor_retrieval(self): rh.destroy() - @pytest.mark.parallel + @pytest.mark.skipif(_ESMF_PIO==False, reason="PIO required in ESMF build") + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_field_regrid_file1(self): mgr = Manager() @@ -238,7 +238,8 @@ def test_field_regrid_file1(self): if os.path.isfile(path): os.remove(path) - @pytest.mark.parallel + @pytest.mark.skipif(_ESMF_PIO==False, reason="PIO required in ESMF build") + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_field_regrid_file2(self): mgr = Manager() filename = 'esmpy_test_field_regrid_file2.nc' @@ -309,9 +310,10 @@ def test_field_regrid_file2(self): if os.path.isfile(path): os.remove(path) - @pytest.mark.parallel + @pytest.mark.skipif(_ESMF_PIO==False, reason="PIO required in ESMF build") + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") # remove this test for 8.2.0 due to unexplained segv - def tet_field_regrid_file_withaux(self): + def test_field_regrid_file_withaux(self): import os DD = os.path.join(os.getcwd(), "test/data") if not os.path.isdir(DD): @@ -374,7 +376,8 @@ def tet_field_regrid_file_withaux(self): if os.path.isfile(path): os.remove(path) - @pytest.mark.parallel + @pytest.mark.skipif(_ESMF_PIO==False, reason="PIO required in ESMF build") + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_field_regrid_file3(self): mgr = Manager() filename = 'esmpy_test_field_from_file.nc' @@ -468,8 +471,6 @@ def test_field_regrid_file3(self): if os.path.isfile(path): os.remove(path) - - @pytest.mark.parallel def test_field_regrid_file4(self): mgr = Manager() filename = 'routehandlefile.nc' @@ -564,17 +565,10 @@ def test_field_regrid_file4(self): if os.path.isfile(path): os.remove(path) + @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") def test_field_regrid_gridmesh(self): - parallel = False - if pet_count() > 1: - parallel = True - - if parallel: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('This test must be run with 4 processors.') - mesh = None - if parallel: + if pet_count() == 4: mesh, nodeCoord, nodeOwner, elemType, elemConn = \ mesh_create_50_parallel() else: @@ -608,18 +602,10 @@ def test_field_regrid_gridmesh(self): rh = Regrid(srcfield, dstfield, regrid_method=RegridMethod.CONSERVE) dstfield = rh(srcfield, dstfield) - @pytest.mark.parallel + @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") def test_field_regrid_zeroregion(self): - parallel = False - if pet_count() > 1: - parallel = True - - if parallel: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('This test must be run with 4 processors.') - mesh = None - if parallel: + if pet_count() == 4: mesh, nodeCoord, nodeOwner, elemType, elemConn = \ mesh_create_50_parallel() else: @@ -655,7 +641,8 @@ def test_field_regrid_zeroregion(self): if dstfield.grid.mask[StaggerLoc.CENTER][i, j] == 0: assert(dstfield[i, j] == 0) - @pytest.mark.parallel + @pytest.mark.skipif(_ESMF_PIO==False, reason="PIO required in ESMF build") + @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_field_regrid_zeroregion_select_ndbounds(self): # Test zero region select during a sparse matrix multiplication # having undistributed dimensions. @@ -707,18 +694,10 @@ def test_field_regrid_zeroregion_select_ndbounds(self): if os.path.exists(filename): os.remove(filename) - @pytest.mark.parallel + @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") def test_field_regrid_area(self): - parallel = False - if pet_count() > 1: - parallel = True - - if parallel: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('This test must be run with 4 processors.') - mesh = None - if parallel: + if pet_count() == 4: mesh, nodeCoord, nodeOwner, elemType, elemConn = \ mesh_create_50_parallel() else: @@ -749,16 +728,7 @@ def test_field_regrid_area(self): if (dstarea.data[i] != 0.25): assert (dstarea.data[i] == 0.125) - @pytest.mark.parallel def test_field_regrid_periodic(self): - parallel = False - if pet_count() > 1: - parallel = True - - if parallel: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('This test must be run with 4 processors.') - # create a grid srcgrid = grid_create_from_bounds_periodic(60, 30, corners=True, domask=True) dstgrid = grid_create_from_bounds_periodic(55, 28, corners=True) @@ -799,7 +769,6 @@ def test_field_regrid_periodic(self): self.assertAlmostEqual(meanrel, 0.0016447124122954575) self.assertAlmostEqual(csrvrel, 0.0) - @pytest.mark.parallel def test_grid_grid_3d_bilinear_cartesian(self): # RO: This test creates the same Grid on every processor, it could be improved @@ -829,7 +798,6 @@ def test_grid_grid_3d_bilinear_cartesian(self): self.assertAlmostEqual(meanrel, 0.00215601743167) self.assertAlmostEqual(csrvrel, 0.0) - @pytest.mark.parallel def test_grid_grid_3d_bilinear_spherical(self): # RO: This test creates the same Grid on every processor, it could be improved @@ -859,7 +827,6 @@ def test_grid_grid_3d_bilinear_spherical(self): self.assertAlmostEqual(meanrel, 0.00061587737764545617) self.assertAlmostEqual(csrvrel, 0.0) - @pytest.mark.parallel def test_grid_grid_regrid_csrv_mask_3D(self): # RO: This test creates the same Grid on every processor, it could be improved @@ -900,7 +867,6 @@ def test_grid_grid_regrid_csrv_mask_3D(self): self.assertAlmostEqual(meanrel, 0.0021560174316746865) self.assertAlmostEqual(csrvrel, 0.0) - @pytest.mark.parallel def test_grid_grid_regrid_csrv_mask(self): # RO: This test creates the same Grid on every processor, it could be improved @@ -942,7 +908,6 @@ def test_grid_grid_regrid_csrv_mask(self): self.assertAlmostEqual(meanrel, 0.0024803189848013785) self.assertAlmostEqual(csrvrel, 0.0) - @pytest.mark.parallel def test_grid_grid_regrid_csrv_2nd_mask(self): # RO: This test creates the same Grid on every processor, it could be improved @@ -984,7 +949,6 @@ def test_grid_grid_regrid_csrv_2nd_mask(self): self.assertAlmostEqual(meanrel, 0.0020296891000258252) self.assertAlmostEqual(csrvrel, 0.0) - @pytest.mark.parallel def test_grid_grid_regrid_srcmask_types(self): # NOTE: this tests an old issue where the items of a grid were not properly set when # the grid coord_typekind differed from the field typekind. @@ -1030,18 +994,10 @@ def test_grid_grid_regrid_srcmask_types(self): self.assertAlmostEqual(meanrel, 0.0024803189848013785) self.assertAlmostEqual(csrvrel, 0.0) - @pytest.mark.parallel + @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") def test_grid_mesh_regrid_csrv_mask(self): - parallel = False - if pet_count() > 1: - parallel = True - - if parallel: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('This test must be run with 4 processors.') - - # create a Mesh - if parallel: + mesh = None + if pet_count() == 4: mesh, nodeCoord, nodeOwner, elemType, elemConn, elemMask, elemArea = \ mesh_create_50_parallel(domask=True, doarea=True) else: @@ -1088,18 +1044,10 @@ def test_grid_mesh_regrid_csrv_mask(self): self.assertAlmostEqual(meanrel, 0.038806630051265847) self.assertAlmostEqual(csrvrel, 0.0) - @pytest.mark.parallel + @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") def test_grid_mesh_regrid_csrv(self): - parallel = False - if pet_count() > 1: - parallel = True - - if parallel: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('This test must be run with 4 processors.') - - # create a Mesh - if parallel: + mesh = None + if pet_count() == 4: mesh, nodeCoord, nodeOwner, elemType, elemConn = \ mesh_create_50_parallel() else: @@ -1144,21 +1092,13 @@ def test_grid_mesh_regrid_csrv(self): self.assertAlmostEqual(meanrel, 0.037733241800767432) self.assertAlmostEqual(csrvrel, 0.0) - @pytest.mark.parallel + @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") def test_grid_mesh_regrid_mask(self): - parallel = False - if pet_count() > 1: - parallel = True - - if parallel: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('This test must be run with 4 processors.') - - # create a grid + # create a grid grid = grid_create_from_bounds([0, 4], [0, 4], 8, 8, corners=True, domask=True) - # create a Mesh - if parallel: + mesh = None + if pet_count() == 4: mesh, nodeCoord, nodeOwner, elemType, elemConn = \ mesh_create_50_parallel() else: @@ -1189,21 +1129,13 @@ def test_grid_mesh_regrid_mask(self): self.assertAlmostEqual(meanrel, 0.0) self.assertAlmostEqual(csrvrel, 0.0) - @pytest.mark.parallel + @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") def test_grid_mesh_regrid(self): - parallel = False - if pet_count() > 1: - parallel = True - - if parallel: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('This test must be run with 4 processors.') - - # create a grid + # create a grid grid = grid_create_from_bounds([0, 4], [0, 4], 8, 8, corners=True) - # create a Mesh - if parallel: + mesh = None + if pet_count() == 4: mesh, nodeCoord, nodeOwner, elemType, elemConn = \ mesh_create_50_parallel() else: @@ -1233,21 +1165,13 @@ def test_grid_mesh_regrid(self): self.assertAlmostEqual(meanrel, 0.0) self.assertAlmostEqual(csrvrel, 0.0) - @pytest.mark.parallel + @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") def test_field_regrid_extrapolation(self): - parallel = False - if pet_count() > 1: - parallel = True - - if parallel: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('This test must be run with 4 processors.') - # create a grid grid = grid_create_from_bounds([0, 4], [0, 4], 8, 8, corners=True) - # create a Mesh - if parallel: + mesh = None + if pet_count() == 4: mesh, nodeCoord, nodeOwner, elemType, elemConn = \ mesh_create_50_parallel() else: @@ -1280,21 +1204,13 @@ def test_field_regrid_extrapolation(self): self.assertAlmostEqual(meanrel, 0.0) self.assertAlmostEqual(csrvrel, 0.0) - @pytest.mark.parallel + @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") def test_field_regrid_extrapolation_creepfill(self): - parallel = False - if pet_count() > 1: - parallel = True - - if parallel: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('This test must be run with 4 processors.') - # create a grid grid = grid_create_from_bounds([0, 4], [0, 4], 8, 8, corners=True) - # create a Mesh - if parallel: + mesh = None + if pet_count == 4: mesh, nodeCoord, nodeOwner, elemType, elemConn = \ mesh_create_50_parallel() else: @@ -1325,18 +1241,11 @@ def test_field_regrid_extrapolation_creepfill(self): self.assertAlmostEqual(meanrel, 0.0) self.assertAlmostEqual(csrvrel, 0.0) - @pytest.mark.parallel + @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") def test_mesh_mesh_regrid(self): - parallel = False - if pet_count() > 1: - parallel = True - - if parallel: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('This test must be run with 4 processors.') - - # create two unique Mesh objects - if parallel: + srcmesh = None + dstmesh = None + if pet_count() == 4: srcmesh, nodeCoordSrc, nodeOwnerSrc, elemTypeSrc, elemConnSrc = \ mesh_create_50_parallel() dstmesh, nodeCoordDst, nodeOwnerDst, elemTypeDst, elemConnDst = \ @@ -1385,18 +1294,10 @@ def test_mesh_mesh_regrid(self): self.assertAlmostEqual(meanrel, 0.037109375) self.assertAlmostEqual(csrvrel, 0.0) - @pytest.mark.parallel + @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") def est_grid_mesh_pentatri_regrid_csrv(self): - parallel = False - if pet_count() > 1: - parallel = True - - if parallel: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('This test must be run with 4 processors.') - - # create a Mesh - if parallel: + mesh = None + if pet_count() == 4: mesh, nodeCoord, nodeOwner, elemType, elemConn = \ mesh_create_50_ngons_parallel() else: @@ -1444,11 +1345,8 @@ def est_grid_mesh_pentatri_regrid_csrv(self): assert (meanrel < 10E-2) assert (csrvrel < 10E-14) - # TODO: this test is disable, I don't remember why + @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") def est_grid_mesh_pentatri_regrid_csrv_simple(self): - if esmpy.pet_count() > 1: - raise NameError('This test can only be run in serial!') - # create a Mesh mesh, nodeCoord, nodeOwner, elemType, elemConn = \ mesh_create_4_ngons() @@ -1494,18 +1392,10 @@ def est_grid_mesh_pentatri_regrid_csrv_simple(self): assert (meanrel < 10E-2) assert (csrvrel < 10E-14) - @pytest.mark.parallel + @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") def test_grid_mesh_pentatri_regrid_bilinear(self): - parallel = False - if pet_count() > 1: - parallel = True - - if parallel: - if constants._ESMF_MPIRUN_NP != 4: - raise SkipTest('This test must be run with 4 processors.') - - # create a Mesh - if parallel: + mesh = None + if pet_count() == 4: mesh, nodeCoord, nodeOwner, elemType, elemConn = \ mesh_create_50_ngons_parallel() else: diff --git a/src/addon/ESMPy/src/esmpy/test/test_api/test_vm.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_vm.py index 4f3a544a18..3be54d4fd5 100644 --- a/src/addon/ESMPy/src/esmpy/test/test_api/test_vm.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_vm.py @@ -4,12 +4,11 @@ from esmpy import * from esmpy.interface.cbindings import * -from esmpy.test.base import TestBase, attr +from esmpy.test.base import TestBase import pytest class TestVM(TestBase): - @pytest.mark.parallel def test_vm_broadcast(self): mg = Manager() @@ -29,7 +28,6 @@ def test_vm_broadcast(self): mg.barrier() - @pytest.mark.parallel def test_vm_reduce(self): send = np.ones(4, dtype=np.float64) recv = np.zeros(4, dtype=np.float64) diff --git a/src/addon/ESMPy/src/esmpy/test/test_cbindings.py b/src/addon/ESMPy/src/esmpy/test/test_cbindings.py index 30185967c2..deb06fce9a 100644 --- a/src/addon/ESMPy/src/esmpy/test/test_cbindings.py +++ b/src/addon/ESMPy/src/esmpy/test/test_cbindings.py @@ -8,7 +8,7 @@ from esmpy import * from esmpy.interface.cbindings import * -from esmpy.test.base import TestBase, attr +from esmpy.test.base import TestBase import numpy as np diff --git a/src/addon/ESMPy/src/esmpy/util/decorators.py b/src/addon/ESMPy/src/esmpy/util/decorators.py index c6ceea769c..38eb52631d 100644 --- a/src/addon/ESMPy/src/esmpy/util/decorators.py +++ b/src/addon/ESMPy/src/esmpy/util/decorators.py @@ -9,8 +9,8 @@ import warnings import functools -from esmpy.api.constants import LogKind, _ESMF_NETCDF -from esmpy.util.exceptions import NetCDFMissing +from esmpy.api.constants import LogKind, _ESMF_NETCDF, _ESMF_PIO +from esmpy.util.exceptions import NetCDFMissing, PIOMissing def beta(func): '''This is a decorator that can be used to mark functions @@ -73,3 +73,31 @@ def new_func(*args, **kwargs): raise NetCDFMissing("This function requires ESMF to have been built with NetCDF.") return new_func + +def pio(func): + '''This is a decorator that can be used to error out of functions + if PIO is not available. (e.g. if ESMF was built using ESMF_COMM=mpiuni).''' + + @functools.wraps(func) + def new_func(*args, **kwargs): + from esmpy.api.constants import _ESMF_PIO + + if _ESMF_PIO: + return func(*args, **kwargs) + else: + raise PIOMissing("This function requires ESMF to have been built with PIO.") + + return new_func + +def PETx4(func): + '''This is a decorator that can be used to error out of functions + if execution does not have 4 cores available.''' + + @functools.wraps(func) + def new_func(*args, **kwargs): + if esmpy.pet_count() == 4: + return func(*args, **kwargs) + else: + raise PETx4NotSatisfied("This function requires 4 core execution.") + + return new_func diff --git a/src/addon/ESMPy/src/esmpy/util/exceptions.py b/src/addon/ESMPy/src/esmpy/util/exceptions.py index 3924539904..206eaae900 100644 --- a/src/addon/ESMPy/src/esmpy/util/exceptions.py +++ b/src/addon/ESMPy/src/esmpy/util/exceptions.py @@ -18,6 +18,10 @@ class NetCDFMissing(ESMPyException): """ESMF was not built with the NetCDF package.""" pass +class PIOMissing(ESMPyException): + """ESMF was not built with PIO support.""" + pass + class MethodNotImplemented(ESMPyException): """Raised when an unimplemented method is called.""" pass From a185290d11bd799c92a62c1d9eb3da3a6015f601 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Wed, 7 Sep 2022 10:15:48 -0700 Subject: [PATCH 27/45] add pytest-json-report, cleap up pytest markers for netcdf and pio dependencies --- src/addon/ESMPy/Makefile | 2 + src/addon/ESMPy/pyproject.toml | 4 +- .../regrid_from_file/run_regrid_from_file.py | 27 +++++----- .../run_regrid_from_file_dryrun.py | 6 +-- .../src/esmpy/test/test_api/test_array.py | 5 +- .../src/esmpy/test/test_api/test_field.py | 30 +++++------- .../src/esmpy/test/test_api/test_grid.py | 49 +++++++++++++------ .../src/esmpy/test/test_api/test_locstream.py | 5 +- .../src/esmpy/test/test_api/test_mesh.py | 1 - .../src/esmpy/test/test_api/test_regrid.py | 2 +- .../ESMPy/src/esmpy/test/test_api/test_vm.py | 5 +- 11 files changed, 74 insertions(+), 62 deletions(-) diff --git a/src/addon/ESMPy/Makefile b/src/addon/ESMPy/Makefile index 7eec02c873..e5d25fe110 100644 --- a/src/addon/ESMPy/Makefile +++ b/src/addon/ESMPy/Makefile @@ -10,6 +10,8 @@ clean: find . -name "*.vtk" -exec rm -f {} \; || : find . -name "*.pytest_cache" -exec rm -rf {} \; || : find . -name "*.python-version" -exec rm -f {} \; || : + find . -name "*__pycache__" -exec rm -rf {} \; || : + find . -name ".report.json" -exec rm -rf {} \; || : rm -rf src/esmpy/test/regrid_from_file/data || : rm -rf examples/data || : diff --git a/src/addon/ESMPy/pyproject.toml b/src/addon/ESMPy/pyproject.toml index 7478d31a21..35590d6390 100644 --- a/src/addon/ESMPy/pyproject.toml +++ b/src/addon/ESMPy/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = [ "setuptools>=41", "wheel", "setuptools-git-versioning", ] +requires = [ "setuptools>=41", "wheel", "setuptools-git-versioning"] build-backend = "setuptools.build_meta" [project] @@ -12,6 +12,7 @@ license = {text = "University of Illinois-NCSA"} dependencies = [ "numpy", 'importlib-metadata; python_version<"3.8"', + "pytest-json-report" ] dynamic = ["version"] @@ -33,4 +34,5 @@ exclude = ["doc*"] testpaths = [ "src/esmpy/test/test_api", "examples/exampletest.py", + "src/esmpy/test/regrid_from_file/run_regrid_from_file.py", ] diff --git a/src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file.py b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file.py index f8dca3a750..d1ce83e1f2 100644 --- a/src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file.py +++ b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file.py @@ -9,21 +9,24 @@ source mesh. """ +import pytest + import sys import os import traceback -import pytest -try: - import esmpy -except: - raise ImportError('The ESMF library cannot be found!') +from esmpy import * +from esmpy.api.constants import _ESMF_NETCDF, _ESMF_PIO from esmpy.test.regrid_from_file.regrid_from_file_consts import DATA_SUBDIR from esmpy.test.regrid_from_file.regrid_check import regrid_check from esmpy.test.regrid_from_file.read_test_cases_from_control_file import read_control_file -# Start up esmpy. -mg = esmpy.Manager(debug=True) + +# Start up esmpy +mg = Manager(debug=True) + +if mg.pet_count == 1: + import esmpy.test.regrid_from_file.run_regrid_from_file_dryrun # Read the test case parameters from the control file. print('Reading control file...') @@ -32,20 +35,18 @@ # For each test case line from the control file parse the line and call # the test subroutine. +@pytest.mark.skipif(_ESMF_PIO==False, reason="PIO required in ESMF build") +@pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") @pytest.mark.parametrize('test_case', test_cases) def test_run_regrid_from_file(test_case): (src_fname, dst_fname, regrid_method, options, itrp_mean_err, itrp_max_err, csrv_err) = test_case test_str = 'Regrid %s to %s as %s with %s itrp_mean_err=%f, itrp_max_err=%f, and csrv_err=%f' % (src_fname, dst_fname, regrid_method, options, itrp_mean_err, itrp_max_err, csrv_err) - if esmpy.local_pet() == 0: + if local_pet() == 0: print ('\n' + test_str) src_fname_full = os.path.join(DATA_SUBDIR, src_fname) dst_fname_full = os.path.join(DATA_SUBDIR, dst_fname) # run the data file retrieval and regridding through try/except - try: - correct = regrid_check(src_fname_full, dst_fname_full, regrid_method, + regrid_check(src_fname_full, dst_fname_full, regrid_method, options, itrp_mean_err, itrp_max_err, csrv_err) - except: - print ("PET {}: Regridding ERROR:{}".format(esmpy.local_pet(), correct)) - traceback.print_exc(file=sys.stdout) diff --git a/src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file_dryrun.py b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file_dryrun.py index 21eb31c7d1..b0e4d9b896 100644 --- a/src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file_dryrun.py +++ b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file_dryrun.py @@ -40,8 +40,4 @@ def cache_data_files_for_test_cases(test_cases): test_cases = read_control_file() # Retrieve the data files needed for the test cases from the remote server. -try: - status_ok = cache_data_files_for_test_cases(test_cases) -except: - print ("Cache data file error: {}\n".format(status_ok)) - traceback.print_exc(file=sys.stdout) +cache_data_files_for_test_cases(test_cases) diff --git a/src/addon/ESMPy/src/esmpy/test/test_api/test_array.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_array.py index 3e4f1dfb43..69cf12f670 100644 --- a/src/addon/ESMPy/src/esmpy/test/test_api/test_array.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_array.py @@ -3,12 +3,13 @@ unit test file """ +import pytest +import numpy as np + from esmpy import * from esmpy.interface.cbindings import * from esmpy.test.base import TestBase -import numpy as np - # TODO: test view casting # TODO: demonstrate Fortran reordering in reshape call diff --git a/src/addon/ESMPy/src/esmpy/test/test_api/test_field.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_field.py index c02e2012e2..f7314c34bc 100644 --- a/src/addon/ESMPy/src/esmpy/test/test_api/test_field.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_field.py @@ -5,7 +5,6 @@ import pytest from esmpy import * -from esmpy.interface.cbindings import * from esmpy.test.base import TestBase from esmpy.util.mesh_utilities import mesh_create_50, mesh_create_50_parallel @@ -72,7 +71,7 @@ def test_meta_del(self): del (self.field) assert (not hasattr(self, 'field')) - @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") + @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") def test_numpy_funcs(self): field = self.make_field(np.array([10, 10], dtype=np.int32)) @@ -99,7 +98,7 @@ def test_numpy_funcs(self): @pytest.mark.skipif(mg.test_exhaustive==False, reason="only run in exhaustive mode") - @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") + @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") def _field_create_2d_grid(self): keywords = dict( # periodic specifies all valid combos of [num_peri_dims, periodic_dim, pole_dim] @@ -149,7 +148,7 @@ def _field_create_2d_grid(self): "The following combinations of parameters failed to create a proper Field: " + str(fail)) @pytest.mark.skipif(mg.test_exhaustive==False, reason="only run in exhaustive mode") - @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") + @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") def _field_create_3d_grid(self): keywords = dict( # periodic specifies all valid combos of [num_peri_dims, periodic_dim, pole_dim] @@ -201,7 +200,7 @@ def _field_create_3d_grid(self): "The following combinations of parameters failed to create a proper Field: " + str(len(fail))) @pytest.mark.skipif(mg.test_exhaustive==False, reason="only run in exhaustive mode") - @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") def _field_create_2d_mesh(self): keywords = dict( meshloc=[MeshLoc.NODE, MeshLoc.ELEMENT], @@ -277,7 +276,7 @@ def create_field(gml, name): return field - @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") def test_field_uniqueness(self): mesh = None if (pet_count() == 4): @@ -301,7 +300,7 @@ def test_field_uniqueness(self): assert (field.struct.ptr != field2.struct.ptr) - @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") + @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") def test_field_area(self): grid = Grid(np.array([3, 4]), staggerloc=[StaggerLoc.CENTER, StaggerLoc.CORNER], coord_sys=CoordSys.SPH_DEG, num_peri_dims=1, @@ -337,7 +336,7 @@ def test_field_area(self): assert(np.all(field.data == field2.data)) - @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") + @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") def test_field_locstream_mask(self): # LocStream creation and simple validation locstream = LocStream(5, name="Test LocStream") @@ -390,11 +389,8 @@ def test_field_extradims_grid(self): field2.data[...] = 10 self.examine_field_attributes(field2) - @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") def test_field_extradims_mesh(self): - - print("Pet count {}".format(pet_count())) - mesh = None if (pet_count() == 4): mesh, nodeCoord, nodeOwner, elemType, elemConn = \ @@ -412,7 +408,7 @@ def test_field_extradims_mesh(self): field2.data[...] = 10 self.examine_field_attributes(field2) - @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") + @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") def test_field_slice_grid(self): typekind = TypeKind.R8 grid = Grid(np.array([100, 100]), coord_sys=CoordSys.CART, @@ -452,7 +448,7 @@ def test_field_slice_grid(self): assert (field3.grid.upper_bounds[0].tolist() == [2, 2]) # slicing is disabled in parallel - @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") + @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") def test_field_slice_mesh(self): mesh = None if pet_count() > 1: @@ -483,7 +479,7 @@ def test_field_slice_mesh(self): assert (field2.grid.size[0] == 5) assert (field3.grid.size[0] == 2) - @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") + @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") def test_field_slice_grid_extraindices(self): n = 10 grid = Grid(np.array([n,n]), coord_sys=CoordSys.CART, staggerloc=StaggerLoc.CENTER) @@ -521,7 +517,7 @@ def test_field_slice_grid_extraindices(self): assert (field2.grid.upper_bounds[0].tolist() == [5, 5]) assert (field3.grid.upper_bounds[0].tolist() == [2, 2]) - @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") + @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") def disable_est_field_slice_mesh_extraindices(self): mesh, nodeCoord, nodeOwner, elemType, elemConn, elemCoord = mesh_create_50() @@ -543,7 +539,7 @@ def disable_est_field_slice_mesh_extraindices(self): assert field2.data.shape == (5, 2, 1) assert field3.data.shape == (2, 1, 1) - @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") + @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") def test_field_reshape(self): field = self.make_field(np.array([10, 10], dtype=np.int32), ndbounds=False) diff --git a/src/addon/ESMPy/src/esmpy/test/test_api/test_grid.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_grid.py index 3186877b5a..2452e046c0 100644 --- a/src/addon/ESMPy/src/esmpy/test/test_api/test_grid.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_grid.py @@ -3,17 +3,17 @@ grid unit test file """ -import esmpy +import pytest +import numpy as np + +import os +import inspect + from esmpy import * from esmpy.interface.cbindings import * from esmpy.test.base import TestBase from esmpy.api.constants import _ESMF_NETCDF -import numpy as np -import os -import inspect -import pytest - class TestGrid(TestBase): mg = Manager(debug=True) @@ -141,28 +141,28 @@ def make_grid_periodic(self): assert lon.size == 100 assert lat.size == 100 - grid = esmpy.Grid(np.array([lon.size, lat.size], 'int32'), + grid = Grid(np.array([lon.size, lat.size], 'int32'), num_peri_dims=1, staggerloc=[StaggerLoc.CENTER, StaggerLoc.CORNER]) - gridXCorner = grid.get_coords(0, staggerloc=esmpy.StaggerLoc.CORNER) - lon_par = lon[grid.lower_bounds[esmpy.StaggerLoc.CORNER][0]:grid.upper_bounds[esmpy.StaggerLoc.CORNER][0]] + gridXCorner = grid.get_coords(0, staggerloc=StaggerLoc.CORNER) + lon_par = lon[grid.lower_bounds[StaggerLoc.CORNER][0]:grid.upper_bounds[StaggerLoc.CORNER][0]] gridXCorner[...] = lon_par.reshape((lon_par.size, 1)) - gridYCorner = grid.get_coords(1, staggerloc=esmpy.StaggerLoc.CORNER) + gridYCorner = grid.get_coords(1, staggerloc=StaggerLoc.CORNER) lat_corner = np.linspace(90, -90, lat.size + 1) - lat_par = lat_corner[grid.lower_bounds[esmpy.StaggerLoc.CORNER][1]:grid.upper_bounds[esmpy.StaggerLoc.CORNER][1]] + lat_par = lat_corner[grid.lower_bounds[StaggerLoc.CORNER][1]:grid.upper_bounds[StaggerLoc.CORNER][1]] gridYCorner[...] = lat_par.reshape((1, lat_par.size)) offset_lon = 360. / lon.size / 2. lon -= offset_lon gridXCenter = grid.get_coords(0) - lon_par = lon[grid.lower_bounds[esmpy.StaggerLoc.CENTER][0]:grid.upper_bounds[esmpy.StaggerLoc.CENTER][0]] + lon_par = lon[grid.lower_bounds[StaggerLoc.CENTER][0]:grid.upper_bounds[StaggerLoc.CENTER][0]] gridXCenter[...] = lon_par.reshape((lon_par.size, 1)) offset_lat = 180. / (lat.size) / 2. lat = np.linspace(90 - offset_lat, -90 + offset_lat, lat.size) gridYCenter = grid.get_coords(1) - lat_par = lat[grid.lower_bounds[esmpy.StaggerLoc.CENTER][1]:grid.upper_bounds[esmpy.StaggerLoc.CENTER][1]] + lat_par = lat[grid.lower_bounds[StaggerLoc.CENTER][1]:grid.upper_bounds[StaggerLoc.CENTER][1]] gridYCenter[...] = lat_par.reshape((1, lat_par.size)) @@ -283,8 +283,6 @@ def test_grid_create_cubed_sphere(self): # [DecompFlag.DEFAULT, 6]], dtype=np.int32) # deLabelList = np.array([11,12,13,14,15,16], dtype=np.int32) - esmpy.Manager(debug=True) - grid = Grid(tilesize = 45, regDecompPTile = regDecompPTile, #decompFlagPTile = decompFlagPTile, #deLabelList = deLabelList, @@ -322,7 +320,7 @@ def test_grid_slice_2d(self): def test_grid_slice_2d_corners(self): grid = self.make_grid_2d() - grid.add_coords(staggerloc=esmpy.StaggerLoc.CORNER) + grid.add_coords(staggerloc=StaggerLoc.CORNER) grid_row = grid.get_coords(0, staggerloc=StaggerLoc.CORNER) grid_col = grid.get_coords(1, staggerloc=StaggerLoc.CORNER) @@ -433,6 +431,7 @@ def test_grid_slice_periodic(self): @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") def test_slice_grid_created_from_file_scrip(self): + import esmpy reg_decomp = [pet_count(), 1] try: esmfdir = os.path.dirname(inspect.getfile(esmpy)) @@ -632,6 +631,7 @@ def test_grid_area_3D(self): @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_gridspec1D(self): + import esmpy esmfdir = os.path.dirname(inspect.getfile(esmpy)) grid = Grid(filename=os.path.join(esmfdir, "test/data/gridspec1Dcoords.nc"), filetype=FileFormat.GRIDSPEC, add_corner_stagger=True, @@ -641,6 +641,7 @@ def test_grid_create_from_file_gridspec1D(self): @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip(self): + import esmpy reg_decomp = [pet_count(), 1] try: esmfdir = os.path.dirname(inspect.getfile(esmpy)) @@ -652,6 +653,7 @@ def test_grid_create_from_file_scrip(self): @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_balanced_balanced(self): + import esmpy reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.BALANCED, DecompFlag.BALANCED], dtype=np.int32) @@ -665,6 +667,7 @@ def test_grid_create_from_file_scrip_decomp_balanced_balanced(self): @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_balanced_restfirst(self): + import esmpy reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.BALANCED, DecompFlag.RESTFIRST], dtype=np.int32) @@ -678,6 +681,7 @@ def test_grid_create_from_file_scrip_decomp_balanced_restfirst(self): @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_balanced_restlast(self): + import esmpy reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.BALANCED, DecompFlag.RESTLAST], dtype=np.int32) @@ -692,6 +696,7 @@ def test_grid_create_from_file_scrip_decomp_balanced_restlast(self): @pytest.mark.xfail @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_balanced_cyclic(self): + import esmpy reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.BALANCED, DecompFlag.CYCLIC], dtype=np.int32) @@ -705,6 +710,7 @@ def test_grid_create_from_file_scrip_decomp_balanced_cyclic(self): @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_restfirst_balanced(self): + import esmpy reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.RESTFIRST, DecompFlag.BALANCED], dtype=np.int32) @@ -718,6 +724,7 @@ def test_grid_create_from_file_scrip_decomp_restfirst_balanced(self): @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_restfirst_restfirst(self): + import esmpy reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.RESTFIRST, DecompFlag.RESTFIRST], dtype=np.int32) @@ -731,6 +738,7 @@ def test_grid_create_from_file_scrip_decomp_restfirst_restfirst(self): @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_restfirst_restlast(self): + import esmpy reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.RESTFIRST, DecompFlag.RESTLAST], dtype=np.int32) @@ -745,6 +753,7 @@ def test_grid_create_from_file_scrip_decomp_restfirst_restlast(self): @pytest.mark.xfail @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_restfirst_cyclic(self): + import esmpy reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.RESTFIRST, DecompFlag.CYCLIC], dtype=np.int32) @@ -758,6 +767,7 @@ def test_grid_create_from_file_scrip_decomp_restfirst_cyclic(self): @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_restlast_balanced(self): + import esmpy reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.RESTLAST, DecompFlag.BALANCED], dtype=np.int32) @@ -771,6 +781,7 @@ def test_grid_create_from_file_scrip_decomp_restlast_balanced(self): @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_restlast_restfirst(self): + import esmpy reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.RESTLAST, DecompFlag.RESTFIRST], dtype=np.int32) @@ -784,6 +795,7 @@ def test_grid_create_from_file_scrip_decomp_restlast_restfirst(self): @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_restlast_restlast(self): + import esmpy reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.RESTLAST, DecompFlag.RESTLAST], dtype=np.int32) @@ -798,6 +810,7 @@ def test_grid_create_from_file_scrip_decomp_restlast_restlast(self): @pytest.mark.xfail @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_restlast_cyclic(self): + import esmpy reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.RESTLAST, DecompFlag.CYCLIC], dtype=np.int32) @@ -812,6 +825,7 @@ def test_grid_create_from_file_scrip_decomp_restlast_cyclic(self): @pytest.mark.xfail @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_cyclic_balanced(self): + import esmpy reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.CYCLIC, DecompFlag.BALANCED], dtype=np.int32) @@ -826,6 +840,7 @@ def test_grid_create_from_file_scrip_decomp_cyclic_balanced(self): @pytest.mark.xfail @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_cyclic_restfirst(self): + import esmpy reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.CYCLIC, DecompFlag.RESTFIRST], dtype=np.int32) @@ -840,6 +855,7 @@ def test_grid_create_from_file_scrip_decomp_cyclic_restfirst(self): @pytest.mark.xfail @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_cyclic_restlast(self): + import esmpy reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.CYCLIC, DecompFlag.RESTLAST], dtype=np.int32) @@ -854,6 +870,7 @@ def test_grid_create_from_file_scrip_decomp_cyclic_restlast(self): @pytest.mark.xfail @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_create_from_file_scrip_decomp_cyclic_cyclic(self): + import esmpy reg_decomp = [pet_count(), 1] decompflag = np.array([DecompFlag.CYCLIC, DecompFlag.CYCLIC], dtype=np.int32) diff --git a/src/addon/ESMPy/src/esmpy/test/test_api/test_locstream.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_locstream.py index b455acbc04..7ec83755b9 100644 --- a/src/addon/ESMPy/src/esmpy/test/test_api/test_locstream.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_locstream.py @@ -3,12 +3,11 @@ locstream unit test file """ +import pytest + from esmpy import * -from esmpy.interface.cbindings import * from esmpy.test.base import TestBase -import pytest - class TestLocStream(TestBase): mg = Manager(debug=True) diff --git a/src/addon/ESMPy/src/esmpy/test/test_api/test_mesh.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_mesh.py index 8d97691b76..41b87d4bb8 100644 --- a/src/addon/ESMPy/src/esmpy/test/test_api/test_mesh.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_mesh.py @@ -8,7 +8,6 @@ import os import inspect -import esmpy from esmpy import * from esmpy.test.base import TestBase from esmpy.api.constants import _ESMF_NETCDF, _ESMF_PIO diff --git a/src/addon/ESMPy/src/esmpy/test/test_api/test_regrid.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_regrid.py index 3a6e1ffefe..a42d0e8306 100644 --- a/src/addon/ESMPy/src/esmpy/test/test_api/test_regrid.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_regrid.py @@ -313,7 +313,7 @@ def test_field_regrid_file2(self): @pytest.mark.skipif(_ESMF_PIO==False, reason="PIO required in ESMF build") @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") # remove this test for 8.2.0 due to unexplained segv - def test_field_regrid_file_withaux(self): + def _field_regrid_file_withaux(self): import os DD = os.path.join(os.getcwd(), "test/data") if not os.path.isdir(DD): diff --git a/src/addon/ESMPy/src/esmpy/test/test_api/test_vm.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_vm.py index 3be54d4fd5..7fd61057b7 100644 --- a/src/addon/ESMPy/src/esmpy/test/test_api/test_vm.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_vm.py @@ -2,12 +2,11 @@ vm unit test file """ +import pytest + from esmpy import * -from esmpy.interface.cbindings import * from esmpy.test.base import TestBase -import pytest - class TestVM(TestBase): def test_vm_broadcast(self): mg = Manager() From f1b50ddf40746bebdfbe04a0b88f45bf37af8720 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Wed, 7 Sep 2022 15:45:36 -0600 Subject: [PATCH 28/45] remove old.setup.cfg --- src/addon/ESMPy/old.setup.cfg | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 src/addon/ESMPy/old.setup.cfg diff --git a/src/addon/ESMPy/old.setup.cfg b/src/addon/ESMPy/old.setup.cfg deleted file mode 100644 index 48cdbf3ff0..0000000000 --- a/src/addon/ESMPy/old.setup.cfg +++ /dev/null @@ -1,27 +0,0 @@ -[metadata] -name = ESMPy -description = ESMF Python interface -license = University of Illinois-NCSA -author = University Corporation for Atmospheric Research, Massachusetts Institute of Technology, Geophysical Fluid Dynamics Laboratory, University of Michigan, National Centers for Environmental Prediction, Los Alamos National Laboratory, Argonne National Laboratory, NASA Goddard Space Flight Center -maintainer_email = esmf_support@ucar.edu -url = http://earthsystemmodeling.org/esmpy/ -obsoletes = ESMF -requires = numpy -python_requires = '>=3.7', - -[options] -zip_safe = False -include_package_data = True -package_dir= - =src -packages = find: -install_requires = - numpy - pytest - -[options.packages.find] -where=src -exclude = - doc* - examples* - test* From 4bf9050978c301a1454afe5048caa042fa68c0a8 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Wed, 7 Sep 2022 15:51:24 -0600 Subject: [PATCH 29/45] ESMPy test script and targets for Cheyenne --- src/addon/ESMPy/Makefile | 28 ++++++++++++++++------------ src/addon/ESMPy/test_all.bash | 17 +++++++++++++++++ 2 files changed, 33 insertions(+), 12 deletions(-) create mode 100644 src/addon/ESMPy/test_all.bash diff --git a/src/addon/ESMPy/Makefile b/src/addon/ESMPy/Makefile index e5d25fe110..707e9dde4b 100644 --- a/src/addon/ESMPy/Makefile +++ b/src/addon/ESMPy/Makefile @@ -12,42 +12,46 @@ clean: find . -name "*.python-version" -exec rm -f {} \; || : find . -name "*__pycache__" -exec rm -rf {} \; || : find . -name ".report.json" -exec rm -rf {} \; || : + find . -name ".test" -exec rm -rf {} \; || : rm -rf src/esmpy/test/regrid_from_file/data || : rm -rf examples/data || : install: python3 -m pip install . +dryrun_examples: + python3 -m pytest -vs examples/exampletestdryrun.py + +dryrun_regrid_from_file: + python3 -m pytest -vs src/esmpy/test/regrid_from_file/run_regrid_from_file_dryrun.py + +dryrun: dryrun_examples dryrun_regrid_from_file + +test: + bash test_all.bash + test_unit: - python3 -m pytest -m="not parallel" + python3 -m pytest -vs test_unit_parallel: - mpirun -n 4 python3 -m pytest -m="not serial" + mpiexec -n 4 python3 -vs test_examples: python3 -m pytest -vs examples/exampletest.py test_examples_parallel: - mpirun -n 4 python3 -m pytest -vs examples/exampletest.py + mpiexec -n 4 python3 -m pytest -vs examples/exampletest.py -test_examples_dryrun: - python3 -m pytest -vs examples/exampletestdryrun.py - test_regrid_from_file: python3 -m pytest -vs src/esmpy/test/regrid_from_file/run_regrid_from_file.py test_regrid_from_file_parallel: - mpirun -n 4 python3 -m pytest -vs src/esmpy/test/regrid_from_file/run_regrid_from_file.py - -test_regrid_from_file_dryrun: - python3 -m pytest -vs src/esmpy/test/regrid_from_file/run_regrid_from_file_dryrun.py + mpiexec -n 4 python3 -m pytest -vs src/esmpy/test/regrid_from_file/run_regrid_from_file.py test_serial: test_unit test_examples test_regrid_from_file test_parallel: test_unit_parallel test_examples_parallel test_regrid_from_file_parallel -test_dryrun: test_examples_dryrun test_regrid_from_file_dryrun - test_all: test_unit test_unit_parallel test_examples test_examples_parallel test_regrid_from_file test_regrid_from_file_parallel uninstall: diff --git a/src/addon/ESMPy/test_all.bash b/src/addon/ESMPy/test_all.bash new file mode 100644 index 0000000000..cf55141a0f --- /dev/null +++ b/src/addon/ESMPy/test_all.bash @@ -0,0 +1,17 @@ +#!/bin/bash + +VERSION=$(python3 -c "import esmpy; print (esmpy.__version__)") + +echo "Testing ESMPy ${VERSION}" + +for NP in 1 4 6 +do + REPORT="esmpy${VERSION}-cheyenne-intelmpt-petx${NP}.test" + COMMAND="mpiexec -n ${NP} python3 -m pytest -vs --json-report --json-report-summary > $REPORT 2>&1"00 + echo ${COMMAND} + eval "${COMMAND}" + find . -name "*.ESMF_LogFile" -exec cat {} >> ${REPORT} \; + cat .report.json >> ${REPORT} +done + +echo "Report is in ${REPORT}" From 830bda657844be68e93acfd48864aa53d8bd532b Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Wed, 7 Sep 2022 15:15:36 -0700 Subject: [PATCH 30/45] rename ESMPy example and regrid_from_file test files, add dryrun target and clean up dryruns --- src/addon/ESMPy/Makefile | 19 ++++++++++++------- src/addon/ESMPy/examples/exampletestdryrun.py | 15 --------------- .../{exampletest.py => test_examples.py} | 14 +++++++------- .../ESMPy/examples/test_examples_dryrun.py | 8 ++++++++ src/addon/ESMPy/pyproject.toml | 6 +++--- .../test/regrid_from_file/regrid_check.py | 4 ++-- ..._from_file.py => test_regrid_from_file.py} | 2 +- ...run.py => test_regrid_from_file_dryrun.py} | 2 +- .../src/esmpy/test/test_api/test_regrid.py | 18 +++++++++--------- src/addon/ESMPy/test_all.bash | 2 +- 10 files changed, 44 insertions(+), 46 deletions(-) delete mode 100644 src/addon/ESMPy/examples/exampletestdryrun.py rename src/addon/ESMPy/examples/{exampletest.py => test_examples.py} (93%) create mode 100644 src/addon/ESMPy/examples/test_examples_dryrun.py rename src/addon/ESMPy/src/esmpy/test/regrid_from_file/{run_regrid_from_file.py => test_regrid_from_file.py} (96%) rename src/addon/ESMPy/src/esmpy/test/regrid_from_file/{run_regrid_from_file_dryrun.py => test_regrid_from_file_dryrun.py} (95%) diff --git a/src/addon/ESMPy/Makefile b/src/addon/ESMPy/Makefile index 707e9dde4b..157e7c82db 100644 --- a/src/addon/ESMPy/Makefile +++ b/src/addon/ESMPy/Makefile @@ -5,25 +5,30 @@ clean: rm -rf dist || : find . -name "*.egg-info" -exec rm -rf {} \; || : find . -name "*.pyc" -exec rm -f {} \; || : - find . -name "*ESMF_LogFile*" -exec rm -f {} \; || : find . -name "*.log" -exec rm -f {} \; || : find . -name "*.vtk" -exec rm -f {} \; || : find . -name "*.pytest_cache" -exec rm -rf {} \; || : find . -name "*.python-version" -exec rm -f {} \; || : find . -name "*__pycache__" -exec rm -rf {} \; || : + find . -name "*ESMF_LogFile*" -exec rm -f {} \; || : find . -name ".report.json" -exec rm -rf {} \; || : find . -name ".test" -exec rm -rf {} \; || : rm -rf src/esmpy/test/regrid_from_file/data || : rm -rf examples/data || : +dust: + find . -name "*ESMF_LogFile*" -exec rm -f {} \; || : + find . -name ".report.json" -exec rm -rf {} \; || : + find . -name ".test" -exec rm -rf {} \; || : + install: python3 -m pip install . dryrun_examples: - python3 -m pytest -vs examples/exampletestdryrun.py + python3 examples/test_examples_dryrun.py dryrun_regrid_from_file: - python3 -m pytest -vs src/esmpy/test/regrid_from_file/run_regrid_from_file_dryrun.py + python3 src/esmpy/test/regrid_from_file/test_regrid_from_file_dryrun.py dryrun: dryrun_examples dryrun_regrid_from_file @@ -37,16 +42,16 @@ test_unit_parallel: mpiexec -n 4 python3 -vs test_examples: - python3 -m pytest -vs examples/exampletest.py + python3 -m pytest -vs examples/test_examples.py test_examples_parallel: - mpiexec -n 4 python3 -m pytest -vs examples/exampletest.py + mpiexec -n 4 python3 -m pytest -vs examples/test_examples.py test_regrid_from_file: - python3 -m pytest -vs src/esmpy/test/regrid_from_file/run_regrid_from_file.py + python3 -m pytest -vs src/esmpy/test/regrid_from_file/test_regrid_from_file.py test_regrid_from_file_parallel: - mpiexec -n 4 python3 -m pytest -vs src/esmpy/test/regrid_from_file/run_regrid_from_file.py + mpiexec -n 4 python3 -m pytest -vs src/esmpy/test/regrid_from_file/test_regrid_from_file.py test_serial: test_unit test_examples test_regrid_from_file diff --git a/src/addon/ESMPy/examples/exampletestdryrun.py b/src/addon/ESMPy/examples/exampletestdryrun.py deleted file mode 100644 index 348f08431a..0000000000 --- a/src/addon/ESMPy/examples/exampletestdryrun.py +++ /dev/null @@ -1,15 +0,0 @@ -# $Id$ - -""" -examples dryrun test file -""" - -import pytest - -from esmpy.test.base import TestBase - -class TestExamplesDryrun(TestBase): - - def test_examples_dryrun(self): - from esmpy.util.cache_data import cache_data_files - cache_data_files() diff --git a/src/addon/ESMPy/examples/exampletest.py b/src/addon/ESMPy/examples/test_examples.py similarity index 93% rename from src/addon/ESMPy/examples/exampletest.py rename to src/addon/ESMPy/examples/test_examples.py index 97e9607a13..94bdf1a6c9 100644 --- a/src/addon/ESMPy/examples/exampletest.py +++ b/src/addon/ESMPy/examples/test_examples.py @@ -11,15 +11,15 @@ import esmpy.api.constants as constants from esmpy.api.esmpymanager import Manager +# Start up esmpy +mg = Manager(debug=True) + +if mg.pet_count == 1: + from esmpy.util.cache_data import cache_data_files + cache_data_files() + class TestExamples(TestBase): - - mg = Manager(debug=True) - # '0' in the name is so it is run first - def test_0_examples_dryrun(self): - from esmpy.util.cache_data import cache_data_files - cache_data_files() - def test_helloworld(self): from . import hello_world diff --git a/src/addon/ESMPy/examples/test_examples_dryrun.py b/src/addon/ESMPy/examples/test_examples_dryrun.py new file mode 100644 index 0000000000..14319d7b86 --- /dev/null +++ b/src/addon/ESMPy/examples/test_examples_dryrun.py @@ -0,0 +1,8 @@ +# $Id$ + +""" +examples data dryrun +""" + +from esmpy.util.cache_data import cache_data_files +cache_data_files() diff --git a/src/addon/ESMPy/pyproject.toml b/src/addon/ESMPy/pyproject.toml index 35590d6390..91a8ecb838 100644 --- a/src/addon/ESMPy/pyproject.toml +++ b/src/addon/ESMPy/pyproject.toml @@ -11,8 +11,8 @@ requires-python = ">=3.7" license = {text = "University of Illinois-NCSA"} dependencies = [ "numpy", + "pytest-json-report", 'importlib-metadata; python_version<"3.8"', - "pytest-json-report" ] dynamic = ["version"] @@ -33,6 +33,6 @@ exclude = ["doc*"] [tool.pytest.ini_options] testpaths = [ "src/esmpy/test/test_api", - "examples/exampletest.py", - "src/esmpy/test/regrid_from_file/run_regrid_from_file.py", + "examples/test_examples.py", + "src/esmpy/test/regrid_from_file/test_regrid_from_file.py", ] diff --git a/src/addon/ESMPy/src/esmpy/test/regrid_from_file/regrid_check.py b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/regrid_check.py index 0714009da0..f0748021d8 100644 --- a/src/addon/ESMPy/src/esmpy/test/regrid_from_file/regrid_check.py +++ b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/regrid_check.py @@ -117,9 +117,9 @@ def run_regridding(srcfield, dstfield, src_mask, dst_mask, src_mask_vals = None dst_mask_vals = None if src_mask: - src_mask_vals = np.array([0]) + src_mask_vals = np.atleast_1d(np.array([0])) if dst_mask: - dst_mask_vals = np.array([0]) + dst_mask_vals = np.atleast_1d(np.array([0])) regridSrc2Dst = esmpy.Regrid(srcfield, dstfield, src_mask_values=src_mask_vals, diff --git a/src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file.py b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/test_regrid_from_file.py similarity index 96% rename from src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file.py rename to src/addon/ESMPy/src/esmpy/test/regrid_from_file/test_regrid_from_file.py index d1ce83e1f2..37ac3e70da 100644 --- a/src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file.py +++ b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/test_regrid_from_file.py @@ -26,7 +26,7 @@ mg = Manager(debug=True) if mg.pet_count == 1: - import esmpy.test.regrid_from_file.run_regrid_from_file_dryrun + import esmpy.test.regrid_from_file.test_regrid_from_file_dryrun # Read the test case parameters from the control file. print('Reading control file...') diff --git a/src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file_dryrun.py b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/test_regrid_from_file_dryrun.py similarity index 95% rename from src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file_dryrun.py rename to src/addon/ESMPy/src/esmpy/test/regrid_from_file/test_regrid_from_file_dryrun.py index b0e4d9b896..99d415aee6 100644 --- a/src/addon/ESMPy/src/esmpy/test/regrid_from_file/run_regrid_from_file_dryrun.py +++ b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/test_regrid_from_file_dryrun.py @@ -4,7 +4,7 @@ coordinate grid. Parses each line and retrieves the source and destination files from a remote server if they do not already exist locally. On parallel computers where the compute nodes do not have internet access, this script must -be run on the front-end machine before running run_regrid_from_file.py to do +be run on the front-end machine before running test_regrid_from_file.py to do the regridding. """ diff --git a/src/addon/ESMPy/src/esmpy/test/test_api/test_regrid.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_regrid.py index a42d0e8306..ba515571a9 100644 --- a/src/addon/ESMPy/src/esmpy/test/test_api/test_regrid.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_regrid.py @@ -632,7 +632,7 @@ def test_field_regrid_zeroregion(self): # regridding rh = Regrid(srcfield, dstfield, regrid_method=RegridMethod.CONSERVE, - dst_mask_values=np.array([0])) + dst_mask_values=np.atleast_1d(np.array([0]))) dstfield = rh(srcfield, dstfield, zero_region=Region.SELECT) # validate that the masked values were not zeroed out @@ -663,8 +663,8 @@ def test_field_regrid_zeroregion_select_ndbounds(self): # Regrid in-memory rh = Regrid(srcfield, dstfield, regrid_method=RegridMethod.BILINEAR, - src_mask_values=np.array([0]), - dst_mask_values=np.array([0]), + src_mask_values=np.atleast_1d(np.array([0])), + dst_mask_values=np.atleast_1d(np.array([0])), unmapped_action=UnmappedAction.IGNORE) _ = rh(srcfield, dstfield, zero_region=Region.SELECT) @@ -676,7 +676,7 @@ def test_field_regrid_zeroregion_select_ndbounds(self): dstfield.data[:] = -999 filename = '_esmf_test_weights_.nc' _ = Regrid(srcfield, dstfield, regrid_method=RegridMethod.BILINEAR, - src_mask_values=np.array([0]), + src_mask_values=np.atleast_1d(np.array([0])), unmapped_action=UnmappedAction.IGNORE, filename=filename) self.assertTrue(np.all(dstfield.data == -999)) @@ -748,7 +748,7 @@ def test_field_regrid_periodic(self): # run the ESMF regridding regridSrc2Dst = esmpy.Regrid(srcfield, dstfield, - src_mask_values=np.array([0]), + src_mask_values=np.atleast_1d(np.array([0])), regrid_method=esmpy.RegridMethod.CONSERVE, unmapped_action=esmpy.UnmappedAction.ERROR, src_frac_field=srcfracfield, @@ -887,7 +887,7 @@ def test_grid_grid_regrid_csrv_mask(self): # run the ESMF regridding regridSrc2Dst = esmpy.Regrid(srcfield, dstfield, - src_mask_values=np.array([0]), + src_mask_values=np.atleast_1d(np.array([0])), regrid_method=esmpy.RegridMethod.CONSERVE, unmapped_action=esmpy.UnmappedAction.ERROR, src_frac_field=srcfracfield, @@ -928,7 +928,7 @@ def test_grid_grid_regrid_csrv_2nd_mask(self): # run the ESMF regridding regridSrc2Dst = esmpy.Regrid(srcfield, dstfield, - src_mask_values=np.array([0]), + src_mask_values=np.atleast_1d(np.array([0])), regrid_method=esmpy.RegridMethod.CONSERVE_2ND, unmapped_action=esmpy.UnmappedAction.ERROR, src_frac_field=srcfracfield, @@ -1023,7 +1023,7 @@ def test_grid_mesh_regrid_csrv_mask(self): # run the ESMF regridding regridSrc2Dst = esmpy.Regrid(srcfield, dstfield, - src_mask_values=np.array([0]), + src_mask_values=np.atleast_1d(np.array([0])), regrid_method=esmpy.RegridMethod.CONSERVE, unmapped_action=esmpy.UnmappedAction.ERROR, src_frac_field=srcfracfield, @@ -1116,7 +1116,7 @@ def test_grid_mesh_regrid_mask(self): # run the ESMF regridding regridSrc2Dst = esmpy.Regrid(srcfield, dstfield, - dst_mask_values=np.array([0]), + dst_mask_values=np.atleast_1d(np.array([0])), regrid_method=esmpy.RegridMethod.BILINEAR, unmapped_action=esmpy.UnmappedAction.IGNORE) dstfield = regridSrc2Dst(srcfield, dstfield) diff --git a/src/addon/ESMPy/test_all.bash b/src/addon/ESMPy/test_all.bash index cf55141a0f..a2aee0ce57 100644 --- a/src/addon/ESMPy/test_all.bash +++ b/src/addon/ESMPy/test_all.bash @@ -7,7 +7,7 @@ echo "Testing ESMPy ${VERSION}" for NP in 1 4 6 do REPORT="esmpy${VERSION}-cheyenne-intelmpt-petx${NP}.test" - COMMAND="mpiexec -n ${NP} python3 -m pytest -vs --json-report --json-report-summary > $REPORT 2>&1"00 + COMMAND="mpiexec -n ${NP} python3 -m pytest -vs --json-report --json-report-summary > $REPORT 2>&1" echo ${COMMAND} eval "${COMMAND}" find . -name "*.ESMF_LogFile" -exec cat {} >> ${REPORT} \; From 46533806b31256e97a67aa7bfc78608277f5f32c Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Thu, 8 Sep 2022 10:56:54 -0700 Subject: [PATCH 31/45] remove deprecated decorator from ESMP_FieldSMMStore --- src/addon/ESMPy/src/esmpy/interface/cbindings.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/addon/ESMPy/src/esmpy/interface/cbindings.py b/src/addon/ESMPy/src/esmpy/interface/cbindings.py index b0499f19d0..126ff6372f 100644 --- a/src/addon/ESMPy/src/esmpy/interface/cbindings.py +++ b/src/addon/ESMPy/src/esmpy/interface/cbindings.py @@ -2329,7 +2329,6 @@ def ESMP_FieldRegrid(srcField, dstField, routehandle, zeroregion=None): _ESMF.ESMC_FieldSMMStore.argtypes = [ct.c_void_p, ct.c_void_p, ct.c_char_p, ct.POINTER(ESMP_RouteHandle), ct.c_bool, ct.POINTER(ct.c_int), ct.POINTER(ct.c_int)] -@deprecated def ESMP_FieldSMMStore(srcField, dstField, filename, ignoreUnmatchedIndices=None): """ From e89e1c46786e0204ef754c4638ffd1e1450ae5dd Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Thu, 8 Sep 2022 10:57:23 -0700 Subject: [PATCH 32/45] fix clean and dust targets of ESMPy Makefile --- src/addon/ESMPy/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/addon/ESMPy/Makefile b/src/addon/ESMPy/Makefile index 157e7c82db..3129383ef6 100644 --- a/src/addon/ESMPy/Makefile +++ b/src/addon/ESMPy/Makefile @@ -11,15 +11,15 @@ clean: find . -name "*.python-version" -exec rm -f {} \; || : find . -name "*__pycache__" -exec rm -rf {} \; || : find . -name "*ESMF_LogFile*" -exec rm -f {} \; || : - find . -name ".report.json" -exec rm -rf {} \; || : - find . -name ".test" -exec rm -rf {} \; || : + find . -name "*.report.json" -exec rm -rf {} \; || : + find . -name "*.test" -exec rm -rf {} \; || : rm -rf src/esmpy/test/regrid_from_file/data || : rm -rf examples/data || : dust: find . -name "*ESMF_LogFile*" -exec rm -f {} \; || : - find . -name ".report.json" -exec rm -rf {} \; || : - find . -name ".test" -exec rm -rf {} \; || : + find . -name "*.report.json" -exec rm -rf {} \; || : + find . -name "*.test" -exec rm -rf {} \; || : install: python3 -m pip install . From 7624b3ce3821f54a9eb8447ee79decfa8ad6cd59 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Thu, 8 Sep 2022 10:57:43 -0700 Subject: [PATCH 33/45] add a version check for ESMPy and ESMF installations --- src/addon/ESMPy/src/esmpy/__init__.py | 25 +++++++++++-------- src/addon/ESMPy/src/esmpy/api/constants.py | 4 +++ src/addon/ESMPy/src/esmpy/api/esmpymanager.py | 3 ++- .../ESMPy/src/esmpy/interface/loadESMF.py | 23 ++++++++++++++--- src/addon/ESMPy/src/esmpy/util/exceptions.py | 17 +++++++++++-- 5 files changed, 55 insertions(+), 17 deletions(-) diff --git a/src/addon/ESMPy/src/esmpy/__init__.py b/src/addon/ESMPy/src/esmpy/__init__.py index ec5f90f4bd..a7f90a2a3e 100644 --- a/src/addon/ESMPy/src/esmpy/__init__.py +++ b/src/addon/ESMPy/src/esmpy/__init__.py @@ -64,19 +64,10 @@ data values. """ -#### IMPORT LIBRARIES ######################################################### - -from esmpy.api.esmpymanager import * -from esmpy.api.grid import * -from esmpy.api.mesh import * -from esmpy.api.locstream import * -from esmpy.api.field import * -from esmpy.api.regrid import * -from esmpy.api.constants import * -from esmpy.util.helpers import * - #### SET UP SOME INFO ######################################################### +import esmpy.api.constants as constants + import sys msg = "" @@ -105,6 +96,7 @@ # set the private metadata __name__ = msg["Name"] __version__ = msg["Version"] +constants._ESMPY_VERSION = __version__ # required to check against ESMF_VERSION in loadESMF __license__ = msg["License"] __email__ = msg["Maintainer-email"] __description__ = msg["Summary"] @@ -114,3 +106,14 @@ __author__ = msg["Author"] __homepage__ = msg["Home-page"] __obsoletes__ = msg["obsoletes"] + +#### IMPORT LIBRARIES ######################################################### + +from esmpy.api.esmpymanager import * +from esmpy.api.grid import * +from esmpy.api.mesh import * +from esmpy.api.locstream import * +from esmpy.api.field import * +from esmpy.api.regrid import * +from esmpy.api.constants import * +from esmpy.util.helpers import * diff --git a/src/addon/ESMPy/src/esmpy/api/constants.py b/src/addon/ESMPy/src/esmpy/api/constants.py index 52791233da..87f6abac97 100644 --- a/src/addon/ESMPy/src/esmpy/api/constants.py +++ b/src/addon/ESMPy/src/esmpy/api/constants.py @@ -51,6 +51,10 @@ # ESMF_VERSION _ESMF_VERSION = None +# ESMPY_VERSION, this is required to avoid a circular import in loadESMF when +# checking that the ESMF_VERSION matches esmpy.__version__ +_ESMPY_VERSION = None + # ESMF_MPIRUN _ESMF_MPIRUN = None _ESMF_MPIRUN_NP = None diff --git a/src/addon/ESMPy/src/esmpy/api/esmpymanager.py b/src/addon/ESMPy/src/esmpy/api/esmpymanager.py index cda53527da..8dd02bb50c 100644 --- a/src/addon/ESMPy/src/esmpy/api/esmpymanager.py +++ b/src/addon/ESMPy/src/esmpy/api/esmpymanager.py @@ -6,9 +6,10 @@ #### IMPORT LIBRARIES ######################################################### +from esmpy.interface.cbindings import * + from esmpy.api.constants import * from esmpy.util.exceptions import * -from esmpy.interface.cbindings import * from esmpy.util.decorators import initialize import re diff --git a/src/addon/ESMPy/src/esmpy/interface/loadESMF.py b/src/addon/ESMPy/src/esmpy/interface/loadESMF.py index bf791c0c4d..0b57d47775 100644 --- a/src/addon/ESMPy/src/esmpy/interface/loadESMF.py +++ b/src/addon/ESMPy/src/esmpy/interface/loadESMF.py @@ -5,8 +5,10 @@ import os import sys import traceback +import re import esmpy.api.constants as constants +from esmpy.util.exceptions import VersionWarning, VersionMismatch try: import numpy as np @@ -65,6 +67,24 @@ if "gfortran" in line: use_inmem_factors = True +# check and set _ESMF_VERSION_STRING +esmfvs = re.split(r'\D+',esmfversion) +esmpyvs = re.split(r'\D+',constants._ESMPY_VERSION) + +if esmfversion != constants._ESMPY_VERSION: + # check if major, minor and patch version numbers are equivalent + if esmfvs[0:2] != esmpyvs[0:2]: + raise VersionMismatch("ESMF installation version {}, ESMPy version {}".format( + esmfversion, constants._ESMPY_VERSION)) + # otherwise warn that beta versions may be in use + else: + import warnings + warnings.warn("ESMF installation version {}, ESMPy version {}".format( + esmfversion, constants._ESMPY_VERSION), VersionWarning) + +constants._ESMF_VERSION = esmfversion + + if not libsdir: raise ValueError("ESMF_LIBSDIR not found!") if not esmfos: @@ -104,9 +124,6 @@ if "mpiuni" in esmfcomm: constants._ESMF_COMM = constants._ESMF_COMM_MPIUNI -# set _ESMF_VERSION_STRING -constants._ESMF_VERSION = esmfversion - # look for ESMPY_MPIRUN, set accordingly try: constants._ESMF_MPIRUN = os.environ['ESMPY_MPIRUN'] diff --git a/src/addon/ESMPy/src/esmpy/util/exceptions.py b/src/addon/ESMPy/src/esmpy/util/exceptions.py index 206eaae900..746692b6a5 100644 --- a/src/addon/ESMPy/src/esmpy/util/exceptions.py +++ b/src/addon/ESMPy/src/esmpy/util/exceptions.py @@ -10,8 +10,16 @@ class ESMPyException(Exception): """Base class for errors in the ESMPy package.""" pass -class RequiredArgs(ESMPyException): - """Required arguments were not specified.""" +class ESMPyWarning(Warning): + """Base class for warnings in the ESMPy package.""" + pass + +class VersionMismatch(ESMPyException): + """The ESMF installation is not compatible with this version of ESMPy.""" + pass + +class VersionWarning(ESMPyWarning): + """The ESMF and/or ESMPy installations are beta version which may not be fully compatible.""" pass class NetCDFMissing(ESMPyException): @@ -22,6 +30,7 @@ class PIOMissing(ESMPyException): """ESMF was not built with PIO support.""" pass + class MethodNotImplemented(ESMPyException): """Raised when an unimplemented method is called.""" pass @@ -30,6 +39,10 @@ class SerialMethod(ESMPyException): """This method is not safe to run in parallel!""" pass +class RequiredArgs(ESMPyException): + """Required arguments were not specified.""" + pass + class GridException(ESMPyException): """Base class for errors in the Grid class.""" From 458d4a315676a0aaee43028b9434ad556e2b0f70 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Thu, 8 Sep 2022 11:00:39 -0700 Subject: [PATCH 34/45] move test_all.bash to src/esmpy/test --- src/addon/ESMPy/Makefile | 2 +- src/addon/ESMPy/{ => src/esmpy/test}/test_all.bash | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/addon/ESMPy/{ => src/esmpy/test}/test_all.bash (100%) diff --git a/src/addon/ESMPy/Makefile b/src/addon/ESMPy/Makefile index 3129383ef6..e87cd11770 100644 --- a/src/addon/ESMPy/Makefile +++ b/src/addon/ESMPy/Makefile @@ -33,7 +33,7 @@ dryrun_regrid_from_file: dryrun: dryrun_examples dryrun_regrid_from_file test: - bash test_all.bash + bash src/esmpy/test/test_all.bash test_unit: python3 -m pytest -vs diff --git a/src/addon/ESMPy/test_all.bash b/src/addon/ESMPy/src/esmpy/test/test_all.bash similarity index 100% rename from src/addon/ESMPy/test_all.bash rename to src/addon/ESMPy/src/esmpy/test/test_all.bash From 0e17ea875f076741062d858674fc52b0dc2ef99d Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Thu, 8 Sep 2022 11:05:41 -0700 Subject: [PATCH 35/45] fix esmpy skipif marker for inmemory factors with compilers other than GNU --- src/addon/ESMPy/src/esmpy/test/test_api/test_regrid.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/addon/ESMPy/src/esmpy/test/test_api/test_regrid.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_regrid.py index ba515571a9..3f19a3ef9f 100644 --- a/src/addon/ESMPy/src/esmpy/test/test_api/test_regrid.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_regrid.py @@ -85,7 +85,7 @@ def test_field_regrid(self): line_type=LineType.CART, factors=False) _ = rh(srcfield, dstfield) - @pytest.mark.skipif(constants._ESMF_USE_INMEM_FACTORS, reason="compiler does not support in-memory weights") + @pytest.mark.skipif(not constants._ESMF_USE_INMEM_FACTORS, reason="compiler does not support in-memory weights") @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") def test_field_regrid_factor_retrieval(self): # Test retrieving factors from a route handle. From 8a52bc1cd65f8a9131a7c7ae32736c26bac3d295 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Thu, 8 Sep 2022 12:53:21 -0700 Subject: [PATCH 36/45] remove platform specific info from ESMPy test script --- src/addon/ESMPy/src/esmpy/test/test_all.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/addon/ESMPy/src/esmpy/test/test_all.bash b/src/addon/ESMPy/src/esmpy/test/test_all.bash index a2aee0ce57..a847a0d0e1 100644 --- a/src/addon/ESMPy/src/esmpy/test/test_all.bash +++ b/src/addon/ESMPy/src/esmpy/test/test_all.bash @@ -6,7 +6,7 @@ echo "Testing ESMPy ${VERSION}" for NP in 1 4 6 do - REPORT="esmpy${VERSION}-cheyenne-intelmpt-petx${NP}.test" + REPORT="esmpy${VERSION}-petx${NP}.test" COMMAND="mpiexec -n ${NP} python3 -m pytest -vs --json-report --json-report-summary > $REPORT 2>&1" echo ${COMMAND} eval "${COMMAND}" From 9336e59fc2b1f0a2988de280e1ed880667e7b0e5 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Thu, 8 Sep 2022 14:04:47 -0700 Subject: [PATCH 37/45] remove old ESMPy test file --- src/addon/ESMPy/src/esmpy/test/base_test.py | 24 --------------------- 1 file changed, 24 deletions(-) delete mode 100644 src/addon/ESMPy/src/esmpy/test/base_test.py diff --git a/src/addon/ESMPy/src/esmpy/test/base_test.py b/src/addon/ESMPy/src/esmpy/test/base_test.py deleted file mode 100644 index b95a9313d2..0000000000 --- a/src/addon/ESMPy/src/esmpy/test/base_test.py +++ /dev/null @@ -1,24 +0,0 @@ -from esmpy.test.base import TestBase -import numpy as np -from esmpy import Manager - -class Test(TestBase): - - def setup(self): - mg = Manager() - mg.test_exhaustive = False - # mg.barrier() - - def test_assertNumpyAll_bad_mask(self): - arr = np.ma.array([1,2,3],mask=[True,False,True]) - arr2 = np.ma.array([1,2,3],mask=[False,True,False]) - self.assertRaises(AssertionError, lambda: self.assertNumpyAll(arr,arr2)) - - def test_assertNumpyAll_type_differs(self): - arr = np.ma.array([1,2,3],mask=[True,False,True]) - arr2 = np.array([1,2,3]) - self.assertRaises(AssertionError, lambda: self.assertNumpyAll(arr,arr2)) - - def tearDown(self): - mg = Manager() - # mg.barrier() From 1f2363edd8c5f87055d9b885d88c89926f77cb9f Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Thu, 8 Sep 2022 14:05:44 -0700 Subject: [PATCH 38/45] add ESMPy Manager to TestBase --- src/addon/ESMPy/examples/test_examples.py | 10 +++--- src/addon/ESMPy/src/esmpy/test/base.py | 21 ++++++------- .../src/esmpy/test/test_api/test_field.py | 27 ++++++++-------- .../src/esmpy/test/test_api/test_grid.py | 19 ++++++------ .../src/esmpy/test/test_api/test_locstream.py | 4 +-- .../src/esmpy/test/test_api/test_mesh.py | 23 +++++++------- .../src/esmpy/test/test_api/test_regrid.py | 31 +++++++++---------- .../ESMPy/src/esmpy/test/test_api/test_vm.py | 25 +++++++-------- 8 files changed, 77 insertions(+), 83 deletions(-) diff --git a/src/addon/ESMPy/examples/test_examples.py b/src/addon/ESMPy/examples/test_examples.py index 94bdf1a6c9..d3e01accd5 100644 --- a/src/addon/ESMPy/examples/test_examples.py +++ b/src/addon/ESMPy/examples/test_examples.py @@ -14,7 +14,7 @@ # Start up esmpy mg = Manager(debug=True) -if mg.pet_count == 1: +if pet_count() == 1: from esmpy.util.cache_data import cache_data_files cache_data_files() @@ -33,17 +33,17 @@ def test_field_read(self): def test_grid_create_peridim_mask(self): from . import grid_create_peridim_mask - @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_locstream_regrid(self): from . import grid_locstream_regrid - @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_locstream_grid_regrid(self): from . import locstream_grid_regrid - @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") def test_mesh_locstream_regrid(self): from . import mesh_locstream_regrid @@ -68,7 +68,7 @@ def test_ungridded_dimension_regrid(self): # this will currently never run because it isn't yet possible to run pytest with mpiexec @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") - @pytest.mark.skipif(mg.pet_count!=6, reason="test must be run with 6 cores") + @pytest.mark.skipif(pet_count()!=6, reason="test must be run with 6 cores") def test_cubed_sphere_to_mesh_regrid(self): from . import cubed_sphere_to_mesh_regrid diff --git a/src/addon/ESMPy/src/esmpy/test/base.py b/src/addon/ESMPy/src/esmpy/test/base.py index 1bfcd785e7..28bd37ff37 100644 --- a/src/addon/ESMPy/src/esmpy/test/base.py +++ b/src/addon/ESMPy/src/esmpy/test/base.py @@ -1,23 +1,22 @@ import unittest import numpy as np from esmpy.util.itester import iter_product_keywords +from esmpy.api.esmpymanager import Manager class TestBase(unittest.TestCase): - # mg = None + @property + def mg(self): + """ + :rtype: :class:`~esmpy.api.esmpymanager.Manager` + :return: :class:`~esmpy.api.esmpymanager.Manager` + """ + return self._mg def __init__(self, *args, **kwds): super(TestBase, self).__init__(*args, **kwds) - - # @classmethod - # def setUpClass(cls): - # import esmpy - # cls.mg = esmpy.Manager(debug = True) - # cls.mg.test_exhaustive = False - # - # @classmethod - # def tearDownClass(cls): - # del cls.mg + self._mg = Manager(debug = True) + self._mg.test_exhaustive = False def assertNumpyAll(self, arr1, arr2, check_fill_value_dtype=True, check_arr_dtype=True): """ diff --git a/src/addon/ESMPy/src/esmpy/test/test_api/test_field.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_field.py index f7314c34bc..1a443e0d05 100644 --- a/src/addon/ESMPy/src/esmpy/test/test_api/test_field.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_field.py @@ -11,6 +11,7 @@ class TestField(TestBase): + # prefer TestBase.mg, but in this case required for test_exhaustive in pytest markers mg = Manager(debug=True) mg.test_exhaustive = False @@ -71,7 +72,7 @@ def test_meta_del(self): del (self.field) assert (not hasattr(self, 'field')) - @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def test_numpy_funcs(self): field = self.make_field(np.array([10, 10], dtype=np.int32)) @@ -98,7 +99,7 @@ def test_numpy_funcs(self): @pytest.mark.skipif(mg.test_exhaustive==False, reason="only run in exhaustive mode") - @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def _field_create_2d_grid(self): keywords = dict( # periodic specifies all valid combos of [num_peri_dims, periodic_dim, pole_dim] @@ -148,7 +149,7 @@ def _field_create_2d_grid(self): "The following combinations of parameters failed to create a proper Field: " + str(fail)) @pytest.mark.skipif(mg.test_exhaustive==False, reason="only run in exhaustive mode") - @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def _field_create_3d_grid(self): keywords = dict( # periodic specifies all valid combos of [num_peri_dims, periodic_dim, pole_dim] @@ -200,7 +201,7 @@ def _field_create_3d_grid(self): "The following combinations of parameters failed to create a proper Field: " + str(len(fail))) @pytest.mark.skipif(mg.test_exhaustive==False, reason="only run in exhaustive mode") - @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") def _field_create_2d_mesh(self): keywords = dict( meshloc=[MeshLoc.NODE, MeshLoc.ELEMENT], @@ -276,7 +277,7 @@ def create_field(gml, name): return field - @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") def test_field_uniqueness(self): mesh = None if (pet_count() == 4): @@ -300,7 +301,7 @@ def test_field_uniqueness(self): assert (field.struct.ptr != field2.struct.ptr) - @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def test_field_area(self): grid = Grid(np.array([3, 4]), staggerloc=[StaggerLoc.CENTER, StaggerLoc.CORNER], coord_sys=CoordSys.SPH_DEG, num_peri_dims=1, @@ -336,7 +337,7 @@ def test_field_area(self): assert(np.all(field.data == field2.data)) - @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def test_field_locstream_mask(self): # LocStream creation and simple validation locstream = LocStream(5, name="Test LocStream") @@ -389,7 +390,7 @@ def test_field_extradims_grid(self): field2.data[...] = 10 self.examine_field_attributes(field2) - @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") def test_field_extradims_mesh(self): mesh = None if (pet_count() == 4): @@ -408,7 +409,7 @@ def test_field_extradims_mesh(self): field2.data[...] = 10 self.examine_field_attributes(field2) - @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def test_field_slice_grid(self): typekind = TypeKind.R8 grid = Grid(np.array([100, 100]), coord_sys=CoordSys.CART, @@ -448,7 +449,7 @@ def test_field_slice_grid(self): assert (field3.grid.upper_bounds[0].tolist() == [2, 2]) # slicing is disabled in parallel - @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def test_field_slice_mesh(self): mesh = None if pet_count() > 1: @@ -479,7 +480,7 @@ def test_field_slice_mesh(self): assert (field2.grid.size[0] == 5) assert (field3.grid.size[0] == 2) - @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def test_field_slice_grid_extraindices(self): n = 10 grid = Grid(np.array([n,n]), coord_sys=CoordSys.CART, staggerloc=StaggerLoc.CENTER) @@ -517,7 +518,7 @@ def test_field_slice_grid_extraindices(self): assert (field2.grid.upper_bounds[0].tolist() == [5, 5]) assert (field3.grid.upper_bounds[0].tolist() == [2, 2]) - @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def disable_est_field_slice_mesh_extraindices(self): mesh, nodeCoord, nodeOwner, elemType, elemConn, elemCoord = mesh_create_50() @@ -539,7 +540,7 @@ def disable_est_field_slice_mesh_extraindices(self): assert field2.data.shape == (5, 2, 1) assert field3.data.shape == (2, 1, 1) - @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def test_field_reshape(self): field = self.make_field(np.array([10, 10], dtype=np.int32), ndbounds=False) diff --git a/src/addon/ESMPy/src/esmpy/test/test_api/test_grid.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_grid.py index 2452e046c0..300c810f9a 100644 --- a/src/addon/ESMPy/src/esmpy/test/test_api/test_grid.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_grid.py @@ -16,9 +16,10 @@ class TestGrid(TestBase): + # prefer TestBase.mg, but in this case required for test_exhaustive in pytest markers mg = Manager(debug=True) mg.test_exhaustive = False - + def examine_grid_attributes(self, grid): # ~~~~~~~~~~~~~~~~~~~~~~ STAGGER LOCATIONS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # grid.staggerloc returns a boolean list of the activated stagger locations @@ -181,7 +182,7 @@ def test_grid_periodic(self): self.examine_grid_attributes(grid) @pytest.mark.skipif(mg.test_exhaustive==False, reason="only run in exhaustive mode") - @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def test_grid_create_2d(self): keywords = dict( # periodic specifies all valid combos of [pole_kind, num_peri_dims, periodic_dim, pole_dim] @@ -227,7 +228,7 @@ def test_grid_create_2d(self): "The following combinations of Grid parameters failed to create a proper Grid: " + str(fail)) @pytest.mark.skipif(mg.test_exhaustive==False, reason="only run in exhaustive mode") - @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def test_grid_create_3d(self): keywords = dict( # periodic specifies all valid combos of [num_peri_dims, periodic_dim, pole_dim] @@ -296,7 +297,7 @@ def test_grid_create_cubed_sphere(self): grid.destroy() # grid2.destroy() - @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def test_grid_slice_2d(self): grid = self.make_grid_2d() @@ -316,7 +317,7 @@ def test_grid_slice_2d(self): assert grid3.coords[StaggerLoc.CENTER][0].shape == (2, 1) assert grid3.upper_bounds[StaggerLoc.CENTER].tolist() == [2, 1] - @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def test_grid_slice_2d_corners(self): grid = self.make_grid_2d() @@ -347,7 +348,7 @@ def test_grid_slice_2d_corners(self): assert grid3.upper_bounds[StaggerLoc.CORNER].tolist() == [3, 2] - @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def test_grid_slice_3d(self): grid = self.make_grid_3d() @@ -367,7 +368,7 @@ def test_grid_slice_3d(self): assert grid3.coords[StaggerLoc.CENTER][0].shape == (2, 1, 2) assert grid3.upper_bounds[StaggerLoc.CENTER].tolist() == [2, 1, 2] - @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def test_grid_slice_3d_corners(self): grid = self.make_grid_3d() @@ -402,7 +403,7 @@ def test_grid_slice_3d_corners(self): assert grid3.coords[cvf][0].shape == (3, 2, 3) assert grid3.upper_bounds[cvf].tolist() == [3, 2, 3] - @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def test_grid_slice_periodic(self): grid, x, y = self.make_grid_periodic() @@ -429,7 +430,7 @@ def test_grid_slice_periodic(self): assert grid3.upper_bounds[StaggerLoc.CORNER].tolist() == [3, 2] @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") - @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def test_slice_grid_created_from_file_scrip(self): import esmpy reg_decomp = [pet_count(), 1] diff --git a/src/addon/ESMPy/src/esmpy/test/test_api/test_locstream.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_locstream.py index 7ec83755b9..ea9b71bbaa 100644 --- a/src/addon/ESMPy/src/esmpy/test/test_api/test_locstream.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_locstream.py @@ -10,8 +10,6 @@ class TestLocStream(TestBase): - mg = Manager(debug=True) - def test_create(self): # LocStream creation and simple validation locstream = LocStream(5, name="Test LocStream") @@ -53,7 +51,7 @@ def test_copy(self): assert np.all(l2["ESMF:X"] == [0, 1, 2, 3, 4]) - @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def test_slice(self): locstream = LocStream(5, name="Test LocStream") diff --git a/src/addon/ESMPy/src/esmpy/test/test_api/test_mesh.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_mesh.py index 41b87d4bb8..88a537e642 100644 --- a/src/addon/ESMPy/src/esmpy/test/test_api/test_mesh.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_mesh.py @@ -14,7 +14,6 @@ from esmpy.util.mesh_utilities import * class TestMesh(TestBase): - mg = Manager(debug=True) def check_mesh(self, mesh, nodeCoord, nodeOwner, elemCoord=None): @@ -47,7 +46,7 @@ def check_mesh(self, mesh, nodeCoord, nodeOwner, elemCoord=None): # this call fails if nodes and elements have not been added first # mesh.free_memory() - @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") def test_mesh_5(self): elemCoord = None parallel = False @@ -60,7 +59,7 @@ def test_mesh_5(self): self.check_mesh(mesh, nodeCoord, nodeOwner, elemCoord=elemCoord) - @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") def test_mesh_10(self): elemCoord = None parallel = False @@ -73,7 +72,7 @@ def test_mesh_10(self): self.check_mesh(mesh, nodeCoord, nodeOwner, elemCoord=elemCoord) - @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") def test_mesh_50(self): elemCoord = None parallel = False @@ -86,7 +85,7 @@ def test_mesh_50(self): self.check_mesh(mesh, nodeCoord, nodeOwner, elemCoord=elemCoord) - @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") def test_mesh_50_moab(self): # set this mesh to be created with the MOAB backend mg = Manager() @@ -111,7 +110,7 @@ def test_mesh_50_moab(self): assert (mg.moab == False) - @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") def test_mesh_50_ngons(self): parallel = False if pet_count() == 4: @@ -123,7 +122,7 @@ def test_mesh_50_ngons(self): self.check_mesh(mesh, nodeCoord, nodeOwner) - @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") def test_mesh_50_mask_area(self): elemCoord = None parallel = False @@ -154,7 +153,7 @@ def test_mesh_create_from_file_esmfmesh(self): mesh_from_file = Mesh(filename=os.path.join(esmfdir, "test/data/ne4np4-esmf.nc"), filetype=FileFormat.ESMFMESH) - @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") def test_mesh_copy(self): if pet_count() == 4: mesh, nodeCoord, nodeOwner, elemType, elemConn = \ @@ -169,7 +168,7 @@ def test_mesh_copy(self): self.check_mesh(mesh2, nodeCoord, nodeOwner) # slicing is disabled in parallel - @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def test_mesh_slicing(self): mesh, nodeCoord, nodeOwner, elemType, elemConn = \ mesh_create_5_pentahexa() @@ -195,7 +194,7 @@ def test_mesh_slicing(self): @pytest.mark.skipif(_ESMF_PIO==False, reason="PIO required in ESMF build") @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") - @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def test_slice_mesh_created_from_file_scrip(self): esmfdir = os.path.dirname(inspect.getfile(esmpy)) mesh = Mesh(filename=os.path.join(esmfdir, "test/data/ne4np4-pentagons.nc"), @@ -217,7 +216,7 @@ def test_slice_mesh_created_from_file_scrip(self): @pytest.mark.skipif(_ESMF_PIO==False, reason="PIO required in ESMF build") @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") - @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def test_slice_mesh_created_from_file_esmfmesh(self): esmfdir = os.path.dirname(inspect.getfile(esmpy)) mesh = Mesh(filename=os.path.join(esmfdir, "test/data/ne4np4-esmf.nc"), @@ -239,7 +238,7 @@ def test_slice_mesh_created_from_file_esmfmesh(self): @pytest.mark.xfail @pytest.mark.skipif(_ESMF_PIO==False, reason="PIO required in ESMF build") @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") - @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") #TODO: remove expected failure once we have a smaller data file with mesh element coordinates to use # TODO: have to define slicing for mesh element coordinates as well.. def test_slice_mesh_created_from_file_elem_coords(self): diff --git a/src/addon/ESMPy/src/esmpy/test/test_api/test_regrid.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_regrid.py index 3f19a3ef9f..88a43f0c69 100644 --- a/src/addon/ESMPy/src/esmpy/test/test_api/test_regrid.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_regrid.py @@ -16,9 +16,6 @@ class TestRegrid(TestBase): - mg = Manager(debug=True) - mg.test_exhaustive = False - def run_regridding(srcfield, dstfield, srcfracfield, dstfracfield): # This is for documentation. Do not modify. ''' @@ -86,7 +83,7 @@ def test_field_regrid(self): _ = rh(srcfield, dstfield) @pytest.mark.skipif(not constants._ESMF_USE_INMEM_FACTORS, reason="compiler does not support in-memory weights") - @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def test_field_regrid_factor_retrieval(self): # Test retrieving factors from a route handle. @@ -565,7 +562,7 @@ def test_field_regrid_file4(self): if os.path.isfile(path): os.remove(path) - @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") def test_field_regrid_gridmesh(self): mesh = None if pet_count() == 4: @@ -602,7 +599,7 @@ def test_field_regrid_gridmesh(self): rh = Regrid(srcfield, dstfield, regrid_method=RegridMethod.CONSERVE) dstfield = rh(srcfield, dstfield) - @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") def test_field_regrid_zeroregion(self): mesh = None if pet_count() == 4: @@ -694,7 +691,7 @@ def test_field_regrid_zeroregion_select_ndbounds(self): if os.path.exists(filename): os.remove(filename) - @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") def test_field_regrid_area(self): mesh = None if pet_count() == 4: @@ -994,7 +991,7 @@ def test_grid_grid_regrid_srcmask_types(self): self.assertAlmostEqual(meanrel, 0.0024803189848013785) self.assertAlmostEqual(csrvrel, 0.0) - @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") def test_grid_mesh_regrid_csrv_mask(self): mesh = None if pet_count() == 4: @@ -1044,7 +1041,7 @@ def test_grid_mesh_regrid_csrv_mask(self): self.assertAlmostEqual(meanrel, 0.038806630051265847) self.assertAlmostEqual(csrvrel, 0.0) - @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") def test_grid_mesh_regrid_csrv(self): mesh = None if pet_count() == 4: @@ -1092,7 +1089,7 @@ def test_grid_mesh_regrid_csrv(self): self.assertAlmostEqual(meanrel, 0.037733241800767432) self.assertAlmostEqual(csrvrel, 0.0) - @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") def test_grid_mesh_regrid_mask(self): # create a grid grid = grid_create_from_bounds([0, 4], [0, 4], 8, 8, corners=True, domask=True) @@ -1129,7 +1126,7 @@ def test_grid_mesh_regrid_mask(self): self.assertAlmostEqual(meanrel, 0.0) self.assertAlmostEqual(csrvrel, 0.0) - @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") def test_grid_mesh_regrid(self): # create a grid grid = grid_create_from_bounds([0, 4], [0, 4], 8, 8, corners=True) @@ -1165,7 +1162,7 @@ def test_grid_mesh_regrid(self): self.assertAlmostEqual(meanrel, 0.0) self.assertAlmostEqual(csrvrel, 0.0) - @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") def test_field_regrid_extrapolation(self): # create a grid grid = grid_create_from_bounds([0, 4], [0, 4], 8, 8, corners=True) @@ -1204,7 +1201,7 @@ def test_field_regrid_extrapolation(self): self.assertAlmostEqual(meanrel, 0.0) self.assertAlmostEqual(csrvrel, 0.0) - @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") def test_field_regrid_extrapolation_creepfill(self): # create a grid grid = grid_create_from_bounds([0, 4], [0, 4], 8, 8, corners=True) @@ -1241,7 +1238,7 @@ def test_field_regrid_extrapolation_creepfill(self): self.assertAlmostEqual(meanrel, 0.0) self.assertAlmostEqual(csrvrel, 0.0) - @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") def test_mesh_mesh_regrid(self): srcmesh = None dstmesh = None @@ -1294,7 +1291,7 @@ def test_mesh_mesh_regrid(self): self.assertAlmostEqual(meanrel, 0.037109375) self.assertAlmostEqual(csrvrel, 0.0) - @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") def est_grid_mesh_pentatri_regrid_csrv(self): mesh = None if pet_count() == 4: @@ -1345,7 +1342,7 @@ def est_grid_mesh_pentatri_regrid_csrv(self): assert (meanrel < 10E-2) assert (csrvrel < 10E-14) - @pytest.mark.skipif(mg.pet_count!=1, reason="test must be run in serial") + @pytest.mark.skipif(pet_count()!=1, reason="test must be run in serial") def est_grid_mesh_pentatri_regrid_csrv_simple(self): # create a Mesh mesh, nodeCoord, nodeOwner, elemType, elemConn = \ @@ -1392,7 +1389,7 @@ def est_grid_mesh_pentatri_regrid_csrv_simple(self): assert (meanrel < 10E-2) assert (csrvrel < 10E-14) - @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") def test_grid_mesh_pentatri_regrid_bilinear(self): mesh = None if pet_count() == 4: diff --git a/src/addon/ESMPy/src/esmpy/test/test_api/test_vm.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_vm.py index 7fd61057b7..c06cbe1121 100644 --- a/src/addon/ESMPy/src/esmpy/test/test_api/test_vm.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_vm.py @@ -9,23 +9,22 @@ class TestVM(TestBase): def test_vm_broadcast(self): - mg = Manager() bcst = np.ones(4, dtype=np.float64) - if mg.local_pet != 0: + if self.mg.local_pet != 0: bcst[:] = 2 - if mg.local_pet == 0: + if self.mg.local_pet == 0: assert(np.all(bcst == 1)) else: assert(np.all(bcst == 2)) - mg.barrier() - mg._broadcast_(bcst, 4) - mg.barrier() + self.mg.barrier() + self.mg._broadcast_(bcst, 4) + self.mg.barrier() assert(np.all(bcst == 1)) - mg.barrier() + self.mg.barrier() def test_vm_reduce(self): send = np.ones(4, dtype=np.float64) @@ -33,13 +32,13 @@ def test_vm_reduce(self): mg = Manager() - mg.barrier() - mg._reduce_(send, recv, 4, Reduce.SUM, 0) - mg.barrier() + self.mg.barrier() + self.mg._reduce_(send, recv, 4, Reduce.SUM, 0) + self.mg.barrier() - if mg.local_pet == 0: - assert(np.all(recv == mg.pet_count)) + if self.mg.local_pet == 0: + assert(np.all(recv == self.mg.pet_count)) else: assert(np.all(recv == 0)) - mg.barrier() + self.mg.barrier() From cc821abd0720e46d857724b79a4bdeab70a4732e Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Thu, 8 Sep 2022 14:11:29 -0700 Subject: [PATCH 39/45] add file to test pytest functionality in question --- .../src/esmpy/test/test_api/test_pytest.py | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/addon/ESMPy/src/esmpy/test/test_api/test_pytest.py diff --git a/src/addon/ESMPy/src/esmpy/test/test_api/test_pytest.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_pytest.py new file mode 100644 index 0000000000..c4e7560708 --- /dev/null +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_pytest.py @@ -0,0 +1,28 @@ +""" +pytest tests +""" + +import pytest + +from esmpy.test.base import TestBase +from esmpy.api.esmpymanager import pet_count + +class TestPyTest(TestBase): + + @pytest.mark.xfail + @pytest.mark.skipif(pet_count()<3, reason="test must be run with more than 3 cores") + def test_pytest_2(self): + + print ("Test2: I AM PET {}".format(self.mg.local_pet)) + + if self.mg.local_pet == 2: + raise ValueError("Test failure on a single PET") + + @pytest.mark.mpi(min_size=2) + def test_pytest_1(self): + from mpi4py import MPI + + comm = MPI.COMM_WORLD + rank = comm.Get_rank() + + print ("Test1: I AM PET {} and rank {}".format(local_pet(), rank)) From 94489e281e0fc6e78291edf00506b76e1302b813 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Thu, 8 Sep 2022 14:23:34 -0700 Subject: [PATCH 40/45] better pytest names --- src/addon/ESMPy/src/esmpy/test/test_api/test_pytest.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/addon/ESMPy/src/esmpy/test/test_api/test_pytest.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_pytest.py index c4e7560708..e3516f4c95 100644 --- a/src/addon/ESMPy/src/esmpy/test/test_api/test_pytest.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_pytest.py @@ -11,7 +11,7 @@ class TestPyTest(TestBase): @pytest.mark.xfail @pytest.mark.skipif(pet_count()<3, reason="test must be run with more than 3 cores") - def test_pytest_2(self): + def test_pytest_singlecorefailure(self): print ("Test2: I AM PET {}".format(self.mg.local_pet)) @@ -19,7 +19,7 @@ def test_pytest_2(self): raise ValueError("Test failure on a single PET") @pytest.mark.mpi(min_size=2) - def test_pytest_1(self): + def test_pytest_mpi4py(self): from mpi4py import MPI comm = MPI.COMM_WORLD From 2aa5d4dfcd00933112a7f141c51a16ab12c32359 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Fri, 9 Sep 2022 12:04:28 -0700 Subject: [PATCH 41/45] add a missing esmpy symbol --- src/addon/ESMPy/examples/test_examples.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/addon/ESMPy/examples/test_examples.py b/src/addon/ESMPy/examples/test_examples.py index d3e01accd5..94bdf1a6c9 100644 --- a/src/addon/ESMPy/examples/test_examples.py +++ b/src/addon/ESMPy/examples/test_examples.py @@ -14,7 +14,7 @@ # Start up esmpy mg = Manager(debug=True) -if pet_count() == 1: +if mg.pet_count == 1: from esmpy.util.cache_data import cache_data_files cache_data_files() @@ -33,17 +33,17 @@ def test_field_read(self): def test_grid_create_peridim_mask(self): from . import grid_create_peridim_mask - @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_grid_locstream_regrid(self): from . import grid_locstream_regrid - @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") def test_locstream_grid_regrid(self): from . import locstream_grid_regrid - @pytest.mark.skipif(pet_count() not in {1, 4}, reason="test requires 1 or 4 cores") + @pytest.mark.skipif(mg.pet_count not in {1, 4}, reason="test requires 1 or 4 cores") def test_mesh_locstream_regrid(self): from . import mesh_locstream_regrid @@ -68,7 +68,7 @@ def test_ungridded_dimension_regrid(self): # this will currently never run because it isn't yet possible to run pytest with mpiexec @pytest.mark.skipif(_ESMF_NETCDF==False, reason="NetCDF required in ESMF build") - @pytest.mark.skipif(pet_count()!=6, reason="test must be run with 6 cores") + @pytest.mark.skipif(mg.pet_count!=6, reason="test must be run with 6 cores") def test_cubed_sphere_to_mesh_regrid(self): from . import cubed_sphere_to_mesh_regrid From 1d6d93476c257673b34af88e7a154bb418639920 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Fri, 9 Sep 2022 19:15:42 -0700 Subject: [PATCH 42/45] change esmpy dryrun target to download --- src/addon/ESMPy/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/addon/ESMPy/Makefile b/src/addon/ESMPy/Makefile index e87cd11770..15fc33f6d6 100644 --- a/src/addon/ESMPy/Makefile +++ b/src/addon/ESMPy/Makefile @@ -24,13 +24,13 @@ dust: install: python3 -m pip install . -dryrun_examples: +download_examples: python3 examples/test_examples_dryrun.py -dryrun_regrid_from_file: +download_regrid_from_file: python3 src/esmpy/test/regrid_from_file/test_regrid_from_file_dryrun.py -dryrun: dryrun_examples dryrun_regrid_from_file +download: download_examples download_regrid_from_file test: bash src/esmpy/test/test_all.bash From 074e4bf86527126fd5ab7ab66edd8a6250d78e24 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Fri, 9 Sep 2022 19:17:46 -0700 Subject: [PATCH 43/45] remove pytest that require pytest-mpi --- .../src/esmpy/test/test_api/test_pytest.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/addon/ESMPy/src/esmpy/test/test_api/test_pytest.py b/src/addon/ESMPy/src/esmpy/test/test_api/test_pytest.py index e3516f4c95..a8184efd60 100644 --- a/src/addon/ESMPy/src/esmpy/test/test_api/test_pytest.py +++ b/src/addon/ESMPy/src/esmpy/test/test_api/test_pytest.py @@ -18,11 +18,12 @@ def test_pytest_singlecorefailure(self): if self.mg.local_pet == 2: raise ValueError("Test failure on a single PET") - @pytest.mark.mpi(min_size=2) - def test_pytest_mpi4py(self): - from mpi4py import MPI - - comm = MPI.COMM_WORLD - rank = comm.Get_rank() - - print ("Test1: I AM PET {} and rank {}".format(local_pet(), rank)) + # # this requires pytest-mpi package + # @pytest.mark.mpi(min_size=2) + # def test_pytest_mpi4py(self): + # from mpi4py import MPI + # + # comm = MPI.COMM_WORLD + # rank = comm.Get_rank() + # + # print ("Test1: I AM PET {} and rank {}".format(local_pet(), rank)) From 2626e0053622cd90da7d2ad9011efd4c3d00ef97 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Fri, 9 Sep 2022 19:34:29 -0700 Subject: [PATCH 44/45] add optional dataurl command line argument to esmpy data download scripts --- src/addon/ESMPy/examples/test_examples_dryrun.py | 9 ++++++++- .../test_regrid_from_file_dryrun.py | 13 ++++++++++--- src/addon/ESMPy/src/esmpy/util/cache_data.py | 11 ++++++----- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/addon/ESMPy/examples/test_examples_dryrun.py b/src/addon/ESMPy/examples/test_examples_dryrun.py index 14319d7b86..4c25b40f9e 100644 --- a/src/addon/ESMPy/examples/test_examples_dryrun.py +++ b/src/addon/ESMPy/examples/test_examples_dryrun.py @@ -4,5 +4,12 @@ examples data dryrun """ +import sys + from esmpy.util.cache_data import cache_data_files -cache_data_files() + +DATAURL = None +if len(sys.argv) > 1: + DATAURL = sys.argv[1] + +cache_data_files(DATAURL) diff --git a/src/addon/ESMPy/src/esmpy/test/regrid_from_file/test_regrid_from_file_dryrun.py b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/test_regrid_from_file_dryrun.py index 99d415aee6..94c4d5c384 100644 --- a/src/addon/ESMPy/src/esmpy/test/regrid_from_file/test_regrid_from_file_dryrun.py +++ b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/test_regrid_from_file_dryrun.py @@ -11,15 +11,18 @@ import sys import os -from esmpy.test.regrid_from_file.regrid_from_file_consts import DATA_SUBDIR, DATA_URL_ROOT +from esmpy.test.regrid_from_file.regrid_from_file_consts import DATA_SUBDIR from esmpy.util.cache_data import cache_data_file from esmpy.test.regrid_from_file.read_test_cases_from_control_file import read_control_file -def cache_data_files_for_test_cases(test_cases): +def cache_data_files_for_test_cases(test_cases, DATA_URL_ROOT=None): # Create data subdirectory if it doesn't exist. if not os.path.exists(DATA_SUBDIR): os.mkdir(DATA_SUBDIR) + if DATA_URL_ROOT == None: + DATA_URL_ROOT = 'http://data.earthsystemmodeling.org/download/data/' + # For each test case line from the control file parse the line and call # the test subroutine. status_ok = True @@ -36,8 +39,12 @@ def cache_data_files_for_test_cases(test_cases): break return status_ok +DATAURL = None +if len(sys.argv) > 1: + DATAURL = sys.argv[1] + # Read the test case parameters from the control file. test_cases = read_control_file() # Retrieve the data files needed for the test cases from the remote server. -cache_data_files_for_test_cases(test_cases) +cache_data_files_for_test_cases(test_cases, DATAURL) diff --git a/src/addon/ESMPy/src/esmpy/util/cache_data.py b/src/addon/ESMPy/src/esmpy/util/cache_data.py index 4b414209f3..ab3171bfb6 100644 --- a/src/addon/ESMPy/src/esmpy/util/cache_data.py +++ b/src/addon/ESMPy/src/esmpy/util/cache_data.py @@ -1,9 +1,7 @@ import os -DATA_URL_ROOT = 'http://data.earthsystemmodeling.org/download/data/' - # If fname doesn't exist, retrieve it from the remote server via http. -def cache_data_file(fname, DATA_URL_ROOT=DATA_URL_ROOT): +def cache_data_file(fname, DATA_URL_ROOT=None): import sys if sys.version_info[0] >= 3: from urllib.request import urlopen, URLError @@ -12,6 +10,9 @@ def cache_data_file(fname, DATA_URL_ROOT=DATA_URL_ROOT): from shutil import copyfileobj + if DATA_URL_ROOT == None: + DATA_URL_ROOT = 'http://data.earthsystemmodeling.org/download/data/' + status_ok = True if not os.path.exists(fname): url = os.path.join(DATA_URL_ROOT, os.path.basename(fname)) @@ -30,7 +31,7 @@ def cache_data_file(fname, DATA_URL_ROOT=DATA_URL_ROOT): return status_ok -def cache_data_files(): +def cache_data_files(dataurl=None): # Filenames to download. datafilelist = ["aggregAtlanticESTOFS.nc", "GRIDSPEC_ACCESS1.nc", @@ -49,6 +50,6 @@ def cache_data_files(): # Download each test file. for fname in datafilelist: # Retrieve the data files needed for the test cases from the remote server. - status_ok = cache_data_file(os.path.join(datadir, fname)) + status_ok = cache_data_file(os.path.join(datadir, fname), dataurl) if not status_ok: raise IOError("Error downloading '{}'".format(fname)) From 08f639de3e3c5ba460640b72299ea5010e2f3fd3 Mon Sep 17 00:00:00 2001 From: Ryan O'Kuinghttons Date: Mon, 12 Sep 2022 09:55:30 -0700 Subject: [PATCH 45/45] change dryrun to download in esmpy file names_ --- src/addon/ESMPy/Makefile | 4 ++-- src/addon/ESMPy/doc/install.rst | 9 +++++---- ...test_examples_dryrun.py => test_examples_download.py} | 2 +- .../esmpy/test/regrid_from_file/test_regrid_from_file.py | 2 +- ..._file_dryrun.py => test_regrid_from_file_download.py} | 0 5 files changed, 9 insertions(+), 8 deletions(-) rename src/addon/ESMPy/examples/{test_examples_dryrun.py => test_examples_download.py} (88%) rename src/addon/ESMPy/src/esmpy/test/regrid_from_file/{test_regrid_from_file_dryrun.py => test_regrid_from_file_download.py} (100%) diff --git a/src/addon/ESMPy/Makefile b/src/addon/ESMPy/Makefile index 15fc33f6d6..2eb768b263 100644 --- a/src/addon/ESMPy/Makefile +++ b/src/addon/ESMPy/Makefile @@ -25,10 +25,10 @@ install: python3 -m pip install . download_examples: - python3 examples/test_examples_dryrun.py + python3 examples/test_examples_download.py download_regrid_from_file: - python3 src/esmpy/test/regrid_from_file/test_regrid_from_file_dryrun.py + python3 src/esmpy/test/regrid_from_file/test_regrid_from_file_download.py download: download_examples download_regrid_from_file diff --git a/src/addon/ESMPy/doc/install.rst b/src/addon/ESMPy/doc/install.rst index dbd79dd29a..fa514d782f 100644 --- a/src/addon/ESMPy/doc/install.rst +++ b/src/addon/ESMPy/doc/install.rst @@ -118,10 +118,11 @@ greater test coverage is desired: .. Note:: - The ``regrid_from_file`` tests can take up a lot of memory and bandwidth. - The ``test_regrid_from_file_dryrun`` command will simply download the test - files without actually running them (allowing the stress on the machine to - be applied to bandwidth first, and then memory). + The ``regrid_from_file`` and ``example`` tests can take up a lot of memory + and bandwidth. The ``download_regrid_from_file`` and ``download_examples`` + commands will simply download the test files without actually running them + (allowing the stress on the machine to be applied to bandwidth first, and + then memory). ----------- Limitations diff --git a/src/addon/ESMPy/examples/test_examples_dryrun.py b/src/addon/ESMPy/examples/test_examples_download.py similarity index 88% rename from src/addon/ESMPy/examples/test_examples_dryrun.py rename to src/addon/ESMPy/examples/test_examples_download.py index 4c25b40f9e..ac6c18da48 100644 --- a/src/addon/ESMPy/examples/test_examples_dryrun.py +++ b/src/addon/ESMPy/examples/test_examples_download.py @@ -1,7 +1,7 @@ # $Id$ """ -examples data dryrun +examples data download """ import sys diff --git a/src/addon/ESMPy/src/esmpy/test/regrid_from_file/test_regrid_from_file.py b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/test_regrid_from_file.py index 37ac3e70da..7c5a648fb4 100644 --- a/src/addon/ESMPy/src/esmpy/test/regrid_from_file/test_regrid_from_file.py +++ b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/test_regrid_from_file.py @@ -26,7 +26,7 @@ mg = Manager(debug=True) if mg.pet_count == 1: - import esmpy.test.regrid_from_file.test_regrid_from_file_dryrun + import esmpy.test.regrid_from_file.test_regrid_from_file_download # Read the test case parameters from the control file. print('Reading control file...') diff --git a/src/addon/ESMPy/src/esmpy/test/regrid_from_file/test_regrid_from_file_dryrun.py b/src/addon/ESMPy/src/esmpy/test/regrid_from_file/test_regrid_from_file_download.py similarity index 100% rename from src/addon/ESMPy/src/esmpy/test/regrid_from_file/test_regrid_from_file_dryrun.py rename to src/addon/ESMPy/src/esmpy/test/regrid_from_file/test_regrid_from_file_download.py