PROGRAM MshGlacierDEM
USE types
USE DefUtils
IMPLICIT NONE
REAL(KIND=dp) :: x, y, z
REAL(KIND=dp), ALLOCATABLE :: xb(:), yb(:), zb(:), xs(:), &
ys(:), zs(:)
REAL(KIND=dp), ALLOCATABLE :: xnode(:), ynode(:), znode(:)
INTEGER, ALLOCATABLE :: Node(:)
CHARACTER :: NameMsh*30, Rien*1, NameSurf*30, NameBed*30
Character(len=10) :: iNp, iNN
REAL(KIND=dp) :: dsx, dsy, dbx, dby, x1, x2, y1, y2, zi(2,2)
REAL(KIND=dp) :: xs0, ys0, xb0, yb0, zbed, zsurf, znew, Rmin, R
REAL(KIND=dp) :: lsx, lsy, lbx, lby, hmin
INTEGER :: NtN, i, j, Ns, Nsx, Nsy, Nb, Nbx, Nby, n, Npt, ix, iy, imin, is, ib
Integer k, Np
Logical :: Serial = .False.
OPEN(10,file="mesh_input.dat")
READ(10,*)Rien
READ(10,*)NameMsh
READ(10,*)Rien
READ(10,*)NameSurf
READ(10,*)Rien
READ(10,*)Nsx, Nsy
READ(10,*)Rien
READ(10,*)xs0, ys0
READ(10,*)Rien
READ(10,*)lsx, lsy
READ(10,*)Rien
READ(10,*)NameBed
READ(10,*)Rien
READ(10,*)Nbx, Nby
READ(10,*)Rien
READ(10,*)xb0, yb0
READ(10,*)Rien
READ(10,*)lbx, lby
READ(10,*)Rien
READ(10,*)hmin
READ(10,*)Rien
READ(10,*)Np
CLOSE(10)
Ns = Nsx*Nsy
Nb = Nbx*Nby
ALLOCATE(xs(Ns), ys(Ns), zs(Ns))
ALLOCATE(xb(Nb), yb(Nb), zb(Nb))
dsx = lsx / (Nsx-1.0)
dsy = lsy / (Nsy-1.0)
dbx = lbx / (Nbx-1.0)
dby = lby / (Nby-1.0)
IF (Np==1) Serial=.True.
IF (.NOT.Serial) THEN
IF (Np < 10) THEN
WRITE(iNp,'(i1.1)')Np
ELSE IF (Np < 100) THEN
WRITE(iNp,'(i2.2)')Np
ELSE IF (Np < 1000) THEN
WRITE(iNp,'(i3.3)')Np
ELSE IF (Np < 10000) THEN
WRITE(iNp,'(i4.4)')Np
ELSE
WRITE(*,*)'Work for a number of partitions < 1000'
STOP
END IF
iNp = ADJUSTL(iNp)
END IF
WRITE(*,*)'Ns, Nb',Ns,Nb
WRITE(*,*)'dx, dy',dsx,dsy,dbx,dby
OPEN(10,file=TRIM(NameSurf))
READ(10,*)(xs(i), ys(i), zs(i), i=1,Ns)
CLOSE(10)
OPEN(10,file=TRIM(NameBed))
READ(10,*)(xb(i), yb(i), zb(i), i=1,Nb)
CLOSE(10)
k = 0
DO j = 1, Nsy
y = ys0 + dsy*(j-1)
DO i = 1, Nsx
k = k + 1
x = xs0 + dsx*(i-1)
IF ((ABS(x-xs(k))>1.0e-6*dsx).OR.(ABS(y-ys(k))>1.0e-6*dsy)) THEN
WRITE(*,*)'Structure of the DEM is not conforming to what is in mesh_input.dat for Surface DEM'
WRITE(*,*)'Found that point ',k,' coordinate is ',xs(k),ys(k),' whereas it should be ',x,y
STOP
END IF
END DO
END DO
k = 0
DO j = 1, Nby
y = yb0 + dby*(j-1)
DO i = 1, Nbx
k = k + 1
x = xb0 + dbx*(i-1)
IF ((ABS(x-xb(k))>1.0e-6*dbx).OR.(ABS(y-yb(k))>1.0e-6*dby)) THEN
WRITE(*,*)'Structure of the DEM is not conforming to what is in mesh_input.dat for Surface DEM'
WRITE(*,*)'Found that point ',k,' coordinate is ',xb(k),yb(k),' whereas it should be ',x,y
STOP
END IF
END DO
END DO
DO k = 1, Np
WRITE(*,*)k,' of ', Np, ' partitions'
IF (.NOT.Serial) THEN
IF (k < 10) THEN
WRITE(iNN,'(i1.1)')k
ELSE IF (k < 100) THEN
WRITE(iNN,'(i2.2)')k
ELSE IF (k < 1000) THEN
WRITE(iNN,'(i3.3)')k
ELSE IF (k < 10000) THEN
WRITE(iNN,'(i4.4)')k
END IF
iNN = ADJUSTL(iNN)
OPEN(11,file=TRIM(NameMsh)//"/partitioning."//TRIM(iNp)//"/part."//TRIM(iNN)//".header")
ELSE
OPEN(11,file=TRIM(NameMsh)//"/mesh.header")
END IF
READ(11,*)NtN
CLOSE(11)
ALLOCATE (Node(NtN), xnode(NtN), ynode(NtN), znode(NtN))
WRITE(*,*)'Part ', k, ' NtN = ', NtN
IF (.NOT.Serial) THEN
OPEN(12,file=TRIM(NameMsh)//"/partitioning."//TRIM(iNp)//"/part."//TRIM(iNN)//".nodes")
ELSE
OPEN(12,file=TRIM(NameMsh)//"/mesh.nodes")
END IF
READ(12,*)(Node(i), j, xnode(i), ynode(i), znode(i), i=1,NtN)
REWIND(12)
IF (((MINVAL(xnode)<MINVAL(xs)).OR.(MAXVAL(xnode)>MAXVAL(xs))).OR. &
((MINVAL(ynode)<MINVAL(ys)).OR.(MAXVAL(ynode)>MAXVAL(ys)))) THEN
WRITE(*,*)'Some nodes are outside of the Surface DEM'
WRITE(*,*)'DEM xmin, ymin, xmax, ymax: ', &
MINVAL(xs),MINVAL(ys),MAXVAL(xs),MAXVAL(ys)
WRITE(*,*)'Mesh xmin, ymin, xmax, ymax: ', &
MINVAL(xnode),MINVAL(ynode),MAXVAL(xnode),MAXVAL(ynode)
STOP
END IF
IF (((MINVAL(xnode)<MINVAL(xb)).OR.(MAXVAL(xnode)>MAXVAL(xb))).OR. &
((MINVAL(ynode)<MINVAL(yb)).OR.(MAXVAL(ynode)>MAXVAL(yb)))) THEN
WRITE(*,*)'Some nodes are outside of the bedrock DEM'
WRITE(*,*)'DEM xmin, ymin, xmax, ymax: ', &
MINVAL(xb),MINVAL(yb),MAXVAL(xb),MAXVAL(yb)
WRITE(*,*)'Mesh xmin, ymin, xmax, ymax: ', &
MINVAL(xnode),MINVAL(ynode),MAXVAL(xnode),MAXVAL(ynode)
STOP
END IF
DO n=1, NtN
x = xnode(n)
y = ynode(n)
z = znode(n)
ix = INT((x-xb0)/dbx)+1
IF (x.EQ.(xb0+lbx)) ix=ix-1
iy = INT((y-yb0)/dby)+1
IF (y.EQ.(yb0+lby)) iy=iy-1
ib = Nbx * (iy - 1) + ix
x1 = xb(ib)
x2 = xb(ib+1)
y1 = yb(ib)
y2 = yb(ib + Nbx)
zi(1,1) = zb(ib)
zi(2,1) = zb(ib+1)
zi(2,2) = zb(ib + Nbx + 1)
zi(1,2) = zb(ib + Nbx)
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
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
Rmin = 9999.0
DO i=1, Nb
IF (zb(i)>-9990.0) THEN
R = SQRT((x-xb(i))**2.0+(y-yb(i))**2.0)
IF (R<Rmin) THEN
Rmin = R
imin = i
END IF
END IF
END DO
zbed = zb(imin)
WRITE(*,*)'No data in the DEM cell ',ix,iy,' . Using the closest point at distance ', Rmin, zbed
ELSE
zbed = 0.0
Npt = 0
DO i=1, 2
DO J=1, 2
IF (zi(i,j) > -9990.0) THEN
zbed = zbed + zi(i,j)
Npt = Npt + 1
END IF
END DO
END DO
zbed = zbed / Npt
WRITE(*,*)'Missing data in cell ',ix,iy,'. Value ',zbed,' computed using ', Npt, 'points.'
END IF
ELSE
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)
END IF
ix = INT((x-xs0)/dsx)+1
IF (x.EQ.(xs0+lsx)) ix=ix-1
iy = INT((y-ys0)/dsy)+1
IF (y.EQ.(ys0+lsy)) iy=iy-1
is = Nsx * (iy - 1) + ix
x1 = xs(is)
x2 = xs(is+1)
y1 = ys(is)
y2 = ys(is + Nsx)
zi(1,1) = zs(is)
zi(2,1) = zs(is+1)
zi(2,2) = zs(is + Nsx + 1)
zi(1,2) = zs(is + Nsx)
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
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
Rmin = 9999.0
DO i=1, Ns
IF (zs(i)>-9990.0) THEN
R = SQRT((x-xs(i))**2.0+(y-ys(i))**2.0)
IF (R<Rmin) THEN
Rmin = R
imin = i
END IF
END IF
END DO
zsurf = zs(imin)
WRITE(*,*)'No data in the DEM cell ',ix,iy,' . Using the closest point at distance ', Rmin, zsurf
ELSE
zsurf = 0.0
Npt = 0
DO i=1, 2
DO J=1, 2
IF (zi(i,j) > -9990.0) THEN
zsurf = zsurf + zi(i,j)
Npt = Npt + 1
END IF
END DO
END DO
zsurf = zsurf / Npt
WRITE(*,*)'Missing data in cell ',ix,iy,'. Value ',zsurf,' computed using ', Npt, 'points.'
END IF
ELSE
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)
END IF
znew = zbed + z * MAX((zsurf - zbed),hmin)
WRITE(12,1200)Node(n),j,x,y,znew
END DO
CLOSE(12)
DEALLOCATE (Node, xnode, ynode, znode)
END DO
WRITE(*,*)'END WITH NO TROUBLE ...'
1000 FORMAT(I6)
1200 FORMAT(i10,2x,i5,3(2x,e22.15))
END PROGRAM MshGlacierDEM