11module Bathymetry
22
3- export regrid_bathymetry, retrieve_bathymetry
3+ export regrid_bathymetry, retrieve_bathymetry, download_bathymetry
44
55using ImageMorphology
66using .. DataWrangling: download_progress
7+ using .. DistributedUtils: @root
78
89using Oceananigans
910using Oceananigans. Architectures: architecture, on_architecture
3637etopo_url = " https://www.dropbox.com/scl/fi/6pwalcuuzgtpanysn4h6f/" *
3738 " ETOPO_2022_v1_60s_N90W180_surface.nc?rlkey=2t7890ruyk4nd5t5eov5768lt&st=yfxsy1lu&dl=0"
3839
40+ """
41+ download_bathymetry(; dir = download_bathymetry_cache,
42+ url = etopo_url,
43+ filename = "ETOPO_2022_v1_60s_N90W180_surface.nc")
44+
45+ Download the bathymetry from `url` and saves it under `filename` in the directory `dir` and
46+ return the full filepath where the bathymetry is saved.
47+ """
48+ function download_bathymetry (; url = etopo_url,
49+ dir = download_bathymetry_cache,
50+ filename = " ETOPO_2022_v1_60s_N90W180_surface.nc" )
51+
52+ filepath = joinpath (dir, filename)
53+
54+ # TODO : embed this into a @root macro; see failed attempts in https://github.com/CliMA/ClimaOcean.jl/pull/391
55+ if ! isfile (filepath)
56+ Downloads. download (url, filepath; progress= download_progress)
57+ end
58+
59+ return filepath
60+ end
61+
3962"""
4063 regrid_bathymetry(target_grid;
4164 height_above_water = nothing,
@@ -57,10 +80,10 @@ Arguments
5780Keyword Arguments
5881=================
5982
60- - `height_above_water`: limits the maximum height of above-water topography (where ``h > 0``) before inetrpolating .
83+ - `height_above_water`: limits the maximum height of above-water topography (where ``h > 0``) before interpolating .
6184 Default: `nothing`, which implies that the original topography is retained.
6285
63- - `minimum_depth`: minimum depth for the shallow regions, defined as a positive value.
86+ - `minimum_depth`: minimum depth for the shallow regions, defined as a positive value.
6487 `h > - minimum_depth` is considered land. Default: 0.
6588
6689- `dir`: directory of the bathymetry-containing file. Default: `download_bathymetry_cache`.
@@ -103,13 +126,7 @@ function regrid_bathymetry(target_grid;
103126 interpolation_passes = 1 ,
104127 major_basins = 1 ) # Allow an `Inf` number of "lakes"
105128
106- filepath = joinpath (dir, filename)
107-
108- # No need for @root here, because only rank 0 accesses this function
109- if ! isfile (filepath)
110- Downloads. download (url, filepath; progress= download_progress)
111- end
112-
129+ filepath = download_bathymetry (; url, dir, filename)
113130 dataset = Dataset (filepath, " r" )
114131
115132 FT = eltype (target_grid)
@@ -129,7 +146,7 @@ function regrid_bathymetry(target_grid;
129146 arch = architecture (target_grid)
130147 λ_data = λ_data |> Array{BigFloat}
131148 φ_data = φ_data |> Array{BigFloat}
132-
149+
133150 if ! isnothing (height_above_water)
134151 # Overwrite the height of cells above water.
135152 # This has an impact on reconstruction. Greater height_above_water reduces total
@@ -161,8 +178,8 @@ function regrid_bathymetry(target_grid;
161178 native_z = Field {Center, Center, Nothing} (native_grid)
162179 set! (native_z, z_data)
163180 fill_halo_regions! (native_z)
164-
165- target_z = interpolate_bathymetry_in_passes (native_z, target_grid;
181+
182+ target_z = interpolate_bathymetry_in_passes (native_z, target_grid;
166183 passes = interpolation_passes)
167184
168185 if minimum_depth > 0
@@ -182,7 +199,7 @@ function regrid_bathymetry(target_grid;
182199 return target_z
183200end
184201
185- # Here we can either use `regrid!` (three dimensional version) or `interpolate`
202+ # Here we can either use `regrid!` (three dimensional version) or `interpolate!`.
186203function interpolate_bathymetry_in_passes (native_z, target_grid;
187204 passes = 10 )
188205 Nλt, Nφt = Nt = size (target_grid)
@@ -205,7 +222,7 @@ function interpolate_bathymetry_in_passes(native_z, target_grid;
205222 " is finer than the target grid in both horizontal directions." )
206223 return target_z
207224 end
208-
225+
209226 # Interpolate in passes
210227 latitude = y_domain (native_z. grid)
211228 longitude = x_domain (native_z. grid)
@@ -254,8 +271,8 @@ function regrid_bathymetry(target_grid::DistributedGrid; kw...)
254271 arch = architecture (target_grid)
255272 Nx, Ny, _ = size (global_grid)
256273
257- # If all ranks open a gigantic bathymetry and the memory is
258- # shared, we could easily have OOM errors.
274+ # If all ranks open a gigantic bathymetry and the memory is
275+ # shared, we could easily have OOM errors.
259276 # We perform the reconstruction only on rank 0 and share the result.
260277 bottom_height = if arch. local_rank == 0
261278 bottom_field = regrid_bathymetry (global_grid; kw... )
@@ -316,7 +333,7 @@ function maybe_extend_longitude(zb_cpu, ::Periodic)
316333 nx = Nx ÷ 2
317334
318335 zb_data = zb_cpu. data[1 : Nx, :, 1 ]
319- zb_parent = zb_data. parent
336+ zb_parent = zb_data. parent
320337
321338 # Add information on the LHS and to the RHS
322339 zb_parent = vcat (zb_parent[nx: Nx, :], zb_parent, zb_parent[1 : nx, :])
@@ -328,7 +345,7 @@ function maybe_extend_longitude(zb_cpu, ::Periodic)
328345 return OffsetArray (zb_parent, xoffsets, yoffsets)
329346end
330347
331- remove_major_basins! (zb:: OffsetArray , keep_minor_basins) =
348+ remove_major_basins! (zb:: OffsetArray , keep_minor_basins) =
332349 remove_minor_basins! (zb. parent, keep_minor_basins)
333350
334351function remove_minor_basins! (zb, keep_major_basins)
@@ -342,24 +359,24 @@ function remove_minor_basins!(zb, keep_major_basins)
342359 end
343360
344361 water = zb .< 0
345-
362+
346363 connectivity = ImageMorphology. strel (water)
347364 labels = ImageMorphology. label_components (connectivity)
348-
365+
349366 total_elements = zeros (maximum (labels))
350367 label_elements = zeros (maximum (labels))
351368
352369 for e in 1 : lastindex (total_elements)
353370 total_elements[e] = length (labels[labels .== e])
354371 label_elements[e] = e
355372 end
356-
373+
357374 mm_basins = [] # major basins indexes
358375 m = 1
359376
360377 # We add basin indexes until we reach the specified number (m == keep_major_basins) or
361- # we run out of basins to keep -> isempty(total_elements)
362- while (m <= keep_major_basins) && ! isempty (total_elements)
378+ # we run out of basins to keep -> isempty(total_elements)
379+ while (m <= keep_major_basins) && ! isempty (total_elements)
363380 next_maximum = findfirst (x -> x == maximum (total_elements), total_elements)
364381 push! (mm_basins, label_elements[next_maximum])
365382 deleteat! (total_elements, next_maximum)
@@ -399,11 +416,11 @@ Returns
399416
400417- `bottom_height`: The retrieved or generated bathymetry data.
401418
402- If the specified file exists, the function reads the bathymetry data from the file.
419+ If the specified file exists, the function reads the bathymetry data from the file.
403420Otherwise, it generates the bathymetry data using the provided grid and saves it to the file before returning it.
404421"""
405- function retrieve_bathymetry (grid, filename; kw... )
406-
422+ function retrieve_bathymetry (grid, filename; kw... )
423+
407424 if isfile (filename)
408425 bottom_height = jldopen (filename)[" bathymetry" ]
409426 else
0 commit comments