Yes, that’s a good idea. Here is my working example: I am running a simulation in the context of physical oceanography.
I have a 4D matrix u
(velocity) with x, y, z
(Cartesian coordinates), and time in the 4th dimension. The domain has rough topography at the bottom, so the deepest depth at each x
and y
is not the same, similar to our real ocean. My goal is to take terrain-following horizontal averages, i.e., dims=(1,2), in the height-above-bottom coordinate.
For example, if I want to take the horizontal average of u
at 20 meters above the topography, I need to find every point in the x
and y
(horizontal) dimensions that are 20 meters above the corresponding topography and average all these points.
This can be done using for loops. Thanks to @stevengj’s suggestion, my goal is to optimize the code as efficiently as possible owing to the fact that broadcasting functions might not be more efficient. So any suggestions or tips on optimization would be great.
The code for my terrain-following average is below:
using Interpolations
Nx = 500; Ny = 1000; Nz = 250;
# hab: height above bottom coordinate;
# zC is a vector indicating the vertical grid points
# z_topography(x,y) is a 2D matrix showing the depth of the topography at each points
hab = ones(Nx,Ny).*reshape(zC,1,1,Nz) .- z_topography
new_height = 0:40:3000. # desired height above bottom grids
hab_interp = zeros(Nx,Ny,Nz)
function terrain_following_avg(hab, u, new_height)
u_interp = zeros(Nx, Ny, length(new_height), size(u,4))
for i in 1:Nx, j in 1:Ny
for tt = 1:size(u,4)
hab_interp = hab[i, j, :]
itp = interpolate((hab_interp,), u[i, j, :, tt], Gridded(Linear()))
itp_extrapolated = extrapolate(itp, Interpolations.Flat())
u_interp[i, j, :, tt] .= itp_extrapolated.(new_height)
end
end
return dropdims(mean(u_interp,dims=(1,2)) , dims=(1,2))
end
# call the function to get the terrain following averaged velocity (assuming u is a 4D matrix)
u_avg = terrain_following_avg(hab, u, new_height);
The result should be a 2D matrix in terms of z and time. (I am not sure if this post should be a new discussion since this is a little off track to my original question regarding broadcasting.)