source: flexpart.git/src/gridcheck_gfs.f90 @ 3481cc1

10.4.1_peseiGFS_025bugfixes+enhancementsdevrelease-10release-10.4.1scaling-bug
Last change on this file since 3481cc1 was 3481cc1, checked in by Ignacio Pisso <ip@…>, 4 years ago

move license from headers to a different file

  • Property mode set to 100644
File size: 17.5 KB
Line 
1subroutine gridcheck_gfs
2
3  !**********************************************************************
4  !                                                                     *
5  !             FLEXPART MODEL SUBROUTINE GRIDCHECK                     *
6  !                                                                     *
7  !**********************************************************************
8  !                                                                     *
9  !             AUTHOR:      G. WOTAWA                                  *
10  !             DATE:        1997-08-06                                 *
11  !             LAST UPDATE: 1997-10-10                                 *
12  !                                                                     *
13  !             Update:      1999-02-08, global fields allowed, A. Stohl*
14  !             CHANGE: 17/11/2005, Caroline Forster, GFS data          *
15  !             CHANGE: 11/01/2008, Harald Sodemann, GRIB1/2 input with *
16  !                                 ECMWF grib_api                      *
17  !             CHANGE: 03/12/2008, Harald Sodemann, update to f90 with *
18  !                                 ECMWF grib_api                      *
19  !                                                                     *
20  !   Unified ECMWF and GFS builds                                      *
21  !   Marian Harustak, 12.5.2017                                        *
22  !     - Renamed routine from gridcheck to gridcheck_gfs               *
23  !                                                                     *
24  !**********************************************************************
25  !                                                                     *
26  ! DESCRIPTION:                                                        *
27  !                                                                     *
28  ! THIS SUBROUTINE DETERMINES THE GRID SPECIFICATIONS (LOWER LEFT      *
29  ! LONGITUDE, LOWER LEFT LATITUDE, NUMBER OF GRID POINTS, GRID DIST-   *
30  ! ANCE AND VERTICAL DISCRETIZATION OF THE ECMWF MODEL) FROM THE       *
31  ! GRIB HEADER OF THE FIRST INPUT FILE. THE CONSISTANCY (NO CHANGES    *
32  ! WITHIN ONE FLEXPART RUN) IS CHECKED IN THE ROUTINE "READWIND" AT    *
33  ! ANY CALL.                                                           *
34  !                                                                     *
35  ! XLON0                geographical longitude of lower left gridpoint *
36  ! YLAT0                geographical latitude of lower left gridpoint  *
37  ! NX                   number of grid points x-direction              *
38  ! NY                   number of grid points y-direction              *
39  ! DX                   grid distance x-direction                      *
40  ! DY                   grid distance y-direction                      *
41  ! NUVZ                 number of grid points for horizontal wind      *
42  !                      components in z direction                      *
43  ! NWZ                  number of grid points for vertical wind        *
44  !                      component in z direction                       *
45  ! sizesouth, sizenorth give the map scale (i.e. number of virtual grid*
46  !                      points of the polar stereographic grid):       *
47  !                      used to check the CFL criterion                *
48  ! UVHEIGHT(1)-         heights of gridpoints where u and v are        *
49  ! UVHEIGHT(NUVZ)       given                                          *
50  ! WHEIGHT(1)-          heights of gridpoints where w is given         *
51  ! WHEIGHT(NWZ)                                                        *
52  !                                                                     *
53  !**********************************************************************
54
55  use grib_api
56  use par_mod
57  use com_mod
58  use conv_mod
59  use cmapf_mod, only: stlmbr,stcm2p
60
61  implicit none
62
63  !HSO  parameters for grib_api
64  integer :: ifile
65  integer :: iret
66  integer :: igrib
67  real(kind=4) :: xaux1,xaux2,yaux1,yaux2
68  real(kind=8) :: xaux1in,xaux2in,yaux1in,yaux2in
69  integer :: gribVer,parCat,parNum,typSurf,valSurf,discipl
70  !HSO  end
71  integer :: ix,jy,i,ifn,ifield,j,k,iumax,iwmax,numskip
72  real :: sizesouth,sizenorth,xauxa,pint
73  real :: akm_usort(nwzmax)
74  real,parameter :: eps=0.0001
75
76  ! NCEP GFS
77  real :: pres(nwzmax), help
78
79  integer :: i179,i180,i181
80
81  ! VARIABLES AND ARRAYS NEEDED FOR GRIB DECODING
82
83  integer :: isec1(8),isec2(3)
84  real(kind=4) :: zsec4(jpunp)
85  character(len=1) :: opt
86
87  !HSO  grib api error messages
88  character(len=24) :: gribErrorMsg = 'Error reading grib file'
89  character(len=20) :: gribFunction = 'gridcheckwind_gfs'
90  !
91  if (numbnests.ge.1) then
92  write(*,*) ' ###########################################'
93  write(*,*) ' FLEXPART ERROR SUBROUTINE GRIDCHECK:'
94  write(*,*) ' NO NESTED WINDFIELDAS ALLOWED FOR GFS!      '
95  write(*,*) ' ###########################################'
96  stop
97  endif
98
99  iumax=0
100  iwmax=0
101
102  if(ideltas.gt.0) then
103    ifn=1
104  else
105    ifn=numbwf
106  endif
107  !
108  ! OPENING OF DATA FILE (GRIB CODE)
109  !
1105   call grib_open_file(ifile,path(3)(1:length(3)) &
111         //trim(wfname(ifn)),'r',iret)
112  if (iret.ne.GRIB_SUCCESS) then
113    goto 999   ! ERROR DETECTED
114  endif
115  !turn on support for multi fields messages
116  call grib_multi_support_on
117
118  ifield=0
11910   ifield=ifield+1
120  !
121  ! GET NEXT FIELDS
122  !
123  call grib_new_from_file(ifile,igrib,iret)
124  if (iret.eq.GRIB_END_OF_FILE )  then
125    goto 30    ! EOF DETECTED
126  elseif (iret.ne.GRIB_SUCCESS) then
127    goto 999   ! ERROR DETECTED
128  endif
129
130  !first see if we read GRIB1 or GRIB2
131  call grib_get_int(igrib,'editionNumber',gribVer,iret)
132  call grib_check(iret,gribFunction,gribErrorMsg)
133
134  if (gribVer.eq.1) then ! GRIB Edition 1
135
136  !read the grib1 identifiers
137  call grib_get_int(igrib,'indicatorOfParameter',isec1(6),iret)
138  call grib_check(iret,gribFunction,gribErrorMsg)
139  call grib_get_int(igrib,'indicatorOfTypeOfLevel',isec1(7),iret)
140  call grib_check(iret,gribFunction,gribErrorMsg)
141  call grib_get_int(igrib,'level',isec1(8),iret)
142  call grib_check(iret,gribFunction,gribErrorMsg)
143
144  !get the size and data of the values array
145  call grib_get_real4_array(igrib,'values',zsec4,iret)
146  call grib_check(iret,gribFunction,gribErrorMsg)
147
148  else ! GRIB Edition 2
149
150  !read the grib2 identifiers
151  call grib_get_int(igrib,'discipline',discipl,iret)
152  call grib_check(iret,gribFunction,gribErrorMsg)
153  call grib_get_int(igrib,'parameterCategory',parCat,iret)
154  call grib_check(iret,gribFunction,gribErrorMsg)
155  call grib_get_int(igrib,'parameterNumber',parNum,iret)
156  call grib_check(iret,gribFunction,gribErrorMsg)
157  call grib_get_int(igrib,'typeOfFirstFixedSurface',typSurf,iret)
158  call grib_check(iret,gribFunction,gribErrorMsg)
159  call grib_get_int(igrib,'scaledValueOfFirstFixedSurface', &
160       valSurf,iret)
161  call grib_check(iret,gribFunction,gribErrorMsg)
162
163  !convert to grib1 identifiers
164  isec1(6)=-1
165  isec1(7)=-1
166  isec1(8)=-1
167  if ((parCat.eq.2).and.(parNum.eq.2).and.(typSurf.eq.100)) then ! U
168    isec1(6)=33          ! indicatorOfParameter
169    isec1(7)=100         ! indicatorOfTypeOfLevel
170    isec1(8)=valSurf/100 ! level, convert to hPa
171  elseif ((parCat.eq.3).and.(parNum.eq.5).and.(typSurf.eq.1)) then ! TOPO
172    isec1(6)=7           ! indicatorOfParameter
173    isec1(7)=1           ! indicatorOfTypeOfLevel
174    isec1(8)=0
175  elseif ((parCat.eq.0).and.(parNum.eq.0).and.(typSurf.eq.1) &
176       .and.(discipl.eq.2)) then ! LSM
177    isec1(6)=81          ! indicatorOfParameter
178    isec1(7)=1           ! indicatorOfTypeOfLevel
179    isec1(8)=0
180  endif
181
182  if (isec1(6).ne.-1) then
183  !  get the size and data of the values array
184    call grib_get_real4_array(igrib,'values',zsec4,iret)
185    call grib_check(iret,gribFunction,gribErrorMsg)
186  endif
187
188  endif ! gribVer
189
190  if(ifield.eq.1) then
191
192  !get the required fields from section 2
193  !store compatible to gribex input
194  call grib_get_int(igrib,'numberOfPointsAlongAParallel', &
195       isec2(2),iret)
196  call grib_check(iret,gribFunction,gribErrorMsg)
197  call grib_get_int(igrib,'numberOfPointsAlongAMeridian', &
198       isec2(3),iret)
199  call grib_check(iret,gribFunction,gribErrorMsg)
200  call grib_get_real8(igrib,'longitudeOfFirstGridPointInDegrees', &
201       xaux1in,iret)
202  call grib_check(iret,gribFunction,gribErrorMsg)
203  call grib_get_real8(igrib,'longitudeOfLastGridPointInDegrees', &
204       xaux2in,iret)
205  call grib_check(iret,gribFunction,gribErrorMsg)
206  call grib_get_real8(igrib,'latitudeOfLastGridPointInDegrees', &
207       yaux1in,iret)
208  call grib_check(iret,gribFunction,gribErrorMsg)
209  call grib_get_real8(igrib,'latitudeOfFirstGridPointInDegrees', &
210       yaux2in,iret)
211  call grib_check(iret,gribFunction,gribErrorMsg)
212
213  ! Fix for flexpart.eu ticket #48
214  if (xaux2in.lt.0) xaux2in = 359.0
215
216  xaux1=xaux1in
217  xaux2=xaux2in
218  yaux1=yaux1in
219  yaux2=yaux2in
220
221  nxfield=isec2(2)
222  ny=isec2(3)
223  if((abs(xaux1).lt.eps).and.(xaux2.ge.359)) then ! NCEP DATA FROM 0 TO
224    xaux1=-179.0                             ! 359 DEG EAST ->
225    xaux2=-179.0+360.-360./real(nxfield)    ! TRANSFORMED TO -179
226  endif                                      ! TO 180 DEG EAST
227  if (xaux1.gt.180) xaux1=xaux1-360.0
228  if (xaux2.gt.180) xaux2=xaux2-360.0
229  if (xaux1.lt.-180) xaux1=xaux1+360.0
230  if (xaux2.lt.-180) xaux2=xaux2+360.0
231  if (xaux2.lt.xaux1) xaux2=xaux2+360.
232  xlon0=xaux1
233  ylat0=yaux1
234  dx=(xaux2-xaux1)/real(nxfield-1)
235  dy=(yaux2-yaux1)/real(ny-1)
236  dxconst=180./(dx*r_earth*pi)
237  dyconst=180./(dy*r_earth*pi)
238  !HSO end edits
239
240
241  ! Check whether fields are global
242  ! If they contain the poles, specify polar stereographic map
243  ! projections using the stlmbr- and stcm2p-calls
244  !***********************************************************
245
246    xauxa=abs(xaux2+dx-360.-xaux1)
247    if (xauxa.lt.0.001) then
248      nx=nxfield+1                 ! field is cyclic
249      xglobal=.true.
250      if (abs(nxshift).ge.nx) &
251           stop 'nxshift in file par_mod is too large'
252      xlon0=xlon0+real(nxshift)*dx
253    else
254      nx=nxfield
255      xglobal=.false.
256      if (nxshift.ne.0) &
257           stop 'nxshift (par_mod) must be zero for non-global domain'
258    endif
259    nxmin1=nx-1
260    nymin1=ny-1
261    if (xlon0.gt.180.) xlon0=xlon0-360.
262    xauxa=abs(yaux1+90.)
263    if (xglobal.and.xauxa.lt.0.001) then
264      sglobal=.true.               ! field contains south pole
265  ! Enhance the map scale by factor 3 (*2=6) compared to north-south
266  ! map scale
267      sizesouth=6.*(switchsouth+90.)/dy
268      call stlmbr(southpolemap,-90.,0.)
269      call stcm2p(southpolemap,0.,0.,switchsouth,0.,sizesouth, &
270           sizesouth,switchsouth,180.)
271      switchsouthg=(switchsouth-ylat0)/dy
272    else
273      sglobal=.false.
274      switchsouthg=999999.
275    endif
276    xauxa=abs(yaux2-90.)
277    if (xglobal.and.xauxa.lt.0.001) then
278      nglobal=.true.               ! field contains north pole
279  ! Enhance the map scale by factor 3 (*2=6) compared to north-south
280  ! map scale
281      sizenorth=6.*(90.-switchnorth)/dy
282      call stlmbr(northpolemap,90.,0.)
283      call stcm2p(northpolemap,0.,0.,switchnorth,0.,sizenorth, &
284           sizenorth,switchnorth,180.)
285      switchnorthg=(switchnorth-ylat0)/dy
286    else
287      nglobal=.false.
288      switchnorthg=999999.
289    endif
290  endif ! ifield.eq.1
291
292  if (nxshift.lt.0) stop 'nxshift (par_mod) must not be negative'
293  if (nxshift.ge.nxfield) stop 'nxshift (par_mod) too large'
294
295  ! NCEP ISOBARIC LEVELS
296  !*********************
297
298  if((isec1(6).eq.33).and.(isec1(7).eq.100)) then ! check for U wind
299    iumax=iumax+1
300    pres(iumax)=real(isec1(8))*100.0
301  endif
302
303
304  i179=nint(179./dx)
305  if (dx.lt.0.7) then
306    i180=nint(180./dx)+1    ! 0.5 deg data
307  else
308    i180=nint(179./dx)+1    ! 1 deg data
309  endif
310  i181=i180+1
311
312
313  ! NCEP TERRAIN
314  !*************
315
316  if((isec1(6).eq.007).and.(isec1(7).eq.001)) then
317    do jy=0,ny-1
318      do ix=0,nxfield-1
319        help=zsec4(nxfield*(ny-jy-1)+ix+1)
320        if(ix.le.i180) then
321          oro(i179+ix,jy)=help
322          excessoro(i179+ix,jy)=0.0 ! ISOBARIC SURFACES: SUBGRID TERRAIN DISREGARDED
323        else
324          oro(ix-i181,jy)=help
325          excessoro(ix-i181,jy)=0.0 ! ISOBARIC SURFACES: SUBGRID TERRAIN DISREGARDED
326        endif
327      end do
328    end do
329  endif
330
331  ! NCEP LAND SEA MASK
332  !*******************
333
334  if((isec1(6).eq.081).and.(isec1(7).eq.001)) then
335    do jy=0,ny-1
336      do ix=0,nxfield-1
337        help=zsec4(nxfield*(ny-jy-1)+ix+1)
338        if(ix.le.i180) then
339          lsm(i179+ix,jy)=help
340        else
341          lsm(ix-i181,jy)=help
342        endif
343      end do
344    end do
345  endif
346
347  call grib_release(igrib)
348
349  goto 10                      !! READ NEXT LEVEL OR PARAMETER
350  !
351  ! CLOSING OF INPUT DATA FILE
352  !
353
354  ! HSO
35530   continue
356  call grib_close_file(ifile)
357  ! HSO end edits
358
359  nuvz=iumax
360  nwz =iumax
361  nlev_ec=iumax
362
363  if (nx.gt.nxmax) then
364   write(*,*) 'FLEXPART error: Too many grid points in x direction.'
365    write(*,*) 'Reduce resolution of wind fields.'
366    write(*,*) 'Or change parameter settings in file par_mod.'
367    write(*,*) nx,nxmax
368    stop
369  endif
370
371  if (ny.gt.nymax) then
372   write(*,*) 'FLEXPART error: Too many grid points in y direction.'
373    write(*,*) 'Reduce resolution of wind fields.'
374    write(*,*) 'Or change parameter settings in file par_mod.'
375    write(*,*) ny,nymax
376    stop
377  endif
378
379  if (nuvz.gt.nuvzmax) then
380    write(*,*) 'FLEXPART error: Too many u,v grid points in z '// &
381         'direction.'
382    write(*,*) 'Reduce resolution of wind fields.'
383    write(*,*) 'Or change parameter settings in file par_mod.'
384    write(*,*) nuvz,nuvzmax
385    stop
386  endif
387
388  if (nwz.gt.nwzmax) then
389    write(*,*) 'FLEXPART error: Too many w grid points in z '// &
390         'direction.'
391    write(*,*) 'Reduce resolution of wind fields.'
392    write(*,*) 'Or change parameter settings in file par_mod.'
393    write(*,*) nwz,nwzmax
394    stop
395  endif
396
397  ! If desired, shift all grids by nxshift grid cells
398  !**************************************************
399
400  if (xglobal) then
401    call shift_field_0(oro,nxfield,ny)
402    call shift_field_0(lsm,nxfield,ny)
403    call shift_field_0(excessoro,nxfield,ny)
404  endif
405
406  ! Output of grid info
407  !********************
408
409  if (lroot) then
410    write(*,*)
411    write(*,*)
412    write(*,'(a,2i7)') 'Vertical levels in NCEP data: ', &
413         nuvz,nwz
414    write(*,*)
415    write(*,'(a)') 'Mother domain:'
416    write(*,'(a,f10.2,a1,f10.2,a,f10.2)') '  Longitude range: ', &
417         xlon0,' to ',xlon0+(nx-1)*dx,'   Grid distance: ',dx
418    write(*,'(a,f10.2,a1,f10.2,a,f10.2)') '  Latitude range : ', &
419         ylat0,' to ',ylat0+(ny-1)*dy,'   Grid distance: ',dy
420    write(*,*)
421  end if
422
423  ! CALCULATE VERTICAL DISCRETIZATION OF ECMWF MODEL
424  ! PARAMETER akm,bkm DESCRIBE THE HYBRID "ETA" COORDINATE SYSTEM
425
426  numskip=nlev_ec-nuvz  ! number of ecmwf model layers not used
427                        ! by trajectory model
428  do i=1,nwz
429    j=numskip+i
430    k=nlev_ec+1+numskip+i
431    akm_usort(nwz-i+1)=pres(nwz-i+1)
432    bkm(nwz-i+1)=0.0
433  end do
434
435  !******************************
436  ! change Sabine Eckhardt: akm should always be in descending order ... readwind adapted!
437  !******************************
438      do i=1,nwz
439         if (akm_usort(1).gt.akm_usort(2)) then
440            akm(i)=akm_usort(i)
441         else
442            akm(i)=akm_usort(nwz-i+1)
443         endif
444      end do
445
446  !
447  ! CALCULATION OF AKZ, BKZ
448  ! AKZ,BKZ: model discretization parameters at the center of each model
449  !     layer
450  !
451  ! Assign the 10 m winds to an artificial model level with akz=0 and bkz=1.0,
452  ! i.e. ground level
453  !*****************************************************************************
454
455  do i=1,nuvz
456     akz(i)=akm(i)
457     bkz(i)=bkm(i)
458  end do
459
460  ! NOTE: In FLEXPART versions up to 4.0, the number of model levels was doubled
461  ! upon the transformation to z levels. In order to save computer memory, this is
462  ! not done anymore in the standard version. However, this option can still be
463  ! switched on by replacing the following lines with those below, that are
464  ! currently commented out. For this, similar changes are necessary in
465  ! verttransform.f and verttranform_nests.f
466  !*****************************************************************************
467
468  nz=nuvz
469  if (nz.gt.nzmax) stop 'nzmax too small'
470  do i=1,nuvz
471    aknew(i)=akz(i)
472    bknew(i)=bkz(i)
473  end do
474
475  ! Switch on following lines to use doubled vertical resolution
476  !*************************************************************
477  !nz=nuvz+nwz-1
478  !if (nz.gt.nzmax) stop 'nzmax too small'
479  !do 100 i=1,nwz
480  !  aknew(2*(i-1)+1)=akm(i)
481  !00     bknew(2*(i-1)+1)=bkm(i)
482  !do 110 i=2,nuvz
483  !  aknew(2*(i-1))=akz(i)
484  !10     bknew(2*(i-1))=bkz(i)
485  ! End doubled vertical resolution
486
487
488  ! Determine the uppermost level for which the convection scheme shall be applied
489  ! by assuming that there is no convection above 50 hPa (for standard SLP)
490  !*****************************************************************************
491
492  do i=1,nuvz-2
493    pint=akz(i)+bkz(i)*101325.
494    if (pint.lt.5000.) goto 96
495  end do
49696   nconvlev=i
497  if (nconvlev.gt.nconvlevmax-1) then
498    nconvlev=nconvlevmax-1
499    write(*,*) 'Attention, convection only calculated up to ', &
500         akz(nconvlev)+bkz(nconvlev)*1013.25,' hPa'
501  endif
502
503  return
504
505999   write(*,*)
506  write(*,*) ' ###########################################'// &
507       '###### '
508  write(*,*) '       TRAJECTORY MODEL SUBROUTINE GRIDCHECK:'
509  write(*,*) ' CAN NOT OPEN INPUT DATA FILE '//wfname(ifn)
510  write(*,*) ' ###########################################'// &
511       '###### '
512  write(*,*)
513  write(*,'(a)') '!!! PLEASE INSERT A NEW CD-ROM AND   !!!'
514  write(*,'(a)') '!!! PRESS ANY KEY TO CONTINUE...     !!!'
515  write(*,'(a)') '!!! ...OR TERMINATE FLEXPART PRESSING!!!'
516  write(*,'(a)') '!!! THE "X" KEY...                   !!!'
517  write(*,*)
518  read(*,'(a)') opt
519  if(opt.eq.'X') then
520    stop
521  else
522    goto 5
523  endif
524
525end subroutine gridcheck_gfs
Note: See TracBrowser for help on using the repository browser.
hosted by ZAMG