Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmerice/Meshers/MshGlacierDEM.F90
3196 views
1
!/*****************************************************************************/
2
! *
3
! * Elmer/Ice, a glaciological add-on to Elmer
4
! * http://elmerice.elmerfem.org
5
! *
6
! *
7
! * This program is free software; you can redistribute it and/or
8
! * modify it under the terms of the GNU General Public License
9
! * as published by the Free Software Foundation; either version 2
10
! * of the License, or (at your option) any later version.
11
! *
12
! * This program is distributed in the hope that it will be useful,
13
! * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
! * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
! * GNU General Public License for more details.
16
! *
17
! * You should have received a copy of the GNU General Public License
18
! * along with this program (in file fem/GPL-2); if not, write to the
19
! * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20
! * Boston, MA 02110-1301, USA.
21
! *
22
! *****************************************************************************/
23
! ******************************************************************************
24
! *
25
! * Authors: Olivier Gagliardini
26
! * Email:
27
! * Web: http://elmerice.elmerfem.org
28
! *
29
! * Original Date:
30
! *
31
! *****************************************************************************
32
!> Create a 3D mesh given by its bed and surface topography
33
!> given as structured Grid DEMs (x, y, z)
34
!> Add some testing to ensure the file structure does correspond to what is
35
!> indicated in mesh_input.dat
36
! *****************************************************************************
37
PROGRAM MshGlacierDEM
38
USE types
39
USE DefUtils
40
41
IMPLICIT NONE
42
REAL(KIND=dp) :: x, y, z
43
REAL(KIND=dp), ALLOCATABLE :: xb(:), yb(:), zb(:), xs(:), &
44
ys(:), zs(:)
45
REAL(KIND=dp), ALLOCATABLE :: xnode(:), ynode(:), znode(:)
46
INTEGER, ALLOCATABLE :: Node(:)
47
CHARACTER :: NameMsh*30, Rien*1, NameSurf*30, NameBed*30
48
Character(len=10) :: iNp, iNN
49
REAL(KIND=dp) :: dsx, dsy, dbx, dby, x1, x2, y1, y2, zi(2,2)
50
REAL(KIND=dp) :: xs0, ys0, xb0, yb0, zbed, zsurf, znew, Rmin, R
51
REAL(KIND=dp) :: lsx, lsy, lbx, lby, hmin
52
INTEGER :: NtN, i, j, Ns, Nsx, Nsy, Nb, Nbx, Nby, n, Npt, ix, iy, imin, is, ib
53
Integer k, Np
54
Logical :: Serial = .False.
55
56
!
57
! Read data input from mesh_input.dat
58
!
59
OPEN(10,file="mesh_input.dat")
60
READ(10,*)Rien
61
READ(10,*)NameMsh
62
READ(10,*)Rien
63
READ(10,*)NameSurf
64
READ(10,*)Rien
65
READ(10,*)Nsx, Nsy
66
READ(10,*)Rien
67
READ(10,*)xs0, ys0
68
READ(10,*)Rien
69
READ(10,*)lsx, lsy
70
READ(10,*)Rien
71
READ(10,*)NameBed
72
READ(10,*)Rien
73
READ(10,*)Nbx, Nby
74
READ(10,*)Rien
75
READ(10,*)xb0, yb0
76
READ(10,*)Rien
77
READ(10,*)lbx, lby
78
READ(10,*)Rien
79
READ(10,*)hmin
80
READ(10,*)Rien
81
READ(10,*)Np
82
CLOSE(10)
83
84
Ns = Nsx*Nsy
85
Nb = Nbx*Nby
86
ALLOCATE(xs(Ns), ys(Ns), zs(Ns))
87
ALLOCATE(xb(Nb), yb(Nb), zb(Nb))
88
89
dsx = lsx / (Nsx-1.0)
90
dsy = lsy / (Nsy-1.0)
91
dbx = lbx / (Nbx-1.0)
92
dby = lby / (Nby-1.0)
93
94
IF (Np==1) Serial=.True.
95
96
IF (.NOT.Serial) THEN
97
IF (Np < 10) THEN
98
WRITE(iNp,'(i1.1)')Np
99
ELSE IF (Np < 100) THEN
100
WRITE(iNp,'(i2.2)')Np
101
ELSE IF (Np < 1000) THEN
102
WRITE(iNp,'(i3.3)')Np
103
ELSE IF (Np < 10000) THEN
104
WRITE(iNp,'(i4.4)')Np
105
ELSE
106
WRITE(*,*)'Work for a number of partitions < 1000'
107
STOP
108
END IF
109
iNp = ADJUSTL(iNp)
110
END IF
111
112
WRITE(*,*)'Ns, Nb',Ns,Nb
113
WRITE(*,*)'dx, dy',dsx,dsy,dbx,dby
114
115
!-------------------------------------------------------------
116
! Load Bedrock and Surface DEMs and make some verifications
117
!-------------------------------------------------------------
118
OPEN(10,file=TRIM(NameSurf))
119
READ(10,*)(xs(i), ys(i), zs(i), i=1,Ns)
120
CLOSE(10)
121
122
OPEN(10,file=TRIM(NameBed))
123
READ(10,*)(xb(i), yb(i), zb(i), i=1,Nb)
124
CLOSE(10)
125
126
k = 0
127
DO j = 1, Nsy
128
y = ys0 + dsy*(j-1)
129
DO i = 1, Nsx
130
k = k + 1
131
x = xs0 + dsx*(i-1)
132
IF ((ABS(x-xs(k))>1.0e-6*dsx).OR.(ABS(y-ys(k))>1.0e-6*dsy)) THEN
133
WRITE(*,*)'Structure of the DEM is not conforming to what is in mesh_input.dat for Surface DEM'
134
WRITE(*,*)'Found that point ',k,' coordinate is ',xs(k),ys(k),' whereas it should be ',x,y
135
STOP
136
END IF
137
END DO
138
END DO
139
k = 0
140
DO j = 1, Nby
141
y = yb0 + dby*(j-1)
142
DO i = 1, Nbx
143
k = k + 1
144
x = xb0 + dbx*(i-1)
145
IF ((ABS(x-xb(k))>1.0e-6*dbx).OR.(ABS(y-yb(k))>1.0e-6*dby)) THEN
146
WRITE(*,*)'Structure of the DEM is not conforming to what is in mesh_input.dat for Surface DEM'
147
WRITE(*,*)'Found that point ',k,' coordinate is ',xb(k),yb(k),' whereas it should be ',x,y
148
STOP
149
END IF
150
END DO
151
END DO
152
!-------------------------------------------------------------
153
! Loop over the Np partitions
154
!-------------------------------------------------------------
155
DO k = 1, Np
156
WRITE(*,*)k,' of ', Np, ' partitions'
157
158
IF (.NOT.Serial) THEN
159
IF (k < 10) THEN
160
WRITE(iNN,'(i1.1)')k
161
ELSE IF (k < 100) THEN
162
WRITE(iNN,'(i2.2)')k
163
ELSE IF (k < 1000) THEN
164
WRITE(iNN,'(i3.3)')k
165
ELSE IF (k < 10000) THEN
166
WRITE(iNN,'(i4.4)')k
167
END IF
168
iNN = ADJUSTL(iNN)
169
170
OPEN(11,file=TRIM(NameMsh)//"/partitioning."//TRIM(iNp)//"/part."//TRIM(iNN)//".header")
171
ELSE
172
OPEN(11,file=TRIM(NameMsh)//"/mesh.header")
173
END IF
174
175
READ(11,*)NtN
176
CLOSE(11)
177
178
ALLOCATE (Node(NtN), xnode(NtN), ynode(NtN), znode(NtN))
179
WRITE(*,*)'Part ', k, ' NtN = ', NtN
180
181
IF (.NOT.Serial) THEN
182
OPEN(12,file=TRIM(NameMsh)//"/partitioning."//TRIM(iNp)//"/part."//TRIM(iNN)//".nodes")
183
ELSE
184
OPEN(12,file=TRIM(NameMsh)//"/mesh.nodes")
185
END IF
186
READ(12,*)(Node(i), j, xnode(i), ynode(i), znode(i), i=1,NtN)
187
REWIND(12)
188
189
! Make some verifications that all nodes are included in the DEMs
190
IF (((MINVAL(xnode)<MINVAL(xs)).OR.(MAXVAL(xnode)>MAXVAL(xs))).OR. &
191
((MINVAL(ynode)<MINVAL(ys)).OR.(MAXVAL(ynode)>MAXVAL(ys)))) THEN
192
WRITE(*,*)'Some nodes are outside of the Surface DEM'
193
WRITE(*,*)'DEM xmin, ymin, xmax, ymax: ', &
194
MINVAL(xs),MINVAL(ys),MAXVAL(xs),MAXVAL(ys)
195
WRITE(*,*)'Mesh xmin, ymin, xmax, ymax: ', &
196
MINVAL(xnode),MINVAL(ynode),MAXVAL(xnode),MAXVAL(ynode)
197
STOP
198
END IF
199
200
IF (((MINVAL(xnode)<MINVAL(xb)).OR.(MAXVAL(xnode)>MAXVAL(xb))).OR. &
201
((MINVAL(ynode)<MINVAL(yb)).OR.(MAXVAL(ynode)>MAXVAL(yb)))) THEN
202
WRITE(*,*)'Some nodes are outside of the bedrock DEM'
203
WRITE(*,*)'DEM xmin, ymin, xmax, ymax: ', &
204
MINVAL(xb),MINVAL(yb),MAXVAL(xb),MAXVAL(yb)
205
WRITE(*,*)'Mesh xmin, ymin, xmax, ymax: ', &
206
MINVAL(xnode),MINVAL(ynode),MAXVAL(xnode),MAXVAL(ynode)
207
STOP
208
END IF
209
210
DO n=1, NtN
211
x = xnode(n)
212
y = ynode(n)
213
z = znode(n)
214
215
! Find zbed for that point from the Bedrock MNT
216
ix = INT((x-xb0)/dbx)+1
217
IF (x.EQ.(xb0+lbx)) ix=ix-1
218
iy = INT((y-yb0)/dby)+1
219
IF (y.EQ.(yb0+lby)) iy=iy-1
220
ib = Nbx * (iy - 1) + ix
221
222
x1 = xb(ib)
223
x2 = xb(ib+1)
224
y1 = yb(ib)
225
y2 = yb(ib + Nbx)
226
227
zi(1,1) = zb(ib)
228
zi(2,1) = zb(ib+1)
229
zi(2,2) = zb(ib + Nbx + 1)
230
zi(1,2) = zb(ib + Nbx)
231
232
IF ((zi(1,1)<-9990.0).OR.(zi(1,2)<-9990.0).OR.(zi(2,1)<-9990.0).OR.(zi(2,2)<-9990.0)) THEN
233
IF ((zi(1,1)<-9990.0).AND.(zi(1,2)<-9990.0).AND.(zi(2,1)<-9990.0).AND.(zi(2,2)<-9990.0)) THEN
234
! Find the nearest point available
235
Rmin = 9999.0
236
DO i=1, Nb
237
IF (zb(i)>-9990.0) THEN
238
R = SQRT((x-xb(i))**2.0+(y-yb(i))**2.0)
239
IF (R<Rmin) THEN
240
Rmin = R
241
imin = i
242
END IF
243
END IF
244
END DO
245
zbed = zb(imin)
246
WRITE(*,*)'No data in the DEM cell ',ix,iy,' . Using the closest point at distance ', Rmin, zbed
247
248
ELSE
249
! Mean value over the available data
250
zbed = 0.0
251
Npt = 0
252
DO i=1, 2
253
DO J=1, 2
254
IF (zi(i,j) > -9990.0) THEN
255
zbed = zbed + zi(i,j)
256
Npt = Npt + 1
257
END IF
258
END DO
259
END DO
260
zbed = zbed / Npt
261
WRITE(*,*)'Missing data in cell ',ix,iy,'. Value ',zbed,' computed using ', Npt, 'points.'
262
END IF
263
ELSE
264
zbed = (zi(1,1)*(x2-x)*(y2-y)+zi(2,1)*(x-x1)*(y2-y)+zi(1,2)*(x2-x)*(y-y1)+zi(2,2)*(x-x1)*(y-y1))/(dbx*dby)
265
END IF
266
267
! Find zsurf for that point from the Surface MNT
268
ix = INT((x-xs0)/dsx)+1
269
IF (x.EQ.(xs0+lsx)) ix=ix-1
270
iy = INT((y-ys0)/dsy)+1
271
IF (y.EQ.(ys0+lsy)) iy=iy-1
272
is = Nsx * (iy - 1) + ix
273
274
x1 = xs(is)
275
x2 = xs(is+1)
276
y1 = ys(is)
277
y2 = ys(is + Nsx)
278
279
zi(1,1) = zs(is)
280
zi(2,1) = zs(is+1)
281
zi(2,2) = zs(is + Nsx + 1)
282
zi(1,2) = zs(is + Nsx)
283
284
IF ((zi(1,1)<-9990.0).OR.(zi(1,2)<-9990.0).OR.(zi(2,1)<-9990.0).OR.(zi(2,2)<-9990.0)) THEN
285
IF ((zi(1,1)<-9990.0).AND.(zi(1,2)<-9990.0).AND.(zi(2,1)<-9990.0).AND.(zi(2,2)<-9990.0)) THEN
286
! Find the nearest point available
287
Rmin = 9999.0
288
DO i=1, Ns
289
IF (zs(i)>-9990.0) THEN
290
R = SQRT((x-xs(i))**2.0+(y-ys(i))**2.0)
291
IF (R<Rmin) THEN
292
Rmin = R
293
imin = i
294
END IF
295
END IF
296
END DO
297
zsurf = zs(imin)
298
WRITE(*,*)'No data in the DEM cell ',ix,iy,' . Using the closest point at distance ', Rmin, zsurf
299
300
ELSE
301
! Mean value over the available data
302
zsurf = 0.0
303
Npt = 0
304
DO i=1, 2
305
DO J=1, 2
306
IF (zi(i,j) > -9990.0) THEN
307
zsurf = zsurf + zi(i,j)
308
Npt = Npt + 1
309
END IF
310
END DO
311
END DO
312
zsurf = zsurf / Npt
313
WRITE(*,*)'Missing data in cell ',ix,iy,'. Value ',zsurf,' computed using ', Npt, 'points.'
314
END IF
315
ELSE
316
zsurf = (zi(1,1)*(x2-x)*(y2-y)+zi(2,1)*(x-x1)*(y2-y)+zi(1,2)*(x2-x)*(y-y1)+zi(2,2)*(x-x1)*(y-y1))/(dsx*dsy)
317
END IF
318
319
znew = zbed + z * MAX((zsurf - zbed),hmin)
320
321
WRITE(12,1200)Node(n),j,x,y,znew
322
END DO ! NtN
323
CLOSE(12)
324
DEALLOCATE (Node, xnode, ynode, znode)
325
326
END DO ! Np
327
328
WRITE(*,*)'END WITH NO TROUBLE ...'
329
330
!
331
1000 FORMAT(I6)
332
1200 FORMAT(i10,2x,i5,3(2x,e22.15))
333
334
END PROGRAM MshGlacierDEM
335
336
! --------------------------------------------------------
337
338
339