source: trunk/UTIL/z2sig/build_sig.py @ 3651

Last change on this file since 3651 was 3651, checked in by afalco, 4 months ago

Script to create new z2sig with different number of layers

  • Property svn:executable set to *
File size: 4.9 KB
RevLine 
[3651]1#!/usr/bin/python3
2from    numpy                 import    *
3import  numpy                 as        np
4import  matplotlib.pyplot     as        mpl
5from matplotlib.cm import get_cmap
6import pylab
7from matplotlib import ticker
8import matplotlib.colors as colors
9import datetime
10from matplotlib import pyplot
11
12######################################################################
13# Fonction  read  file
14######################################################################
15def readfile(name):
16# test reading lire texte txt
17    myfile = open(name, 'r')
18    mylines=myfile.readlines()
19    nbline=size(mylines)
20    nbcolumn=len(mylines[0].split())
21    print('nbline, nbcol:',nbline, nbcolumn)
22    data=np.zeros(nbline-1,dtype='f')
23    i=0
24    for line in mylines:
25        s=str.split(line)
26        if i==0:
27          hh=float(s[0])
28        else:
29          data[i-1]=float(s[0])
30        i=i+1
31    return data,hh
32
33######################################################################
34# Input Parameters
35######################################################################
36nbl=47
37data,hh=readfile('z2sig.def_47')
38# nb of levels
39clev=np.linspace(1,nbl,nbl)
40ps=1.1
41# New levels
42mynbl=201
43n=float(mynbl)
44plot = True
45plot = False
46
47#####################
48# Get sigma levels
49#####################
50sig=np.ones(nbl,dtype='f')
51for i in range(nbl-1):
52 sig[i+1]=0.5*(exp(-data[i+1]/hh)+exp(-data[i]/hh))
53
54#####################
55# Get non-hybrid pressure levels
56#####################
57ap=0
58bp=sig
59pp=ap+bp*1.1
60
61#####################
62# Get hybrid pressure levels
63#####################
64def sig_hybrid(sig,pa,preff):
65#c     Subroutine utilisee pour calculer des valeurs de sigma modifie
66#c     pour conserver les coordonnees verticales decrites dans
67#c     esasig.def/z2sig.def lors du passage en coordonnees hybrides
68#c     F. Forget 2002
69#c     Connaissant sig (niveaux "sigma" ou on veut mettre les couches)
70#c     L'objectif est de calculer newsig telle que
71#c       (1 -pa/preff)*exp(1-1./newsig**2)+(pa/preff)*newsig = sig
72#c     Cela ne se resoud pas analytiquement:
73#c     => on resoud par iterration bourrine
74#c     ----------------------------------------------
75#c     Information  : where exp(1-1./x**2) become << x
76#c           x      exp(1-1./x**2) /x
77#c           1           1
78#c           0.68       0.5
79#c           0.391      1.E-2
80#c        => on peut utiliser newsig = sig*preff/pa si sig*preff/pa < 0.25
81
82  newsig = sig
83  x1=0
84  x2=1
85  if (sig>=1):
86     newsig = sig
87  elif (sig*preff/pa>=0.25):
88     for j in range(9999):  # nombre d'iteration max
89       F=((1-pa/preff)*exp(1-1./newsig**2)+(pa/preff)*newsig)/sig
90       if (F>1):
91          x2 = newsig
92          newsig=(x1+newsig)*0.5
93       else:
94          x1=newsig
95          newsig=(x2+newsig)*0.5
96       #Test : on arete lorsque on approxime sig a moins de 0.01 m pres
97       #(en pseudo altiude) :
98       #if (abs(10.*log(F))<1.e-5):
99       # break
100
101  else:  # if (sig*preff/pa.le.0.25)
102      newsig= sig*preff/pa
103
104  return newsig
105#----------------------------------
106
107# hybrid pressure:
108nsig=np.zeros(nbl,dtype='f')
109pa=0.5 #ps
110preff=2 #ps
111for i in range(nbl):
112  nsig[i]=sig_hybrid(sig[i],pa,preff)
113
114bps=exp(1-1/(nsig)**2)
115aps=pa*(nsig-bps)
116
117pps=aps+bps*ps
118
119#####################
120# Get Pseudo altitude
121#####################
122# non hybrid
123ph=-hh*log(pp/ps)
124dzph=-(ph[0:-1]-ph[1:])
125# hybrid
126phs=-hh*log(pps/ps)
127dzphs=-(phs[0:-1]-phs[1:])
128
129#####################
130# New choice delta-zh
131#####################
132myclev=np.linspace(1,mynbl,mynbl)
133xx=myclev[0:mynbl-1] # xaxis for layer thickness
134xx1=myclev[0:mynbl]
135# first and last level difference in m
136l0=0.0025
137ln=4.6
138# Coefficient for the exp function
139c=0.11
140a=1/n*(np.log(ln/c)-np.log(l0/c))
141b=-1/a*np.log(l0/c)
142# Dz difference altitude between 2 layers :
143mydz=exp(a*(xx-b))*c
144
145# New pseudo altitude myph
146myph=np.zeros(mynbl,dtype='f')
147myph[0]=mydz[0]
148print(myph[0])
149for i in range(mynbl-1):
150 myph[i+1]=mydz[i]+myph[i]
151 print(myph[i+1])
152
153to_file = np.concatenate([[hh], myph])
154output = f"z2sig.def_{mynbl}"
155np.savetxt(output,to_file, fmt="%g")
156print(f"Saved to {output}")
157
158# New Ps levels
159mypp=ps*exp(-myph/hh)
160
161
162if plot:
163    ### Plot pressure levels
164    mpl.figure(figsize=(50/2.54, 30/2.54),facecolor='w')
165    ax=mpl.subplot(131)
166    mpl.plot(clev,pp,'k-',marker='*',label='P ini')
167    mpl.plot(clev,pps,'r-',marker='*',label='P ini hybrid')
168    mpl.plot(myclev,mypp,'b-',marker='*',label='P new')
169    mpl.gca().invert_yaxis()
170    pyplot.yscale('log')
171    mpl.grid()
172
173    ### Plot difference altitude between 2 layers
174    ax=mpl.subplot(132)
175    mpl.plot(clev[0:nbl-1],dzph,'k-',marker='*',label='dz ini')
176    mpl.plot(clev[0:nbl-1],dzphs,'r-',marker='*',label='dz ini hybrid')
177    mpl.plot(xx,mydz,'b-',marker='*',label='dz new')
178    pyplot.yscale('log')
179    mpl.grid()
180
181    ### pseudo altitude
182    ax=mpl.subplot(133)
183    mpl.plot(clev[0:nbl],ph,'k-',marker='*',label='sig ini')
184    mpl.plot(clev[0:nbl],phs,'r-',marker='*',label='sig ini hybrid')
185    mpl.plot(xx1,myph,'b-',marker='*',label='sig new')
186    #pyplot.yscale('log')
187    mpl.grid()
188
189    mpl.show()
190
191
192
193
Note: See TracBrowser for help on using the repository browser.