6 use ioipsl
, only: getin
15 include
"dimensions.h"
43 REAL sig0(
llm+1), zz(
llm+1)
44 REAL zk, zkm1, dzk1, dzk2, z, k0, k1
48 REAL vert_scale,vert_dzmin,vert_dzlow,vert_z0low,vert_dzmid,vert_z0mid,vert_h_mid,vert_dzhig,vert_z0hig,vert_h_hig
50 REAL alpha, beta, deltaz
52 character(len=*),
parameter :: modname=
"disvert"
54 character(len=24):: vert_sampling
59 WRITE(
lunout,*) trim(modname)//
" starts"
64 vert_sampling = merge(
"strato",
"tropo ",
ok_strato)
65 call getin(
'vert_sampling', vert_sampling)
66 WRITE(
lunout,*) trim(modname)//
' vert_sampling = ' // vert_sampling
67 if (
llm==39 .and. vert_sampling==
"strato")
then
72 call getin(
'dsigmin', dsigmin)
73 WRITE(
lunout,*) trim(modname),
'Discretisation verticale DSIGMIN=',dsigmin
76 select case (vert_sampling)
79 OPEN(99, file=
'sigma.def', status=
'old', form=
'formatted')
87 write(
lunout, *)trim(modname),
':scaleheight, alpha, k0, k1, beta', &
90 alpha=deltaz/tanh(1./k0)*2.
96 *beta**(l-(
llm-k1))/log(beta))
100 dzk2=alpha*tanh((
llm-k1)/k0)*beta**(l-(
llm-k1))/log(beta)
101 write(
lunout, *)l, sig(l+1), zk, zk-zkm1, dzk1, dzk2
107 bp(:
llm) = exp(1. - 1. / sig(:
llm)**2)
113 x = 2*asin(1.) * (l - 0.5) / (
llm + 1)
114 dsig(l) = dsigmin + 7.0 * sin(x)**2
116 dsig = dsig / sum(dsig)
119 sig(l) = sig(l+1) + dsig(l)
128 x = 2*asin(1.) * (l - 0.5) / (
llm + 1)
129 dsig(l) = dsigmin + 7.0 * sin(x)**2
131 dsig = dsig / sum(dsig)
134 sig(l) = sig(l+1) + dsig(l)
138 bp(2:
llm) = exp(1. - 1. / sig(2:
llm)**2)
145 x = 2*asin(1.) * (l - 0.5) / (
llm + 1)
146 dsig(l) =(dsigmin + 7. * sin(x)**2) &
147 *(0.5*(1.-tanh(1.*(x-asin(1.))/asin(1.))))**2
149 dsig = dsig / sum(dsig)
152 sig(l) = sig(l+1) + dsig(l)
156 bp(2:
llm) = exp(1. - 1. / sig(2:
llm)**2)
161 case(
"strato_correct")
172 x = 2*asin(1.) * (l - 0.5) / (
llm + 1)
173 dsig(l) =(dsigmin + 7. * sin(x)**2) &
174 *(0.5*(1.-tanh(1.*(x-asin(1.))/asin(1.))))**2
176 dsig = dsig / sum(dsig)
179 sig0(l) = sig0(l+1) + dsig(l)
191 CASE(
"strato_custom0")
212 CALL getin(
"strato_alpha",alpha)
213 CALL getin(
"strato_beta",beta)
218 IF (
llm==55.OR.
llm==63)
THEN
221 zz(l+1)=zz(l)+0.03+z*1.5*(1.-tanh(z-0.5))+alpha*(1.+tanh(z-1.5)) &
222 +5.0*exp((l-
llm)/beta)
224 ELSEIF (
llm==71)
THEN
227 zz(l+1)=zz(l)+0.02+0.88*tanh(z/2.5)+alpha*(1.+tanh((z-beta)/15.))
229 ELSEIF (
llm==79)
THEN
232 zz(l+1)=zz(l)+0.02+0.80*tanh(z/3.8)+alpha*(1+tanh((z-beta)/17.)) &
250 CASE(
"strato_custom")
268 call getin(
'vert_scale',vert_scale)
269 call getin(
'vert_dzmin',vert_dzmin)
270 call getin(
'vert_dzlow',vert_dzlow)
271 call getin(
'vert_z0low',vert_z0low)
272 CALL getin(
'vert_dzmid',vert_dzmid)
273 CALL getin(
'vert_z0mid',vert_z0mid)
274 call getin(
'vert_h_mid',vert_h_mid)
275 call getin(
'vert_dzhig',vert_dzhig)
276 call getin(
'vert_z0hig',vert_z0hig)
277 call getin(
'vert_h_hig',vert_h_hig)
284 zz(l+1)=zz(l)+vert_dzmin+vert_dzlow*tanh(z/vert_z0low)+ &
285 & (vert_dzmid-vert_dzlow)* &
286 & (tanh((z-vert_z0mid)/vert_h_mid)-tanh((-vert_z0mid)/vert_h_mid)) &
287 & +(vert_dzhig-vert_dzmid-vert_dzlow)* &
288 & (tanh((z-vert_z0hig)/vert_h_hig)-tanh((-vert_z0hig)/vert_h_hig))
303 sig0=exp(-zz(:)/vert_scale)
316 open(unit, file=
"hybrid.txt", status=
"old", action=
"read", &
320 read(unit, fmt=*) ap(l),
bp(l)
323 call assert(ap(1) == 0., ap(
llm + 1) == 0.,
bp(1) == 1., &
324 bp(
llm + 1) == 0.,
"disvert: bad ap or bp values")
326 call abort_gcm(
"disvert",
'Wrong value for "vert_sampling"', 1)
337 write(
lunout, *) trim(modname),
': BP '
339 write(
lunout, *) trim(modname),
': AP '
342 write(
lunout, *)
'Niveaux de pressions approximatifs aux centres des'
343 write(
lunout, *)
'couches calcules pour une pression de surface =',
preff
344 write(
lunout, *)
'et altitudes equivalentes pour une hauteur d echelle de '
352 max(ap(l+1)+
bp(l+1)*
preff, 1.e-10))
355 write(
lunout, *) trim(modname),
': PRESNIVS '
362 FUNCTION ridders(sig) RESULT(sg)
373 REAL,
INTENT(IN) :: sig(:)
374 REAL :: sg(size(sig))
377 INTEGER :: it, ns, maxit
378 REAL :: c1, c2, x1, x2, x3, x4, f1, f2, f3, f4, s, xx, distrib
380 ns=
SIZE(sig); maxit=9999
384 x1=0.0; f1=distrib(x1,c1,c2,sig(l))
385 x2=1.0; f2=distrib(x2,c1,c2,sig(l))
387 x3=0.5*(x1+x2); f3=distrib(x3,c1,c2,sig(l))
388 s=sqrt(f3**2-f1*f2);
IF(s==0.)
EXIT
389 x4=x3+(x3-x1)*(sign(1.,f1-f2)*f3/s);
IF(abs(10.*log(x4-xx))<=1e-5)
EXIT
390 xx=x4; f4=distrib(x4,c1,c2,sig(l));
IF(f4==0.)
EXIT
391 IF(sign(f3,f4)/=f3) then; x1=x3; f1=f3; x2=xx; f2=f4
392 ELSE IF(sign(f1,f4)/=f1) then; x2=xx; f2=f4
393 ELSE IF(sign(f2,f4)/=f2) then; x1=xx; f1=f4
394 else;
CALL abort_gcm(
"ridders",
'Algorithm failed (which is odd...')
396 IF(abs(10.*log(abs(x2-x1)))<=1e-5)
EXIT
398 IF(it==maxit+1)
WRITE(
lunout,
'(a,i3)')
'WARNING in ridder: failed to converg&
416 REAL,
INTENT(IN) :: sig(:)
417 REAL :: sg(size(sig))
420 INTEGER :: it, ns, maxit
421 REAL :: c1, c2, x1, x2, x3, x4, f1, f2, f3, f4, s, xx, distrib
423 ns=
SIZE(sig); maxit=100
428 f1=exp(1-1./sg(l)**2)*(1.-c1)
429 sg(l)=sg(l)-(c1*sg(l)+f1-sig(l))/(c1+2*f1*sg(l)**(-3))
444 FUNCTION distrib(x,c1,c2,x0) RESULT(res)
448 REAL,
INTENT(IN) :: x, c1, c2, x0
451 res=c1*x+c2*exp(1-1/(x**2))-x0
real function, dimension(size(sig)) ridders(sig)
real function distrib(x, c1, c2, x0)
subroutine abort_gcm(modname, message, ierr)
!$Id Turb_fcg_gcssold get_uvd hqturb_gcssold endif!large scale llm day day1 day day1 *dt_toga endif!time annee_ref dt_toga u_toga vq_toga w_prof vq_prof llm day day1 day day1 *dt_dice endif!time annee_ref dt_dice swup_dice vg_dice omega_dice tg_prof vg_profd w_profd omega_profd!do llm!print llm l llm
subroutine new_unit(unit)
real function, dimension(size(sig)) racinesig(sig)
!$Header!gestion des impressions de sorties et de débogage la sortie standard prt_level COMMON comprint lunout