source: flexpart.git/src/verttransform_ecmwf.f90 @ 8b3d324

univie
Last change on this file since 8b3d324 was 8b3d324, checked in by pesei <petra seibert at univie ac at>, 6 years ago

comment out print statements

comment out print statements for the reference height, adjust the i/o
comment line

  • Property mode set to 100644
File size: 32.6 KB
RevLine 
[1a8fbee]1! **********************************************************************
[61e07ba]2! Copyright 1998,1999,2000,2001,2002,2005,2007,2008,2009,2010         *
3! Andreas Stohl, Petra Seibert, A. Frank, Gerhard Wotawa,             *
4! Caroline Forster, Sabine Eckhardt, John Burkhart, Harald Sodemann   *
5!                                                                     *
6! This file is part of FLEXPART.                                      *
7!                                                                     *
8! FLEXPART is free software: you can redistribute it and/or modify    *
9! it under the terms of the GNU General Public License as published by*
10! the Free Software Foundation, either version 3 of the License, or   *
11! (at your option) any later version.                                 *
12!                                                                     *
13! FLEXPART is distributed in the hope that it will be useful,         *
14! but WITHOUT ANY WARRANTY; without even the implied warranty of      *
15! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the       *
16! GNU General Public License for more details.                        *
17!                                                                     *
18! You should have received a copy of the GNU General Public License   *
19! along with FLEXPART.  If not, see <http://www.gnu.org/licenses/>.   *
[1a8fbee]20! **********************************************************************
[61e07ba]21
22subroutine verttransform_ecmwf(n,uuh,vvh,wwh,pvh)
[8b3d324]23!                              i  i   i   i   i
[61e07ba]24!*****************************************************************************
25!                                                                            *
26!     This subroutine transforms temperature, dew point temperature and      *
27!     wind components from eta to meter coordinates.                         *
28!     The vertical wind component is transformed from Pa/s to m/s using      *
29!     the conversion factor pinmconv.                                        *
30!     In addition, this routine calculates vertical density gradients        *
31!     needed for the parameterization of the turbulent velocities.           *
32!                                                                            *
33!     Author: A. Stohl, G. Wotawa                                            *
34!                                                                            *
35!     12 August 1996                                                         *
36!     Update: 16 January 1998                                                *
37!                                                                            *
[1a8fbee]38!                                                                            *
39!*****************************************************************************
40!  CHANGES                                                                   *
[61e07ba]41!     Major update: 17 February 1999                                         *
42!     by G. Wotawa                                                           *
43!                                                                            *
44!     - Vertical levels for u, v and w are put together                      *
45!     - Slope correction for vertical velocity: Modification of calculation  *
46!       procedure                                                            *
47!                                                                            *
[1a8fbee]48!  Bernd C. Krueger, Feb. 2001:
[61e07ba]49!   Variables tth and qvh (on eta coordinates) from common block
[1a8fbee]50!                                                                            *
51! Sabine Eckhardt, March 2007:
52!   added the variable cloud for use with scavenging - descr. in com_mod
53!                                                                            *
54! Who? When?                                                                 *
55!   Unified ECMWF and GFS builds
[61e07ba]56! Marian Harustak, 12.5.2017
57!     - Renamed from verttransform to verttransform_ecmwf
[1a8fbee]58!                                                                            *
59! Don Morton, 2017-05-30:
60!   modification of a bug in ew. Don Morton (CTBTO project)                  *
61!                                                                            *
62!  undocumented modifications by NILU for v10                                *
63!                                                                            *
64!  Petra Seibert, 2018-06-13:                                                *
65!   - fix bug of ticket:140 (find reference position for vertical grid)      *
66!   - put back SAVE attribute for INIT, just to be safe                      *
67!   - minor changes, most of them just cosmetics                             *
68!   for details see changelog.txt                                            *
69!                                                                            *
70! ****************************************************************************
71
[61e07ba]72!*****************************************************************************
73!                                                                            *
74! Variables:                                                                 *
75! nx,ny,nz                        field dimensions in x,y and z direction    *
76! clouds(0:nxmax,0:nymax,0:nzmax,numwfmem) cloud field for wet deposition    *
77! uu(0:nxmax,0:nymax,nzmax,numwfmem)     wind components in x-direction [m/s]*
78! vv(0:nxmax,0:nymax,nzmax,numwfmem)     wind components in y-direction [m/s]*
79! ww(0:nxmax,0:nymax,nzmax,numwfmem)     wind components in z-direction      *
80!                                          [deltaeta/s]                      *
81! tt(0:nxmax,0:nymax,nzmax,numwfmem)     temperature [K]                     *
82! pv(0:nxmax,0:nymax,nzmax,numwfmem)     potential voriticity (pvu)          *
83! ps(0:nxmax,0:nymax,numwfmem)           surface pressure [Pa]               *
84!                                                                            *
85!*****************************************************************************
86
87  use par_mod
88  use com_mod
89  use cmapf_mod, only: cc2gll
90
91  implicit none
92
93  real,intent(in),dimension(0:nxmax-1,0:nymax-1,nuvzmax) :: uuh,vvh,pvh
94  real,intent(in),dimension(0:nxmax-1,0:nymax-1,nwzmax) :: wwh
95
96  real,dimension(0:nxmax-1,0:nymax-1,nuvzmax) :: rhoh,uvzlev,wzlev
97  real,dimension(0:nxmax-1,0:nymax-1,nzmax) :: pinmconv
[1a8fbee]98!>   for reference profile (PS) 
99  real ::  tvoldref, poldref, pintref, psmean, psstd
100  integer :: ixyref(2)
101  integer, parameter :: ioldref = 1 ! PS 2018-06-13: set to 0 if you
102!!   want old method of searching reference location for the vertical grid
103!!   1 for new method (options for other methods 2,... in the future)
104
[61e07ba]105  real,dimension(0:nymax-1) :: cosf
[1a8fbee]106  real,dimension(0:nxmax-1,0:nymax-1) ::  tvold,pold,pint,tv
107!! automatic arrays introduced in v10 by ?? to achieve better loop order (PS)
[61e07ba]108
109  integer,dimension(0:nxmax-1,0:nymax-1) :: rain_cloud_above,idx
110
[1a8fbee]111  integer :: ix,jy,kz,iz,n,kmin,ix1,jy1,ixp,jyp,ixref,jyref,kz_inv
[61e07ba]112  real :: f_qvsat,pressure,rh,lsp,convp,cloudh_min,prec
113  real :: ew,dz1,dz2,dz
114  real :: xlon,ylat,xlonr,dzdx,dzdy
115  real :: dzdx1,dzdx2,dzdy1,dzdy2
116  real :: uuaux,vvaux,uupolaux,vvpolaux,ddpol,ffpol,wdummy
117  real,parameter :: const=r_air/ga
118  real,parameter :: precmin = 0.002 ! minimum prec in mm/h for cloud diagnostics
119
[1a8fbee]120  logical, save :: init = .true. ! PS 2018-06-13: add back save attribute
[de4c5e9]121
[61e07ba]122
123  !ZHG SEP 2014 tests 
124  ! integer :: cloud_ver,cloud_min, cloud_max
125  ! integer ::teller(5), convpteller=0, lspteller=0
126  ! real :: cloud_col_wat, cloud_water
127  !ZHG 2015 temporary variables for testing
128  ! real :: rcw(0:nxmax-1,0:nymax-1)
129  ! real :: rpc(0:nxmax-1,0:nymax-1)
130  ! character(len=60) :: zhgpath='/xnilu_wrk/flex_wrk/zhg/'
131  ! character(len=60) :: fnameA,fnameB,fnameC,fnameD,fnameE,fnameF,fnameG,fnameH
132  ! CHARACTER(LEN=3)  :: aspec
133  ! integer :: virr=0
[de4c5e9]134  !real :: tot_cloud_h
135  !real :: dbg_height(nzmax)
[61e07ba]136!ZHG
137
138!*************************************************************************
139! If verttransform is called the first time, initialize heights of the   *
140! z levels in meter. The heights are the heights of model levels, where  *
141! u,v,T and qv are given, and of the interfaces, where w is given. So,   *
[1a8fbee]142! the vertical rESOlution in the z system is doubled. As reference point,*
[61e07ba]143! the lower left corner of the grid is used.                             *
144! Unlike in the eta system, no difference between heights for u,v and    *
145! heights for w exists.                                                  *
146!*************************************************************************
147
[1a8fbee]148!ESO measure CPU time
[61e07ba]149!  call mpif_mtime('verttransform',0)
150
151  if (init) then
152
[1a8fbee]153!! Search for a point with high surface pressure (i.e. not above significant
154!!  topography) Then, use this point to construct a reference z profile,
155!!  to be used at all times
156! *****************************************************************************
157
158    if (ioldref .eq. 0) then ! old reference grid point
159       do jy=0,nymin1
160         do ix=0,nxmin1
161           if (ps(ix,jy,1,n).gt.1000.e2) then
162             ixref=ix
163             jyref=jy
164             goto 3
165           endif
166         end do
167       end do
1683     continue
169
[8b3d324]170!      print*,'oldheights at' ,ixref,jyref,ps(ixref,jyref,1,n)
[1a8fbee]171    else ! new reference grid point
172!     PS: the old version fails if the pressure is <=1000 hPa in the whole
173!     domain. Let us find a good replacement, not just a quick fix.
174!     Search point near to mean pressure after excluding mountains
175
176      psmean = sum( ps(:,:,1,n) ) / (nx*ny)
177      print*,'height: fg psmean',psmean
178      psstd = sqrt(sum( (ps(:,:,1,n) - psmean)**2 ) / (nx*ny))
179
180!>    new psmean using only points within $\plusminus\sigma$ 
181!      psmean = sum( ps(:,:,1,n), abs(ps(:,:,1,n)-psmean) < psstd ) / &
182!        count(abs(ps(:,:,1,n)-psmean) < psstd)
183
184!>    new psmean using only points with $p\gt \overbar{p}+\sigma_p$ 
185!>    (reject mountains, accept valleys)
186      psmean = sum( ps(:,:,1,n), ps(:,:,1,n) > psmean - psstd ) / &
187        count(ps(:,:,1,n) > psmean - psstd)
[8b3d324]188!      print*,'height: std, new psmean',psstd,psmean
[1a8fbee]189      ixyref = minloc( abs( ps(:,:,1,n) - psmean ) )
190      ixref = ixyref(1)
191      jyref = ixyref(2)
[8b3d324]192!      print*,'newheights at' ,ixref,jyref,ps(ixref,jyref,1,n)
[1a8fbee]193    endif 
194
195    tvoldref=tt2(ixref,jyref,1,n)* &
196      ( 1. + 0.378*ew(td2(ixref,jyref,1,n) ) / ps(ixref,jyref,1,n))
197    poldref=ps(ixref,jyref,1,n)
[61e07ba]198    height(1)=0.
199
200    do kz=2,nuvz
201
[1a8fbee]202      pintref = akz(kz)+bkz(kz)*ps(ixref,jyref,1,n)
203      tv = tth(ixref,jyref,kz,n)*(1.+0.608*qvh(ixref,jyref,kz,n))
204
205      if (abs(tv(ixref,jyref)-tvoldref) .gt. 0.2) then
206        height(kz) = height(kz-1) +      &
207          const*log( poldref/pintref ) * &
208          ( tv(ixref,jyref) - tvoldref ) / log( tv(ixref,jyref) / tvoldref )
[61e07ba]209      else
[1a8fbee]210        height(kz) = height(kz-1) + &
211          const*log( poldref/pintref ) * tv(ixref,jyref)
[61e07ba]212      endif
213
[1a8fbee]214      tvoldref = tv(ixref,jyref)
215      poldref = pintref
216      print*,'height=',kz,height(kz),tvoldref,poldref
[61e07ba]217
[1a8fbee]218    end do
[de4c5e9]219
[61e07ba]220
221! Determine highest levels that can be within PBL
222!************************************************
223
224    do kz=1,nz
225      if (height(kz).gt.hmixmax) then
226        nmixz=kz
227        goto 9
228      endif
229    end do
2309   continue
231
232! Do not repeat initialization of the Cartesian z grid
233!*****************************************************
234    init=.false.
235
[1a8fbee]236  endif ! init block (vertical grid construction)
[61e07ba]237
238
239! Loop over the whole grid
240!*************************
241
[1a8fbee]242  tvold(:,:)=tt2(:,:,1,n) * (1.+0.378*ew( td2(:,:,1,n) ) / ps(:,:,1,n))
[61e07ba]243  pold=ps(:,:,1,n)
244  uvzlev(:,:,1)=0.
245  wzlev(:,:,1)=0.
246  rhoh(:,:,1)=pold/(r_air*tvold)
247
248
249! Compute heights of eta levels
250!******************************
251
252  do kz=2,nuvz
[1a8fbee]253    pint(:,:)=akz(kz)+bkz(kz)*ps(:,:,1,n)
254    tv(:,:)=tth(:,:,kz,n)*(1.+0.608*qvh(:,:,kz,n))
255    rhoh(:,:,kz)=pint(:,:)/(r_air*tv(:,:))
[61e07ba]256
[1a8fbee]257    where (abs(tv(:,:)-tvold(:,:)).gt.0.2)
258      uvzlev(:,:,kz)=uvzlev(:,:,kz-1)+const*log(pold(:,:)/pint(:,:))* &
259           (tv(:,:)-tvold(:,:))/log(tv(:,:)/tvold(:,:))
[61e07ba]260    elsewhere
[1a8fbee]261      uvzlev(:,:,kz)=uvzlev(:,:,kz-1)+const*log(pold(:,:)/pint(:,:))*tv(:,:)
[61e07ba]262    endwhere
263
[1a8fbee]264    tvold(:,:)=tv(:,:)
265    pold(:,:)=pint(:,:)
[61e07ba]266  end do
267
268
269  do kz=2,nwz-1
270    wzlev(:,:,kz)=(uvzlev(:,:,kz+1)+uvzlev(:,:,kz))/2.
271  end do
272  wzlev(:,:,nwz)=wzlev(:,:,nwz-1)+ &
273       uvzlev(:,:,nuvz)-uvzlev(:,:,nuvz-1)
274
275! pinmconv=(h2-h1)/(p2-p1)
276
277  pinmconv(:,:,1)=(uvzlev(:,:,2))/ &
[1a8fbee]278    ((aknew(2)+bknew(2)*ps(:,:,1,n))- &
279     (aknew(1)+bknew(1)*ps(:,:,1,n)))
[61e07ba]280  do kz=2,nz-1
281    pinmconv(:,:,kz)=(uvzlev(:,:,kz+1)-uvzlev(:,:,kz-1))/ &
[1a8fbee]282      ((aknew(kz+1)+bknew(kz+1)*ps(:,:,1,n))- &
283       (aknew(kz-1)+bknew(kz-1)*ps(:,:,1,n)))
[61e07ba]284  end do
285  pinmconv(:,:,nz)=(uvzlev(:,:,nz)-uvzlev(:,:,nz-1))/ &
286       ((aknew(nz)+bknew(nz)*ps(:,:,1,n))- &
[1a8fbee]287        (aknew(nz-1)+bknew(nz-1)*ps(:,:,1,n)))
[61e07ba]288
[1a8fbee]289! Levels where u,v,t and q are given
290!***********************************
[61e07ba]291
292  uu(:,:,1,n)=uuh(:,:,1)
293  vv(:,:,1,n)=vvh(:,:,1)
294  tt(:,:,1,n)=tth(:,:,1,n)
295  qv(:,:,1,n)=qvh(:,:,1,n)
[1a8fbee]296!HG adding the cloud water
[61e07ba]297  if (readclouds) then
298    clwc(:,:,1,n)=clwch(:,:,1,n)
299    if (.not.sumclouds) ciwc(:,:,1,n)=ciwch(:,:,1,n)
300  end if
[1a8fbee]301!HG
[61e07ba]302  pv(:,:,1,n)=pvh(:,:,1)
303  rho(:,:,1,n)=rhoh(:,:,1)
304
305  uu(:,:,nz,n)=uuh(:,:,nuvz)
306  vv(:,:,nz,n)=vvh(:,:,nuvz)
307  tt(:,:,nz,n)=tth(:,:,nuvz,n)
308  qv(:,:,nz,n)=qvh(:,:,nuvz,n)
[1a8fbee]309!HG adding the cloud water
[61e07ba]310  if (readclouds) then
311    clwc(:,:,nz,n)=clwch(:,:,nuvz,n)
[1a8fbee]312    if (.not. sumclouds) ciwc(:,:,nz,n)=ciwch(:,:,nuvz,n)
[61e07ba]313  end if
[1a8fbee]314!HG
[61e07ba]315  pv(:,:,nz,n)=pvh(:,:,nuvz)
316  rho(:,:,nz,n)=rhoh(:,:,nuvz)
317
318  kmin=2
319  idx=kmin
[1a8fbee]320  iz_loop: do iz=2,nz-1
[61e07ba]321    do jy=0,nymin1
322      do ix=0,nxmin1
[1a8fbee]323        if (height(iz).gt.uvzlev(ix,jy,nuvz)) then
324       
[61e07ba]325          uu(ix,jy,iz,n)=uu(ix,jy,nz,n)
326          vv(ix,jy,iz,n)=vv(ix,jy,nz,n)
327          tt(ix,jy,iz,n)=tt(ix,jy,nz,n)
328          qv(ix,jy,iz,n)=qv(ix,jy,nz,n)
[1a8fbee]329!HG adding the cloud water
[61e07ba]330          if (readclouds) then
331            clwc(ix,jy,iz,n)=clwc(ix,jy,nz,n)
[1a8fbee]332            if (.not. sumclouds) ciwc(ix,jy,iz,n)=ciwc(ix,jy,nz,n)
[61e07ba]333          end if
[1a8fbee]334!HG
[61e07ba]335          pv(ix,jy,iz,n)=pv(ix,jy,nz,n)
336          rho(ix,jy,iz,n)=rho(ix,jy,nz,n)
[1a8fbee]337
[61e07ba]338        else
[1a8fbee]339
340          kz_loop: do kz=idx(ix,jy),nuvz
341            if (idx(ix,jy) .le. kz .and. height(iz).gt.uvzlev(ix,jy,kz-1) &
342                .and. height(iz).le.uvzlev(ix,jy,kz)) then
[61e07ba]343              idx(ix,jy)=kz
[1a8fbee]344              exit kz_loop
[61e07ba]345            endif
[1a8fbee]346          enddo kz_loop
347
[61e07ba]348        endif
349      enddo
350    enddo
351    do jy=0,nymin1
352      do ix=0,nxmin1
[1a8fbee]353        if (height(iz).le.uvzlev(ix,jy,nuvz)) then
354       
[61e07ba]355          kz=idx(ix,jy)
356          dz1=height(iz)-uvzlev(ix,jy,kz-1)
357          dz2=uvzlev(ix,jy,kz)-height(iz)
358          dz=dz1+dz2
359          uu(ix,jy,iz,n)=(uuh(ix,jy,kz-1)*dz2+uuh(ix,jy,kz)*dz1)/dz
360          vv(ix,jy,iz,n)=(vvh(ix,jy,kz-1)*dz2+vvh(ix,jy,kz)*dz1)/dz
361          tt(ix,jy,iz,n)=(tth(ix,jy,kz-1,n)*dz2 &
362               +tth(ix,jy,kz,n)*dz1)/dz
363          qv(ix,jy,iz,n)=(qvh(ix,jy,kz-1,n)*dz2 &
364               +qvh(ix,jy,kz,n)*dz1)/dz
[1a8fbee]365!HG adding the cloud water
[61e07ba]366          if (readclouds) then
367            clwc(ix,jy,iz,n)=(clwch(ix,jy,kz-1,n)*dz2+clwch(ix,jy,kz,n)*dz1)/dz
[1a8fbee]368            if (.not. sumclouds) ciwc(ix,jy,iz,n)= &
369              (ciwch(ix,jy,kz-1,n)*dz2+ciwch(ix,jy,kz,n)*dz1)/dz
[61e07ba]370          end if
[1a8fbee]371!HG
[61e07ba]372          pv(ix,jy,iz,n)=(pvh(ix,jy,kz-1)*dz2+pvh(ix,jy,kz)*dz1)/dz
373          rho(ix,jy,iz,n)=(rhoh(ix,jy,kz-1)*dz2+rhoh(ix,jy,kz)*dz1)/dz
[1a8fbee]374
[61e07ba]375        endif
376      enddo
377    enddo
[1a8fbee]378  enddo iz_loop
[61e07ba]379
380
[1a8fbee]381! Levels where w is given
[61e07ba]382!*************************
383
384  ww(:,:,1,n)=wwh(:,:,1)*pinmconv(:,:,1)
385  ww(:,:,nz,n)=wwh(:,:,nwz)*pinmconv(:,:,nz)
386  kmin=2
387  idx=kmin
[1a8fbee]388  iz_loop2: do iz=2,nz
[61e07ba]389    do jy=0,nymin1
390      do ix=0,nxmin1
[1a8fbee]391        kz_loop2: do kz=idx(ix,jy),nwz
392          if (idx(ix,jy) .le. kz .and. height(iz).gt.wzlev(ix,jy,kz-1) &
393            .and. height(iz).le.wzlev(ix,jy,kz)) then
[61e07ba]394            idx(ix,jy)=kz
[1a8fbee]395            exit kz_loop2
[61e07ba]396          endif
[1a8fbee]397        enddo kz_loop2
[61e07ba]398      enddo
399    enddo
400    do jy=0,nymin1
401      do ix=0,nxmin1
402        kz=idx(ix,jy)
403        dz1=height(iz)-wzlev(ix,jy,kz-1)
404        dz2=wzlev(ix,jy,kz)-height(iz)
405        dz=dz1+dz2
406        ww(ix,jy,iz,n)=(wwh(ix,jy,kz-1)*pinmconv(ix,jy,kz-1)*dz2 &
[1a8fbee]407                      + wwh(ix,jy,kz)  *pinmconv(ix,jy,kz)*dz1)/dz
[61e07ba]408      enddo
409    enddo
[1a8fbee]410  enddo iz_loop2
[61e07ba]411
412! Compute density gradients at intermediate levels
413!*************************************************
414
[1a8fbee]415  drhodz(:,:,1,n)=(rho(:,:,2,n)-rho(:,:,1,n))/(height(2)-height(1))
[61e07ba]416  do kz=2,nz-1
417    drhodz(:,:,kz,n)=(rho(:,:,kz+1,n)-rho(:,:,kz-1,n))/ &
[1a8fbee]418      (height(kz+1)-height(kz-1))
[61e07ba]419  end do
420  drhodz(:,:,nz,n)=drhodz(:,:,nz-1,n)
421
422
423!****************************************************************
424! Compute slope of eta levels in windward direction and resulting
425! vertical wind correction
426!****************************************************************
427
428  do jy=1,ny-2
[1a8fbee]429    cosf(jy) = 1. / cos( ( real(jy)*dy + ylat0 )*pi180 )
[61e07ba]430  enddo
431
432  kmin=2
433  idx=kmin
[1a8fbee]434  iz_loop3: do iz=2,nz-1
[61e07ba]435    do jy=1,ny-2
436      do ix=1,nx-2
437
[1a8fbee]438        kz_loop3: do kz=idx(ix,jy),nz
439          if (idx(ix,jy) .le. kz .and. height(iz).gt.uvzlev(ix,jy,kz-1) &
440            .and. height(iz).le.uvzlev(ix,jy,kz)) then
[61e07ba]441            idx(ix,jy)=kz
[1a8fbee]442            exit kz_loop3
[61e07ba]443          endif
[1a8fbee]444        enddo kz_loop3
[61e07ba]445      enddo
446    enddo
447
448    do jy=1,ny-2
449      do ix=1,nx-2
450        kz=idx(ix,jy)
451        dz1=height(iz)-uvzlev(ix,jy,kz-1)
452        dz2=uvzlev(ix,jy,kz)-height(iz)
453        dz=dz1+dz2
454        ix1=ix-1
455        jy1=jy-1
456        ixp=ix+1
457        jyp=jy+1
458
459        dzdx1=(uvzlev(ixp,jy,kz-1)-uvzlev(ix1,jy,kz-1))/2.
[1a8fbee]460        dzdx2=(uvzlev(ixp,jy,kz)  -uvzlev(ix1,jy,kz)  )/2.
[61e07ba]461        dzdx=(dzdx1*dz2+dzdx2*dz1)/dz
462
463        dzdy1=(uvzlev(ix,jyp,kz-1)-uvzlev(ix,jy1,kz-1))/2.
[1a8fbee]464        dzdy2=(uvzlev(ix,jyp,kz)  -uvzlev(ix,jy1,kz)  )/2.
[61e07ba]465        dzdy=(dzdy1*dz2+dzdy2*dz1)/dz
466
[1a8fbee]467        ww(ix,jy,iz,n)=ww(ix,jy,iz,n) +( dzdx*uu(ix,jy,iz,n)*dxconst*cosf(jy) &
468          + dzdy*vv(ix,jy,iz,n)*dyconst)
[61e07ba]469
[1a8fbee]470      enddo
471    enddo
[61e07ba]472
[1a8fbee]473  enddo iz_loop3
[61e07ba]474
475! If north pole is in the domain, calculate wind velocities in polar
476! stereographic coordinates
477!*******************************************************************
478
479  if (nglobal) then
[1a8fbee]480   
[61e07ba]481    do iz=1,nz
482      do jy=int(switchnorthg)-2,nymin1
483        ylat=ylat0+real(jy)*dy
484        do ix=0,nxmin1
485          xlon=xlon0+real(ix)*dx
486          call cc2gll(northpolemap,ylat,xlon,uu(ix,jy,iz,n), &
[1a8fbee]487               vv(ix,jy,iz,n),uupol(ix,jy,iz,n), vvpol(ix,jy,iz,n))
488        enddo
489      enddo
490    enddo
[61e07ba]491
492
493    do iz=1,nz
494
[1a8fbee]495!   CALCULATE FFPOL, DDPOL FOR CENTRAL GRID POINT
[61e07ba]496!
[1a8fbee]497!   AMS nauffer Nov 18 2004 Added check for case vv=0
498
[61e07ba]499      xlon=xlon0+real(nx/2-1)*dx
500      xlonr=xlon*pi/180.
[1a8fbee]501      ffpol=sqrt(uu(nx/2-1,nymin1,iz,n)**2+vv(nx/2-1,nymin1,iz,n)**2)
[61e07ba]502      if (vv(nx/2-1,nymin1,iz,n).lt.0.) then
[1a8fbee]503        ddpol=atan(uu(nx/2-1,nymin1,iz,n)/vv(nx/2-1,nymin1,iz,n))-xlonr
[61e07ba]504      else if (vv(nx/2-1,nymin1,iz,n).gt.0.) then
[1a8fbee]505        ddpol=pi+atan(uu(nx/2-1,nymin1,iz,n)/vv(nx/2-1,nymin1,iz,n))-xlonr
[61e07ba]506      else
[1a8fbee]507        ddpol=pi/2.-xlonr
[61e07ba]508      endif
[1a8fbee]509      if (ddpol.lt.0.) ddpol=2.0*pi+ddpol
510      if (ddpol.gt.2.0*pi) ddpol=ddpol-2.0*pi
[61e07ba]511
512! CALCULATE U,V FOR 180 DEG, TRANSFORM TO POLAR STEREOGRAPHIC GRID
513      xlon=180.0
514      xlonr=xlon*pi/180.
515      ylat=90.0
516      uuaux=-ffpol*sin(xlonr+ddpol)
517      vvaux=-ffpol*cos(xlonr+ddpol)
[1a8fbee]518      call cc2gll(northpolemap,ylat,xlon,uuaux,vvaux,uupolaux, vvpolaux)
[61e07ba]519
520      jy=nymin1
521      do ix=0,nxmin1
522        uupol(ix,jy,iz,n)=uupolaux
523        vvpol(ix,jy,iz,n)=vvpolaux
[1a8fbee]524      enddo
525    enddo
[61e07ba]526
[1a8fbee]527! Fix: Set W (vertical wind) at pole to the zonally averaged W of the next
528! equator-ward parallel
[61e07ba]529
530    do iz=1,nz
531      wdummy=0.
532      jy=ny-2
533      do ix=0,nxmin1
534        wdummy=wdummy+ww(ix,jy,iz,n)
[1a8fbee]535      enddo
[61e07ba]536      wdummy=wdummy/real(nx)
537      jy=nymin1
538      do ix=0,nxmin1
539        ww(ix,jy,iz,n)=wdummy
[1a8fbee]540      enddo
541    enddo
[61e07ba]542
543  endif
544
545
546! If south pole is in the domain, calculate wind velocities in polar
547! stereographic coordinates
548!*******************************************************************
549
550  if (sglobal) then
[1a8fbee]551 
[61e07ba]552    do iz=1,nz
553      do jy=0,int(switchsouthg)+3
554        ylat=ylat0+real(jy)*dy
555        do ix=0,nxmin1
556          xlon=xlon0+real(ix)*dx
557          call cc2gll(southpolemap,ylat,xlon,uu(ix,jy,iz,n), &
[1a8fbee]558               vv(ix,jy,iz,n),uupol(ix,jy,iz,n),vvpol(ix,jy,iz,n))
559        enddo
560      enddo
561    enddo
[61e07ba]562
563    do iz=1,nz
564
[1a8fbee]565!   CALCULATE FFPOL, DDPOL FOR CENTRAL GRID POINT
[61e07ba]566!
[1a8fbee]567!   AMS nauffer Nov 18 2004 Added check for case vv=0
568
[61e07ba]569      xlon=xlon0+real(nx/2-1)*dx
570      xlonr=xlon*pi/180.
[1a8fbee]571      ffpol=sqrt(uu(nx/2-1,0,iz,n)**2+vv(nx/2-1,0,iz,n)**2)
[61e07ba]572      if (vv(nx/2-1,0,iz,n).lt.0.) then
[1a8fbee]573        ddpol=atan(uu(nx/2-1,0,iz,n)/vv(nx/2-1,0,iz,n))+xlonr
[61e07ba]574      else if (vv(nx/2-1,0,iz,n).gt.0.) then
[1a8fbee]575        ddpol=pi+atan(uu(nx/2-1,0,iz,n)/vv(nx/2-1,0,iz,n))+xlonr
[61e07ba]576      else
[1a8fbee]577        ddpol=pi/2.-xlonr
[61e07ba]578      endif
[1a8fbee]579      if (ddpol.lt.0.) ddpol=2.0*pi+ddpol
580      if (ddpol.gt.2.0*pi) ddpol=ddpol-2.0*pi
[61e07ba]581
582! CALCULATE U,V FOR 180 DEG, TRANSFORM TO POLAR STEREOGRAPHIC GRID
583      xlon=180.0
584      xlonr=xlon*pi/180.
585      ylat=-90.0
586      uuaux=+ffpol*sin(xlonr-ddpol)
587      vvaux=-ffpol*cos(xlonr-ddpol)
[1a8fbee]588      call cc2gll(northpolemap,ylat,xlon,uuaux,vvaux,uupolaux,vvpolaux)
[61e07ba]589
590      jy=0
591      do ix=0,nxmin1
592        uupol(ix,jy,iz,n)=uupolaux
593        vvpol(ix,jy,iz,n)=vvpolaux
[1a8fbee]594      enddo
595    enddo
[61e07ba]596
[1a8fbee]597! Fix: Set W (vertical wind) at pole to the zonally averaged W of the next
598! equator-ward parallel
[61e07ba]599
600    do iz=1,nz
601      wdummy=0.
602      jy=1
603      do ix=0,nxmin1
604        wdummy=wdummy+ww(ix,jy,iz,n)
[1a8fbee]605      enddo
[61e07ba]606      wdummy=wdummy/real(nx)
607      jy=0
608      do ix=0,nxmin1
609        ww(ix,jy,iz,n)=wdummy
[1a8fbee]610      enddo
611    enddo
[61e07ba]612  endif
613
614
[1a8fbee]615!******************************************************************************
616  if (readclouds) then ! HG METHOD
617
618! Loops over all grid cells vertically and construct the 3D matrix for clouds
619! Cloud top and cloud bottom grid cells are assigned as well as the total column
620! cloud water. For precipitating columns, the type and whether it is in or below
[61e07ba]621! cloud scavenging are assigned with numbers 2-5 (following the old metod).
[1a8fbee]622! A distinction is made between lsp and convp though they are treated the equally
623! with regard to scavenging. Also, clouds that are not precipitating are defined which
624! may be used in the future for cloud processing by non-precipitating-clouds.
625!*******************************************************************************
626
627!PS    write(*,*) 'Global ECMWF fields: using cloud water'
[61e07ba]628    clw(:,:,:,n)=0.0
629    ctwc(:,:,n)=0.0
630    clouds(:,:,:,n)=0
631! If water/ice are read separately into clwc and ciwc, store sum in clwc
[1a8fbee]632    if (.not. sumclouds) then
[61e07ba]633      clwc(:,:,:,n) = clwc(:,:,:,n) + ciwc(:,:,:,n)
[1a8fbee]634    endif
[61e07ba]635    do jy=0,nymin1
636      do ix=0,nxmin1
637        lsp=lsprec(ix,jy,1,n)
638        convp=convprec(ix,jy,1,n)
[1a8fbee]639        prec=lsp+convp  ! Note PS: prec is not used currently
[de4c5e9]640!        tot_cloud_h=0
[61e07ba]641! Find clouds in the vertical
[1a8fbee]642!! Note PS: bad loop order.
[61e07ba]643        do kz=1, nz-1 !go from top to bottom
644          if (clwc(ix,jy,kz,n).gt.0) then     
645! assuming rho is in kg/m3 and hz in m gives: kg/kg * kg/m3 *m3/kg /m = m2/m3
[1a8fbee]646            clw(ix,jy,kz,n)=(clwc(ix,jy,kz,n)*rho(ix,jy,kz,n))* &
647              (height(kz+1)-height(kz))
[de4c5e9]648!            tot_cloud_h=tot_cloud_h+(height(kz+1)-height(kz))
[61e07ba]649           
650!            icloud_stats(ix,jy,4,n)= icloud_stats(ix,jy,4,n)+clw(ix,jy,kz,n)          ! Column cloud water [m3/m3]
651            ctwc(ix,jy,n) = ctwc(ix,jy,n)+clw(ix,jy,kz,n)
652!            icloud_stats(ix,jy,3,n)= min(height(kz+1),height(kz))                     ! Cloud BOT height stats      [m]
653            cloudh_min=min(height(kz+1),height(kz))
654!ZHG 2015 extra for testing
655!            clh(ix,jy,kz,n)=height(kz+1)-height(kz)
656!            icloud_stats(ix,jy,1,n)=icloud_stats(ix,jy,1,n)+(height(kz+1)-height(kz)) ! Cloud total vertical extent [m]
657!            icloud_stats(ix,jy,2,n)= max(icloud_stats(ix,jy,2,n),height(kz))          ! Cloud TOP height            [m]
658!ZHG
659          endif
660        end do
661
662! If Precipitation. Define removal type in the vertical
[1a8fbee]663        if (lsp.gt.0.01 .or. convp.gt.0.01) then ! cloud and precipitation
664!! Note PS: such hardcoded limits would better be parameters defined in par_mod
[61e07ba]665
666          do kz=nz,1,-1 !go Bottom up!
[1a8fbee]667!! Note PS: bad loop order
[61e07ba]668            if (clw(ix,jy,kz,n).gt. 0) then ! is in cloud
669              cloudsh(ix,jy,n)=cloudsh(ix,jy,n)+height(kz)-height(kz-1)
670              clouds(ix,jy,kz,n)=1                               ! is a cloud
671              if (lsp.ge.convp) then
672                clouds(ix,jy,kz,n)=3                            ! lsp in-cloud
673              else
674                clouds(ix,jy,kz,n)=2                             ! convp in-cloud
675              endif                                              ! convective or large scale
[1a8fbee]676            elseif( clw(ix,jy,kz,n).le.0 .and. cloudh_min.ge.height(kz)) then ! is below cloud
[61e07ba]677              if (lsp.ge.convp) then
678                clouds(ix,jy,kz,n)=5                             ! lsp dominated washout
679              else
680                clouds(ix,jy,kz,n)=4                             ! convp dominated washout
681              endif                                              ! convective or large scale
682            endif
683
684            if (height(kz).ge. 19000) then                        ! set a max height for removal
[1a8fbee]685!! Note PS: such hardcoded limits would better be parameters defined in par_mod
[61e07ba]686              clouds(ix,jy,kz,n)=0
[1a8fbee]687            endif ! clw>0
688          enddo ! kz
[61e07ba]689        endif ! precipitation
690      end do
691    end do
692
[1a8fbee]693! ESO: copy the relevant data to clw4 to reduce amount of communicated data for MPI
[61e07ba]694!    ctwc(:,:,n) = icloud_stats(:,:,4,n)
695
696!**************************************************************************
697  else       ! use old definitions
698!**************************************************************************
[1a8fbee]699
[61e07ba]700!   create a cloud and rainout/washout field, clouds occur where rh>80%
701!   total cloudheight is stored at level 0
[1a8fbee]702
703!PS    write(*,*) 'Global fields: using cloud water from Parameterization'
[61e07ba]704    do jy=0,nymin1
705      do ix=0,nxmin1
706        rain_cloud_above(ix,jy)=0
707        lsp=lsprec(ix,jy,1,n)
708        convp=convprec(ix,jy,1,n)
709        cloudsh(ix,jy,n)=0
710        do kz_inv=1,nz-1
[1a8fbee]711!! Note PS: bad loop order.
[61e07ba]712          kz=nz-kz_inv+1
713          pressure=rho(ix,jy,kz,n)*r_air*tt(ix,jy,kz,n)
714          rh=qv(ix,jy,kz,n)/f_qvsat(pressure,tt(ix,jy,kz,n))
715          clouds(ix,jy,kz,n)=0
[1a8fbee]716
717          if (rh .gt. 0.8) then ! in cloud
718!! Note PS: such hardcoded limits would better be parameters defined in par_mod
719
720            if (lsp.gt.0.01 .or. convp.gt.0.01) then ! cloud and precipitation
721!! Note PS: such hardcoded limits would better be parameters defined in par_mod
[61e07ba]722              rain_cloud_above(ix,jy)=1
723              cloudsh(ix,jy,n)=cloudsh(ix,jy,n)+ &
724                   height(kz)-height(kz-1)
725              if (lsp.ge.convp) then
726                clouds(ix,jy,kz,n)=3 ! lsp dominated rainout
727              else
728                clouds(ix,jy,kz,n)=2 ! convp dominated rainout
729              endif
730            else ! no precipitation
731              clouds(ix,jy,kz,n)=1 ! cloud
732            endif
[1a8fbee]733
[61e07ba]734          else ! no cloud
[1a8fbee]735
[61e07ba]736            if (rain_cloud_above(ix,jy).eq.1) then ! scavenging
737              if (lsp.ge.convp) then
738                clouds(ix,jy,kz,n)=5 ! lsp dominated washout
739              else
740                clouds(ix,jy,kz,n)=4 ! convp dominated washout
741              endif
742            endif
[1a8fbee]743
[61e07ba]744          endif
745        end do
[1a8fbee]746
[61e07ba]747      end do
748    end do
[1a8fbee]749  endif ! END OLD METHOD
[61e07ba]750
751
752     !********* TEST ***************
753     ! WRITE OUT SOME TEST VARIABLES
754     !********* TEST ************'**
755!teller(:)=0
756!virr=virr+1
757!WRITE(aspec, '(i3.3)'), virr
758
759!if (readclouds) then
760!fnameH=trim(zhgpath)//trim(aspec)//'Vertical_placement.txt'
761!else
762!fnameH=trim(zhgpath)//trim(aspec)//'Vertical_placement_old.txt'
763!endif
764!
765!OPEN(UNIT=118, FILE=fnameH,FORM='FORMATTED',STATUS = 'UNKNOWN')
766!do kz_inv=1,nz-1
767!  kz=nz-kz_inv+1
768!  !kz=91
769!  do jy=0,nymin1
770!     do ix=0,nxmin1
771!          if (clouds(ix,jy,kz,n).eq.1) teller(1)=teller(1)+1 ! no precipitation cloud
772!          if (clouds(ix,jy,kz,n).eq.2) teller(2)=teller(2)+1 ! convp dominated rainout
773!          if (clouds(ix,jy,kz,n).eq.3) teller(3)=teller(3)+1 ! lsp dominated rainout
774!          if (clouds(ix,jy,kz,n).eq.4) teller(4)=teller(4)+1 ! convp dominated washout
775!          if (clouds(ix,jy,kz,n).eq.5) teller(5)=teller(5)+1 ! lsp dominated washout
776!         
777!        !  write(*,*) height(kz),teller
778!     end do
779!  end do
780!  write(118,*) height(kz),teller
781!  teller(:)=0
782!end do
783!teller(:)=0
784!write(*,*) teller
785!write(*,*) aspec
786!
787!fnameA=trim(zhgpath)//trim(aspec)//'cloudV.txt'
788!fnameB=trim(zhgpath)//trim(aspec)//'cloudT.txt'
789!fnameC=trim(zhgpath)//trim(aspec)//'cloudB.txt'
790!fnameD=trim(zhgpath)//trim(aspec)//'cloudW.txt'
791!fnameE=trim(zhgpath)//trim(aspec)//'old_cloudV.txt'
792!fnameF=trim(zhgpath)//trim(aspec)//'lsp.txt'
793!fnameG=trim(zhgpath)//trim(aspec)//'convp.txt'
794!if (readclouds) then
795!OPEN(UNIT=111, FILE=fnameA,FORM='FORMATTED',STATUS = 'UNKNOWN')
796!OPEN(UNIT=112, FILE=fnameB,FORM='FORMATTED',STATUS = 'UNKNOWN')
797!OPEN(UNIT=113, FILE=fnameC,FORM='FORMATTED',STATUS = 'UNKNOWN')
798!OPEN(UNIT=114, FILE=fnameD,FORM='FORMATTED',STATUS = 'UNKNOWN')
799!else
800!OPEN(UNIT=115, FILE=fnameE,FORM='FORMATTED',STATUS = 'UNKNOWN')
801!OPEN(UNIT=116, FILE=fnameF,FORM='FORMATTED',STATUS = 'UNKNOWN')
802!OPEN(UNIT=117, FILE=fnameG,FORM='FORMATTED',STATUS = 'UNKNOWN')
803!endif
804!
805!do ix=0,nxmin1
806!if (readclouds) then
807!write(111,*) (icloud_stats(ix,jy,1,n),jy=0,nymin1)
808!write(112,*) (icloud_stats(ix,jy,2,n),jy=0,nymin1)
809!write(113,*) (icloud_stats(ix,jy,3,n),jy=0,nymin1)
810!write(114,*) (icloud_stats(ix,jy,4,n),jy=0,nymin1)
811!else
812!write(115,*) (cloudsh(ix,jy,n),jy=0,nymin1)    !integer
813!write(116,*) (lsprec(ix,jy,1,n),jy=0,nymin1)   !7.83691406E-02
814!write(117,*) (convprec(ix,jy,1,n),jy=0,nymin1) !5.38330078E-02
815!endif
816!end do
817!
818!if (readclouds) then
819!CLOSE(111)
820!CLOSE(112)
821!CLOSE(113)
822!CLOSE(114)
823!else
824!CLOSE(115)
825!CLOSE(116)
826!CLOSE(117)
827!endif
828!
829!END ********* TEST *************** END
830! WRITE OUT SOME TEST VARIABLES
831!END ********* TEST *************** END
832
833
834! PS 2012
835!      lsp=lsprec(ix,jy,1,n)
836!      convp=convprec(ix,jy,1,n)
837!          prec=lsp+convp
838!          if (lsp.gt.convp) then !  prectype='lsp'
839!            lconvectprec = .false.
840!          else ! prectype='cp'
841!            lconvectprec = .true.
842!           endif
843!      else ! windfields does not contain cloud data
844!          rhmin = 0.90 ! standard condition for presence of clouds
845!PS       note that original by Sabine Eckhart was 80%
846!PS       however, for T<-20 C we consider saturation over ice
847!PS       so I think 90% should be enough         
848!          icloudbot(ix,jy,n)=icmv
849!          icloudtop=icmv ! this is just a local variable
850!98        do kz=1,nz
851!            pressure=rho(ix,jy,kz,n)*r_air*tt(ix,jy,kz,n)
852!            rh=qv(ix,jy,kz,n)/f_qvsat(pressure,tt(ix,jy,kz,n))
853!ps            if (prec.gt.0.01) print*,'relhum',prec,kz,rh,height(kz)
854!            if (rh .gt. rhmin) then
855!              if (icloudbot(ix,jy,n) .eq. icmv) then
856!                icloudbot(ix,jy,n)=nint(height(kz))
857!              endif
858!              icloudtop=nint(height(kz)) ! use int to save memory
859!            endif
860    ! end do
861!PS try to get a cloud thicker than 50 m
862!PS if there is at least .01 mm/h  - changed to 0.002 and put into
863!PS parameter precpmin       
864!          if ((icloudbot(ix,jy,n) .eq. icmv .or. &
865!              icloudtop-icloudbot(ix,jy,n) .lt. 50) .and. &
866!              prec .gt. precmin) then
867!            rhmin = rhmin - 0.05
868!            if (rhmin .ge. 0.30) goto 98 ! give up for <= 25% rel.hum.
869!   end if
870
871!PS is based on looking at a limited set of comparison data
872!          if (lconvectprec .and. icloudtop .lt. 6000 .and. &
873!             prec .gt. precmin) then
874!
875!            if (convp .lt. 0.1) then
876!              icloudbot(ix,jy,n) = 500
877!              icloudtop =         8000
878!            else
879!              icloudbot(ix,jy,n) = 0
880!              icloudtop =      10000
881!            endif
882!          endif
883!          if (icloudtop .ne. icmv) then
884!            icloudthck(ix,jy,n) = icloudtop-icloudbot(ix,jy,n)
885!          else
886!            icloudthck(ix,jy,n) = icmv
887!          endif
888!PS  get rid of too thin clouds     
889!          if (icloudthck(ix,jy,n) .lt. 50) then
890!            icloudbot(ix,jy,n)=icmv
891!            icloudthck(ix,jy,n)=icmv
892!          endif
[1a8fbee]893!HG__________________________________
[61e07ba]894!           rcw(ix,jy)=2E-7*prec**0.36
895!           rpc(ix,jy)=prec
[1a8fbee]896!HG end______________________________
[61e07ba]897
[1a8fbee]898!      endif !HG read clouds
[61e07ba]899
900
901
902
[1a8fbee]903!ESO measure CPU time
[61e07ba]904!  call mpif_mtime('verttransform',1)
905
[1a8fbee]906!ESO print out the same measure as in Leo's routine
[61e07ba]907    ! write(*,*) 'verttransform: ', &
908    !      sum(tt(:,:,:,n)*tt(:,:,:,n)), &
909    !      sum(uu(:,:,:,n)*uu(:,:,:,n)),sum(vv(:,:,:,n)*vv(:,:,:,n)),&
910    !      sum(qv(:,:,:,n)*qv(:,:,:,n)),sum(pv(:,:,:,n)*pv(:,:,:,n)),&
911    !      sum(rho(:,:,:,n)*rho(:,:,:,n)),sum(drhodz(:,:,:,n)*drhodz(:,:,:,n)),&
912    !      sum(ww(:,:,:,n)*ww(:,:,:,n)), &
913    !      sum(clouds(:,:,:,n)), sum(cloudsh(:,:,n)),sum(idx),sum(pinmconv)
914end subroutine verttransform_ecmwf
915
Note: See TracBrowser for help on using the repository browser.
hosted by ZAMG