source: LMDZ6/branches/Amaury_dev/libf/dyn3dmem/gcm.F90 @ 5214

Last change on this file since 5214 was 5195, checked in by abarral, 8 weeks ago

Correct r5192, some lmdz_description cases were missing

  • 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:keywords set to Id
File size: 15.0 KB
Line 
1! $Id: gcm.F90 5195 2024-09-16 13:18:00Z dcugnet $
2
3PROGRAM gcm
4
5  USE IOIPSL
6
7  USE mod_const_mpi, ONLY: init_const_mpi
8  USE parallel_lmdz
9  USE lmdz_infotrac, ONLY: nqtot, init_infotrac
10  USE mod_hallo
11  USE Bands
12  USE lmdz_filtreg
13  USE control_mod
14
15  USE iniphysiq_mod, ONLY: iniphysiq
16  USE lmdz_cppkeys_wrapper, ONLY: CPPKEY_PHYS
17
18  USE comconst_mod, ONLY: cpp, daysec, dtphys, dtvr, g, r, rad
19  USE logic_mod ! all of it, because of copyin clause when calling leapfrog
20  USE temps_mod, ONLY: calend, start_time, annee_ref, day_ref, &
21          itau_dyn, itau_phy, day_ini, jD_ref, jH_ref, day_end, &
22          dt, hour_ini, itaufin
23  USE mod_xios_dyn3dmem, ONLY: xios_dyn3dmem_init
24  USE lmdz_filtreg, ONLY: inifilr
25  USE lmdz_iniprint, ONLY: lunout, prt_level
26  USE lmdz_comdissnew, ONLY: lstardis, nitergdiv, nitergrot, niterh, tetagdiv, &
27          tetagrot, tetatemp, coefdis, vert_prof_dissip
28  USE lmdz_comgeom
29  USE lmdz_tracstoke
30
31  USE lmdz_dimensions, ONLY: iim, jjm, llm, ndm
32  USE lmdz_paramet
33  USE lmdz_conf_gcm, ONLY: conf_gcm
34
35  IMPLICIT NONE
36
37  !      ......   Version  du 10/01/98    ..........
38
39  !             avec  coordonnees  verticales hybrides
40  !   avec nouveaux operat. dissipation * ( gradiv2,divgrad2,nxgraro2 )
41
42  !=======================================================================
43
44  !   Auteur:  P. Le Van /L. Fairhead/F.Hourdin
45  !   -------
46
47  !   Objet:
48  !   ------
49
50  !   GCM LMD nouvelle grille
51
52  !=======================================================================
53
54  !  ... Dans inigeom , nouveaux calculs pour les elongations  cu , cv
55  !      et possibilite d'appeler une fonction f(y)  a derivee tangente
56  !      hyperbolique a la  place de la fonction a derivee sinusoidale.
57  !  ... Possibilite de choisir le schema pour l'advection de
58  !        q  , en modifiant iadv dans traceur.def  (MAF,10/02) .
59
60  !      Pour Van-Leer + Vapeur d'eau saturee, iadv(1)=4. (F.Codron,10/99)
61  !      Pour Van-Leer iadv=10
62
63  !-----------------------------------------------------------------------
64  !   Declarations:
65  !   -------------
66
67  REAL zdtvr
68
69  !   variables dynamiques
70  REAL, ALLOCATABLE, SAVE :: vcov(:, :), ucov(:, :) ! vents covariants
71  REAL, ALLOCATABLE, SAVE :: teta(:, :)     ! temperature potentielle
72  REAL, ALLOCATABLE, SAVE :: q(:, :, :)      ! champs advectes
73  REAL, ALLOCATABLE, SAVE :: ps(:)         ! pression  au sol
74  !      REAL p (ip1jmp1,llmp1  )               ! pression aux interfac.des couches
75  REAL, ALLOCATABLE, SAVE :: masse(:, :)    ! masse d'air
76  REAL, ALLOCATABLE, SAVE :: phis(:)       ! geopotentiel au sol
77  !      REAL phi(ip1jmp1,llm)                  ! geopotentiel
78  !      REAL w(ip1jmp1,llm)                    ! vitesse verticale
79
80  ! variables dynamiques intermediaire pour le transport
81
82  !   variables pour le fichier histoire
83  REAL dtav      ! intervalle de temps elementaire
84
85  REAL time_0
86
87  LOGICAL lafin
88
89  REAL time_step, t_wrt, t_ops
90
91  !+jld variables test conservation energie
92  !      REAL ecin(ip1jmp1,llm),ecin0(ip1jmp1,llm)
93  !     Tendance de la temp. potentiel d (theta)/ d t due a la
94  !     tansformation d'energie cinetique en energie thermique
95  !     cree par la dissipation
96  !      REAL dhecdt(ip1jmp1,llm)
97  !      REAL vcont(ip1jm,llm),ucont(ip1jmp1,llm)
98  !      REAL      d_h_vcol, d_qt, d_qw, d_ql, d_ec
99  !      CHARACTER (len=15) :: ztit
100  !-jld
101
102  CHARACTER (LEN = 80) :: dynhist_file, dynhistave_file
103  CHARACTER (LEN = 20) :: modname
104  CHARACTER (LEN = 80) :: abort_message
105  ! locales pour gestion du temps
106  INTEGER :: an, mois, jour
107  REAL :: heure
108  ! needed for xios interface
109  CHARACTER (LEN = 10) :: xios_cal_type
110  INTEGER :: anref, moisref, jourref
111  REAL :: heureref
112
113
114
115  !-----------------------------------------------------------------------
116  !   Initialisations:
117  !   ----------------
118
119  abort_message = 'last timestep reached'
120  modname = 'gcm'
121  lafin = .FALSE.
122  dynhist_file = 'dyn_hist'
123  dynhistave_file = 'dyn_hist_ave'
124
125
126
127  !----------------------------------------------------------------------
128  !  lecture des fichiers gcm.def ou run.def
129  !  ---------------------------------------
130
131  CALL conf_gcm(99, .TRUE.)
132  IF (mod(iphysiq, iperiod) /= 0) CALL abort_gcm("conf_gcm", &
133          "iphysiq must be a multiple of iperiod", 1)
134
135
136  !------------------------------------
137  !   Initialisation partie parallele
138  !------------------------------------
139  CALL init_const_mpi
140
141  CALL init_parallel
142  CALL Read_Distrib
143
144  !#ifdef CPP_PHYS
145  !  CALL Init_Phys_lmdz(iim,jjp1,llm,mpi_size,distrib_phys)
146  !#endif
147  !      CALL set_bands
148  !#ifdef CPP_PHYS
149  !  CALL Init_interface_dyn_phys
150  !#endif
151  CALL barrier
152
153  CALL set_bands
154  IF (mpi_rank==0) CALL WriteBands
155  CALL Set_Distrib(distrib_caldyn)
156
157  !$OMP PARALLEL
158  CALL Init_Mod_hallo
159  !$OMP END PARALLEL
160
161  !#ifdef CPP_PHYS
162  !c$OMP PARALLEL
163  !      CALL InitComgeomphy ! now done in iniphysiq
164  !c$OMP END PARALLEL
165  !#endif
166
167  !-----------------------------------------------------------------------
168  !   Choix du calendrier
169  !   -------------------
170
171  !      calend = 'earth_365d'
172
173  IF (calend == 'earth_360d') THEN
174    CALL ioconf_calendar('360_day')
175    WRITE(lunout, *)'CALENDRIER CHOISI: Terrestre a 360 jours/an'
176    xios_cal_type = 'd360'
177  ELSE IF (calend == 'earth_365d') THEN
178    CALL ioconf_calendar('noleap')
179    WRITE(lunout, *)'CALENDRIER CHOISI: Terrestre a 365 jours/an'
180    xios_cal_type = 'noleap'
181  ELSE IF (calend == 'gregorian') THEN
182    CALL ioconf_calendar('gregorian')
183    WRITE(lunout, *)'CALENDRIER CHOISI: Terrestre bissextile'
184    xios_cal_type = 'gregorian'
185  else
186    abort_message = 'Mauvais choix de calendrier'
187    CALL abort_gcm(modname, abort_message, 1)
188  ENDIF
189
190
191  !-----------------------------------------------------------------------
192  !   Initialisation des traceurs
193  !   ---------------------------
194  !  Choix du nombre de traceurs et du schema pour l'advection
195  !  dans fichier traceur.def, par default ou via INCA
196  CALL init_infotrac
197
198  ! Allocation de la tableau q : champs advectes   
199  ALLOCATE(ucov(ijb_u:ije_u, llm))
200  ALLOCATE(vcov(ijb_v:ije_v, llm))
201  ALLOCATE(teta(ijb_u:ije_u, llm))
202  ALLOCATE(masse(ijb_u:ije_u, llm))
203  ALLOCATE(ps(ijb_u:ije_u))
204  ALLOCATE(phis(ijb_u:ije_u))
205  ALLOCATE(q(ijb_u:ije_u, llm, nqtot))
206
207  !-----------------------------------------------------------------------
208  !   Lecture de l'etat initial :
209  !   ---------------------------
210
211  !  lecture du fichier start.nc
212  IF (read_start) THEN
213    ! we still need to run iniacademic to initialize some
214    ! constants & fields, if we run the 'newtonian' or 'SW' cases:
215    IF (iflag_phys/=1) THEN
216      CALL iniacademic_loc(vcov, ucov, teta, q, masse, ps, phis, time_0)
217    endif
218
219    !        if (planet_type.EQ."earth") THEN
220    ! Load an Earth-format start file
221    CALL dynetat0_loc("start.nc", vcov, ucov, &
222            teta, q, masse, ps, phis, time_0)
223    !        endif ! of if (planet_type.EQ."earth")
224
225    !       WRITE(73,*) 'ucov',ucov
226    !       WRITE(74,*) 'vcov',vcov
227    !       WRITE(75,*) 'teta',teta
228    !       WRITE(76,*) 'ps',ps
229    !       WRITE(77,*) 'q',q
230
231  ENDIF ! of if (read_start)
232
233  ! le cas echeant, creation d un etat initial
234  IF (prt_level > 9) WRITE(lunout, *) &
235          'GCM: AVANT iniacademic AVANT AVANT AVANT AVANT'
236  IF (.NOT.read_start) THEN
237    start_time = 0.
238    annee_ref = anneeref
239    CALL iniacademic_loc(vcov, ucov, teta, q, masse, ps, phis, time_0)
240  ENDIF
241
242  !-----------------------------------------------------------------------
243  !   Lecture des parametres de controle pour la simulation :
244  !   -------------------------------------------------------
245  !  on recalcule eventuellement le pas de temps
246
247  IF(MOD(day_step, iperiod)/=0) THEN
248    abort_message = &
249            'Il faut choisir un nb de pas par jour multiple de iperiod'
250    CALL abort_gcm(modname, abort_message, 1)
251  ENDIF
252
253  IF(MOD(day_step, iphysiq)/=0) THEN
254    abort_message = &
255            'Il faut choisir un nb de pas par jour multiple de iphysiq'
256    CALL abort_gcm(modname, abort_message, 1)
257  ENDIF
258
259  zdtvr = daysec / REAL(day_step)
260  IF(dtvr/=zdtvr) THEN
261    WRITE(lunout, *) &
262            'WARNING!!! changement de pas de temps', dtvr, '>', zdtvr
263  ENDIF
264
265  ! on remet le calendrier \`a zero si demande
266
267  IF (start_time /= starttime) THEN
268    WRITE(lunout, *)' GCM: Attention l''heure de depart lue dans le' &
269            , ' fichier restart ne correspond pas a celle lue dans le run.def'
270    IF (raz_date == 1) THEN
271      WRITE(lunout, *)'Je prends l''heure lue dans run.def'
272      start_time = starttime
273    ELSE
274      WRITE(lunout, *)'Je m''arrete'
275      CALL abort
276    ENDIF
277  ENDIF
278  IF (raz_date == 1) THEN
279    annee_ref = anneeref
280    day_ref = dayref
281    day_ini = dayref
282    itau_dyn = 0
283    itau_phy = 0
284    time_0 = 0.
285    WRITE(lunout, *) &
286            'GCM: On reinitialise a la date lue dans gcm.def'
287  ELSE IF (annee_ref /= anneeref .OR. day_ref /= dayref) THEN
288    WRITE(lunout, *) &
289            'GCM: Attention les dates initiales lues dans le fichier'
290    WRITE(lunout, *) &
291            ' restart ne correspondent pas a celles lues dans '
292    WRITE(lunout, *)' gcm.def'
293    WRITE(lunout, *)' annee_ref=', annee_ref, " anneeref=", anneeref
294    WRITE(lunout, *)' day_ref=', day_ref, " dayref=", dayref
295    WRITE(lunout, *)' Pas de remise a zero'
296  ENDIF
297  !      if (annee_ref .NE. anneeref .OR. day_ref .NE. dayref) THEN
298  !        WRITE(lunout,*)
299  !     .  'GCM: Attention les dates initiales lues dans le fichier'
300  !        WRITE(lunout,*)
301  !     .  ' restart ne correspondent pas a celles lues dans '
302  !        WRITE(lunout,*)' gcm.def'
303  !        WRITE(lunout,*)' annee_ref=',annee_ref," anneeref=",anneeref
304  !        WRITE(lunout,*)' day_ref=',day_ref," dayref=",dayref
305  !        if (raz_date .NE. 1) THEN
306  !          WRITE(lunout,*)
307  !     .    'GCM: On garde les dates du fichier restart'
308  !        else
309  !          annee_ref = anneeref
310  !          day_ref = dayref
311  !          day_ini = dayref
312  !          itau_dyn = 0
313  !          itau_phy = 0
314  !          time_0 = 0.
315  !          WRITE(lunout,*)
316  !     .   'GCM: On reinitialise a la date lue dans gcm.def'
317  !        endif
318  !      ELSE
319  !        raz_date = 0
320  !      endif
321
322  mois = 1
323  heure = 0.
324  CALL ymds2ju(annee_ref, mois, day_ref, heure, jD_ref)
325  jH_ref = jD_ref - int(jD_ref)
326  jD_ref = int(jD_ref)
327
328  CALL ioconf_startdate(INT(jD_ref), jH_ref)
329
330  WRITE(lunout, *)'DEBUG'
331  WRITE(lunout, *)'annee_ref, mois, day_ref, heure, jD_ref'
332  WRITE(lunout, *)annee_ref, mois, day_ref, heure, jD_ref
333  CALL ju2ymds(jD_ref + jH_ref, anref, moisref, jourref, heureref)
334  WRITE(lunout, *)'jD_ref+jH_ref,an, mois, jour, heure'
335  WRITE(lunout, *)jD_ref + jH_ref, anref, moisref, jourref, heureref
336
337  IF (iflag_phys==1) THEN
338    ! these initialisations have already been done (via iniacademic)
339    ! if running in SW or Newtonian mode
340    !-----------------------------------------------------------------------
341    !   Initialisation des constantes dynamiques :
342    !   ------------------------------------------
343    dtvr = zdtvr
344    CALL iniconst
345
346    !-----------------------------------------------------------------------
347    !   Initialisation de la geometrie :
348    !   --------------------------------
349    CALL inigeom
350
351    !-----------------------------------------------------------------------
352    !   Initialisation du filtre :
353    !   --------------------------
354    CALL inifilr
355  ENDIF ! of if (iflag_phys.EQ.1)
356
357  !-----------------------------------------------------------------------
358  !   Initialisation de la dissipation :
359  !   ----------------------------------
360
361  CALL inidissip(lstardis, nitergdiv, nitergrot, niterh, &
362          tetagdiv, tetagrot, tetatemp, vert_prof_dissip)
363
364  !-----------------------------------------------------------------------
365  !   Initialisation des I/O :
366  !   ------------------------
367
368  IF (nday>=0) THEN
369    day_end = day_ini + nday
370  else
371    day_end = day_ini - nday / day_step
372  ENDIF
373
374  WRITE(lunout, 300)day_ini, day_end
375  300 FORMAT('1'/, 15x, 'run du jour', i7, 2x, 'au jour', i7//)
376
377  CALL ju2ymds(jD_ref + day_ini - day_ref, an, mois, jour, heure)
378  write (lunout, 301)jour, mois, an
379  CALL ju2ymds(jD_ref + day_end - day_ref, an, mois, jour, heure)
380  write (lunout, 302)jour, mois, an
381  301 FORMAT('1'/, 15x, 'run du ', i2, '/', i2, '/', i4)
382  302 FORMAT('1'/, 15x, '    au ', i2, '/', i2, '/', i4)
383
384  !-----------------------------------------------------------------------
385  !   Initialisation de la physique :
386  !   -------------------------------
387
388  !  Choix des frequences de stokage pour le offline
389  !      istdyn=day_step/4     ! stockage toutes les 6h=1jour/4
390  !      istdyn=day_step/12     ! stockage toutes les 2h=1jour/12
391  istdyn = day_step / 8     ! stockage toutes les 6h=1jour/12
392  istphy = istdyn / iphysiq
393
394  IF ((iflag_phys==1).OR.(iflag_phys>=100)) THEN
395    ! Physics:
396    IF (CPPKEY_PHYS) THEN
397      CALL iniphysiq(iim, jjm, llm, &
398              distrib_phys(mpi_rank), comm_lmdz, &
399              daysec, day_ini, dtphys / nsplit_phys, &
400              rlatu, rlatv, rlonu, rlonv, aire, cu, cv, rad, g, r, cpp, &
401              iflag_phys)
402    END IF
403  ENDIF ! of IF ((iflag_phys==1).OR.(iflag_phys>=100))
404
405
406  !      if (planet_type.EQ."earth") THEN
407  ! Write an Earth-format restart file
408  CALL dynredem0_loc("restart.nc", day_end, phis)
409  !      endif
410
411  ecripar = .TRUE.
412
413  time_step = zdtvr
414  IF (ok_dyn_ins) THEN
415    ! initialize output file for instantaneous outputs
416    ! t_ops = iecri * daysec ! do operations every t_ops
417    t_ops = ((1.0 * iecri) / day_step) * daysec
418    t_wrt = daysec ! iecri * daysec ! write output every t_wrt
419    CALL inithist_loc(day_ref, annee_ref, time_step, &
420            t_ops, t_wrt)
421  endif
422
423  IF (ok_dyn_ave) THEN
424    ! initialize output file for averaged outputs
425    t_ops = iperiod * time_step ! do operations every t_ops
426    t_wrt = periodav * daysec   ! write output every t_wrt
427    CALL initdynav_loc(day_ref, annee_ref, time_step, t_ops, t_wrt)
428  END IF
429  dtav = iperiod * dtvr / daysec
430
431  ! setting up DYN3D/XIOS inerface
432  IF (ok_dyn_xios) THEN
433    CALL xios_dyn3dmem_init(xios_cal_type, anref, moisref, jourref, heureref, an, &
434            mois, jour, heure, zdtvr)
435  ENDIF
436
437  !-----------------------------------------------------------------------
438  !   Integration temporelle du modele :
439  !   ----------------------------------
440
441  !       WRITE(78,*) 'ucov',ucov
442  !       WRITE(78,*) 'vcov',vcov
443  !       WRITE(78,*) 'teta',teta
444  !       WRITE(78,*) 'ps',ps
445  !       WRITE(78,*) 'q',q
446
447  !!$OMP PARALLEL DEFAULT(SHARED) COPYIN(/temps/,/logici/,/logicl/)
448  !     Copy all threadprivate variables in temps_mod logic_mod
449  !$OMP PARALLEL DEFAULT(SHARED) &
450  !$OMP COPYIN(dt,jD_ref,jH_ref,start_time,hour_ini,day_ini,day_end) &
451  !$OMP COPYIN(annee_ref,day_ref,itau_dyn,itau_phy,itaufin,calend) &
452  !$OMP COPYIN(purmats,forward,leapf,apphys,statcl,conser,apdiss,apdelq) &
453  !$OMP COPYIN(saison,ecripar,fxyhypb,ysinus,read_start,ok_guide) &
454  !$OMP COPYIN(ok_strato,ok_gradsfile,ok_limit,ok_etat0) &
455  !$OMP COPYIN(iflag_phys,iflag_trac,adv_qsat_liq)
456  CALL leapfrog_loc(ucov, vcov, teta, ps, masse, phis, q, time_0)
457  !$OMP END PARALLEL
458
459  !      OPEN(unit=5487,file='ok_lmdz',status='replace')
460  !      WRITE(5487,*) 'ok_lmdz'
461  !      CLOSE(5487)
462END PROGRAM gcm
Note: See TracBrowser for help on using the repository browser.