DevelopmentActivities/CMIP6/DevelopmentsCMIP6/soil_physic: Revised_HydroVert.py

File Revised_HydroVert.py, 9.7 KB (added by jpolcher, 9 years ago)

Revised version of the vertical layer system

Line 
1import numpy as np
2from matplotlib.backends.backend_pdf import PdfPages
3import matplotlib.pyplot as plt
4import matplotlib as mpl
5import matplotlib.cm as cm
6from mpl_toolkits.basemap import Basemap
7from matplotlib.patches import Polygon
8
9def DiagThick(dd):
10    nbx=len(dd)-1
11    hh=np.zeros(nbx, float)   
12    for i in range(0,nbx):
13        hh[i]=(dd[i]+dd[i+1])/2
14    hcum=np.zeros(nbx, float)
15    hcum[0]=hh[0]
16    for i in range(1,nbx):
17        hcum[i]=hcum[i-1]+hh[i]
18    #
19    return hh, hcum
20#
21# Compute layer thickness
22#
23def CompThickness(x):
24    nbx=len(x)
25    dx=0.0
26    for i in range(1,nbx):
27        dx = np.append(dx,(x[i-1]+x[i])/2.0)
28    # Last layer
29    dx=np.append(dx,(x[nbx-1]-dx[nbx-1])*2+dx[nbx-1])
30    #
31    tx=[]
32    for i in range(len(dx)-1):
33        tx = np.append(tx,dx[i+1]-dx[i])
34    #
35    return dx,tx
36#
37# Reading booleans
38#
39def str2bool(v):
40  return v.lower() in ("yes", "true", "t", "1")
41#
42# Ploting function
43#
44def discretizationplot(wlev, tlev, wdepth_max, tsol_max, overalltitle):
45    #
46    # Compute thicknesses
47    #
48    wy,wz=CompThickness(wlev)
49    ty,tz=CompThickness(tlev)
50    #
51    x=np.array([0,1])
52
53    f, (ax1, ax2) = plt.subplots(1, 2, sharey=False)
54
55    zmax=max([np.max(wz),np.max(tz)])
56    cNorm = mpl.colors.Normalize(vmin=0, vmax=zmax)
57    cmap = plt.get_cmap('Dark2')   
58
59    ztmp=np.reshape(np.repeat(wz,2), (len(wy)-1, len(x)) )
60    ax1.set_yscale('symlog')
61    ax1.yaxis.set_major_formatter(mpl.ticker.ScalarFormatter())
62    ax1.yaxis.set_major_formatter(mpl.ticker.FormatStrFormatter('%d'))
63    ax1.yaxis.set_major_formatter(mpl.ticker.FuncFormatter(lambda x, pos: str(int(round(x)))))
64#    ax1.set_yticks([-0.02, -0.2, -2])
65    datamap=ax1.pcolor(x,-wy, ztmp, zorder=0, norm=cNorm, cmap=cmap)
66    # Add tine lines to show the middle of the layer where SM is positioned
67    for i in range(len(wlev)):
68        ax1.plot(x,np.array([-wlev[i],-wlev[i]]), color='k', linewidth=0.4)
69#
70    ax1.text(0.5, -wdepth_max, "depth_Wmax", fontweight='bold',ha='center',
71             va='center')
72    ax1.set_xlabel("Min thickness="+str(round(np.min(wz),5))+"[m]")
73    ax1.set_title("nslm="+str(len(wlev)))
74#
75    ztmp=np.reshape(np.repeat(tz, 2), (len(ty)-1,len(x)))
76    datamap = ax2.pcolor(x,-ty, ztmp, zorder=0, norm=cNorm, cmap=cmap)
77    # Add tine lines to show the middle of the layer where T is positioned
78    for i in range(len(tlev)):
79        ax2.plot(x,np.array([-tlev[i],-tlev[i]]), color='k', linewidth=0.4)
80
81    ax2.text(0.5, -tsol_max, "depth_max", fontweight='bold',ha='center',
82                 va='center')
83    ax2.set_title("ngrnd="+str(len(tlev)))
84    ax2.set_xlabel("Max thickness="+str(round(np.max(tz),5))+"[m]")
85#
86    cb=plt.colorbar(datamap, cmap=cmap, shrink=0.5, norm=cNorm)
87    cb.set_label("Layer Thickness [m]")
88#
89    plt.suptitle(overalltitle)
90#
91    pdf.savefig()
92#
93############################################################################################
94#
95# As a reminder, the levels of the hydrology as in the code today
96#
97depth_Wmax=2.0
98nslm=11
99zz=np.zeros(nslm, float)
100dz=np.zeros(nslm+1, float)
101thickness=np.zeros(nslm, float)
102depth=np.zeros(nslm+1, float)
103
104for i in range(1,nslm):
105    zz[i] = depth_Wmax*((2**i)-1)/((2**(nslm-1))-1)
106    dz[i] = zz[i]-zz[i-1]
107
108hh,hcum=DiagThick(dz)
109print "== Old depth of the hydrology for reference =========================="
110print "zz = depth of nodes"
111print zz
112print "dz = internode distance"
113print dz
114print "hh = soil layer thickness"
115print hh
116print "hcum = depth of soil layer bottom"
117print hcum
118print "======================================================================"
119print "  "
120print "  "
121#
122###############################################################################
123#
124# Ask the user for input to configure the vertical levels
125#
126# New Methode for computing levels with the new parameters to control.
127#
128# All units in meters
129#
130# Maximum depth of the soil thermodynamics
131depth_max = 8.0
132try :
133    depth_max=float(raw_input("Maximum depth of soil : depth_max [8.0m] >"))
134except ValueError:
135    depth_max = 8.0
136#
137# Maximum depth of soil moisture
138depth_Wmax=2.0
139try :
140    depth_Wmax=float(raw_input("Depth of hydrology (smaller than depth_max) : depth_Wmax [2.0m] >"))
141except ValueError:
142    depth_Wmax=2.0
143if ( depth_Wmax > depth_max) :
144    print "ERROR : depth_Wmax needs to be smaller than depth_max."
145    print "Correction : depth_Wmax set to depth_max"
146    depth_Wmax = depth_max
147#
148# Thickness of first Layer
149depth_toptickness = 9.77517107e-04
150try :
151    depth_toptickness=float(raw_input("Depth of top hydrology layer : depth_toptickness [9.77517107e-04 m] >"))
152except ValueError:
153    depth_toptickness = 9.77517107e-04
154# The constant layer thickness starts at :
155depth_cstthickness=depth_Wmax
156try :
157    depth_cstthickness=float(raw_input("Depth at which constant layer thickness start (smaller than depth_Wmax/2)  : depth_cstthickness [depth_Wmax] >"))
158except ValueError:
159    depth_cstthickness = depth_Wmax
160if ( (depth_cstthickness != depth_Wmax) & (depth_cstthickness > depth_Wmax/2.0) ) :
161    print "ERROR : depth_cstthickness needs to be smaller than depth_Wmax/2.0"
162    print "Correction : Constant thickness disabled"
163    depth_cstthickness = depth_Wmax
164#
165# Do we refine the layers as we reach the depth_Wmax
166refinebottom = False
167try :
168    refinebottom=str2bool(raw_input("Refinement at the bottom (symetrical to the top refinement): refinebottom [False] >"))
169except ValueError:
170    refinebottom=False
171#
172# Depth at which we resume geometrical increases
173depth_geom=depth_Wmax
174try :
175    depth_geom=float(raw_input("Depth at which geometrical increase starts again (larger than depth_Wmax)  : depth_geom [depth_Wmax] >"))
176except ValueError:
177    depth_geom=depth_Wmax
178if ( depth_geom < depth_Wmax ) :
179    print "ERROR : depth_geom needs to be larger than depth_Wmax"
180    print "Correction : setting depth_geom to depth_Wmax"
181
182    depth_geom=depth_Wmax
183#
184# Ratio of geometrical serie below depth_geom
185ratio_geom_below=2
186try :
187    ratio_geom_below=float(raw_input("Ratio of geometrical serie below depth_geom : ratio_geom_below [2] >"))
188except ValueError:
189    ratio_geom_below=2
190#
191###################################################################################################
192#
193#  Start computing the new levels
194#
195# It is coded FORTRAN style so that translations is easier
196#
197nltmp=500
198ztmp=np.zeros(nltmp, float)
199dtmp=np.zeros(nltmp+1, float)
200for i in range(1,nltmp):
201    if ( ztmp[i-1] < depth_cstthickness ) :
202        ztmp[i] = depth_toptickness*2.0*((2**i)-1)
203        dtmp[i] = ztmp[i]-ztmp[i-1]
204        igeo=i
205        zgeoend=ztmp[i]
206        dgeoend=dtmp[i]
207    else :
208        ztmp[i] = ztmp[i-1]+dtmp[i-1]
209        dtmp[i] = dtmp[i-1]
210#
211nbrefine=0
212drefine=np.zeros(nltmp, float)
213if (refinebottom) :
214    #
215    # Compute parameters for the constant increment interval before refining,
216    # If needed !
217    cstint=depth_Wmax-(2.0*zgeoend)
218    nbcst=max(int(np.modf(cstint/dgeoend)[1]),0)
219    if ( nbcst > 0 ) :
220        dcst=cstint/nbcst
221    else :
222        dcst=dgeoend
223    #
224    # If we have to add constant increments
225    #
226    if ( nbcst > 0 ) :
227        # Add linear levels
228        for i in range(igeo+1,igeo+nbcst+1) :
229            ztmp[i] = ztmp[i-1]+dcst
230            dtmp[i] = dcst
231        # Refine the levels toward the bottom
232        for i in range(igeo+nbcst+1,2*igeo+nbcst+1) :
233            irev=(2*igeo+nbcst+1)-i
234            ztmp[i] = ztmp[i-1]+dtmp[irev]
235            dtmp[i] = ztmp[i]-ztmp[i-1]
236            drefine[nbrefine]=dtmp[i]
237            nbrefine=nbrefine+1
238    # Without constant increments
239    else :
240        igeo=np.argmin(np.abs(ztmp-(depth_Wmax/2.0)))
241        ztmp[igeo]=depth_Wmax/2.0
242        dtmp[igeo] = ztmp[igeo]-ztmp[igeo-1]
243        for i in range(igeo+1,2*igeo+1) :
244            irev=(2*igeo+1)-i
245            ztmp[i] = ztmp[i-1]+dtmp[irev]
246            dtmp[i] = ztmp[i]-ztmp[i-1]
247            drefine[nbrefine]=dtmp[i]
248            nbrefine=nbrefine+1
249#
250nslm=np.argmin(np.abs(ztmp-depth_Wmax))+1
251#
252# Extract now the values we need to reach depth_Wmax
253#
254zz=ztmp[0:nslm]
255dz=dtmp[0:nslm+1]
256dz[nslm]=0.0
257hh,hcum = DiagThick(dz)
258print "== New values ========================================================"
259print "Number of layers in hydrol = ", nslm
260print "zz = depth of nodes"
261print zz
262print "dz = internode distance"
263print dz
264print "hh = soil layer thickness"
265print hh
266print "hcum = depth of soil layer bottom"
267print hcum
268print "======================================================================"
269print "  "
270print "  "
271#
272# Extension for the thermodynamics below depth_Wmax
273#
274ztmp=np.zeros(nltmp, float)
275# Exception for the first layer. It is at the top in the hydrology and in
276# the middle for temlperature.
277ztmp[0]=depth_toptickness/2
278for i in range(1,nslm):
279    ztmp[i]=zz[i]
280#
281# Exception for the last layer where again temperature needs to be in
282# the middle of the layer. Also add a layer with the same thickness
283ztmp[nslm-1]=ztmp[nslm-1]-hh[nslm-1]/2.0
284ztmp[nslm]=ztmp[nslm-1]+hh[nslm-1]
285nslm=nslm+1
286#
287# If we have created a refined region at the bottom of the soil moisture. We need to
288# unwinde it for temperature below depth_Wmax
289#
290if ( nbrefine > 1 ) :
291    for i in range(nslm,nslm+nbrefine,1):
292        iref=(nbrefine-1)-(i-nslm)
293        ztmp[i]=ztmp[i-1]+drefine[iref]
294#
295# New nslm
296#
297nslm=nslm+nbrefine
298#
299for i in range(nslm,nltmp):
300    if ( ztmp[i-1] < depth_geom ) :
301        ratio = 1.0
302    else :
303        ratio = ratio_geom_below
304    ztmp[i]=ztmp[i-1]+ratio*(ztmp[i-1]-ztmp[i-2])
305#       
306ngrnd=np.argmin(np.abs(ztmp-depth_max))+1
307#
308tdepth=np.zeros(ngrnd, float)
309tdepth=ztmp[0:ngrnd]
310print "Number of layers in thermosoil = ", ngrnd
311print "tdepth=",tdepth
312print "======================================================================"
313#
314# Do the plot
315#
316pdf = PdfPages('VerticalLayers.pdf')
317wdepth=np.copy(zz)
318wdepth[0]=(zz[1]-zz[0])/2
319discretizationplot(wdepth, tdepth, depth_Wmax, depth_max, "Mixing water and temperature")
320pdf.close()