source: trunk/LMDZ.COMMON/libf/dyn3dpar/gcm.F @ 3840

Last change on this file since 3840 was 3836, checked in by jbclement, 2 weeks ago

COMMON:
Rework related to the command-line parsing:

  • Replace ad-hoc argument parsing with a unified 'parse_args' subroutine, allowing easier extension to other programs and options across models;;
  • Use of '--version' (with ab optional output file) to print compilation/version details;
  • Addition of 'job_timelimit_mod' module to handle SLURM/PBS job time-limit via '--jobid' (currently only used in the PEM), allowing easier extension to other programs;
  • Replace manual SSO handling with 'parse_args' for the Mars start2archive;
  • Clean-up related legacy code in the programs supporting the version option.

JBC

File size: 18.1 KB
Line 
1!
2! $Id: gcm.F 1446 2010-10-22 09:27:25Z emillour $
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!#ifdef CPP_PHYS
17!      USE mod_interface_dyn_phys
18!#endif
19      USE mod_hallo
20      USE Bands
21      USE getparam
22      USE filtreg_mod
23      USE control_mod, only: planet_type,nday,day_step,iperiod,iphysiq,
24     &                       raz_date,anneeref,starttime,dayref,
25     &                       ok_dyn_ins,ok_dyn_ave,iecri,periodav,
26     &                       less1day,fractday,ndynstep,nsplit_phys,
27     &                       ecritstart
28      use cpdet_mod, only: ini_cpdet
29      use parse_args_mod, only: parse_args
30
31
32! Ehouarn: the following are needed with (parallel) physics:
33#ifdef CPP_PHYS
34      USE iniphysiq_mod, ONLY: iniphysiq
35      USE mod_grid_phy_lmdz
36!      USE mod_phys_lmdz_para, ONLY : klon_mpi_para_nb
37      USE mod_phys_lmdz_omp_data, ONLY: klon_omp
38      USE dimphy
39#endif
40      USE comconst_mod, ONLY: daysec,dtvr,dtphys,rad,g,r,cpp
41      USE logic_mod
42      USE temps_mod, ONLY: calend,start_time,annee_ref,day_ref,
43     .          itau_dyn,itau_phy,day_ini,jD_ref,jH_ref,day_end,
44     .          dt,hour_ini,itaufin
45      IMPLICIT NONE
46
47c      ......   Version  du 10/01/98    ..........
48
49c             avec  coordonnees  verticales hybrides
50c   avec nouveaux operat. dissipation * ( gradiv2,divgrad2,nxgraro2 )
51
52c=======================================================================
53c
54c   Auteur:  P. Le Van /L. Fairhead/F.Hourdin
55c   -------
56c
57c   Objet:
58c   ------
59c
60c   GCM LMD nouvelle grille
61c
62c=======================================================================
63c
64c  ... Dans inigeom , nouveaux calculs pour les elongations  cu , cv
65c      et possibilite d'appeler une fonction f(y)  a derivee tangente
66c      hyperbolique a la  place de la fonction a derivee sinusoidale.
67c  ... Possibilite de choisir le schema pour l'advection de
68c        q  , en modifiant iadv dans traceur.def  (MAF,10/02) .
69c
70c      Pour Van-Leer + Vapeur d'eau saturee, iadv(1)=4. (F.Codron,10/99)
71c      Pour Van-Leer iadv=10
72c
73c-----------------------------------------------------------------------
74c   Declarations:
75c   -------------
76
77#include "dimensions.h"
78#include "paramet.h"
79#include "comdissnew.h"
80#include "comgeom.h"
81!!!!!!!!!!!#include "control.h"
82!#include "com_io_dyn.h"
83#include "iniprint.h"
84#include "tracstoke.h"
85
86
87      REAL zdtvr
88
89c   variables dynamiques
90      REAL vcov(ip1jm,llm),ucov(ip1jmp1,llm) ! vents covariants
91      REAL teta(ip1jmp1,llm)                 ! temperature potentielle
92      REAL, ALLOCATABLE, DIMENSION(:,:,:):: q! champs advectes
93      REAL ps(ip1jmp1)                       ! pression  au sol
94c      REAL p (ip1jmp1,llmp1  )               ! pression aux interfac.des couches
95c      REAL pks(ip1jmp1)                      ! exner au  sol
96c      REAL pk(ip1jmp1,llm)                   ! exner au milieu des couches
97c      REAL pkf(ip1jmp1,llm)                  ! exner filt.au milieu des couches
98      REAL masse(ip1jmp1,llm)                ! masse d'air
99      REAL phis(ip1jmp1)                     ! geopotentiel au sol
100c      REAL phi(ip1jmp1,llm)                  ! geopotentiel
101c      REAL w(ip1jmp1,llm)                    ! vitesse verticale
102
103c variables dynamiques intermediaire pour le transport
104
105c   variables pour le fichier histoire
106      REAL dtav      ! intervalle de temps elementaire
107
108      REAL time_0
109
110      LOGICAL lafin
111c      INTEGER ij,iq,l,i,j
112      INTEGER i,j
113
114
115      real time_step, t_wrt, t_ops
116
117
118!      LOGICAL call_iniphys
119!      data call_iniphys/.true./
120
121c      REAL alpha(ip1jmp1,llm),beta(ip1jmp1,llm)
122c+jld variables test conservation energie
123c      REAL ecin(ip1jmp1,llm),ecin0(ip1jmp1,llm)
124C     Tendance de la temp. potentiel d (theta)/ d t due a la
125C     tansformation d'energie cinetique en energie thermique
126C     cree par la dissipation
127c      REAL dhecdt(ip1jmp1,llm)
128c      REAL vcont(ip1jm,llm),ucont(ip1jmp1,llm)
129c      REAL      d_h_vcol, d_qt, d_qw, d_ql, d_ec
130c      CHARACTER (len=15) :: ztit
131c-jld
132
133
134      character (len=80) :: dynhist_file, dynhistave_file
135      character (len=20) :: modname
136      character (len=80) :: abort_message
137! locales pour gestion du temps
138      INTEGER :: an, mois, jour
139      REAL :: heure
140
141      logical :: present
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      ! Parse command-line options
160      call parse_args()
161
162      abort_message = 'last timestep reached'
163      modname = 'gcm'
164      lafin    = .FALSE.
165      dynhist_file = 'dyn_hist'
166      dynhistave_file = 'dyn_hist_ave'
167
168
169
170c----------------------------------------------------------------------
171c  Load flags and options from run.def
172c  ---------------------------------------
173c
174      ! Start by checking that there indeed is a run.def file
175      INQUIRE(file="run.def", EXIST=present)
176      IF(.not. present) then
177        CALL abort_gcm("gcm", "file run.def not found, Aborting!",1)
178      ENDIF
179
180      CALL conf_gcm( 99, .TRUE. )
181      if (mod(iphysiq, iperiod) /= 0) call abort_gcm("conf_gcm",
182     s "iphysiq must be a multiple of iperiod", 1)
183c
184c
185c------------------------------------
186c   Initialisation partie parallele
187c------------------------------------
188
189      CALL init_const_mpi
190      call init_parallel
191      call Read_Distrib
192
193!#ifdef CPP_PHYS
194!        CALL init_phys_lmdz(iim,jjp1,llm,mpi_size,distrib_phys)
195!#endif
196!      CALL set_bands
197!#ifdef CPP_PHYS
198!      CALL Init_interface_dyn_phys
199!#endif
200      CALL barrier
201
202      CALL set_bands
203      if (mpi_rank==0) call WriteBands
204      call SetDistrib(jj_Nb_Caldyn)
205
206c$OMP PARALLEL
207      call Init_Mod_hallo
208c$OMP END PARALLEL
209
210#ifdef CPP_PHYS
211!c$OMP PARALLEL
212!      call initcomgeomphy
213!c$OMP END PARALLEL
214#endif
215
216!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
217! Initialisation de XIOS
218!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
219
220
221c
222c Initialisations pour Cp(T) Venus
223      call ini_cpdet
224c
225c-----------------------------------------------------------------------
226c   Choix du calendrier
227c   -------------------
228
229c      calend = 'earth_365d'
230
231#ifdef CPP_IOIPSL
232      if (calend == 'earth_360d') then
233        call ioconf_calendar('360d')
234        write(lunout,*)'CALENDRIER CHOISI: Terrestre a 360 jours/an'
235      else if (calend == 'earth_365d') then
236        call ioconf_calendar('noleap')
237        write(lunout,*)'CALENDRIER CHOISI: Terrestre a 365 jours/an'
238      else if (calend == 'earth_366d') then
239        call ioconf_calendar('gregorian')
240        write(lunout,*)'CALENDRIER CHOISI: Terrestre bissextile'
241      else if (calend == 'titan') then
242!        call ioconf_calendar('titan')
243        write(lunout,*)'CALENDRIER CHOISI: Titan'
244        abort_message = 'A FAIRE...'
245        call abort_gcm(modname,abort_message,1)
246      else if (calend == 'venus') then
247!        call ioconf_calendar('venus')
248        write(lunout,*)'CALENDRIER CHOISI: Venus'
249        abort_message = 'A FAIRE...'
250        call abort_gcm(modname,abort_message,1)
251      else
252        abort_message = 'Mauvais choix de calendrier'
253        call abort_gcm(modname,abort_message,1)
254      endif
255#endif
256c-----------------------------------------------------------------------
257c   Initialisation des traceurs
258c   ---------------------------
259c  Choix du nombre de traceurs et du schema pour l'advection
260c  dans fichier traceur.def, par default ou via INCA
261      call infotrac_init
262
263c Allocation de la tableau q : champs advectes   
264      ALLOCATE(q(ip1jmp1,llm,nqtot))
265
266c-----------------------------------------------------------------------
267c   Lecture de l'etat initial :
268c   ---------------------------
269
270c  lecture du fichier start.nc
271      if (read_start) then
272      ! we still need to run iniacademic to initialize some
273      ! constants & fields, if we run the 'newtonian' or 'SW' cases:
274        if (iflag_phys.ne.1) then
275          CALL iniacademic(vcov,ucov,teta,q,masse,ps,phis,time_0)
276        endif
277
278        CALL dynetat0("start.nc",vcov,ucov,
279     &              teta,q,masse,ps,phis, time_0)
280       
281        ! Load relaxation fields (simple nudging). AS 09/2013
282        ! ---------------------------------------------------
283        if (planet_type.eq."generic") then
284         if (ok_guide) then
285           CALL relaxetat0("relax.nc")
286         endif
287        endif
288 
289c       write(73,*) 'ucov',ucov
290c       write(74,*) 'vcov',vcov
291c       write(75,*) 'teta',teta
292c       write(76,*) 'ps',ps
293c       write(77,*) 'q',q
294
295      endif ! of if (read_start)
296
297c le cas echeant, creation d un etat initial
298      IF (prt_level > 9) WRITE(lunout,*)
299     .              'GCM: AVANT iniacademic AVANT AVANT AVANT AVANT'
300      if (.not.read_start) then
301         CALL iniacademic(vcov,ucov,teta,q,masse,ps,phis,time_0)
302      endif
303
304
305c-----------------------------------------------------------------------
306c   Lecture des parametres de controle pour la simulation :
307c   -------------------------------------------------------
308c  on recalcule eventuellement le pas de temps
309
310      IF(MOD(day_step,iperiod).NE.0) THEN
311        abort_message =
312     .  'Il faut choisir un nb de pas par jour multiple de iperiod'
313        call abort_gcm(modname,abort_message,1)
314      ENDIF
315
316      IF(MOD(day_step,iphysiq).NE.0) THEN
317        abort_message =
318     * 'Il faut choisir un nb de pas par jour multiple de iphysiq'
319        call abort_gcm(modname,abort_message,1)
320      ENDIF
321
322      zdtvr    = daysec/REAL(day_step)
323        IF(dtvr.NE.zdtvr) THEN
324         WRITE(lunout,*)
325     .    'WARNING!!! time step change: ',dtvr,'>',zdtvr
326        ENDIF
327      dtvr=zdtvr
328
329C
330C reset calendar if requested
331c
332      IF (raz_date == 1) then
333        WRITE(lunout,*)'Reinitializing to start time from run.def'
334        start_time = starttime
335      ENDIF
336
337      IF (raz_date == 1) THEN
338        annee_ref = anneeref
339        day_ref = dayref
340        day_ini = dayref
341        itau_dyn = 0
342        itau_phy = 0
343        time_0 = 0.
344        write(lunout,*)
345     .   'GCM: On reinitialise a la date lue dans gcm.def'
346      ELSE IF (annee_ref .ne. anneeref .or. day_ref .ne. dayref) THEN
347        write(lunout,*)
348     .  'GCM: Attention les dates initiales lues dans le fichier'
349        write(lunout,*)
350     .  ' restart ne correspondent pas a celles lues dans '
351        write(lunout,*)' gcm.def'
352        write(lunout,*)' annee_ref=',annee_ref," anneeref=",anneeref
353        write(lunout,*)' day_ref=',day_ref," dayref=",dayref
354        write(lunout,*)' Pas de remise a zero'
355      ENDIF
356
357c      if (annee_ref .ne. anneeref .or. day_ref .ne. dayref) then
358c        write(lunout,*)
359c     .  'GCM: Attention les dates initiales lues dans le fichier'
360c        write(lunout,*)
361c     .  ' restart ne correspondent pas a celles lues dans '
362c        write(lunout,*)' gcm.def'
363c        write(lunout,*)' annee_ref=',annee_ref," anneeref=",anneeref
364c        write(lunout,*)' day_ref=',day_ref," dayref=",dayref
365c        if (raz_date .ne. 1) then
366c          write(lunout,*)
367c     .    'GCM: On garde les dates du fichier restart'
368c        else
369c          annee_ref = anneeref
370c          day_ref = dayref
371c          day_ini = dayref
372c          itau_dyn = 0
373c          itau_phy = 0
374c          time_0 = 0.
375c          write(lunout,*)
376c     .   'GCM: On reinitialise a la date lue dans gcm.def'
377c        endif
378c      ELSE
379c        raz_date = 0
380c      endif
381
382#ifdef CPP_IOIPSL
383      mois = 1
384      heure = 0.
385! Ce n'est defini pour l'instant que pour la Terre...
386      if (planet_type.eq.'earth') then
387      call ymds2ju(annee_ref, mois, day_ref, heure, jD_ref)
388      jH_ref = jD_ref - int(jD_ref)
389      jD_ref = int(jD_ref)
390
391      call ioconf_startdate(INT(jD_ref), jH_ref)
392
393      write(lunout,*)'DEBUG'
394      write(lunout,*)'annee_ref, mois, day_ref, heure, jD_ref'
395      write(lunout,*)annee_ref, mois, day_ref, heure, jD_ref
396      call ju2ymds(jD_ref+jH_ref,an, mois, jour, heure)
397      write(lunout,*)'jD_ref+jH_ref,an, mois, jour, heure'
398      write(lunout,*)jD_ref+jH_ref,an, mois, jour, heure
399!      else if (planet_type.eq.'titan') then
400!        jD_ref=1 ! Only if we use old Titan starts (J.V.O 2016)
401      else
402! A voir pour Titan et Venus
403        jD_ref=0
404        jH_ref=0
405      write(lunout,*)'A VOIR POUR VENUS ET TITAN: jD_ref, jH_ref'
406      write(lunout,*)jD_ref,jH_ref
407      endif ! planet_type
408#else
409! Ehouarn: we still need to define JD_ref and JH_ref
410! and since we don't know how many days there are in a year
411! we set JD_ref to 0 (this should be improved ...)
412      jD_ref=0
413      jH_ref=0
414#endif
415
416      if (iflag_phys.eq.1) then
417      ! these initialisations have already been done (via iniacademic)
418      ! if running in SW or Newtonian mode
419c-----------------------------------------------------------------------
420c   Initialisation des constantes dynamiques :
421c   ------------------------------------------
422        dtvr = zdtvr
423        CALL iniconst
424
425c-----------------------------------------------------------------------
426c   Initialisation de la geometrie :
427c   --------------------------------
428        CALL inigeom
429
430c-----------------------------------------------------------------------
431c   Initialisation du filtre :
432c   --------------------------
433        CALL inifilr
434      endif ! of if (iflag_phys.eq.1)
435c
436c-----------------------------------------------------------------------
437c   Initialisation de la dissipation :
438c   ----------------------------------
439
440      CALL inidissip( lstardis, nitergdiv, nitergrot, niterh   ,
441     *                tetagdiv, tetagrot , tetatemp, vert_prof_dissip)
442
443c-----------------------------------------------------------------------
444c   Initialisation des I/O :
445c   ------------------------
446
447
448      if (nday>=0) then ! standard case
449        day_end=day_ini+nday
450      else ! special case when nday <0, run -nday dynamical steps
451        day_end=day_ini-nday/day_step
452      endif
453      if (less1day) then
454        day_end=day_ini+floor(time_0+fractday)
455      endif
456      if (ndynstep.gt.0) then
457        day_end=day_ini+floor(time_0+float(ndynstep)/float(day_step))
458      endif
459     
460      WRITE(lunout,'(a,i7,a,i7)')
461     &             "run from day ",day_ini,"  to day",day_end
462
463#ifdef CPP_IOIPSL
464! Ce n'est defini pour l'instant que pour la Terre...
465      if (planet_type.eq.'earth') then
466      call ju2ymds(jD_ref + day_ini - day_ref, an, mois, jour, heure)
467      write (lunout,301)jour, mois, an
468      call ju2ymds(jD_ref + day_end - day_ref, an, mois, jour, heure)
469      write (lunout,302)jour, mois, an
470      else
471! A voir pour Titan et Venus
472      write(lunout,*)'A VOIR POUR VENUS/TITAN: separation en annees...'
473      endif ! planet_type
474
475 301  FORMAT('1'/,15x,'run du ', i2,'/',i2,'/',i4)
476 302  FORMAT('1'/,15x,'    au ', i2,'/',i2,'/',i4)
477#endif
478
479
480c-----------------------------------------------------------------------
481c   Initialisation de la physique :
482c   -------------------------------
483
484      IF ((iflag_phys==1).or.(iflag_phys>=100)) THEN
485! Physics
486#ifdef CPP_PHYS
487         CALL iniphysiq(iim,jjm,llm,
488     &                distrib_phys(mpi_rank),comm_lmdz,
489     &                daysec,day_ini,dtphys/nsplit_phys,
490     &                rlatu,rlatv,rlonu,rlonv,aire,cu,cv,
491     &                rad,g,r,cpp,iflag_phys)
492#endif
493!         call_iniphys=.false.
494      ENDIF ! of IF (call_iniphys.and.(iflag_phys==1.or.iflag_phys>=100))
495
496
497      if (planet_type=="mars") then
498         ! For Mars we transmit day_ini
499        !CALL dynredem0_p("restart.nc", day_ini, phis)
500        if (ecritstart.GT.0) then
501         CALL dynredem0_p("restart.nc", day_ini, phis)
502        else
503         CALL dynredem0_p("restart.nc", day_end, phis)
504        endif
505      else
506        CALL dynredem0_p("restart.nc", day_end, phis)
507      endif
508      ecripar = .TRUE.
509
510#ifdef CPP_IOIPSL
511      time_step = zdtvr
512      IF (mpi_rank==0) then
513        if (ok_dyn_ins) then
514        ! initialize output file for instantaneous outputs
515        ! t_ops = iecri * daysec ! do operations every t_ops
516        t_ops =((1.0*iecri)/day_step) * daysec 
517        t_wrt = daysec ! iecri * daysec ! write output every t_wrt
518        CALL inithist(day_ref,annee_ref,time_step,
519     &                  t_ops,t_wrt)
520        endif
521
522        IF (ok_dyn_ave) THEN
523          ! initialize output file for averaged outputs
524          t_ops = iperiod * time_step ! do operations every t_ops
525          t_wrt = periodav * daysec   ! write output every t_wrt
526          CALL initdynav(day_ref,annee_ref,time_step,
527     &                   t_ops,t_wrt)
528!         CALL initdynav_p(dynhistave_file,day_ref,annee_ref,time_step,
529!     .        t_ops, t_wrt, histaveid)
530        END IF
531      ENDIF
532      dtav = iperiod*dtvr/daysec
533#endif
534! #endif of #ifdef CPP_IOIPSL
535
536c  Choix des frequences de stokage pour le offline
537c      istdyn=day_step/4     ! stockage toutes les 6h=1jour/4
538c      istdyn=day_step/12     ! stockage toutes les 2h=1jour/12
539      istdyn=day_step/4     ! stockage toutes les 6h=1jour/12
540      istphy=istdyn/iphysiq     
541
542
543c
544c-----------------------------------------------------------------------
545c   Integration temporelle du modele :
546c   ----------------------------------
547
548c       write(78,*) 'ucov',ucov
549c       write(78,*) 'vcov',vcov
550c       write(78,*) 'teta',teta
551c       write(78,*) 'ps',ps
552c       write(78,*) 'q',q
553
554!c$OMP PARALLEL DEFAULT(SHARED) COPYIN(/temps/,/logici/,/logicl/)
555!variable temps no longer exists
556c$OMP PARALLEL DEFAULT(SHARED)
557c       Copy all threadprivate variables from temps_mod
558c$OMP1 COPYIN(dt,jD_ref,jH_ref,start_time,hour_ini,day_ini,day_end)
559c$OMP1 COPYIN(annee_ref,day_ref,itau_dyn,itau_phy,itaufin,calend)
560c       Copy all threadprivate variables from logic_mod
561c$OMP1 COPYIN(purmats,forward,leapf,apphys,statcl,conser,apdiss,apdelq)
562c$OMP1 COPYIN(saison,ecripar,fxyhypb,ysinus,read_start,ok_guide)
563c$OMP1 COPYIN(ok_strato,tidal,ok_gradsfile,ok_limit,ok_etat0)
564c$OMP1 COPYIN(iflag_phys,iflag_trac)
565
566
567      CALL leapfrog_p(ucov,vcov,teta,ps,masse,phis,q,
568     .              time_0)
569c$OMP END PARALLEL
570
571
572      END
573
Note: See TracBrowser for help on using the repository browser.