source: trunk/LMDZ.COMMON/libf/dyn3d/integrd.F @ 3553

Last change on this file since 3553 was 2126, checked in by emillour, 6 years ago

Common dynamics:
Some work to enforce total tracer mass conservation in the dynamics.
Still to be further studied and validated.
For now these changes are triggered by setting a "force_conserv_tracer"
flag to ".true." in run.def (default is ".false." to not change anything
with respect to previous versions).
When force_conserv_tracer=.true. then:

  1. Rescale tracer mass in caladvtrac after tracer advection computations
  2. Recompute q ratios once atmospheric mass has been updated in integrd

These steps technically ensure total tracer mass conservation but it
might be the tracer advection scheme and/or time-stepping updating
sequence of fields that should be rethought or fixed.
EM

File size: 7.6 KB
RevLine 
[1]1!
[776]2! $Id: integrd.F 1616 2012-02-17 11:59:00Z emillour $
[1]3!
4      SUBROUTINE integrd
5     $  (  nq,vcovm1,ucovm1,tetam1,psm1,massem1,
[776]6     $     dv,du,dteta,dq,dp,vcov,ucov,teta,q,ps,masse,phis !,finvmaold
7     &  )
[1]8
[2126]9      use control_mod, only : planet_type,force_conserv_tracer
[1422]10      USE comvert_mod, ONLY: ap,bp
11      USE comconst_mod, ONLY: pi
12      USE logic_mod, ONLY: leapf
13      USE temps_mod, ONLY: dt
[1]14
15      IMPLICIT NONE
16
17
18c=======================================================================
19c
20c   Auteur:  P. Le Van
21c   -------
22c
23c   objet:
24c   ------
25c
26c   Incrementation des tendances dynamiques
27c
28c=======================================================================
29c-----------------------------------------------------------------------
30c   Declarations:
31c   -------------
32
33#include "dimensions.h"
34#include "paramet.h"
35#include "comgeom.h"
[776]36#include "iniprint.h"
[1]37
38c   Arguments:
39c   ----------
40
[776]41      integer,intent(in) :: nq ! number of tracers to handle in this routine
42      real,intent(inout) :: vcov(ip1jm,llm) ! covariant meridional wind
43      real,intent(inout) :: ucov(ip1jmp1,llm) ! covariant zonal wind
44      real,intent(inout) :: teta(ip1jmp1,llm) ! potential temperature
45      real,intent(inout) :: q(ip1jmp1,llm,nq) ! advected tracers
46      real,intent(inout) :: ps(ip1jmp1) ! surface pressure
47      real,intent(inout) :: masse(ip1jmp1,llm) ! atmospheric mass
48      real,intent(in) :: phis(ip1jmp1) ! ground geopotential !!! unused
49      ! values at previous time step
50      real,intent(inout) :: vcovm1(ip1jm,llm)
51      real,intent(inout) :: ucovm1(ip1jmp1,llm)
52      real,intent(inout) :: tetam1(ip1jmp1,llm)
53      real,intent(inout) :: psm1(ip1jmp1)
54      real,intent(inout) :: massem1(ip1jmp1,llm)
55      ! the tendencies to add
56      real,intent(in) :: dv(ip1jm,llm)
57      real,intent(in) :: du(ip1jmp1,llm)
58      real,intent(in) :: dteta(ip1jmp1,llm)
59      real,intent(in) :: dp(ip1jmp1)
60      real,intent(in) :: dq(ip1jmp1,llm,nq) !!! unused
61!      real,intent(out) :: finvmaold(ip1jmp1,llm) !!! unused
[1]62
63c   Local:
64c   ------
65
66      REAL vscr( ip1jm ),uscr( ip1jmp1 ),hscr( ip1jmp1 ),pscr(ip1jmp1)
[776]67      REAL massescr( ip1jmp1,llm )
[2126]68      REAL :: massratio(ip1jmp1,llm)
[776]69!      REAL finvmasse(ip1jmp1,llm)
[1]70      REAL p(ip1jmp1,llmp1)
71      REAL tpn,tps,tppn(iim),tpps(iim)
72      REAL qpn,qps,qppn(iim),qpps(iim)
73      REAL deltap( ip1jmp1,llm )
74
[776]75      INTEGER  l,ij,iq,i,j
[1]76
77      REAL SSUM
78
79c-----------------------------------------------------------------------
80
81      DO  l = 1,llm
82        DO  ij = 1,iip1
83         ucov(    ij    , l) = 0.
84         ucov( ij +ip1jm, l) = 0.
85         uscr(     ij      ) = 0.
86         uscr( ij +ip1jm   ) = 0.
87        ENDDO
88      ENDDO
89
90
91c    ............    integration  de       ps         ..............
92
93      CALL SCOPY(ip1jmp1*llm, masse, 1, massescr, 1)
94
[7]95      DO ij = 1,ip1jmp1
[1]96       pscr (ij)    = ps(ij)
97       ps (ij)      = psm1(ij) + dt * dp(ij)
[7]98      ENDDO
[1]99c
100      DO ij = 1,ip1jmp1
101        IF( ps(ij).LT.0. ) THEN
[776]102         write(lunout,*) "integrd: negative surface pressure ",ps(ij)
103         write(lunout,*) " at node ij =", ij
104         ! since ij=j+(i-1)*jjp1 , we have
105         j=modulo(ij,jjp1)
106         i=1+(ij-j)/jjp1
107         write(lunout,*) " lon = ",rlonv(i)*180./pi, " deg",
108     &                   " lat = ",rlatu(j)*180./pi, " deg"
[907]109         write(lunout,*) " psm1(ij)=",psm1(ij)," dt=",dt,
110     &                   " dp(ij)=",dp(ij)
[1391]111         call abort_gcm("integrd", "", 1)
[1]112        ENDIF
113      ENDDO
114c
115      DO  ij    = 1, iim
116       tppn(ij) = aire(   ij   ) * ps(  ij    )
117       tpps(ij) = aire(ij+ip1jm) * ps(ij+ip1jm)
118      ENDDO
119       tpn      = SSUM(iim,tppn,1)/apoln
120       tps      = SSUM(iim,tpps,1)/apols
121      DO ij   = 1, iip1
122       ps(   ij   )  = tpn
123       ps(ij+ip1jm)  = tps
124      ENDDO
125c
126c  ... Calcul  de la nouvelle masse d'air au dernier temps integre t+1 ...
127c
128      CALL pression ( ip1jmp1, ap, bp, ps, p )
129      CALL massdair (     p  , masse         )
130
[776]131! Ehouarn : we don't use/need finvmaold and finvmasse,
132!           so might as well not compute them
133!      CALL   SCOPY( ijp1llm  , masse, 1, finvmasse,  1      )
134!      CALL filtreg( finvmasse, jjp1, llm, -2, 2, .TRUE., 1  )
[1]135c
136
137c    ............   integration  de  ucov, vcov,  h     ..............
138
[7]139      DO l = 1,llm
[1]140
[7]141       DO ij = iip2,ip1jm
142        uscr( ij )   =  ucov( ij,l )
143        ucov( ij,l ) = ucovm1( ij,l ) + dt * du( ij,l )
144       ENDDO
[1]145
[7]146       DO ij = 1,ip1jm
147        vscr( ij )   =  vcov( ij,l )
148        vcov( ij,l ) = vcovm1( ij,l ) + dt * dv( ij,l )
149       ENDDO
[1]150
[7]151       DO ij = 1,ip1jmp1
152        hscr( ij )    =  teta(ij,l)
153        teta ( ij,l ) = tetam1(ij,l) *  massem1(ij,l) / masse(ij,l)
154     &                + dt * dteta(ij,l) / masse(ij,l)
155       ENDDO
[1]156
157c   ....  Calcul de la valeur moyenne, unique  aux poles pour  teta    ......
158c
159c
[7]160       DO  ij   = 1, iim
[1]161        tppn(ij) = aire(   ij   ) * teta(  ij    ,l)
162        tpps(ij) = aire(ij+ip1jm) * teta(ij+ip1jm,l)
[7]163       ENDDO
[1]164        tpn      = SSUM(iim,tppn,1)/apoln
165        tps      = SSUM(iim,tpps,1)/apols
166
[7]167       DO ij   = 1, iip1
[1]168        teta(   ij   ,l)  = tpn
169        teta(ij+ip1jm,l)  = tps
[7]170       ENDDO
[1]171c
172
[7]173       IF(leapf)  THEN
[1]174         CALL SCOPY ( ip1jmp1, uscr(1), 1, ucovm1(1, l), 1 )
175         CALL SCOPY (   ip1jm, vscr(1), 1, vcovm1(1, l), 1 )
176         CALL SCOPY ( ip1jmp1, hscr(1), 1, tetam1(1, l), 1 )
[7]177       END IF
[1]178
[7]179      ENDDO ! of DO l = 1,llm
[1]180
181
182c
183c   .......  integration de   q   ......
184c
185c$$$      IF( iadv(1).NE.3.AND.iadv(2).NE.3 )    THEN
186c$$$c
187c$$$       IF( forward. OR . leapf )  THEN
188c$$$        DO iq = 1,2
189c$$$        DO  l = 1,llm
190c$$$        DO ij = 1,ip1jmp1
191c$$$        q(ij,l,iq) = ( q(ij,l,iq)*finvmaold(ij,l) + dtvr *dq(ij,l,iq) )/
192c$$$     $                            finvmasse(ij,l)
193c$$$        ENDDO
194c$$$        ENDDO
195c$$$        ENDDO
196c$$$       ELSE
197c$$$         DO iq = 1,2
198c$$$         DO  l = 1,llm
199c$$$         DO ij = 1,ip1jmp1
200c$$$         q( ij,l,iq ) = q( ij,l,iq ) * finvmaold(ij,l) / finvmasse(ij,l)
201c$$$         ENDDO
202c$$$         ENDDO
203c$$$         ENDDO
204c$$$
205c$$$       END IF
206c$$$c
207c$$$      ENDIF
208
[7]209      if (planet_type.eq."earth") then
[1]210! Earth-specific treatment of first 2 tracers (water)
[7]211        DO l = 1, llm
212          DO ij = 1, ip1jmp1
[1]213            deltap(ij,l) =  p(ij,l) - p(ij,l+1)
214          ENDDO
[7]215        ENDDO
[1]216
[7]217        CALL qminimum( q, nq, deltap )
[1]218
219c
220c    .....  Calcul de la valeur moyenne, unique  aux poles pour  q .....
221c
222
[7]223       DO iq = 1, nq
[1]224        DO l = 1, llm
225
226           DO ij = 1, iim
227             qppn(ij) = aire(   ij   ) * q(   ij   ,l,iq)
228             qpps(ij) = aire(ij+ip1jm) * q(ij+ip1jm,l,iq)
229           ENDDO
230             qpn  =  SSUM(iim,qppn,1)/apoln
231             qps  =  SSUM(iim,qpps,1)/apols
232
233           DO ij = 1, iip1
234             q(   ij   ,l,iq)  = qpn
235             q(ij+ip1jm,l,iq)  = qps
236           ENDDO
237
238        ENDDO
[7]239       ENDDO
[1]240
[776]241! Ehouarn: forget about finvmaold
242!      CALL  SCOPY( ijp1llm , finvmasse, 1, finvmaold, 1 )
[1]243
[7]244      endif ! of if (planet_type.eq."earth")
[2126]245
246      if (force_conserv_tracer) then
247        ! Ehouarn: try to keep total amont of tracers fixed
248        ! by acounting for mass change in each cell
249        massratio(1:ip1jmp1,1:llm)=massescr(1:ip1jmp1,1:llm)
250     &                             /masse(1:ip1jmp1,1:llm)
251        do iq=1,nq
252        q(1:ip1jmp1,1:llm,iq)=q(1:ip1jmp1,1:llm,iq)
253     &                        *massratio(1:ip1jmp1,1:llm)
254        enddo
255      endif ! of if (force_conserv_tracer)
[1]256c
257c
258c     .....   FIN  de l'integration  de   q    .......
259
260c    .................................................................
261
262
263      IF( leapf )  THEN
264         CALL SCOPY (    ip1jmp1 ,  pscr   , 1,   psm1  , 1 )
265         CALL SCOPY ( ip1jmp1*llm, massescr, 1,  massem1, 1 )
266      END IF
267
268      RETURN
269      END
Note: See TracBrowser for help on using the repository browser.