/[lmdze]/trunk/dyn3d/leapfrog.f90
ViewVC logotype

Diff of /trunk/dyn3d/leapfrog.f90

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

trunk/libf/dyn3d/leapfrog.f90 revision 71 by guez, Mon Jul 8 18:12:18 2013 UTC trunk/dyn3d/leapfrog.f revision 313 by guez, Mon Dec 10 15:54:30 2018 UTC
# Line 4  module leapfrog_m Line 4  module leapfrog_m
4    
5  contains  contains
6    
7    SUBROUTINE leapfrog(ucov, vcov, teta, ps, masse, phis, q, time_0)    SUBROUTINE leapfrog(ucov, vcov, teta, ps, masse, phis, q)
8    
9      ! From dyn3d/leapfrog.F, version 1.6, 2005/04/13 08:58:34 revision 616      ! From dyn3d/leapfrog.F, version 1.6, 2005/04/13 08:58:34 revision 616
10      ! Authors: P. Le Van, L. Fairhead, F. Hourdin      ! Authors: P. Le Van, L. Fairhead, F. Hourdin
11      ! Matsuno-leapfrog scheme.  
12        ! Int\'egration temporelle du mod\`ele : Matsuno-leapfrog scheme.
13    
14      use addfi_m, only: addfi      use addfi_m, only: addfi
15      use bilan_dyn_m, only: bilan_dyn      use bilan_dyn_m, only: bilan_dyn
16      use caladvtrac_m, only: caladvtrac      use caladvtrac_m, only: caladvtrac
17      use caldyn_m, only: caldyn      use caldyn_m, only: caldyn
18      USE calfis_m, ONLY: calfis      USE calfis_m, ONLY: calfis
19      USE comconst, ONLY: daysec, dtphys, dtvr      USE comconst, ONLY: dtvr
20      USE comgeom, ONLY: aire_2d, apoln, apols      USE comgeom, ONLY: aire_2d, apoln, apols
21        use covcont_m, only: covcont
22      USE disvert_m, ONLY: ap, bp      USE disvert_m, ONLY: ap, bp
23      USE conf_gcm_m, ONLY: day_step, iconser, iperiod, iphysiq, nday, offline, &      USE conf_gcm_m, ONLY: day_step, iconser, iperiod, iphysiq, nday, iflag_phys
24           iflag_phys, ok_guide, iecri      USE conf_guide_m, ONLY: ok_guide
25      USE dimens_m, ONLY: iim, jjm, llm, nqmx      USE dimensions, ONLY: iim, jjm, llm, nqmx
26      use dissip_m, only: dissip      use dissip_m, only: dissip
27      USE dynetat0_m, ONLY: day_ini      USE dynetat0_m, ONLY: day_ini, itau_dyn
28      use dynredem1_m, only: dynredem1      use dynredem1_m, only: dynredem1
29        use enercin_m, only: enercin
30      USE exner_hyb_m, ONLY: exner_hyb      USE exner_hyb_m, ONLY: exner_hyb
31      use filtreg_m, only: filtreg      use filtreg_scal_m, only: filtreg_scal
     use fluxstokenc_m, only: fluxstokenc  
32      use geopot_m, only: geopot      use geopot_m, only: geopot
33      USE guide_m, ONLY: guide      USE guide_m, ONLY: guide
34      use inidissip_m, only: idissip      use inidissip_m, only: idissip
35      use integrd_m, only: integrd      use integrd_m, only: integrd
36      use nr_util, only: assert      use nr_util, only: assert
     USE pressure_var, ONLY: p3d  
     USE temps, ONLY: itau_dyn  
     use writedynav_m, only: writedynav  
37      use writehist_m, only: writehist      use writehist_m, only: writehist
38    
39      ! Variables dynamiques:      ! Variables dynamiques:
# Line 51  contains Line 50  contains
50      REAL, intent(inout):: q(:, :, :, :) ! (iim + 1, jjm + 1, llm, nqmx)      REAL, intent(inout):: q(:, :, :, :) ! (iim + 1, jjm + 1, llm, nqmx)
51      ! mass fractions of advected fields      ! mass fractions of advected fields
52    
53      REAL, intent(in):: time_0      ! Local:
   
     ! Variables local to the procedure:  
54    
55      ! Variables dynamiques:      ! Variables dynamiques:
56    
57      REAL pks(iim + 1, jjm + 1) ! exner au sol      REAL pks(iim + 1, jjm + 1) ! exner au sol
58      REAL pk(iim + 1, jjm + 1, llm) ! exner au milieu des couches      REAL pk(iim + 1, jjm + 1, llm) ! exner au milieu des couches
59      REAL pkf(iim + 1, jjm + 1, llm) ! exner filtré au milieu des couches      REAL pkf(iim + 1, jjm + 1, llm) ! exner filtr\'e au milieu des couches
60      REAL phi(iim + 1, jjm + 1, llm) ! geopotential      REAL phi(iim + 1, jjm + 1, llm) ! geopotential
61      REAL w((iim + 1) * (jjm + 1), llm) ! vitesse verticale      REAL w(iim + 1, jjm + 1, llm) ! vitesse verticale
62    
63      ! Variables dynamiques intermediaire pour le transport      ! Variables dynamiques interm\'ediaires pour le transport
64      ! Flux de masse :      ! Flux de masse :
65      REAL pbaru((iim + 1) * (jjm + 1), llm), pbarv((iim + 1) * jjm, llm)      REAL pbaru(iim + 1, jjm + 1, llm), pbarv(iim + 1, jjm, llm)
66    
67      ! Variables dynamiques au pas - 1      ! Variables dynamiques au pas - 1
68      REAL vcovm1(iim + 1, jjm, llm), ucovm1(iim + 1, jjm + 1, llm)      REAL vcovm1(iim + 1, jjm, llm), ucovm1(iim + 1, jjm + 1, llm)
# Line 73  contains Line 70  contains
70      REAL massem1(iim + 1, jjm + 1, llm)      REAL massem1(iim + 1, jjm + 1, llm)
71    
72      ! Tendances dynamiques      ! Tendances dynamiques
73      REAL dv((iim + 1) * jjm, llm), dudyn((iim + 1) * (jjm + 1), llm)      REAL dv((iim + 1) * jjm, llm), du(iim + 1, jjm + 1, llm)
74      REAL dteta(iim + 1, jjm + 1, llm)      REAL dteta(iim + 1, jjm + 1, llm)
75      real dp((iim + 1) * (jjm + 1))      real dp(iim + 1, jjm + 1)
76    
77      ! Tendances de la dissipation :      ! Tendances de la dissipation :
78      REAL dvdis(iim + 1, jjm, llm), dudis(iim + 1, jjm + 1, llm)      REAL dvdis(iim + 1, jjm, llm), dudis(iim + 1, jjm + 1, llm)
79      REAL dtetadis(iim + 1, jjm + 1, llm)      REAL dtetadis(iim + 1, jjm + 1, llm)
80    
81      ! Tendances physiques      ! Tendances physiques
82      REAL dvfi((iim + 1) * jjm, llm), dufi((iim + 1) * (jjm + 1), llm)      REAL dvfi(iim + 1, jjm, llm), dufi(iim + 1, jjm + 1, llm)
83      REAL dtetafi(iim + 1, jjm + 1, llm), dqfi((iim + 1) * (jjm + 1), llm, nqmx)      REAL dtetafi(iim + 1, jjm + 1, llm), dqfi(iim + 1, jjm + 1, llm, nqmx)
     real dpfi((iim + 1) * (jjm + 1))  
84    
85      ! Variables pour le fichier histoire      ! Variables pour le fichier histoire
   
86      INTEGER itau ! index of the time step of the dynamics, starts at 0      INTEGER itau ! index of the time step of the dynamics, starts at 0
87      INTEGER itaufin      INTEGER itaufin
     REAL time ! time of day, as a fraction of day length  
     real finvmaold(iim + 1, jjm + 1, llm)  
88      INTEGER l      INTEGER l
     REAL rdayvrai, rdaym_ini  
89    
90      ! Variables test conservation énergie      ! Variables test conservation \'energie
91      REAL ecin(iim + 1, jjm + 1, llm), ecin0(iim + 1, jjm + 1, llm)      REAL ecin(iim + 1, jjm + 1, llm), ecin0(iim + 1, jjm + 1, llm)
92    
93      REAL vcont((iim + 1) * jjm, llm), ucont((iim + 1) * (jjm + 1), llm)      REAL vcont((iim + 1) * jjm, llm), ucont((iim + 1) * (jjm + 1), llm)
94      logical leapf      logical leapf
95      real dt      real dt ! time step, in s
96    
97        REAL p3d(iim + 1, jjm + 1, llm + 1) ! pressure at layer interfaces, in Pa
98        ! ("p3d(i, j, l)" is at longitude "rlonv(i)", latitude "rlatu(j)",
99        ! for interface "l")
100    
101      !---------------------------------------------------      !---------------------------------------------------
102    
# Line 112  contains Line 108  contains
108    
109      ! On initialise la pression et la fonction d'Exner :      ! On initialise la pression et la fonction d'Exner :
110      forall (l = 1: llm + 1) p3d(:, :, l) = ap(l) + bp(l) * ps      forall (l = 1: llm + 1) p3d(:, :, l) = ap(l) + bp(l) * ps
111      CALL exner_hyb(ps, p3d, pks, pk, pkf)      CALL exner_hyb(ps, p3d, pks, pk)
112        pkf = pk
113        CALL filtreg_scal(pkf, direct = .true., intensive = .true.)
114    
115      time_integration: do itau = 0, itaufin - 1      time_integration: do itau = 0, itaufin - 1
116         leapf = mod(itau, iperiod) /= 0         leapf = mod(itau, iperiod) /= 0
117          
118         if (leapf) then         if (leapf) then
119            dt = 2 * dtvr            dt = 2 * dtvr
120         else         else
121            ! Matsuno            ! Matsuno
122            dt = dtvr            dt = dtvr
123            if (ok_guide .and. (itaufin - itau - 1) * dtvr > 21600.) &            if (ok_guide) call guide(itau, ucov, vcov, teta, q(:, :, :, 1), ps)
                call guide(itau, ucov, vcov, teta, q, masse, ps)  
124            vcovm1 = vcov            vcovm1 = vcov
125            ucovm1 = ucov            ucovm1 = ucov
126            tetam1 = teta            tetam1 = teta
127            massem1 = masse            massem1 = masse
128            psm1 = ps            psm1 = ps
           finvmaold = masse  
           CALL filtreg(finvmaold, jjm + 1, llm, - 2, 2, .TRUE.)  
129         end if         end if
130    
131         ! Calcul des tendances dynamiques:         ! Calcul des tendances dynamiques:
132         CALL geopot(teta, pk, pks, phis, phi)         CALL geopot(teta, pk, pks, phis, phi)
133         CALL caldyn(itau, ucov, vcov, teta, ps, masse, pk, pkf, phis, phi, &         CALL caldyn(itau, ucov, vcov, teta, ps, masse, pk, pkf, phis, phi, du, &
134              dudyn, dv, dteta, dp, w, pbaru, pbarv, time_0, &              dv, dteta, dp, w, pbaru, pbarv, conser = MOD(itau, iconser) == 0)
             conser=MOD(itau, iconser)==0)  
135    
136         CALL caladvtrac(q, pbaru, pbarv, p3d, masse, teta, pk)         CALL caladvtrac(q, pbaru, pbarv, p3d, masse, teta, pk)
137    
138         ! Stokage du flux de masse pour traceurs offline:         ! Int\'egrations dynamique et traceurs:
139         IF (offline) CALL fluxstokenc(pbaru, pbarv, masse, teta, phi, phis, &         CALL integrd(vcovm1, ucovm1, tetam1, psm1, massem1, dv, du, dteta, dp, &
140              dtvr, itau)              vcov, ucov, teta, q(:, :, :, :2), ps, masse, dt, leapf)
141    
142         ! Intégrations dynamique et traceurs:         forall (l = 1: llm + 1) p3d(:, :, l) = ap(l) + bp(l) * ps
143         CALL integrd(vcovm1, ucovm1, tetam1, psm1, massem1, dv, dudyn, dteta, &         CALL exner_hyb(ps, p3d, pks, pk)
144              dp, vcov, ucov, teta, q(:, :, :, :2), ps, masse, finvmaold, dt, &         pkf = pk
145              leapf)         CALL filtreg_scal(pkf, direct = .true., intensive = .true.)
146    
147         if (.not. leapf) then         if (.not. leapf) then
148            ! Matsuno backward            ! Matsuno backward
           forall (l = 1: llm + 1) p3d(:, :, l) = ap(l) + bp(l) * ps  
           CALL exner_hyb(ps, p3d, pks, pk, pkf)  
   
149            ! Calcul des tendances dynamiques:            ! Calcul des tendances dynamiques:
150            CALL geopot(teta, pk, pks, phis, phi)            CALL geopot(teta, pk, pks, phis, phi)
151            CALL caldyn(itau + 1, ucov, vcov, teta, ps, masse, pk, pkf, phis, &            CALL caldyn(itau + 1, ucov, vcov, teta, ps, masse, pk, pkf, phis, &
152                 phi, dudyn, dv, dteta, dp, w, pbaru, pbarv, time_0, &                 phi, du, dv, dteta, dp, w, pbaru, pbarv, conser = .false.)
                conser=.false.)  
153    
154            ! integrations dynamique et traceurs:            ! integrations dynamique et traceurs:
155            CALL integrd(vcovm1, ucovm1, tetam1, psm1, massem1, dv, dudyn, &            CALL integrd(vcovm1, ucovm1, tetam1, psm1, massem1, dv, du, dteta, &
156                 dteta, dp, vcov, ucov, teta, q(:, :, :, :2), ps, masse, &                 dp, vcov, ucov, teta, q(:, :, :, :2), ps, masse, dtvr, &
157                 finvmaold, dtvr, leapf=.false.)                 leapf=.false.)
        end if  
   
        IF (MOD(itau + 1, iphysiq) == 0 .AND. iflag_phys /= 0) THEN  
           ! Calcul des tendances physiques:  
158    
159            forall (l = 1: llm + 1) p3d(:, :, l) = ap(l) + bp(l) * ps            forall (l = 1: llm + 1) p3d(:, :, l) = ap(l) + bp(l) * ps
160            CALL exner_hyb(ps, p3d, pks, pk, pkf)            CALL exner_hyb(ps, p3d, pks, pk)
161              pkf = pk
162            rdaym_ini = itau * dtvr / daysec            CALL filtreg_scal(pkf, direct = .true., intensive = .true.)
163            rdayvrai = rdaym_ini + day_ini         end if
           time = REAL(mod(itau, day_step)) / day_step + time_0  
           IF (time > 1.) time = time - 1.  
164    
165            CALL calfis(rdayvrai, time, ucov, vcov, teta, q, ps, pk, phis, phi, &         IF (MOD(itau + 1, iphysiq) == 0 .AND. iflag_phys) THEN
166                 dudyn, dv, w, dufi, dvfi, dtetafi, dqfi, dpfi, &            CALL calfis(ucov, vcov, teta, q, p3d, pk, phis, phi, w, dufi, dvfi, &
167                   dtetafi, dqfi, dayvrai = itau / day_step + day_ini, &
168                   time = REAL(mod(itau, day_step)) / day_step, &
169                 lafin = itau + 1 == itaufin)                 lafin = itau + 1 == itaufin)
170    
171            ! Ajout des tendances physiques:            CALL addfi(ucov, vcov, teta, q, dufi, dvfi, dtetafi, dqfi)
           CALL addfi(ucov, vcov, teta, q, ps, dufi, dvfi, dtetafi, dqfi, dpfi)  
172         ENDIF         ENDIF
173    
        forall (l = 1: llm + 1) p3d(:, :, l) = ap(l) + bp(l) * ps  
        CALL exner_hyb(ps, p3d, pks, pk, pkf)  
   
174         IF (MOD(itau + 1, idissip) == 0) THEN         IF (MOD(itau + 1, idissip) == 0) THEN
175            ! Dissipation horizontale et verticale des petites échelles            ! Dissipation horizontale et verticale des petites \'echelles
176    
177            ! calcul de l'énergie cinétique avant dissipation            ! calcul de l'\'energie cin\'etique avant dissipation
178            call covcont(llm, ucov, vcov, ucont, vcont)            call covcont(llm, ucov, vcov, ucont, vcont)
179            call enercin(vcov, ucov, vcont, ucont, ecin0)            call enercin(vcov, ucov, vcont, ucont, ecin0)
180    
# Line 200  contains Line 183  contains
183            ucov = ucov + dudis            ucov = ucov + dudis
184            vcov = vcov + dvdis            vcov = vcov + dvdis
185    
186            ! On ajoute la tendance due à la transformation énergie            ! On ajoute la tendance due \`a la transformation \'energie
187            ! cinétique en énergie thermique par la dissipation            ! cin\'etique en \'energie thermique par la dissipation
188            call covcont(llm, ucov, vcov, ucont, vcont)            call covcont(llm, ucov, vcov, ucont, vcont)
189            call enercin(vcov, ucov, vcont, ucont, ecin)            call enercin(vcov, ucov, vcont, ucont, ecin)
190            dtetadis = dtetadis + (ecin0 - ecin) / pk            dtetadis = dtetadis + (ecin0 - ecin) / pk
191            teta = teta + dtetadis            teta = teta + dtetadis
192    
193            ! Calcul de la valeur moyenne aux pôles :            ! Calcul de la valeur moyenne aux p\^oles :
194            forall (l = 1: llm)            forall (l = 1: llm)
195               teta(:, 1, l) = SUM(aire_2d(:iim, 1) * teta(:iim, 1, l)) &               teta(:, 1, l) = SUM(aire_2d(:iim, 1) * teta(:iim, 1, l)) / apoln
196                    / apoln               teta(:, jjm + 1, l) = SUM(aire_2d(:iim, jjm + 1) &
              teta(:, jjm + 1, l) = SUM(aire_2d(:iim, jjm+1) &  
197                    * teta(:iim, jjm + 1, l)) / apols                    * teta(:iim, jjm + 1, l)) / apols
198            END forall            END forall
   
           ps(:, 1) = SUM(aire_2d(:iim, 1) * ps(:iim, 1)) / apoln  
           ps(:, jjm + 1) = SUM(aire_2d(:iim, jjm+1) * ps(:iim, jjm + 1)) &  
                / apols  
199         END IF         END IF
200    
201         IF (MOD(itau + 1, iperiod) == 0) THEN         IF (MOD(itau + 1, iperiod) == 0) THEN
           ! Écriture du fichier histoire moyenne:  
           CALL writedynav(vcov, ucov, teta, pk, phi, q, masse, ps, phis, &  
                time = itau + 1)  
202            call bilan_dyn(ps, masse, pk, pbaru, pbarv, teta, phi, ucov, vcov, &            call bilan_dyn(ps, masse, pk, pbaru, pbarv, teta, phi, ucov, vcov, &
203                 q(:, :, :, 1))                 q(:, :, :, 1))
204         ENDIF         ENDIF
205    
206         IF (MOD(itau + 1, iecri * day_step) == 0) THEN         CALL geopot(teta, pk, pks, phis, phi)
207            CALL geopot(teta, pk, pks, phis, phi)         CALL writehist(vcov, ucov, teta, pk, phi, q, masse, ps, &
208            CALL writehist(itau, vcov, ucov, teta, phi, q, masse, ps)              itau_w = itau_dyn + itau + 1)
        END IF  
209      end do time_integration      end do time_integration
210    
211      CALL dynredem1("restart.nc", vcov, ucov, teta, q, masse, ps, &      CALL dynredem1(vcov, ucov, teta, q, masse, ps, itau = itau_dyn + itaufin)
          itau = itau_dyn + itaufin)  
212    
213      ! Calcul des tendances dynamiques:      ! Calcul des tendances dynamiques:
214      CALL geopot(teta, pk, pks, phis, phi)      CALL geopot(teta, pk, pks, phis, phi)
215      CALL caldyn(itaufin, ucov, vcov, teta, ps, masse, pk, pkf, phis, phi, &      CALL caldyn(itaufin, ucov, vcov, teta, ps, masse, pk, pkf, phis, phi, du, &
216           dudyn, dv, dteta, dp, w, pbaru, pbarv, time_0, &           dv, dteta, dp, w, pbaru, pbarv, conser = MOD(itaufin, iconser) == 0)
          conser = MOD(itaufin, iconser) == 0)  
217    
218    END SUBROUTINE leapfrog    END SUBROUTINE leapfrog
219    

Legend:
Removed from v.71  
changed lines
  Added in v.313

  ViewVC Help
Powered by ViewVC 1.1.21