Directory: | ./ |
---|---|
File: | dyn3d_common/disvert.f90 |
Date: | 2022-01-11 19:19:34 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 46 | 170 | 27.1% |
Branches: | 21 | 95 | 22.1% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | ! $Id: disvert.F90 2786 2017-01-30 10:24:47Z emillour $ | ||
2 | |||
3 | 52 | SUBROUTINE disvert() | |
4 | |||
5 | use ioipsl, only: getin | ||
6 | use new_unit_m, only: new_unit | ||
7 | use assert_m, only: assert | ||
8 | USE comvert_mod, ONLY: ap, bp, aps, bps, nivsigs, nivsig, dpres, presnivs, & | ||
9 | pseudoalt, pa, preff, scaleheight | ||
10 | USE logic_mod, ONLY: ok_strato | ||
11 | |||
12 | IMPLICIT NONE | ||
13 | |||
14 | include "dimensions.h" | ||
15 | include "paramet.h" | ||
16 | include "iniprint.h" | ||
17 | |||
18 | !------------------------------------------------------------------------------- | ||
19 | ! Purpose: Vertical distribution functions for LMDZ. | ||
20 | ! Triggered by the levels number llm. | ||
21 | !------------------------------------------------------------------------------- | ||
22 | ! Read in "comvert_mod": | ||
23 | |||
24 | ! pa !--- vertical coordinate is close to a PRESSURE COORDINATE FOR P | ||
25 | ! < 0.3 * pa (relative variation of p on a model level is < 0.1 %) | ||
26 | |||
27 | ! preff !--- REFERENCE PRESSURE (101325 Pa) | ||
28 | ! Written in "comvert_mod": | ||
29 | ! ap(llm+1), bp(llm+1) !--- Ap, Bp HYBRID COEFFICIENTS AT INTERFACES | ||
30 | ! aps(llm), bps(llm) !--- Ap, Bp HYBRID COEFFICIENTS AT MID-LAYERS | ||
31 | ! dpres(llm) !--- PRESSURE DIFFERENCE FOR EACH LAYER | ||
32 | ! presnivs(llm) !--- PRESSURE AT EACH MID-LAYER | ||
33 | ! scaleheight !--- VERTICAL SCALE HEIGHT (Earth: 8kms) | ||
34 | ! nivsig(llm+1) !--- SIGMA INDEX OF EACH LAYER INTERFACE | ||
35 | ! nivsigs(llm) !--- SIGMA INDEX OF EACH MID-LAYER | ||
36 | !------------------------------------------------------------------------------- | ||
37 | ! Local variables: | ||
38 | REAL sig(llm+1), dsig(llm) | ||
39 | REAL sig0(llm+1), zz(llm+1) | ||
40 | REAL zk, zkm1, dzk1, dzk2, z, k0, k1 | ||
41 | |||
42 | INTEGER l, unit | ||
43 | REAL dsigmin | ||
44 | REAL vert_scale,vert_dzmin,vert_dzlow,vert_z0low,vert_dzmid,vert_z0mid,vert_h_mid,vert_dzhig,vert_z0hig,vert_h_hig | ||
45 | |||
46 | REAL alpha, beta, deltaz | ||
47 | REAL x | ||
48 | character(len=*),parameter :: modname="disvert" | ||
49 | |||
50 | character(len=24):: vert_sampling | ||
51 | ! (allowed values are "param", "tropo", "strato" and "read") | ||
52 | |||
53 | !----------------------------------------------------------------------- | ||
54 | |||
55 | 1 | WRITE(lunout,*) TRIM(modname)//" starts" | |
56 | |||
57 | ! default scaleheight is 8km for earth | ||
58 | 1 | scaleheight=8. | |
59 | |||
60 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | vert_sampling = merge("strato", "tropo ", ok_strato) ! default value |
61 | 1 | call getin('vert_sampling', vert_sampling) | |
62 | 1 | WRITE(lunout,*) TRIM(modname)//' vert_sampling = ' // vert_sampling | |
63 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (llm==39 .and. vert_sampling=="strato") then |
64 | 1 | dsigmin=0.3 ! Vieille option par défaut pour CMIP5 | |
65 | else | ||
66 | ✗ | dsigmin=1. | |
67 | endif | ||
68 | 1 | call getin('dsigmin', dsigmin) | |
69 | 1 | WRITE(LUNOUT,*) trim(modname), 'Discretisation verticale DSIGMIN=',dsigmin | |
70 | |||
71 | |||
72 | ✗ | select case (vert_sampling) | |
73 | case ("param") | ||
74 | ! On lit les options dans sigma.def: | ||
75 | ✗ | OPEN(99, file='sigma.def', status='old', form='formatted') | |
76 | ✗ | READ(99, *) scaleheight ! hauteur d'echelle 8. | |
77 | ✗ | READ(99, *) deltaz ! epaiseur de la premiere couche 0.04 | |
78 | ✗ | READ(99, *) beta ! facteur d'acroissement en haut 1.3 | |
79 | ✗ | READ(99, *) k0 ! nombre de couches dans la transition surf | |
80 | ✗ | READ(99, *) k1 ! nombre de couches dans la transition haute | |
81 | ✗ | CLOSE(99) | |
82 | ✗ | alpha=deltaz/(llm*scaleheight) | |
83 | ✗ | write(lunout, *)trim(modname),':scaleheight, alpha, k0, k1, beta', & | |
84 | ✗ | scaleheight, alpha, k0, k1, beta | |
85 | |||
86 | ✗ | alpha=deltaz/tanh(1./k0)*2. | |
87 | zkm1=0. | ||
88 | ✗ | sig(1)=1. | |
89 | ✗ | do l=1, llm | |
90 | sig(l+1)=(cosh(l/k0))**(-alpha*k0/scaleheight) & | ||
91 | *exp(-alpha/scaleheight*tanh((llm-k1)/k0) & | ||
92 | ✗ | *beta**(l-(llm-k1))/log(beta)) | |
93 | ✗ | zk=-scaleheight*log(sig(l+1)) | |
94 | |||
95 | ✗ | dzk1=alpha*tanh(l/k0) | |
96 | ✗ | dzk2=alpha*tanh((llm-k1)/k0)*beta**(l-(llm-k1))/log(beta) | |
97 | ✗ | write(lunout, *)l, sig(l+1), zk, zk-zkm1, dzk1, dzk2 | |
98 | ✗ | zkm1=zk | |
99 | enddo | ||
100 | |||
101 | ✗ | sig(llm+1)=0. | |
102 | |||
103 | ✗ | bp(: llm) = EXP(1. - 1. / sig(: llm)**2) | |
104 | ✗ | bp(llmp1) = 0. | |
105 | |||
106 | ✗ | ap = pa * (sig - bp) | |
107 | case("sigma") | ||
108 | ✗ | DO l = 1, llm | |
109 | ✗ | x = 2*asin(1.) * (l - 0.5) / (llm + 1) | |
110 | ✗ | dsig(l) = dsigmin + 7.0 * SIN(x)**2 | |
111 | ENDDO | ||
112 | ✗ | dsig = dsig / sum(dsig) | |
113 | ✗ | sig(llm+1) = 0. | |
114 | ✗ | DO l = llm, 1, -1 | |
115 | ✗ | sig(l) = sig(l+1) + dsig(l) | |
116 | ENDDO | ||
117 | |||
118 | ✗ | bp(1)=1. | |
119 | ✗ | bp(2: llm) = sig(2:llm) | |
120 | ✗ | bp(llmp1) = 0. | |
121 | ✗ | ap(:)=0. | |
122 | case("tropo") | ||
123 | ✗ | DO l = 1, llm | |
124 | ✗ | x = 2*asin(1.) * (l - 0.5) / (llm + 1) | |
125 | ✗ | dsig(l) = dsigmin + 7.0 * SIN(x)**2 | |
126 | ENDDO | ||
127 | ✗ | dsig = dsig / sum(dsig) | |
128 | ✗ | sig(llm+1) = 0. | |
129 | ✗ | DO l = llm, 1, -1 | |
130 | ✗ | sig(l) = sig(l+1) + dsig(l) | |
131 | ENDDO | ||
132 | |||
133 | ✗ | bp(1)=1. | |
134 | ✗ | bp(2: llm) = EXP(1. - 1. / sig(2: llm)**2) | |
135 | ✗ | bp(llmp1) = 0. | |
136 | |||
137 | ✗ | ap(1)=0. | |
138 | ✗ | ap(2: llm + 1) = pa * (sig(2: llm + 1) - bp(2: llm + 1)) | |
139 | case("strato") | ||
140 |
2/2✓ Branch 0 taken 39 times.
✓ Branch 1 taken 1 times.
|
40 | DO l = 1, llm |
141 | 39 | x = 2*asin(1.) * (l - 0.5) / (llm + 1) | |
142 | dsig(l) =(dsigmin + 7. * SIN(x)**2) & | ||
143 | 40 | *(0.5*(1.-tanh(1.*(x-asin(1.))/asin(1.))))**2 | |
144 | ENDDO | ||
145 |
4/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 39 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 1 times.
|
80 | dsig = dsig / sum(dsig) |
146 | 1 | sig(llm+1) = 0. | |
147 |
2/2✓ Branch 0 taken 39 times.
✓ Branch 1 taken 1 times.
|
40 | DO l = llm, 1, -1 |
148 | 40 | sig(l) = sig(l+1) + dsig(l) | |
149 | ENDDO | ||
150 | |||
151 | 1 | bp(1)=1. | |
152 |
2/2✓ Branch 0 taken 38 times.
✓ Branch 1 taken 1 times.
|
39 | bp(2: llm) = EXP(1. - 1. / sig(2: llm)**2) |
153 | 1 | bp(llmp1) = 0. | |
154 | |||
155 | 1 | ap(1)=0. | |
156 |
2/2✓ Branch 0 taken 39 times.
✓ Branch 1 taken 1 times.
|
40 | ap(2: llm + 1) = pa * (sig(2: llm + 1) - bp(2: llm + 1)) |
157 | case("strato_correct") | ||
158 | !================================================================== | ||
159 | ! Fredho 2014/05/18, Saint-Louis du Senegal | ||
160 | ! Cette version de la discretisation strato est corrige au niveau | ||
161 | ! du passage des sig aux ap, bp | ||
162 | ! la version precedente donne un coude dans l'epaisseur des couches | ||
163 | ! vers la tropopause | ||
164 | !================================================================== | ||
165 | |||
166 | |||
167 | ✗ | DO l = 1, llm | |
168 | ✗ | x = 2*asin(1.) * (l - 0.5) / (llm + 1) | |
169 | dsig(l) =(dsigmin + 7. * SIN(x)**2) & | ||
170 | ✗ | *(0.5*(1.-tanh(1.*(x-asin(1.))/asin(1.))))**2 | |
171 | ENDDO | ||
172 | ✗ | dsig = dsig / sum(dsig) | |
173 | ✗ | sig0(llm+1) = 0. | |
174 | ✗ | DO l = llm, 1, -1 | |
175 | ✗ | sig0(l) = sig0(l+1) + dsig(l) | |
176 | ENDDO | ||
177 | ✗ | sig=racinesig(sig0) | |
178 | |||
179 | ✗ | bp(1)=1. | |
180 | ✗ | bp(2:llm)=EXP(1.-1./sig(2: llm)**2) | |
181 | ✗ | bp(llmp1)=0. | |
182 | |||
183 | ✗ | ap(1)=0. | |
184 | ✗ | ap(2:llm)=pa*(sig(2:llm)-bp(2:llm)) | |
185 | ✗ | ap(llm+1)=0. | |
186 | |||
187 | CASE("strato_custom0") | ||
188 | !======================================================= | ||
189 | ! Version Transitoire | ||
190 | ! custumize strato distribution with specific alpha & beta values and function | ||
191 | ! depending on llm (experimental and temporary)! | ||
192 | SELECT CASE (llm) | ||
193 | CASE(55) | ||
194 | alpha=0.45 | ||
195 | beta=4.0 | ||
196 | CASE(63) | ||
197 | alpha=0.45 | ||
198 | beta=5.0 | ||
199 | CASE(71) | ||
200 | alpha=3.05 | ||
201 | beta=65. | ||
202 | CASE(79) | ||
203 | alpha=3.20 | ||
204 | ! alpha=2.05 ! FLOTT 79 (PLANTE) | ||
205 | beta=70. | ||
206 | END SELECT | ||
207 | ! Or used values provided by user in def file: | ||
208 | ✗ | CALL getin("strato_alpha",alpha) | |
209 | ✗ | CALL getin("strato_beta",beta) | |
210 | |||
211 | ! Build geometrical distribution | ||
212 | ✗ | scaleheight=7. | |
213 | ✗ | zz(1)=0. | |
214 | IF (llm==55.OR.llm==63) THEN | ||
215 | DO l=1,llm | ||
216 | z=zz(l)/scaleheight | ||
217 | zz(l+1)=zz(l)+0.03+z*1.5*(1.-TANH(z-0.5))+alpha*(1.+TANH(z-1.5)) & | ||
218 | +5.0*EXP((l-llm)/beta) | ||
219 | ENDDO | ||
220 | ELSEIF (llm==71) THEN !.OR.llm==79) THEN ! FLOTT 79 (PLANTE) | ||
221 | DO l=1,llm | ||
222 | z=zz(l) | ||
223 | zz(l+1)=zz(l)+0.02+0.88*TANH(z/2.5)+alpha*(1.+TANH((z-beta)/15.)) | ||
224 | ENDDO | ||
225 | ELSEIF (llm==79) THEN | ||
226 | DO l=1,llm | ||
227 | z=zz(l) | ||
228 | zz(l+1)=zz(l)+0.02+0.80*TANH(z/3.8)+alpha*(1+TANH((z-beta)/17.)) & | ||
229 | +0.03*TANH(z/.25) | ||
230 | ENDDO | ||
231 | ENDIF ! of IF (llm==55.OR.llm==63) ... | ||
232 | |||
233 | |||
234 | ! Build sigma distribution | ||
235 | ✗ | sig0=EXP(-zz(:)/scaleheight) | |
236 | ✗ | sig0(llm+1)=0. | |
237 | ! sig=ridders(sig0) | ||
238 | ✗ | sig=racinesig(sig0) | |
239 | |||
240 | ! Compute ap() and bp() | ||
241 | ✗ | bp(1)=1. | |
242 | ✗ | bp(2:llm)=EXP(1.-1./sig(2:llm)**2) | |
243 | ✗ | bp(llm+1)=0. | |
244 | ✗ | ap=pa*(sig-bp) | |
245 | |||
246 | CASE("strato_custom") | ||
247 | !=================================================================== | ||
248 | ! David Cugnet, François Lott, Lionel Guez, Ehouoarn Millour, Fredho | ||
249 | ! 2014/05 | ||
250 | ! custumize strato distribution | ||
251 | ! Al the parameter are given in km assuming a given scalehigh | ||
252 | ✗ | vert_scale=7. ! scale hight | |
253 | ✗ | vert_dzmin=0.02 ! width of first layer | |
254 | ✗ | vert_dzlow=1. ! dz in the low atmosphere | |
255 | ✗ | vert_z0low=8. ! height at which resolution recches dzlow | |
256 | ✗ | vert_dzmid=3. ! dz in the mid atmsophere | |
257 | ✗ | vert_z0mid=70. ! height at which resolution recches dzmid | |
258 | ✗ | vert_h_mid=20. ! width of the transition | |
259 | ✗ | vert_dzhig=11. ! dz in the high atmsophere | |
260 | ✗ | vert_z0hig=80. ! height at which resolution recches dz | |
261 | ✗ | vert_h_hig=20. ! width of the transition | |
262 | !=================================================================== | ||
263 | |||
264 | ✗ | call getin('vert_scale',vert_scale) | |
265 | ✗ | call getin('vert_dzmin',vert_dzmin) | |
266 | ✗ | call getin('vert_dzlow',vert_dzlow) | |
267 | ✗ | call getin('vert_z0low',vert_z0low) | |
268 | ✗ | CALL getin('vert_dzmid',vert_dzmid) | |
269 | ✗ | CALL getin('vert_z0mid',vert_z0mid) | |
270 | ✗ | call getin('vert_h_mid',vert_h_mid) | |
271 | ✗ | call getin('vert_dzhig',vert_dzhig) | |
272 | ✗ | call getin('vert_z0hig',vert_z0hig) | |
273 | ✗ | call getin('vert_h_hig',vert_h_hig) | |
274 | |||
275 | ✗ | scaleheight=vert_scale ! for consistency with further computations | |
276 | ! Build geometrical distribution | ||
277 | ✗ | zz(1)=0. | |
278 | ✗ | DO l=1,llm | |
279 | ✗ | z=zz(l) | |
280 | zz(l+1)=zz(l)+vert_dzmin+vert_dzlow*TANH(z/vert_z0low)+ & | ||
281 | & (vert_dzmid-vert_dzlow)* & | ||
282 | & (TANH((z-vert_z0mid)/vert_h_mid)-TANH((-vert_z0mid)/vert_h_mid)) & | ||
283 | & +(vert_dzhig-vert_dzmid-vert_dzlow)* & | ||
284 | ✗ | & (TANH((z-vert_z0hig)/vert_h_hig)-TANH((-vert_z0hig)/vert_h_hig)) | |
285 | ENDDO | ||
286 | |||
287 | |||
288 | !=================================================================== | ||
289 | ! Comment added Fredho 2014/05/18, Saint-Louis, Senegal | ||
290 | ! From approximate z to ap, bp, so that p=ap+bp*p0 and p/p0=exp(-z/H) | ||
291 | ! sig0 is p/p0 | ||
292 | ! sig is an intermediate distribution introduce to estimate bp | ||
293 | ! 1. sig0=exp(-z/H) | ||
294 | ! 2. inversion of sig0=(1-pa/p0)*sig+(1-pa/p0)*exp(1-1/sig**2) | ||
295 | ! 3. bp=exp(1-1/sig**2) | ||
296 | ! 4. ap deduced from the combination of 2 and 3 so that sig0=ap/p0+bp | ||
297 | !=================================================================== | ||
298 | |||
299 | ✗ | sig0=EXP(-zz(:)/vert_scale) | |
300 | ✗ | sig0(llm+1)=0. | |
301 | ✗ | sig=racinesig(sig0) | |
302 | ✗ | bp(1)=1. | |
303 | ✗ | bp(2:llm)=EXP(1.-1./sig(2:llm)**2) | |
304 | ✗ | bp(llm+1)=0. | |
305 | ✗ | ap=pa*(sig-bp) | |
306 | |||
307 | case("read") | ||
308 | ! Read "ap" and "bp". First line is skipped (title line). "ap" | ||
309 | ! should be in Pa. First couple of values should correspond to | ||
310 | ! the surface, that is : "bp" should be in descending order. | ||
311 | ✗ | call new_unit(unit) | |
312 | open(unit, file="hybrid.txt", status="old", action="read", & | ||
313 | ✗ | position="rewind") | |
314 | ✗ | read(unit, fmt=*) ! skip title line | |
315 | ✗ | do l = 1, llm + 1 | |
316 | ✗ | read(unit, fmt=*) ap(l), bp(l) | |
317 | end do | ||
318 | ✗ | close(unit) | |
319 | call assert(ap(1) == 0., ap(llm + 1) == 0., bp(1) == 1., & | ||
320 | ✗ | bp(llm + 1) == 0., "disvert: bad ap or bp values") | |
321 | case default | ||
322 |
1/9✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
|
1 | call abort_gcm("disvert", 'Wrong value for "vert_sampling"', 1) |
323 | END select | ||
324 | |||
325 |
2/2✓ Branch 0 taken 39 times.
✓ Branch 1 taken 1 times.
|
40 | DO l=1, llm |
326 | 40 | nivsigs(l) = REAL(l) | |
327 | ENDDO | ||
328 | |||
329 |
2/2✓ Branch 0 taken 40 times.
✓ Branch 1 taken 1 times.
|
41 | DO l=1, llmp1 |
330 | 41 | nivsig(l)= REAL(l) | |
331 | ENDDO | ||
332 | |||
333 | 1 | write(lunout, *) trim(modname),': BP ' | |
334 | 1 | write(lunout, *) bp | |
335 | 1 | write(lunout, *) trim(modname),': AP ' | |
336 | 1 | write(lunout, *) ap | |
337 | |||
338 | 1 | write(lunout, *) 'Niveaux de pressions approximatifs aux centres des' | |
339 | 1 | write(lunout, *)'couches calcules pour une pression de surface =', preff | |
340 | 1 | write(lunout, *) 'et altitudes equivalentes pour une hauteur d echelle de ' | |
341 | 1 | write(lunout, *) scaleheight,' km' | |
342 |
2/2✓ Branch 0 taken 39 times.
✓ Branch 1 taken 1 times.
|
40 | DO l = 1, llm |
343 | 39 | dpres(l) = bp(l) - bp(l+1) | |
344 | 39 | aps(l) = 0.5 *( ap(l) +ap(l+1)) | |
345 | 39 | bps(l) = 0.5 *( bp(l) +bp(l+1)) | |
346 | 39 | presnivs(l) = 0.5 *( ap(l)+bp(l)*preff + ap(l+1)+bp(l+1)*preff ) | |
347 | 39 | pseudoalt(l) = log(preff/presnivs(l))*scaleheight | |
348 | 39 | write(lunout, *)'PRESNIVS(', l, ')=', presnivs(l), ' Z ~ ', & | |
349 | pseudoalt(l) & | ||
350 | 39 | , ' DZ ~ ', scaleheight*log((ap(l)+bp(l)*preff)/ & | |
351 | 79 | max(ap(l+1)+bp(l+1)*preff, 1.e-10)) | |
352 | ENDDO | ||
353 | |||
354 | 1 | write(lunout, *) trim(modname),': PRESNIVS ' | |
355 | 1 | write(lunout, *) presnivs | |
356 | |||
357 | CONTAINS | ||
358 | |||
359 | !------------------------------------------------------------------------------- | ||
360 | ! | ||
361 | FUNCTION ridders(sig) RESULT(sg) | ||
362 | ! | ||
363 | !------------------------------------------------------------------------------- | ||
364 | IMPLICIT NONE | ||
365 | !------------------------------------------------------------------------------- | ||
366 | ! Purpose: Search for s solving (Pa/Preff)*s+(1-Pa/Preff)*EXP(1-1./s**2)=sg | ||
367 | ! Notes: Uses Ridders' method, quite robust. Initial bracketing: 0<=sg<=1. | ||
368 | ! Reference: Ridders, C. F. J. "A New Algorithm for Computing a Single Root of a | ||
369 | ! Real Continuous Function" IEEE Trans. Circuits Systems 26, 979-980, 1979 | ||
370 | !------------------------------------------------------------------------------- | ||
371 | ! Arguments: | ||
372 | REAL, INTENT(IN) :: sig(:) | ||
373 | REAL :: sg(SIZE(sig)) | ||
374 | !------------------------------------------------------------------------------- | ||
375 | ! Local variables: | ||
376 | INTEGER :: it, ns, maxit | ||
377 | REAL :: c1, c2, x1, x2, x3, x4, f1, f2, f3, f4, s, xx, distrib | ||
378 | !------------------------------------------------------------------------------- | ||
379 | ns=SIZE(sig); maxit=9999 | ||
380 | c1=Pa/Preff; c2=1.-c1 | ||
381 | DO l=1,ns | ||
382 | xx=HUGE(1.) | ||
383 | x1=0.0; f1=distrib(x1,c1,c2,sig(l)) | ||
384 | x2=1.0; f2=distrib(x2,c1,c2,sig(l)) | ||
385 | DO it=1,maxit | ||
386 | x3=0.5*(x1+x2); f3=distrib(x3,c1,c2,sig(l)) | ||
387 | s=SQRT(f3**2-f1*f2); IF(s==0.) EXIT | ||
388 | x4=x3+(x3-x1)*(SIGN(1.,f1-f2)*f3/s); IF(ABS(10.*LOG(x4-xx))<=1E-5) EXIT | ||
389 | xx=x4; f4=distrib(x4,c1,c2,sig(l)); IF(f4==0.) EXIT | ||
390 | IF(SIGN(f3,f4)/=f3) THEN; x1=x3; f1=f3; x2=xx; f2=f4 | ||
391 | ELSE IF(SIGN(f1,f4)/=f1) THEN; x2=xx; f2=f4 | ||
392 | ELSE IF(SIGN(f2,f4)/=f2) THEN; x1=xx; f1=f4 | ||
393 | ELSE; CALL abort_gcm("ridders",'Algorithm failed (which is odd...') | ||
394 | END IF | ||
395 | IF(ABS(10.*LOG(ABS(x2-x1)))<=1E-5) EXIT !--- ERROR ON SIG <= 0.01m | ||
396 | END DO | ||
397 | IF(it==maxit+1) WRITE(lunout,'(a,i3)')'WARNING in ridder: failed to converg& | ||
398 | &e for level ',l | ||
399 | sg(l)=xx | ||
400 | END DO | ||
401 | sg(1)=1.; sg(ns)=0. | ||
402 | |||
403 | END FUNCTION ridders | ||
404 | |||
405 | ✗ | FUNCTION racinesig(sig) RESULT(sg) | |
406 | ! | ||
407 | !------------------------------------------------------------------------------- | ||
408 | IMPLICIT NONE | ||
409 | !------------------------------------------------------------------------------- | ||
410 | ! Fredho 2014/05/18 | ||
411 | ! Purpose: Search for s solving (Pa/Preff)*sg+(1-Pa/Preff)*EXP(1-1./sg**2)=s | ||
412 | ! Notes: Uses Newton Raphson search | ||
413 | !------------------------------------------------------------------------------- | ||
414 | ! Arguments: | ||
415 | REAL, INTENT(IN) :: sig(:) | ||
416 | REAL :: sg(SIZE(sig)) | ||
417 | !------------------------------------------------------------------------------- | ||
418 | ! Local variables: | ||
419 | INTEGER :: it, ns, maxit | ||
420 | REAL :: c1, c2, x1, x2, x3, x4, f1, f2, f3, f4, s, xx, distrib | ||
421 | !------------------------------------------------------------------------------- | ||
422 | ns=SIZE(sig); maxit=100 | ||
423 | ✗ | c1=Pa/Preff; c2=1.-c1 | |
424 | ✗ | DO l=2,ns-1 | |
425 | ✗ | sg(l)=sig(l) | |
426 | ✗ | DO it=1,maxit | |
427 | ✗ | f1=exp(1-1./sg(l)**2)*(1.-c1) | |
428 | ✗ | sg(l)=sg(l)-(c1*sg(l)+f1-sig(l))/(c1+2*f1*sg(l)**(-3)) | |
429 | ENDDO | ||
430 | ! print*,'SSSSIG ',sig(l),sg(l),c1*sg(l)+exp(1-1./sg(l)**2)*(1.-c1) | ||
431 | ENDDO | ||
432 | ✗ | sg(1)=1.; sg(ns)=0. | |
433 | |||
434 | ✗ | END FUNCTION racinesig | |
435 | |||
436 | |||
437 | |||
438 | |||
439 | END SUBROUTINE disvert | ||
440 | |||
441 | !------------------------------------------------------------------------------- | ||
442 | |||
443 | ✗ | FUNCTION distrib(x,c1,c2,x0) RESULT(res) | |
444 | ! | ||
445 | !------------------------------------------------------------------------------- | ||
446 | ! Arguments: | ||
447 | REAL, INTENT(IN) :: x, c1, c2, x0 | ||
448 | REAL :: res | ||
449 | !------------------------------------------------------------------------------- | ||
450 | ✗ | res=c1*x+c2*EXP(1-1/(x**2))-x0 | |
451 | |||
452 | ✗ | END FUNCTION distrib | |
453 | |||
454 | |||
455 |