-
Notifications
You must be signed in to change notification settings - Fork 250
Docs, Examples, and Validation for the XESMF extension #4823
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
|
Could we optimise the for loop for k at: Oceananigans.jl/ext/OceananigansXESMFExt.jl Lines 179 to 191 in cbfb6f2
? |
I can't think of anything |
|
We could leverage batched multiplies from the CUBLAS and BLAS libraries. |
|
Related to reproducing python's xESMF results: https://forum.access-hive.org.au/t/conservative-regridding-with-xesmf-puzzled-because-the-integrals-dont-quite-agree/5343 |
|
@juliasloan25 once this PR is in, you will probably be ready to use XESMF for tripolar -> lat lon interpolation. (@navidcy can say more maybe). You might be able to use it now. |
|
You can use it now! This PR cleans up some pf the code and adds up examples. But doesn’t add functionality. I wanted to confirm that we reproduce pythons xesmf results. I’m pretty sure we do. Im gonna wrap that up and include it. bottom line: no need to wait for this PR @juliasloan25 |
|
I confirmed that the regridder here reproduces python's results. In particular: using Oceananigans
using XESMF
arch = CPU()
z = (-1, 0)
radius = Oceananigans.defaults.planet_radius
llg_coarse = LatitudeLongitudeGrid(arch; z, radius,
size = (180, 90, 1),
longitude = (0, 360),
latitude = (-90, 90))
llg_fine = LatitudeLongitudeGrid(arch; z, radius,
size = (360, 180, 1),
longitude = (0, 360),
latitude = (-90, 90))
src_field = CenterField(llg_coarse)
dst_field = CenterField(llg_fine)
width = 12 # degrees
set!(src_field, (λ, φ, z) -> exp(-((λ - 150)^2 + (φ - 30)^2) / 2width^2) - 2exp(-((λ - 270)^2 + (φ + 20)^2) / 2width^2))
regridder = XESMF.Regridder(dst_field, src_field, method="conservative")
regrid!(dst_field, regridder, src_field)
println("integral src_field = ", first(Field(Integral(src_field, dims=(1, 2)))))
println("integral dst_field = ", first(Field(Integral(dst_field, dims=(1, 2)))))gives integral src_field = -1.1089929769375445e13
integral dst_field = -1.109066523206981e13And in Python, here's a Jupyter notebook getting exactly the same numbers: |
|
This is ready to review/merge. Could somebody have a look? |
|
wow, not so conservative after all! (with zstar at #4811 I am stressing over a relative error in tracer conservation of 1e-13 😅, maybe I don't need to be so pedantic...) |
|
Shall we add the validation somewhere in the XESMF.jl package? |
|
You mean the Python validation? I can add both in a validation script. I'm amazed how it's not giving the same integral to machine precision. But I don't know how xESMF computes their weights. Do they compute them in a way to ensure that the integrals are the same? |
|
I would have suspected so. In general, if they compute intersections between surface areas it should be quite simple to ensure that the integral is conserved. Maybe they assume the areas are planes rather than spherical sectors? This could introduce an error. If this is the case, a rectilinear grid should lead to exact conservation. |
|
The grid I tried didn't have overlapping areas. I used a lat-lon grid of 1deg and 2deg. |
|
I added the validation scripts; I'll merge when CI passes. |
Oceananigans.jl/ext/OceananigansXESMFExt.jl
Lines 12 to 28 in cbfb6f2
eg use
permutedimsinstead of'rtol = 1e-4?Closes #4818