Skip to content

Commit 76ffbfd

Browse files
committed
Add regional coarsening function
1 parent 36a416e commit 76ffbfd

File tree

4 files changed

+43
-57
lines changed

4 files changed

+43
-57
lines changed

.zenodo.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"creators": [
77
{
88
"orcid": "0000-0002-3838-5976",
9-
"affiliation": "Contract Researcher for CSIRO; Adjunct Fellow at the School of Mathematics and Statistics, UNSW, Sydney, AU",
9+
"affiliation": "Research Associate, CCRC, UNSW, Sydney, AU",
1010
"name": "Benoît Pasquier"
1111
}
1212
],
@@ -22,6 +22,12 @@
2222
"affiliation": "CSIRO, Hobart, AU",
2323
"name": "Richard J. Matear",
2424
"type": "Supervisor"
25+
},
26+
{
27+
"orcid": "0000-0002-5068-1591",
28+
"affiliation": "CCRC, UNSW, Sydney, AU",
29+
"name": "Laurie C. Menviel",
30+
"type": "Supervisor"
2531
}
2632
],
2733
"keywords": [

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "OceanTransportMatrixBuilder"
22
uuid = "c2b4a04e-6049-4fc4-aa6a-5508a29a1e1c"
33
authors = ["Benoit Pasquier <[email protected]> and contributors"]
4-
version = "0.5.5"
4+
version = "0.6.0"
55

66
[deps]
77
Distances = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7"

src/extratools.jl

Lines changed: 34 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
"""
2-
LUMP, SPRAY = lump_and_spray(wet3D, volume; di=2, dj=2, dk=1)
2+
LUMP, SPRAY, v_c = lump_and_spray(wet3D, volume; f=Returns(true),di=2, dj=2, dk=1)
33
4-
returns the LUMP and SPRAY matrices that go with the
5-
coarsened grid (also returned).
4+
returns the LUMP and SPRAY matrices, and the coarsened volume vector.
65
76
To get the coarsened vector from fine vector x, use
87
@@ -23,58 +22,43 @@ will lump:
2322
- every 4 cells in the y direction (lat),
2423
- and every 1 cell (default) in the z direction (depth).
2524
26-
Expected grid arrangement is OCIM2 like, i.e.,
27-
lat × lon × depth.
25+
The optional function argument `f` can be used to specify a region
26+
where the lumping should occur.
27+
`f` should be a function of the indices, e.g.,
2828
29-
You can also provide a vector of indices instead of a scalar
30-
in order to customize the coarsening. For example,
29+
f(i,j,k) = lat[i,j] > -40 # only lump north of 40°S
3130
32-
lump_and_spray(wet3D, volume; di=[1 1 1 1 1 1 1 2 2 2 ... n])
33-
34-
will lump all the boxes in the x dimension that are marked
35-
with a 1, then all those marked with a 2, and so on.
36-
Confusing? Let me give a practical example. Say you want to
37-
coarsen the ACCESS grid in the vertical to match the OCIM grid.
38-
The you can do
39-
40-
[~, zidx] = min(abs(ACCESSgrd.zt - OCIMgrd.zt'), [], 1)
41-
42-
to get the OCIM2 z-indices that are closest to the
43-
ACCESS z-indices. And then you can pass it to this function via
44-
45-
lump_and_spray(wet3D, volume; dk=zidx)
46-
47-
TODO: Fix these docs that have not been fully translated from MATLAB version.
31+
Outside of this region, no lumping.
32+
Default is `f=Returns(true)`, i.e. lump everywhere.
4833
"""
49-
lump_and_spray(wet3D, volume; di=2, dj=2, dk=1) = _lump_and_spray(wet3D, volume, di, dj, dk)
50-
function _lump_and_spray(wet3D, volume, di::Int, dj::Int, dk::Int)
51-
# grd wet array and vector and sizes
52-
nx, ny, nz = size(wet3D)
53-
# Convert scalar lumping options into lumping indices vector
54-
# So that syntax like `di=2` works
55-
vi = repeat(1:nx, inner=di)[1:nx]
56-
vj = repeat(1:ny, inner=dj)[1:ny]
57-
vk = repeat(1:nz, inner=dk)[1:nz]
58-
59-
return _lump_and_spray(wet3D, volume, vi, vj, vk)
60-
end
61-
function _lump_and_spray(wet3D, volume, vi, vj, vk)
62-
wet = wet3D[:]
63-
nx, ny, nz = size(wet3D)
64-
# Create lumping matrices in each dimension
65-
LUMPx = sparse(vi, 1:nx, true)
66-
LUMPy = sparse(vj, 1:ny, true)
67-
LUMPz = sparse(vk, 1:nz, true)
68-
# kron each dimension to build whole LUMP matrix
69-
LUMP = kron(LUMPz, kron(LUMPy, LUMPx))
34+
function lump_and_spray(wet3D, volume; f=Returns(true), di=2, dj=2, dk=1)
35+
36+
# extend the grid to avoid lumping cells outside of bounds
37+
nxyz = size(wet3D)
38+
LUMPidx = zeros(Int, nxyz .+ (di - 1, dj - 1, dk - 1))
39+
40+
# loop once over all grid cells and assign lumped indices
41+
c = 1 # index / counter
42+
neighbours = CartesianIndices((0:di-1, 0:dj-1, 0:dk-1))
43+
C = CartesianIndices(nxyz)
44+
for 𝑖 in eachindex(C)
45+
C𝑖 = C[𝑖]
46+
i, j, k = C𝑖.I
47+
# assign index if not indexed yet
48+
if LUMPidx[C𝑖] == 0
49+
if f(i,j,k) # to all lumped cells if in region
50+
LUMPidx[C𝑖 .+ neighbours] .= c
51+
else # to only this cell if outside region
52+
LUMPidx[C𝑖] = c
53+
end
54+
c += 1
55+
end
56+
end
57+
LUMP = sparse(LUMPidx[:], 1:length(LUMPidx), 1)
7058

7159
# Find wet points in coarsened grid
60+
wet = wet3D[:]
7261
wet_c = LUMP * wet .> 0
73-
nx_c = vi[end]
74-
ny_c = vj[end]
75-
nz_c = vk[end]
76-
wet3D_c = fill(false, nx_c, ny_c, nz_c)
77-
wet3D_c[wet_c] .= true
7862

7963
# Extract only indices of wet grd points
8064
LUMP = LUMP[wet_c, wet]
@@ -90,17 +74,13 @@ function _lump_and_spray(wet3D, volume, vi, vj, vk)
9074
SPRAY = copy(LUMP')
9175
SPRAY.nzval .= 1
9276

93-
return LUMP, SPRAY, wet3D_c, volume_c
77+
return LUMP, SPRAY, volume_c
9478
end
9579

9680

9781

9882

9983

100-
101-
102-
103-
10484
"""
10585
as2D(x, wet3D)
10686

test/local_full.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ end
128128
v = v3D[wet3D]
129129

130130
@info "coarsening grid"
131-
LUMP, SPRAY, wet3D_c, v_c = OceanTransportMatrixBuilder.lump_and_spray(wet3D, v; di=2, dj=2, dk=1)
131+
LUMP, SPRAY, v_c = OceanTransportMatrixBuilder.lump_and_spray(wet3D, v; di=2, dj=2, dk=1)
132132

133133
# surface mask
134134
issrf3D = copy(wet3D)

0 commit comments

Comments
 (0)