source: LMDZ5/trunk/libf/dyn3dpar/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
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.6 KB
Line 
1!
2! $Id: gcm.F 2021 2014-04-25 10:20:14Z lguez $
3!
4c
5c
6      PROGRAM gcm
7
8#ifdef CPP_IOIPSL
9      USE IOIPSL
10#endif
11
12
13      USE mod_const_mpi, ONLY: init_const_mpi
14      USE parallel_lmdz
15      USE infotrac
16      USE mod_interface_dyn_phys
17      USE mod_hallo
18      USE Bands
19      USE getparam
20      USE filtreg_mod
21      USE control_mod
22
23#ifdef INCA
24! Only INCA needs these informations (from the Earth's physics)
25      USE indice_sol_mod
26#endif
27
28#ifdef CPP_PHYS
29      USE mod_grid_phy_lmdz
30      USE mod_phys_lmdz_para, ONLY : klon_mpi_para_nb
31      USE mod_phys_lmdz_omp_data, ONLY: klon_omp
32      USE dimphy
33      USE comgeomphy
34#endif
35      IMPLICIT NONE
36
37c      ......   Version  du 10/01/98    ..........
38
39c             avec  coordonnees  verticales hybrides
40c   avec nouveaux operat. dissipation * ( gradiv2,divgrad2,nxgraro2 )
41
42c=======================================================================
43c
44c   Auteur:  P. Le Van /L. Fairhead/F.Hourdin
45c   -------
46c
47c   Objet:
48c   ------
49c
50c   GCM LMD nouvelle grille
51c
52c=======================================================================
53c
54c  ... Dans inigeom , nouveaux calculs pour les elongations  cu , cv
55c      et possibilite d'appeler une fonction f(y)  a derivee tangente
56c      hyperbolique a la  place de la fonction a derivee sinusoidale.
57c  ... Possibilite de choisir le schema pour l'advection de
58c        q  , en modifiant iadv dans traceur.def  (MAF,10/02) .
59c
60c      Pour Van-Leer + Vapeur d'eau saturee, iadv(1)=4. (F.Codron,10/99)
61c      Pour Van-Leer iadv=10
62c
63c-----------------------------------------------------------------------
64c   Declarations:
65c   -------------
66#include "dimensions.h"
67#include "paramet.h"
68#include "comconst.h"
69#include "comdissnew.h"
70#include "comvert.h"
71#include "comgeom.h"
72#include "logic.h"
73#include "temps.h"
74#include "ener.h"
75#include "description.h"
76#include "serre.h"
77!#include "com_io_dyn.h"
78#include "iniprint.h"
79#include "tracstoke.h"
80
81#ifdef INCA
82! Only INCA needs these informations (from the Earth's physics)
83!#include "indicesol.h"
84#endif
85
86      INTEGER         longcles
87      PARAMETER     ( longcles = 20 )
88      REAL  clesphy0( longcles )
89      SAVE  clesphy0
90
91
92
93      REAL zdtvr
94
95c   variables dynamiques
96      REAL vcov(ip1jm,llm),ucov(ip1jmp1,llm) ! vents covariants
97      REAL teta(ip1jmp1,llm)                 ! temperature potentielle
98      REAL, ALLOCATABLE, DIMENSION(:,:,:) :: q ! champs advectes
99      REAL ps(ip1jmp1)                       ! pression  au sol
100c      REAL p (ip1jmp1,llmp1  )               ! pression aux interfac.des couches
101      REAL masse(ip1jmp1,llm)                ! masse d'air
102      REAL phis(ip1jmp1)                     ! geopotentiel au sol
103c      REAL phi(ip1jmp1,llm)                  ! geopotentiel
104c      REAL w(ip1jmp1,llm)                    ! vitesse verticale
105
106c variables dynamiques intermediaire pour le transport
107
108c   variables pour le fichier histoire
109      REAL dtav      ! intervalle de temps elementaire
110
111      REAL time_0
112
113      LOGICAL lafin
114c      INTEGER ij,iq,l,i,j
115      INTEGER i,j
116
117
118      real time_step, t_wrt, t_ops
119
120
121      LOGICAL call_iniphys
122      data call_iniphys/.true./
123
124c+jld variables test conservation energie
125c      REAL ecin(ip1jmp1,llm),ecin0(ip1jmp1,llm)
126C     Tendance de la temp. potentiel d (theta)/ d t due a la
127C     tansformation d'energie cinetique en energie thermique
128C     cree par la dissipation
129c      REAL dhecdt(ip1jmp1,llm)
130c      REAL vcont(ip1jm,llm),ucont(ip1jmp1,llm)
131c      REAL      d_h_vcol, d_qt, d_qw, d_ql, d_ec
132c      CHARACTER (len=15) :: ztit
133c-jld
134
135
136      character (len=80) :: dynhist_file, dynhistave_file
137      character (len=20) :: modname
138      character (len=80) :: abort_message
139! locales pour gestion du temps
140      INTEGER :: an, mois, jour
141      REAL :: heure
142
143
144c-----------------------------------------------------------------------
145c    variables pour l'initialisation de la physique :
146c    ------------------------------------------------
147      INTEGER ngridmx
148      PARAMETER( ngridmx = 2+(jjm-1)*iim - 1/jjm   )
149      REAL zcufi(ngridmx),zcvfi(ngridmx)
150      REAL latfi(ngridmx),lonfi(ngridmx)
151      REAL airefi(ngridmx)
152      SAVE latfi, lonfi, airefi
153     
154      INTEGER :: ierr
155
156
157c-----------------------------------------------------------------------
158c   Initialisations:
159c   ----------------
160
161      abort_message = 'last timestep reached'
162      modname = 'gcm'
163      descript = 'Run GCM LMDZ'
164      lafin    = .FALSE.
165      dynhist_file = 'dyn_hist'
166      dynhistave_file = 'dyn_hist_ave'
167
168
169
170c----------------------------------------------------------------------
171c  lecture des fichiers gcm.def ou run.def
172c  ---------------------------------------
173c
174! Ehouarn: dump possibility of using defrun
175!#ifdef CPP_IOIPSL
176      CALL conf_gcm( 99, .TRUE. , clesphy0 )
177!#else
178!      CALL defrun( 99, .TRUE. , clesphy0 )
179!#endif
180c
181c
182c------------------------------------
183c   Initialisation partie parallele
184c------------------------------------
185
186      CALL init_const_mpi
187      call init_parallel
188      call ini_getparam("out.def")
189      call Read_Distrib
190
191#ifdef CPP_PHYS
192        CALL Init_Phys_lmdz(iim,jjp1,llm,mpi_size,distrib_phys)
193#endif
194      CALL set_bands
195#ifdef CPP_PHYS
196      CALL Init_interface_dyn_phys
197#endif
198      CALL barrier
199
200      if (mpi_rank==0) call WriteBands
201      call SetDistrib(jj_Nb_Caldyn)
202
203c$OMP PARALLEL
204      call Init_Mod_hallo
205c$OMP END PARALLEL
206
207#ifdef CPP_PHYS
208c$OMP PARALLEL
209      call InitComgeomphy
210c$OMP END PARALLEL
211#endif
212
213!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
214! Initialisation de XIOS
215!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
216
217
218c-----------------------------------------------------------------------
219c   Choix du calendrier
220c   -------------------
221
222c      calend = 'earth_365d'
223
224#ifdef CPP_IOIPSL
225      if (calend == 'earth_360d') then
226        call ioconf_calendar('360d')
227        write(lunout,*)'CALENDRIER CHOISI: Terrestre a 360 jours/an'
228      else if (calend == 'earth_365d') then
229        call ioconf_calendar('noleap')
230        write(lunout,*)'CALENDRIER CHOISI: Terrestre a 365 jours/an'
231      else if (calend == 'earth_366d') then
232        call ioconf_calendar('gregorian')
233        write(lunout,*)'CALENDRIER CHOISI: Terrestre bissextile'
234      else
235        abort_message = 'Mauvais choix de calendrier'
236        call abort_gcm(modname,abort_message,1)
237      endif
238#endif
239
240      IF (type_trac == 'inca') THEN
241#ifdef INCA
242         call init_const_lmdz(
243     $        nbtr,anneeref,dayref,
244     $        iphysiq,day_step,nday,
245     $        nbsrf, is_oce,is_sic,
246     $        is_ter,is_lic)
247
248         call init_inca_para(
249     $        iim,jjm+1,llm,klon_glo,mpi_size,
250     $        distrib_phys,COMM_LMDZ)
251#endif
252      END IF
253
254c-----------------------------------------------------------------------
255c   Initialisation des traceurs
256c   ---------------------------
257c  Choix du nombre de traceurs et du schema pour l'advection
258c  dans fichier traceur.def, par default ou via INCA
259      call infotrac_init
260
261c Allocation de la tableau q : champs advectes   
262      ALLOCATE(q(ip1jmp1,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(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("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(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          call abort_gcm("gcm", "'Je m''arrete'", 1)
331        ENDIF
332      ENDIF
333      IF (raz_date == 1) THEN
334        annee_ref = anneeref
335        day_ref = dayref
336        day_ini = dayref
337        itau_dyn = 0
338        itau_phy = 0
339        time_0 = 0.
340        write(lunout,*)
341     .   'GCM: On reinitialise a la date lue dans gcm.def'
342      ELSE IF (annee_ref .ne. anneeref .or. day_ref .ne. dayref) THEN
343        write(lunout,*)
344     .  'GCM: Attention les dates initiales lues dans le fichier'
345        write(lunout,*)
346     .  ' restart ne correspondent pas a celles lues dans '
347        write(lunout,*)' gcm.def'
348        write(lunout,*)' annee_ref=',annee_ref," anneeref=",anneeref
349        write(lunout,*)' day_ref=',day_ref," dayref=",dayref
350        write(lunout,*)' Pas de remise a zero'
351      ENDIF
352c      if (annee_ref .ne. anneeref .or. day_ref .ne. dayref) then
353c        write(lunout,*)
354c     .  'GCM: Attention les dates initiales lues dans le fichier'
355c        write(lunout,*)
356c     .  ' restart ne correspondent pas a celles lues dans '
357c        write(lunout,*)' gcm.def'
358c        write(lunout,*)' annee_ref=',annee_ref," anneeref=",anneeref
359c        write(lunout,*)' day_ref=',day_ref," dayref=",dayref
360c        if (raz_date .ne. 1) then
361c          write(lunout,*)
362c     .    'GCM: On garde les dates du fichier restart'
363c        else
364c          annee_ref = anneeref
365c          day_ref = dayref
366c          day_ini = dayref
367c          itau_dyn = 0
368c          itau_phy = 0
369c          time_0 = 0.
370c          write(lunout,*)
371c     .   'GCM: On reinitialise a la date lue dans gcm.def'
372c        endif
373c      ELSE
374c        raz_date = 0
375c      endif
376
377#ifdef CPP_IOIPSL
378      mois = 1
379      heure = 0.
380      call ymds2ju(annee_ref, mois, day_ref, heure, jD_ref)
381      jH_ref = jD_ref - int(jD_ref)
382      jD_ref = int(jD_ref)
383
384      call ioconf_startdate(INT(jD_ref), jH_ref)
385
386      write(lunout,*)'DEBUG'
387      write(lunout,*)'annee_ref, mois, day_ref, heure, jD_ref'
388      write(lunout,*)annee_ref, mois, day_ref, heure, jD_ref
389      call ju2ymds(jD_ref+jH_ref,an, mois, jour, heure)
390      write(lunout,*)'jD_ref+jH_ref,an, mois, jour, heure'
391      write(lunout,*)jD_ref+jH_ref,an, mois, jour, heure
392#else
393! Ehouarn: we still need to define JD_ref and JH_ref
394! and since we don't know how many days there are in a year
395! we set JD_ref to 0 (this should be improved ...)
396      jD_ref=0
397      jH_ref=0
398#endif
399
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_p("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(day_ref,annee_ref,time_step,
517     &                   t_ops,t_wrt)
518!         CALL initdynav_p(dynhistave_file,day_ref,annee_ref,time_step,
519!     .        t_ops, t_wrt, histaveid)
520        END IF
521      ENDIF
522      dtav = iperiod*dtvr/daysec
523#endif
524! #endif of #ifdef CPP_IOIPSL
525
526c  Choix des frequences de stokage pour le offline
527c      istdyn=day_step/4     ! stockage toutes les 6h=1jour/4
528c      istdyn=day_step/12     ! stockage toutes les 2h=1jour/12
529      istdyn=day_step/4     ! stockage toutes les 6h=1jour/12
530      istphy=istdyn/iphysiq     
531
532
533c
534c-----------------------------------------------------------------------
535c   Integration temporelle du modele :
536c   ----------------------------------
537
538c       write(78,*) 'ucov',ucov
539c       write(78,*) 'vcov',vcov
540c       write(78,*) 'teta',teta
541c       write(78,*) 'ps',ps
542c       write(78,*) 'q',q
543
544c$OMP PARALLEL DEFAULT(SHARED) COPYIN(/temps/,/logici/,/logicl/)
545      CALL leapfrog_p(ucov,vcov,teta,ps,masse,phis,q,clesphy0,
546     .              time_0)
547c$OMP END PARALLEL
548
549
550      END
551
Note: See TracBrowser for help on using the repository browser.