-
Notifications
You must be signed in to change notification settings - Fork 25
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
Grid-flexible spectral transform #127
Conversation
@hottad at the moment this PR lets one use any julia> alms = LowerTriangularMatrix(randn(ComplexF64,33,32));
julia> alms[:,1] .= real.(alms[:,1]);
julia> map = gridded(alms,grid=FullGaussianGrid);
julia> alms2 = spectral(map);
julia> imshow(log10.(abs.(alms-alms2))) an absolute error that is O(1e-14) with Float64. That's good. However, for Octahedral/HEALPix the absolute errors are O(1e-2) and larger. I believe this is because I messed up the normalisation with the solid angle julia> nlat_half = 24
julia> w = SpeedyWeather.get_quadrature_weights(FullGaussianGrid,nlat_half);
julia> w *= π/2nlat_half
24-element Vector{Float64}:
0.0002063860165031381
0.0004795872813548503
0.0007511832466177125
...
0.0041838316317469116
0.00421930059577275
0.004237072348271895 so quadrature weights *pi/nlat and the same for the Clenshaw-Curtis grid but with other weights obviously. I believe this has to be changed for Octahedral/HEALPix. I'll try to figure this out in the next days. |
@hottad With the latest commit the transform errors on the HEALPix grid are much smaller from julia> alms = LowerTriangularMatrix(randn(ComplexF64,33,32))
julia> alms[end,:] .= 0
julia> alms[:,1] .= real.(alms[:,1])
julia> map = gridded(alms,grid=HEALPixGrid)
julia> alms2 = spectral(map)
julia> maximum(abs.(alms)-abs.(alms2))
0.018819099369166703
julia> imshow(abs.(alms-alms2)) but only when the lon offset rotation is deactivated |
src/grids.jl
Outdated
sin_colat_Δθ = zero(colat) | ||
sin_colat_Δθ[1] = sin(colat[1])*colat[2]/2 | ||
for j in 2:length(colat)-1 | ||
sin_colat_Δθ[j] = sin(colat[j])*(colat[j+1]-colat[j-1])/2 | ||
end | ||
sin_colat_Δθ[end] = sin(colat[end])*(π-colat[end])/2 |
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 are the best quadrature weights for the HEALPix grid I was sofar able to come up with.
src/spectral_transform.jl
Outdated
|
||
# QUADRATURE WEIGHTS and LONGITUDE OFFSET | ||
w = lon_offsets[m,ilat_n] # longitude offset rotation | ||
# quadrature_weight *= conj(w) # complex conjugate for back transform |
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.
However, the longitude offset rotation had to be deactivated. In general we do here
_, lons = get_colatlons(grid,nresolution)
lon1s = [lons[each_index_in_ring(grid,i,nresolution)[1]] for i in 1:nlat]
lon_offsets = [cispi(m*lon1/π) for m in 0:mmax, lon1 in lon1s]
with lon1s
the longitude in radians of the first grid point per ring.
@hottad While I'm still not sure about the accuracy of the HEALPix spectral transform, I'm tempted to merge this once all tests pass as all the other structure has been set up such that you can start contributing/experimenting and do whatever you'd like to test with new grids in SpeedyWeather.jl, I think we probably just ran the first HEALPix atmospheric simulation, see below? |
@milankl Fantastic! |
Yeah, the HEALPixGrid still doesn't have the correct longitude offset rotation implemented, that's something that I need to play around with. As you suggest, it's probably some implementation bug that I don't currently understand as the mathematics are rather clear I believe. However, it's still good enough to run even 1000 days or longer and also at different resolution. |
This PR is intended to fix #112 by allowing for a flexible
grid<:AbstractGrid
to be used in the spectral transform.