source: trunk/LMDZ.GENERIC/libf/dyn3d/calfis.F @ 832

Last change on this file since 832 was 787, checked in by aslmd, 12 years ago

LMDZ.GENERIC. (Sorry for long text but this is a quite major commit)

Paving the path for parallel computations. And moving towards a more flexible code.

Automatic allocation is used within all routines in phystd. No further mention to ngridmx and nqmx.

  1. ngridmx and nqmx are still used in LMDZ.GENERIC in the dyn3d part
  2. if the LMDZ4/LMDZ5 dynamical core is used, there is no more fixed dimensions ngridmx and nqmx --> a fully flexible parallel implementation is now possible (e.g. no need to recompile when changing numbers of processors)

The important stuff :

  • Compilation checked with ifort. OK with and without debug mode. No errors. Checked for: gcm, newstart, rcm1d, kcm1d
  • RUN GCM: Running an Earth test case. Comparison with previous revision --> debug mode : perfect match. bit by bit (diff command). checked with plots --> O1 mode : close match (checked with plots) --> O2 mode : sometimes up to 0.5 K departure.... BUT in this new version O2 and O1 are quite close while in previous version O1 and O2 differed by about, well, typically 0.5 K (pictures available on request)
  • RUN NEWSTART : perfect match (bit-by-bit) in either debug or normal mode.
  • RUN RCM1D : perfect match in normal mode.
  • RUN KCM1D : not tested (I don't know what is the use of kcm1d)

List of main changes :

  • Additional arguments to some subroutines (ngrid and nq)
  • F77 include strategy is obsolete and replaced by F90 module strategy In this new strategy arrays are allocatable and allocated once at first use This has to be done for all common featuring arrays defined with ngridmx or nqmx

surfdat.h >> surfdat_h.F90
tracer.h >> tracer_h.F90
comsaison.h >> comsaison_h.F90
comgeomfi.h >> comgeomfi_h.F90
comsoil.h >> comsoil_h.F90
comdiurn.h >> comdiurn_h.F90
fisice.h >> DELETED. was not used. probably a fossil.
watercap.h >> DELETED. variable put in surfdat_h.F90

  • F77 'save' strategy is obsolete and replaced by F90 'allocatable save' strategy (see previous point and e.g. new version of physiq.F90)
  • Suppressing any mention to advtrac.h which is a common in the dynamics and needs nqmx This was easily solved by adding an argument with tracer names, coming from the dynamics This is probably not a definitive solution, ... but this allows for generic physics to work easily with either LMDZ.GENERIC or LMDZ dynamical cores
  • Removing consistency tests between nq and nqmx ; and ngrid and ngridmx. No use now!
  • Adaptation of rcm1d, kcm1d, newstart given above-mentioned changes

A note on phyetat0 and soil_setting:

  • Now written so that a slice of horizontal size 'ngrid' starting at grid point 'cursor' is read in startfi.nc 'cursor' is defined in dimphys.h and initialized by inifis (or in newstart) this is useful for parallel computations. default behavior is the usual one : sequential runs, cursor is 1, size ngrid is the whole global domain

A note on an additional change :

  • nueffrad is now an argument to callcorrk as is the case for reffrad both are saved in physiq this is for consistency and lisibility (previously nueffrad was saved in callcorrk) ... but there is a call to a function which modifies nueffrad in physiq ... previously this was not modifying nueffrad (although it was quite cumbersome to detect this) ... to be conservative I kept this behaviour and highlighted it with an array nueffrad_dummy ... I added a comment because someone might want to change this
File size: 15.1 KB
Line 
1      SUBROUTINE calfis(nq, lafin, rdayvrai,rday_ecri, heure,
2     $            pucov,pvcov,pteta,pq,pmasse,pps,pp,ppk,pphis,pphi,
3     $            pducov,pdvcov,pdteta,pdq,pw,
4     $            pdufi,pdvfi,pdhfi,pdqfi,pdpsfi,tracer )
5c
6c    Auteur :  P. Le Van, F. Hourdin
7c   .........
8
9      IMPLICIT NONE
10c=======================================================================
11c
12c   1. rearrangement des tableaux et transformation
13c      variables dynamiques  >  variables physiques
14c   2. calcul des termes physiques
15c   3. retransformation des tendances physiques en tendances dynamiques
16c
17c   remarques:
18c   ----------
19c
20c    - les vents sont donnes dans la physique par leurs composantes
21c      naturelles.
22c    - la variable thermodynamique de la physique est une variable
23c      intensive :   T
24c      pour la dynamique on prend    T * ( preff / p(l) ) **kappa
25c    - les deux seules variables dependant de la geometrie necessaires
26c      pour la physique sont la latitude pour le rayonnement et
27c      l'aire de la maille quand on veut integrer une grandeur
28c      horizontalement.
29c    - les points de la physique sont les points scalaires de la
30c      la dynamique; numerotation:
31c          1 pour le pole nord
32c          (jjm-1)*iim pour l'interieur du domaine
33c          ngridmx pour le pole sud
34c      ---> ngridmx=2+(jjm-1)*iim
35c
36c     Input :
37c     -------
38c       ecritphy        frequence d'ecriture (en jours)de histphy
39c       pucov           covariant zonal velocity
40c       pvcov           covariant meridional velocity
41c       pteta           potential temperature
42c       pps             surface pressure
43c       pmasse          masse d'air dans chaque maille
44c       pts             surface temperature  (K)
45c       pw              flux vertical (kg m-2)
46c
47c    Output :
48c    --------
49c        pdufi          tendency for the natural zonal velocity (ms-1)
50c        pdvfi          tendency for the natural meridional velocity
51c        pdhfi          tendency for the potential temperature
52c        pdtsfi         tendency for the surface temperature
53c
54c        tracer         Call tracer in  gcm.F ? (decided in callphys.def)
55c
56c=======================================================================
57c
58c-----------------------------------------------------------------------
59c
60c    0.  Declarations :
61c    ------------------
62
63#include "dimensions.h"
64#include "paramet.h"
65#include "temps.h"
66
67      INTEGER ngridmx,nq
68      PARAMETER( ngridmx = 2+(jjm-1)*iim - 1/jjm   )
69
70#include "comconst.h"
71#include "comvert.h"
72#include "comgeom2.h"
73#include "control.h"
74
75#include "advtrac.h"
76!! this is to get tnom (tracers name)
77
78c    Arguments :
79c    -----------
80      LOGICAL  lafin
81      REAL heure
82
83      REAL pvcov(iip1,jjm,llm)
84      REAL pucov(iip1,jjp1,llm)
85      REAL pteta(iip1,jjp1,llm)
86      REAL pmasse(iip1,jjp1,llm)
87      REAL pq(iip1,jjp1,llm,nqmx)
88      REAL pphis(iip1,jjp1)
89      REAL pphi(iip1,jjp1,llm)
90c
91      REAL pdvcov(iip1,jjm,llm)
92      REAL pducov(iip1,jjp1,llm)
93      REAL pdteta(iip1,jjp1,llm)
94      REAL pdq(iip1,jjp1,llm,nqmx)
95c
96      REAL pw(iip1,jjp1,llm)
97c
98      REAL pps(iip1,jjp1)
99      REAL pp(iip1,jjp1,llmp1)
100      REAL ppk(iip1,jjp1,llm)
101c
102      REAL pdvfi(iip1,jjm,llm)
103      REAL pdufi(iip1,jjp1,llm)
104      REAL pdhfi(iip1,jjp1,llm)
105      REAL pdqfi(iip1,jjp1,llm,nqmx)
106      REAL pdpsfi(iip1,jjp1)
107      logical tracer
108
109c    Local variables :
110c    -----------------
111
112      INTEGER i,j,l,ig0,ig,iq
113      REAL zpsrf(ngridmx)
114      REAL zplev(ngridmx,llm+1),zplay(ngridmx,llm)
115      REAL zphi(ngridmx,llm),zphis(ngridmx)
116c
117      REAL zufi(ngridmx,llm), zvfi(ngridmx,llm)
118      REAL ztfi(ngridmx,llm),zqfi(ngridmx,llm,nqmx)
119c
120      REAL zvervel(ngridmx,llm)
121c
122      REAL zdufi(ngridmx,llm),zdvfi(ngridmx,llm)
123      REAL zdtfi(ngridmx,llm),zdqfi(ngridmx,llm,nqmx)
124      REAL zdpsrf(ngridmx)
125c
126      REAL zsin(iim),zcos(iim),z1(iim)
127      REAL zsinbis(iim),zcosbis(iim),z1bis(iim)
128      REAL unskap, pksurcp
129c
130     
131      EXTERNAL gr_dyn_fi,gr_fi_dyn
132      EXTERNAL physiq,multipl
133      REAL SSUM
134      EXTERNAL SSUM
135
136      REAL latfi(ngridmx),lonfi(ngridmx)
137      REAL airefi(ngridmx)
138      SAVE latfi, lonfi, airefi
139
140      LOGICAL firstcal, debut
141      DATA firstcal/.true./
142      SAVE firstcal,debut
143      REAL rdayvrai,rday_ecri
144c
145c-----------------------------------------------------------------------
146c
147c    1. Initialisations :
148c    --------------------
149c
150
151
152      IF (ngridmx.NE.2+(jjm-1)*iim) THEN
153         PRINT*,'STOP dans calfis'
154         PRINT*,'La dimension ngridmx doit etre egale a 2 + (jjm-1)*iim'
155         PRINT*,'  ngridmx  jjm   iim   '
156         PRINT*,ngridmx,jjm,iim
157         STOP
158      ENDIF
159
160c-----------------------------------------------------------------------
161c   latitude, longitude et aires des mailles pour la physique:
162c   ----------------------------------------------------------
163
164c
165      IF ( firstcal )  THEN
166          debut = .TRUE.
167      ELSE
168          debut = .FALSE.
169      ENDIF
170
171c
172      IF (firstcal) THEN
173         latfi(1)=rlatu(1)
174         lonfi(1)=0.
175         DO j=2,jjm
176            DO i=1,iim
177               latfi((j-2)*iim+1+i)= rlatu(j)
178               lonfi((j-2)*iim+1+i)= rlonv(i)
179            ENDDO
180         ENDDO
181         latfi(ngridmx)= rlatu(jjp1)
182         lonfi(ngridmx)= 0.
183
184         ! build airefi(), mesh area on physics grid
185         CALL gr_dyn_fi(1,iip1,jjp1,ngridmx,aire,airefi)
186         ! Poles are single points on physics grid
187         airefi(1)=airefi(1)*iim
188         airefi(ngridmx)=airefi(ngridmx)*iim
189
190         CALL inifis(ngridmx,llm,day_ini,daysec,dtphys,
191     .                latfi,lonfi,airefi,rad,g,r,cpp)
192      ENDIF
193
194c
195c-----------------------------------------------------------------------
196c   40. transformation des variables dynamiques en variables physiques:
197c   ---------------------------------------------------------------
198
199c   41. pressions au sol (en Pascals)
200c   ----------------------------------
201
202       
203      zpsrf(1) = pps(1,1)
204
205      ig0  = 2
206      DO j = 2,jjm
207         CALL SCOPY( iim,pps(1,j),1,zpsrf(ig0), 1 )
208         ig0 = ig0+iim
209      ENDDO
210
211      zpsrf(ngridmx) = pps(1,jjp1)
212
213
214c   42. pression intercouches :
215c
216c   -----------------------------------------------------------------
217c     .... zplev  definis aux (llm +1) interfaces des couches  ....
218c     .... zplay  definis aux (  llm )    milieux des couches  ....
219c   -----------------------------------------------------------------
220
221c    ...    Exner = cp * ( p(l) / preff ) ** kappa     ....
222c
223       unskap   = 1./ kappa
224c
225      DO l = 1, llmp1
226        zplev( 1,l ) = pp(1,1,l)
227        ig0 = 2
228          DO j = 2, jjm
229             DO i =1, iim
230              zplev( ig0,l ) = pp(i,j,l)
231              ig0 = ig0 +1
232             ENDDO
233          ENDDO
234        zplev( ngridmx,l ) = pp(1,jjp1,l)
235      ENDDO
236c
237c
238
239c   43. temperature naturelle (en K) et pressions milieux couches .
240c   ---------------------------------------------------------------
241
242      DO l=1,llm
243
244         pksurcp     =  ppk(1,1,l) / cpp
245         zplay(1,l)  =  preff * pksurcp ** unskap
246         ztfi(1,l)   =  pteta(1,1,l) *  pksurcp
247         ig0         =  2
248
249         DO j = 2, jjm
250            DO i = 1, iim
251              pksurcp        = ppk(i,j,l) / cpp
252              zplay(ig0,l)   = preff * pksurcp ** unskap
253              ztfi(ig0,l)    = pteta(i,j,l)  * pksurcp
254              ig0            = ig0 + 1
255            ENDDO
256         ENDDO
257
258         pksurcp       = ppk(1,jjp1,l) / cpp
259         zplay(ig0,l)  = preff * pksurcp ** unskap
260         ztfi (ig0,l)  = pteta(1,jjp1,l)  * pksurcp
261
262      ENDDO
263
264      DO l=1, llm
265        DO ig=1,ngridmx
266             if (ztfi(ig,l).lt.15) then
267                  write(*,*) 'New Temperature below 15 K !!! '
268                      write(*,*) 'Stop in calfis.F '
269                      write(*,*) 'ig=', ig, ' l=', l
270                      write(*,*) 'ztfi(ig,l)=',ztfi(ig,l)
271                  stop
272             end if
273        ENDDO
274      ENDDO
275
276
277
278c   43.bis Taceurs (en kg/kg)
279c   --------------------------
280      DO iq=1,nqmx
281         DO l=1,llm
282            zqfi(1,l,iq) = pq(1,1,l,iq)
283            ig0          = 2
284            DO j=2,jjm
285               DO i = 1, iim
286                  zqfi(ig0,l,iq)  = pq(i,j,l,iq)
287                  ig0             = ig0 + 1
288               ENDDO
289            ENDDO
290            zqfi(ig0,l,iq) = pq(1,jjp1,l,iq)
291         ENDDO
292      ENDDO
293
294c   Geopotentiel calcule par rapport a la surface locale:
295c   -----------------------------------------------------
296
297      CALL gr_dyn_fi(llm,iip1,jjp1,ngridmx,pphi,zphi)
298      CALL gr_dyn_fi(1,iip1,jjp1,ngridmx,pphis,zphis)
299      DO l=1,llm
300         DO ig=1,ngridmx
301            zphi(ig,l)=zphi(ig,l)-zphis(ig)
302         ENDDO
303      ENDDO
304
305c   Calcul de la vitesse  verticale (m/s) pour diagnostique
306c   -------------------------------
307c     pw est en kg/s
308c On interpole "lineairement" la temperature entre les couches(FF,10/95)
309
310      DO ig=1,ngridmx
311         zvervel(ig,1)=0.
312      END DO
313      DO l=2,llm
314        zvervel(1,l)=(pw(1,1,l)/apoln)
315     &  * r *0.5*(ztfi(1,l)+ztfi(1,l-1)) /zplev(1,l)             
316        ig0=2
317       DO j=2,jjm
318           DO i = 1, iim
319              zvervel(ig0,l) = pw(i,j,l) * unsaire(i,j)
320     &        * r *0.5*(ztfi(ig0,l)+ztfi(ig0,l-1)) /zplev(ig0,l)             
321              ig0 = ig0 + 1
322           ENDDO
323       ENDDO
324        zvervel(ig0,l)=(pw(1,jjp1,l)/apols)
325     &  * r *0.5*(ztfi(ig0,l)+ztfi(ig0,l-1)) /zplev(ig0,l)             
326      ENDDO
327
328c    .........  Reindexation : calcul de zvervel au MILIEU des couches
329       DO l=1,llm-1
330              DO ig=1,ngridmx
331                     zvervel(ig,l) = 0.5*(zvervel(ig,l)+zvervel(ig,l+1))
332          END DO
333       END DO
334c      (dans la couche llm, on garde la valeur à la limite inférieure llm)
335
336c   45. champ u:
337c   ------------
338
339      DO 50 l=1,llm
340
341         DO 25 j=2,jjm
342            ig0 = 1+(j-2)*iim
343            zufi(ig0+1,l)= 0.5 *
344     $      ( pucov(iim,j,l)/cu(iim,j) + pucov(1,j,l)/cu(1,j) )
345            DO 10 i=2,iim
346               zufi(ig0+i,l)= 0.5 *
347     $         ( pucov(i-1,j,l)/cu(i-1,j) + pucov(i,j,l)/cu(i,j) )
34810         CONTINUE
34925      CONTINUE
350
35150    CONTINUE
352
353
354c   46.champ v:
355c   -----------
356
357      DO l=1,llm
358         DO j=2,jjm
359            ig0=1+(j-2)*iim
360            DO i=1,iim
361               zvfi(ig0+i,l)= 0.5 *
362     $         ( pvcov(i,j-1,l)/cv(i,j-1) + pvcov(i,j,l)/cv(i,j) )
363            ENDDO
364         ENDDO
365      ENDDO
366
367
368c   47. champs de vents aux pole nord   
369c   ------------------------------
370c        U = 1 / pi  *  integrale [ v * cos(long) * d long ]
371c        V = 1 / pi  *  integrale [ v * sin(long) * d long ]
372
373      DO l=1,llm
374
375         z1(1)   =(rlonu(1)-rlonu(iim)+2.*pi)*pvcov(1,1,l)/cv(1,1)
376         z1bis(1)=(rlonu(1)-rlonu(iim)+2.*pi)*pdvcov(1,1,l)/cv(1,1)
377         DO i=2,iim
378            z1(i)   =(rlonu(i)-rlonu(i-1))*pvcov(i,1,l)/cv(i,1)
379            z1bis(i)=(rlonu(i)-rlonu(i-1))*pdvcov(i,1,l)/cv(i,1)
380         ENDDO
381
382         DO i=1,iim
383            zcos(i)   = COS(rlonv(i))*z1(i)
384            zcosbis(i)= COS(rlonv(i))*z1bis(i)
385            zsin(i)   = SIN(rlonv(i))*z1(i)
386            zsinbis(i)= SIN(rlonv(i))*z1bis(i)
387         ENDDO
388
389         zufi(1,l)  = SSUM(iim,zcos,1)/pi
390         zvfi(1,l)  = SSUM(iim,zsin,1)/pi
391
392      ENDDO
393
394
395c   48. champs de vents aux pole sud:
396c   ---------------------------------
397c        U = 1 / pi  *  integrale [ v * cos(long) * d long ]
398c        V = 1 / pi  *  integrale [ v * sin(long) * d long ]
399
400      DO l=1,llm
401
402         z1(1)   =(rlonu(1)-rlonu(iim)+2.*pi)*pvcov(1,jjm,l)/cv(1,jjm)
403         z1bis(1)=(rlonu(1)-rlonu(iim)+2.*pi)*pdvcov(1,jjm,l)/cv(1,jjm)
404         DO i=2,iim
405            z1(i)   =(rlonu(i)-rlonu(i-1))*pvcov(i,jjm,l)/cv(i,jjm)
406            z1bis(i)=(rlonu(i)-rlonu(i-1))*pdvcov(i,jjm,l)/cv(i,jjm)
407      ENDDO
408
409         DO i=1,iim
410            zcos(i)    = COS(rlonv(i))*z1(i)
411            zcosbis(i) = COS(rlonv(i))*z1bis(i)
412            zsin(i)    = SIN(rlonv(i))*z1(i)
413            zsinbis(i) = SIN(rlonv(i))*z1bis(i)
414      ENDDO
415
416         zufi(ngridmx,l)  = SSUM(iim,zcos,1)/pi
417         zvfi(ngridmx,l)  = SSUM(iim,zsin,1)/pi
418
419      ENDDO
420
421c-----------------------------------------------------------------------
422c   Appel de la physique:
423c   ---------------------
424
425
426      CALL physiq (ngridmx,llm,nq,
427     .     tnom,
428     ,     debut,lafin,
429     ,     rday_ecri,heure,dtphys,
430     ,     zplev,zplay,zphi,
431     ,     zufi, zvfi,ztfi, zqfi, 
432     ,     zvervel,
433C - sorties
434     s     zdufi, zdvfi, zdtfi, zdqfi,zdpsrf,tracer)
435
436
437c-----------------------------------------------------------------------
438c   transformation des tendances physiques en tendances dynamiques:
439c   ---------------------------------------------------------------
440
441c  tendance sur la pression :
442c  -----------------------------------
443
444      CALL gr_fi_dyn(1,ngridmx,iip1,jjp1,zdpsrf,pdpsfi)
445c
446ccc     CALL multipl(ip1jmp1,aire,pdpsfi,pdpsfi)
447
448c   62. enthalpie potentielle
449c   ---------------------
450
451      DO l=1,llm
452
453         DO i=1,iip1
454          pdhfi(i,1,l)    = cpp *  zdtfi(1,l)      / ppk(i, 1  ,l)
455          pdhfi(i,jjp1,l) = cpp *  zdtfi(ngridmx,l)/ ppk(i,jjp1,l)
456         ENDDO
457
458         DO j=2,jjm
459            ig0=1+(j-2)*iim
460            DO i=1,iim
461               pdhfi(i,j,l) = cpp * zdtfi(ig0+i,l) / ppk(i,j,l)
462            ENDDO
463               pdhfi(iip1,j,l) =  pdhfi(1,j,l)
464         ENDDO
465
466      ENDDO
467
468
469c   62. humidite specifique
470c   ---------------------
471
472      DO iq=1,nqmx
473         DO l=1,llm
474            DO i=1,iip1
475               pdqfi(i,1,l,iq)    = zdqfi(1,l,iq)
476               pdqfi(i,jjp1,l,iq) = zdqfi(ngridmx,l,iq)
477            ENDDO
478            DO j=2,jjm
479               ig0=1+(j-2)*iim
480               DO i=1,iim
481                  pdqfi(i,j,l,iq) = zdqfi(ig0+i,l,iq)
482               ENDDO
483               pdqfi(iip1,j,l,iq) = pdqfi(1,j,l,iq)
484            ENDDO
485         ENDDO
486      ENDDO
487
488c   65. champ u:
489c   ------------
490
491      DO l=1,llm
492
493         DO i=1,iip1
494            pdufi(i,1,l)    = 0.
495            pdufi(i,jjp1,l) = 0.
496         ENDDO
497
498         DO j=2,jjm
499            ig0=1+(j-2)*iim
500            DO i=1,iim-1
501               pdufi(i,j,l)=
502     $         0.5*(zdufi(ig0+i,l)+zdufi(ig0+i+1,l))*cu(i,j)
503            ENDDO
504            pdufi(iim,j,l)=
505     $      0.5*(zdufi(ig0+1,l)+zdufi(ig0+iim,l))*cu(iim,j)
506            pdufi(iip1,j,l)=pdufi(1,j,l)
507         ENDDO
508
509      ENDDO
510
511
512c   67. champ v:
513c   ------------
514
515      DO l=1,llm
516
517         DO j=2,jjm-1
518            ig0=1+(j-2)*iim
519            DO i=1,iim
520               pdvfi(i,j,l)=
521     $         0.5*(zdvfi(ig0+i,l)+zdvfi(ig0+i+iim,l))*cv(i,j)
522            ENDDO
523            pdvfi(iip1,j,l) = pdvfi(1,j,l)
524         ENDDO
525      ENDDO
526
527
528c   68. champ v pres des poles:
529c   ---------------------------
530c      v = U * cos(long) + V * SIN(long)
531
532      DO l=1,llm
533
534         DO i=1,iim
535            pdvfi(i,1,l)=
536     $      zdufi(1,l)*COS(rlonv(i))+zdvfi(1,l)*SIN(rlonv(i))
537            pdvfi(i,jjm,l)=zdufi(ngridmx,l)*COS(rlonv(i))
538     $      +zdvfi(ngridmx,l)*SIN(rlonv(i))
539            pdvfi(i,1,l)=
540     $      0.5*(pdvfi(i,1,l)+zdvfi(i+1,l))*cv(i,1)
541            pdvfi(i,jjm,l)=
542     $      0.5*(pdvfi(i,jjm,l)+zdvfi(ngridmx-iip1+i,l))*cv(i,jjm)
543          ENDDO
544
545         pdvfi(iip1,1,l)  = pdvfi(1,1,l)
546         pdvfi(iip1,jjm,l)= pdvfi(1,jjm,l)
547
548      ENDDO
549
550c-----------------------------------------------------------------------
551
552700   CONTINUE
553
554      firstcal = .FALSE.
555
556      RETURN
557      END
Note: See TracBrowser for help on using the repository browser.