Skip to content

Commit 2eda21c

Browse files
committed
Add fluxes2velocity function
1 parent e59d2a0 commit 2eda21c

5 files changed

Lines changed: 98 additions & 2 deletions

File tree

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "OceanTransportMatrixBuilder"
22
uuid = "c2b4a04e-6049-4fc4-aa6a-5508a29a1e1c"
3-
version = "0.8.2"
3+
version = "0.8.3"
44
authors = ["Benoit Pasquier <briochemc@gmail.com> and contributors"]
55

66
[deps]

src/OceanTransportMatrixBuilder.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ include("RediGM.jl")
2828
# Extras
2929
include("extratools.jl") # <- I think this should be in a separate "base" repo
3030

31-
export velocity2fluxes
31+
export velocity2fluxes, fluxes2velocity
3232
export facefluxesfrommasstransport
3333
export facefluxesfromvelocities
3434
export makegridmetrics

src/velocities.jl

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,41 @@ function velocity2fluxes(u, u_lon, u_lat, v, v_lon, v_lat, gridmetrics, ρ)
3838
return ϕᵢ, ϕⱼ
3939
end
4040

41+
"""
42+
fluxes2velocity(ϕᵢ, ϕⱼ, gridmetrics, ρ)
43+
44+
Return the velocities `u` and `v` on the C-grid given the mass fluxes `ϕᵢ` and `ϕⱼ` (in kg/s).
45+
46+
The velocities are calculated from the density ρ (number or 3D array) and from the cell face areas between the cells.
47+
The mean density from the two cells that share the face is used.
48+
The minimum thickness of the two cells that share the face is used.
49+
"""
50+
function fluxes2velocity(ϕᵢ, ϕⱼ, gridmetrics, ρ)
51+
52+
# Unpack gridmetrics
53+
(; thkcello, edge_length_2D, v3D, lon_vertices, lat_vertices, zt) = gridmetrics
54+
55+
# make indices
56+
indices = makeindices(v3D)
57+
58+
# grid type
59+
gridtopology = getgridtopology(lon_vertices, lat_vertices, zt)
60+
61+
u = zeros(size(ϕᵢ))
62+
v = zeros(size(ϕⱼ))
63+
64+
# Calculate velocities from fluxes
65+
for 𝑖 in indices.C
66+
i, j = 𝑖.I
67+
𝑗 = i₊₁(𝑖, gridtopology) # grid cell to the "east"
68+
u[𝑖] = ϕᵢ[𝑖] / (twocellnanmean(ρ, 𝑖, 𝑗) * twocellnanmin(thkcello, 𝑖, 𝑗) * edge_length_2D[:east][i, j])
69+
𝑗 = j₊₁(𝑖, gridtopology) # grid cell to the "north"
70+
v[𝑖] = ϕⱼ[𝑖] / (twocellnanmean(ρ, 𝑖, 𝑗) * twocellnanmin(thkcello, 𝑖, 𝑗) * edge_length_2D[:north][i, j])
71+
end
72+
73+
return u, v
74+
end
75+
4176
"""
4277
twocellnanmean(x, 𝑖, 𝑗)
4378

test/local_full.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,4 +297,10 @@ end
297297
save(outputfile, fig)
298298
end
299299

300+
# Round-trip test: velocity → fluxes → velocity should recover the C-grid velocities
301+
u_cgrid, _, _, v_cgrid, _, _ = OceanTransportMatrixBuilder.interpolateontodefaultCgrid(uo, uo_lon, uo_lat, vo, vo_lon, vo_lat, gridmetrics)
302+
u_rec, v_rec = fluxes2velocity(umo_bis, vmo_bis, gridmetrics, ρ)
303+
@test u_rec[wet3D] u_cgrid[wet3D]
304+
@test v_rec[wet3D] v_cgrid[wet3D]
305+
300306
end

test/test_fluxes2velocity.jl

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Standalone round-trip test for fluxes2velocity
2+
# Run with: julia --project test/test_fluxes2velocity.jl
3+
4+
using Test
5+
using OceanTransportMatrixBuilder
6+
using NetCDF
7+
using YAXArrays
8+
using GibbsSeaWater
9+
using DimensionalData
10+
using NaNStatistics
11+
12+
model = "ACCESS-ESM1-5"
13+
member = "r1i1p1f1"
14+
inputdir = "$(ENV["HOME"])/Data/TMIP/data/$model/historical/$member/Jan1990-Dec1999"
15+
16+
# Load datasets
17+
uo_ds = open_dataset(joinpath(inputdir, "uo.nc"))
18+
vo_ds = open_dataset(joinpath(inputdir, "vo.nc"))
19+
volcello_ds = open_dataset(joinpath(inputdir, "volcello.nc"))
20+
areacello_ds = open_dataset(joinpath(inputdir, "areacello.nc"))
21+
thetao_ds = open_dataset(joinpath(inputdir, "thetao.nc"))
22+
so_ds = open_dataset(joinpath(inputdir, "so.nc"))
23+
24+
areacello = readcubedata(areacello_ds.areacello)
25+
volcello = readcubedata(volcello_ds.volcello)
26+
lon = readcubedata(volcello_ds.lon)
27+
lat = readcubedata(volcello_ds.lat)
28+
lev = volcello_ds.lev
29+
lon_vertices = readcubedata(volcello_ds.lon_verticies)
30+
lat_vertices = readcubedata(volcello_ds.lat_verticies)
31+
uo = readcubedata(uo_ds.uo)
32+
vo = readcubedata(vo_ds.vo)
33+
uo_lon = readcubedata(uo_ds.lon)
34+
uo_lat = readcubedata(uo_ds.lat)
35+
vo_lon = readcubedata(vo_ds.lon)
36+
vo_lat = readcubedata(vo_ds.lat)
37+
thetao = readcubedata(thetao_ds.thetao) |> Array
38+
so = readcubedata(so_ds.so) |> Array
39+
40+
gridmetrics = makegridmetrics(; areacello, volcello, lon, lat, lev, lon_vertices, lat_vertices)
41+
(; Z3D, v3D) = gridmetrics
42+
ct = gsw_ct_from_pt.(so, thetao)
43+
ρ = gsw_rho.(so, ct, Z3D)
44+
indices = makeindices(v3D)
45+
(; wet3D) = indices
46+
47+
# Round-trip: velocity → flux → velocity
48+
u_cgrid, _, _, v_cgrid, _, _ = OceanTransportMatrixBuilder.interpolateontodefaultCgrid(uo, uo_lon, uo_lat, vo, vo_lon, vo_lat, gridmetrics)
49+
umo_bis, vmo_bis = velocity2fluxes(uo, uo_lon, uo_lat, vo, vo_lon, vo_lat, gridmetrics, ρ)
50+
u_rec, v_rec = fluxes2velocity(umo_bis, vmo_bis, gridmetrics, ρ)
51+
52+
@test u_rec[wet3D] u_cgrid[wet3D]
53+
@test v_rec[wet3D] v_cgrid[wet3D]
54+
55+
println("All tests passed!")

0 commit comments

Comments
 (0)