-
Notifications
You must be signed in to change notification settings - Fork 7
Add torus support to GridGeometry #953
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
Conversation
| ) | ||
| x = edge_orientation * xdiff | ||
| y = edge_orientation * ydiff | ||
| z = 0.0 * x # TODO(msimberg): zeros |
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.
@egparedes @havogt is there a nicer way to express this? Essentially I'm looking for np.zeros_like(field) in gt4py, but as far as I could tell that doesn't exist.
We could consider leaving the all-zeros Z field out, but I suspect that it would cause too much complexity for downstream field computations that would have to deal with the missing field.
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 think this is the best you can do for now...
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.
The comment should probably be updated to something like:
| z = 0.0 * x # TODO(msimberg): zeros | |
| # TODO(msimberg): This should use something like numpy.zeros_like if and when that becomes available in gt4py. | |
| z = 0.0 * x |
| edge_normal_y: y coordinate of the normal | ||
| edge_normal_z: y coordinate of the normal | ||
| """ | ||
| z = 0.0 * edge_tangent_x # TODO(msimberg): zeros |
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.
To do: same as in https://github.com/C2SM/icon4py/pull/953/files#r2542084148.
| # TODO(msimberg): x, y, z added temporarily for torus grids, but should they be in a separate dict? | ||
| CoordinateDict: TypeAlias = dict[ | ||
| gtx.Dimension, dict[Literal["lat", "lon", "x", "y", "z"], gtx.Field] | ||
| ] |
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 haven't tried it yet, but I think the places where CoordinateDict is used could be changed to a GeometryDict. We possibly lose a bit of type safety (any GeometryName could be used instead of the closed set of naems currently in CoordinateDict).
@halungge do you have thoughts on what you'd prefer to see here (I see the TODO below, so you may already have thought about this)?
|
Mandatory Tests Please make sure you run these tests via comment before you merge!
Optional Tests To run benchmarks you can use:
To run tests and benchmarks with the DaCe backend you can use:
To run test levels ignored by the default test suite (mostly simple datatest for static fields computations) you can use:
For more detailed information please look at CI in the EXCLAIM universe. |
| params=[ | ||
| definitions.Experiments.MCH_CH_R04B09, | ||
| definitions.Experiments.EXCLAIM_APE, | ||
| definitions.Experiments.GAUSS3D, | ||
| ], |
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.
Note that I've added GAUSS3D here which means that the experiment will be used for all tests that use the fixture, including tests that haven't yet been updated to handle torus grids correctly.
My preference would be to keep this here so that we really test with the torus grid everywhere it makes sense. The downside is that we'd have to mark tests that don't handle toruses yet with XFAIL or SKIP.
One alternative is introducing GAUSS3D locally only in test_geometry.py for now.
Preferences?
| coordinates: gm.CoordinateDict, | ||
| extra_fields: gm.GeometryDict, | ||
| metadata: dict[str, model.FieldMetaData], | ||
| ) -> "GridGeometry": |
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.
| ) -> "GridGeometry": | |
| ) -> GridGeometry | None: |
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.
Hmm, is this for the type checker, for the assert_never case?
|
|
||
| def _register_computed_fields(self) -> None: | ||
| def _register_computed_fields( | ||
| self, input_fields_provider: factory.PrecomputedFieldProvider |
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.
| self, input_fields_provider: factory.PrecomputedFieldProvider | |
| self |
this input is unused?
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.
Yeah, I think so. It was only a requirement for the torus grid.
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.
These fields are computed and saved in coordinates_ below but are never used anywhere in the code. can we clean them and the create_... method up?
@halungge am I missing something?
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.
Diff is unclear, but are you referring to latitude_of_edge_cell_neighbor_0 and friends? To me they also look unused, but @halungge can hopefully confirm if there was another planned use for them.
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.
see above
| self.register_provider(input_fields_provider) | ||
| self._register_computed_fields(input_fields_provider) | ||
|
|
||
| def _register_computed_fields( |
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.
_register_computed_fields does not exist in GridGeometry anymore, but it has a lot of code in common between IcosahedronGridGeometry and TorusGridGeometry.
Isn't it better to move back to GridGeometry the common stuff and have here only the differences?
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.
Yeah, this was mostly for a simple first pass, I don't think I've separated things particularly well at this point. As hinted in the PR description, we could even drop the subclasses and do something like what I've done in the interpolation PR: https://github.com/msimberg/icon4py/blob/bc7e2bcd4ffa5d786d4eafe9902eb8cb3a04aeb9/model/common/src/icon4py/model/common/interpolation/interpolation_factory.py#L188-L240. I.e. just dispatch to different implementations field-by-field, and only where needed.
What do you think looks more manageable?
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 like the interpolation approach more, dispatching only where needed, and we keep just one GridGeometry class with 2-3 differences in the distance and vector orientation parts
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.
Dropping the subclasses also has the benefit of not requiring going through the special factory method to construct the right instances. It's also more consistent with the rest.
I guess it's very, very, very unlikely that there will be any geometry type other than sphere and torus in the near to medium future?
|
#954 extracts the interpolation field changes. |
This PR continues the series of PRs to add torus grid support. This is extracted from #853.
This PR:
IcosahedronGridGeometryandTorusGridGeometry, ofGridGeometrythat handle initializing geometry fields for the two grid types.GridGeometry,with_geometry_type(bikeshedding on name and placement welcome) which initializesGridGeometrybased ongeometry_type. With a closed set of geometry types, this could possibly also be nicely solved with branching inside a singleGridGeometryclass, but I think the current setup isn't bad either.