Skip to content

Commit bda0bcb

Browse files
authored
Merge pull request #204 from CHLNDDEV/interp_irregular_grid_fix
Fix for irregular grid in FindLinearIdx
2 parents 8fdc5ba + 08bcb7d commit bda0bcb

File tree

7 files changed

+113
-16
lines changed

7 files changed

+113
-16
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
146146
## Fixed
147147
- Correctly deleting weirs from boundary object through `make_bc` delete method. See https://github.com/CHLNDDEV/OceanMesh2D/pull/205
148148
- Array format fix for reading in ibtype and nvell from fort.14 file and when executing carry_over_weirs. See https://github.com/CHLNDDEV/OceanMesh2D/pull/206
149+
- Fix for irregular grid spacings in DEMs. See https://github.com/CHLNDDEV/OceanMesh2D/pull/204
149150

150151
### [4.0.0] - 2021-03-14
151152
## Added

Tests/RunTests.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
TestSanity
1616

1717
TestEleSizes
18+
19+
TestInterp
1820

1921
if exist('SRTM15+V2.1.nc')
2022

Tests/TestInterp.m

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
%% Test for the msh.interp() method using topo-bathy
2+
%% DEMs with following grid spacings:
3+
% i) constant dx = constant dy
4+
% ii) constant dx ~= constant dy
5+
% iii) varying dx ~= varying dy
6+
cd ..
7+
8+
addpath(genpath('utilities/'))
9+
addpath(genpath('datasets/'))
10+
addpath(genpath('m_map/'))
11+
12+
% add the geospatial data filenames
13+
coastline = 'GSHHS_f_L1';
14+
DEMS = ["CUDEM_equal.nc" "CUDEM_unequal.nc" "CUDEM_varying.nc"];
15+
16+
% meshing parameters
17+
min_el = 40; % minimum resolution in meters.
18+
max_el = 500; % maximum resolution in meters.
19+
grade = 0.25; % mesh grade in decimal percent.
20+
dis = grade; % increasing resolution with distance from shoreline.
21+
22+
volumes = [];
23+
% loop over the different DEMs
24+
for dem = DEMS
25+
dem_name = dem{1};
26+
%x = ncread(dem_name,'lon');
27+
%y = ncread(dem_name,'lat');
28+
%min(diff(x))
29+
%max(diff(x))
30+
%min(diff(y))
31+
%max(diff(y))
32+
%continue
33+
34+
gdat = geodata('shp',coastline,'dem',dem_name,'h0',min_el);
35+
36+
fh = edgefx('geodata',gdat,...
37+
'dis',dis,'max_el',max_el,'g',grade);
38+
39+
mshopts = meshgen('ef',fh,'bou',gdat,...
40+
'plot_on',0,'proj','utm');
41+
mshopts = mshopts.build;
42+
43+
m = mshopts.grd;
44+
45+
m = interp(m,dem_name);
46+
47+
%plot(m,'type','bmesh')
48+
%print([dem_name(1:end-3) '_bmesh.png'],'-r300','-dpng')
49+
50+
% compute the volume of the mesh
51+
x = m.p(:,1); y = m.p(:,2);
52+
areas = polyarea(x(m.t)',y(m.t)');
53+
[~,bc] = baryc(m);
54+
volumes = [volumes areas*bc];
55+
end
56+
57+
% Check the different mesh volumes
58+
disp('Mesh volumes:')
59+
disp(volumes)
60+
61+
volume_diff = (max(volumes)-min(volumes))/mean(volumes);
62+
disp('Maximum relative volume difference:')
63+
disp(volume_diff)
64+
65+
if volume_diff > 0.001
66+
error('Mesh volumes are too disparate with different dems')
67+
disp('Not Passed: Interp');
68+
else
69+
disp('Mesh volumes are within 0.1% of each other')
70+
disp('Passed: Interp');
71+
end

datasets/CUDEMS/CUDEM_equal.nc

1.61 MB
Binary file not shown.

datasets/CUDEMS/CUDEM_unequal.nc

1.71 MB
Binary file not shown.

datasets/CUDEMS/CUDEM_varying.nc

4.02 MB
Binary file not shown.

utilities/FindLinearIdx.m

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,55 @@
44
% lon and lat must be matrices created by ndgrid.
55
% kjr, 20171210 chl, und.
66
% wjp, 20201120 making sure dx and dy can be different
7+
% 20200325 implementing method for irregular grid, cleaning up
78
ny = size(lon,1);
89
nx = size(lon,2);
910
np = numel(x);
1011

11-
X = reshape(lon,[],1);
12-
Y = reshape(lat,[],1);
12+
% make sure entry points are column vectors
13+
x = x(:);
14+
y = y(:);
1315

1416
% Get the grid spacing in x and y directions
1517
% (trying both directions so could be meshgrid or ndgrid format)
16-
dx = max(abs(lon(2,1)-lon(1,1)),abs(lon(1,2)-lon(1,1)));
17-
dy = max(abs(lat(1,2)-lat(1,1)),abs(lat(2,1)-lat(1,1)));
18+
dx = diff(lon(:,1));
19+
dy = diff(lat(1,:));
1820

19-
x = x(:);
20-
y = y(:);
21+
if max(dx) ~= min(dx) || max(dy) ~= min(dy)
22+
% % IRREGULAR GRID (SLOWER)
23+
24+
% convert ndgrid to vector
25+
lonV = reshape(lon(:,1),1,[]);
26+
% repeat the vector along the length of x
27+
LON = repmat(lonV,np,1);
28+
% find the closest lon to each point of x
29+
[~,IX1] = min(abs(x - LON),[],2);
30+
31+
% convert ndgrid to vector
32+
latV = lat(1,:);
33+
% repeat the vector along the length of y
34+
LAT = repmat(latV,np,1);
35+
% find the closest lon to each point of y
36+
[~,IX2] = min(abs(y - LAT),[],2);
2137

22-
IX1 = (x-X(1))./dx + 1;
23-
IX2 = (y-Y(1))./dy + 1;
38+
else
39+
% % REGULAR GRID (FASTER)
40+
dx = dx(1); dy = dy(1);
2441

25-
IX1 = round(IX1);
26-
IX2 = round(IX2);
42+
IX1 = (x-lon(1,1))/dx + 1;
43+
IX2 = (y-lat(1,1))/dy + 1;
2744

28-
IX1 = max([IX1,ones(np,1)],[],2);
29-
IX1 = min([IX1,ny*ones(np,1)],[],2);
30-
%
31-
IX2 = max([IX2,ones(np,1)],[],2);
32-
IX2 = min([IX2,nx*ones(np,1)],[],2);
45+
IX1 = round(IX1);
46+
IX2 = round(IX2);
47+
48+
IX1 = max([IX1,ones(np,1)],[],2);
49+
IX1 = min([IX1,ny*ones(np,1)],[],2);
50+
51+
IX2 = max([IX2,ones(np,1)],[],2);
52+
IX2 = min([IX2,nx*ones(np,1)],[],2);
53+
54+
end
3355

3456
IX = sub2ind([ny,nx],IX1,IX2);
35-
end
57+
58+
end

0 commit comments

Comments
 (0)