orog_mask_tools  1.13.0
 All Data Structures Files Functions Variables Pages
mtnlm7_oclsm.F
Go to the documentation of this file.
1 C> @file
2 C> Terrain maker for global spectral model.
3 C> @author Mark Iredell @date 92-04-16
4 
5 C> This program creates 7 terrain-related files computed from the
6 C> GMTED2010 terrain dataset. The model physics grid parameters and
7 C> spectral truncation and filter parameters are read by this program as
8 C> input.
9 C>
10 C> The 7 files produced are:
11 C> 1. sea-land mask on model physics grid
12 C> 2. gridded orography on model physics grid
13 C> 3. mountain std dev on model physics grid
14 C> 4. spectral orography in spectral domain
15 C> 5. unfiltered gridded orography on model physics grid
16 C> 6. grib sea-land mask on model physics grid
17 C> 7. grib gridded orography on model physics grid
18 C>
19 C> The orography is only filtered for wavenumbers greater than nf0. For
20 C> wavenumbers n between nf0 and nf1, the orography is filtered by the
21 C> factor 1-((n-nf0)/(nf1-nf0))**2. The filtered orography will not have
22 C> information beyond wavenumber nf1.
23 C>
24 C> PROGRAM HISTORY LOG:
25 C> - 92-04-16 IREDELL
26 C> - 98-02-02 IREDELL FILTER
27 C> - 98-05-31 HONG Modified for subgrid orography used in Kim's scheme
28 C> - 98-12-31 HONG Modified for high-resolution GTOPO orography
29 C> - 99-05-31 HONG Modified for getting OL4 (mountain fraction)
30 C> - 00-02-10 Moorthi's modifications
31 C> - 00-04-11 HONG Modified for reduced grids
32 C> - 00-04-12 Iredell Modified for reduced grids
33 C> - 02-01-07 (*j*) modified for principal axes of orography
34 C> There are now 14 files, 4 additional for lm mb
35 C> - 04-04-04 (*j*) re-Test on IST/ilen calc for sea-land mask(*j*)
36 C> - 04-09-04 minus sign here in MAKEOA IST and IEN as in MAKEMT!
37 C> - 05-09-05 if test on HK and HLPRIM for GAMMA SQRT
38 C> - 07-08-07 replace 8' with 30" incl GICE, conintue w/ S-Y. lake slm
39 C> - 08-08-07 All input 30", UMD option, and filter as described below
40 C> Quadratic filter applied by default.
41 C> NF0 is normally set to an even value beyond the previous truncation,
42 C> for example, for jcap=382, NF0=254+2
43 C> NF1 is set as jcap+2 (and/or nearest even), eg., for t382, NF1=382+2=384
44 C> if no filter is desired then NF1=NF0=0 and ORF=ORO
45 C> but if no filter but spectral to grid (with gibbs) then NF1=jcap+2, and NF1=jcap+1
46 C>
47 C> INPUT FILES:
48 C> - UNIT5 - PHYSICS LONGITUDES (IM), PHYSICS LATITUDES (JM),
49 C> SPECTRAL TRUNCATION (NM), RHOMBOIDAL FLAG (NR),
50 C> AND FIRST AND SECOND FILTER PARAMETERS (NF0,NF1).
51 C> RESPECTIVELY READ IN FREE FORMAT.
52 C> - NCID - GMTED2010 USGS orography (NetCDF)
53 C> - NCID - 30" UMD land cover mask. (NetCDF)
54 C> - NCID - GICE Grumbine 30" RAMP Antarctica orog IMNx3601. (NetCDF)
55 C> - UNIT25 - Ocean land-sea mask on gaussian grid
56 C>
57 C> OUTPUT FILES:
58 C> - UNIT51 - SEA-LAND MASK (IM,JM)
59 C> - UNIT52 - GRIDDED OROGRAPHY (IM,JM)
60 C> - UNIT54 - SPECTRAL OROGRAPHY ((NM+1)*((NR+1)*NM+2))
61 C> - UNIT55 - UNFILTERED GRIDDED OROGRAPHY (IM,JM)
62 C> - UNIT57 - GRIB GRIDDED OROGRAPHY (IM,JM)
63 C>
64 C> SUBPROGRAMS CALLED:
65 C> - UNIQUE:
66 C> - TERSUB - MAIN SUBPROGRAM
67 C> - SPLAT - COMPUTE GAUSSIAN LATITUDES OR EQUALLY-SPACED LATITUDES
68 C> - LIBRARY:
69 C> - SPTEZ - SPHERICAL TRANSFORM
70 C> - GBYTES - UNPACK BITS
71 C>
72 C> @return 0 for success, error code otherwise.
73  include 'netcdf.inc'
74  logical fexist, opened
75  integer fsize, ncid, error, id_dim, nx, ny
76  character(len=256) :: outgrid = "none"
77  character(len=256) :: inputorog = "none"
78  character(len=256) :: merge_file = "none"
79  logical :: mask_only = .false.
80  integer :: mtnres,im,jm,nm,nr,nf0,nf1,efac,blat,nw
81  fsize=65536
82  READ(5,*) mtnres,im,jm,nm,nr,nf0,nf1,efac,blat
83  READ(5,*) outgrid
84  READ(5,*) inputorog
85  READ(5,*) mask_only
86  READ(5,*) merge_file
87 ! MTNRES=1
88 ! IM=48
89 ! JM=48
90 ! NM=46
91 ! NF0=0
92 ! NF1=0
93 ! efac=0
94 ! blat=0
95 ! NR=0
96 ! OUTGRID = "C48_grid.tile1.nc"
97 ! INPUTOROG = "oro.288x144.nc"
98  print*, "INPUTOROG=", trim(inputorog)
99  print*, "IM,JM=", im, jm
100  print*, "MASK_ONLY", mask_only
101  print*, "MERGE_FILE", trim(merge_file)
102 ! --- MTNRES defines the input (highest) elev resolution
103 ! --- =1 is topo30 30" in units of 1/2 minute.
104 ! so MTNRES for old values must be *2.
105 ! =16 is now Song Yu's 8' orog the old ops standard
106 ! --- other possibilities are =8 for 4' and =4 for 2' see
107 ! HJ for T1000 test. Must set to 1 for now.
108  mtnres=1
109  print*, mtnres,im,jm,nm,nr,nf0,nf1,efac,blat
110  nw=(nm+1)*((nr+1)*nm+2)
111  imn = 360*120/mtnres
112  jmn = 180*120/mtnres
113  print *, ' Starting terr12 mtnlm7_slm30.f IMN,JMN:',imn,jmn
114 
115 ! --- read the grid resolution if the OUTGRID exists.
116  if( trim(outgrid) .NE. "none" ) then
117  inquire(file=trim(outgrid), exist=fexist)
118  if(.not. fexist) then
119  print*, "file "//trim(outgrid)//" does not exist"
120  CALL errexit(4)
121  endif
122  do ncid = 103, 512
123  inquire( ncid,opened=opened )
124  if( .NOT.opened )exit
125  end do
126 
127  print*, "outgrid=", trim(outgrid)
128  error=nf__open(trim(outgrid),nf_nowrite,fsize,ncid)
129  call netcdf_err(error, 'Open file '//trim(outgrid) )
130  error=nf_inq_dimid(ncid, 'nx', id_dim)
131  call netcdf_err(error, 'inquire dimension nx from file '//
132  & trim(outgrid) )
133  error=nf_inq_dimlen(ncid,id_dim,nx)
134  call netcdf_err(error, 'inquire dimension nx length '//
135  & 'from file '//trim(outgrid) )
136 
137  error=nf_inq_dimid(ncid, 'ny', id_dim)
138  call netcdf_err(error, 'inquire dimension ny from file '//
139  & trim(outgrid) )
140  error=nf_inq_dimlen(ncid,id_dim,ny)
141  call netcdf_err(error, 'inquire dimension ny length '//
142  & 'from file '//trim(outgrid) )
143  print*, "nx = ", nx
144  if(im .ne. nx/2) then
145  print*, "IM=",im, " /= grid file nx/2=",nx/2
146  print*, "Set IM = ", nx/2
147  im = nx/2
148  endif
149  if(jm .ne. ny/2) then
150  print*, "JM=",jm, " /= grid file ny/2=",ny/2
151  print*, "Set JM = ", ny/2
152  jm = ny/2
153  endif
154  error=nf_close(ncid)
155  call netcdf_err(error, 'close file '//trim(outgrid) )
156 
157  endif
158 
159  CALL tersub(imn,jmn,im,jm,nm,nr,nf0,nf1,nw,efac,blat,
160  & outgrid,inputorog,mask_only,merge_file)
161  stop
162  END
163 
186  SUBROUTINE tersub(IMN,JMN,IM,JM,NM,NR,NF0,NF1,NW,EFAC,BLAT,
187  & outgrid,inputorog,mask_only,merge_file)
188  implicit none
189  include 'netcdf.inc'
190 C
191  integer :: imn,jmn,im,jm,nm,nr,nf0,nf1,nw
192  character(len=*), intent(in) :: outgrid
193  character(len=*), intent(in) :: inputorog
194  character(len=*), intent(in) :: merge_file
195 
196  logical, intent(in) :: mask_only
197 
198  real, parameter :: missing_value=-9999.
199  real, PARAMETER :: pi=3.1415926535897931
200  integer, PARAMETER :: nmt=14
201 
202  integer :: efac,blat,zsave1,zsave2
203  integer :: mskocn,notocn
204  integer :: i,j,nx,ny,ncid,js,jn,iw,ie,k,it,jt,error,id_dim
205  integer :: id_var,nx_in,ny_in,fsize,wgta,in,inw,ine,is,isw,ise
206  integer :: m,n,imt,iret,ios,iosg,latg2,istat,itest,jtest
207  integer :: i_south_pole,j_south_pole,i_north_pole,j_north_pole
208  integer :: maxc3,maxc4,maxc5,maxc6,maxc7,maxc8
209  integer(1) :: i3save
210  integer(2) :: i2save
211 
212  integer, allocatable :: jst(:),jen(:),kpds(:),kgds(:),numi(:)
213  integer, allocatable :: lonsperlat(:)
214 
215  integer, allocatable :: ist(:,:),ien(:,:),zslmx(:,:)
216  integer, allocatable :: zavg(:,:),zslm(:,:)
217  integer(1), allocatable :: umd(:,:)
218  integer(2), allocatable :: glob(:,:)
219 
220  integer, allocatable :: iwork(:,:,:)
221 
222  real :: degrad,maxlat, minlat,timef,tbeg,tend,tbeg1
223  real :: phi,delxn,rs,rn,slma,oroa,vara,var4a,xn,xs,fff,www
224  real :: sumdif,avedif
225 
226  real, allocatable :: cosclt(:),wgtclt(:),rclt(:),xlat(:),diffx(:)
227  real, allocatable :: xlon(:),ors(:),oaa(:),ola(:),glat(:)
228 
229  real, allocatable :: geolon(:,:),geolon_c(:,:),dx(:,:)
230  real, allocatable :: geolat(:,:),geolat_c(:,:),dy(:,:)
231  real, allocatable :: slm(:,:),oro(:,:),var(:,:),orf(:,:)
232  real, allocatable :: land_frac(:,:),lake_frac(:,:)
233  real, allocatable :: theta(:,:),gamma(:,:),sigma(:,:),elvmax(:,:)
234  real, allocatable :: var4(:,:),slmi(:,:)
235  real, allocatable :: work1(:,:),work2(:,:),work3(:,:),work4(:,:)
236  real, allocatable :: work5(:,:),work6(:,:)
237  real, allocatable :: tmpvar(:,:)
238  real, allocatable :: slm_in(:,:), lon_in(:,:), lat_in(:,:)
239  real(4), allocatable:: gice(:,:),oclsm(:,:)
240 
241  real, allocatable :: oa(:,:,:),ol(:,:,:),hprime(:,:,:)
242  real, allocatable :: oa_in(:,:,:), ol_in(:,:,:)
243 
244 
245  complex :: ffj(im/2+1)
246 
247  logical :: grid_from_file,output_binary,fexist,opened
248  logical :: spectr, revlat, filter
249 
250  logical :: is_south_pole(im,jm), is_north_pole(im,jm)
251  logical :: lb(im*jm)
252 
253  output_binary = .false.
254  tbeg1=timef()
255  tbeg=timef()
256  fsize = 65536
257 ! integers
258  allocate (jst(jm),jen(jm),kpds(200),kgds(200),numi(jm))
259  allocate (lonsperlat(jm/2))
260  allocate (ist(im,jm),ien(im,jm),zslmx(2700,1350))
261  allocate (glob(imn,jmn))
262 
263 ! reals
264  allocate (cosclt(jm),wgtclt(jm),rclt(jm),xlat(jm),diffx(jm/2))
265  allocate (xlon(im),ors(nw),oaa(4),ola(4),glat(jmn))
266 
267  allocate (zavg(imn,jmn))
268  allocate (zslm(imn,jmn))
269  allocate (umd(imn,jmn))
270 
271 !
272 ! SET CONSTANTS AND ZERO FIELDS
273 !
274  degrad = 180./pi
275  spectr = nm .GT. 0 ! if NM <=0 grid is assumed lat/lon
276  filter = .true. ! Spectr Filter defaults true and set by NF1 & NF0
277  revlat = blat .LT. 0 ! Reverse latitude/longitude for output
278  mskocn = 1 ! Ocean land sea mask =1, =0 if not present
279  notocn = 1 ! =1 Ocean lsm input reverse: Ocean=1, land=0
280 ! --- The LSM Gaussian file from the ocean model sometimes arrives with
281 ! --- 0=Ocean and 1=Land or it arrives with 1=Ocean and 0=land without
282 ! --- metadata to distinguish its disposition. The AI below mitigates this.
283 
284  print *,' In TERSUB'
285  if (mskocn .eq. 1)then
286  print *,' Ocean Model LSM Present and '
287  print *, ' Overrides OCEAN POINTS in LSM: mskocn=',mskocn
288  if (notocn .eq. 1)then
289  print *,' Ocean LSM Reversed: NOTOCN=',notocn
290  endif
291  endif
292 
293  print *,' Attempt to open/read UMD 30sec slmsk.'
294 
295  error=nf__open("./landcover.umd.30s.nc",nf_nowrite,fsize,ncid)
296  call netcdf_err(error, 'Open file landcover.umd.30s.nc' )
297  error=nf_inq_varid(ncid, 'land_mask', id_var)
298  call netcdf_err(error, 'Inquire varid of land_mask')
299  error=nf_get_var_int1(ncid, id_var, umd)
300  call netcdf_err(error, 'Inquire data of land_mask')
301  error = nf_close(ncid)
302 
303  print *,' UMD lake, UMD(50,50)=',umd(50,50)
304 C
305 C- READ_G for global 30" terrain
306 C
307  print *,' Call read_g to read global topography'
308  call read_g(glob)
309 ! --- transpose even though glob 30" is from S to N and NCEP std is N to S
310  do j=1,jmn/2
311  do i=1,imn
312  jt=jmn - j + 1
313  i2save = glob(i,j)
314  glob(i,j)=glob(i,jt)
315  glob(i,jt) = i2save
316  enddo
317  enddo
318 ! --- transpose glob as USGS 30" is from dateline and NCEP std is 0
319  do j=1,jmn
320  do i=1,imn/2
321  it=imn/2 + i
322  i2save = glob(i,j)
323  glob(i,j)=glob(it,j)
324  glob(it,j) = i2save
325  enddo
326  enddo
327  print *,' After read_g, glob(500,500)=',glob(500,500)
328 !
329 
330 ! --- IMN,JMN
331  print*, ' IM, JM, NM, NR, NF0, NF1, EFAC, BLAT'
332  print*, im,jm,nm,nr,nf0,nf1,efac,blat
333  print *,' imn,jmn,glob(imn,jmn)=',imn,jmn,glob(imn,jmn)
334  print *,' UBOUND ZAVG=',ubound(zavg)
335  print *,' UBOUND glob=',ubound(glob)
336  print *,' UBOUND ZSLM=',ubound(zslm)
337  print *,' UBOUND GICE=',imn+1,3601
338  print *,' UBOUND OCLSM=',im,jm
339 !
340 ! --- 0 is ocean and 1 is land for slm
341 !
342 C
343 ! --- ZSLM initialize with all land 1, ocean 0
344  zslm=1
345 ! --- ZAVG initialize from glob
346  zavg=glob
347 
348 ! --- transpose mask even though glob 30" is from N to S and NCEP std is S to N
349  do j=1,jmn/2
350  do i=1,imn
351  jt=jmn - j + 1
352  i3save = umd(i,j)
353  umd(i,j)=umd(i,jt)
354  umd(i,jt) = i3save
355  enddo
356  enddo
357 ! --- transpose UMD as USGS 30" is from dateline and NCEP std is 0
358  do j=1,jmn
359  do i=1,imn/2
360  it=imn/2 + i
361  i3save = umd(i,j)
362  umd(i,j)=umd(it,j)
363  umd(it,j) = i3save
364  enddo
365  enddo
366 ! --- Non-land is 0.
367  do j=1,jmn
368  do i=1,imn
369  if ( umd(i,j) .eq. 0 ) zslm(i,j) = 0
370  enddo
371  enddo
372 
373  deallocate (zslmx,umd,glob)
374 ! ---
375 ! --- Fixing an error in the topo 30" data set at pole (-9999).
376  do i=1,imn
377  zslm(i,1)=0
378  zslm(i,jmn)=1
379  enddo
380 !
381 ! print *,' kount1,2,ZAVG(1,1),ZAVG(imn,jmn),ZAVG(500,500)',
382 ! & kount,kount2,ZAVG(1,1),ZAVG(imn,jmn),ZAVG(500,500)
383 ! --- The center of pixel (1,1) is 89.9958333N/179.9958333W with dx/dy
384 ! --- spacing of 1/120 degrees.
385 !
386 ! READ REDUCED GRID EXTENTS IF GIVEN
387 !
388  read(20,*,iostat=ios) latg2,lonsperlat
389  if(ios.ne.0.or.2*latg2.ne.jm) then
390  do j=1,jm
391  numi(j)=im
392  enddo
393  print *,ios,latg2,'COMPUTE TERRAIN ON A FULL GAUSSIAN GRID'
394  else
395  do j=1,jm/2
396  numi(j)=lonsperlat(j)
397  enddo
398  do j=jm/2+1,jm
399  numi(j)=lonsperlat(jm+1-j)
400  enddo
401  print *,ios,latg2,'COMPUTE TERRAIN ON A REDUCED GAUSSIAN GRID',
402  & numi
403 C print *,ios,latg2,'COMPUTE TERRAIN ON A REDUCED GAUSSIAN GRID'
404  endif
405 ! print *,ios,latg2,'TERRAIN ON GAUSSIAN GRID',numi
406 
407 !
408 ! This code assumes that lat runs from north to south for gg!
409 !
410 
411  print *,' SPECTR=',spectr,' REVLAT=',revlat,' ** with GICE-07 **'
412  IF (spectr) THEN
413  CALL splat(4,jm,cosclt,wgtclt)
414  DO j=1,jm/2
415  rclt(j) = acos(cosclt(j))
416  ENDDO
417  DO j = 1,jm/2
418  phi = rclt(j) * degrad
419  xlat(j) = 90. - phi
420  xlat(jm-j+1) = phi - 90.
421  ENDDO
422  ELSE
423  CALL splat(0,jm,cosclt,wgtclt)
424  DO j=1,jm
425  rclt(j) = acos(cosclt(j))
426  xlat(j) = 90.0 - rclt(j) * degrad
427  ENDDO
428  ENDIF
429 
430  allocate (gice(imn+1,3601))
431 !
432  sumdif = 0.
433  DO j = jm/2,2,-1
434  diffx(j) = xlat(j) - xlat(j-1)
435  sumdif = sumdif + diffx(j)
436  ENDDO
437  avedif=sumdif/(float(jm/2))
438 ! print *,' XLAT= avedif: ',avedif
439 ! write (6,107) (xlat(J)-xlat(j-1),J=JM,2,-1)
440  print *,' XLAT='
441  write (6,106) (xlat(j),j=jm,1,-1)
442  106 format( 10(f7.3,1x))
443  107 format( 10(f9.5,1x))
444 C
445  delxn = 360./imn ! MOUNTAIN DATA RESOLUTION
446 C
447  DO j=1,jmn
448  glat(j) = -90. + (j-1) * delxn + delxn * 0.5
449  ENDDO
450  print *,
451  & ' Before GICE ZAVG(1,2)=',zavg(1,2),zslm(1,2)
452  print *,
453  & ' Before GICE ZAVG(1,12)=',zavg(1,12),zslm(1,12)
454  print *,
455  & ' Before GICE ZAVG(1,52)=',zavg(1,52),zslm(1,52)
456  print *,
457  & ' Before GICE ZAVG(1,112)=',zavg(1,jmn-112),zslm(1,112)
458 
459 ! Read 30-sec Antarctica RAMP data. Points scan from South
460 ! to North, and from Greenwich to Greenwich.
461 
462 ! The error handling here needs to be cleaned up.
463  iosg = 0
464  error=nf__open("./topography.antarctica.ramp.30s.nc",
465  & nf_nowrite,fsize,ncid)
466  call netcdf_err(error, 'Opening RAMP topo file' )
467  error=nf_inq_varid(ncid, 'topo', id_var)
468  call netcdf_err(error, 'Inquire varid of RAMP topo')
469  error=nf_get_var_real(ncid, id_var, gice)
470  iosg=error
471  call netcdf_err(error, 'Inquire data of RAMP topo')
472  error = nf_close(ncid)
473 
474  if(iosg .ne. 0 ) then
475  print *,' *** Err on reading GICE record, iosg=',iosg
476  print *,' exec continues but NO GICE correction done '
477  else
478  print *,' GICE 30" Antarctica RAMP orog 43201x3601 read OK'
479  print *,' Processing! '
480  print *,' Processing! '
481  print *,' Processing! '
482  do j = 1, 3601
483  do i = 1, imn
484  zsave1 = zavg(i,j)
485  zsave2 = zslm(i,j)
486  if( gice(i,j) .ne. -99. .and. gice(i,j) .ne. -1.0 ) then
487  if ( gice(i,j) .gt. 0.) then
488  zavg(i,j) = int( gice(i,j) + 0.5 )
489 !! --- for GICE values less than or equal to 0 (0, -1, or -99) then
490 !! --- radar-sat (RAMP) values are not valid and revert back to old orog
491  zslm(i,j) = 1
492  endif
493  endif
494  152 format(1x,' ZAVG(i=',i4,' j=',i4,')=',i5,i3,
495  &' orig:',i5,i4,' Lat=',f7.3,f8.2,'E',' GICE=',f8.1)
496  enddo
497  enddo
498  endif
499 
500  deallocate (gice)
501 
502  allocate (oclsm(im,jm),slmi(im,jm))
503 !C
504 C COMPUTE MOUNTAIN DATA : ORO SLM VAR (Std Dev) OC
505 C
506 ! --- The coupled ocean model is already on a Guasian grid if (IM,JM)
507 ! --- Attempt to Open the file if mskocn=1
508  istat=0
509  if (mskocn .eq. 1) then
510 ! open(25,form='unformatted',iostat=istat)
511 ! open(25,form='binary',iostat=istat)
512 ! --- open to fort.25 with link to file in script
513  open(25,form='formatted',iostat=istat)
514  if (istat.ne.0) then
515  mskocn = 0
516  print *,' Ocean lsm file Open failure: mskocn,istat=',mskocn,istat
517  else
518  mskocn = 1
519  print *,' Ocean lsm file Opened OK: mskocn,istat=',mskocn,istat
520  endif
521 ! --- Read it in
522  ios=0
523  oclsm=0.
524 ! read(25,iostat=ios)OCLSM
525  read(25,*,iostat=ios)oclsm
526  if (ios.ne.0) then
527  mskocn = 0
528 ! --- did not properly read Gaussian grid ocean land-sea mask, but
529 ! continue using ZSLMX
530  print *,' Rd fail: Ocean lsm - continue, mskocn,ios=',mskocn,ios
531  else
532  mskocn = 1
533  print *,' Rd OK: ocean lsm: mskocn,ios=',mskocn,ios
534 ! --- LSM initialized to ocean mask especially for case where Ocean
535 ! --- changed by ocean model to land to cope with its problems
536 ! --- remember, that lake mask is in zslm to be assigned in MAKEMT.
537  if ( mskocn .eq. 1 ) then
538  DO j = 1,jm
539  DO i = 1,numi(j)
540  if ( notocn .eq. 0 ) then
541  slmi(i,j) = float(nint(oclsm(i,j)))
542  else
543  if ( nint(oclsm(i,j)) .eq. 0) then
544  slmi(i,j) = 1
545  else
546  slmi(i,j) = 0
547  endif
548  endif
549  enddo
550  enddo
551  print *,' OCLSM',oclsm(1,1),oclsm(50,50),oclsm(75,75),oclsm(im,jm)
552  print *,' SLMI:',slmi(1,1),slmi(50,50),slmi(75,75),slmi(im,jm)
553 ! --- Diag
554 ! WRITE(27,iostat=ios) REAL(SLMI,4)
555 ! print *,' write SLMI/OCLSM diag input:',ios
556  endif
557  endif
558 
559  else
560  print *,' Not using Ocean model land sea mask'
561  endif
562 
563  if (mskocn .eq. 1)then
564  print *,' LSM:',oclsm(1,1),oclsm(50,50),oclsm(75,75),oclsm(im,jm)
565  endif
566 
567  allocate (geolon(im,jm),geolon_c(im+1,jm+1),dx(im,jm))
568  allocate (geolat(im,jm),geolat_c(im+1,jm+1),dy(im,jm))
569  allocate (slm(im,jm),oro(im,jm),var(im,jm),var4(im,jm))
570  allocate (land_frac(im,jm),lake_frac(im,jm))
571 
572 !--- reading grid file.
573  grid_from_file = .false.
574  is_south_pole = .false.
575  is_north_pole = .false.
576  i_south_pole = 0
577  j_south_pole = 0
578  i_north_pole = 0
579  j_north_pole = 0
580  if( trim(outgrid) .NE. "none" ) then
581  grid_from_file = .true.
582  inquire(file=trim(outgrid), exist=fexist)
583  if(.not. fexist) then
584  print*, "file "//trim(outgrid)//" does not exist"
585  CALL errexit(4)
586  endif
587  do ncid = 103, 512
588  inquire( ncid,opened=opened )
589  if( .NOT.opened )exit
590  end do
591 
592  print*, "outgrid=", trim(outgrid)
593  error=nf__open(trim(outgrid),nf_nowrite,fsize,ncid)
594  call netcdf_err(error, 'Open file '//trim(outgrid) )
595  error=nf_inq_dimid(ncid, 'nx', id_dim)
596  call netcdf_err(error, 'inquire dimension nx from file '//
597  & trim(outgrid) )
598  nx = 2*im
599  ny = 2*jm
600 ! error=nf_inq_dimlen(ncid,id_dim,nx)
601 ! print*, "nx = ", nx, id_dim
602 ! call netcdf_err(error, 'inquire dimension nx length '//
603 ! & 'from file '//trim(OUTGRID) )
604 ! error=nf_inq_dimid(ncid, 'ny', id_dim)
605 ! call netcdf_err(error, 'inquire dimension ny from file '//
606 ! & trim(OUTGRID) )
607 ! error=nf_inq_dimlen(ncid,id_dim,ny)
608 ! call netcdf_err(error, 'inquire dimension ny length '//
609 ! & 'from file '//trim(OUTGRID) )
610 ! IM should equal nx/2 and JM should equal ny/2
611 ! if(IM .ne. nx/2) then
612 ! print*, "IM=",IM, " /= grid file nx/2=",nx/2
613 ! CALL ERREXIT(4)
614 ! endif
615 ! if(JM .ne. ny/2) then
616 ! print*, "JM=",JM, " /= grid file ny/2=",ny/2
617 ! CALL ERREXIT(4)
618 ! endif
619  print*, "Read the grid from file "//trim(outgrid)
620 
621  allocate(tmpvar(nx+1,ny+1))
622 
623  error=nf_inq_varid(ncid, 'x', id_var)
624  call netcdf_err(error, 'inquire varid of x from file '
625  & //trim(outgrid) )
626  error=nf_get_var_double(ncid, id_var, tmpvar)
627  call netcdf_err(error, 'inquire data of x from file '
628  & //trim(outgrid) )
629  !--- adjust lontitude to be between 0 and 360.
630  do j = 1,ny+1; do i = 1,nx+1
631  if(tmpvar(i,j) .NE. missing_value) then
632  if(tmpvar(i,j) .GT. 360) tmpvar(i,j) = tmpvar(i,j) - 360
633  if(tmpvar(i,j) .LT. 0) tmpvar(i,j) = tmpvar(i,j) + 360
634  endif
635  enddo; enddo
636 
637  geolon(1:im,1:jm) = tmpvar(2:nx:2,2:ny:2)
638  geolon_c(1:im+1,1:jm+1) = tmpvar(1:nx+1:2,1:ny+1:2)
639 
640  error=nf_inq_varid(ncid, 'y', id_var)
641  call netcdf_err(error, 'inquire varid of y from file '
642  & //trim(outgrid) )
643  error=nf_get_var_double(ncid, id_var, tmpvar)
644  call netcdf_err(error, 'inquire data of y from file '
645  & //trim(outgrid) )
646  geolat(1:im,1:jm) = tmpvar(2:nx:2,2:ny:2)
647  geolat_c(1:im+1,1:jm+1) = tmpvar(1:nx+1:2,1:ny+1:2)
648 
649  !--- figure out pole location.
650  maxlat = -90
651  minlat = 90
652  i_north_pole = 0
653  j_north_pole = 0
654  i_south_pole = 0
655  j_south_pole = 0
656  do j = 1, ny+1; do i = 1, nx+1
657  if( tmpvar(i,j) > maxlat ) then
658  i_north_pole=i
659  j_north_pole=j
660  maxlat = tmpvar(i,j)
661  endif
662  if( tmpvar(i,j) < minlat ) then
663  i_south_pole=i
664  j_south_pole=j
665  minlat = tmpvar(i,j)
666  endif
667  enddo ; enddo
668  !--- only when maxlat is close to 90. the point is north pole
669  if(maxlat < 89.9 ) then
670  i_north_pole = 0
671  j_north_pole = 0
672  endif
673  if(minlat > -89.9 ) then
674  i_south_pole = 0
675  j_south_pole = 0
676  endif
677  print*, "minlat=", minlat, "maxlat=", maxlat
678  print*, "north pole supergrid index is ",
679  & i_north_pole, j_north_pole
680  print*, "south pole supergrid index is ",
681  & i_south_pole, j_south_pole
682  deallocate(tmpvar)
683 
684  if(i_south_pole >0 .and. j_south_pole > 0) then
685  if(mod(i_south_pole,2)==0) then ! stretched grid
686  do j = 1, jm; do i = 1, im
687  if(i==i_south_pole/2 .and. (j==j_south_pole/2
688  & .or. j==j_south_pole/2+1) ) then
689  is_south_pole(i,j) = .true.
690  print*, "south pole at i,j=", i, j
691  endif
692  enddo; enddo
693  else
694  do j = 1, jm; do i = 1, im
695  if((i==i_south_pole/2 .or. i==i_south_pole/2+1)
696  & .and. (j==j_south_pole/2 .or.
697  & j==j_south_pole/2+1) ) then
698  is_south_pole(i,j) = .true.
699  print*, "south pole at i,j=", i, j
700  endif
701  enddo; enddo
702  endif
703  endif
704  if(i_north_pole >0 .and. j_north_pole > 0) then
705  if(mod(i_north_pole,2)==0) then ! stretched grid
706  do j = 1, jm; do i = 1, im
707  if(i==i_north_pole/2 .and. (j==j_north_pole/2 .or.
708  & j==j_north_pole/2+1) ) then
709  is_north_pole(i,j) = .true.
710  print*, "north pole at i,j=", i, j
711  endif
712  enddo; enddo
713  else
714  do j = 1, jm; do i = 1, im
715  if((i==i_north_pole/2 .or. i==i_north_pole/2+1)
716  & .and. (j==j_north_pole/2 .or.
717  & j==j_north_pole/2+1) ) then
718  is_north_pole(i,j) = .true.
719  print*, "north pole at i,j=", i, j
720  endif
721  enddo; enddo
722  endif
723  endif
724 
725 
726  allocate(tmpvar(nx,ny))
727  error=nf_inq_varid(ncid, 'area', id_var)
728  call netcdf_err(error, 'inquire varid of area from file '
729  & //trim(outgrid) )
730  error=nf_get_var_double(ncid, id_var, tmpvar)
731  call netcdf_err(error, 'inquire data of area from file '
732  & //trim(outgrid) )
733 
734  do j = 1, jm
735  do i = 1, im
736  dx(i,j) = sqrt(tmpvar(2*i-1,2*j-1)+tmpvar(2*i,2*j-1)
737  & +tmpvar(2*i-1,2*j )+tmpvar(2*i,2*j ))
738  dy(i,j) = dx(i,j)
739  enddo
740  enddo
741 ! allocate(tmpvar(nx,ny+1))
742 
743 ! error=nf_inq_varid(ncid, 'dx', id_var)
744 ! call netcdf_err(error, 'inquire varid of dx from file '
745 ! & //trim(OUTGRID) )
746 ! error=nf_get_var_double(ncid, id_var, tmpvar)
747 ! call netcdf_err(error, 'inquire data of dx from file '
748 ! & //trim(OUTGRID) )
749 ! dx(1:IM,1:JM+1) = tmpvar(2:nx:2,1:ny+1:2)
750 ! deallocate(tmpvar)
751 
752 ! allocate(tmpvar(nx+1,ny))
753 ! error=nf_inq_varid(ncid, 'dy', id_var)
754 ! call netcdf_err(error, 'inquire varid of dy from file '
755 ! & //trim(OUTGRID) )
756 ! error=nf_get_var_double(ncid, id_var, tmpvar)
757 ! call netcdf_err(error, 'inquire data of dy from file '
758 ! & //trim(OUTGRID) )
759 ! dy(1:IM+1,1:JM) = tmpvar(1:nx+1:2,2:ny:2)
760  deallocate(tmpvar)
761  endif
762  tend=timef()
763  write(6,*)' Timer 1 time= ',tend-tbeg
764  !
765  if(grid_from_file) then
766  tbeg=timef()
767 
768  IF (merge_file == 'none') then
769  CALL make_mask(zslm,slm,land_frac,glat,
770  & im,jm,imn,jmn,geolon_c,geolat_c)
771  lake_frac=9999.9
772  ELSE
773  print*,'got here - read in external mask ',merge_file
774  CALL read_mask(merge_file,slm,land_frac,lake_frac,im,jm)
775  ENDIF
776 
777  IF (mask_only) THEN
778  print*,'got here computing mask only.'
779  CALL write_mask_netcdf(im,jm,slm,land_frac,
780  1 1,1,geolon,geolat)
781 
782  print*,' DONE.'
783  stop
784  END IF
785 
786  CALL makemt2(zavg,zslm,oro,slm,var,var4,glat,
787  & im,jm,imn,jmn,geolon_c,geolat_c,lake_frac,land_frac)
788 
789  tend=timef()
790  write(6,*)' MAKEMT2 time= ',tend-tbeg
791  else
792  CALL makemt(zavg,zslm,oro,slm,var,var4,glat,
793  & ist,ien,jst,jen,im,jm,imn,jmn,xlat,numi)
794  endif
795 
796  call minmxj(im,jm,oro,' ORO')
797  call minmxj(im,jm,slm,' SLM')
798  call minmxj(im,jm,var,' VAR')
799  call minmxj(im,jm,var4,' VAR4')
800 C --- check for nands in above
801 ! call nanc(ORO,IM*JM,"MAKEMT_ORO")
802 ! call nanc(SLM,IM*JM,"MAKEMT_SLM")
803 ! call nanc(VAR,IM*JM,"MAKEMT_VAR")
804 ! call nanc(VAR4,IM*JM,"MAKEMT_VAR4")
805 !
806 C check antarctic pole
807 ! DO J = 1,JM
808 ! DO I = 1,numi(j)
809 ! if ( i .le. 100 .and. i .ge. 1 )then
810 ! if (j .ge. JM-1 )then
811 ! if (height .eq. 0.) print *,'I,J,SLM:',I,J,SLM(I,J)
812 ! write(6,153)i,j,ORO(i,j),HEIGHT,SLM(i,j)
813 ! endif
814 ! endif
815 ! ENDDO
816 ! ENDDO
817 C
818 C === Compute mtn principal coord HTENSR: THETA,GAMMA,SIGMA
819 C
820  allocate (theta(im,jm),gamma(im,jm),sigma(im,jm),elvmax(im,jm))
821  if(grid_from_file) then
822  tbeg=timef()
823  CALL makepc2(zavg,zslm,theta,gamma,sigma,glat,
824  1 im,jm,imn,jmn,geolon_c,geolat_c,slm)
825  tend=timef()
826  write(6,*)' MAKEPC2 time= ',tend-tbeg
827  else
828  CALL makepc(zavg,zslm,theta,gamma,sigma,glat,
829  1 ist,ien,jst,jen,im,jm,imn,jmn,xlat,numi)
830  endif
831 
832  call minmxj(im,jm,theta,' THETA')
833  call minmxj(im,jm,gamma,' GAMMA')
834  call minmxj(im,jm,sigma,' SIGMA')
835 
836 C --- check for nands in above
837 ! call nanc(THETA,IM*JM,"MAKEPC_THETA")
838 ! call nanc(GAMMA,IM*JM,"MAKEPC_GAMMA")
839 ! call nanc(SIGMA,IM*JM,"MAKEPC_SIGMA")
840 C
841 C COMPUTE MOUNTAIN DATA : OA OL
842 C
843  allocate (iwork(im,jm,4))
844  allocate (oa(im,jm,4),ol(im,jm,4),hprime(im,jm,14))
845  allocate (work1(im,jm),work2(im,jm),work3(im,jm),work4(im,jm))
846  allocate (work5(im,jm),work6(im,jm))
847 
848  call minmxj(im,jm,oro,' ORO')
849  print*, "inputorog=", trim(inputorog)
850  if(grid_from_file) then
851  if(trim(inputorog) == "none") then
852  print*, "calling MAKEOA2 to compute OA, OL"
853  tbeg=timef()
854  CALL makeoa2(zavg,zslm,var,glat,oa,ol,iwork,elvmax,oro,
855  1 work1,work2,work3,work4,work5,work6,
856  2 im,jm,imn,jmn,geolon_c,geolat_c,
857  3 geolon,geolat,dx,dy,is_south_pole,is_north_pole)
858  tend=timef()
859  write(6,*)' MAKEOA2 time= ',tend-tbeg
860  else
861  !-- read the data from INPUTOROG file.
862  error=nf__open(trim(inputorog),nf_nowrite,fsize,ncid)
863  call netcdf_err(error, 'Open file '//trim(inputorog) )
864  error=nf_inq_dimid(ncid, 'lon', id_dim)
865  call netcdf_err(error, 'inquire dimension lon from file '//
866  & trim(inputorog) )
867  error=nf_inq_dimlen(ncid,id_dim,nx_in)
868  call netcdf_err(error, 'inquire dimension lon length '//
869  & 'from file '//trim(inputorog) )
870  error=nf_inq_dimid(ncid, 'lat', id_dim)
871  call netcdf_err(error, 'inquire dimension lat from file '//
872  & trim(inputorog) )
873  error=nf_inq_dimlen(ncid,id_dim,ny_in)
874  call netcdf_err(error, 'inquire dimension lat length '//
875  & 'from file '//trim(inputorog) )
876 
877  print*, "extrapolate OA, OL from Gaussian grid with nx=",
878  & nx_in, ", ny=", ny_in
879  allocate(oa_in(nx_in,ny_in,4), ol_in(nx_in,ny_in,4))
880  allocate(slm_in(nx_in,ny_in) )
881  allocate(lon_in(nx_in,ny_in), lat_in(nx_in,ny_in) )
882 
883  error=nf_inq_varid(ncid, 'oa1', id_var)
884  call netcdf_err(error, 'inquire varid of oa1 from file '
885  & //trim(inputorog) )
886  error=nf_get_var_double(ncid, id_var, oa_in(:,:,1))
887  call netcdf_err(error, 'inquire data of oa1 from file '
888  & //trim(inputorog) )
889  error=nf_inq_varid(ncid, 'oa2', id_var)
890  call netcdf_err(error, 'inquire varid of oa2 from file '
891  & //trim(inputorog) )
892  error=nf_get_var_double(ncid, id_var, oa_in(:,:,2))
893  call netcdf_err(error, 'inquire data of oa2 from file '
894  & //trim(inputorog) )
895  error=nf_inq_varid(ncid, 'oa3', id_var)
896  call netcdf_err(error, 'inquire varid of oa3 from file '
897  & //trim(inputorog) )
898  error=nf_get_var_double(ncid, id_var, oa_in(:,:,3))
899  call netcdf_err(error, 'inquire data of oa3 from file '
900  & //trim(inputorog) )
901  error=nf_inq_varid(ncid, 'oa4', id_var)
902  call netcdf_err(error, 'inquire varid of oa4 from file '
903  & //trim(inputorog) )
904  error=nf_get_var_double(ncid, id_var, oa_in(:,:,4))
905  call netcdf_err(error, 'inquire data of oa4 from file '
906  & //trim(inputorog) )
907 
908  error=nf_inq_varid(ncid, 'ol1', id_var)
909  call netcdf_err(error, 'inquire varid of ol1 from file '
910  & //trim(inputorog) )
911  error=nf_get_var_double(ncid, id_var, ol_in(:,:,1))
912  call netcdf_err(error, 'inquire data of ol1 from file '
913  & //trim(inputorog) )
914  error=nf_inq_varid(ncid, 'ol2', id_var)
915  call netcdf_err(error, 'inquire varid of ol2 from file '
916  & //trim(inputorog) )
917  error=nf_get_var_double(ncid, id_var, ol_in(:,:,2))
918  call netcdf_err(error, 'inquire data of ol2 from file '
919  & //trim(inputorog) )
920  error=nf_inq_varid(ncid, 'ol3', id_var)
921  call netcdf_err(error, 'inquire varid of ol3 from file '
922  & //trim(inputorog) )
923  error=nf_get_var_double(ncid, id_var, ol_in(:,:,3))
924  call netcdf_err(error, 'inquire data of ol3 from file '
925  & //trim(inputorog) )
926  error=nf_inq_varid(ncid, 'ol4', id_var)
927  call netcdf_err(error, 'inquire varid of ol4 from file '
928  & //trim(inputorog) )
929  error=nf_get_var_double(ncid, id_var, ol_in(:,:,4))
930  call netcdf_err(error, 'inquire data of ol4 from file '
931  & //trim(inputorog) )
932 
933  error=nf_inq_varid(ncid, 'slmsk', id_var)
934  call netcdf_err(error, 'inquire varid of slmsk from file '
935  & //trim(inputorog) )
936  error=nf_get_var_double(ncid, id_var, slm_in)
937  call netcdf_err(error, 'inquire data of slmsk from file '
938  & //trim(inputorog) )
939 
940  error=nf_inq_varid(ncid, 'geolon', id_var)
941  call netcdf_err(error, 'inquire varid of geolon from file '
942  & //trim(inputorog) )
943  error=nf_get_var_double(ncid, id_var, lon_in)
944  call netcdf_err(error, 'inquire data of geolon from file '
945  & //trim(inputorog) )
946 
947  error=nf_inq_varid(ncid, 'geolat', id_var)
948  call netcdf_err(error, 'inquire varid of geolat from file '
949  & //trim(inputorog) )
950  error=nf_get_var_double(ncid, id_var, lat_in)
951  call netcdf_err(error, 'inquire data of geolat from file '
952  & //trim(inputorog) )
953 
954  ! set slmsk=2 to be ocean (0)
955  do j=1,ny_in; do i=1,nx_in
956  if(slm_in(i,j) == 2) slm_in(i,j) = 0
957  enddo; enddo
958 
959  error=nf_close(ncid)
960  call netcdf_err(error, 'close file '
961  & //trim(inputorog) )
962 
963  print*, "calling MAKEOA3 to compute OA, OL"
964  CALL makeoa3(zavg,zslm,var,glat,oa,ol,iwork,elvmax,oro,slm,
965  1 work1,work2,work3,work4,work5,work6,
966  2 im,jm,imn,jmn,geolon_c,geolat_c,
967  3 geolon,geolat,is_south_pole,is_north_pole,nx_in,ny_in,
968  4 oa_in,ol_in,slm_in,lon_in,lat_in)
969 
970  deallocate(oa_in,ol_in,slm_in,lon_in,lat_in)
971 
972  endif
973  else
974  CALL makeoa(zavg,var,glat,oa,ol,iwork,elvmax,oro,
975  1 work1,work2,work3,work4,
976  2 work5,work6,
977  3 ist,ien,jst,jen,im,jm,imn,jmn,xlat,numi)
978  endif
979 
980 ! Deallocate 2d vars
981  deallocate(ist,ien)
982  deallocate (zslm,zavg)
983  deallocate (dx,dy)
984  deallocate (work2,work3,work4,work5,work6)
985 
986 ! Deallocate 3d vars
987  deallocate(iwork)
988 
989  tbeg=timef()
990  call minmxj(im,jm,oa,' OA')
991  call minmxj(im,jm,ol,' OL')
992  call minmxj(im,jm,elvmax,' ELVMAX')
993  call minmxj(im,jm,oro,' ORO')
994 C --- check for nands in above
995 ! call nanc(OA(1,1,1), IM*JM,"MAKEOA_OA(1,1,1)")
996 ! call nanc(OA(1,1,2), IM*JM,"MAKEOA_OA(1,1,2)")
997 ! call nanc(OA(1,1,3), IM*JM,"MAKEOA_OA(1,1,3)")
998 ! call nanc(OA(1,1,4), IM*JM,"MAKEOA_OA(1,1,4)")
999 ! call nanc(OL(1,1,1), IM*JM,"MAKEOA_OL(1,1,1)")
1000 ! call nanc(OL(1,1,2), IM*JM,"MAKEOA_OL(1,1,2)")
1001 ! call nanc(OL(1,1,3), IM*JM,"MAKEOA_OL(1,1,3)")
1002 ! call nanc(OL(1,1,4), IM*JM,"MAKEOA_OL(1,1,4)")
1003 ! call nanc(ELVMAX, IM*JM,"MAKEPC_ELVMAX")
1004 
1005  maxc3 = 0
1006  maxc4 = 0
1007  maxc5 = 0
1008  maxc6 = 0
1009  maxc7 = 0
1010  maxc8 = 0
1011  DO j = 1,jm
1012  DO i = 1,numi(j)
1013  if (elvmax(i,j) .gt. 3000.) maxc3 = maxc3 +1
1014  if (elvmax(i,j) .gt. 4000.) maxc4 = maxc4 +1
1015  if (elvmax(i,j) .gt. 5000.) maxc5 = maxc5 +1
1016  if (elvmax(i,j) .gt. 6000.) maxc6 = maxc6 +1
1017  if (elvmax(i,j) .gt. 7000.) maxc7 = maxc7 +1
1018  if (elvmax(i,j) .gt. 8000.) maxc8 = maxc8 +1
1019  ENDDO
1020  ENDDO
1021  print *,' MAXC3:',maxc3,maxc4,maxc5,maxc6,maxc7,maxc8
1022 !
1023 c itest=151
1024 c jtest=56
1025 C
1026  print *,' ===> Replacing ELVMAX with ELVMAX-ORO <=== '
1027  print *,' ===> if ELVMAX<=ORO replace with proxy <=== '
1028  print *,' ===> the sum of mean orog (ORO) and std dev <=== '
1029  DO j = 1,jm
1030  DO i = 1,numi(j)
1031  if (elvmax(i,j) .lt. oro(i,j) ) then
1032 C--- subtracting off ORO leaves std dev (this should never happen)
1033  elvmax(i,j) = max( 3. * var(i,j),0.)
1034  else
1035  elvmax(i,j) = max( elvmax(i,j) - oro(i,j),0.)
1036  endif
1037  ENDDO
1038  ENDDO
1039  maxc3 = 0
1040  maxc4 = 0
1041  maxc5 = 0
1042  maxc6 = 0
1043  maxc7 = 0
1044  maxc8 = 0
1045  DO j = 1,jm
1046  DO i = 1,numi(j)
1047  if (elvmax(i,j) .gt. 3000.) maxc3 = maxc3 +1
1048  if (elvmax(i,j) .gt. 4000.) maxc4 = maxc4 +1
1049  if (elvmax(i,j) .gt. 5000.) maxc5 = maxc5 +1
1050  if (elvmax(i,j) .gt. 6000.) maxc6 = maxc6 +1
1051  if (elvmax(i,j) .gt. 7000.) maxc7 = maxc7 +1
1052  if (elvmax(i,j) .gt. 8000.) maxc8 = maxc8 +1
1053  ENDDO
1054  ENDDO
1055  print *,' after MAXC 3-6 km:',maxc3,maxc4,maxc5,maxc6
1056 c
1057  call mnmxja(im,jm,elvmax,itest,jtest,' ELVMAX')
1058 ! if (JM .gt. 0) stop
1059 C
1060 C ZERO OVER OCEAN
1061 C
1062  print *,' Testing at point (itest,jtest)=',itest,jtest
1063  print *,' SLM(itest,jtest)=',slm(itest,jtest),itest,jtest
1064  print *,' ORO(itest,jtest)=',oro(itest,jtest),itest,jtest
1065  DO j = 1,jm
1066  DO i = 1,numi(j)
1067  IF(slm(i,j).EQ.0.) THEN
1068 C VAR(I,J) = 0.
1069  var4(i,j) = 0.
1070  oa(i,j,1) = 0.
1071  oa(i,j,2) = 0.
1072  oa(i,j,3) = 0.
1073  oa(i,j,4) = 0.
1074  ol(i,j,1) = 0.
1075  ol(i,j,2) = 0.
1076  ol(i,j,3) = 0.
1077  ol(i,j,4) = 0.
1078 C THETA(I,J) =0.
1079 C GAMMA(I,J) =0.
1080 C SIGMA(I,J) =0.
1081 C ELVMAX(I,J)=0.
1082 ! --- the sub-grid scale parameters for mtn blocking and gwd retain
1083 ! --- properties even if over ocean but there is elevation within the
1084 ! --- gaussian grid box.
1085  ENDIF
1086  ENDDO
1087  ENDDO
1088 C
1089 ! --- if mskocn=1 ocean land sea mask given, =0 if not present
1090 ! --- OCLSM is real(*4) array with fractional values possible
1091 ! --- 0 is ocean and 1 is land for slm
1092 ! --- Step 1: Only change SLM after GFS SLM is applied
1093 ! --- SLM is only field that will be altered by OCLSM
1094 ! --- Ocean land sea mask ocean points made ocean in atm model
1095 ! --- Land and Lakes and all other atm elv moments remain unchanged.
1096 
1097  IF (merge_file == 'none') then
1098 
1099  msk_ocn : if ( mskocn .eq. 1 ) then
1100 
1101  DO j = 1,jm
1102  DO i = 1,numi(j)
1103  if (abs(oro(i,j)) .lt. 1. ) then
1104  slm(i,j) = slmi(i,j)
1105  else
1106  if ( slmi(i,j) .eq. 1. .and. slm(i,j) .eq. 1) slm(i,j) = 1
1107  if ( slmi(i,j) .eq. 0. .and. slm(i,j) .eq. 0) slm(i,j) = 0
1108  if ( slmi(i,j) .eq. 0. .and. slm(i,j) .eq. 1) slm(i,j) = 0
1109  if ( slmi(i,j) .eq. 0. .and. slm(i,j) .eq. 0) slm(i,j) = 0
1110  endif
1111  enddo
1112  enddo
1113  endif msk_ocn
1114  endif
1115  print *,' SLM(itest,jtest)=',slm(itest,jtest),itest,jtest
1116  print *,' ORO(itest,jtest)=',oro(itest,jtest),itest,jtest
1117 
1118  deallocate(slmi)
1119 
1120  IF (merge_file == 'none') then
1121 
1122 C REMOVE ISOLATED POINTS
1123  iso_loop : DO j=2,jm-1
1124  jn=j-1
1125  js=j+1
1126  rn=REAL(numi(jn))/REAL(numi(j))
1127  rs=REAL(numi(js))/REAL(numi(j))
1128  DO i=1,numi(j)
1129  iw=mod(i+im-2,im)+1
1130  ie=mod(i,im)+1
1131  slma=slm(iw,j)+slm(ie,j)
1132  oroa=oro(iw,j)+oro(ie,j)
1133  vara=var(iw,j)+var(ie,j)
1134  var4a=var4(iw,j)+var4(ie,j)
1135  DO k=1,4
1136  oaa(k)=oa(iw,j,k)+oa(ie,j,k)
1137 ! --- (*j*) fix typo:
1138  ola(k)=ol(iw,j,k)+ol(ie,j,k)
1139  ENDDO
1140  wgta=2
1141  xn=rn*(i-1)+1
1142  IF(abs(xn-nint(xn)).LT.1.e-2) THEN
1143  in=mod(nint(xn)-1,numi(jn))+1
1144  inw=mod(in+numi(jn)-2,numi(jn))+1
1145  ine=mod(in,numi(jn))+1
1146  slma=slma+slm(inw,jn)+slm(in,jn)+slm(ine,jn)
1147  oroa=oroa+oro(inw,jn)+oro(in,jn)+oro(ine,jn)
1148  vara=vara+var(inw,jn)+var(in,jn)+var(ine,jn)
1149  var4a=var4a+var4(inw,jn)+var4(in,jn)+var4(ine,jn)
1150  DO k=1,4
1151  oaa(k)=oaa(k)+oa(inw,jn,k)+oa(in,jn,k)+oa(ine,jn,k)
1152  ola(k)=ola(k)+ol(inw,jn,k)+ol(in,jn,k)+ol(ine,jn,k)
1153  ENDDO
1154  wgta=wgta+3
1155  ELSE
1156  inw=int(xn)
1157  ine=mod(inw,numi(jn))+1
1158  slma=slma+slm(inw,jn)+slm(ine,jn)
1159  oroa=oroa+oro(inw,jn)+oro(ine,jn)
1160  vara=vara+var(inw,jn)+var(ine,jn)
1161  var4a=var4a+var4(inw,jn)+var4(ine,jn)
1162  DO k=1,4
1163  oaa(k)=oaa(k)+oa(inw,jn,k)+oa(ine,jn,k)
1164  ola(k)=ola(k)+ol(inw,jn,k)+ol(ine,jn,k)
1165  ENDDO
1166  wgta=wgta+2
1167  ENDIF
1168  xs=rs*(i-1)+1
1169  IF(abs(xs-nint(xs)).LT.1.e-2) THEN
1170  is=mod(nint(xs)-1,numi(js))+1
1171  isw=mod(is+numi(js)-2,numi(js))+1
1172  ise=mod(is,numi(js))+1
1173  slma=slma+slm(isw,js)+slm(is,js)+slm(ise,js)
1174  oroa=oroa+oro(isw,js)+oro(is,js)+oro(ise,js)
1175  vara=vara+var(isw,js)+var(is,js)+var(ise,js)
1176  var4a=var4a+var4(isw,js)+var4(is,js)+var4(ise,js)
1177  DO k=1,4
1178  oaa(k)=oaa(k)+oa(isw,js,k)+oa(is,js,k)+oa(ise,js,k)
1179  ola(k)=ola(k)+ol(isw,js,k)+ol(is,js,k)+ol(ise,js,k)
1180  ENDDO
1181  wgta=wgta+3
1182  ELSE
1183  isw=int(xs)
1184  ise=mod(isw,numi(js))+1
1185  slma=slma+slm(isw,js)+slm(ise,js)
1186  oroa=oroa+oro(isw,js)+oro(ise,js)
1187  vara=vara+var(isw,js)+var(ise,js)
1188  var4a=var4a+var4(isw,js)+var4(ise,js)
1189  DO k=1,4
1190  oaa(k)=oaa(k)+oa(isw,js,k)+oa(ise,js,k)
1191  ola(k)=ola(k)+ol(isw,js,k)+ol(ise,js,k)
1192  ENDDO
1193  wgta=wgta+2
1194  ENDIF
1195  oroa=oroa/wgta
1196  vara=vara/wgta
1197  var4a=var4a/wgta
1198  DO k=1,4
1199  oaa(k)=oaa(k)/wgta
1200  ola(k)=ola(k)/wgta
1201  ENDDO
1202  IF(slm(i,j).EQ.0..AND.slma.EQ.wgta) THEN
1203  print '("SEA ",2F8.0," MODIFIED TO LAND",2F8.0," AT ",2I8)',
1204  & oro(i,j),var(i,j),oroa,vara,i,j
1205  slm(i,j)=1.
1206  oro(i,j)=oroa
1207  var(i,j)=vara
1208  var4(i,j)=var4a
1209  DO k=1,4
1210  oa(i,j,k)=oaa(k)
1211  ol(i,j,k)=ola(k)
1212  ENDDO
1213  ELSEIF(slm(i,j).EQ.1..AND.slma.EQ.0.) THEN
1214  print '("LAND",2F8.0," MODIFIED TO SEA ",2F8.0," AT ",2I8)',
1215  & oro(i,j),var(i,j),oroa,vara,i,j
1216  slm(i,j)=0.
1217  oro(i,j)=oroa
1218  var(i,j)=vara
1219  var4(i,j)=var4a
1220  DO k=1,4
1221  oa(i,j,k)=oaa(k)
1222  ol(i,j,k)=ola(k)
1223  ENDDO
1224  ENDIF
1225  ENDDO
1226  ENDDO iso_loop
1227 C--- print for testing after isolated points removed
1228  print *,' after isolated points removed'
1229  call minmxj(im,jm,oro,' ORO')
1230 C print *,' JM=',JM,' numi=',numi
1231  print *,' ORO(itest,jtest)=',oro(itest,jtest)
1232  print *,' VAR(itest,jtest)=',var(itest,jtest)
1233  print *,' VAR4(itest,jtest)=',var4(itest,jtest)
1234  print *,' OA(itest,jtest,1)=',oa(itest,jtest,1)
1235  print *,' OA(itest,jtest,2)=',oa(itest,jtest,2)
1236  print *,' OA(itest,jtest,3)=',oa(itest,jtest,3)
1237  print *,' OA(itest,jtest,4)=',oa(itest,jtest,4)
1238  print *,' OL(itest,jtest,1)=',ol(itest,jtest,1)
1239  print *,' OL(itest,jtest,2)=',ol(itest,jtest,2)
1240  print *,' OL(itest,jtest,3)=',ol(itest,jtest,3)
1241  print *,' OL(itest,jtest,4)=',ol(itest,jtest,4)
1242  print *,' Testing at point (itest,jtest)=',itest,jtest
1243  print *,' THETA(itest,jtest)=',theta(itest,jtest)
1244  print *,' GAMMA(itest,jtest)=',gamma(itest,jtest)
1245  print *,' SIGMA(itest,jtest)=',sigma(itest,jtest)
1246  print *,' ELVMAX(itest,jtest)=',elvmax(itest,jtest)
1247  print *,' EFAC=',efac
1248 
1249  endif
1250 
1251 C
1252  DO j=1,jm
1253  DO i=1,numi(j)
1254  oro(i,j) = oro(i,j) + efac*var(i,j)
1255  hprime(i,j,1) = var(i,j)
1256  hprime(i,j,2) = var4(i,j)
1257  hprime(i,j,3) = oa(i,j,1)
1258  hprime(i,j,4) = oa(i,j,2)
1259  hprime(i,j,5) = oa(i,j,3)
1260  hprime(i,j,6) = oa(i,j,4)
1261  hprime(i,j,7) = ol(i,j,1)
1262  hprime(i,j,8) = ol(i,j,2)
1263  hprime(i,j,9) = ol(i,j,3)
1264  hprime(i,j,10)= ol(i,j,4)
1265  hprime(i,j,11)= theta(i,j)
1266  hprime(i,j,12)= gamma(i,j)
1267  hprime(i,j,13)= sigma(i,j)
1268  hprime(i,j,14)= elvmax(i,j)
1269  ENDDO
1270  ENDDO
1271 !
1272  call mnmxja(im,jm,elvmax,itest,jtest,' ELVMAX')
1273 ! --- Quadratic filter applied by default.
1274 ! --- NF0 is normally set to an even value beyond the previous truncation,
1275 ! --- for example, for jcap=382, NF0=254+2
1276 ! --- NF1 is set as jcap+2 (and/or nearest even), eg., for t382, NF1=382+2=384
1277 ! --- if no filter is desired then NF1=NF0=0 and ORF=ORO
1278 ! --- if no filter but spectral to grid (with gibbs) then NF1=jcap+2, and NF1=jcap+1
1279 !
1280  deallocate(var4)
1281  allocate (orf(im,jm))
1282  IF ( nf1 - nf0 .eq. 0 ) filter=.false.
1283  print *,' NF1, NF0, FILTER=',nf1,nf0,filter
1284  IF (filter) THEN
1285 C SPECTRALLY TRUNCATE AND FILTER OROGRAPHY
1286  do j=1,jm
1287  if(numi(j).lt.im) then
1288  ffj=cmplx(0.,0.)
1289  call spfft1(numi(j),im/2+1,numi(j),1,ffj,oro(1,j),-1)
1290  call spfft1(im,im/2+1,im,1,ffj,oro(1,j),+1)
1291  endif
1292  enddo
1293  CALL sptez(nr,nm,4,im,jm,ors,oro,-1)
1294 !
1295  print *,' about to apply spectral filter '
1296  fff=1./(nf1-nf0)**2
1297  i=0
1298  DO m=0,nm
1299  DO n=m,nm+nr*m
1300  IF(n.GT.nf0) THEN
1301  www=max(1.-fff*(n-nf0)**2,0.)
1302  ors(i+1)=ors(i+1)*www
1303  ors(i+2)=ors(i+2)*www
1304  ENDIF
1305  i=i+2
1306  ENDDO
1307  ENDDO
1308 !
1309  CALL sptez(nr,nm,4,im,jm,ors,orf,+1)
1310  do j=1,jm
1311  if(numi(j).lt.im) then
1312  call spfft1(im,im/2+1,im,1,ffj,orf(1,j),-1)
1313  call spfft1(numi(j),im/2+1,numi(j),1,ffj,orf(1,j),+1)
1314  endif
1315  enddo
1316 
1317  ELSE
1318  IF (revlat) THEN
1319  CALL revers(im, jm, numi, slm, work1)
1320  CALL revers(im, jm, numi, oro, work1)
1321  DO imt=1,nmt
1322  CALL revers(im, jm, numi, hprime(1,1,imt), work1)
1323  ENDDO
1324  ENDIF
1325  ors=0.
1326  orf=oro
1327  ENDIF
1328 
1329  deallocate (work1)
1330 
1331  call mnmxja(im,jm,elvmax,itest,jtest,' ELVMAX')
1332  print *,' ELVMAX(',itest,jtest,')=',elvmax(itest,jtest)
1333  print *,' after spectral filter is applied'
1334  call minmxj(im,jm,oro,' ORO')
1335  call minmxj(im,jm,orf,' ORF')
1336 C
1337 C USE NEAREST NEIGHBOR INTERPOLATION TO FILL FULL GRIDS
1338  call rg2gg(im,jm,numi,slm)
1339  call rg2gg(im,jm,numi,oro)
1340  call rg2gg(im,jm,numi,orf)
1341 C --- not apply to new prin coord and ELVMAX (*j*)
1342  do imt=1,10
1343  call rg2gg(im,jm,numi,hprime(1,1,imt))
1344  enddo
1345 C
1346  print *,' after nearest neighbor interpolation applied '
1347  call minmxj(im,jm,oro,' ORO')
1348  call minmxj(im,jm,orf,' ORF')
1349  call mnmxja(im,jm,elvmax,itest,jtest,' ELVMAX')
1350  print *,' ORO,ORF(itest,jtest),itest,jtest:',
1351  & oro(itest,jtest),orf(itest,jtest),itest,jtest
1352  print *,' ELVMAX(',itest,jtest,')=',elvmax(itest,jtest)
1353 
1354 
1355 C check antarctic pole
1356  DO j = 1,jm
1357  DO i = 1,numi(j)
1358  if ( i .le. 21 .and. i .ge. 1 )then
1359  if (j .eq. jm )write(6,153)i,j,oro(i,j),elvmax(i,j),slm(i,j)
1360  153 format(1x,' ORO,ELVMAX(i=',i4,' j=',i4,')=',2e14.5,f5.1)
1361  endif
1362  ENDDO
1363  ENDDO
1364  tend=timef()
1365  write(6,*)' Timer 5 time= ',tend-tbeg
1366  if (output_binary) then
1367  tbeg=timef()
1368 C OUTPUT BINARY FIELDS
1369  print *,' OUTPUT BINARY FIELDS'
1370  WRITE(51) REAL(slm,4)
1371  WRITE(52) REAL(orf,4)
1372  WRITE(53) REAL(hprime,4)
1373  WRITE(54) REAL(ors,4)
1374  WRITE(55) REAL(oro,4)
1375  WRITE(66) REAL(theta,4)
1376  WRITE(67) REAL(gamma,4)
1377  WRITE(68) REAL(sigma,4)
1378 ! --- OCLSM is real(4) write only if ocean mask is present
1379  if ( mskocn .eq. 1 ) then
1380  ios=0
1381  WRITE(27,iostat=ios) oclsm
1382  print *,' write OCLSM input:',ios
1383 ! print *,' LSM:',OCLSM(1,1),OCLSM(50,50),OCLSM(75,75),OCLSM(IM,JM)
1384  endif
1385 C
1386  call minmxj(im,jm,oro,' ORO')
1387  print *,' IM=',im,' JM=',jm,' SPECTR=',spectr
1388 C--- Test binary file output:
1389  WRITE(71) REAL(slm,4)
1390  DO imt=1,nmt
1391  WRITE(71) REAL(HPRIME(:,:,IMT),4)
1392  print *,' HPRIME(',itest,jtest,imt,')=',hprime(itest,jtest,imt)
1393  ENDDO
1394  WRITE(71) REAL(oro,4)
1395  IF (spectr) THEN
1396  WRITE(71) REAL(ORF,4) ! smoothed spectral orography!
1397  ENDIF
1398 C OUTPUT GRIB FIELDS
1399  kpds=0
1400  kpds(1)=7
1401  kpds(2)=78
1402  kpds(3)=255
1403  kpds(4)=128
1404  kpds(5)=81
1405  kpds(6)=1
1406  kpds(8)=2004
1407  kpds(9)=1
1408  kpds(10)=1
1409  kpds(13)=4
1410  kpds(15)=1
1411  kpds(16)=51
1412  kpds(17)=1
1413  kpds(18)=1
1414  kpds(19)=1
1415  kpds(21)=20
1416  kpds(22)=0
1417  kgds=0
1418  kgds(1)=4
1419  kgds(2)=im
1420  kgds(3)=jm
1421  kgds(4)=90000-180000/pi*rclt(1)
1422  kgds(6)=128
1423  kgds(7)=180000/pi*rclt(1)-90000
1424  kgds(8)=-nint(360000./im)
1425  kgds(9)=nint(360000./im)
1426  kgds(10)=jm/2
1427  kgds(20)=255
1428 ! --- SLM
1429  CALL baopen(56,'fort.56',iret)
1430  if (iret .ne. 0) print *,' BAOPEN ERROR UNIT 56: IRET=',iret
1431  CALL putgb(56,im*jm,kpds,kgds,lb,slm,iret)
1432  print *,' SLM: putgb-KPDS(22,5),iret:',kpds(22),kpds(5),iret
1433  if (iret .ne. 0) print *,' SLM PUTGB ERROR: UNIT 56: IRET=',iret
1434  print *,' SLM: putgb-KPDS(22,5),iret:',kpds(22),kpds(5),iret
1435 ! --- OCLSM if present
1436 ! if ( mskocn .eq. 1 ) then
1437 ! CALL BAOPEN(27,'fort.27',IRET)
1438 ! if (iret .ne. 0) print *,' OCLSM BAOPEN ERROR UNIT 27:IRET=',IRET
1439 ! CALL PUTGB(27,IM*JM,KPDS,KGDS,LB,OCLSM,IRET)
1440 ! if (iret .ne. 0) print *,' OCLSM PUTGB ERROR: UNIT 27:IRET=',IRET
1441 ! print *,' OCLSM: putgb-KPDS(22,5),iret:',KPDS(22),KPDS(5),IRET
1442 ! endif
1443 
1444  kpds(5)=8
1445  IF (spectr) THEN
1446  CALL baopen(57,'fort.57',iret)
1447  CALL putgb(57,im*jm,kpds,kgds,lb,orf,iret)
1448  print *,' ORF (ORO): putgb-KPDS(22,5),iret:',kpds(22),kpds(5),iret
1449  ENDIF
1450 C
1451 C === write out theta (angle of land to East) using #101 (wave dir)
1452 C === [radians] and since < 1 scale adjust kpds(22)
1453 C
1454  kpds(5)=101
1455  CALL baopen(58,'fort.58',iret)
1456  CALL putgb(58,im*jm,kpds,kgds,lb,theta,iret)
1457  print *,' THETA: putgb-KPDS(22,5),iret:',kpds(22),kpds(5),iret
1458 C
1459 C === write out (land aspect ratio or anisotropy) using #102
1460 C === (as in wind wave hgt)
1461 C
1462  kpds(22)=2
1463  kpds(5)=102
1464  CALL baopen(60,'fort.60',iret)
1465  CALL putgb(60,im*jm,kpds,kgds,lb,sigma,iret)
1466  print *,' SIGMA: putgb-KPDS(22,5),iret:',kpds(22),kpds(5),iret
1467 C
1468 C === write out (slope parameter sigma) using #9
1469 C === (as in std hgt)
1470 C
1471  kpds(22)=1
1472  kpds(5)=103
1473  CALL baopen(59,'fort.59',iret)
1474  CALL putgb(59,im*jm,kpds,kgds,lb,gamma,iret)
1475  print *,' GAMMA: putgb-KPDS(22,5),iret:',kpds(22),kpds(5),iret
1476 C
1477  kpds(22)=1
1478  kpds(5)=9
1479  CALL baopen(61,'fort.61',iret)
1480  CALL putgb(61,im*jm,kpds,kgds,lb,hprime,iret)
1481  print *,' HPRIME: putgb-KPDS(22,5),iret:',kpds(22),kpds(5),iret
1482 C
1483 C
1484  kpds(22)=0
1485  kpds(5)=8
1486  CALL baopen(62,'fort.62',iret)
1487  CALL putgb(62,im*jm,kpds,kgds,lb,elvmax,iret)
1488  print *,' ELVMAX: putgb-KPDS(22,5),iret:',kpds(22),kpds(5),iret
1489  endif ! output_binary
1490 C
1491  delxn = 360./im
1492  do i=1,im
1493  xlon(i) = delxn*(i-1)
1494  enddo
1495  IF(trim(outgrid) == "none") THEN
1496  do j=1,jm
1497  do i=1,im
1498  geolon(i,j) = xlon(i)
1499  geolat(i,j) = xlat(j)
1500  enddo
1501  enddo
1502  else
1503  do j = 1, jm
1504  xlat(j) = geolat(1,j)
1505  enddo
1506  do i = 1, im
1507  xlon(i) = geolon(i,1)
1508  enddo
1509  endif
1510  tend=timef()
1511  write(6,*)' Binary output time= ',tend-tbeg
1512  tbeg=timef()
1513  CALL write_netcdf(im,jm,slm,land_frac,oro,orf,hprime,1,1,
1514  1 geolon(1:im,1:jm),geolat(1:im,1:jm), xlon,xlat)
1515  tend=timef()
1516  write(6,*)' WRITE_NETCDF time= ',tend-tbeg
1517  print *,' wrote netcdf file out.oro.tile?.nc'
1518 
1519  print *,' ===== Deallocate Arrays and ENDING MTN VAR OROG program'
1520 
1521 ! Deallocate 1d vars
1522  deallocate(jst,jen,kpds,kgds,numi,lonsperlat)
1523  deallocate(cosclt,wgtclt,rclt,xlat,diffx,xlon,ors,oaa,ola,glat)
1524 
1525 ! Deallocate 2d vars
1526  deallocate (oclsm)
1527  deallocate (geolon,geolon_c,geolat,geolat_c)
1528  deallocate (slm,oro,var,orf,land_frac)
1529  deallocate (theta,gamma,sigma,elvmax)
1530 
1531 
1532  tend=timef()
1533  write(6,*)' Total runtime time= ',tend-tbeg1
1534  RETURN
1535  END
1536 
1566  SUBROUTINE makemt(ZAVG,ZSLM,ORO,SLM,VAR,VAR4,
1567  1 glat,ist,ien,jst,jen,im,jm,imn,jmn,xlat,numi)
1568  dimension glat(jmn),xlat(jm)
1569 ! REAL*4 OCLSM
1570  INTEGER zavg(imn,jmn),zslm(imn,jmn)
1571  dimension oro(im,jm),slm(im,jm),var(im,jm),var4(im,jm)
1572  dimension ist(im,jm),ien(im,jm),jst(jm),jen(jm),numi(jm)
1573  LOGICAL flag, debug
1574 C==== DATA DEBUG/.TRUE./
1575  DATA debug/.false./
1576 C
1577 ! ---- OCLSM holds the ocean (im,jm) grid
1578  print *,' _____ SUBROUTINE MAKEMT '
1579 C---- GLOBAL XLAT AND XLON ( DEGREE )
1580 C
1581  jm1 = jm - 1
1582  delxn = 360./imn ! MOUNTAIN DATA RESOLUTION
1583 C
1584  DO j=1,jmn
1585  glat(j) = -90. + (j-1) * delxn + delxn * 0.5
1586  ENDDO
1587 C
1588 C---- FIND THE AVERAGE OF THE MODES IN A GRID BOX
1589 C
1590 C (*j*) for hard wired zero offset (lambda s =0) for terr05
1591  DO j=1,jm
1592  DO i=1,numi(j)
1593  im1 = numi(j) - 1
1594  delx = 360./numi(j) ! GAUSSIAN GRID RESOLUTION
1595  faclon = delx / delxn
1596  ist(i,j) = faclon * float(i-1) - faclon * 0.5 + 1
1597  ien(i,j) = faclon * float(i) - faclon * 0.5 + 1
1598 ! IST(I,j) = FACLON * FLOAT(I-1) + 1.0001
1599 ! IEN(I,j) = FACLON * FLOAT(I) + 0.0001
1600 C
1601  IF (ist(i,j) .LE. 0) ist(i,j) = ist(i,j) + imn
1602  IF (ien(i,j) .LT. ist(i,j)) ien(i,j) = ien(i,j) + imn
1603 !
1604 ! if ( I .lt. 10 .and. J .ge. JM-1 )
1605 ! 1 PRINT*,' MAKEMT: I j IST IEN ',I,j,IST(I,j),IEN(I,j)
1606  ENDDO
1607 ! if ( J .ge. JM-1 ) then
1608 ! print *,' *** FACLON=',FACLON, 'numi(j=',j,')=',numi(j)
1609 ! endif
1610  ENDDO
1611  print *,' DELX=',delx,' DELXN=',delxn
1612  DO j=1,jm-1
1613  flag=.true.
1614  DO j1=1,jmn
1615  xxlat = (xlat(j)+xlat(j+1))/2.
1616  IF(flag.AND.glat(j1).GT.xxlat) THEN
1617  jst(j) = j1
1618  jen(j+1) = j1 - 1
1619  flag = .false.
1620  ENDIF
1621  ENDDO
1622 CX PRINT*, ' J JST JEN ',J,JST(J),JEN(J),XLAT(J),GLAT(J1)
1623  ENDDO
1624  jst(jm) = max(jst(jm-1) - (jen(jm-1)-jst(jm-1)),1)
1625  jen(1) = min(jen(2) + (jen(2)-jst(2)),jmn)
1626 ! PRINT*, ' JM JST JEN=',JST(JM),JEN(JM),XLAT(JM),GLAT(JMN)
1627 C
1628 C...FIRST, AVERAGED HEIGHT
1629 C
1630  DO j=1,jm
1631  DO i=1,numi(j)
1632  oro(i,j) = 0.0
1633  var(i,j) = 0.0
1634  var4(i,j) = 0.0
1635  xnsum = 0.0
1636  xland = 0.0
1637  xwatr = 0.0
1638  xl1 = 0.0
1639  xs1 = 0.0
1640  xw1 = 0.0
1641  xw2 = 0.0
1642  xw4 = 0.0
1643  DO ii1 = 1, ien(i,j) - ist(i,j) + 1
1644  i1 = ist(i,j) + ii1 - 1
1645  IF(i1.LE.0.) i1 = i1 + imn
1646  IF(i1.GT.imn) i1 = i1 - imn
1647 ! if ( i .le. 10 .and. i .ge. 1 ) then
1648 ! if (j .eq. JM )
1649 ! &print *,' J,JST,JEN,IST,IEN,I1=',
1650 ! &J,JST(j),JEN(J),IST(I,j),IEN(I,j),I1
1651 ! endif
1652  DO j1=jst(j),jen(j)
1653  xland = xland + float(zslm(i1,j1))
1654  xwatr = xwatr + float(1-zslm(i1,j1))
1655  xnsum = xnsum + 1.
1656  height = float(zavg(i1,j1))
1657 C.........
1658  IF(height.LT.-990.) height = 0.0
1659  xl1 = xl1 + height * float(zslm(i1,j1))
1660  xs1 = xs1 + height * float(1-zslm(i1,j1))
1661  xw1 = xw1 + height
1662  xw2 = xw2 + height ** 2
1663 C check antarctic pole
1664 ! if ( i .le. 10 .and. i .ge. 1 )then
1665 ! if (j .ge. JM-1 )then
1666 C=== degub testing
1667 ! print *," I,J,I1,J1,XL1,XS1,XW1,XW2:",I,J,I1,J1,XL1,XS1,XW1,XW2
1668 ! 153 format(1x,' ORO,ELVMAX(i=',i4,' j=',i4,')=',2E14.5,3f5.1)
1669 ! endif
1670 ! endif
1671  ENDDO
1672  ENDDO
1673  IF(xnsum.GT.1.) THEN
1674 ! --- SLM initialized with OCLSM calc from all land points except ....
1675 ! --- 0 is ocean and 1 is land for slm
1676 ! --- Step 1 is to only change SLM after GFS SLM is applied
1677 
1678  slm(i,j) = float(nint(xland/xnsum))
1679  IF(slm(i,j).NE.0.) THEN
1680  oro(i,j)= xl1 / xland
1681  ELSE
1682  oro(i,j)= xs1 / xwatr
1683  ENDIF
1684  var(i,j)=sqrt(max(xw2/xnsum-(xw1/xnsum)**2,0.))
1685  DO ii1 = 1, ien(i,j) - ist(i,j) + 1
1686  i1 = ist(i,j) + ii1 - 1
1687  IF(i1.LE.0.) i1 = i1 + imn
1688  IF(i1.GT.imn) i1 = i1 - imn
1689  DO j1=jst(j),jen(j)
1690  height = float(zavg(i1,j1))
1691  IF(height.LT.-990.) height = 0.0
1692  xw4 = xw4 + (height-oro(i,j)) ** 4
1693  ENDDO
1694  ENDDO
1695  IF(var(i,j).GT.1.) THEN
1696 ! if ( I .lt. 20 .and. J .ge. JM-19 ) then
1697 ! print *,'I,J,XW4,XNSUM,VAR(I,J)',I,J,XW4,XNSUM,VAR(I,J)
1698 ! endif
1699  var4(i,j) = min(xw4/xnsum/var(i,j) **4,10.)
1700  ENDIF
1701  ENDIF
1702  ENDDO
1703  ENDDO
1704  WRITE(6,*) "! MAKEMT ORO SLM VAR VAR4 DONE"
1705 C
1706 
1707  RETURN
1708  END
1709 
1729  SUBROUTINE get_index(IMN,JMN,npts,lonO,latO,DELXN,
1730  & jst,jen,ilist,numx)
1731  implicit none
1732  integer, intent(in) :: imn,jmn
1733  integer :: npts
1734  real, intent(in) :: lono(npts), lato(npts)
1735  real, intent(in) :: delxn
1736  integer, intent(out) :: jst,jen
1737  integer, intent(out) :: ilist(imn)
1738  integer, intent(out) :: numx
1739  real minlat,maxlat,minlon,maxlon
1740  integer i2, ii, ist, ien
1741 
1742  minlat = minval(lato)
1743  maxlat = maxval(lato)
1744  minlon = minval(lono)
1745  maxlon = maxval(lono)
1746  ist = minlon/delxn+1
1747  ien = maxlon/delxn+1
1748  jst = (minlat+90)/delxn+1
1749  jen = (maxlat+90)/delxn
1750  !--- add a few points to both ends of j-direction
1751  jst = jst - 5
1752  if(jst<1) jst = 1
1753  jen = jen + 5
1754  if(jen>jmn) jen = jmn
1755 
1756  !--- when around the pole, just search through all the points.
1757  if((jst == 1 .OR. jen == jmn) .and.
1758  & (ien-ist+1 > imn/2) )then
1759  numx = imn
1760  do i2 = 1, imn
1761  ilist(i2) = i2
1762  enddo
1763  else if( ien-ist+1 > imn/2 ) then ! cross longitude = 0
1764  !--- find the minimum that greater than IMN/2
1765  !--- and maximum that less than IMN/2
1766  ist = 0
1767  ien = imn+1
1768  do i2 = 1, npts
1769  ii = lono(i2)/delxn+1
1770  if(ii <0 .or. ii>imn) print*,"ii=",ii,imn,lono(i2),delxn
1771  if( ii < imn/2 ) then
1772  ist = max(ist,ii)
1773  else if( ii > imn/2 ) then
1774  ien = min(ien,ii)
1775  endif
1776  enddo
1777  if(ist<1 .OR. ist>imn) then
1778  print*, .or."ist<1 ist>IMN"
1779  call abort()
1780  endif
1781  if(ien<1 .OR. ien>imn) then
1782  print*, .or."iend<1 iend>IMN"
1783  call abort()
1784  endif
1785 
1786  numx = imn - ien + 1
1787  do i2 = 1, numx
1788  ilist(i2) = ien + (i2-1)
1789  enddo
1790  do i2 = 1, ist
1791  ilist(numx+i2) = i2
1792  enddo
1793  numx = numx+ist
1794  else
1795  numx = ien-ist+1
1796  do i2 = 1, numx
1797  ilist(i2) = ist + (i2-1)
1798  enddo
1799  endif
1800 
1801  END
1802 
1818  SUBROUTINE make_mask(zslm,SLM,land_frac,
1819  1 glat,im,jm,imn,jmn,lon_c,lat_c)
1820  implicit none
1821  real, parameter :: d2r = 3.14159265358979/180.
1822  integer, parameter :: maxsum=20000000
1823  integer im, jm, imn, jmn, jst, jen
1824  real glat(jmn), glon(imn)
1825  INTEGER zslm(imn,jmn)
1826  real land_frac(im,jm)
1827  real slm(im,jm)
1828  real lon_c(im+1,jm+1), lat_c(im+1,jm+1)
1829  real lono(4),lato(4),loni,lati
1830  integer jm1,i,j,nsum,nsum_all,ii,jj,numx,i2
1831  integer ilist(imn)
1832  real delxn,xnsum,xland,xwatr,xl1,xs1,xw1
1833  real xnsum_all,xland_all,xwatr_all
1834  logical inside_a_polygon
1835 C
1836 ! ---- OCLSM holds the ocean (im,jm) grid
1837  print *,' _____ SUBROUTINE MAKE_MASK '
1838 C---- GLOBAL XLAT AND XLON ( DEGREE )
1839 C
1840  jm1 = jm - 1
1841  delxn = 360./imn ! MOUNTAIN DATA RESOLUTION
1842 C
1843  DO j=1,jmn
1844  glat(j) = -90. + (j-1) * delxn + delxn * 0.5
1845  ENDDO
1846  DO i=1,imn
1847  glon(i) = 0. + (i-1) * delxn + delxn * 0.5
1848  ENDDO
1849 
1850  land_frac(:,:) = 0.0
1851 C
1852 C---- FIND THE AVERAGE OF THE MODES IN A GRID BOX
1853 C
1854 C (*j*) for hard wired zero offset (lambda s =0) for terr05
1855 !$omp parallel do
1856 !$omp* private (j,i,xnsum,xland,xwatr,nsum,xl1,xs1,xw1,lono,
1857 !$omp* lato,jst,jen,ilist,numx,jj,i2,ii,loni,lati,
1858 !$omp* xnsum_all,xland_all,xwatr_all,nsum_all)
1859 !$omp*
1860  DO j=1,jm
1861 ! print*, "J=", J
1862  DO i=1,im
1863  xnsum = 0.0
1864  xland = 0.0
1865  xwatr = 0.0
1866  nsum = 0
1867  xnsum_all = 0.0
1868  xland_all = 0.0
1869  xwatr_all = 0.0
1870  nsum_all = 0
1871 
1872  lono(1) = lon_c(i,j)
1873  lono(2) = lon_c(i+1,j)
1874  lono(3) = lon_c(i+1,j+1)
1875  lono(4) = lon_c(i,j+1)
1876  lato(1) = lat_c(i,j)
1877  lato(2) = lat_c(i+1,j)
1878  lato(3) = lat_c(i+1,j+1)
1879  lato(4) = lat_c(i,j+1)
1880  call get_index(imn,jmn,4,lono,lato,delxn,jst,jen,ilist,numx)
1881  do jj = jst, jen; do i2 = 1, numx
1882  ii = ilist(i2)
1883  loni = ii*delxn
1884  lati = -90 + jj*delxn
1885 
1886  xland_all = xland_all + float(zslm(ii,jj))
1887  xwatr_all = xwatr_all + float(1-zslm(ii,jj))
1888  xnsum_all = xnsum_all + 1.
1889  nsum_all = nsum_all+1
1890  if(nsum_all > maxsum) then
1891  print*, "nsum_all is greater than MAXSUM, increase MAXSUM"
1892  call abort()
1893  endif
1894 
1895  if(inside_a_polygon(loni*d2r,lati*d2r,4,
1896  & lono*d2r,lato*d2r))then
1897 
1898  xland = xland + float(zslm(ii,jj))
1899  xwatr = xwatr + float(1-zslm(ii,jj))
1900  xnsum = xnsum + 1.
1901  nsum = nsum+1
1902  if(nsum > maxsum) then
1903  print*, "nsum is greater than MAXSUM, increase MAXSUM"
1904  call abort()
1905  endif
1906  endif
1907  enddo ; enddo
1908 
1909 
1910  IF(xnsum.GT.1.) THEN
1911 ! --- SLM initialized with OCLSM calc from all land points except ....
1912 ! --- 0 is ocean and 1 is land for slm
1913 ! --- Step 1 is to only change SLM after GFS SLM is applied
1914  land_frac(i,j) = xland/xnsum
1915  slm(i,j) = float(nint(xland/xnsum))
1916  ELSEIF(xnsum_all.GT.1.) THEN
1917  land_frac(i,j) = xland_all/xnsum _all
1918  slm(i,j) = float(nint(xland_all/xnsum_all))
1919  ELSE
1920  print*, "no source points in MAKE_MASK"
1921  call abort()
1922  ENDIF
1923  ENDDO
1924  ENDDO
1925 !$omp end parallel do
1926  WRITE(6,*) "! MAKE_MASK DONE"
1927 C
1928  RETURN
1929  END SUBROUTINE make_mask
1951  SUBROUTINE makemt2(ZAVG,ZSLM,ORO,SLM,VAR,VAR4,
1952  1 glat,im,jm,imn,jmn,lon_c,lat_c,lake_frac,land_frac)
1953  implicit none
1954  real, parameter :: d2r = 3.14159265358979/180.
1955  integer, parameter :: maxsum=20000000
1956  real, dimension(:), allocatable :: hgt_1d, hgt_1d_all
1957  integer im, jm, imn, jmn
1958  real glat(jmn), glon(imn)
1959  INTEGER zavg(imn,jmn),zslm(imn,jmn)
1960  real oro(im,jm),var(im,jm),var4(im,jm)
1961  real, intent(in) :: slm(im,jm), lake_frac(im,jm),land_frac(im,jm)
1962  integer jst, jen
1963  real lon_c(im+1,jm+1), lat_c(im+1,jm+1)
1964  real lono(4),lato(4),loni,lati
1965  real height
1966  integer jm1,i,j,nsum,nsum_all,ii,jj,i1,numx,i2
1967  integer ilist(imn)
1968  real delxn,xnsum,xland,xwatr,xl1,xs1,xw1,xw2,xw4
1969  real xnsum_all,xland_all,xwatr_all,height_all
1970  real xl1_all,xs1_all,xw1_all,xw2_all,xw4_all
1971  logical inside_a_polygon
1972 C
1973 ! ---- OCLSM holds the ocean (im,jm) grid
1974 ! --- mskocn=1 Use ocean model sea land mask, OK and present,
1975 ! --- mskocn=0 dont use Ocean model sea land mask, not OK, not present
1976  print *,' _____ SUBROUTINE MAKEMT2 '
1977  allocate(hgt_1d(maxsum))
1978  allocate(hgt_1d_all(maxsum))
1979 C---- GLOBAL XLAT AND XLON ( DEGREE )
1980 C
1981  jm1 = jm - 1
1982  delxn = 360./imn ! MOUNTAIN DATA RESOLUTION
1983 C
1984  DO j=1,jmn
1985  glat(j) = -90. + (j-1) * delxn + delxn * 0.5
1986  ENDDO
1987  DO i=1,imn
1988  glon(i) = 0. + (i-1) * delxn + delxn * 0.5
1989  ENDDO
1990 
1991 ! land_frac(:,:) = 0.0
1992 C
1993 C---- FIND THE AVERAGE OF THE MODES IN A GRID BOX
1994 C
1995 C (*j*) for hard wired zero offset (lambda s =0) for terr05
1996 !$omp parallel do
1997 !$omp* private (j,i,xnsum,xland,xwatr,nsum,xl1,xs1,xw1,xw2,xw4,lono,
1998 !$omp* lato,jst,jen,ilist,numx,jj,i2,ii,loni,lati,height,
1999 !$omp* hgt_1d,
2000 !$omp* xnsum_all,xland_all,xwatr_all,nsum_all,
2001 !$omp* xl1_all,xs1_all,xw1_all,xw2_all,xw4_all,
2002 !$omp* height_all,hgt_1d_all)
2003  DO j=1,jm
2004 ! print*, "J=", J
2005  DO i=1,im
2006  oro(i,j) = 0.0
2007  var(i,j) = 0.0
2008  var4(i,j) = 0.0
2009  xnsum = 0.0
2010  xland = 0.0
2011  xwatr = 0.0
2012  nsum = 0
2013  xl1 = 0.0
2014  xs1 = 0.0
2015  xw1 = 0.0
2016  xw2 = 0.0
2017  xw4 = 0.0
2018  xnsum_all = 0.0
2019  xland_all = 0.0
2020  xwatr_all = 0.0
2021  nsum_all = 0
2022  xl1_all = 0.0
2023  xs1_all = 0.0
2024  xw1_all = 0.0
2025  xw2_all = 0.0
2026  xw4_all = 0.0
2027 
2028  lono(1) = lon_c(i,j)
2029  lono(2) = lon_c(i+1,j)
2030  lono(3) = lon_c(i+1,j+1)
2031  lono(4) = lon_c(i,j+1)
2032  lato(1) = lat_c(i,j)
2033  lato(2) = lat_c(i+1,j)
2034  lato(3) = lat_c(i+1,j+1)
2035  lato(4) = lat_c(i,j+1)
2036  call get_index(imn,jmn,4,lono,lato,delxn,jst,jen,ilist,numx)
2037  do jj = jst, jen; do i2 = 1, numx
2038  ii = ilist(i2)
2039  loni = ii*delxn
2040  lati = -90 + jj*delxn
2041 
2042  xland_all = xland_all + float(zslm(ii,jj))
2043  xwatr_all = xwatr_all + float(1-zslm(ii,jj))
2044  xnsum_all = xnsum_all + 1.
2045  height_all = float(zavg(ii,jj))
2046  nsum_all = nsum_all+1
2047  if(nsum_all > maxsum) then
2048  print*, "nsum_all is greater than MAXSUM, increase MAXSUM"
2049  call abort()
2050  endif
2051  hgt_1d_all(nsum_all) = height_all
2052  IF(height_all.LT.-990.) height_all = 0.0
2053  xl1_all = xl1_all + height_all * float(zslm(ii,jj))
2054  xs1_all = xs1_all + height_all * float(1-zslm(ii,jj))
2055  xw1_all = xw1_all + height_all
2056  xw2_all = xw2_all + height_all ** 2
2057 
2058  if(inside_a_polygon(loni*d2r,lati*d2r,4,
2059  & lono*d2r,lato*d2r))then
2060 
2061  xland = xland + float(zslm(ii,jj))
2062  xwatr = xwatr + float(1-zslm(ii,jj))
2063  xnsum = xnsum + 1.
2064  height = float(zavg(ii,jj))
2065  nsum = nsum+1
2066  if(nsum > maxsum) then
2067  print*, "nsum is greater than MAXSUM, increase MAXSUM"
2068  call abort()
2069  endif
2070  hgt_1d(nsum) = height
2071  IF(height.LT.-990.) height = 0.0
2072  xl1 = xl1 + height * float(zslm(ii,jj))
2073  xs1 = xs1 + height * float(1-zslm(ii,jj))
2074  xw1 = xw1 + height
2075  xw2 = xw2 + height ** 2
2076  endif
2077  enddo ; enddo
2078 
2079  IF(xnsum.GT.1.) THEN
2080 ! --- SLM initialized with OCLSM calc from all land points except ....
2081 ! --- 0 is ocean and 1 is land for slm
2082 ! --- Step 1 is to only change SLM after GFS SLM is applied
2083 
2084  !IF(SLM(I,J).NE.0.) THEN
2085  IF(slm(i,j) .NE. 0. .OR. land_frac(i,j) > 0.) THEN
2086  IF (xland > 0) THEN
2087  oro(i,j)= xl1 / xland
2088  ELSE
2089  oro(i,j)= xs1 / xwatr
2090  ENDIF
2091  ELSE
2092  IF (xwatr > 0) THEN
2093  oro(i,j)= xs1 / xwatr
2094  ELSE
2095  oro(i,j)= xl1 / xland
2096  ENDIF
2097  ENDIF
2098 
2099  var(i,j)=sqrt(max(xw2/xnsum-(xw1/xnsum)**2,0.))
2100  do i1 = 1, nsum
2101  xw4 = xw4 + (hgt_1d(i1) - oro(i,j)) ** 4
2102  enddo
2103 
2104  IF(var(i,j).GT.1.) THEN
2105  var4(i,j) = min(xw4/xnsum/var(i,j) **4,10.)
2106  ENDIF
2107 
2108  ELSEIF(xnsum_all.GT.1.) THEN
2109 
2110  !IF(SLM(I,J).NE.0.) THEN
2111  IF(slm(i,j) .NE. 0. .OR. land_frac(i,j) > 0.) THEN
2112  IF (xland_all > 0) THEN
2113  oro(i,j)= xl1_all / xland_all
2114  ELSE
2115  oro(i,j)= xs1_all / xwatr_all
2116  ENDIF
2117  ELSE
2118  IF (xwatr_all > 0) THEN
2119  oro(i,j)= xs1_all / xwatr_all
2120  ELSE
2121  oro(i,j)= xl1_all / xland_all
2122  ENDIF
2123  ENDIF
2124 
2125  var(i,j)=sqrt(max(xw2_all/xnsum_all-
2126  & (xw1_all/xnsum_all)**2,0.))
2127  do i1 = 1, nsum_all
2128  xw4_all = xw4_all +
2129  & (hgt_1d_all(i1) - oro(i,j)) ** 4
2130  enddo
2131 
2132  IF(var(i,j).GT.1.) THEN
2133  var4(i,j) = min(xw4_all/xnsum_all/var(i,j) **4,10.)
2134  ENDIF
2135  ELSE
2136  print*, "no source points in MAKEMT2"
2137  call abort()
2138  ENDIF
2139 
2140 ! set orog to 0 meters at ocean.
2141 ! IF (LAKE_FRAC(I,J) .EQ. 0. .AND. SLM(I,J) .EQ. 0.)THEN
2142  IF (lake_frac(i,j) .EQ. 0. .AND. land_frac(i,j) .EQ. 0.)THEN
2143  oro(i,j) = 0.0
2144  ENDIF
2145 
2146  ENDDO
2147  ENDDO
2148 !$omp end parallel do
2149  WRITE(6,*) "! MAKEMT2 ORO SLM VAR VAR4 DONE"
2150 C
2151  deallocate(hgt_1d)
2152  deallocate(hgt_1d_all)
2153  RETURN
2154  END
2155 
2184  SUBROUTINE makepc(ZAVG,ZSLM,THETA,GAMMA,SIGMA,
2185  1 glat,ist,ien,jst,jen,im,jm,imn,jmn,xlat,numi)
2186 C
2187 C=== PC: principal coordinates of each Z avg orog box for L&M
2188 C
2189  parameter(rearth=6.3712e+6)
2190  dimension glat(jmn),xlat(jm),deltax(jmn)
2191  INTEGER zavg(imn,jmn),zslm(imn,jmn)
2192  dimension oro(im,jm),slm(im,jm),hl(im,jm),hk(im,jm)
2193  dimension hx2(im,jm),hy2(im,jm),hxy(im,jm),hlprim(im,jm)
2194  dimension theta(im,jm),gamma(im,jm),sigma2(im,jm),sigma(im,jm)
2195  dimension ist(im,jm),ien(im,jm),jst(jm),jen(jm),numi(jm)
2196  LOGICAL flag, debug
2197 C=== DATA DEBUG/.TRUE./
2198  DATA debug/.false./
2199 C
2200  pi = 4.0 * atan(1.0)
2201  certh = pi * rearth
2202 C---- GLOBAL XLAT AND XLON ( DEGREE )
2203 C
2204  jm1 = jm - 1
2205  delxn = 360./imn ! MOUNTAIN DATA RESOLUTION
2206  deltay = certh / float(jmn)
2207  print *, 'MAKEPC: DELTAY=',deltay
2208 C
2209  DO j=1,jmn
2210  glat(j) = -90. + (j-1) * delxn + delxn * 0.5
2211  deltax(j) = deltay * cos(glat(j)*pi/180.0)
2212  ENDDO
2213 C
2214 C---- FIND THE AVERAGE OF THE MODES IN A GRID BOX
2215 C
2216  DO j=1,jm
2217  DO i=1,numi(j)
2218 C IM1 = numi(j) - 1
2219  delx = 360./numi(j) ! GAUSSIAN GRID RESOLUTION
2220  faclon = delx / delxn
2221  ist(i,j) = faclon * float(i-1) - faclon * 0.5
2222  ist(i,j) = ist(i,j) + 1
2223  ien(i,j) = faclon * float(i) - faclon * 0.5
2224 C if (debug) then
2225 C if ( I .lt. 10 .and. J .lt. 10 )
2226 C 1 PRINT*, ' I j IST IEN ',I,j,IST(I,j),IEN(I,j)
2227 C endif
2228 ! IST(I,j) = FACLON * FLOAT(I-1) + 1.0001
2229 ! IEN(I,j) = FACLON * FLOAT(I) + 0.0001
2230  IF (ist(i,j) .LE. 0) ist(i,j) = ist(i,j) + imn
2231  IF (ien(i,j) .LT. ist(i,j)) ien(i,j) = ien(i,j) + imn
2232  if (debug) then
2233  if ( i .lt. 10 .and. j .lt. 10 )
2234  1 print*, ' I j IST IEN ',i,j,ist(i,j),ien(i,j)
2235  endif
2236  IF (ien(i,j) .LT. ist(i,j))
2237  1 print *,' MAKEPC: IEN < IST: I,J,IST(I,J),IEN(I,J)',
2238  2 i,j,ist(i,j),ien(i,j)
2239  ENDDO
2240  ENDDO
2241  DO j=1,jm-1
2242  flag=.true.
2243  DO j1=1,jmn
2244  xxlat = (xlat(j)+xlat(j+1))/2.
2245  IF(flag.AND.glat(j1).GT.xxlat) THEN
2246  jst(j) = j1
2247  jen(j+1) = j1 - 1
2248  flag = .false.
2249  ENDIF
2250  ENDDO
2251  ENDDO
2252  jst(jm) = max(jst(jm-1) - (jen(jm-1)-jst(jm-1)),1)
2253  jen(1) = min(jen(2) + (jen(2)-jst(2)),jmn)
2254  if (debug) then
2255  print*, ' IST,IEN(1,1-numi(1,JM))',ist(1,1),ien(1,1),
2256  1 ist(numi(jm),jm),ien(numi(jm),jm), numi(jm)
2257  print*, ' JST,JEN(1,JM) ',jst(1),jen(1),jst(jm),jen(jm)
2258  endif
2259 C
2260 C... DERIVITIVE TENSOR OF HEIGHT
2261 C
2262  DO j=1,jm
2263  DO i=1,numi(j)
2264  oro(i,j) = 0.0
2265  hx2(i,j) = 0.0
2266  hy2(i,j) = 0.0
2267  hxy(i,j) = 0.0
2268  xnsum = 0.0
2269  xland = 0.0
2270  xwatr = 0.0
2271  xl1 = 0.0
2272  xs1 = 0.0
2273  xfp = 0.0
2274  yfp = 0.0
2275  xfpyfp = 0.0
2276  xfp2 = 0.0
2277  yfp2 = 0.0
2278  hl(i,j) = 0.0
2279  hk(i,j) = 0.0
2280  hlprim(i,j) = 0.0
2281  theta(i,j) = 0.0
2282  gamma(i,j) = 0.
2283  sigma2(i,j) = 0.
2284  sigma(i,j) = 0.
2285 C
2286  DO ii1 = 1, ien(i,j) - ist(i,j) + 1
2287  i1 = ist(i,j) + ii1 - 1
2288  IF(i1.LE.0.) i1 = i1 + imn
2289  IF(i1.GT.imn) i1 = i1 - imn
2290 C
2291 C=== set the rest of the indexs for ave: 2pt staggered derivitive
2292 C
2293  i0 = i1 - 1
2294  if (i1 - 1 .le. 0 ) i0 = i0 + imn
2295  if (i1 - 1 .gt. imn) i0 = i0 - imn
2296 C
2297  ip1 = i1 + 1
2298  if (i1 + 1 .le. 0 ) ip1 = ip1 + imn
2299  if (i1 + 1 .gt. imn) ip1 = ip1 - imn
2300 C
2301  DO j1=jst(j),jen(j)
2302  if (debug) then
2303  if ( i1 .eq. ist(i,j) .and. j1 .eq. jst(j) )
2304  1 print*, ' J, J1,IST,JST,DELTAX,GLAT ',
2305  2 j,j1,ist(i,j),jst(j),deltax(j1),glat(j1)
2306  if ( i1 .eq. ien(i,j) .and. j1 .eq. jen(j) )
2307  1 print*, ' J, J1,IEN,JEN,DELTAX,GLAT ',
2308  2 j,j1,ien(i,j),jen(j),deltax(j1),glat(j1)
2309  endif
2310  xland = xland + float(zslm(i1,j1))
2311  xwatr = xwatr + float(1-zslm(i1,j1))
2312  xnsum = xnsum + 1.
2313 C
2314  height = float(zavg(i1,j1))
2315  hi0 = float(zavg(i0,j1))
2316  hip1 = float(zavg(ip1,j1))
2317 C
2318  IF(height.LT.-990.) height = 0.0
2319  if(hi0 .lt. -990.) hi0 = 0.0
2320  if(hip1 .lt. -990.) hip1 = 0.0
2321 C........ xfp = xfp + 0.5 * ( hip1 - hi0 ) / DELTAX(J1)
2322  xfp = 0.5 * ( hip1 - hi0 ) / deltax(j1)
2323  xfp2 = xfp2 + 0.25 * ( ( hip1 - hi0 )/deltax(j1) )** 2
2324 C
2325 ! --- not at boundaries
2326 !RAB if ( J1 .ne. JST(1) .and. J1 .ne. JEN(JM) ) then
2327  if ( j1 .ne. jst(jm) .and. j1 .ne. jen(1) ) then
2328  hj0 = float(zavg(i1,j1-1))
2329  hjp1 = float(zavg(i1,j1+1))
2330  if(hj0 .lt. -990.) hj0 = 0.0
2331  if(hjp1 .lt. -990.) hjp1 = 0.0
2332 C....... yfp = yfp + 0.5 * ( hjp1 - hj0 ) / DELTAY
2333  yfp = 0.5 * ( hjp1 - hj0 ) / deltay
2334  yfp2 = yfp2 + 0.25 * ( ( hjp1 - hj0 )/deltay )**2
2335 C
2336 C..............elseif ( J1 .eq. JST(J) .or. J1 .eq. JEN(JM) ) then
2337 C === the NH pole: NB J1 goes from High at NP to Low toward SP
2338 C
2339 !RAB elseif ( J1 .eq. JST(1) ) then
2340  elseif ( j1 .eq. jst(jm) ) then
2341  ijax = i1 + imn/2
2342  if (ijax .le. 0 ) ijax = ijax + imn
2343  if (ijax .gt. imn) ijax = ijax - imn
2344 C..... at N pole we stay at the same latitude j1 but cross to opp side
2345  hijax = float(zavg(ijax,j1))
2346  hi1j1 = float(zavg(i1,j1))
2347  if(hijax .lt. -990.) hijax = 0.0
2348  if(hi1j1 .lt. -990.) hi1j1 = 0.0
2349 C....... yfp = yfp + 0.5 * ( ( 0.5 * ( hijax + hi1j1) ) - hi1j1 )/DELTAY
2350  yfp = 0.5 * ( ( 0.5 * ( hijax - hi1j1 ) ) )/deltay
2351  yfp2 = yfp2 + 0.25 * ( ( 0.5 * ( hijax - hi1j1) )
2352  1 / deltay )**2
2353 C
2354 C === the SH pole: NB J1 goes from High at NP to Low toward SP
2355 C
2356 !RAB elseif ( J1 .eq. JEN(JM) ) then
2357  elseif ( j1 .eq. jen(1) ) then
2358  ijax = i1 + imn/2
2359  if (ijax .le. 0 ) ijax = ijax + imn
2360  if (ijax .gt. imn) ijax = ijax - imn
2361  hijax = float(zavg(ijax,j1))
2362  hi1j1 = float(zavg(i1,j1))
2363  if(hijax .lt. -990.) hijax = 0.0
2364  if(hi1j1 .lt. -990.) hi1j1 = 0.0
2365  if ( i1 .lt. 5 )print *,' S.Pole i1,j1 :',i1,j1,hijax,hi1j1
2366 C..... yfp = yfp + 0.5 * (0.5 * ( hijax - hi1j1) )/DELTAY
2367  yfp = 0.5 * (0.5 * ( hijax - hi1j1) )/deltay
2368  yfp2 = yfp2 + 0.25 * ( (0.5 * (hijax - hi1j1) )
2369  1 / deltay )**2
2370  endif
2371 C
2372 C === The above does an average across the pole for the bndry in j.
2373 C23456789012345678901234567890123456789012345678901234567890123456789012......
2374 C
2375  xfpyfp = xfpyfp + xfp * yfp
2376  xl1 = xl1 + height * float(zslm(i1,j1))
2377  xs1 = xs1 + height * float(1-zslm(i1,j1))
2378 C
2379 C === average the HX2, HY2 and HXY
2380 C === This will be done over all land
2381 C
2382  ENDDO
2383  ENDDO
2384 C
2385 C === HTENSR
2386 C
2387  IF(xnsum.GT.1.) THEN
2388  slm(i,j) = float(nint(xland/xnsum))
2389  IF(slm(i,j).NE.0.) THEN
2390  oro(i,j)= xl1 / xland
2391  hx2(i,j) = xfp2 / xland
2392  hy2(i,j) = yfp2 / xland
2393  hxy(i,j) = xfpyfp / xland
2394  ELSE
2395  oro(i,j)= xs1 / xwatr
2396  ENDIF
2397 C=== degub testing
2398  if (debug) then
2399  print *," I,J,i1,j1,HEIGHT:", i,j,i1,j1,height,
2400  1 xland,slm(i,j)
2401  print *," xfpyfp,xfp2,yfp2:",xfpyfp,xfp2,yfp2
2402  print *," HX2,HY2,HXY:",hx2(i,j),hy2(i,j),hxy(i,j)
2403  ENDIF
2404 C
2405 C === make the principal axes, theta, and the degree of anisotropy,
2406 C === and sigma2, the slope parameter
2407 C
2408  hk(i,j) = 0.5 * ( hx2(i,j) + hy2(i,j) )
2409  hl(i,j) = 0.5 * ( hx2(i,j) - hy2(i,j) )
2410  hlprim(i,j) = sqrt(hl(i,j)*hl(i,j) + hxy(i,j)*hxy(i,j))
2411  IF( hl(i,j).NE. 0. .AND. slm(i,j) .NE. 0. ) THEN
2412 C
2413  theta(i,j) = 0.5 * atan2(hxy(i,j),hl(i,j)) * 180.0 / pi
2414 C === for testing print out in degrees
2415 C THETA(I,J) = 0.5 * ATAN2(HXY(I,J),HL(I,J))
2416  ENDIF
2417  sigma2(i,j) = ( hk(i,j) + hlprim(i,j) )
2418  if ( sigma2(i,j) .GE. 0. ) then
2419  sigma(i,j) = sqrt(sigma2(i,j) )
2420  if (sigma2(i,j) .ne. 0. .and.
2421  & hk(i,j) .GE. hlprim(i,j) )
2422  1 gamma(i,j) = sqrt( (hk(i,j) - hlprim(i,j)) / sigma2(i,j) )
2423  else
2424  sigma(i,j)=0.
2425  endif
2426  ENDIF
2427  if (debug) then
2428  print *," I,J,THETA,SIGMA,GAMMA,",i,j,theta(i,j),
2429  1 sigma(i,j),gamma(i,j)
2430  print *," HK,HL,HLPRIM:",hk(i,j),hl(i,j),hlprim(i,j)
2431  endif
2432  ENDDO
2433  ENDDO
2434  WRITE(6,*) "! MAKE Principal Coord DONE"
2435 C
2436  RETURN
2437  END
2438 
2459  SUBROUTINE makepc2(ZAVG,ZSLM,THETA,GAMMA,SIGMA,
2460  1 glat,im,jm,imn,jmn,lon_c,lat_c,slm)
2461 C
2462 C=== PC: principal coordinates of each Z avg orog box for L&M
2463 C
2464  implicit none
2465  real, parameter :: rearth=6.3712e+6
2466  real, parameter :: d2r = 3.14159265358979/180.
2467  integer :: im,jm,imn,jmn
2468  real :: glat(jmn),deltax(jmn)
2469  INTEGER zavg(imn,jmn),zslm(imn,jmn)
2470  real lon_c(im+1,jm+1), lat_c(im+1,jm+1)
2471  real, intent(in) :: slm(im,jm)
2472  real hl(im,jm),hk(im,jm)
2473  real hx2(im,jm),hy2(im,jm),hxy(im,jm),hlprim(im,jm)
2474  real theta(im,jm),gamma(im,jm),sigma2(im,jm),sigma(im,jm)
2475  real pi,certh,delxn,deltay,xnsum,xland
2476  real xfp,yfp,xfpyfp,xfp2,yfp2
2477  real hi0,hip1,hj0,hjp1,hijax,hi1j1
2478  real lono(4),lato(4),loni,lati
2479  integer i,j,i1,j1,i2,jst,jen,numx,i0,ip1,ijax
2480  integer ilist(imn)
2481  logical inside_a_polygon
2482  LOGICAL debug
2483 C=== DATA DEBUG/.TRUE./
2484  DATA debug/.false./
2485 C
2486  pi = 4.0 * atan(1.0)
2487  certh = pi * rearth
2488 C---- GLOBAL XLAT AND XLON ( DEGREE )
2489 C
2490  delxn = 360./imn ! MOUNTAIN DATA RESOLUTION
2491  deltay = certh / float(jmn)
2492  print *, 'MAKEPC2: DELTAY=',deltay
2493 C
2494  DO j=1,jmn
2495  glat(j) = -90. + (j-1) * delxn + delxn * 0.5
2496  deltax(j) = deltay * cos(glat(j)*d2r)
2497  ENDDO
2498 C
2499 C---- FIND THE AVERAGE OF THE MODES IN A GRID BOX
2500 C
2501 
2502 C... DERIVITIVE TENSOR OF HEIGHT
2503 C
2504 !$omp parallel do
2505 !$omp* private (j,i,xnsum,xland,xfp,yfp,xfpyfp,
2506 !$omp* xfp2,yfp2,lono,lato,jst,jen,ilist,numx,j1,i2,i1,
2507 !$omp* loni,lati,i0,ip1,hi0,hip1,hj0,hjp1,ijax,
2508 !$omp* hijax,hi1j1)
2509  jloop : DO j=1,jm
2510 ! print*, "J=", J
2511  iloop : DO i=1,im
2512  hx2(i,j) = 0.0
2513  hy2(i,j) = 0.0
2514  hxy(i,j) = 0.0
2515  xnsum = 0.0
2516  xland = 0.0
2517  xfp = 0.0
2518  yfp = 0.0
2519  xfpyfp = 0.0
2520  xfp2 = 0.0
2521  yfp2 = 0.0
2522  hl(i,j) = 0.0
2523  hk(i,j) = 0.0
2524  hlprim(i,j) = 0.0
2525  theta(i,j) = 0.0
2526  gamma(i,j) = 0.
2527  sigma2(i,j) = 0.
2528  sigma(i,j) = 0.
2529 
2530  lono(1) = lon_c(i,j)
2531  lono(2) = lon_c(i+1,j)
2532  lono(3) = lon_c(i+1,j+1)
2533  lono(4) = lon_c(i,j+1)
2534  lato(1) = lat_c(i,j)
2535  lato(2) = lat_c(i+1,j)
2536  lato(3) = lat_c(i+1,j+1)
2537  lato(4) = lat_c(i,j+1)
2538  call get_index(imn,jmn,4,lono,lato,delxn,jst,jen,ilist,numx)
2539 
2540  do j1 = jst, jen; do i2 = 1, numx
2541  i1 = ilist(i2)
2542  loni = i1*delxn
2543  lati = -90 + j1*delxn
2544  inside : if(inside_a_polygon(loni*d2r,lati*d2r,4,
2545  & lono*d2r,lato*d2r))then
2546 
2547 C=== set the rest of the indexs for ave: 2pt staggered derivitive
2548 C
2549  i0 = i1 - 1
2550  if (i1 - 1 .le. 0 ) i0 = i0 + imn
2551  if (i1 - 1 .gt. imn) i0 = i0 - imn
2552 C
2553  ip1 = i1 + 1
2554  if (i1 + 1 .le. 0 ) ip1 = ip1 + imn
2555  if (i1 + 1 .gt. imn) ip1 = ip1 - imn
2556 
2557  xland = xland + float(zslm(i1,j1))
2558  xnsum = xnsum + 1.
2559 C
2560  hi0 = float(zavg(i0,j1))
2561  hip1 = float(zavg(ip1,j1))
2562 C
2563  if(hi0 .lt. -990.) hi0 = 0.0
2564  if(hip1 .lt. -990.) hip1 = 0.0
2565 C........ xfp = xfp + 0.5 * ( hip1 - hi0 ) / DELTAX(J1)
2566  xfp = 0.5 * ( hip1 - hi0 ) / deltax(j1)
2567  xfp2 = xfp2 + 0.25 * ( ( hip1 - hi0 )/deltax(j1) )** 2
2568 C
2569 ! --- not at boundaries
2570 !RAB if ( J1 .ne. JST(1) .and. J1 .ne. JEN(JM) ) then
2571  if ( j1 .ne. 1 .and. j1 .ne. jmn ) then
2572  hj0 = float(zavg(i1,j1-1))
2573  hjp1 = float(zavg(i1,j1+1))
2574  if(hj0 .lt. -990.) hj0 = 0.0
2575  if(hjp1 .lt. -990.) hjp1 = 0.0
2576 C....... yfp = yfp + 0.5 * ( hjp1 - hj0 ) / DELTAY
2577  yfp = 0.5 * ( hjp1 - hj0 ) / deltay
2578  yfp2 = yfp2 + 0.25 * ( ( hjp1 - hj0 )/deltay )**2
2579 C
2580 C..............elseif ( J1 .eq. JST(J) .or. J1 .eq. JEN(JM) ) then
2581 C === the NH pole: NB J1 goes from High at NP to Low toward SP
2582 C
2583 !RAB elseif ( J1 .eq. JST(1) ) then
2584  elseif ( j1 .eq. 1 ) then
2585  ijax = i1 + imn/2
2586  if (ijax .le. 0 ) ijax = ijax + imn
2587  if (ijax .gt. imn) ijax = ijax - imn
2588 C..... at N pole we stay at the same latitude j1 but cross to opp side
2589  hijax = float(zavg(ijax,j1))
2590  hi1j1 = float(zavg(i1,j1))
2591  if(hijax .lt. -990.) hijax = 0.0
2592  if(hi1j1 .lt. -990.) hi1j1 = 0.0
2593 C....... yfp = yfp + 0.5 * ( ( 0.5 * ( hijax + hi1j1) ) - hi1j1 )/DELTAY
2594  yfp = 0.5 * ( ( 0.5 * ( hijax - hi1j1 ) ) )/deltay
2595  yfp2 = yfp2 + 0.25 * ( ( 0.5 * ( hijax - hi1j1) )
2596  1 / deltay )**2
2597 C
2598 C === the SH pole: NB J1 goes from High at NP to Low toward SP
2599 C
2600 !RAB elseif ( J1 .eq. JEN(JM) ) then
2601  elseif ( j1 .eq. jmn ) then
2602  ijax = i1 + imn/2
2603  if (ijax .le. 0 ) ijax = ijax + imn
2604  if (ijax .gt. imn) ijax = ijax - imn
2605  hijax = float(zavg(ijax,j1))
2606  hi1j1 = float(zavg(i1,j1))
2607  if(hijax .lt. -990.) hijax = 0.0
2608  if(hi1j1 .lt. -990.) hi1j1 = 0.0
2609  if ( i1 .lt. 5 )print *,' S.Pole i1,j1 :',i1,j1,
2610  & hijax,hi1j1
2611 C..... yfp = yfp + 0.5 * (0.5 * ( hijax - hi1j1) )/DELTAY
2612  yfp = 0.5 * (0.5 * ( hijax - hi1j1) )/deltay
2613  yfp2 = yfp2 + 0.25 * ( (0.5 * (hijax - hi1j1) )
2614  1 / deltay )**2
2615  endif
2616 C
2617 C === The above does an average across the pole for the bndry in j.
2618 C23456789012345678901234567890123456789012345678901234567890123456789012......
2619 C
2620  xfpyfp = xfpyfp + xfp * yfp
2621  ENDIF inside
2622 C
2623 C === average the HX2, HY2 and HXY
2624 C === This will be done over all land
2625 C
2626  ENDDO
2627  ENDDO
2628 C
2629 C === HTENSR
2630 C
2631  xnsum_gt_1 : IF(xnsum.GT.1.) THEN
2632  IF(slm(i,j).NE.0.) THEN
2633  IF (xland > 0) THEN
2634  hx2(i,j) = xfp2 / xland
2635  hy2(i,j) = yfp2 / xland
2636  hxy(i,j) = xfpyfp / xland
2637  ELSE
2638  hx2(i,j) = xfp2 / xnsum
2639  hy2(i,j) = yfp2 / xnsum
2640  hxy(i,j) = xfpyfp / xnsum
2641  ENDIF
2642  ENDIF
2643 C=== degub testing
2644  if (debug) then
2645  print *," I,J,i1,j1:", i,j,i1,j1,
2646  1 xland,slm(i,j)
2647  print *," xfpyfp,xfp2,yfp2:",xfpyfp,xfp2,yfp2
2648  print *," HX2,HY2,HXY:",hx2(i,j),hy2(i,j),hxy(i,j)
2649  ENDIF
2650 C
2651 C === make the principal axes, theta, and the degree of anisotropy,
2652 C === and sigma2, the slope parameter
2653 C
2654  hk(i,j) = 0.5 * ( hx2(i,j) + hy2(i,j) )
2655  hl(i,j) = 0.5 * ( hx2(i,j) - hy2(i,j) )
2656  hlprim(i,j) = sqrt(hl(i,j)*hl(i,j) + hxy(i,j)*hxy(i,j))
2657  IF( hl(i,j).NE. 0. .AND. slm(i,j) .NE. 0. ) THEN
2658 C
2659  theta(i,j) = 0.5 * atan2(hxy(i,j),hl(i,j)) / d2r
2660 C === for testing print out in degrees
2661 C THETA(I,J) = 0.5 * ATAN2(HXY(I,J),HL(I,J))
2662  ENDIF
2663  sigma2(i,j) = ( hk(i,j) + hlprim(i,j) )
2664  if ( sigma2(i,j) .GE. 0. ) then
2665  sigma(i,j) = sqrt(sigma2(i,j) )
2666  if (sigma2(i,j) .ne. 0. .and.
2667  & hk(i,j) .GE. hlprim(i,j) )
2668  1 gamma(i,j) = sqrt( (hk(i,j) - hlprim(i,j)) / sigma2(i,j) )
2669  else
2670  sigma(i,j)=0.
2671  endif
2672  ENDIF xnsum_gt_1
2673  if (debug) then
2674  print *," I,J,THETA,SIGMA,GAMMA,",i,j,theta(i,j),
2675  1 sigma(i,j),gamma(i,j)
2676  print *," HK,HL,HLPRIM:",hk(i,j),hl(i,j),hlprim(i,j)
2677  endif
2678  ENDDO iloop
2679  ENDDO jloop
2680 !$omp end parallel do
2681  WRITE(6,*) "! MAKE Principal Coord DONE"
2682 C
2683  RETURN
2684  END SUBROUTINE makepc2
2685 
2727  SUBROUTINE makeoa(ZAVG,VAR,GLAT,OA4,OL,IOA4,ELVMAX,
2728  1 oro,oro1,xnsum,xnsum1,xnsum2,xnsum3,xnsum4,
2729  2 ist,ien,jst,jen,im,jm,imn,jmn,xlat,numi)
2730  dimension glat(jmn),xlat(jm)
2731  INTEGER zavg(imn,jmn)
2732  dimension oro(im,jm),oro1(im,jm),elvmax(im,jm),zmax(im,jm)
2733  dimension oa4(im,jm,4),ioa4(im,jm,4)
2734  dimension ist(im,jm),ien(im,jm),jst(jm),jen(jm)
2735  dimension xnsum(im,jm),xnsum1(im,jm),xnsum2(im,jm)
2736  dimension xnsum3(im,jm),xnsum4(im,jm)
2737  dimension var(im,jm),ol(im,jm,4),numi(jm)
2738  LOGICAL flag
2739 C
2740 C---- GLOBAL XLAT AND XLON ( DEGREE )
2741 C
2742 ! --- IM1 = IM - 1 removed (not used in this sub)
2743  jm1 = jm - 1
2744  delxn = 360./imn ! MOUNTAIN DATA RESOLUTION
2745 C
2746  DO j=1,jmn
2747  glat(j) = -90. + (j-1) * delxn + delxn * 0.5
2748  ENDDO
2749  print *,' IM=',im,' JM=',jm,' IMN=',imn,' JMN=',jmn
2750 C
2751 C---- FIND THE AVERAGE OF THE MODES IN A GRID BOX
2752 C
2753  DO j=1,jm
2754  DO i=1,numi(j)
2755  delx = 360./numi(j) ! GAUSSIAN GRID RESOLUTION
2756  faclon = delx / delxn
2757 C --- minus sign here in IST and IEN as in MAKEMT!
2758  ist(i,j) = faclon * float(i-1) - faclon * 0.5
2759  ist(i,j) = ist(i,j) + 1
2760  ien(i,j) = faclon * float(i) - faclon * 0.5
2761 ! IST(I,j) = FACLON * FLOAT(I-1) + 1.0001
2762 ! IEN(I,j) = FACLON * FLOAT(I) + 0.0001
2763  IF (ist(i,j) .LE. 0) ist(i,j) = ist(i,j) + imn
2764  IF (ien(i,j) .LT. ist(i,j)) ien(i,j) = ien(i,j) + imn
2765 cx PRINT*, ' I j IST IEN ',I,j,IST(I,j),IEN(I,j)
2766  if ( i .lt. 3 .and. j .lt. 3 )
2767  1print*,' MAKEOA: I j IST IEN ',i,j,ist(i,j),ien(i,j)
2768  if ( i .lt. 3 .and. j .ge. jm-1 )
2769  1print*,' MAKEOA: I j IST IEN ',i,j,ist(i,j),ien(i,j)
2770  ENDDO
2771  ENDDO
2772  print *,'MAKEOA: DELXN,DELX,FACLON',delxn,delx,faclon
2773  print *, ' ***** ready to start JST JEN section '
2774  DO j=1,jm-1
2775  flag=.true.
2776  DO j1=1,jmn
2777 ! --- XXLAT added as in MAKEMT and in next line as well
2778  xxlat = (xlat(j)+xlat(j+1))/2.
2779  IF(flag.AND.glat(j1).GT.xxlat) THEN
2780  jst(j) = j1
2781 ! --- JEN(J+1) = J1 - 1
2782  flag = .false.
2783  if ( j .eq. 1 )
2784  1print*,' MAKEOA: XX j JST JEN ',j,jst(j),jen(j)
2785  ENDIF
2786  ENDDO
2787  if ( j .lt. 3 )
2788  1print*,' MAKEOA: j JST JEN ',j,jst(j),jen(j)
2789  if ( j .ge. jm-2 )
2790  1print*,' MAKEOA: j JST JEN ',j,jst(j),jen(j)
2791 C FLAG=.TRUE.
2792 C DO J1=JST(J),JMN
2793 C IF(FLAG.AND.GLAT(J1).GT.XLAT(J)) THEN
2794 C JEN(J) = J1 - 1
2795 C FLAG = .FALSE.
2796 C ENDIF
2797 C ENDDO
2798  ENDDO
2799  jst(jm) = max(jst(jm-1) - (jen(jm-1)-jst(jm-1)),1)
2800  jen(1) = min(jen(2) + (jen(2)-jst(2)),jmn)
2801  print *,' ***** JST(1) JEN(1) ',jst(1),jen(1)
2802  print *,' ***** JST(JM) JEN(JM) ',jst(jm),jen(jm)
2803 C
2804  DO j=1,jm
2805  DO i=1,numi(j)
2806  xnsum(i,j) = 0.0
2807  elvmax(i,j) = oro(i,j)
2808  zmax(i,j) = 0.0
2809  ENDDO
2810  ENDDO
2811 !
2812 ! --- # of peaks > ZAVG value and ZMAX(IM,JM) -- ORO is already avg.
2813 ! --- to JM or to JM1
2814  DO j=1,jm
2815  DO i=1,numi(j)
2816  DO ii1 = 1, ien(i,j) - ist(i,j) + 1
2817  i1 = ist(i,j) + ii1 - 1
2818 ! --- next line as in makemt (I1 not II1) (*j*) 20070701
2819  IF(i1.LE.0.) i1 = i1 + imn
2820  IF (i1 .GT. imn) i1 = i1 - imn
2821  DO j1=jst(j),jen(j)
2822  height = float(zavg(i1,j1))
2823  IF(height.LT.-990.) height = 0.0
2824  IF ( height .gt. oro(i,j) ) then
2825  if ( height .gt. zmax(i,j) )zmax(i,j) = height
2826  xnsum(i,j) = xnsum(i,j) + 1
2827  ENDIF
2828  ENDDO
2829  ENDDO
2830  if ( i .lt. 5 .and. j .ge. jm-5 ) then
2831  print *,' I,J,ORO(I,J),XNSUM(I,J),ZMAX(I,J):',
2832  1 i,j,oro(i,j),xnsum(i,j),zmax(i,j)
2833  endif
2834  ENDDO
2835  ENDDO
2836 !
2837 C.... make ELVMAX ORO from MAKEMT sub
2838 C
2839 ! --- this will make work1 array take on oro's values on return
2840  DO j=1,jm
2841  DO i=1,numi(j)
2842 
2843  oro1(i,j) = oro(i,j)
2844  elvmax(i,j) = zmax(i,j)
2845  ENDDO
2846  ENDDO
2847 C........
2848 C The MAX elev peak (no averaging)
2849 C........
2850 ! DO J=1,JM
2851 ! DO I=1,numi(j)
2852 ! DO II1 = 1, IEN(I,J) - IST(I,J) + 1
2853 ! I1 = IST(I,J) + II1 - 1
2854 ! IF(I1.LE.0.) I1 = I1 + IMN
2855 ! IF(I1.GT.IMN) I1 = I1 - IMN
2856 ! DO J1=JST(J),JEN(J)
2857 ! if ( ELVMAX(I,J) .lt. ZMAX(I1,J1))
2858 ! 1 ELVMAX(I,J) = ZMAX(I1,J1)
2859 ! ENDDO
2860 ! ENDDO
2861 ! ENDDO
2862 ! ENDDO
2863 C
2864 C---- COUNT NUMBER OF MODE. HIGHER THAN THE HC, CRITICAL HEIGHT
2865 C IN A GRID BOX
2866  DO j=1,jm
2867  DO i=1,numi(j)
2868  xnsum1(i,j) = 0.0
2869  xnsum2(i,j) = 0.0
2870  xnsum3(i,j) = 0.0
2871  xnsum4(i,j) = 0.0
2872  ENDDO
2873  ENDDO
2874 ! --- loop
2875  DO j=1,jm1
2876  DO i=1,numi(j)
2877  hc = 1116.2 - 0.878 * var(i,j)
2878 ! print *,' I,J,HC,VAR:',I,J,HC,VAR(I,J)
2879  DO ii1 = 1, ien(i,j) - ist(i,j) + 1
2880  i1 = ist(i,j) + ii1 - 1
2881 ! IF (I1.LE.0.) print *,' I1 less than 0',I1,II1,IST(I,J),IEN(I,J)
2882 ! if ( J .lt. 3 .or. J .gt. JM-2 ) then
2883 ! IF(I1 .GT. IMN)print *,' I1 > IMN',J,I1,II1,IMN,IST(I,J),IEN(I,J)
2884 ! endif
2885  IF(i1.GT.imn) i1 = i1 - imn
2886  DO j1=jst(j),jen(j)
2887  IF(float(zavg(i1,j1)) .GT. hc)
2888  1 xnsum1(i,j) = xnsum1(i,j) + 1
2889  xnsum2(i,j) = xnsum2(i,j) + 1
2890  ENDDO
2891  ENDDO
2892 C
2893  inci = nint((ien(i,j)-ist(i,j)) * 0.5)
2894  isttt = min(max(ist(i,j)-inci,1),imn)
2895  ieddd = min(max(ien(i,j)-inci,1),imn)
2896 C
2897  incj = nint((jen(j)-jst(j)) * 0.5)
2898  jsttt = min(max(jst(j)-incj,1),jmn)
2899  jeddd = min(max(jen(j)-incj,1),jmn)
2900 ! if ( J .lt. 3 .or. J .gt. JM-3 ) then
2901 ! if(I .lt. 3 .or. I .gt. IM-3) then
2902 ! print *,' INCI,ISTTT,IEDDD,INCJ,JSTTT,JEDDD:',
2903 ! 1 I,J,INCI,ISTTT,IEDDD,INCJ,JSTTT,JEDDD
2904 ! endif
2905 ! endif
2906 C
2907  DO i1=isttt,ieddd
2908  DO j1=jsttt,jeddd
2909  IF(float(zavg(i1,j1)) .GT. hc)
2910  1 xnsum3(i,j) = xnsum3(i,j) + 1
2911  xnsum4(i,j) = xnsum4(i,j) + 1
2912  ENDDO
2913  ENDDO
2914 cx print*,' i j hc var ',i,j,hc,var(i,j)
2915 cx print*,'xnsum12 ',xnsum1(i,j),xnsum2(i,j)
2916 cx print*,'xnsum34 ',xnsum3(i,j),xnsum4(i,j)
2917  ENDDO
2918  ENDDO
2919 C
2920 C---- CALCULATE THE 3D OROGRAPHIC ASYMMETRY FOR 4 WIND DIRECTIONS
2921 C---- AND THE 3D OROGRAPHIC SUBGRID OROGRAPHY FRACTION
2922 C (KWD = 1 2 3 4)
2923 C ( WD = W S SW NW)
2924 C
2925 C
2926  DO kwd = 1, 4
2927  DO j=1,jm
2928  DO i=1,numi(j)
2929  oa4(i,j,kwd) = 0.0
2930  ENDDO
2931  ENDDO
2932  ENDDO
2933 C
2934  DO j=1,jm-2
2935  DO i=1,numi(j)
2936  ii = i + 1
2937  IF (ii .GT. numi(j)) ii = ii - numi(j)
2938  xnpu = xnsum(i,j) + xnsum(i,j+1)
2939  xnpd = xnsum(ii,j) + xnsum(ii,j+1)
2940  IF (xnpd .NE. xnpu) oa4(ii,j+1,1) = 1. - xnpd / max(xnpu , 1.)
2941  ol(ii,j+1,1) = (xnsum3(i,j+1)+xnsum3(ii,j+1))/
2942  1 (xnsum4(i,j+1)+xnsum4(ii,j+1))
2943 ! if ( I .lt. 20 .and. J .ge. JM-19 ) then
2944 ! PRINT*,' MAKEOA: I J IST IEN ',I,j,IST(I,J),IEN(I,J)
2945 ! PRINT*,' HC VAR ',HC,VAR(i,j)
2946 ! PRINT*,' MAKEOA: XNSUM(I,J)=',XNSUM(I,J),XNPU, XNPD
2947 ! PRINT*,' MAKEOA: XNSUM3(I,J+1),XNSUM3(II,J+1)',
2948 ! 1 XNSUM3(I,J+1),XNSUM3(II,J+1)
2949 ! PRINT*,' MAKEOA: II, OA4(II,J+1,1), OL(II,J+1,1):',
2950 ! 1 II, OA4(II,J+1,1), OL(II,J+1,1)
2951 ! endif
2952  ENDDO
2953  ENDDO
2954  DO j=1,jm-2
2955  DO i=1,numi(j)
2956  ii = i + 1
2957  IF (ii .GT. numi(j)) ii = ii - numi(j)
2958  xnpu = xnsum(i,j+1) + xnsum(ii,j+1)
2959  xnpd = xnsum(i,j) + xnsum(ii,j)
2960  IF (xnpd .NE. xnpu) oa4(ii,j+1,2) = 1. - xnpd / max(xnpu , 1.)
2961  ol(ii,j+1,2) = (xnsum3(ii,j)+xnsum3(ii,j+1))/
2962  1 (xnsum4(ii,j)+xnsum4(ii,j+1))
2963  ENDDO
2964  ENDDO
2965  DO j=1,jm-2
2966  DO i=1,numi(j)
2967  ii = i + 1
2968  IF (ii .GT. numi(j)) ii = ii - numi(j)
2969  xnpu = xnsum(i,j+1) + ( xnsum(i,j) + xnsum(ii,j+1) )*0.5
2970  xnpd = xnsum(ii,j) + ( xnsum(i,j) + xnsum(ii,j+1) )*0.5
2971  IF (xnpd .NE. xnpu) oa4(ii,j+1,3) = 1. - xnpd / max(xnpu , 1.)
2972  ol(ii,j+1,3) = (xnsum1(ii,j)+xnsum1(i,j+1))/
2973  1 (xnsum2(ii,j)+xnsum2(i,j+1))
2974  ENDDO
2975  ENDDO
2976  DO j=1,jm-2
2977  DO i=1,numi(j)
2978  ii = i + 1
2979  IF (ii .GT. numi(j)) ii = ii - numi(j)
2980  xnpu = xnsum(i,j) + ( xnsum(ii,j) + xnsum(i,j+1) )*0.5
2981  xnpd = xnsum(ii,j+1) + ( xnsum(ii,j) + xnsum(i,j+1) )*0.5
2982  IF (xnpd .NE. xnpu) oa4(ii,j+1,4) = 1. - xnpd / max(xnpu , 1.)
2983  ol(ii,j+1,4) = (xnsum1(i,j)+xnsum1(ii,j+1))/
2984  1 (xnsum2(i,j)+xnsum2(ii,j+1))
2985  ENDDO
2986  ENDDO
2987 C
2988  DO kwd = 1, 4
2989  DO i=1,numi(j)
2990  ol(i,1,kwd) = ol(i,2,kwd)
2991  ol(i,jm,kwd) = ol(i,jm-1,kwd)
2992  ENDDO
2993  ENDDO
2994 C
2995  DO kwd=1,4
2996  DO j=1,jm
2997  DO i=1,numi(j)
2998  t = oa4(i,j,kwd)
2999  oa4(i,j,kwd) = sign( min( abs(t), 1. ), t )
3000  ENDDO
3001  ENDDO
3002  ENDDO
3003 C
3004  ns0 = 0
3005  ns1 = 0
3006  ns2 = 0
3007  ns3 = 0
3008  ns4 = 0
3009  ns5 = 0
3010  ns6 = 0
3011  DO kwd=1,4
3012  DO j=1,jm
3013  DO i=1,numi(j)
3014  t = abs( oa4(i,j,kwd) )
3015  IF(t .EQ. 0.) THEN
3016  ioa4(i,j,kwd) = 0
3017  ns0 = ns0 + 1
3018  ELSE IF(t .GT. 0. .AND. t .LE. 1.) THEN
3019  ioa4(i,j,kwd) = 1
3020  ns1 = ns1 + 1
3021  ELSE IF(t .GT. 1. .AND. t .LE. 10.) THEN
3022  ioa4(i,j,kwd) = 2
3023  ns2 = ns2 + 1
3024  ELSE IF(t .GT. 10. .AND. t .LE. 100.) THEN
3025  ioa4(i,j,kwd) = 3
3026  ns3 = ns3 + 1
3027  ELSE IF(t .GT. 100. .AND. t .LE. 1000.) THEN
3028  ioa4(i,j,kwd) = 4
3029  ns4 = ns4 + 1
3030  ELSE IF(t .GT. 1000. .AND. t .LE. 10000.) THEN
3031  ioa4(i,j,kwd) = 5
3032  ns5 = ns5 + 1
3033  ELSE IF(t .GT. 10000.) THEN
3034  ioa4(i,j,kwd) = 6
3035  ns6 = ns6 + 1
3036  ENDIF
3037  ENDDO
3038  ENDDO
3039  ENDDO
3040 C
3041  WRITE(6,*) "! MAKEOA EXIT"
3042 C
3043  RETURN
3044  END SUBROUTINE makeoa
3045 
3055  function get_lon_angle(dx,lat, DEGRAD)
3056  implicit none
3057  real dx, lat, degrad
3058 
3059  real get_lon_angle
3060  real, parameter :: radius = 6371200
3061 
3062  get_lon_angle = 2*asin( sin(dx/radius*0.5)/cos(lat) )*degrad
3063 
3064  end function get_lon_angle
3065 
3074  function get_lat_angle(dy, DEGRAD)
3075  implicit none
3076  real dy, degrad
3077 
3078  real get_lat_angle
3079  real, parameter :: radius = 6371200
3080 
3081  get_lat_angle = dy/radius*degrad
3082 
3083  end function get_lat_angle
3084 
3121  SUBROUTINE makeoa2(ZAVG,zslm,VAR,GLAT,OA4,OL,IOA4,ELVMAX,
3122  1 oro,oro1,xnsum,xnsum1,xnsum2,xnsum3,xnsum4,
3123  2 im,jm,imn,jmn,lon_c,lat_c,lon_t,lat_t,dx,dy,
3124  3 is_south_pole,is_north_pole )
3125  implicit none
3126  real, parameter :: missing_value = -9999.
3127  real, parameter :: d2r = 3.14159265358979/180.
3128  real, PARAMETER :: r2d=180./3.14159265358979
3129  integer im,jm,imn,jmn
3130  real glat(jmn)
3131  INTEGER zavg(imn,jmn),zslm(imn,jmn)
3132  real oro(im,jm),oro1(im,jm),elvmax(im,jm),zmax(im,jm)
3133  real oa4(im,jm,4)
3134  integer ioa4(im,jm,4)
3135  real lon_c(im+1,jm+1), lat_c(im+1,jm+1)
3136  real lon_t(im,jm), lat_t(im,jm)
3137  real dx(im,jm), dy(im,jm)
3138  logical is_south_pole(im,jm), is_north_pole(im,jm)
3139  real xnsum(im,jm),xnsum1(im,jm),xnsum2(im,jm)
3140  real xnsum3(im,jm),xnsum4(im,jm)
3141  real var(im,jm),ol(im,jm,4)
3142  integer i,j,ilist(imn),numx,i1,j1,ii1
3143  integer kwd
3144  real lono(4),lato(4),loni,lati
3145  real delxn,hc,height,xnpu,xnpd,t
3146  integer ns0,ns1,ns2,ns3,ns4,ns5,ns6
3147  logical inside_a_polygon
3148  real lon,lat,dlon,dlat,dlat_old
3149  real lon1,lat1,lon2,lat2
3150  real xnsum11,xnsum12,xnsum21,xnsum22
3151  real hc_11, hc_12, hc_21, hc_22
3152  real xnsum1_11,xnsum1_12,xnsum1_21,xnsum1_22
3153  real xnsum2_11,xnsum2_12,xnsum2_21,xnsum2_22
3155  integer jst, jen
3156 C
3157 C---- GLOBAL XLAT AND XLON ( DEGREE )
3158 C
3159  delxn = 360./imn ! MOUNTAIN DATA RESOLUTION
3160 C
3161  DO j=1,jmn
3162  glat(j) = -90. + (j-1) * delxn + delxn * 0.5
3163  ENDDO
3164  print *,' IM=',im,' JM=',jm,' IMN=',imn,' JMN=',jmn
3165 C
3166 C---- FIND THE AVERAGE OF THE MODES IN A GRID BOX
3167 C
3168 C
3169  DO j=1,jm
3170  DO i=1,im
3171  xnsum(i,j) = 0.0
3172  elvmax(i,j) = oro(i,j)
3173  zmax(i,j) = 0.0
3174 C---- COUNT NUMBER OF MODE. HIGHER THAN THE HC, CRITICAL HEIGHT
3175 C IN A GRID BOX
3176  xnsum1(i,j) = 0.0
3177  xnsum2(i,j) = 0.0
3178  xnsum3(i,j) = 0.0
3179  xnsum4(i,j) = 0.0
3180  oro1(i,j) = oro(i,j)
3181  elvmax(i,j) = zmax(i,j)
3182  ENDDO
3183  ENDDO
3184 
3185 ! --- # of peaks > ZAVG value and ZMAX(IM,JM) -- ORO is already avg.
3186 ! --- to JM or to JM1
3187 !$omp parallel do
3188 !$omp* private (j,i,hc,lono,lato,jst,jen,ilist,numx,j1,ii1,i1,loni,
3189 !$omp* lati,height)
3190  DO j=1,jm
3191 ! print*, "J=", J
3192  DO i=1,im
3193  hc = 1116.2 - 0.878 * var(i,j)
3194  lono(1) = lon_c(i,j)
3195  lono(2) = lon_c(i+1,j)
3196  lono(3) = lon_c(i+1,j+1)
3197  lono(4) = lon_c(i,j+1)
3198  lato(1) = lat_c(i,j)
3199  lato(2) = lat_c(i+1,j)
3200  lato(3) = lat_c(i+1,j+1)
3201  lato(4) = lat_c(i,j+1)
3202  call get_index(imn,jmn,4,lono,lato,delxn,jst,jen,ilist,numx)
3203  do j1 = jst, jen; do ii1 = 1, numx
3204  i1 = ilist(ii1)
3205  loni = i1*delxn
3206  lati = -90 + j1*delxn
3207  if(inside_a_polygon(loni*d2r,lati*d2r,4,
3208  & lono*d2r,lato*d2r))then
3209 
3210  height = float(zavg(i1,j1))
3211  IF(height.LT.-990.) height = 0.0
3212  IF ( height .gt. oro(i,j) ) then
3213  if ( height .gt. zmax(i,j) )zmax(i,j) = height
3214  ENDIF
3215  endif
3216  ENDDO ; ENDDO
3217  ENDDO
3218  ENDDO
3219 !$omp end parallel do
3220 C
3221 ! --- this will make work1 array take on oro's values on return
3222 ! --- this will make work1 array take on oro's values on return
3223  DO j=1,jm
3224  DO i=1,im
3225 
3226  oro1(i,j) = oro(i,j)
3227  elvmax(i,j) = zmax(i,j)
3228  ENDDO
3229  ENDDO
3230 
3231  DO kwd = 1, 4
3232  DO j=1,jm
3233  DO i=1,im
3234  oa4(i,j,kwd) = 0.0
3235  ol(i,j,kwd) = 0.0
3236  ENDDO
3237  ENDDO
3238  ENDDO
3239  !
3240 ! --- # of peaks > ZAVG value and ZMAX(IM,JM) -- ORO is already avg.
3241 C
3242 C---- CALCULATE THE 3D OROGRAPHIC ASYMMETRY FOR 4 WIND DIRECTIONS
3243 C---- AND THE 3D OROGRAPHIC SUBGRID OROGRAPHY FRACTION
3244 C (KWD = 1 2 3 4)
3245 C ( WD = W S SW NW)
3246 C
3247 C
3248 !$omp parallel do
3249 !$omp* private (j,i,lon,lat,kwd,dlon,dlat,lon1,lon2,lat1,lat2,
3250 !$omp* xnsum11,xnsum12,xnsum21,xnsum22,xnpu,xnpd,
3251 !$omp* xnsum1_11,xnsum2_11,hc_11, xnsum1_12,xnsum2_12,
3252 !$omp* hc_12,xnsum1_21,xnsum2_21,hc_21, xnsum1_22,
3253 !$omp* xnsum2_22,hc_22)
3254  DO j=1,jm
3255 ! print*, "j = ", j
3256  DO i=1,im
3257  lon = lon_t(i,j)
3258  lat = lat_t(i,j)
3259  !--- for around north pole, oa and ol are all 0
3260 
3261  if(is_north_pole(i,j)) then
3262  print*, "set oa1 = 0 and ol=0 at i,j=", i,j
3263  do kwd = 1, 4
3264  oa4(i,j,kwd) = 0.
3265  ol(i,j,kwd) = 0.
3266  enddo
3267  else if(is_south_pole(i,j)) then
3268  print*, "set oa1 = 0 and ol=1 at i,j=", i,j
3269  do kwd = 1, 4
3270  oa4(i,j,kwd) = 0.
3271  ol(i,j,kwd) = 1.
3272  enddo
3273  else
3274 
3275  !--- for each point, find a lat-lon grid box with same dx and dy as the cubic grid box
3276  dlon = get_lon_angle(dx(i,j), lat*d2r, r2d )
3277  dlat = get_lat_angle(dy(i,j), r2d)
3278  !--- adjust dlat if the points are close to pole.
3279  if( lat-dlat*0.5<-90.) then
3280  print*, "at i,j =", i,j, lat, dlat, lat-dlat*0.5
3281  print*, "ERROR: lat-dlat*0.5<-90."
3282  call errexit(4)
3283  endif
3284  if( lat+dlat*2 > 90.) then
3285  dlat_old = dlat
3286  dlat = (90-lat)*0.5
3287  print*, "at i,j=",i,j," adjust dlat from ",
3288  & dlat_old, " to ", dlat
3289  endif
3290  !--- lower left
3291  lon1 = lon-dlon*1.5
3292  lon2 = lon-dlon*0.5
3293  lat1 = lat-dlat*0.5
3294  lat2 = lat+dlat*0.5
3295 
3296  if(lat1<-90 .or. lat2>90) then
3297  print*, "at upper left i=,j=", i, j, lat, dlat,lat1,lat2
3298  endif
3299  xnsum11 = get_xnsum(lon1,lat1,lon2,lat2,imn,jmn,glat,
3300  & zavg,zslm,delxn)
3301 
3302  !--- upper left
3303  lon1 = lon-dlon*1.5
3304  lon2 = lon-dlon*0.5
3305  lat1 = lat+dlat*0.5
3306  lat2 = lat+dlat*1.5
3307  if(lat1<-90 .or. lat2>90) then
3308  print*, "at lower left i=,j=", i, j, lat, dlat,lat1,lat2
3309  endif
3310  xnsum12 = get_xnsum(lon1,lat1,lon2,lat2,imn,jmn,glat,
3311  & zavg,zslm,delxn)
3312 
3313  !--- lower right
3314  lon1 = lon-dlon*0.5
3315  lon2 = lon+dlon*0.5
3316  lat1 = lat-dlat*0.5
3317  lat2 = lat+dlat*0.5
3318  if(lat1<-90 .or. lat2>90) then
3319  print*, "at upper right i=,j=", i, j, lat, dlat,lat1,lat2
3320  endif
3321  xnsum21 = get_xnsum(lon1,lat1,lon2,lat2,imn,jmn,glat,
3322  & zavg,zslm,delxn)
3323 
3324  !--- upper right
3325  lon1 = lon-dlon*0.5
3326  lon2 = lon+dlon*0.5
3327  lat1 = lat+dlat*0.5
3328  lat2 = lat+dlat*1.5
3329  if(lat1<-90 .or. lat2>90) then
3330  print*, "at lower right i=,j=", i, j, lat, dlat,lat1,lat2
3331  endif
3332 
3333  xnsum22 = get_xnsum(lon1,lat1,lon2,lat2,imn,jmn,glat,
3334  & zavg,zslm,delxn)
3335 
3336  xnpu = xnsum11 + xnsum12
3337  xnpd = xnsum21 + xnsum22
3338  IF (xnpd .NE. xnpu) oa4(i,j,1) = 1. - xnpd / max(xnpu , 1.)
3339 
3340  xnpu = xnsum11 + xnsum21
3341  xnpd = xnsum12 + xnsum22
3342  IF (xnpd .NE. xnpu) oa4(i,j,2) = 1. - xnpd / max(xnpu , 1.)
3343 
3344  xnpu = xnsum11 + (xnsum12+xnsum21)*0.5
3345  xnpd = xnsum22 + (xnsum12+xnsum21)*0.5
3346  IF (xnpd .NE. xnpu) oa4(i,j,3) = 1. - xnpd / max(xnpu , 1.)
3347 
3348  xnpu = xnsum12 + (xnsum11+xnsum22)*0.5
3349  xnpd = xnsum21 + (xnsum11+xnsum22)*0.5
3350  IF (xnpd .NE. xnpu) oa4(i,j,4) = 1. - xnpd / max(xnpu , 1.)
3351 
3352 
3353  !--- calculate OL3 and OL4
3354  !--- lower left
3355  lon1 = lon-dlon*1.5
3356  lon2 = lon-dlon*0.5
3357  lat1 = lat-dlat*0.5
3358  lat2 = lat+dlat*0.5
3359  if(lat1<-90 .or. lat2>90) then
3360  print*, "at upper left i=,j=", i, j, lat, dlat,lat1,lat2
3361  endif
3362  call get_xnsum2(lon1,lat1,lon2,lat2,imn,jmn,glat,
3363  & zavg,delxn, xnsum1_11, xnsum2_11, hc_11)
3364 
3365  !--- upper left
3366  lon1 = lon-dlon*1.5
3367  lon2 = lon-dlon*0.5
3368  lat1 = lat+dlat*0.5
3369  lat2 = lat+dlat*1.5
3370  if(lat1<-90 .or. lat2>90) then
3371  print*, "at lower left i=,j=", i, j, lat, dlat,lat1,lat2
3372  endif
3373  call get_xnsum2(lon1,lat1,lon2,lat2,imn,jmn,glat,
3374  & zavg,delxn, xnsum1_12, xnsum2_12, hc_12)
3375 
3376  !--- lower right
3377  lon1 = lon-dlon*0.5
3378  lon2 = lon+dlon*0.5
3379  lat1 = lat-dlat*0.5
3380  lat2 = lat+dlat*0.5
3381  if(lat1<-90 .or. lat2>90) then
3382  print*, "at upper right i=,j=", i, j, lat, dlat,lat1,lat2
3383  endif
3384  call get_xnsum2(lon1,lat1,lon2,lat2,imn,jmn,glat,
3385  & zavg,delxn, xnsum1_21, xnsum2_21, hc_21)
3386 
3387  !--- upper right
3388  lon1 = lon-dlon*0.5
3389  lon2 = lon+dlon*0.5
3390  lat1 = lat+dlat*0.5
3391  lat2 = lat+dlat*1.5
3392  if(lat1<-90 .or. lat2>90) then
3393  print*, "at lower right i=,j=", i, j, lat, dlat,lat1,lat2
3394  endif
3395  call get_xnsum2(lon1,lat1,lon2,lat2,imn,jmn,glat,
3396  & zavg,delxn, xnsum1_22, xnsum2_22, hc_22)
3397 
3398  ol(i,j,3) = (xnsum1_22+xnsum1_11)/(xnsum2_22+xnsum2_11)
3399  ol(i,j,4) = (xnsum1_12+xnsum1_21)/(xnsum2_12+xnsum2_21)
3400 
3401  !--- calculate OL1 and OL2
3402  !--- lower left
3403  lon1 = lon-dlon*2.0
3404  lon2 = lon-dlon
3405  lat1 = lat
3406  lat2 = lat+dlat
3407  if(lat1<-90 .or. lat2>90) then
3408  print*, "at upper left i=,j=", i, j, lat, dlat,lat1,lat2
3409  endif
3410  call get_xnsum3(lon1,lat1,lon2,lat2,imn,jmn,glat,
3411  & zavg,delxn, xnsum1_11, xnsum2_11, hc_11)
3412 
3413  !--- upper left
3414  lon1 = lon-dlon*2.0
3415  lon2 = lon-dlon
3416  lat1 = lat+dlat
3417  lat2 = lat+dlat*2.0
3418  if(lat1<-90 .or. lat2>90) then
3419  print*, "at lower left i=,j=", i, j, lat, dlat,lat1,lat2
3420  endif
3421 
3422  call get_xnsum3(lon1,lat1,lon2,lat2,imn,jmn,glat,
3423  & zavg,delxn, xnsum1_12, xnsum2_12, hc_12)
3424 
3425  !--- lower right
3426  lon1 = lon-dlon
3427  lon2 = lon
3428  lat1 = lat
3429  lat2 = lat+dlat
3430  if(lat1<-90 .or. lat2>90) then
3431  print*, "at upper right i=,j=", i, j, lat, dlat,lat1,lat2
3432  endif
3433  call get_xnsum3(lon1,lat1,lon2,lat2,imn,jmn,glat,
3434  & zavg,delxn, xnsum1_21, xnsum2_21, hc_21)
3435 
3436  !--- upper right
3437  lon1 = lon-dlon
3438  lon2 = lon
3439  lat1 = lat+dlat
3440  lat2 = lat+dlat*2.0
3441  if(lat1<-90 .or. lat2>90) then
3442  print*, "at lower right i=,j=", i, j, lat, dlat,lat1,lat2
3443  endif
3444 
3445  call get_xnsum3(lon1,lat1,lon2,lat2,imn,jmn,glat,
3446  & zavg,delxn, xnsum1_22, xnsum2_22, hc_22)
3447 
3448  ol(i,j,1) = (xnsum1_11+xnsum1_21)/(xnsum2_11+xnsum2_21)
3449  ol(i,j,2) = (xnsum1_21+xnsum1_22)/(xnsum2_21+xnsum2_22)
3450  ENDIF
3451  ENDDO
3452  ENDDO
3453 !$omp end parallel do
3454  DO kwd=1,4
3455  DO j=1,jm
3456  DO i=1,im
3457  t = oa4(i,j,kwd)
3458  oa4(i,j,kwd) = sign( min( abs(t), 1. ), t )
3459  ENDDO
3460  ENDDO
3461  ENDDO
3462 C
3463  ns0 = 0
3464  ns1 = 0
3465  ns2 = 0
3466  ns3 = 0
3467  ns4 = 0
3468  ns5 = 0
3469  ns6 = 0
3470  DO kwd=1,4
3471  DO j=1,jm
3472  DO i=1,im
3473  t = abs( oa4(i,j,kwd) )
3474  IF(t .EQ. 0.) THEN
3475  ioa4(i,j,kwd) = 0
3476  ns0 = ns0 + 1
3477  ELSE IF(t .GT. 0. .AND. t .LE. 1.) THEN
3478  ioa4(i,j,kwd) = 1
3479  ns1 = ns1 + 1
3480  ELSE IF(t .GT. 1. .AND. t .LE. 10.) THEN
3481  ioa4(i,j,kwd) = 2
3482  ns2 = ns2 + 1
3483  ELSE IF(t .GT. 10. .AND. t .LE. 100.) THEN
3484  ioa4(i,j,kwd) = 3
3485  ns3 = ns3 + 1
3486  ELSE IF(t .GT. 100. .AND. t .LE. 1000.) THEN
3487  ioa4(i,j,kwd) = 4
3488  ns4 = ns4 + 1
3489  ELSE IF(t .GT. 1000. .AND. t .LE. 10000.) THEN
3490  ioa4(i,j,kwd) = 5
3491  ns5 = ns5 + 1
3492  ELSE IF(t .GT. 10000.) THEN
3493  ioa4(i,j,kwd) = 6
3494  ns6 = ns6 + 1
3495  ENDIF
3496  ENDDO
3497  ENDDO
3498  ENDDO
3499 C
3500  WRITE(6,*) "! MAKEOA2 EXIT"
3501 C
3502  RETURN
3503 
3504  END SUBROUTINE makeoa2
3505 
3514  function spherical_distance(theta1,phi1,theta2,phi2)
3515 
3516  real, intent(in) :: theta1, phi1, theta2, phi2
3517  real :: spherical_distance, dot
3518 
3519  if(theta1 == theta2 .and. phi1 == phi2) then
3520  spherical_distance = 0.0
3521  return
3522  endif
3523 
3524  dot = cos(phi1)*cos(phi2)*cos(theta1-theta2) + sin(phi1)*sin(phi2)
3525  if(dot > 1. ) dot = 1.
3526  if(dot < -1.) dot = -1.
3527  spherical_distance = acos(dot)
3528 
3529  return
3530 
3531  end function spherical_distance
3532 
3549  subroutine get_mismatch_index(im_in, jm_in, geolon_in,geolat_in,
3550  & bitmap_in,num_out, lon_out,lat_out, iindx, jindx )
3551  integer, intent(in) :: im_in, jm_in, num_out
3552  real, intent(in) :: geolon_in(im_in,jm_in)
3553  real, intent(in) :: geolat_in(im_in,jm_in)
3554  logical*1, intent(in) :: bitmap_in(im_in,jm_in)
3555  real, intent(in) :: lon_out(num_out), lat_out(num_out)
3556  integer, intent(out):: iindx(num_out), jindx(num_out)
3557  real, parameter :: max_dist = 1.e+20
3558  integer, parameter :: numnbr = 20
3559  integer :: i_c,j_c,jstart,jend
3560  real :: lon,lat
3561 
3562  print*, "im_in,jm_in = ", im_in, jm_in
3563  print*, "num_out = ", num_out
3564  print*, "max and min of lon_in is", minval(geolon_in),
3565  & maxval(geolon_in)
3566  print*, "max and min of lat_in is", minval(geolat_in),
3567  & maxval(geolat_in)
3568  print*, "max and min of lon_out is", minval(lon_out),
3569  & maxval(lon_out)
3570  print*, "max and min of lat_out is", minval(lat_out),
3571  & maxval(lat_out)
3572  print*, "count(bitmap_in)= ", count(bitmap_in), max_dist
3573 
3574  do n = 1, num_out
3575  ! print*, "n = ", n
3576  lon = lon_out(n)
3577  lat = lat_out(n)
3578  !--- find the j-index for the nearest point
3579  i_c = 0; j_c = 0
3580  do j = 1, jm_in-1
3581  if(lat .LE. geolat_in(1,j) .and.
3582  & lat .GE. geolat_in(1,j+1)) then
3583  j_c = j
3584  endif
3585  enddo
3586  if(lat > geolat_in(1,1)) j_c = 1
3587  if(lat < geolat_in(1,jm_in)) j_c = jm_in
3588  ! print*, "lat =", lat, geolat_in(1,jm_in), geolat_in(1,jm_in-1)
3589  ! The input is Gaussian grid.
3590  jstart = max(j_c-numnbr,1)
3591  jend = min(j_c+numnbr,jm_in)
3592  dist = max_dist
3593  iindx(n) = 0
3594  jindx(n) = 0
3595  ! print*, "jstart, jend =", jstart, jend
3596  do j = jstart, jend; do i = 1,im_in
3597  if(bitmap_in(i,j) ) then
3598  ! print*, "bitmap_in is true"
3599  d = spherical_distance(lon_out(n),lat_out(n),
3600  & geolon_in(i,j), geolat_in(i,j))
3601  if( dist > d ) then
3602  iindx(n) = i; jindx(n) = j
3603  dist = d
3604  endif
3605  endif
3606  enddo; enddo
3607  if(iindx(n) ==0) then
3608  print*, "lon,lat=", lon,lat
3609  print*, "jstart, jend=", jstart, jend, dist
3610  print*, "ERROR in get mismatch_index: not find nearest points"
3611  call errexit(4)
3612  endif
3613  enddo
3614 
3615  end subroutine get_mismatch_index
3616 
3630  subroutine interpolate_mismatch(im_in, jm_in, data_in,
3631  & num_out, data_out, iindx, jindx)
3632  integer, intent(in) :: im_in, jm_in, num_out
3633  real, intent(in) :: data_in(im_in,jm_in)
3634  real, intent(out):: data_out(num_out)
3635  integer, intent(in) :: iindx(num_out), jindx(num_out)
3636 
3637  do n = 1, num_out
3638  data_out(n) = data_in(iindx(n),jindx(n))
3639  enddo
3640 
3641  end subroutine interpolate_mismatch
3642 
3687  SUBROUTINE makeoa3(ZAVG,zslm,VAR,GLAT,OA4,OL,IOA4,ELVMAX,
3688  1 oro,slm,oro1,xnsum,xnsum1,xnsum2,xnsum3,xnsum4,
3689  2 im,jm,imn,jmn,lon_c,lat_c,lon_t,lat_t,
3690  3 is_south_pole,is_north_pole,imi,jmi,oa_in,ol_in,
3691  4 slm_in,lon_in,lat_in)
3692 
3693 ! Required when using iplib v4.0 or higher.
3694 #ifdef IP_V4
3695  use ipolates_mod
3696 #endif
3697 
3698  implicit none
3699  real, parameter :: missing_value = -9999.
3700  real, parameter :: d2r = 3.14159265358979/180.
3701  real, PARAMETER :: r2d=180./3.14159265358979
3702  integer im,jm,imn,jmn,imi,jmi
3703  real glat(jmn)
3704  INTEGER zavg(imn,jmn),zslm(imn,jmn)
3705  real slm(im,jm)
3706  real oro(im,jm),oro1(im,jm),elvmax(im,jm),zmax(im,jm)
3707  real oa4(im,jm,4)
3708  integer ioa4(im,jm,4)
3709  real oa_in(imi,jmi,4), ol_in(imi,jmi,4)
3710  real slm_in(imi,jmi)
3711  real lon_in(imi,jmi), lat_in(imi,jmi)
3712  real lon_c(im+1,jm+1), lat_c(im+1,jm+1)
3713  real lon_t(im,jm), lat_t(im,jm)
3714  logical is_south_pole(im,jm), is_north_pole(im,jm)
3715  real xnsum(im,jm),xnsum1(im,jm),xnsum2(im,jm)
3716  real xnsum3(im,jm),xnsum4(im,jm)
3717  real var(im,jm),ol(im,jm,4)
3718  LOGICAL flag
3719  integer i,j,ilist(imn),numx,i1,j1,ii1
3720  integer kwd,ii,npts
3721  real lono(4),lato(4),loni,lati
3722  real delxn,hc,height,xnpu,xnpd,t
3723  integer ns0,ns1,ns2,ns3,ns4,ns5,ns6
3724  logical inside_a_polygon
3725  real lon,lat,dlon,dlat,dlat_old
3726  real lon1,lat1,lon2,lat2
3727  real xnsum11,xnsum12,xnsum21,xnsum22,xnsumx
3728  real hc_11, hc_12, hc_21, hc_22
3729  real xnsum1_11,xnsum1_12,xnsum1_21,xnsum1_22
3730  real xnsum2_11,xnsum2_12,xnsum2_21,xnsum2_22
3732  integer ist, ien, jst, jen
3733  real xland,xwatr,xl1,xs1,oroavg
3734  integer int_opt, ipopt(20), kgds_input(200), kgds_output(200)
3735  integer count_land_output
3736  integer ij, ijmdl_output, iret, num_mismatch_land, num
3737  integer ibo(1), ibi(1)
3738  logical*1, allocatable :: bitmap_input(:,:)
3739  logical*1, allocatable :: bitmap_output(:,:)
3740  integer, allocatable :: ijsav_land_output(:)
3741  real, allocatable :: lats_land_output(:)
3742  real, allocatable :: lons_land_output(:)
3743  real, allocatable :: output_data_land(:,:)
3744  real, allocatable :: lons_mismatch_output(:)
3745  real, allocatable :: lats_mismatch_output(:)
3746  real, allocatable :: data_mismatch_output(:)
3747  integer, allocatable :: iindx(:), jindx(:)
3748 C
3749 C---- GLOBAL XLAT AND XLON ( DEGREE )
3750 C
3751  delxn = 360./imn ! MOUNTAIN DATA RESOLUTION
3752 C
3753  ijmdl_output = im*jm
3754 
3755  DO j=1,jmn
3756  glat(j) = -90. + (j-1) * delxn + delxn * 0.5
3757  ENDDO
3758  print *,' IM=',im,' JM=',jm,' IMN=',imn,' JMN=',jmn
3759 C
3760 C---- FIND THE AVERAGE OF THE MODES IN A GRID BOX
3761 C
3762 C
3763  DO j=1,jm
3764  DO i=1,im
3765  xnsum(i,j) = 0.0
3766  elvmax(i,j) = oro(i,j)
3767  zmax(i,j) = 0.0
3768 C---- COUNT NUMBER OF MODE. HIGHER THAN THE HC, CRITICAL HEIGHT
3769 C IN A GRID BOX
3770  xnsum1(i,j) = 0.0
3771  xnsum2(i,j) = 0.0
3772  xnsum3(i,j) = 0.0
3773  xnsum4(i,j) = 0.0
3774  oro1(i,j) = oro(i,j)
3775  elvmax(i,j) = zmax(i,j)
3776  ENDDO
3777  ENDDO
3778 
3779 ! --- # of peaks > ZAVG value and ZMAX(IM,JM) -- ORO is already avg.
3780 ! --- to JM or to JM1
3781  DO j=1,jm
3782 ! print*, "J=", J
3783  DO i=1,im
3784  hc = 1116.2 - 0.878 * var(i,j)
3785  lono(1) = lon_c(i,j)
3786  lono(2) = lon_c(i+1,j)
3787  lono(3) = lon_c(i+1,j+1)
3788  lono(4) = lon_c(i,j+1)
3789  lato(1) = lat_c(i,j)
3790  lato(2) = lat_c(i+1,j)
3791  lato(3) = lat_c(i+1,j+1)
3792  lato(4) = lat_c(i,j+1)
3793  call get_index(imn,jmn,4,lono,lato,delxn,jst,jen,ilist,numx)
3794  do j1 = jst, jen; do ii1 = 1, numx
3795  i1 = ilist(ii1)
3796  loni = i1*delxn
3797  lati = -90 + j1*delxn
3798  if(inside_a_polygon(loni*d2r,lati*d2r,4,
3799  & lono*d2r,lato*d2r))then
3800 
3801  height = float(zavg(i1,j1))
3802  IF(height.LT.-990.) height = 0.0
3803  IF ( height .gt. oro(i,j) ) then
3804  if ( height .gt. zmax(i,j) )zmax(i,j) = height
3805  ENDIF
3806  endif
3807  ENDDO ; ENDDO
3808  ENDDO
3809  ENDDO
3810 
3811 C
3812 ! --- this will make work1 array take on oro's values on return
3813 ! --- this will make work1 array take on oro's values on return
3814  DO j=1,jm
3815  DO i=1,im
3816 
3817  oro1(i,j) = oro(i,j)
3818  elvmax(i,j) = zmax(i,j)
3819  ENDDO
3820  ENDDO
3821 
3822  DO kwd = 1, 4
3823  DO j=1,jm
3824  DO i=1,im
3825  oa4(i,j,kwd) = 0.0
3826  ol(i,j,kwd) = 0.0
3827  ENDDO
3828  ENDDO
3829  ENDDO
3830 
3831  !--- use the nearest point to do remapping.
3832  int_opt = 2
3833  ipopt=0
3834  kgds_input = 0
3835  kgds_input(1) = 4 ! OCT 6 - TYPE OF GRID (GAUSSIAN)
3836  kgds_input(2) = imi ! OCT 7-8 - # PTS ON LATITUDE CIRCLE
3837  kgds_input(3) = jmi ! OCT 9-10 - # PTS ON LONGITUDE CIRCLE
3838  kgds_input(4) = 90000 ! OCT 11-13 - LAT OF ORIGIN
3839  kgds_input(5) = 0 ! OCT 14-16 - LON OF ORIGIN
3840  kgds_input(6) = 128 ! OCT 17 - RESOLUTION FLAG
3841  kgds_input(7) = -90000 ! OCT 18-20 - LAT OF EXTREME POINT
3842  kgds_input(8) = nint(-360000./imi) ! OCT 21-23 - LON OF EXTREME POINT
3843  kgds_input(9) = nint((360.0 / float(imi))*1000.0)
3844  ! OCT 24-25 - LONGITUDE DIRECTION INCR.
3845  kgds_input(10) = jmi /2 ! OCT 26-27 - NUMBER OF CIRCLES POLE TO EQUATOR
3846  kgds_input(12) = 255 ! OCT 29 - RESERVED
3847  kgds_input(20) = 255 ! OCT 5 - NOT USED, SET TO 255
3848 
3849 
3850  kgds_output = -1
3851 ! KGDS_OUTPUT(1) = IDRT ! OCT 6 - TYPE OF GRID (GAUSSIAN)
3852  kgds_output(2) = im ! OCT 7-8 - # PTS ON LATITUDE CIRCLE
3853  kgds_output(3) = jm ! OCT 9-10 - # PTS ON LONGITUDE CIRCLE
3854  kgds_output(4) = 90000 ! OCT 11-13 - LAT OF ORIGIN
3855  kgds_output(5) = 0 ! OCT 14-16 - LON OF ORIGIN
3856  kgds_output(6) = 128 ! OCT 17 - RESOLUTION FLAG
3857  kgds_output(7) = -90000 ! OCT 18-20 - LAT OF EXTREME POINT
3858  kgds_output(8) = nint(-360000./im) ! OCT 21-23 - LON OF EXTREME POINT
3859  kgds_output(9) = nint((360.0 / float(im))*1000.0)
3860  ! OCT 24-25 - LONGITUDE DIRECTION INCR.
3861  kgds_output(10) = jm /2 ! OCT 26-27 - NUMBER OF CIRCLES POLE TO EQUATOR
3862  kgds_output(12) = 255 ! OCT 29 - RESERVED
3863  kgds_output(20) = 255 ! OCT 5 - NOT USED, SET TO 255
3864 
3865  count_land_output=0
3866  print*, "sum(slm) = ", sum(slm)
3867  do ij = 1, ijmdl_output
3868  j = (ij-1)/im + 1
3869  i = mod(ij-1,im) + 1
3870  if (slm(i,j) > 0.0) then
3871  count_land_output=count_land_output+1
3872  endif
3873  enddo
3874  allocate(bitmap_input(imi,jmi))
3875  bitmap_input=.false.
3876  print*, "number of land input=", sum(slm_in)
3877  where(slm_in > 0.0) bitmap_input=.true.
3878  print*, "count(bitmap_input)", count(bitmap_input)
3879 
3880  allocate(bitmap_output(count_land_output,1))
3881  allocate(output_data_land(count_land_output,1))
3882  allocate(ijsav_land_output(count_land_output))
3883  allocate(lats_land_output(count_land_output))
3884  allocate(lons_land_output(count_land_output))
3885 
3886 
3887 
3888  count_land_output=0
3889  do ij = 1, ijmdl_output
3890  j = (ij-1)/im + 1
3891  i = mod(ij-1,im) + 1
3892  if (slm(i,j) > 0.0) then
3893  count_land_output=count_land_output+1
3894  ijsav_land_output(count_land_output)=ij
3895  lats_land_output(count_land_output)=lat_t(i,j)
3896  lons_land_output(count_land_output)=lon_t(i,j)
3897  endif
3898  enddo
3899 
3900  oa4 = 0.0
3901  ol = 0.0
3902  ibi = 1
3903 
3904  do kwd=1,4
3905  bitmap_output = .false.
3906  output_data_land = 0.0
3907  call ipolates(int_opt, ipopt, kgds_input, kgds_output,
3908  & (imi*jmi), count_land_output,
3909  & 1, ibi, bitmap_input, oa_in(:,:,kwd),
3910  & count_land_output, lats_land_output,
3911  & lons_land_output, ibo,
3912  & bitmap_output, output_data_land, iret)
3913  if (iret /= 0) then
3914  print*,'- ERROR IN IPOLATES ',iret
3915  call errexit(4)
3916  endif
3917 
3918  num_mismatch_land = 0
3919  do ij = 1, count_land_output
3920  if (bitmap_output(ij,1)) then
3921  j = (ijsav_land_output(ij)-1)/im + 1
3922  i = mod(ijsav_land_output(ij)-1,im) + 1
3923  oa4(i,j,kwd)=output_data_land(ij,1)
3924  else ! default value
3925  num_mismatch_land = num_mismatch_land + 1
3926  endif
3927  enddo
3928  print*, "num_mismatch_land = ", num_mismatch_land
3929 
3930  if(.not. allocated(data_mismatch_output)) then
3931  allocate(lons_mismatch_output(num_mismatch_land))
3932  allocate(lats_mismatch_output(num_mismatch_land))
3933  allocate(data_mismatch_output(num_mismatch_land))
3934  allocate(iindx(num_mismatch_land))
3935  allocate(jindx(num_mismatch_land))
3936 
3937  num = 0
3938  do ij = 1, count_land_output
3939  if (.not. bitmap_output(ij,1)) then
3940  num = num+1
3941  lons_mismatch_output(num) = lons_land_output(ij)
3942  lats_mismatch_output(num) = lats_land_output(ij)
3943  endif
3944  enddo
3945 
3946  ! For those land points that with bitmap_output=.false. use
3947  ! the nearest land points to interpolate.
3948  print*,"before get_mismatch_index", count(bitmap_input)
3949  call get_mismatch_index(imi,jmi,lon_in*d2r,
3950  & lat_in*d2r,bitmap_input,num_mismatch_land,
3951  & lons_mismatch_output*d2r,lats_mismatch_output*d2r,
3952  & iindx, jindx )
3953  endif
3954 
3955  data_mismatch_output = 0
3956  call interpolate_mismatch(imi,jmi,oa_in(:,:,kwd),
3957  & num_mismatch_land,data_mismatch_output,iindx,jindx)
3958 
3959  num = 0
3960  do ij = 1, count_land_output
3961  if (.not. bitmap_output(ij,1)) then
3962  num = num+1
3963  j = (ijsav_land_output(ij)-1)/im + 1
3964  i = mod(ijsav_land_output(ij)-1,im) + 1
3965  oa4(i,j,kwd) = data_mismatch_output(num)
3966  if(i==372 .and. j== 611) then
3967  print*, "ij=",ij, num, oa4(i,j,kwd),iindx(num),jindx(num)
3968  endif
3969  endif
3970  enddo
3971 
3972 
3973  enddo
3974 
3975  !OL
3976  do kwd=1,4
3977  bitmap_output = .false.
3978  output_data_land = 0.0
3979  call ipolates(int_opt, ipopt, kgds_input, kgds_output,
3980  & (imi*jmi), count_land_output,
3981  & 1, ibi, bitmap_input, ol_in(:,:,kwd),
3982  & count_land_output, lats_land_output,
3983  & lons_land_output, ibo,
3984  & bitmap_output, output_data_land, iret)
3985  if (iret /= 0) then
3986  print*,'- ERROR IN IPOLATES ',iret
3987  call errexit(4)
3988  endif
3989 
3990  num_mismatch_land = 0
3991  do ij = 1, count_land_output
3992  if (bitmap_output(ij,1)) then
3993  j = (ijsav_land_output(ij)-1)/im + 1
3994  i = mod(ijsav_land_output(ij)-1,im) + 1
3995  ol(i,j,kwd)=output_data_land(ij,1)
3996  else ! default value
3997  num_mismatch_land = num_mismatch_land + 1
3998  endif
3999  enddo
4000  print*, "num_mismatch_land = ", num_mismatch_land
4001 
4002  data_mismatch_output = 0
4003  call interpolate_mismatch(imi,jmi,ol_in(:,:,kwd),
4004  & num_mismatch_land,data_mismatch_output,iindx,jindx)
4005 
4006  num = 0
4007  do ij = 1, count_land_output
4008  if (.not. bitmap_output(ij,1)) then
4009  num = num+1
4010  j = (ijsav_land_output(ij)-1)/im + 1
4011  i = mod(ijsav_land_output(ij)-1,im) + 1
4012  ol(i,j,kwd) = data_mismatch_output(num)
4013  if(i==372 .and. j== 611) then
4014  print*, "ij=",ij, num, ol(i,j,kwd),iindx(num),jindx(num)
4015  endif
4016  endif
4017  enddo
4018 
4019 
4020  enddo
4021 
4022  deallocate(lons_mismatch_output,lats_mismatch_output)
4023  deallocate(data_mismatch_output,iindx,jindx)
4024  deallocate(bitmap_output,output_data_land)
4025  deallocate(ijsav_land_output,lats_land_output)
4026  deallocate(lons_land_output)
4027 
4028  DO kwd=1,4
4029  DO j=1,jm
4030  DO i=1,im
4031  t = oa4(i,j,kwd)
4032  oa4(i,j,kwd) = sign( min( abs(t), 1. ), t )
4033  ENDDO
4034  ENDDO
4035  ENDDO
4036 C
4037  ns0 = 0
4038  ns1 = 0
4039  ns2 = 0
4040  ns3 = 0
4041  ns4 = 0
4042  ns5 = 0
4043  ns6 = 0
4044  DO kwd=1,4
4045  DO j=1,jm
4046  DO i=1,im
4047  t = abs( oa4(i,j,kwd) )
4048  IF(t .EQ. 0.) THEN
4049  ioa4(i,j,kwd) = 0
4050  ns0 = ns0 + 1
4051  ELSE IF(t .GT. 0. .AND. t .LE. 1.) THEN
4052  ioa4(i,j,kwd) = 1
4053  ns1 = ns1 + 1
4054  ELSE IF(t .GT. 1. .AND. t .LE. 10.) THEN
4055  ioa4(i,j,kwd) = 2
4056  ns2 = ns2 + 1
4057  ELSE IF(t .GT. 10. .AND. t .LE. 100.) THEN
4058  ioa4(i,j,kwd) = 3
4059  ns3 = ns3 + 1
4060  ELSE IF(t .GT. 100. .AND. t .LE. 1000.) THEN
4061  ioa4(i,j,kwd) = 4
4062  ns4 = ns4 + 1
4063  ELSE IF(t .GT. 1000. .AND. t .LE. 10000.) THEN
4064  ioa4(i,j,kwd) = 5
4065  ns5 = ns5 + 1
4066  ELSE IF(t .GT. 10000.) THEN
4067  ioa4(i,j,kwd) = 6
4068  ns6 = ns6 + 1
4069  ENDIF
4070  ENDDO
4071  ENDDO
4072  ENDDO
4073 C
4074  WRITE(6,*) "! MAKEOA3 EXIT"
4075 C
4076  RETURN
4077  END SUBROUTINE makeoa3
4078 
4089  SUBROUTINE revers(IM, JM, numi, F, WRK)
4090 !
4091  REAL f(im,jm), wrk(im,jm)
4092  integer numi(jm)
4093  imb2 = im / 2
4094  do i=1,im*jm
4095  wrk(i,1) = f(i,1)
4096  enddo
4097  do j=1,jm
4098  jr = jm - j + 1
4099  do i=1,im
4100  ir = i + imb2
4101  if (ir .gt. im) ir = ir - im
4102  f(ir,jr) = wrk(i,j)
4103  enddo
4104  enddo
4105 !
4106  tem = 0.0
4107  do i=1,im
4108  tem= tem + f(i,1)
4109  enddo
4110  tem = tem / im
4111  do i=1,im
4112  f(i,1) = tem
4113  enddo
4114 !
4115  RETURN
4116  END
4117 
4126  subroutine rg2gg(im,jm,numi,a)
4127  implicit none
4128  integer,intent(in):: im,jm,numi(jm)
4129  real,intent(inout):: a(im,jm)
4130  integer j,ir,ig
4131  real r,t(im)
4132  do j=1,jm
4133  r=real(numi(j))/real(im)
4134  do ig=1,im
4135  ir=mod(nint((ig-1)*r),numi(j))+1
4136  t(ig)=a(ir,j)
4137  enddo
4138  do ig=1,im
4139  a(ig,j)=t(ig)
4140  enddo
4141  enddo
4142  end subroutine
4143 
4152  subroutine gg2rg(im,jm,numi,a)
4153  implicit none
4154  integer,intent(in):: im,jm,numi(jm)
4155  real,intent(inout):: a(im,jm)
4156  integer j,ir,ig
4157  real r,t(im)
4158  do j=1,jm
4159  r=real(numi(j))/real(im)
4160  do ir=1,numi(j)
4161  ig=nint((ir-1)/r)+1
4162  t(ir)=a(ig,j)
4163  enddo
4164  do ir=1,numi(j)
4165  a(ir,j)=t(ir)
4166  enddo
4167  enddo
4168  end subroutine
4169 
4178  SUBROUTINE minmxj(IM,JM,A,title)
4179  implicit none
4180 
4181  real a(im,jm),rmin,rmax
4182  integer i,j,im,jm
4183  character*8 title
4184 
4185  rmin=1.e+10
4186  rmax=-rmin
4187 csela....................................................
4188 csela if(rmin.eq.1.e+10)return
4189 csela....................................................
4190  DO j=1,jm
4191  DO i=1,im
4192  if(a(i,j).ge.rmax)rmax=a(i,j)
4193  if(a(i,j).le.rmin)rmin=a(i,j)
4194  ENDDO
4195  ENDDO
4196  write(6,150)rmin,rmax,title
4197 150 format('rmin=',e13.4,2x,'rmax=',e13.4,2x,a8,' ')
4198 C
4199  RETURN
4200  END
4201 
4213  SUBROUTINE mnmxja(IM,JM,A,imax,jmax,title)
4214  implicit none
4215 
4216  real a(im,jm),rmin,rmax
4217  integer i,j,im,jm,imax,jmax
4218  character*8 title
4219 
4220  rmin=1.e+10
4221  rmax=-rmin
4222 csela....................................................
4223 csela if(rmin.eq.1.e+10)return
4224 csela....................................................
4225  DO j=1,jm
4226  DO i=1,im
4227  if(a(i,j).ge.rmax)then
4228  rmax=a(i,j)
4229  imax=i
4230  jmax=j
4231  endif
4232  if(a(i,j).le.rmin)rmin=a(i,j)
4233  ENDDO
4234  ENDDO
4235  write(6,150)rmin,rmax,title
4236 150 format('rmin=',e13.4,2x,'rmax=',e13.4,2x,a8,' ')
4237 C
4238  RETURN
4239  END
4240 
4275  SUBROUTINE spfft1(IMAX,INCW,INCG,KMAX,W,G,IDIR)
4276  IMPLICIT NONE
4277  INTEGER,INTENT(IN):: imax,incw,incg,kmax,idir
4278  COMPLEX,INTENT(INOUT):: w(incw,kmax)
4279  REAL,INTENT(INOUT):: g(incg,kmax)
4280  REAL:: aux1(25000+int(0.82*imax))
4281  REAL:: aux2(20000+int(0.57*imax))
4282  INTEGER:: naux1,naux2
4283 C - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4284  naux1=25000+int(0.82*imax)
4285  naux2=20000+int(0.57*imax)
4286 C - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4287 C FOURIER TO PHYSICAL TRANSFORM.
4288  SELECT CASE(idir)
4289  CASE(1:)
4290  SELECT CASE(digits(1.))
4291  CASE(digits(1._4))
4292  CALL scrft(1,w,incw,g,incg,imax,kmax,-1,1.,
4293  & aux1,naux1,aux2,naux2,0.,0)
4294  CALL scrft(0,w,incw,g,incg,imax,kmax,-1,1.,
4295  & aux1,naux1,aux2,naux2,0.,0)
4296  CASE(digits(1._8))
4297  CALL dcrft(1,w,incw,g,incg,imax,kmax,-1,1.,
4298  & aux1,naux1,aux2,naux2,0.,0)
4299  CALL dcrft(0,w,incw,g,incg,imax,kmax,-1,1.,
4300  & aux1,naux1,aux2,naux2,0.,0)
4301  END SELECT
4302 C - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4303 C PHYSICAL TO FOURIER TRANSFORM.
4304  CASE(:-1)
4305  SELECT CASE(digits(1.))
4306  CASE(digits(1._4))
4307  CALL srcft(1,g,incg,w,incw,imax,kmax,+1,1./imax,
4308  & aux1,naux1,aux2,naux2,0.,0)
4309  CALL srcft(0,g,incg,w,incw,imax,kmax,+1,1./imax,
4310  & aux1,naux1,aux2,naux2,0.,0)
4311  CASE(digits(1._8))
4312  CALL drcft(1,g,incg,w,incw,imax,kmax,+1,1./imax,
4313  & aux1,naux1,aux2,naux2,0.,0)
4314  CALL drcft(0,g,incg,w,incw,imax,kmax,+1,1./imax,
4315  & aux1,naux1,aux2,naux2,0.,0)
4316  END SELECT
4317  END SELECT
4318  END SUBROUTINE
4319 
4324  subroutine read_g(glob)
4325  implicit none
4326 
4327  include 'netcdf.inc'
4328 
4329  integer*2, intent(out) :: glob(360*120,180*120)
4330 
4331  integer :: ncid, error, id_var, fsize
4332 
4333  fsize=65536
4334 
4335  error=nf__open("./topography.gmted2010.30s.nc",
4336  & nf_nowrite,fsize,ncid)
4337  call netcdf_err(error, 'Open file topography.gmted2010.30s.nc' )
4338  error=nf_inq_varid(ncid, 'topo', id_var)
4339  call netcdf_err(error, 'Inquire varid of topo')
4340  error=nf_get_var_int2(ncid, id_var, glob)
4341  call netcdf_err(error, 'Read topo')
4342  error = nf_close(ncid)
4343 
4344  print*,' '
4345  call maxmin(glob,360*120*180*120,'global0')
4346 
4347  return
4348  end subroutine read_g
4349 
4357  subroutine maxmin(ia,len,tile)
4358 ccmr
4359  implicit none
4360 ccmr
4361  integer*2 ia(len)
4362  character*7 tile
4363  integer iaamax, iaamin, len, j, m, ja, kount
4364  integer(8) sum2,std,mean,isum
4365  integer i_count_notset,kount_9
4366 ! --- missing is -9999
4367 c
4368  isum = 0
4369  sum2 = 0
4370  kount = 0
4371  kount_9 = 0
4372  iaamax = -9999999
4373 ccmr iaamin = 1
4374  iaamin = 9999999
4375  i_count_notset=0
4376  do 10 m=1,len
4377  ja=ia(m)
4378 ccmr if ( ja .lt. 0 ) print *,' ja < 0:',ja
4379 ccmr if ( ja .eq. -9999 ) goto 10
4380  if ( ja .eq. -9999 ) then
4381  kount_9=kount_9+1
4382  goto 10
4383  endif
4384  if ( ja .eq. -12345 ) i_count_notset=i_count_notset+1
4385 ccmr if ( ja .eq. 0 ) goto 11
4386  iaamax = max0( iaamax, ja )
4387  iaamin = min0( iaamin, ja )
4388 ! iaamax = max0( iaamax, ia(m,j) )
4389 ! iaamin = min0( iaamin, ia(m,j) )
4390  11 continue
4391  kount = kount + 1
4392  isum = isum + ja
4393 ccmr sum2 = sum2 + ifix( float(ja) * float(ja) )
4394  sum2 = sum2 + ja*ja
4395  10 continue
4396 !
4397  mean = isum/kount
4398  std = ifix(sqrt(float((sum2/(kount))-mean**2)))
4399  print*,tile,' max=',iaamax,' min=',iaamin,' sum=',isum,
4400  & ' i_count_notset=',i_count_notset
4401  print*,tile,' mean=',mean,' std.dev=',std,
4402  & ' ko9s=',kount,kount_9,kount+kount_9
4403  return
4404  end
4405 
4415  SUBROUTINE minmaxj(IM,JM,A,title)
4416  implicit none
4417 
4418  real(kind=4) a(im,jm),rmin,rmax,undef
4419  integer i,j,im,jm,imax,jmax,imin,jmin,iundef
4420  character*8 title,chara
4421  data chara/' '/
4422  chara=title
4423  rmin=1.e+10
4424  rmax=-rmin
4425  imax=0
4426  imin=0
4427  jmax=0
4428  jmin=0
4429  iundef=0
4430  undef=-9999.
4431 csela....................................................
4432 csela if(rmin.eq.1.e+10)return
4433 csela....................................................
4434  DO j=1,jm
4435  DO i=1,im
4436  if(a(i,j).ge.rmax)then
4437  rmax=a(i,j)
4438  imax=i
4439  jmax=j
4440  endif
4441  if(a(i,j).le.rmin)then
4442  if ( a(i,j) .eq. undef ) then
4443  iundef = iundef + 1
4444  else
4445  rmin=a(i,j)
4446  imin=i
4447  jmin=j
4448  endif
4449  endif
4450  ENDDO
4451  ENDDO
4452  write(6,150)chara,rmin,imin,jmin,rmax,imax,jmax,iundef
4453 150 format(1x,a8,2x,'rmin=',e13.4,2i6,2x,'rmax=',e13.4,3i6)
4454 C
4455  RETURN
4456  END
4457 
4467  subroutine latlon2xyz(siz,lon, lat, x, y, z)
4468  implicit none
4469  integer, intent(in) :: siz
4470  real, intent(in) :: lon(siz), lat(siz)
4471  real, intent(out) :: x(siz), y(siz), z(siz)
4472 
4473  integer n
4474 
4475  do n = 1, siz
4476  x(n) = cos(lat(n))*cos(lon(n))
4477  y(n) = cos(lat(n))*sin(lon(n))
4478  z(n) = sin(lat(n))
4479  enddo
4480  end
4481 
4489  FUNCTION spherical_angle(v1, v2, v3)
4490  implicit none
4491  real, parameter :: epsln30 = 1.e-30
4492  real, parameter :: pi=3.1415926535897931
4493  real v1(3), v2(3), v3(3)
4494  real spherical_angle
4495 
4496  real px, py, pz, qx, qy, qz, ddd;
4497 
4498  ! vector product between v1 and v2
4499  px = v1(2)*v2(3) - v1(3)*v2(2)
4500  py = v1(3)*v2(1) - v1(1)*v2(3)
4501  pz = v1(1)*v2(2) - v1(2)*v2(1)
4502  ! vector product between v1 and v3
4503  qx = v1(2)*v3(3) - v1(3)*v3(2);
4504  qy = v1(3)*v3(1) - v1(1)*v3(3);
4505  qz = v1(1)*v3(2) - v1(2)*v3(1);
4506 
4507  ddd = (px*px+py*py+pz*pz)*(qx*qx+qy*qy+qz*qz);
4508  if ( ddd <= 0.0 ) then
4509  spherical_angle = 0.
4510  else
4511  ddd = (px*qx+py*qy+pz*qz) / sqrt(ddd);
4512  if( abs(ddd-1) < epsln30 ) ddd = 1;
4513  if( abs(ddd+1) < epsln30 ) ddd = -1;
4514  if ( ddd>1. .or. ddd<-1. ) then
4515  !FIX to correctly handle co-linear points (angle near pi or 0) */
4516  if (ddd < 0.) then
4517  spherical_angle = pi
4518  else
4519  spherical_angle = 0.
4520  endif
4521  else
4522  spherical_angle = acos( ddd )
4523  endif
4524  endif
4525 
4526  return
4527  END
4528 
4539  FUNCTION inside_a_polygon(lon1, lat1, npts, lon2, lat2)
4540  implicit none
4541  real, parameter :: epsln10 = 1.e-10
4542  real, parameter :: epsln8 = 1.e-8
4543  real, parameter :: pi=3.1415926535897931
4544  real, parameter :: range_check_criteria=0.05
4545  real :: anglesum, angle, spherical_angle
4546  integer i, ip1
4547  real lon1, lat1
4548  integer npts
4549  real lon2(npts), lat2(npts)
4550  real x2(npts), y2(npts), z2(npts)
4551  real lon1_1d(1), lat1_1d(1)
4552  real x1(1), y1(1), z1(1)
4553  real pnt0(3),pnt1(3),pnt2(3)
4554  logical inside_a_polygon
4555  real max_x2,min_x2,max_y2,min_y2,max_z2,min_z2
4556  !first convert to cartesian grid */
4557  call latlon2xyz(npts,lon2, lat2, x2, y2, z2);
4558  lon1_1d(1) = lon1
4559  lat1_1d(1) = lat1
4560  call latlon2xyz(1,lon1_1d, lat1_1d, x1, y1, z1);
4561  inside_a_polygon = .false.
4562  max_x2 = maxval(x2)
4563  if( x1(1) > max_x2+range_check_criteria ) return
4564  min_x2 = minval(x2)
4565  if( x1(1)+range_check_criteria < min_x2 ) return
4566  max_y2 = maxval(y2)
4567  if( y1(1) > max_y2+range_check_criteria ) return
4568  min_y2 = minval(y2)
4569  if( y1(1)+range_check_criteria < min_y2 ) return
4570  max_z2 = maxval(z2)
4571  if( z1(1) > max_z2+range_check_criteria ) return
4572  min_z2 = minval(z2)
4573  if( z1(1)+range_check_criteria < min_z2 ) return
4574 
4575  pnt0(1) = x1(1)
4576  pnt0(2) = y1(1)
4577  pnt0(3) = z1(1)
4578 
4579  anglesum = 0;
4580  do i = 1, npts
4581  if(abs(x1(1)-x2(i)) < epsln10 .and.
4582  & abs(y1(1)-y2(i)) < epsln10 .and.
4583  & abs(z1(1)-z2(i)) < epsln10 ) then ! same as the corner point
4584  inside_a_polygon = .true.
4585  return
4586  endif
4587  ip1 = i+1
4588  if(ip1>npts) ip1 = 1
4589  pnt1(1) = x2(i)
4590  pnt1(2) = y2(i)
4591  pnt1(3) = z2(i)
4592  pnt2(1) = x2(ip1)
4593  pnt2(2) = y2(ip1)
4594  pnt2(3) = z2(ip1)
4595 
4596  angle = spherical_angle(pnt0, pnt2, pnt1);
4597 ! anglesum = anglesum + spherical_angle(pnt0, pnt2, pnt1);
4598  anglesum = anglesum + angle
4599  enddo
4600 
4601  if(abs(anglesum-2*pi) < epsln8) then
4602  inside_a_polygon = .true.
4603  else
4604  inside_a_polygon = .false.
4605  endif
4606 
4607  return
4608 
4609  end
4610 
4634  function get_xnsum(lon1,lat1,lon2,lat2,IMN,JMN,
4635  & glat,zavg,zslm,delxn)
4636  implicit none
4637 
4638  real get_xnsum
4639  logical verbose
4640  real, intent(in) :: lon1,lat1,lon2,lat2,delxn
4641  integer, intent(in) :: imn,jmn
4642  real, intent(in) :: glat(jmn)
4643  integer, intent(in) :: zavg(imn,jmn),zslm(imn,jmn)
4644  integer i, j, ist, ien, jst, jen, i1
4645  real oro, height
4646  real xland,xwatr,xl1,xs1,slm,xnsum
4647  !---figure out ist,ien,jst,jen
4648  do j = 1, jmn
4649  if( glat(j) .GT. lat1 ) then
4650  jst = j
4651  exit
4652  endif
4653  enddo
4654  do j = 1, jmn
4655  if( glat(j) .GT. lat2 ) then
4656  jen = j
4657  exit
4658  endif
4659  enddo
4660 
4661 
4662  ist = lon1/delxn + 1
4663  ien = lon2/delxn
4664  if(ist .le.0) ist = ist + imn
4665  if(ien < ist) ien = ien + imn
4666 ! if(verbose) print*, "ist,ien=",ist,ien,jst,jen
4667 
4668  !--- compute average oro
4669  oro = 0.0
4670  xnsum = 0
4671  xland = 0
4672  xwatr = 0
4673  xl1 = 0
4674  xs1 = 0
4675  do j = jst,jen
4676  do i1 = 1, ien - ist + 1
4677  i = ist + i1 -1
4678  if( i .LE. 0) i = i + imn
4679  if( i .GT. imn) i = i - imn
4680  xland = xland + float(zslm(i,j))
4681  xwatr = xwatr + float(1-zslm(i,j))
4682  xnsum = xnsum + 1.
4683  height = float(zavg(i,j))
4684  IF(height.LT.-990.) height = 0.0
4685  xl1 = xl1 + height * float(zslm(i,j))
4686  xs1 = xs1 + height * float(1-zslm(i,j))
4687  enddo
4688  enddo
4689  if( xnsum > 1.) THEN
4690  slm = float(nint(xland/xnsum))
4691  IF(slm.NE.0.) THEN
4692  oro= xl1 / xland
4693  ELSE
4694  oro = xs1 / xwatr
4695  ENDIF
4696  ENDIF
4697 
4698  get_xnsum = 0
4699  do j = jst, jen
4700  do i1= 1, ien-ist+1
4701  i = ist + i1 -1
4702  if( i .LE. 0) i = i + imn
4703  if( i .GT. imn) i = i - imn
4704  height = float(zavg(i,j))
4705  IF(height.LT.-990.) height = 0.0
4706  IF ( height .gt. oro ) get_xnsum = get_xnsum + 1
4707  enddo
4708  enddo
4709 ! if(verbose) print*, "get_xnsum=", get_xnsum, oro
4710 
4711  end function get_xnsum
4712 
4740  subroutine get_xnsum2(lon1,lat1,lon2,lat2,IMN,JMN,
4741  & glat,zavg,delxn,xnsum1,xnsum2,hc)
4742  implicit none
4743 
4744  real, intent(out) :: xnsum1,xnsum2,hc
4745  logical verbose
4746  real lon1,lat1,lon2,lat2,oro,delxn
4747  integer imn,jmn
4748  real glat(jmn)
4749  integer zavg(imn,jmn)
4750  integer i, j, ist, ien, jst, jen, i1
4751  real height, var
4752  real xw1,xw2,slm,xnsum
4753  !---figure out ist,ien,jst,jen
4754  do j = 1, jmn
4755  if( glat(j) .GT. lat1 ) then
4756  jst = j
4757  exit
4758  endif
4759  enddo
4760  do j = 1, jmn
4761  if( glat(j) .GT. lat2 ) then
4762  jen = j
4763  exit
4764  endif
4765  enddo
4766 
4767 
4768  ist = lon1/delxn + 1
4769  ien = lon2/delxn
4770  if(ist .le.0) ist = ist + imn
4771  if(ien < ist) ien = ien + imn
4772 ! if(verbose) print*, "ist,ien=",ist,ien,jst,jen
4773 
4774  !--- compute average oro
4775  xnsum = 0
4776  xw1 = 0
4777  xw2 = 0
4778  do j = jst,jen
4779  do i1 = 1, ien - ist + 1
4780  i = ist + i1 -1
4781  if( i .LE. 0) i = i + imn
4782  if( i .GT. imn) i = i - imn
4783  xnsum = xnsum + 1.
4784  height = float(zavg(i,j))
4785  IF(height.LT.-990.) height = 0.0
4786  xw1 = xw1 + height
4787  xw2 = xw2 + height ** 2
4788  enddo
4789  enddo
4790  var = sqrt(max(xw2/xnsum-(xw1/xnsum)**2,0.))
4791  hc = 1116.2 - 0.878 * var
4792  xnsum1 = 0
4793  xnsum2 = 0
4794  do j = jst, jen
4795  do i1= 1, ien-ist+1
4796  i = ist + i1 -1
4797  if( i .LE. 0) i = i + imn
4798  if( i .GT. imn) i = i - imn
4799  height = float(zavg(i,j))
4800  IF ( height .gt. hc ) xnsum1 = xnsum1 + 1
4801  xnsum2 = xnsum2 + 1
4802  enddo
4803  enddo
4804 
4805  end subroutine get_xnsum2
4806 
4835  subroutine get_xnsum3(lon1,lat1,lon2,lat2,IMN,JMN,
4836  & glat,zavg,delxn,xnsum1,xnsum2,hc)
4837  implicit none
4838 
4839  real, intent(out) :: xnsum1,xnsum2
4840  real lon1,lat1,lon2,lat2,oro,delxn
4841  integer imn,jmn
4842  real glat(jmn)
4843  integer zavg(imn,jmn)
4844  integer i, j, ist, ien, jst, jen, i1
4845  real height, hc
4846  real xw1,xw2,slm,xnsum
4847  !---figure out ist,ien,jst,jen
4848  ! if lat1 or lat 2 is 90 degree. set jst = JMN
4849  jst = jmn
4850  jen = jmn
4851  do j = 1, jmn
4852  if( glat(j) .GT. lat1 ) then
4853  jst = j
4854  exit
4855  endif
4856  enddo
4857  do j = 1, jmn
4858  if( glat(j) .GT. lat2 ) then
4859  jen = j
4860  exit
4861  endif
4862  enddo
4863 
4864 
4865  ist = lon1/delxn + 1
4866  ien = lon2/delxn
4867  if(ist .le.0) ist = ist + imn
4868  if(ien < ist) ien = ien + imn
4869 ! if(verbose) print*, "ist,ien=",ist,ien,jst,jen
4870 
4871  xnsum1 = 0
4872  xnsum2 = 0
4873  do j = jst, jen
4874  do i1= 1, ien-ist+1
4875  i = ist + i1 -1
4876  if( i .LE. 0) i = i + imn
4877  if( i .GT. imn) i = i - imn
4878  height = float(zavg(i,j))
4879  IF ( height .gt. hc ) xnsum1 = xnsum1 + 1
4880  xnsum2 = xnsum2 + 1
4881  enddo
4882  enddo
4883 
4884  end subroutine get_xnsum3
4885 
4899  subroutine nanc(a,l,c)
4900  integer inan1,inan2,inan3,inan4,inaq1,inaq2,inaq3,inaq4
4901  real word
4902  integer itest
4903  equivalence(itest,word)
4904 c
4905 c signaling NaN
4906  data inan1/x'7F800001'/
4907  data inan2/x'7FBFFFFF'/
4908  data inan3/x'FF800001'/
4909  data inan4/x'FFBFFFFF'/
4910 c
4911 c quiet NaN
4912 c
4913  data inaq1/x'7FC00000'/
4914  data inaq2/x'7FFFFFFF'/
4915  data inaq3/x'FFC00000'/
4916  data inaq4/x'FFFFFFFF'/
4917 c
4918  real(kind=8)a(l),rtc,t1,t2
4919  character*(*) c
4920 c t1=rtc()
4921 cgwv print *, ' nanc call ',c
4922  do k=1,l
4923  word=a(k)
4924  if( (itest .GE. inan1 .AND. itest .LE. inan2) .OR.
4925  * (itest .GE. inan3 .AND. itest .LE. inan4) ) then
4926  print *,' NaNs detected at word',k,' ',c
4927  return
4928  endif
4929  if( (itest .GE. inaq1 .AND. itest .LE. inaq2) .OR.
4930  * (itest .GE. inaq3 .AND. itest .LE. inaq4) ) then
4931  print *,' NaNq detected at word',k,' ',c
4932  return
4933  endif
4934 
4935  101 format(e20.10)
4936  end do
4937 c t2=rtc()
4938 cgwv print 102,l,t2-t1,c
4939  102 format(' time to check ',i9,' words is ',f10.4,' ',a24)
4940  return
4941  end
4942 
4947  real function timef()
4948  character(8) :: date
4949  character(10) :: time
4950  character(5) :: zone
4951  integer,dimension(8) :: values
4952  integer :: total
4953  real :: elapsed
4954  call date_and_time(date,time,zone,values)
4955  total=(3600*values(5))+(60*values(6))
4956  * +values(7)
4957  elapsed=float(total) + (1.0e-3*float(values(8)))
4958  timef=elapsed
4959  return
4960  end
subroutine write_mask_netcdf(im, jm, slm, land_frac, ntiles, tile, geolon, geolat)
Write the land mask file.
Definition: netcdf_io.F90:243
subroutine read_mask(merge_file, slm, land_frac, lake_frac, im, jm)
Read the land mask file.
Definition: netcdf_io.F90:334
subroutine makemt(ZAVG, ZSLM, ORO, SLM, VAR, VAR4, GLAT, IST, IEN, JST, JEN, IM, JM, IMN, JMN, XLAT, numi)
Create the orography, land-mask, standard deviation of orography and the convexity on a model gaussia...
subroutine get_index(IMN, JMN, npts, lonO, latO, DELXN, jst, jen, ilist, numx)
Determine the location of a cubed-sphere point within the high-resolution orography data...
real function timef()
Get the date/time for the system clock.
subroutine netcdf_err(err, string)
Check NetCDF error code and output the error message.
Definition: netcdf_io.F90:218
real function get_lat_angle(dy, DEGRAD)
Convert the &#39;y&#39; direction distance of a cubed-sphere grid point to the corresponding distance in lati...
subroutine mnmxja(IM, JM, A, imax, jmax, title)
Print out the maximum and minimum values of an array.
subroutine makepc2(ZAVG, ZSLM, THETA, GAMMA, SIGMA, GLAT, IM, JM, IMN, JMN, lon_c, lat_c, SLM)
Make the principle coordinates - slope of orography, anisotropy, angle of mountain range with respect...
real function spherical_angle(v1, v2, v3)
Compute spherical angle.
subroutine minmaxj(IM, JM, A, title)
Print out the maximum and minimum values of an array and their i/j location.
subroutine spfft1(IMAX, INCW, INCG, KMAX, W, G, IDIR)
Perform multiple fast fourier transforms.
program lake_frac
This program computes lake fraction and depth numbers for FV3 cubed sphere grid cells, from a high resolution lat/lon data set.
Definition: lakefrac.F90:21
subroutine rg2gg(im, jm, numi, a)
Convert from a reduced grid to a full grid.
subroutine write_netcdf(im, jm, slm, land_frac, oro, orf, hprime, ntiles, tile, geolon, geolat, lon, lat)
Write out orography file in netcdf format.
Definition: netcdf_io.F90:21
subroutine makepc(ZAVG, ZSLM, THETA, GAMMA, SIGMA, GLAT, IST, IEN, JST, JEN, IM, JM, IMN, JMN, XLAT, numi)
Make the principle coordinates - slope of orography, anisotropy, angle of mountain range with respect...
subroutine gg2rg(im, jm, numi, a)
Convert from a full grid to a reduced grid.
subroutine get_xnsum3(lon1, lat1, lon2, lat2, IMN, JMN, glat, zavg, delxn, xnsum1, xnsum2, HC)
Count the number of high-resolution orography points that are higher than a critical value inside a m...
logical function inside_a_polygon(lon1, lat1, npts, lon2, lat2)
Check if a point is inside a polygon.
real function spherical_distance(theta1, phi1, theta2, phi2)
Compute a great circle distance between two points.
subroutine nanc(a, l, c)
Report NaNS and NaNQ within an address range for 8-byte real words.
subroutine makeoa3(ZAVG, zslm, VAR, GLAT, OA4, OL, IOA4, ELVMAX, ORO, SLM, oro1, XNSUM, XNSUM1, XNSUM2, XNSUM3, XNSUM4, IM, JM, IMN, JMN, lon_c, lat_c, lon_t, lat_t, is_south_pole, is_north_pole, IMI, JMI, OA_IN, OL_IN, slm_in, lon_in, lat_in)
Create orographic asymmetry and orographic length scale on the model grid.
subroutine get_mismatch_index(im_in, jm_in, geolon_in, geolat_in, bitmap_in, num_out, lon_out, lat_out, iindx, jindx)
For unmapped land points, find the nearest land point on the input data and pass back its i/j index...
subroutine make_mask(zslm, SLM, land_frac, GLAT, IM, JM, IMN, JMN, lon_c, lat_c)
Create the land-mask, land fraction.
subroutine maxmin(ia, len, tile)
Print the maximum, mininum, mean and standard deviation of an array.
subroutine makemt2(ZAVG, ZSLM, ORO, SLM, VAR, VAR4, GLAT, IM, JM, IMN, JMN, lon_c, lat_c, lake_frac, land_frac)
Create the orography, land-mask, land fraction, standard deviation of orography and the convexity on ...
subroutine interpolate_mismatch(im_in, jm_in, data_in, num_out, data_out, iindx, jindx)
Replace unmapped model land points with the nearest land point on the input grid. ...
real function get_lon_angle(dx, lat, DEGRAD)
Convert the &#39;x&#39; direction distance of a cubed-sphere grid point to the corresponding distance in long...
subroutine get_xnsum2(lon1, lat1, lon2, lat2, IMN, JMN, glat, zavg, delxn, xnsum1, xnsum2, HC)
Count the number of high-resolution orography points that are higher than a critical value inside a m...
subroutine revers(IM, JM, numi, F, WRK)
Reverse the east-west and north-south axes in a two-dimensional array.
subroutine makeoa2(ZAVG, zslm, VAR, GLAT, OA4, OL, IOA4, ELVMAX, ORO, oro1, XNSUM, XNSUM1, XNSUM2, XNSUM3, XNSUM4, IM, JM, IMN, JMN, lon_c, lat_c, lon_t, lat_t, dx, dy, is_south_pole, is_north_pole)
Create orographic asymmetry and orographic length scale on the model grid.
subroutine latlon2xyz(siz, lon, lat, x, y, z)
Convert from latitude and longitude to x,y,z coordinates.
subroutine minmxj(IM, JM, A, title)
Print out the maximum and minimum values of an array.
subroutine makeoa(ZAVG, VAR, GLAT, OA4, OL, IOA4, ELVMAX, ORO, oro1, XNSUM, XNSUM1, XNSUM2, XNSUM3, XNSUM4, IST, IEN, JST, JEN, IM, JM, IMN, JMN, XLAT, numi)
Create orographic asymmetry and orographic length scale on the model grid.
subroutine tersub(IMN, JMN, IM, JM, NM, NR, NF0, NF1, NW, EFAC, BLAT, OUTGRID, INPUTOROG, MASK_ONLY, MERGE_FILE)
Driver routine to compute terrain.
Definition: mtnlm7_oclsm.F:186
real function get_xnsum(lon1, lat1, lon2, lat2, IMN, JMN, glat, zavg, zslm, delxn)
Count the number of high-resolution orography points that are higher than the model grid box average ...
subroutine read_g(glob)
Read input global 30-arc second orography data.