source: LMDZ5/trunk/libf/dyn3dmem/gcm.F @ 2021

Last change on this file since 2021 was 2021, checked in by lguez, 10 years ago

Removed unused variables pks, pk, pkf from main program unit gcm.

Encapsulated procedures exner_hyb, exner_hyb_p, exner_hyb_loc,
exner_milieu, exner_milieu_p and exner_milieu_loc into
modules. (Compulsory to allow optional arguments.)

In the procedures exner_hyb, exner_hyb_p, exner_hyb_loc, donwgraded
arguments alpha and beta to local variables. In exner_milieu,
exner_milieu_p and exner_milieu_loc, removed beta altogether. In the
six procedures exner_*, made pkf an optional argument. Made some
cosmetic modifications in order to keep the six procedures exner_* as
close as possible.

In the six procedures exner_*, removed the averaging of pks at the
poles: this is not useful because ps is already the same at all
longitudes at the poles. This modification changes the results of the
program. Motivation: had to do this for exner_hyb because we call it
from test_disvert with a few surface pressure values.

In all the procedures calling exner_*, removed the variables alpha and
beta. Also removed variables alpha and beta from module leapfrog_mod
and from module call_calfis_mod.

Removed actual argument pkf in call to exner_hyb* and exner_milieu*
from guide_interp, guide_main, iniacademic and iniacademic_loc (pkf
was not used in those procedures).

Argument workvar of startget_dyn is used only if varname is tpot or

  1. When varname is tpot or q, the actual argument associated to

workvar in etat0_netcdf is not y. So y in etat0_netcdf is a
place-holder, never used. So we remove optional argument y in the
calls to exner_hyb and exner_milieu from etat0_netcdf.

Created procedure test_disvert, called only by etat0_netcdf. This
procedure tests the order of pressure values at half-levels and full
levels.

  • Property copyright set to
    Name of program: LMDZ
    Creation date: 1984
    Version: LMDZ5
    License: CeCILL version 2
    Holder: Laboratoire de m\'et\'eorologie dynamique, CNRS, UMR 8539
    See the license file in the root directory
File size: 16.6 KB
Line 
1!
2! $Id$
3!
4c
5c
6      PROGRAM gcm
7
8#ifdef CPP_IOIPSL
9      USE IOIPSL
10#endif
11
12      USE mod_const_mpi, ONLY: init_const_mpi
13      USE parallel_lmdz
14      USE infotrac
15      USE mod_interface_dyn_phys
16      USE mod_hallo
17      USE Bands
18      USE getparam
19      USE filtreg_mod
20      USE control_mod
21
22#ifdef INCA
23! Only INCA needs these informations (from the Earth's physics)
24      USE indice_sol_mod
25#endif
26
27#ifdef CPP_PHYS
28      USE mod_grid_phy_lmdz
29      USE mod_phys_lmdz_para, ONLY : klon_mpi_para_nb
30      USE mod_phys_lmdz_omp_data, ONLY: klon_omp
31      USE dimphy
32      USE comgeomphy
33#endif
34      IMPLICIT NONE
35
36c      ......   Version  du 10/01/98    ..........
37
38c             avec  coordonnees  verticales hybrides
39c   avec nouveaux operat. dissipation * ( gradiv2,divgrad2,nxgraro2 )
40
41c=======================================================================
42c
43c   Auteur:  P. Le Van /L. Fairhead/F.Hourdin
44c   -------
45c
46c   Objet:
47c   ------
48c
49c   GCM LMD nouvelle grille
50c
51c=======================================================================
52c
53c  ... Dans inigeom , nouveaux calculs pour les elongations  cu , cv
54c      et possibilite d'appeler une fonction f(y)  a derivee tangente
55c      hyperbolique a la  place de la fonction a derivee sinusoidale.
56c  ... Possibilite de choisir le schema pour l'advection de
57c        q  , en modifiant iadv dans traceur.def  (MAF,10/02) .
58c
59c      Pour Van-Leer + Vapeur d'eau saturee, iadv(1)=4. (F.Codron,10/99)
60c      Pour Van-Leer iadv=10
61c
62c-----------------------------------------------------------------------
63c   Declarations:
64c   -------------
65#include "dimensions.h"
66#include "paramet.h"
67#include "comconst.h"
68#include "comdissnew.h"
69#include "comvert.h"
70#include "comgeom.h"
71#include "logic.h"
72#include "temps.h"
73#include "ener.h"
74#include "description.h"
75#include "serre.h"
76!#include "com_io_dyn.h"
77#include "iniprint.h"
78#include "tracstoke.h"
79
80#ifdef INCA
81! Only INCA needs these informations (from the Earth's physics)
82!#include "indicesol.h"
83#endif
84
85      INTEGER         longcles
86      PARAMETER     ( longcles = 20 )
87      REAL  clesphy0( longcles )
88      SAVE  clesphy0
89
90
91
92      REAL zdtvr
93
94c   variables dynamiques
95      REAL,ALLOCATABLE,SAVE  :: vcov(:,:),ucov(:,:) ! vents covariants
96      REAL,ALLOCATABLE,SAVE  :: teta(:,:)     ! temperature potentielle
97      REAL, ALLOCATABLE,SAVE :: q(:,:,:)      ! champs advectes
98      REAL,ALLOCATABLE,SAVE  :: ps(:)         ! pression  au sol
99c      REAL p (ip1jmp1,llmp1  )               ! pression aux interfac.des couches
100      REAL,ALLOCATABLE,SAVE  :: masse(:,:)    ! masse d'air
101      REAL,ALLOCATABLE,SAVE  :: phis(:)       ! geopotentiel au sol
102c      REAL phi(ip1jmp1,llm)                  ! geopotentiel
103c      REAL w(ip1jmp1,llm)                    ! vitesse verticale
104
105c variables dynamiques intermediaire pour le transport
106
107c   variables pour le fichier histoire
108      REAL dtav      ! intervalle de temps elementaire
109
110      REAL time_0
111
112      LOGICAL lafin
113c      INTEGER ij,iq,l,i,j
114      INTEGER i,j
115
116
117      real time_step, t_wrt, t_ops
118
119
120      LOGICAL call_iniphys
121      data call_iniphys/.true./
122
123c+jld variables test conservation energie
124c      REAL ecin(ip1jmp1,llm),ecin0(ip1jmp1,llm)
125C     Tendance de la temp. potentiel d (theta)/ d t due a la
126C     tansformation d'energie cinetique en energie thermique
127C     cree par la dissipation
128c      REAL dhecdt(ip1jmp1,llm)
129c      REAL vcont(ip1jm,llm),ucont(ip1jmp1,llm)
130c      REAL      d_h_vcol, d_qt, d_qw, d_ql, d_ec
131c      CHARACTER (len=15) :: ztit
132c-jld
133
134
135      character (len=80) :: dynhist_file, dynhistave_file
136      character (len=20) :: modname
137      character (len=80) :: abort_message
138! locales pour gestion du temps
139      INTEGER :: an, mois, jour
140      REAL :: heure
141
142
143c-----------------------------------------------------------------------
144c    variables pour l'initialisation de la physique :
145c    ------------------------------------------------
146      INTEGER ngridmx
147      PARAMETER( ngridmx = 2+(jjm-1)*iim - 1/jjm   )
148      REAL zcufi(ngridmx),zcvfi(ngridmx)
149      REAL latfi(ngridmx),lonfi(ngridmx)
150      REAL airefi(ngridmx)
151      SAVE latfi, lonfi, airefi
152     
153      INTEGER :: ierr
154
155
156c-----------------------------------------------------------------------
157c   Initialisations:
158c   ----------------
159
160      abort_message = 'last timestep reached'
161      modname = 'gcm'
162      descript = 'Run GCM LMDZ'
163      lafin    = .FALSE.
164      dynhist_file = 'dyn_hist'
165      dynhistave_file = 'dyn_hist_ave'
166
167
168
169c----------------------------------------------------------------------
170c  lecture des fichiers gcm.def ou run.def
171c  ---------------------------------------
172c
173! Ehouarn: dump possibility of using defrun
174!#ifdef CPP_IOIPSL
175      CALL conf_gcm( 99, .TRUE. , clesphy0 )
176!#else
177!      CALL defrun( 99, .TRUE. , clesphy0 )
178!#endif
179c
180c
181c------------------------------------
182c   Initialisation partie parallele
183c------------------------------------
184      CALL init_const_mpi
185
186      call init_parallel
187      call ini_getparam("out.def")
188      call Read_Distrib
189
190#ifdef CPP_PHYS
191        CALL Init_Phys_lmdz(iim,jjp1,llm,mpi_size,distrib_phys)
192#endif
193      CALL set_bands
194#ifdef CPP_PHYS
195      CALL Init_interface_dyn_phys
196#endif
197      CALL barrier
198
199      if (mpi_rank==0) call WriteBands
200      call Set_Distrib(distrib_caldyn)
201
202c$OMP PARALLEL
203      call Init_Mod_hallo
204c$OMP END PARALLEL
205
206#ifdef CPP_PHYS
207c$OMP PARALLEL
208      call InitComgeomphy
209c$OMP END PARALLEL
210#endif
211
212c-----------------------------------------------------------------------
213c   Choix du calendrier
214c   -------------------
215
216c      calend = 'earth_365d'
217
218#ifdef CPP_IOIPSL
219      if (calend == 'earth_360d') then
220        call ioconf_calendar('360d')
221        write(lunout,*)'CALENDRIER CHOISI: Terrestre a 360 jours/an'
222      else if (calend == 'earth_365d') then
223        call ioconf_calendar('noleap')
224        write(lunout,*)'CALENDRIER CHOISI: Terrestre a 365 jours/an'
225      else if (calend == 'earth_366d') then
226        call ioconf_calendar('gregorian')
227        write(lunout,*)'CALENDRIER CHOISI: Terrestre bissextile'
228      else
229        abort_message = 'Mauvais choix de calendrier'
230        call abort_gcm(modname,abort_message,1)
231      endif
232#endif
233
234      IF (type_trac == 'inca') THEN
235#ifdef INCA
236         call init_const_lmdz(
237     $        nbtr,anneeref,dayref,
238     $        iphysiq,day_step,nday,
239     $        nbsrf, is_oce,is_sic,
240     $        is_ter,is_lic)
241
242         call init_inca_para(
243     $        iim,jjm+1,llm,klon_glo,mpi_size,
244     $        distrib_phys,COMM_LMDZ)
245#endif
246      END IF
247
248c-----------------------------------------------------------------------
249c   Initialisation des traceurs
250c   ---------------------------
251c  Choix du nombre de traceurs et du schema pour l'advection
252c  dans fichier traceur.def, par default ou via INCA
253      call infotrac_init
254
255c Allocation de la tableau q : champs advectes   
256      ALLOCATE(ucov(ijb_u:ije_u,llm))
257      ALLOCATE(vcov(ijb_v:ije_v,llm))
258      ALLOCATE(teta(ijb_u:ije_u,llm))
259      ALLOCATE(masse(ijb_u:ije_u,llm))
260      ALLOCATE(ps(ijb_u:ije_u))
261      ALLOCATE(phis(ijb_u:ije_u))
262      ALLOCATE(q(ijb_u:ije_u,llm,nqtot))
263
264c-----------------------------------------------------------------------
265c   Lecture de l'etat initial :
266c   ---------------------------
267
268c  lecture du fichier start.nc
269      if (read_start) then
270      ! we still need to run iniacademic to initialize some
271      ! constants & fields, if we run the 'newtonian' or 'SW' cases:
272        if (iflag_phys.ne.1) then
273          CALL iniacademic_loc(vcov,ucov,teta,q,masse,ps,phis,time_0)
274        endif
275
276!        if (planet_type.eq."earth") then
277! Load an Earth-format start file
278         CALL dynetat0_loc("start.nc",vcov,ucov,
279     &              teta,q,masse,ps,phis, time_0)
280!        endif ! of if (planet_type.eq."earth")
281
282c       write(73,*) 'ucov',ucov
283c       write(74,*) 'vcov',vcov
284c       write(75,*) 'teta',teta
285c       write(76,*) 'ps',ps
286c       write(77,*) 'q',q
287
288      endif ! of if (read_start)
289
290c le cas echeant, creation d un etat initial
291      IF (prt_level > 9) WRITE(lunout,*)
292     .              'GCM: AVANT iniacademic AVANT AVANT AVANT AVANT'
293      if (.not.read_start) then
294         CALL iniacademic_loc(vcov,ucov,teta,q,masse,ps,phis,time_0)
295      endif
296
297c-----------------------------------------------------------------------
298c   Lecture des parametres de controle pour la simulation :
299c   -------------------------------------------------------
300c  on recalcule eventuellement le pas de temps
301
302      IF(MOD(day_step,iperiod).NE.0) THEN
303        abort_message =
304     .  'Il faut choisir un nb de pas par jour multiple de iperiod'
305        call abort_gcm(modname,abort_message,1)
306      ENDIF
307
308      IF(MOD(day_step,iphysiq).NE.0) THEN
309        abort_message =
310     * 'Il faut choisir un nb de pas par jour multiple de iphysiq'
311        call abort_gcm(modname,abort_message,1)
312      ENDIF
313
314      zdtvr    = daysec/REAL(day_step)
315        IF(dtvr.NE.zdtvr) THEN
316         WRITE(lunout,*)
317     .    'WARNING!!! changement de pas de temps',dtvr,'>',zdtvr
318        ENDIF
319
320C
321C on remet le calendrier à zero si demande
322c
323      IF (start_time /= starttime) then
324        WRITE(lunout,*)' GCM: Attention l''heure de depart lue dans le'
325     &,' fichier restart ne correspond pas à celle lue dans le run.def'
326        IF (raz_date == 1) then
327          WRITE(lunout,*)'Je prends l''heure lue dans run.def'
328          start_time = starttime
329        ELSE
330          WRITE(lunout,*)'Je m''arrete'
331          CALL abort
332        ENDIF
333      ENDIF
334      IF (raz_date == 1) THEN
335        annee_ref = anneeref
336        day_ref = dayref
337        day_ini = dayref
338        itau_dyn = 0
339        itau_phy = 0
340        time_0 = 0.
341        write(lunout,*)
342     .   'GCM: On reinitialise a la date lue dans gcm.def'
343      ELSE IF (annee_ref .ne. anneeref .or. day_ref .ne. dayref) THEN
344        write(lunout,*)
345     .  'GCM: Attention les dates initiales lues dans le fichier'
346        write(lunout,*)
347     .  ' restart ne correspondent pas a celles lues dans '
348        write(lunout,*)' gcm.def'
349        write(lunout,*)' annee_ref=',annee_ref," anneeref=",anneeref
350        write(lunout,*)' day_ref=',day_ref," dayref=",dayref
351        write(lunout,*)' Pas de remise a zero'
352      ENDIF
353c      if (annee_ref .ne. anneeref .or. day_ref .ne. dayref) then
354c        write(lunout,*)
355c     .  'GCM: Attention les dates initiales lues dans le fichier'
356c        write(lunout,*)
357c     .  ' restart ne correspondent pas a celles lues dans '
358c        write(lunout,*)' gcm.def'
359c        write(lunout,*)' annee_ref=',annee_ref," anneeref=",anneeref
360c        write(lunout,*)' day_ref=',day_ref," dayref=",dayref
361c        if (raz_date .ne. 1) then
362c          write(lunout,*)
363c     .    'GCM: On garde les dates du fichier restart'
364c        else
365c          annee_ref = anneeref
366c          day_ref = dayref
367c          day_ini = dayref
368c          itau_dyn = 0
369c          itau_phy = 0
370c          time_0 = 0.
371c          write(lunout,*)
372c     .   'GCM: On reinitialise a la date lue dans gcm.def'
373c        endif
374c      ELSE
375c        raz_date = 0
376c      endif
377
378#ifdef CPP_IOIPSL
379      mois = 1
380      heure = 0.
381      call ymds2ju(annee_ref, mois, day_ref, heure, jD_ref)
382      jH_ref = jD_ref - int(jD_ref)
383      jD_ref = int(jD_ref)
384
385      call ioconf_startdate(INT(jD_ref), jH_ref)
386
387      write(lunout,*)'DEBUG'
388      write(lunout,*)'annee_ref, mois, day_ref, heure, jD_ref'
389      write(lunout,*)annee_ref, mois, day_ref, heure, jD_ref
390      call ju2ymds(jD_ref+jH_ref,an, mois, jour, heure)
391      write(lunout,*)'jD_ref+jH_ref,an, mois, jour, heure'
392      write(lunout,*)jD_ref+jH_ref,an, mois, jour, heure
393#else
394! Ehouarn: we still need to define JD_ref and JH_ref
395! and since we don't know how many days there are in a year
396! we set JD_ref to 0 (this should be improved ...)
397      jD_ref=0
398      jH_ref=0
399#endif
400
401      if (iflag_phys.eq.1) then
402      ! these initialisations have already been done (via iniacademic)
403      ! if running in SW or Newtonian mode
404c-----------------------------------------------------------------------
405c   Initialisation des constantes dynamiques :
406c   ------------------------------------------
407        dtvr = zdtvr
408        CALL iniconst
409
410c-----------------------------------------------------------------------
411c   Initialisation de la geometrie :
412c   --------------------------------
413        CALL inigeom
414
415c-----------------------------------------------------------------------
416c   Initialisation du filtre :
417c   --------------------------
418        CALL inifilr
419      endif ! of if (iflag_phys.eq.1)
420c
421c-----------------------------------------------------------------------
422c   Initialisation de la dissipation :
423c   ----------------------------------
424
425      CALL inidissip( lstardis, nitergdiv, nitergrot, niterh   ,
426     *                tetagdiv, tetagrot , tetatemp, vert_prof_dissip)
427
428c-----------------------------------------------------------------------
429c   Initialisation de la physique :
430c   -------------------------------
431      IF (call_iniphys.and.(iflag_phys==1.or.iflag_phys>=100)) THEN
432         latfi(1)=rlatu(1)
433         lonfi(1)=0.
434         zcufi(1) = cu(1)
435         zcvfi(1) = cv(1)
436         DO j=2,jjm
437            DO i=1,iim
438               latfi((j-2)*iim+1+i)= rlatu(j)
439               lonfi((j-2)*iim+1+i)= rlonv(i)
440               zcufi((j-2)*iim+1+i) = cu((j-1)*iip1+i)
441               zcvfi((j-2)*iim+1+i) = cv((j-1)*iip1+i)
442            ENDDO
443         ENDDO
444         latfi(ngridmx)= rlatu(jjp1)
445         lonfi(ngridmx)= 0.
446         zcufi(ngridmx) = cu(ip1jm+1)
447         zcvfi(ngridmx) = cv(ip1jm-iim)
448         CALL gr_dyn_fi(1,iip1,jjp1,ngridmx,aire,airefi)
449
450         WRITE(lunout,*)
451     .       'GCM: WARNING!!! vitesse verticale nulle dans la physique'
452! Physics:
453#ifdef CPP_PHYS
454         CALL iniphysiq(ngridmx,llm,daysec,day_ini,dtphys/nsplit_phys,
455     &                latfi,lonfi,airefi,zcufi,zcvfi,rad,g,r,cpp,
456     &                iflag_phys)
457#endif
458         call_iniphys=.false.
459      ENDIF ! of IF (call_iniphys.and.(iflag_phys==1.or.iflag_phys>=100))
460
461
462c-----------------------------------------------------------------------
463c   Initialisation des dimensions d'INCA :
464c   --------------------------------------
465      IF (type_trac == 'inca') THEN
466!$OMP PARALLEL
467#ifdef INCA
468         CALL init_inca_dim(klon_omp,llm,iim,jjm,
469     $        rlonu,rlatu,rlonv,rlatv)
470#endif
471!$OMP END PARALLEL
472      END IF
473
474c-----------------------------------------------------------------------
475c   Initialisation des I/O :
476c   ------------------------
477
478
479      day_end = day_ini + nday
480      WRITE(lunout,300)day_ini,day_end
481 300  FORMAT('1'/,15x,'run du jour',i7,2x,'au jour',i7//)
482
483#ifdef CPP_IOIPSL
484      call ju2ymds(jD_ref + day_ini - day_ref, an, mois, jour, heure)
485      write (lunout,301)jour, mois, an
486      call ju2ymds(jD_ref + day_end - day_ref, an, mois, jour, heure)
487      write (lunout,302)jour, mois, an
488 301  FORMAT('1'/,15x,'run du ', i2,'/',i2,'/',i4)
489 302  FORMAT('1'/,15x,'    au ', i2,'/',i2,'/',i4)
490#endif
491
492!      if (planet_type.eq."earth") then
493! Write an Earth-format restart file
494        CALL dynredem0_loc("restart.nc", day_end, phis)
495!      endif
496
497      ecripar = .TRUE.
498
499#ifdef CPP_IOIPSL
500      time_step = zdtvr
501      IF (mpi_rank==0) then
502        if (ok_dyn_ins) then
503          ! initialize output file for instantaneous outputs
504          ! t_ops = iecri * daysec ! do operations every t_ops
505          t_ops =((1.0*iecri)/day_step) * daysec 
506          t_wrt = daysec ! iecri * daysec ! write output every t_wrt
507          t_wrt = daysec ! iecri * daysec ! write output every t_wrt
508          CALL inithist(day_ref,annee_ref,time_step,
509     &                  t_ops,t_wrt)
510        endif
511
512      IF (ok_dyn_ave) THEN
513         ! initialize output file for averaged outputs
514         t_ops = iperiod * time_step ! do operations every t_ops
515         t_wrt = periodav * daysec   ! write output every t_wrt
516         CALL initdynav_loc(day_ref,annee_ref,time_step,t_ops,t_wrt)
517        END IF
518      ENDIF
519      dtav = iperiod*dtvr/daysec
520#endif
521! #endif of #ifdef CPP_IOIPSL
522
523c  Choix des frequences de stokage pour le offline
524c      istdyn=day_step/4     ! stockage toutes les 6h=1jour/4
525c      istdyn=day_step/12     ! stockage toutes les 2h=1jour/12
526      istdyn=day_step/4     ! stockage toutes les 6h=1jour/12
527      istphy=istdyn/iphysiq     
528
529
530c
531c-----------------------------------------------------------------------
532c   Integration temporelle du modele :
533c   ----------------------------------
534
535c       write(78,*) 'ucov',ucov
536c       write(78,*) 'vcov',vcov
537c       write(78,*) 'teta',teta
538c       write(78,*) 'ps',ps
539c       write(78,*) 'q',q
540
541c$OMP PARALLEL DEFAULT(SHARED) COPYIN(/temps/,/logici/,/logicl/)
542      CALL leapfrog_loc(ucov,vcov,teta,ps,masse,phis,q,clesphy0,
543     .              time_0)
544c$OMP END PARALLEL
545
546!      OPEN(unit=5487,file='ok_lmdz',status='replace')
547!      WRITE(5487,*) 'ok_lmdz'
548!      CLOSE(5487)
549      END
550
Note: See TracBrowser for help on using the repository browser.