source: trunk/LMDZ.GENERIC/libf/phystd/largescale.F90 @ 848

Last change on this file since 848 was 787, checked in by aslmd, 12 years ago

LMDZ.GENERIC. (Sorry for long text but this is a quite major commit)

Paving the path for parallel computations. And moving towards a more flexible code.

Automatic allocation is used within all routines in phystd. No further mention to ngridmx and nqmx.

  1. ngridmx and nqmx are still used in LMDZ.GENERIC in the dyn3d part
  2. if the LMDZ4/LMDZ5 dynamical core is used, there is no more fixed dimensions ngridmx and nqmx --> a fully flexible parallel implementation is now possible (e.g. no need to recompile when changing numbers of processors)

The important stuff :

  • Compilation checked with ifort. OK with and without debug mode. No errors. Checked for: gcm, newstart, rcm1d, kcm1d
  • RUN GCM: Running an Earth test case. Comparison with previous revision --> debug mode : perfect match. bit by bit (diff command). checked with plots --> O1 mode : close match (checked with plots) --> O2 mode : sometimes up to 0.5 K departure.... BUT in this new version O2 and O1 are quite close while in previous version O1 and O2 differed by about, well, typically 0.5 K (pictures available on request)
  • RUN NEWSTART : perfect match (bit-by-bit) in either debug or normal mode.
  • RUN RCM1D : perfect match in normal mode.
  • RUN KCM1D : not tested (I don't know what is the use of kcm1d)

List of main changes :

  • Additional arguments to some subroutines (ngrid and nq)
  • F77 include strategy is obsolete and replaced by F90 module strategy In this new strategy arrays are allocatable and allocated once at first use This has to be done for all common featuring arrays defined with ngridmx or nqmx

surfdat.h >> surfdat_h.F90
tracer.h >> tracer_h.F90
comsaison.h >> comsaison_h.F90
comgeomfi.h >> comgeomfi_h.F90
comsoil.h >> comsoil_h.F90
comdiurn.h >> comdiurn_h.F90
fisice.h >> DELETED. was not used. probably a fossil.
watercap.h >> DELETED. variable put in surfdat_h.F90

  • F77 'save' strategy is obsolete and replaced by F90 'allocatable save' strategy (see previous point and e.g. new version of physiq.F90)
  • Suppressing any mention to advtrac.h which is a common in the dynamics and needs nqmx This was easily solved by adding an argument with tracer names, coming from the dynamics This is probably not a definitive solution, ... but this allows for generic physics to work easily with either LMDZ.GENERIC or LMDZ dynamical cores
  • Removing consistency tests between nq and nqmx ; and ngrid and ngridmx. No use now!
  • Adaptation of rcm1d, kcm1d, newstart given above-mentioned changes

A note on phyetat0 and soil_setting:

  • Now written so that a slice of horizontal size 'ngrid' starting at grid point 'cursor' is read in startfi.nc 'cursor' is defined in dimphys.h and initialized by inifis (or in newstart) this is useful for parallel computations. default behavior is the usual one : sequential runs, cursor is 1, size ngrid is the whole global domain

A note on an additional change :

  • nueffrad is now an argument to callcorrk as is the case for reffrad both are saved in physiq this is for consistency and lisibility (previously nueffrad was saved in callcorrk) ... but there is a call to a function which modifies nueffrad in physiq ... previously this was not modifying nueffrad (although it was quite cumbersome to detect this) ... to be conservative I kept this behaviour and highlighted it with an array nueffrad_dummy ... I added a comment because someone might want to change this
File size: 5.6 KB
Line 
1      subroutine largescale(ngrid,nq,ptimestep, pplev, pplay, pt, pq,   &
2                        pdt, pdq, pdtlsc, pdqvaplsc, pdqliqlsc, rneb)
3
4      use watercommon_h, only : RLVTT, RCPD, RVTMP2,  &
5          T_h2O_ice_clouds,T_h2O_ice_liq,Psat_water,Lcpdqsat_water
6      USE tracer_h
7      IMPLICIT none
8
9!==================================================================
10!     
11!     Purpose
12!     -------
13!     Calculates large-scale (stratiform) H2O condensation.
14!     
15!     Authors
16!     -------
17!     Adapted from the LMDTERRE code by R. Wordsworth (2009)
18!     Original author Z. X. Li (1993)
19!     
20!==================================================================
21
22#include "dimensions.h"
23#include "dimphys.h"
24#include "comcstfi.h"
25
26#include "callkeys.h"
27
28      INTEGER ngrid,nq
29
30!     Arguments
31      REAL ptimestep                 ! intervalle du temps (s)
32      REAL pplev(ngrid,nlayermx+1) ! pression a inter-couche
33      REAL pplay(ngrid,nlayermx)   ! pression au milieu de couche
34      REAL pt(ngrid,nlayermx)      ! temperature (K)
35      real pq(ngrid,nlayermx,nq) ! tracer mixing ratio (kg/kg)
36      REAL pdt(ngrid,nlayermx)     ! physical temperature tenedency (K/s)
37      REAL pdq(ngrid,nlayermx,nq)! physical tracer tenedency (K/s)
38      REAL pdtlsc(ngrid,nlayermx)  ! incrementation de la temperature (K)
39      REAL pdqvaplsc(ngrid,nlayermx) ! incrementation de la vapeur d'eau
40      REAL pdqliqlsc(ngrid,nlayermx) ! incrementation de l'eau liquide
41      REAL rneb(ngrid,nlayermx)    ! fraction nuageuse
42
43
44!     Options du programme
45      REAL ratqs   ! determine largeur de la distribution de vapeur
46      PARAMETER (ratqs=0.2)
47
48!     Variables locales
49      REAL CBRT
50      EXTERNAL CBRT
51      INTEGER i, k , nn
52      INTEGER,PARAMETER :: nitermax=1000
53      REAL,PARAMETER :: alpha=.5,qthreshold=1.e-6
54      REAL zt(ngrid), zq(ngrid)
55      REAL zcond(ngrid),zcond_iter
56      REAL zdelq(ngrid)
57      REAL zqs(ngrid), zdqs(ngrid)
58      REAL psat_tmp
59     
60! evaporation calculations
61      REAL dqevap(ngrid,nlayermx),dtevap(ngrid,nlayermx)     
62      REAL qevap(ngrid,nlayermx,nq)
63      REAL tevap(ngrid,nlayermx)
64
65      REAL zcor(ngrid), zdelta(ngrid), zcvm5(ngrid)
66      REAL zx_q(ngrid)
67      REAL Nmix_local,zfice
68
69!     GCM -----> subroutine variables, initialisation of outputs
70
71      pdtlsc(1:ngrid,1:nlayermx)  = 0.0
72      pdqvaplsc(1:ngrid,1:nlayermx)  = 0.0
73      pdqliqlsc(1:ngrid,1:nlayermx) = 0.0
74      rneb(1:ngrid,1:nlayermx) = 0.0
75
76
77      ! Evaporate cloud water/ice
78      call evap(ngrid,nq,ptimestep,pt,pq,pdq,pdt,dqevap,dtevap,qevap,tevap)
79      ! note: we use qevap but not tevap in largescale/moistadj
80            ! otherwise is a big mess
81
82
83!  Boucle verticale (du haut vers le bas)
84   DO k = nlayermx, 1, -1
85
86      zt(1:ngrid)=pt(1:ngrid,k)+(pdt(1:ngrid,k)+dtevap(1:ngrid,k))*ptimestep
87      zq(1:ngrid)=qevap(1:ngrid,k,igcm_h2o_vap) !liquid water is included in qevap
88
89!     Calculer la vapeur d'eau saturante et
90!     determiner la condensation partielle
91      DO i = 1, ngrid
92
93         if(zt(i).le.15.) then
94            print*,'in lsc',i,k,zt(i)
95!           zt(i)=15.   ! check too low temperatures
96         endif
97         call Psat_water(zt(i),pplay(i,k),psat_tmp,zqs(i))
98 
99         zdelq(i) = MAX(MIN(ratqs * zq(i),1.-zq(i)),1.e-12)
100         rneb(i,k) = (zq(i)+zdelq(i)-zqs(i)) / (2.0*zdelq(i))
101!        print*,zq(i),zdelq(i),zqs(i),rneb(i,k)
102         if (rneb(i,k).lt.0.) then  !no clouds
103
104            rneb(i,k)=0.
105            zcond(i)=0.
106
107         else if (rneb(i,k).gt.1.) then    !complete cloud cover, we start without evaporating
108
109            rneb(i,k)=1.
110            zt(i)=pt(i,k)+pdt(i,k)*ptimestep
111            zx_q(i) = pq(i,k,igcm_h2o_vap)+pdq(i,k,igcm_h2o_vap)*ptimestep
112            dqevap(i,k)=0.
113!           iterative process to stabilize the scheme when large water amounts JL12
114            zcond(i) = 0.0
115            Do nn=1,nitermax 
116               call Psat_water(zt(i),pplay(i,k),psat_tmp,zqs(i))
117               call Lcpdqsat_water(zt(i),pplay(i,k),psat_tmp,zqs(i),zdqs(i))
118               zcond_iter = alpha*(zx_q(i)-zqs(i))/(1.+zdqs(i))   
119                  !zcond can be negative here
120               zx_q(i) = zx_q(i) - zcond_iter
121               zcond(i) = zcond(i) + zcond_iter
122               zt(i) = zt(i) + zcond_iter*RLVTT/RCPD
123               if (ABS(zcond_iter/alpha).lt.qthreshold) exit
124            End do ! niter
125            zcond(i)=MAX(zcond(i),-(pq(i,k,igcm_h2o_ice)+pdq(i,k,igcm_h2o_ice)*ptimestep))
126
127         else   !standard case     
128
129            zx_q(i) = (zq(i)+zdelq(i)+zqs(i))/2.0 !water vapor in cloudy sky
130!           iterative process to stabilize the scheme when large water amounts JL12
131            zcond(i) = 0.0
132            Do nn=1,nitermax 
133               call Lcpdqsat_water(zt(i),pplay(i,k),psat_tmp,zqs(i),zdqs(i))
134               zcond_iter = MAX(0.0,alpha*(zx_q(i)-zqs(i))/(1.+zdqs(i)))           
135                  !zcond always postive! cannot evaporate clouds!
136                  !this is why we must reevaporate before largescale
137               zx_q(i) = zx_q(i) - zcond_iter
138               zcond(i) = zcond(i) + zcond_iter
139               if (ABS(zcond_iter/alpha).lt.qthreshold) exit
140               zt(i) = zt(i) + zcond_iter*RLVTT/RCPD
141               call Psat_water(zt(i),pplay(i,k),psat_tmp,zqs(i))
142            End do ! niter
143
144         Endif
145
146         zcond(i) = zcond(i)*rneb(i,k)/ptimestep ! JL12
147
148      ENDDO
149
150!     Tendances de t et q
151         pdqvaplsc(1:ngrid,k)  = dqevap(1:ngrid,k) - zcond(1:ngrid)
152         pdqliqlsc(1:ngrid,k) = - pdqvaplsc(1:ngrid,k)
153         pdtlsc(1:ngrid,k)  = pdqliqlsc(1:ngrid,k)*RLVTT/RCPD
154
155   Enddo ! k= nlayermx, 1, -1
156   
157      !print*,'qsat=',zqs
158      !print*,'q=',q
159      !print*,'dq=',pdqvaplsc*ptimestep
160      !print*,'dT in LS=',pdtlsc*ptimestep
161
162      !print*,'rice=',rice
163      !print*,'rneb=',rneb
164
165      return
166      end
Note: See TracBrowser for help on using the repository browser.