Skip to content

Commit

Permalink
Remove Adapt dependency
Browse files Browse the repository at this point in the history
Replace interpolation op with
generalised spacevaryingutility tools.

Update orographic gravity wave file to use
new artifact. Downsample raw data for use
in parameterization (raw size 21600x10800 is too
large).

Bump ref counter and update news

Co-authored-by: Gabriele Bozzola <[email protected]>
  • Loading branch information
akshaysridhar and Sbozzolo committed Oct 25, 2024
1 parent 09f7aff commit 7c3598c
Show file tree
Hide file tree
Showing 19 changed files with 293 additions and 210 deletions.
11 changes: 11 additions & 0 deletions Artifacts.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,14 @@ git-tree-sha1 = "6693f8451b447543952b3d557d733c7e5c670ed3"
[[ozone_concentrations_lowres.download]]
sha256 = "908384b32e90c733c2173654afbb974d238a9a516ad8965039077c6ddb29b5f0"
url = "https://caltech.box.com/shared/static/6c16wt7i1htxq6tadpt1ng2uftjgdtpr.gz"

[earth_orography_30arcseconds]
git-tree-sha1 = "03dd08fcbf363ed055a176dd7adefb60ff1c3493"

[earth_orography_60arcseconds]
git-tree-sha1 = "fe19d8dbe7a18ff39588e1f718014b0479d9c0f7"
lazy = true

[[earth_orography_60arcseconds.download]]
sha256 = "eca66c0701d1c2b9e271742314915ffbf4a0fae92709df611c323f38e019966e"
url = "https://caltech.box.com/shared/static/4asrxcgl6xsgenfcug9p0wkkyhtqilgk.gz"
12 changes: 12 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@ ClimaAtmos.jl Release Notes
Main
-------

### Features

### ETOPO2022 60arc-second topography dataset.

- Update artifacts to use 60arc-second ETOPO2022 ice-surface topography
dataset. Update surface smoothing functions to rely only on spectral
Laplacian operations. Update raw-topo gravity wave parameterization
dataset. Update interfaces in `make_hybrid_spaces` to support new
inputs using `SpaceVaryingInput` utility. Include a simple example
to generate spectra from scalar variables.
PR [3378](https://github.com/CliMA/ClimaAtmos.jl/pull/3378)

v0.27.7
-------

Expand Down
13 changes: 0 additions & 13 deletions artifacts/artifact_funcs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,6 @@ function mima_gwf_path()
return AW.get_data_folder(mima_data)
end

function topo_elev_dataset_path()
etopo1_elev_data = AW.ArtifactWrapper(
@__DIR__,
"topo-elev-info",
AW.ArtifactFile[AW.ArtifactFile(
url = "https://caltech.box.com/shared/static/gvilybsu5avxso1wubxjthpip9skc6mf.nc",
filename = "ETOPO1_coarse.nc",
),],
)
return AW.get_data_folder(etopo1_elev_data)
end


function gfdl_ogw_data_path()
gfdl_data = AW.ArtifactWrapper(
@__DIR__,
Expand Down
1 change: 0 additions & 1 deletion artifacts/download_artifacts.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ function trigger_download(lazy_download = true)
@info "Era single column dataset path:`$(era_single_column_dataset_path())`"
@info "topo dataset path:`$(topo_res_path())`"
@info "MiMA convective gravity wave path:`$(mima_gwf_path())`"
@info "ETOPO1 arc-minute relief model:`$(topo_elev_dataset_path())`"
@info "GFDL OGWD test data:`$(gfdl_ogw_data_path())`"
return nothing
end
Expand Down
3 changes: 0 additions & 3 deletions config/default_configs/default_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,6 @@ sleve_s:
topo_smoothing:
help: "Choose whether to order-2 smoothing on the LGL mesh"
value: false
smoothing_order:
help: "Define the surface smoothing kernel factor (integer) [`3 (default)`]"
value: 3
# ODE
use_newton_rtol:
help: "Whether to check if the current iteration of Newton's method has an error within a relative tolerance, instead of always taking the maximum number of iterations (only for ClimaTimeSteppers.jl)"
Expand Down
1 change: 0 additions & 1 deletion examples/Project.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
[deps]
Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
ArgParse = "c7e460c6-2fb9-53a9-8c5b-16f535851c63"
ArtifactWrappers = "a14bc488-3040-4b00-9dc1-f6467924858a"
AtmosphericProfilesLibrary = "86bc3604-9858-485a-bdbe-831ec50de11d"
Expand Down
144 changes: 144 additions & 0 deletions examples/topography_spectra.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
using LazyArtifacts
using ClimaAtmos.AtmosArtifacts
import ClimaAtmos as CA
import ClimaCore as CC
import ClimaComms
import ClimaParams as CP
import ClimaCore.Quadratures
using ClimaUtilities: SpaceVaryingInputs
using ClimaCore.Hypsography: diffuse_surface_elevation!
using ClimaCore: Remapping, Geometry, Operators, Spaces
using CairoMakie

import ClimaCoreSpectra: power_spectrum_2d

const AA = AtmosArtifacts


function mask(x::FT) where {FT}
return x * FT(x > 0)
end

"""
generate_spaces(; h_elem=16)
For a given number of elements `h_elem`, this function generates a
horizontal spectral space (ClimaCore.SpectralElementSpace2D) and
generates an interpolated (using SpaceVaryingInputs) orography field
on this space. The `diffuse_surface_elevation` function is called
to apply Laplacian diffusion (canonical diffusion equation) passes,
with a timescale defined by the attenuation required at the smallest
resolved lengthscale.
Returns a `Field` containing surface orography.
"""
function generate_spaces(;
h_elem = 16,
n_attenuation = 1000,
planet_radius = 6.378e6,
)
FT = Float32
cubed_sphere_mesh =
CA.cubed_sphere_mesh(; radius = FT(planet_radius), h_elem)
quad = Quadratures.GLL{4}()
comms_ctx = ClimaComms.context()
h_space = CA.make_horizontal_space(cubed_sphere_mesh, quad, comms_ctx, true)
Δh_scale = Spaces.node_horizontal_length_scale(h_space)
@assert h_space isa CC.Spaces.SpectralElementSpace2D
coords = CC.Fields.coordinate_field(h_space)
target_field = CC.Fields.zeros(h_space)
elev_from_file = SpaceVaryingInputs.SpaceVaryingInput(
AA.earth_orography_file_path(; context = comms_ctx),
"z",
h_space,
)
elev_from_file = @. mask(elev_from_file)
# Fractional damping of smallest resolved scale
# Approximated as k₀ ≈ 1/Δx, with n_attenuation
# the factor by which we wish to damp wavenumber
# k₀. Assume dt == 1 for this example.
diff_courant = FT(0.05)
κ = diff_courant * Δh_scale^2
maxiter = Int(round(log(n_attenuation) / diff_courant))
diffuse_surface_elevation!(elev_from_file; κ, dt = FT(1), maxiter)
elev_from_file = @. mask(elev_from_file)
return elev_from_file
end

"""
remap_to_array(test_var, hcoords)
Given an Array of `hcoords`, this function remaps a ClimaCore
Field `test_var` onto `hcoords`.
Returns an `Array` containing the values which make up `test_var`.
"""
function remap_to_array(test_var, hcoords)
remapper = Remapping.Remapper(axes(test_var), hcoords)
orog = Array(Remapping.interpolate(remapper, test_var))
end

"""
gen_spectra(test_var)
Given a Field `test_var`, this function first calls `remap_to_array`
to remap this spectral element field onto a latitude-longitude
grid, and computes the spectra.
Returns (`w_numbers`, `power_spectrum`) which contain the spherical
wavenumbers and the spectral energy corresponding to this array
of `w_numbers`.
"""
function gen_spectra(test_var)
FT = eltype(test_var)
Δh_scale = Spaces.node_horizontal_length_scale(Spaces.axes(test_var))
planet_radius = FT(6.378e6)
npts = Int(round(2π * planet_radius / Δh_scale))
npts = ifelse(rem(npts, 2) == 0, npts, npts + 1)
longpts = range(FT(-180), FT(180.0), Int(npts))
latpts = range(FT(-90), FT(90), Int(npts // 2))
hcoords =
[Geometry.LatLongPoint(lat, long) for long in longpts, lat in latpts]
test_var = remap_to_array(test_var, hcoords)
# Use ClimaCoreSpectra to generate power spectra for orography data.
len1 = size(test_var)[1]
len2 = size(test_var)[2]
@assert len1 == 2len2
mass_weight = FT(1) # No weighting applied
spectrum_data, wave_numbers, _spherical, mesh_info =
power_spectrum_2d(FT, test_var, mass_weight)
power_spectrum =
dropdims(sum(spectrum_data, dims = 1), dims = 1)[begin:(end - 1), :]
w_numbers = collect(0:1:(mesh_info.num_spherical - 1))
@info "Returning wavenumber array (spherical) and orography power spectrum"
return w_numbers, power_spectrum
end

"""
generate_all_spectra(;h_elem=16)
Uses the spectral calculator and space generation tools in this example file
to generate a series of surface orography fields with different extents of
Laplacian smoothing.
Returns a `CairoMakie.Figure`.
"""
function generate_all_spectra(; h_elem = 16)
fig = Figure(; size = (1200, 900))
ax1 = Axis(
fig[1, 1],
xlabel = "spherical wavenumber",
ylabel = "elevation spectra",
title = "Surface elevation spectra",
xticks = [2, 4, 8, 16, 32, 64, 128, 256],
yticks = [10^-1, 10^0, 10^1, 10^2, 10^3, 10^4],
xscale = log10,
yscale = log10,
xgridvisible = true,
ygridvisible = false,
)
for ii in (1, 2, 4, 8, 16, 32, 64, 128, 256, 512)
n_attenuation = ii
test_var = generate_spaces(; h_elem, n_attenuation)
Δh_scale = Spaces.node_horizontal_length_scale(Spaces.axes(test_var))
diff_courant = 0.05 # Arbitrary example value.
κ = diff_courant * Δh_scale^2
maxiter = Int(round(log(n_attenuation) / diff_courant))
sph_wn, psd = gen_spectra(test_var)
scatterlines!(sph_wn[2:end], psd[2:end], label = "iter = $(maxiter)")
end
CairoMakie.Legend(fig[1, 2], ax1)
return fig
end
10 changes: 9 additions & 1 deletion reproducibility_tests/ref_counter.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
185
186

# **README**
#
Expand All @@ -20,6 +20,14 @@


#=
186
- Topography dataset has been modified to the 60 arc-second ETOPO2022 dataset.
This is behaviour changing for the gravity-wave (raw-topo) parameterization
when computing `hmax` and `T tensor`.
185
184
- Changed default ozone profile.
Jobs that failed:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ function orographic_gravity_wave_cache(Y, ogw::OrographicGravityWave)
elseif ogw.topo_info == "raw_topo"
# TODO: right now this option may easily crash
# because we did not incorporate any smoothing when interpolate back to model grid
elevation_rll = joinpath(topo_elev_dataset_path(), "ETOPO1_coarse.nc")
elevation_rll =
AA.earth_orography_file_path(; context = ClimaComms.context(Y.c))
radius =
Spaces.topology(
Spaces.horizontal_space(axes(Y.c)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,10 +226,13 @@ end

function compute_OGW_info(Y, elev_data, earth_radius, γ, h_frac)
# obtain lat, lon, elevation from the elev_data
FT = Spaces.undertype(Spaces.axes(Y.c))
# downsample to elev dims (3600×1800)
skip_pt = 6
nt = NCDataset(elev_data, "r") do ds
lon = Array(ds["longitude"])
lat = Array(ds["latitude"])
elev = Array(ds["elevation"])
lon = FT.(Array(ds["lon"]))[1:skip_pt:end]
lat = FT.(Array(ds["lat"]))[1:skip_pt:end]
elev = FT.(Array(ds["z"]))[1:skip_pt:end, 1:skip_pt:end]
(; lon, lat, elev)
end
(; lon, lat, elev) = nt
Expand Down
68 changes: 3 additions & 65 deletions src/solver/type_getters.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using Adapt
using Dates: DateTime, @dateformat_str
using Interpolations
import NCDatasets
Expand Down Expand Up @@ -136,39 +135,6 @@ function get_spaces(parsed_args, params, comms_ctx)
bubble = parsed_args["bubble"]
deep = parsed_args["deep_atmosphere"]

@assert topography in ("NoWarp", "DCMIP200", "Earth", "Agnesi", "Schar")
if topography == "DCMIP200"
warp_function = topography_dcmip200
elseif topography == "Agnesi"
warp_function = topography_agnesi
elseif topography == "Schar"
warp_function = topography_schar
elseif topography == "NoWarp"
warp_function = nothing
elseif topography == "Earth"
data_path = joinpath(topo_elev_dataset_path(), "ETOPO1_coarse.nc")
array_type = ClimaComms.array_type(comms_ctx.device)
earth_spline = NCDatasets.NCDataset(data_path) do data
zlevels = Array(data["elevation"])
lon = Array(data["longitude"])
lat = Array(data["latitude"])
# Apply Smoothing
smooth_degree = Int(parsed_args["smoothing_order"])
esmth = CA.gaussian_smooth(zlevels, smooth_degree)
Adapt.adapt(
array_type,
linear_interpolation(
(lon, lat),
esmth,
extrapolation_bc = (Periodic(), Flat()),
),
)
end
@info "Generated interpolation stencil"
warp_function = generate_topography_warp(earth_spline)
end
@info "Topography" topography


h_elem = parsed_args["h_elem"]
radius = CAP.planet_radius(params)
Expand All @@ -183,19 +149,7 @@ function get_spaces(parsed_args, params, comms_ctx)
else
Meshes.Uniform()
end
if warp_function == nothing
make_hybrid_spaces(h_space, z_max, z_elem, z_stretch; deep)
else
make_hybrid_spaces(
h_space,
z_max,
z_elem,
z_stretch;
parsed_args = parsed_args,
surface_warp = warp_function,
deep,
)
end
make_hybrid_spaces(h_space, z_max, z_elem, z_stretch; deep, parsed_args)
elseif parsed_args["config"] == "column" # single column
@warn "perturb_initstate flag is ignored for single column configuration"
FT = eltype(params)
Expand Down Expand Up @@ -240,15 +194,7 @@ function get_spaces(parsed_args, params, comms_ctx)
else
Meshes.Uniform()
end
make_hybrid_spaces(
h_space,
z_max,
z_elem,
z_stretch;
parsed_args,
surface_warp = warp_function,
deep,
)
make_hybrid_spaces(h_space, z_max, z_elem, z_stretch; parsed_args, deep)
elseif parsed_args["config"] == "plane"
FT = eltype(params)
nh_poly = parsed_args["nh_poly"]
Expand All @@ -264,15 +210,7 @@ function get_spaces(parsed_args, params, comms_ctx)
else
Meshes.Uniform()
end
make_hybrid_spaces(
h_space,
z_max,
z_elem,
z_stretch;
parsed_args,
surface_warp = warp_function,
deep,
)
make_hybrid_spaces(h_space, z_max, z_elem, z_stretch; parsed_args, deep)
end
ncols = Fields.ncolumns(center_space)
ndofs_total = ncols * z_elem
Expand Down
Loading

0 comments on commit 7c3598c

Please sign in to comment.