Skip to content

Commit 37fec0e

Browse files
committed
Add OCIM2-48L circulation model
1 parent 2f2e0d7 commit 37fec0e

File tree

4 files changed

+175
-1
lines changed

4 files changed

+175
-1
lines changed

CITATION.bib

+12
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,18 @@ @article{DeVries_Holzer_2019
9090
year = {2019}
9191
}
9292

93+
OCIM2_48L
94+
@article{Holzer_etal_2021,
95+
author = {Holzer, Mark and DeVries, Tim and {de Lavergne}, Casimir},
96+
year = {2021},
97+
journal = {Nature Communications},
98+
volume = {12},
99+
number = {1},
100+
pages = {4348},
101+
issn = {2041-1723},
102+
doi = {10.1038/s41467-021-24648-x}
103+
}
104+
93105
POP
94106
Coming soon!
95107

Project.toml

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "AIBECS"
22
uuid = "ace601d6-714c-11e9-04e5-89b7fad23838"
33
authors = ["Benoit Pasquier <[email protected]>"]
4-
version = "0.11.3"
4+
version = "0.12.0"
55

66
[deps]
77
Bijectors = "76274a88-744f-5084-9051-94815aaf08c4"
@@ -19,6 +19,7 @@ ImageFiltering = "6a3955dd-da59-5b1f-98d4-e7296123deb5"
1919
Interpolations = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59"
2020
JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819"
2121
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
22+
MAT = "23992714-dd62-5051-b70f-ba57cb901cac"
2223
MetadataArrays = "49441bc9-da82-574f-b07c-a0d10dd4ac13"
2324
NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab"
2425
NearestNeighbors = "b8a86587-4115-5ab1-83bc-aa920d37bbce"
@@ -48,6 +49,7 @@ ForwardDiff = "0.10"
4849
ImageFiltering = "0.6, 0.7"
4950
Interpolations = "0.12, 0.13"
5051
JLD2 = "0.4"
52+
MAT = "0.10"
5153
MetadataArrays = "0.1"
5254
NCDatasets = "0.10, 0.11, 0.12"
5355
NearestNeighbors = "0.4"

src/AIBECS.jl

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ include("multiTracer.jl")
4444
include("OCIM0.jl")
4545
include("OCIM1.jl")
4646
include("OCIM2.jl")
47+
include("OCIM2_48L.jl")
4748
include("OCCA.jl")
4849
include("Archer_etal_2000.jl")
4950
include("TwoBoxModel.jl")

src/OCIM2_48L.jl

+159
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
"""
2+
This `OCIM2_48L` module is used to load the OCIM2-48L matrices and grid for use in AIBECS.
3+
4+
!!! tip
5+
To load the default OCIM2_48L matrix and grid, do
6+
```
7+
julia> grd, T = OCIM2_48L.load()
8+
```
9+
But you can also load the other matrices by specifying which version you want, e.g.,
10+
```
11+
julia> grd, T = OCIM2_48L.load(version="OCIM2_48L_KiHIGH_noHe")
12+
```
13+
See *DeVries and Holzer* (2019) for more details
14+
15+
16+
!!! note
17+
The files, that are downloaded from a public and persistant URL in FigShare,
18+
were created with the code available at https://github.com/briochemc/OceanCirculations.
19+
"""
20+
module OCIM2_48L
21+
22+
using SparseArrays # for sparse matrix
23+
using DataDeps # for automated download/storage of data
24+
using Downloads
25+
using MAT # for reading OCIM2_48L transport operator matrix from MAT file
26+
using NCDatasets # for reading OCIM2_48L grid from NetCDF file
27+
using Unitful # for units
28+
using Unitful: s, yr, m, km, °
29+
using Reexport
30+
@reexport using OceanGrids # To store the grid
31+
32+
function fallback_download(remotepath, localdir)
33+
@assert(isdir(localdir))
34+
filename = basename(remotepath) # only works for URLs with filename as last part of name
35+
localpath = joinpath(localdir, filename)
36+
Downloads.download(remotepath, localpath)
37+
return localpath
38+
end
39+
40+
# OCIM2_48L URL
41+
url() = "https://files.figshare.com/28468077/OCIM2_48L_base.tar.gz"
42+
43+
# OCIM2_48L Hashes
44+
sha() = "7c6e7981df69122957c9f2475be7ffe958819ff44d02be6d004886b6dfc3fac7"
45+
46+
OCIM2versionerror(version) = error("""`$version` is not a valid OCIM2 version name.
47+
48+
Valid versions are `CTL_He`, `CTL_noHe`, `KiHIGH_He`, `KiHIGH_noHe`, `KiLOW_He`, `KiLOW_noHe`, `KvHIGH_He`, `KvHIGH_KiHIGH_noHe`, `KvHIGH_KiLOW_He`, `KvHIGH_KiLOW_noHe`, and `KvHIGH_noHe`.
49+
50+
See *DeVries and Holzer* (2019) for more details on OCIM2 configurations.""")
51+
52+
53+
# Create registry entry for OCIM in JLD2 format
54+
function register_OCIM2_48L()
55+
register(
56+
DataDep(
57+
"AIBECS-OCIM2_48L",
58+
"""
59+
References:
60+
- $(citations())
61+
""",
62+
url(),
63+
sha(),
64+
fetch_method = fallback_download,
65+
post_fetch_method = unpack
66+
)
67+
)
68+
return nothing
69+
end
70+
71+
"""
72+
load
73+
74+
Returns the grid and the transport matrix of the OCIM2_48L model.
75+
76+
See *DeVries and Holzer* (2019) and *Holzer et al.* (2021) for more details.
77+
"""
78+
function load()
79+
register_OCIM2_48L()
80+
files_path = @datadep_str "AIBECS-OCIM2_48L"
81+
@info """You are about to use the OCIM2_48L model.
82+
If you use it for research, please cite:
83+
84+
$(citations())
85+
86+
You can find the corresponding BibTeX entries in the CITATION.bib file
87+
at the root of the AIBECS.jl package repository.
88+
(Look for the "DeVries_Holzer_2019" and "Holzer_etal_2021" keys.)
89+
"""
90+
91+
# Convert convergence T in yr⁻¹ from original MAT file to divergence T in s⁻¹
92+
T = -ustrip.(s^-1, matread(joinpath(files_path, "OCIM2_48L_base_transport.mat"))["TR"] * yr^-1);
93+
94+
# Create grid object from NetCDF file variables
95+
# TODO: Add Hyrothermal He fluxes as for the OCIM2 load function
96+
grid = Dataset(joinpath(files_path, "OCIM2_48L_base_data.nc"), "r") do ds
97+
wet3D = ds["ocnmask"][:] .== 1
98+
nlat, nlon, ndepth = size(wet3D)
99+
lat_3D = ds["tlat"][:]°
100+
lon_3D = ds["tlon"][:]°
101+
depth_3D = ds["tz"][:]m
102+
lat = unique(lat_3D)
103+
lon = unique(lon_3D)
104+
depth = unique(depth_3D)
105+
ulat = unique(ds["ulon"][:])° # ulat↔ulon in OCIM2-48L original files
106+
ulon = unique(ds["ulat"][:])° # ulat↔ulon in OCIM2-48L original files
107+
depth_top_3D = ds["wz"][:]m
108+
depth_top = unique(depth_top_3D)
109+
δlat = 2(ulat - lat)
110+
δlon = 2(ulon - lon)
111+
δdepth = 2(depth - depth_top)
112+
R = 6371.0km
113+
δy = R * δlat ./ 360°
114+
δy_3D = repeat(reshape(δy, (nlat,1,1)), outer=(1,nlon,ndepth))
115+
A_3D = ds["area"][:]m^2
116+
δx_3D = A_3D ./ δy_3D
117+
volume_3D = ds["vol"]m^3
118+
δz_3D = volume_3D ./ A_3D
119+
A_2D = A_3D[:,:,1]
120+
nboxes = count(wet3D)
121+
OceanRectilinearGrid(
122+
lat,
123+
lon,
124+
depth,
125+
δlat,
126+
δlon,
127+
δdepth,
128+
lat_3D,
129+
lon_3D,
130+
depth_3D,
131+
δy,
132+
δx_3D,
133+
δy_3D,
134+
δz_3D,
135+
volume_3D,
136+
depth_top,
137+
depth_top_3D,
138+
A_2D,
139+
wet3D,
140+
nlon,
141+
nlat,
142+
ndepth,
143+
nboxes
144+
)
145+
end
146+
147+
return grid, T
148+
149+
end
150+
151+
citations() = """
152+
- Holzer, M., DeVries, T. & de Lavergne, C. Diffusion controls the ventilation of a Pacific Shadow Zone above abyssal overturning. Nat Commun 12, 4348 (2021). https://doi.org/10.1038/s41467-021-24648-x
153+
- DeVries, T., & Holzer, M. (2019). Radiocarbon and helium isotope constraints on deep ocean ventilation and mantle-3He sources. Journal of Geophysical Research: Oceans, 124, 3036–3057. https://doi.org/10.1029/2018JC014716
154+
"""
155+
156+
end # end module
157+
158+
export OCIM2_48L
159+

0 commit comments

Comments
 (0)