source: trunk/LMDZ.PLUTO.old/libf/dyn3d/gcm.F @ 3436

Last change on this file since 3436 was 3175, checked in by emillour, 11 months ago

Pluto PCM:
Add the old Pluto LMDZ for reference (required prior step to making
an LMDZ.PLUTO using the same framework as the other physics packages).
TB+EM

File size: 18.4 KB
Line 
1      PROGRAM gcm
2
3      IMPLICIT NONE
4
5c      ......   Version  du 10/01/98    ..........
6
7c             avec  coordonnees  verticales hybrides
8c   avec nouveaux operat. dissipation * ( gradiv2,divgrad2,nxgraro2 )
9
10c=======================================================================
11c
12c   Auteur:  P. Le Van /L. Fairhead/F.Hourdin
13c   -------
14c
15c   Objet:
16c   ------
17c
18c   GCM LMD nouvelle grille
19c
20c=======================================================================
21c
22c  ... Dans inigeom , nouveaux calculs pour les elongations  cu , cv
23c      et possibilite dappeler une fonction f(y)  a derivee tangente
24c      hyperbolique a la  place de la fonction a derivee sinusoidale.
25
26c  ... Possibilite de choisir le shema de Van-leer pour ladvection de
27c        q  , en faisant iadv = 3  dans   traceur  (29/04/97) .
28c
29c      Pour Van-Leer + Vapeur deau saturee, iadv(1)=4. (F.Codron,10/99)
30c
31c-----------------------------------------------------------------------
32c   Declarations:
33c   -------------
34
35#include "dimensions.h"
36#include "paramet.h"
37#include "comconst.h"
38#include "comdissnew.h"
39#include "comvert.h"
40#include "comgeom.h"
41#include "logic.h"
42#include "temps.h"
43#include "control.h"
44#include "ener.h"
45#include "netcdf.inc"
46#include "description.h"
47#include "serre.h"
48#include "tracstoke.h"
49#include "sponge.h"
50#include"advtrac.h"
51
52      INTEGER*4  iday ! jour julien
53      REAL       time ! Heure de la journee en fraction d''1 jour
54      REAL zdtvr
55
56c   variables dynamiques
57      REAL vcov(ip1jm,llm),ucov(ip1jmp1,llm) ! vents covariants
58      real, dimension(ip1jmp1,llm) :: teta   ! temperature potentielle
59      REAL q(ip1jmp1,llm,nqmx)               ! champs advectes
60      REAL ps(ip1jmp1)                       ! pression  au sol
61      REAL pext(ip1jmp1)                     ! pression  extensive
62      REAL p (ip1jmp1,llmp1  )               ! pression aux interfac.des couches
63      REAL pks(ip1jmp1)                      ! exner au  sol
64      REAL pk(ip1jmp1,llm)                   ! exner au milieu des couches
65      REAL pkf(ip1jmp1,llm)                  ! exner filt.au milieu des couches
66      REAL masse(ip1jmp1,llm)                ! masse d''air
67      REAL phis(ip1jmp1)                     ! geopotentiel au sol
68      REAL phi(ip1jmp1,llm)                  ! geopotentiel
69      REAL w(ip1jmp1,llm)                    ! vitesse verticale
70
71c variables dynamiques intermediaire pour le transport
72      REAL pbaru(ip1jmp1,llm),pbarv(ip1jm,llm) !flux de masse
73
74c   variables dynamiques au pas -1
75      REAL vcovm1(ip1jm,llm),ucovm1(ip1jmp1,llm)
76
77      REAL tetam1(ip1jmp1,llm),psm1(ip1jmp1)
78      REAL massem1(ip1jmp1,llm)
79
80c   tendances dynamiques
81      REAL dv(ip1jm,llm),du(ip1jmp1,llm)
82      REAL dteta(ip1jmp1,llm),dq(ip1jmp1,llm,nqmx),dp(ip1jmp1)
83
84c   tendances de la dissipation
85      REAL dvdis(ip1jm,llm),dudis(ip1jmp1,llm)
86      REAL dhdis(ip1jmp1,llm)
87
88c   tendances physiques
89      REAL dvfi(ip1jm,llm),dufi(ip1jmp1,llm)
90      REAL dhfi(ip1jmp1,llm),dqfi(ip1jmp1,llm,nqmx),dpfi(ip1jmp1)
91
92c   variables pour le fichier histoire
93      REAL dtav      ! intervalle de temps elementaire
94
95      REAL tppn(iim),tpps(iim),tpn,tps
96c
97!      INTEGER iadv(nqmx) ! indice schema de transport pour le traceur iq
98
99      INTEGER itau,itaufinp1,iav
100
101
102      EXTERNAL caldyn, traceur
103      EXTERNAL dissip,geopot,iniconst,inifilr
104      EXTERNAL integrd,SCOPY
105      EXTERNAL inigeom
106      EXTERNAL exner_hyb,addit
107      EXTERNAL defrun_new, test_period
108      REAL  SSUM
109      REAL time_0 , finvmaold(ip1jmp1,llm)
110
111      LOGICAL lafin
112      INTEGER ij,iq,l,ierr,numvanle,iapp_tracvl,i
113
114      REAL rdayvrai,rdaym_ini,rday_ecri
115!      LOGICAL first
116      REAL beta(ip1jmp1,llm)
117
118      LOGICAL offline  ! Controle du stockage ds "fluxmass"
119      PARAMETER (offline=.false.)
120
121      character*20 modname
122      character*80 abort_message
123
124      LOGICAL tracer
125          data tracer/.true./
126      INTEGER nq
127
128C Calendrier
129      LOGICAL true_calendar
130      PARAMETER (true_calendar = .false.)
131
132! flag to set/remove calls to groupeun
133      logical callgroupeun
134      parameter (callgroupeun = .true.)
135
136!     added by RDW for tests without dynamics
137      logical calldyn
138      parameter (calldyn = .true.)
139
140
141c-----------------------------------------------------------------------
142c   Initialisations:
143c   ----------------
144
145      modname = 'gcm'
146      descript = 'Run GCM LMDZ'
147      lafin    = .FALSE.
148
149c-----------------------------------------------------------------------
150c  Initialize tracers using iniadvtrac (Ehouarn, oct 2008)
151      CALL iniadvtrac(nq,numvanle)
152
153      CALL dynetat0("start.nc",nqmx,vcov,ucov,
154     .              teta,q,masse,ps,phis, time_0)
155      !print*, 'TB18  tetalec=',teta
156
157      CALL defrun_new( 99, .TRUE. )
158
159
160c  on recalcule eventuellement le pas de temps
161
162      IF(MOD(day_step,iperiod).NE.0)
163     * STOP'Il faut choisir un nb de pas par jour multiple de iperiod'
164
165      IF(MOD(day_step,iphysiq).NE.0)
166     * STOP'Il faut choisir un nb de pas par jour multiple de iphysiq'
167
168      zdtvr    = daysec/FLOAT(day_step)
169
170        IF(dtvr.NE.zdtvr) THEN
171         PRINT*,'WARNING!!! changement de pas de temps',dtvr,'>',zdtvr
172        ENDIF
173
174c  nombre detats dans les fichiers demarrage et histoire
175
176      dtvr = zdtvr
177      CALL iniconst
178      CALL inigeom
179
180      CALL inifilr
181
182c
183c   ......    P.Le Van    ( modif  le 29/04/97 )   ......... 
184c
185
186      CALL inidissip ( lstardis, nitergdiv, nitergrot, niterh   ,
187     *                tetagdiv, tetagrot , tetatemp              )
188c
189
190      CALL pression ( ip1jmp1, ap, bp, ps, p       )
191
192      call dump2d(iip1,jjp1,ps,'PRESSION SURFACE')
193      CALL exner_hyb( ip1jmp1, ps, p,beta, pks, pk, pkf )
194
195c
196c  numero de stockage pour les fichiers de redemarrage:
197
198c-----------------------------------------------------------------------
199c   temps de depart et de fin:
200c   --------------------------
201
202      itau = 0
203      iday = day_ini+itau/day_step
204      time = FLOAT(itau-(iday-day_ini)*day_step)/day_step+time_0
205
206
207         IF(time.GT.1.) THEN
208          time = time-1.
209          iday = iday+1
210         ENDIF
211      itaufin   = nday*day_step
212      itaufinp1 = itaufin +1
213
214      day_end = day_ini + nday
215      PRINT 300, itau,itaufin,day_ini,day_end
216 300  FORMAT('1'/,15x,'run du pas',i7,2x,'au pas',i7,2x, 
217     . 'c''est a dire du jour',i7,3x,'au jour',i7//)
218
219      CALL dynredem0("restart.nc",day_end,anne_ini,phis,nqmx)
220
221      ecripar = .TRUE.
222
223      dtav = iperiod*dtvr/daysec
224
225
226c   Quelques initialisations pour les traceurs
227      call initial0(ijp1llm*nqmx,dq)
228c     istdyn=day_step/4     ! stockage toutes les 6h=1jour/4
229c     istphy=istdyn/iphysiq
230
231      write(*,*) "gcm: callgroupeun set to:",callgroupeun
232c-----------------------------------------------------------------------
233c   Debut de lintegration temporelle:
234c   ----------------------------------
235
236   1  CONTINUE
237      !print*, 'TB18  teta01=',teta
238c
239      IF( MOD( itau, 10* day_step ).EQ.0 )  THEN
240        CALL test_period ( ucov,vcov,teta,q,p,phis )
241        PRINT *,' ----   Test_period apres continue   OK ! -----', itau
242      ENDIF
243      !print*, 'TB18  teta02=',teta
244
245      if (callgroupeun) then
246        call groupeun(jjp1,llm,ucov,.true.)
247        call groupeun(jjm,llm,vcov,.true.)
248        call groupeun(jjp1,llm,teta,.true.)
249        call groupeun(jjp1,llm,masse,.true.)
250        call groupeun(jjp1,1,ps,.false.)
251      endif
252
253      DO l=1,llm   ! lev
254            do i=1,ip1jmp1
255               massem1(i,l)=masse(i,l)
256               ucovm1(i,l)=ucov(i,l)
257               tetam1(i,l)=teta(i,l)
258               finvmaold(i,l)=masse(i,l)
259            enddo
260            do i=1,ip1jm
261               vcovm1(i,l)=vcov(i,l)
262            enddo
263      ENDDO
264      DO l=1,ip1jmp1
265         psm1(l)=ps(l)
266      ENDDO
267     
268      !CALL SCOPY( ijmllm ,vcov , 1, vcovm1 , 1 )
269      !CALL SCOPY( ijp1llm,ucov , 1, ucovm1 , 1 )
270      !CALL SCOPY( ijp1llm,teta , 1, tetam1 , 1 )
271      !CALL SCOPY( ijp1llm,masse, 1, massem1, 1 )
272      !CALL SCOPY( ip1jmp1, ps  , 1,   psm1 , 1 )
273       
274      forward = .TRUE.
275      leapf   = .FALSE.
276      dt      =  dtvr
277
278c   ...    P.Le Van .26/04/94  ....
279
280      !CALL SCOPY   ( ijp1llm,   masse, 1, finvmaold,     1 )
281      !finvmaold=masse
282cc      CALL filtreg ( finvmaold ,jjp1, llm, -2,2, .TRUE., 1 )
283
284
285   2  CONTINUE
286
287c-----------------------------------------------------------------------
288
289c   date:
290c   -----
291
292!      write(*,*) 'GCM: itau=',itau
293
294c   gestion des appels de la physique et des dissipations:
295c   ------------------------------------------------------
296c
297c   ...    P.Le Van  ( 6/02/95 )  ....
298
299      apphys = .FALSE.
300      statcl = .FALSE.
301      conser = .FALSE.
302      apdiss = .FALSE.
303
304      IF( purmats ) THEN
305         IF( MOD(itau,iconser) .EQ.0.AND.  forward    ) conser = .TRUE.
306         IF( MOD(itau,idissip ).EQ.0.AND..NOT.forward ) apdiss = .TRUE.
307         IF( MOD(itau,iphysiq ).EQ.0.AND..NOT.forward
308     $                              .AND.   physic    ) apphys = .TRUE.
309      ELSE
310         IF( MOD(itau   ,iconser) .EQ. 0              ) conser = .TRUE.
311         IF( MOD(itau+1,idissip)  .EQ. 0              ) apdiss = .TRUE.
312         IF( MOD(itau+1,iphysiq).EQ.0. AND. physic    ) apphys = .TRUE.
313      END IF
314
315c-----------------------------------------------------------------------
316c   calcul des tendances dynamiques:
317c   --------------------------------
318
319      CALL geopot  ( ip1jmp1, teta  , pk , pks,  phis  , phi   )
320
321      if(calldyn)then
322         CALL caldyn
323     $        ( itau,ucov,vcov,teta,ps,masse,pk,pkf,phis ,
324     $        phi,conser,du,dv,dteta,dp,w,pbaru,pbarv,time+iday-day_ini)
325      endif
326      !print*, 'TB18 caldyn dp=',dp
327      !print*, 'TB18 caldyn dp34=',dp(34)
328c-----------------------------------------------------------------------
329c   calcul des tendances advection des traceurs (dont lhumidite)
330c   -------------------------------------------------------------
331
332      if (tracer) then
333       IF( forward. OR . leapf )  THEN
334
335        DO iq = 1, nqmx
336c
337         IF ( iadv(iq).EQ.1.OR.iadv(iq).EQ.2 )  THEN
338            CALL traceur( iq,iadv,q,teta,pk,w, pbaru, pbarv, dq )
339
340         ELSE IF( iq.EQ. nqmx )   THEN
341c
342            iapp_tracvl = 5
343c
344cccc     iapp_tracvl est la frequence en pas du groupement des flux
345cccc      de masse pour  Van-Leer dans la routine  tracvl  .
346c
347
348            CALL vanleer(numvanle,iapp_tracvl,nqmx,q,pbaru,pbarv,
349     *                      p, masse, dq,  iadv(1), teta, pk     )
350
351c
352c                   ...  Modif  F.Codron  ....
353c
354         ENDIF
355c
356        ENDDO
357C
358c        IF (offline) THEN
359C maf stokage du flux de masse pour traceurs OFF-LINE
360
361c           CALL fluxstokenc(pbaru,pbarv,masse,teta,phi,phis,
362c    .   time_step, itau)
363
364c        ENDIF
365c
366      ENDIF
367          END IF   ! tracer
368
369
370c-----------------------------------------------------------------------
371c   integrations dynamique et traceurs:
372c   ----------------------------------
373
374        !print*, 'TB18  teta0=',teta
375          if(calldyn)then
376             CALL integrd(2,vcovm1,ucovm1,tetam1,psm1,massem1,
377     $            dv,du,dteta,dq,dp,vcov,ucov,teta,q,ps,masse,phis,
378     $            finvmaold)
379          endif
380          !print*, 'TB18  tetadyn=',teta
381
382
383
384
385
386c .P.Le Van (26/04/94  ajout de  finvpold dans l'appel d'integrd)
387c
388c-----------------------------------------------------------------------
389c   calcul des tendances physiques:
390c   -------------------------------
391c    ########   P.Le Van ( Modif le  6/02/95 )   ###########
392c
393       IF( purmats )  THEN
394          IF( itau.EQ.itaufin.AND..NOT.forward ) lafin = .TRUE.
395       ELSE
396          IF( itau+1. EQ. itaufin )              lafin = .TRUE.
397       ENDIF
398c
399c
400       IF( apphys )  THEN
401c
402c     .......   Ajout   P.Le Van ( 17/04/96 )   ...........
403c
404
405         CALL pression (  ip1jmp1, ap, bp, ps,  p      )
406         CALL exner_hyb(  ip1jmp1, ps, p,beta,pks, pk, pkf )
407
408           rdaym_ini  = itau * dtvr / daysec
409           rdayvrai   = rdaym_ini  + day_ini
410
411           IF ( ecritphy.LT.1. )  THEN
412             rday_ecri = rdaym_ini
413           ELSE
414c             rday_ecri = INT( rdayvrai )
415c pour lancer avec run0
416             rday_ecri = INT(rdaym_ini)+INT(day_ini)
417           ENDIF
418c
419c        print*, 'TB18  teta=',teta
420        CALL calfis( nqmx, lafin ,rdayvrai,rday_ecri,time  ,
421     $                 ucov,vcov,teta,q,masse,ps,p,pk,phis,phi ,
422     $     du,dv,dteta,dq,w, dufi,dvfi,dhfi,dqfi,dpfi,tracer)
423
424
425c      ajout des tendances physiques:
426c      ------------------------------
427          CALL addfi( nqmx, dtphys, leapf, forward   ,
428     $                  ucov, vcov, teta , q   ,ps , masse,
429     $                 dufi, dvfi, dhfi , dqfi ,dpfi  )
430c!
431          !print*, 'TB18  tetafi=',teta
432       ENDIF
433
434       CALL pression ( ip1jmp1, ap, bp, ps, p                  )
435
436       CALL exner_hyb( ip1jmp1, ps, p,beta, pks, pk, pkf )
437c   ----------------------------------------------------------
438
439c
440c
441c   dissipation horizontale et verticale  des petites echelles:
442c   ----------------------------------------------------------
443
444      IF(apdiss) THEN
445
446c        Sponge layer
447c        ~~~~~~~~~~~~
448         DO ij=1, ip1jmp1
449            pext(ij)=ps(ij)*aire(ij)
450         ENDDO
451         IF (callsponge) THEN
452            CALL sponge(ucov,vcov,teta,pext,dtdiss,mode_sponge)
453         ENDIF
454         !print*, 'TB18  tetasponge=',teta
455
456c        Dissipation horizontale
457c        ~~~~~~~~~~~~~~~~~~~~~~~
458         CALL dissip(vcov,ucov,teta,p,dvdis,dudis,dhdis)
459
460         CALL addit( ijp1llm,ucov ,dudis,ucov )
461         CALL addit( ijmllm ,vcov ,dvdis,vcov )
462         CALL addit( ijp1llm,teta ,dhdis,teta )
463         !print*, 'TB18  tetadis=',teta
464
465
466c    .......        P. Le Van (  ajout  le 17/04/96  )   ...........
467c   ...      Calcul de la valeur moyenne, unique de h aux poles  .....
468c
469
470        DO l  =  1, llm
471          DO ij =  1,iim
472           tppn(ij)  = aire(  ij    ) * teta(  ij    ,l)
473           tpps(ij)  = aire(ij+ip1jm) * teta(ij+ip1jm,l)
474          ENDDO
475
476           tpn  = SSUM(iim,tppn,1)/apoln
477           tps  = SSUM(iim,tpps,1)/apols
478
479          DO ij = 1, iip1
480           teta(  ij    ,l) = tpn
481           teta(ij+ip1jm,l) = tps
482          ENDDO
483        ENDDO
484
485        DO ij =  1,iim
486          tppn(ij)  = aire(  ij    ) * ps (  ij    )
487          tpps(ij)  = aire(ij+ip1jm) * ps (ij+ip1jm)
488        ENDDO
489          tpn  = SSUM(iim,tppn,1)/apoln
490
491          tps  = SSUM(iim,tpps,1)/apols
492
493        DO ij = 1, iip1
494          ps(  ij    ) = tpn
495          ps(ij+ip1jm) = tps
496        ENDDO
497
498
499
500        !print*, 'TB18  tetapole=',teta
501
502
503
504
505      END IF
506       
507c   ********************************************************************
508c   ********************************************************************
509c   .... fin de lintegration dynamique  et physique pour le pas itau ..
510c   ********************************************************************
511c   ********************************************************************
512
513c   preparation du pas dintegration suivant  ......
514
515      IF ( .NOT.purmats ) THEN
516c       ........................................................
517c       ..............  schema matsuno + leapfrog  ..............
518c       ........................................................
519
520            IF(forward. OR. leapf) THEN
521              itau= itau + 1
522              iday= day_ini+itau/day_step
523              time= FLOAT(itau-(iday-day_ini)*day_step)/day_step+time_0
524                IF(time.GT.1.) THEN
525                  time = time-1.
526                  iday = iday+1
527                ENDIF
528            ENDIF
529
530
531            IF( itau. EQ. itaufinp1 ) then 
532              abort_message = 'Simulation finished'
533              call abort_gcm(modname,abort_message,0)
534            ENDIF
535c-----------------------------------------------------------------------
536c   ecriture du fichier histoire moyenne:
537c   -------------------------------------
538
539c           IF(MOD(itau,iperiod).EQ.0 .OR. itau.EQ.itaufin) THEN
540c              IF(itau.EQ.itaufin) THEN
541c                 iav=1
542c              ELSE
543c                 iav=0
544c              ENDIF
545c              CALL writedynav(histaveid, nqmx, itau,vcov ,
546c    ,                          ucov,teta,pk,phi,q,masse,ps,phis)
547c           ENDIF
548
549c-----------------------------------------------------------------------
550
551
552            IF(itau.EQ.itaufin) THEN
553
554
555       PRINT *,' Appel test_period avant redem ', itau
556       CALL test_period ( ucov,vcov,teta,q,p,phis )
557       CALL dynredem1("restart.nc",0.0,
558     .                     vcov,ucov,teta,q,nqmx,masse,ps)
559
560              CLOSE(99)
561            ENDIF
562
563c-----------------------------------------------------------------------
564c   gestion de lintegration temporelle:
565c   ------------------------------------
566
567            IF( MOD(itau,iperiod).EQ.0 )    THEN
568                    GO TO 1
569            ELSE IF ( MOD(itau-1,iperiod). EQ. 0 ) THEN
570
571                   IF( forward )  THEN
572c      fin du pas forward et debut du pas backward
573
574                      forward = .FALSE.
575                        leapf = .FALSE.
576                           GO TO 2
577
578                   ELSE
579c      fin du pas backward et debut du premier pas leapfrog
580
581                        leapf =  .TRUE.
582                        dt  =  2.*dtvr
583                        GO TO 2
584                   END IF
585            ELSE
586
587c      ......   pas leapfrog  .....
588
589                 leapf = .TRUE.
590                 dt  = 2.*dtvr
591                 GO TO 2
592            END IF
593
594      ELSE
595
596c       ........................................................
597c       ..............       schema  matsuno        ...............
598c       ........................................................
599            IF( forward )  THEN
600
601             itau =  itau + 1
602             iday = day_ini+itau/day_step
603             time = FLOAT(itau-(iday-day_ini)*day_step)/day_step+time_0
604
605                  IF(time.GT.1.) THEN
606                   time = time-1.
607                   iday = iday+1
608                  ENDIF
609
610               forward =  .FALSE.
611               IF( itau. EQ. itaufinp1 ) then 
612                 abort_message = 'Simulation finished'
613                 call abort_gcm(modname,abort_message,0)
614               ENDIF
615               GO TO 2
616
617            ELSE
618
619            IF(MOD(itau,iperiod).EQ.0 .OR. itau.EQ.itaufin) THEN
620               IF(itau.EQ.itaufin) THEN
621                  iav=1
622               ELSE
623                  iav=0
624               ENDIF
625c              CALL writedynav(histaveid, nqmx, itau,vcov ,
626c    ,                          ucov,teta,pk,phi,q,masse,ps,phis)
627
628            ENDIF
629
630
631                 IF(itau.EQ.itaufin)
632     . CALL dynredem1("restart.nc",0.0,
633     .                     vcov,ucov,teta,q,nqmx,masse,ps)
634
635                 forward = .TRUE.
636                 GO TO  1
637
638
639            ENDIF
640
641      END IF
642
643      STOP
644      END
Note: See TracBrowser for help on using the repository browser.