-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cartesian grid generation #32
Conversation
initial commit
util/pace/util/grid/generation.py
Outdated
|
||
# TODO: following lines just fill fields with nan | ||
# presumably these aren't needed other than for testing | ||
# so best to get rid of them to reduce memory pressure? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
Can you pass a "fill_all_fields" option to the __init__
default to False
that's flipped for test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
Look at putting non-required floats on a bool
for test only
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commenting for now with some small tweaks that could make the code a bit neater and more optimized. The init_cartesian method does work under a different paradigm than the non-cartesian initialization, so I want to think a bit about that
util/pace/util/grid/generation.py
Outdated
self._dx, self._dy = self._compute_dxdy_cartesian() | ||
self._dx_agrid, self._dy_agrid = self._compute_dxdy_agrid_cartesian() | ||
self._dx_center, self._dy_center = self._compute_dxdy_center_cartesian() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since dx, dxc, and dxa are all the same on an orthogonal grid I think you could consolidate these into one _set_dxdy_cartesian
method
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have three separate methods because _dx
, _dx_agrid
, and _dx_center
(for example) sit at different locations on the grid. Could still work on reducing code duplication if you think that's worthwhile, e.g. with a single method like
def _compute_dxdy_cartesian(self, dx_dims, dy_dims):
dx_64 = self.quantity_factory.zeros(dx_dims, ...)
that can handle all three cases.
util/pace/util/grid/generation.py
Outdated
self._area = self._compute_area_cartesian() | ||
self._area_c = self._compute_area_c_cartesian() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to the dx/dy computation above, these areas are also the same so you could have one _set_area_cartesian
method that can do either/both of these instead of two separate methods
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above: areas sit at different locations, but could still reduce code duplication.
Co-authored-by: Oliver Elbert <[email protected]>
Co-authored-by: Oliver Elbert <[email protected]>
Co-authored-by: Oliver Elbert <[email protected]>
Co-authored-by: Oliver Elbert <[email protected]>
One alternative: could modify @property
def dx(self) -> util.Quantity:
"""
the distance between grid corners along the x-direction
"""
if self._dx is None:
self._dx, self._dy = self._compute_dxdy_cartesian() if self._is_cartesian else self._compute_dxdy()
return self._dx |
On reflection I think this would be my preference. If the metric terms generation works the same way for each grid type that makes things much simpler to deal with if we need to revisit or modify it going forward. |
I just pushed a commit with this change. Let me know what you think. A couple of thoughts:
self._dx, self._dy = (
self._compute_dxdy_cartesian()
if self._is_cartesian
else self._compute_dxdy()
) appears in self._dx, self._dy = self._compute_dxdy(), which I could do by changing def _compute_dxdy(self):
if self._is_cartesian:
return self._compute_dxdy_cartesian()
... # cubed-sphere calculation This seems better to me since |
@FlorianDeconinck @bensonr Thoughts? |
There's a way to have the best of both world. The key here is to keep to the "one idea one code" mantra. Call to class MetricTerms:
def __init__(...):
...
# Configuration block for internal numerics that differ. Requires functions to share signature
if is_cartesian:
self._compute_dx_dy = self._compute_dx_dy_cartesian
....
else:
self._compute_dx_dy = self._compute_dx_dy_cube_sphere
...
...
# Lazy function remains the same and will pull on the proper numerics
def dx(self,...):
...
dx = self._compute_dx_dy(...) |
If we need to implement other grid in the future, we will break out the numerics in it's object and use OO and ABC to make it a true configuration pattern. With two it's fine to keep it as a if/else |
This looks like a good way to go to me |
@FlorianDeconinck Thanks for the suggestion! I just pushed a commit that implements it, and adds a unit test that checks some basic properties of Cartesian grids. These changes pass the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for all the revisions, this is great!
Looking good, thanks for the utest. All this will need a good documentation pass, but it needs to be done globally so it's out-of-scope here and we will probably attack this post framework/model refactor. Great to see new contributor and clean code going in! |
Purpose
Implement grid generation for doubly-periodic Cartesian domains.
Remove the sections below which do not apply.
Code changes:
util/pace/util/grid/generation.py
: Add fields toMetricTerms
class to store grid spacing and latitude for Cartesian grids, and add an_init_cartesian
method to compute Cartesian grid properties. Also fix a bug in vertical grid calculations that was preventing grid translate tests from passing.fv3core/tests/savepoint/translate/translate_grid.py
: Pass grid type and Cartesian grid spacing and latitude toMetricTerms
constructor inInitGrid
andInitGridUtils
tests.Requirements changes:
constraints.txt
: Updateh5py
andnetcdf
versions. (make build
failed with versions in unchangedconstraints.txt
.)Checklist
Before submitting this PR, please make sure:
Additionally, if this PR contains code authored by new contributors: