source: LMDZ4/branches/LMDZ4-dev/libf/dyn3dpar/gcm.F @ 1229

Last change on this file since 1229 was 1222, checked in by Ehouarn Millour, 15 years ago

Changes and cleanups to enable compiling without physics
and without ioipsl.

IOIPSL related cleanups:

  • bibio/writehist.F encapsulate the routine (which needs IOIPSL to function)

with #ifdef IOIPSL flag.

  • dyn3d/abort_gcm.F, dyn3dpar/abort_gcm.F and dyn3dpar/getparam.F90: use ioipsl_getincom module when not compiling with IOIPSL library, in order to always be able to use getin() routine.
  • removed unused "use IOIPSL" in dyn3dpar/guide_p_mod.F90
  • calendar related issue: Initialize day_ref and annee_ref in iniacademic.F (i.e. when they are not read from start.nc file)

Earth-specific programs/routines/modules:
create_etat0.F, fluxstokenc.F, limit_netcdf.F, startvar.F
(versions in dyn3d and dyn3dpar)
These routines and modules, which by design and porpose are made to function with
Earth physics are encapsulated with #CPP_EARTH cpp flag.

Earth-specific instructions:

  • calls to qminimum (specific treatment of first 2 tracers, i.e. water) in dyn3d/caladvtrac.F, dyn3d/integrd.F, dyn3dpar/caladvtrac_p.F, dyn3dpar/integrd_p.F only if (planet_type == 'earth')

Interaction with parallel physics:

  • routine dyn3dpar/parallel.F90 uses "surface_data" module (which is in the physics ...) to know value of "type_ocean" . Encapsulated that with #ifdef CPP_EARTH and set to a default type_ocean="dummy" otherwise.
  • So far, only Earth physics are parallelized, so all the interaction between parallel dynamics and parallel physics are encapsulated with #ifdef CCP_EARTH (this way we can run parallel without any physics). The (dyn3dpar) routines which contains such interaction are: bands.F90, gr_dyn_fi_p.F, gr_fi_dyn_p.F, mod_interface_dyn_phys.F90 This should later (when improving dyn/phys interface) be encapsulated with a more general and appropriate #ifdef CPP_PHYS cpp flag.

I checked that these changes do not alter results (on the simple
32x24x11 bench) on Ciclad (seq & mpi), Brodie (seq, mpi & omp) and
Vargas (seq, mpi & omp).

EM

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