Commit d05d5688 authored by Anthony's avatar Anthony
Browse files

Correct the outflows and inflows in the halos

parent b42bad89
......@@ -715,8 +715,43 @@ SUBROUTINE checkrouting(nbpt, nwbas, outflow_grid, outflow_basin, basin_count)
END SUBROUTINE checkrouting
SUBROUTINE correct_outflows(nbpt, nwbas,nbhalo, outflow_grid, outflow_basin, &
&basin_count, hg, hb, halopts)
!
USE ioipsl
USE grid
USE routing_tools
USE routing_reg
!
!! INPUT VARIABLES
INTEGER(i_std), INTENT (in) :: nbpt !! Domain size (unitless)
INTEGER(i_std), INTENT (in) :: nwbas !!
INTEGER(i_std), INTENT (in) :: nbhalo !!
INTEGER(i_std), DIMENSION(nbhalo) :: halopts
INTEGER(i_std), DIMENSION(nbpt,nwbas), INTENT(inout) :: outflow_grid !! Type of outflow on the grid box (unitless)
INTEGER(i_std), DIMENSION(nbpt,nwbas), INTENT(inout) :: outflow_basin !!
INTEGER(i_std), DIMENSION(nbpt), INTENT(in) :: basin_count
INTEGER(i_std), DIMENSION(nbpt,nwbas), INTENT(in) :: hg !! Type of outflow on the grid box (unitless)
INTEGER(i_std), DIMENSION(nbpt,nwbas), INTENT(in) :: hb !!
!! LOCAL
INTEGER(i_std) ::ih, ig, ib, nbas
SUBROUTINE check_inflows(nbpt, nwbas, inflowmax, outflow_grid, outflow_basin, basin_count, inflow_number, inflow_grid, inflow_basin)
! AJOUT BASIN8COUNT
DO ih=1,nbhalo
ig = halopts(ih)
nbas = basin_count(ig)
DO ib=1,nbas
outflow_grid(ig,ib) = hg(ig,ib)
outflow_basin(ig,ib) = hb(ig,ib)
END DO
END DO
END SUBROUTINE correct_outflows
SUBROUTINE correct_inflows(nbpt, nwbas, inflowmax, outflow_grid,&
& outflow_basin, basin_count, inflow_number, inflow_grid, &
& inflow_basin)
!
USE ioipsl
......@@ -732,43 +767,35 @@ SUBROUTINE check_inflows(nbpt, nwbas, inflowmax, outflow_grid, outflow_basin, ba
INTEGER(i_std), DIMENSION(nbpt,nwbas), INTENT(in) :: outflow_grid !! Type of outflow on the grid box (unitless)
INTEGER(i_std), DIMENSION(nbpt,nwbas), INTENT(in) :: outflow_basin !!
INTEGER(i_std), DIMENSION(nbpt), INTENT(in) :: basin_count !!
INTEGER(i_std), DIMENSION(nbpt,nwbas), INTENT(in) :: inflow_number
INTEGER(i_std), DIMENSION(nbpt,nwbas,inflowmax), INTENT(in) :: inflow_basin
INTEGER(i_std), DIMENSION(nbpt,nwbas,inflowmax), INTENT(in) :: inflow_grid
INTEGER(i_std), DIMENSION(nbpt,nwbas), INTENT(inout) :: inflow_number
INTEGER(i_std), DIMENSION(nbpt,nwbas,inflowmax), INTENT(inout) :: inflow_basin
INTEGER(i_std), DIMENSION(nbpt,nwbas,inflowmax), INTENT(inout) :: inflow_grid
! LOCAL
INTEGER(i_std) :: ig, nbas, ib, og, ob, inf, found
WRITE(numout,*) "Checking if the HTUs are in the inflows of their outflow"
inflow_number(:,:) = 0
inflow_basin(:,:,:)=0
inflow_grid(:,:,:)=0
DO ig=1,nbpt
nbas = basin_count(ig)
DO ib=1,nbas
og = outflow_grid(ig,ib)
ob = outflow_basin(ig,ib)
if (og .GT. 0) THEN
IF (inflow_number(og,ob) .EQ. 0) THEN
WRITE(numout,*) ig, ib, "Error : outflow has no inflow"
WRITE(numout,*) og, ob
ELSE
found = 0
DO inf = 1,inflow_number(og,ob)
IF ((inflow_grid(og,ob,inf) .EQ. ig) .AND. (inflow_basin(og,ob,inf) .EQ. ib)) THEN
found = 1
END IF
END DO
IF (found .EQ. 0) THEN
WRITE(numout,*) ig,ib, "Error, not found the inflows of its outflow"
WRITE(numout,*) og, ob
END IF
END IF
inflow_number(og,ob) = inflow_number(og,ob) +1
inflow_basin(og,ob,inflow_number(og,ob)) = ib
inflow_grid(og,ob,inflow_number(og,ob)) = ig
END IF
END DO
END DO
END SUBROUTINE check_inflows
END SUBROUTINE correct_inflows
SUBROUTINE checkfetch(nbpt, nwbas, fetch_basin, outflow_grid, outflow_basin, basin_count)
!
......
......@@ -201,6 +201,10 @@ def finalfetch(part, routing_area, basin_count, route_togrid, route_tobasin, fet
xtmp = np.hstack(part.comm.allgather(outflow_uparea[np.where(outflow_uparea > 0.0)]))
# Precision in m^2 of the upstream areas when sorting.
sorted_outareas = (np.unique(np.rint(np.array(xtmp)/prec))*prec)[::-1]
if sorted_outareas.shape[0]<largest_pos:
s = sorted_outareas[:]
sorted_outareas = np.zeros(largest_pos, dtype=np.float32, order='F')
sorted_outareas[:s.shape[0]] = s[:]
# If mono-proc no need to iterate as fetch produces the full result.
if part.size == 1 :
maxdiff_sorted = 0.0
......@@ -406,7 +410,7 @@ class HydroSuper :
if part.size == 1 :
maxdiff_sorted = 0.0
else :
maxdiff_sorted = np.max(np.abs(sorted_outareas[0:largest_pos]-old_sorted[0:l]))
maxdiff_sorted = np.max(np.abs(sorted_outareas[0:l]-old_sorted[0:l]))
old_sorted[:l] = sorted_outareas[0:largest_pos]
iter_count += 1
......@@ -437,11 +441,43 @@ class HydroSuper :
return
def check_inflows(self):
def correct_outflows(self, part):
# Global index of the proc domain
nbpt_loc = np.zeros((self.nbpt,1)).astype(np.int32)
nbpt_loc[:,0] = np.arange(1, self.nbpt+1)
nbpt_glo = part.l2glandindex(nbpt_loc)
# Halo points
fhalo = np.array([pt+1 for pt in range(self.nbpt) if pt not in part.landcorelist], order = "F")
#
# Outflow grid in global index and send to halo
hg = part.l2glandindex(self.outflow_grid)
part.landsendtohalo(hg, order='F')
# Convert to local index
outflows = np.unique(hg)
outflows_out = [a for a in outflows if (a not in nbpt_glo and a>0)]
for a in outflows_out:
hg[hg == a] = 0
for i, b in enumerate(nbpt_glo):
hg[hg == b] = nbpt_loc[i]
# Send Outflow basin to the halo and adapt it
hb = np.copy(self.outflow_basin)
part.landsendtohalo(hb, order='F')
hb[hg <= 0] = 999999999
for ig in range(self.nbpt):
hb[ig,self.basin_count[ig]:] = 0
#
# Correct the routing graph in the halo
routing_interface.correct_outflows(nbpt = self.nbpt, nwbas = self.nwbas, nbhalo = fhalo.shape[0], \
outflow_grid = self.outflow_grid, outflow_basin = self.outflow_basin, \
basin_count = self.basin_count, hg = hg, hb = hb, halopts = fhalo)
#
# Correct the inflows
nbxmax_tmp = self.inflow_grid.shape[2]
routing_interface.check_inflows(nbpt = self.nbpt, nwbas = self.nwbas, inflowmax = nbxmax_tmp, outflow_grid = self.outflow_grid, outflow_basin = self.outflow_basin, basin_count = self.basin_count, inflow_number = self.inflow_number, inflow_grid = self.inflow_grid, inflow_basin = self.inflow_basin)
#
#
routing_interface.correct_inflows(nbpt = self.nbpt, nwbas = self.nwbas, inflowmax = nbxmax_tmp, outflow_grid = self.outflow_grid, outflow_basin = self.outflow_basin, basin_count = self.basin_count, inflow_number = self.inflow_number, inflow_grid = self.inflow_grid, inflow_basin = self.inflow_basin)
return
def killbas(self, tokill, totakeover, numops):
ops = tokill.shape[1]
#
......@@ -483,7 +519,7 @@ class HydroSuper :
outnf.createDimension('x', globalgrid.ni)
outnf.createDimension('y', globalgrid.nj)
outnf.createDimension('land', len(procgrid.area))
outnf.createDimension('htuext', self.nbhtuext)
outnf.createDimension('htuext', self.basin_id.shape[1])
outnf.createDimension('htu', self.inflow_number.shape[1])
outnf.createDimension('in',inflow_size )
outnf.createDimension('bnd', nbcorners)
......
import numpy as np
import sys
from numba import jit
#
import getargs
log_master, log_world = getargs.getLogger(__name__)
......@@ -332,7 +333,31 @@ def toland_index(x,landmap) :
xout.append([])
return xout
#
#
@jit(nopython = True)
def subl2glandindex2d(l2glandind, y, x, nl, nh):
LI = np.arange(nl, dtype=np.int32)
LJ = np.arange(nh, dtype=np.int32)
for i in LI:
for j in LJ:
# Land indices are in FORTRAN !!
if x[i,j] > 0:
y[i,j] = l2glandind[x[i,j]-1]+1
else:
y[i,j] = x[i,j]
@jit(nopython = True)
def subl2glandindex3d(l2glandind, y, x, nl, nh1, nh2):
LI = np.arange(nl, dtype=np.int32)
LJ = np.arange(nh1, dtype=np.int32)
LK = np.arange(nh2, dtype=np.int32)
for i in LI:
for j in LJ:
for k in LK:
if x[i,j,k] > 0:
# Land indices are in Fortran
y[i,j,k] = l2glandind[x[i,j,k]-1]+1
else:
y[i,j,k] = x[i,j,k]
#
class partition :
def __init__ (self, nig, njg, land, mpicomm, nbcore, halosz, rank, wunit="None") :
......@@ -571,31 +596,26 @@ class partition :
#
# Convert local index of land points to global index
#
def l2glandindex(self, x) :
def l2glandindex(self, x, order = 'F') :
if x.ndim == 2:
nl,nh = x.shape
y = np.zeros(x.shape, dtype=x.dtype)
y = np.zeros(x.shape, dtype=x.dtype, order = order)
if nl == self.nbland :
for i in range(nl) :
for j in range(nh) :
# Land indices are in FORTRAN !!
y[i,j] = self.l2glandind[x[i,j]-1]+1
subl2glandindex2d(self.l2glandind, y, x, nl, nh)
else :
ERROR("The first dimension does not have the length of the number of land points")
sys.exit()
if x.ndim == 3:
nl,nh1,nh2 = x.shape
y = np.zeros(x.shape,dtype = x.dtype)
y = np.zeros(x.shape,dtype = x.dtype, order = order)
if nl == self.nbland:
for i in range(nl):
for j in range(nh1):
for k in range(nh2):
# Land indices are in Fortran
y[i,j,k] = self.l2glandind[x[i,j,k]-1]+1
subl2glandindex3d(self.l2glandind, y, x, nl, nh1, nh2)
else:
ERROR("The first dimension does not have the length of the number of land points")
sys.exit()
return y
#
# Set to zero all points in the core
#
......@@ -704,4 +724,3 @@ class partition :
self.comm.send(np.pad(x, [0,maxlen-len(x)], mode='constant', constant_values=np.nan), dest=0)
#
return xout
......@@ -98,7 +98,9 @@ hsuper.linkup(hydrodata)
del hoverlap
gc.collect()
comm.Barrier()
#
hsuper.correct_outflows(part)
#
INFO("=================== Compute fetch ====================")
t = time.time()
hsuper.fetch(part)
......@@ -111,8 +113,6 @@ if DumpHydroSuper :
INFO("Dumping HydroSuper")
hsuper.dumpnetcdf(OutGraphFile.replace(".nc","_HydroSuper.nc"), gg, modelgrid, part)
hsuper.check_inflows()
INFO("=================== Truncate ====================")
print("Rank : {0} - Basin_count Before Truncate : ".format(part.rank), hsuper.basin_count)
hs = TR(hsuper, part, comm, modelgrid, numop = numop)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment