75 character(len=256) :: mdl_grid_file =
"none" 76 character(len=256) :: external_mask_file =
"none" 77 integer :: im, jm, efac
78 logical :: mask_only = .false.
80 print*,
"- BEGIN OROGRAPHY PROGRAM." 82 read(5,*) mdl_grid_file
84 read(5,*) external_mask_file
89 print*,
"- WILL COMPUTE LANDMASK ONLY." 92 if (trim(external_mask_file) /=
"none")
then 93 print*,
"- WILL USE EXTERNAL LANDMASK FROM FILE: ", trim(external_mask_file)
98 call tersub(im,jm,efac,mdl_grid_file,mask_only,external_mask_file)
100 print*,
"- NORMAL TERMINATION." 118 SUBROUTINE tersub(IM,JM,EFAC,OUTGRID,MASK_ONLY,EXTERNAL_MASK_FILE)
128 integer,
parameter :: imn = 360*120
129 integer,
parameter :: jmn = 180*120
131 integer,
intent(in) :: IM,JM,efac
132 character(len=*),
intent(in) :: OUTGRID
133 character(len=*),
intent(in) :: EXTERNAL_MASK_FILE
135 logical,
intent(in) :: mask_only
138 integer :: itest,jtest
140 integer,
allocatable :: ZAVG(:,:),ZSLM(:,:)
141 integer(1),
allocatable :: UMD(:,:)
142 integer(2),
allocatable :: glob(:,:)
144 real :: tbeg,tend,tbeg1
146 real,
allocatable :: XLAT(:),XLON(:)
147 real,
allocatable :: GEOLON(:,:),GEOLON_C(:,:),DX(:,:)
148 real,
allocatable :: GEOLAT(:,:),GEOLAT_C(:,:),DY(:,:)
149 real,
allocatable :: SLM(:,:),ORO(:,:),VAR(:,:)
150 real,
allocatable :: land_frac(:,:),lake_frac(:,:)
151 real,
allocatable :: THETA(:,:),GAMMA(:,:),SIGMA(:,:),ELVMAX(:,:)
152 real,
allocatable :: VAR4(:,:)
153 real,
allocatable :: OA(:,:,:),OL(:,:,:),HPRIME(:,:,:)
155 logical :: is_south_pole(IM,JM), is_north_pole(IM,JM)
160 allocate (glob(imn,jmn))
161 allocate (zavg(imn,jmn))
162 allocate (zslm(imn,jmn))
163 allocate (umd(imn,jmn))
183 if ( umd(i,j) .eq. 0 ) zslm(i,j) = 0
187 deallocate (umd,glob)
201 allocate (geolon(im,jm),geolon_c(im+1,jm+1),dx(im,jm))
202 allocate (geolat(im,jm),geolat_c(im+1,jm+1),dy(im,jm))
203 allocate (slm(im,jm))
204 allocate (land_frac(im,jm),lake_frac(im,jm))
209 geolat,geolat_c,dx,dy,is_north_pole,is_south_pole)
212 print*,
"- TIMING: READING INPUT DATA ",tend-tbeg
216 IF (external_mask_file ==
'none')
then 218 im,jm,imn,jmn,geolon_c,geolat_c)
221 CALL read_mask(external_mask_file,slm,land_frac, &
226 print*,
'- WILL COMPUTE LANDMASK ONLY.' 230 DEALLOCATE(zavg, zslm, slm, land_frac, lake_frac)
231 DEALLOCATE(geolon, geolon_c, geolat, geolat_c)
232 print*,
'- NORMAL TERMINATION.' 236 allocate (var(im,jm),var4(im,jm),oro(im,jm))
238 CALL makemt2(zavg,zslm,oro,slm,var,var4, &
239 im,jm,imn,jmn,geolon_c,geolat_c,lake_frac,land_frac)
242 print*,
"- TIMING: MASK AND OROG CREATION ", tend-tbeg
244 call minmax(im,jm,oro,
'ORO ')
245 call minmax(im,jm,slm,
'SLM ')
246 call minmax(im,jm,var,
'VAR ')
247 call minmax(im,jm,var4,
'VAR4 ')
251 allocate (theta(im,jm),gamma(im,jm),sigma(im,jm),elvmax(im,jm))
254 CALL makepc2(zavg,zslm,theta,gamma,sigma, &
255 im,jm,imn,jmn,geolon_c,geolat_c,slm)
258 print*,
"- TIMING: CREATE PRINCIPLE COORDINATE ",tend-tbeg
260 call minmax(im,jm,theta,
'THETA ')
261 call minmax(im,jm,gamma,
'GAMMA ')
262 call minmax(im,jm,sigma,
'SIGMA ')
266 allocate (oa(im,jm,4),ol(im,jm,4))
269 CALL makeoa2(zavg,zslm,var,oa,ol,elvmax,oro, &
270 im,jm,imn,jmn,geolon_c,geolat_c, &
271 geolon,geolat,dx,dy,is_south_pole,is_north_pole)
275 print*,
"- TIMING: CREATE ASYMETRY AND LENGTH SCALE ",tend-tbeg
277 deallocate (zslm,zavg)
281 call minmax(im,jm,oa,
'OA ')
282 call minmax(im,jm,ol,
'OL ')
283 call minmax(im,jm,elvmax,
'ELVMAX ')
284 call minmax(im,jm,oro,
'ORO ')
290 print*,
"- QC MAXIMUM ELEVATION." 293 if (elvmax(i,j) .lt. oro(i,j) )
then 294 elvmax(i,j) = max( 3. * var(i,j),0.)
296 elvmax(i,j) = max( elvmax(i,j) - oro(i,j),0.)
301 call minmax(im,jm,elvmax,
'ELVMAX ',itest,jtest)
303 print*,
"- ZERO FIELDS OVER OCEAN." 307 IF(slm(i,j).EQ.0.)
THEN 329 IF (external_mask_file ==
'none')
then 335 allocate(hprime(im,jm,14))
339 oro(i,j) = oro(i,j) + efac*var(i,j)
340 hprime(i,j,1) = var(i,j)
341 hprime(i,j,2) = var4(i,j)
342 hprime(i,j,3) = oa(i,j,1)
343 hprime(i,j,4) = oa(i,j,2)
344 hprime(i,j,5) = oa(i,j,3)
345 hprime(i,j,6) = oa(i,j,4)
346 hprime(i,j,7) = ol(i,j,1)
347 hprime(i,j,8) = ol(i,j,2)
348 hprime(i,j,9) = ol(i,j,3)
349 hprime(i,j,10)= ol(i,j,4)
350 hprime(i,j,11)= theta(i,j)
351 hprime(i,j,12)= gamma(i,j)
352 hprime(i,j,13)= sigma(i,j)
353 hprime(i,j,14)= elvmax(i,j)
359 call minmax(im,jm,elvmax,
'ELVMAX ',itest,jtest)
360 call minmax(im,jm,oro,
'ORO ')
362 print *,
'- ORO(itest,jtest),itest,jtest:', &
363 oro(itest,jtest),itest,jtest
364 print *,
'- ELVMAX(',itest,jtest,
')=',elvmax(itest,jtest)
367 print*,
"- TIMING: FINAL QUALITY CONTROL ", tend-tbeg
369 allocate(xlat(jm), xlon(im))
371 xlat(j) = geolat(1,j)
374 xlon(i) = geolon(i,1)
379 geolon(1:im,1:jm),geolat(1:im,1:jm), xlon,xlat)
381 print*,
"- TIMING: WRITE OUTPUT FILE ", tend-tbeg
383 deallocate(xlat,xlon)
384 deallocate (geolon,geolon_c,geolat,geolat_c)
385 deallocate (slm,oro,var,land_frac)
386 deallocate (theta,gamma,sigma,elvmax,hprime)
389 print*,
"- TIMING: TOTAL RUNTIME ", tend-tbeg1
407 SUBROUTINE make_mask(zslm,slm,land_frac, &
408 im,jm,imn,jmn,lon_c,lat_c)
414 integer,
intent(in) :: zslm(imn,jmn)
415 integer,
intent(in) :: im, jm, imn, jmn
417 real,
intent(in) :: lon_c(im+1,jm+1), lat_c(im+1,jm+1)
419 real,
intent(out) :: slm(im,jm)
420 real,
intent(out) :: land_frac(im,jm)
422 real,
parameter :: D2R = 3.14159265358979/180.
425 real GLAT(JMN), GLON(IMN)
426 real LONO(4),LATO(4),LONI,LATI
427 real LONO_RAD(4), LATO_RAD(4)
428 integer JM1,i,j,ii,jj,numx,i2
430 real DELXN,XNSUM,XLAND,XWATR,XL1,XS1,XW1
431 real XNSUM_ALL,XLAND_ALL,XWATR_ALL
433 print *,
'- CREATE LANDMASK AND LAND FRACTION.' 440 glat(j) = -90. + (j-1) * delxn + delxn * 0.5
443 glon(i) = 0. + (i-1) * delxn + delxn * 0.5
466 lono(2) = lon_c(i+1,j)
467 lono(3) = lon_c(i+1,j+1)
468 lono(4) = lon_c(i,j+1)
470 lato(2) = lat_c(i+1,j)
471 lato(3) = lat_c(i+1,j+1)
472 lato(4) = lat_c(i,j+1)
475 call get_index(imn,jmn,4,lono,lato,delxn,jst,jen,ilist,numx)
476 do jj = jst, jen;
do i2 = 1, numx
479 lati = -90 + jj*delxn
481 xland_all = xland_all + float(zslm(ii,jj))
482 xwatr_all = xwatr_all + float(1-zslm(ii,jj))
483 xnsum_all = xnsum_all + 1.
486 lono_rad,lato_rad))
then 488 xland = xland + float(zslm(ii,jj))
489 xwatr = xwatr + float(1-zslm(ii,jj))
496 land_frac(i,j) = xland/xnsum
497 slm(i,j) = float(nint(xland/xnsum))
498 ELSEIF(xnsum_all.GT.1.)
THEN 499 land_frac(i,j) = xland_all/xnsum_all
500 slm(i,j) = float(nint(xland_all/xnsum_all))
502 print*,
"FATAL ERROR: no source points in MAKE_MASK." 529 SUBROUTINE makemt2(ZAVG,ZSLM,ORO,SLM,VAR,VAR4, &
530 IM,JM,IMN,JMN,lon_c,lat_c,lake_frac,land_frac)
536 integer,
intent(in) :: zavg(imn,jmn),zslm(imn,jmn)
537 integer,
intent(in) :: im, jm, imn, jmn
539 real,
intent(in) :: slm(im,jm)
540 real,
intent(in) :: lake_frac(im,jm),land_frac(im,jm)
541 real,
intent(in) :: lon_c(im+1,jm+1), lat_c(im+1,jm+1)
543 real,
intent(out) :: oro(im,jm)
544 real,
intent(out) :: var(im,jm),var4(im,jm)
546 real,
parameter :: D2R = 3.14159265358979/180.
548 real,
dimension(:),
allocatable :: hgt_1d, hgt_1d_all
550 real GLAT(JMN), GLON(IMN)
551 integer JST, JEN, maxsum
552 real LONO(4),LATO(4),LONI,LATI
553 real LONO_RAD(4), LATO_RAD(4)
555 integer JM1,i,j,nsum,nsum_all,ii,jj,i1,numx,i2
557 real DELXN,XNSUM,XLAND,XWATR,XL1,XS1,XW1,XW2,XW4
558 real XNSUM_ALL,XLAND_ALL,XWATR_ALL,HEIGHT_ALL
559 real XL1_ALL,XS1_ALL,XW1_ALL,XW2_ALL,XW4_ALL
561 print*,
'- CREATE OROGRAPHY AND CONVEXITY.' 568 glat(j) = -90. + (j-1) * delxn + delxn * 0.5
571 glon(i) = 0. + (i-1) * delxn + delxn * 0.5
578 lono(2) = lon_c(i+1,j)
579 lono(3) = lon_c(i+1,j+1)
580 lono(4) = lon_c(i,j+1)
582 lato(2) = lat_c(i+1,j)
583 lato(3) = lat_c(i+1,j+1)
584 lato(4) = lat_c(i,j+1)
585 call get_index(imn,jmn,4,lono,lato,delxn,jst,jen,ilist,numx)
586 maxsum=max(maxsum,(jen-jst+1)*imn)
589 print*,
"- MAXSUM IS ", maxsum
590 allocate(hgt_1d(maxsum))
591 allocate(hgt_1d_all(maxsum))
628 lono(2) = lon_c(i+1,j)
629 lono(3) = lon_c(i+1,j+1)
630 lono(4) = lon_c(i,j+1)
632 lato(2) = lat_c(i+1,j)
633 lato(3) = lat_c(i+1,j+1)
634 lato(4) = lat_c(i,j+1)
637 call get_index(imn,jmn,4,lono,lato,delxn,jst,jen,ilist,numx)
638 do jj = jst, jen;
do i2 = 1, numx
641 lati = -90 + jj*delxn
643 xland_all = xland_all + float(zslm(ii,jj))
644 xwatr_all = xwatr_all + float(1-zslm(ii,jj))
645 xnsum_all = xnsum_all + 1.
646 height_all = float(zavg(ii,jj))
647 nsum_all = nsum_all+1
648 if(nsum_all > maxsum)
then 649 print*,
"FATAL ERROR: nsum_all is greater than MAXSUM," 650 print*,
"increase MAXSUM.", jst,jen
653 hgt_1d_all(nsum_all) = height_all
654 IF(height_all.LT.-990.) height_all = 0.0
655 xl1_all = xl1_all + height_all * float(zslm(ii,jj))
656 xs1_all = xs1_all + height_all * float(1-zslm(ii,jj))
657 xw1_all = xw1_all + height_all
658 xw2_all = xw2_all + height_all ** 2
662 xland = xland + float(zslm(ii,jj))
663 xwatr = xwatr + float(1-zslm(ii,jj))
665 height = float(zavg(ii,jj))
667 if(nsum > maxsum)
then 668 print*,
"FATAL ERROR: nsum is greater than MAXSUM," 669 print*,
"increase MAXSUM.", jst,jen
672 hgt_1d(nsum) = height
673 IF(height.LT.-990.) height = 0.0
674 xl1 = xl1 + height * float(zslm(ii,jj))
675 xs1 = xs1 + height * float(1-zslm(ii,jj))
677 xw2 = xw2 + height ** 2
682 IF(slm(i,j) .NE. 0. .OR. land_frac(i,j) > 0.)
THEN 684 oro(i,j)= xl1 / xland
686 oro(i,j)= xs1 / xwatr
690 oro(i,j)= xs1 / xwatr
692 oro(i,j)= xl1 / xland
696 var(i,j)=sqrt(max(xw2/xnsum-(xw1/xnsum)**2,0.))
698 xw4 = xw4 + (hgt_1d(i1) - oro(i,j)) ** 4
701 IF(var(i,j).GT.1.)
THEN 702 var4(i,j) = min(xw4/xnsum/var(i,j) **4,10.)
705 ELSEIF(xnsum_all.GT.1.)
THEN 708 IF(slm(i,j) .NE. 0. .OR. land_frac(i,j) > 0.)
THEN 709 IF (xland_all > 0)
THEN 710 oro(i,j)= xl1_all / xland_all
712 oro(i,j)= xs1_all / xwatr_all
715 IF (xwatr_all > 0)
THEN 716 oro(i,j)= xs1_all / xwatr_all
718 oro(i,j)= xl1_all / xland_all
722 var(i,j)=sqrt(max(xw2_all/xnsum_all-(xw1_all/xnsum_all)**2,0.))
724 xw4_all = xw4_all + (hgt_1d_all(i1) - oro(i,j)) ** 4
727 IF(var(i,j).GT.1.)
THEN 728 var4(i,j) = min(xw4_all/xnsum_all/var(i,j) **4,10.)
731 print*,
"FATAL ERROR: no source points in MAKEMT2." 737 IF (lake_frac(i,j) .EQ. 0. .AND. land_frac(i,j) .EQ. 0.)
THEN 746 deallocate(hgt_1d_all)
768 SUBROUTINE makepc2(ZAVG,ZSLM,THETA,GAMMA,SIGMA, &
769 IM,JM,IMN,JMN,lon_c,lat_c,SLM)
777 integer,
intent(in) :: zavg(imn,jmn),zslm(imn,jmn)
778 integer,
intent(in) :: im,jm,imn,jmn
780 real,
intent(in) :: lon_c(im+1,jm+1), lat_c(im+1,jm+1)
781 real,
intent(in) :: slm(im,jm)
783 real,
intent(out) :: theta(im,jm), gamma(im,jm), sigma(im,jm)
785 real,
parameter :: REARTH=6.3712e+6
786 real,
parameter :: D2R = 3.14159265358979/180.
788 real GLAT(JMN),DELTAX(JMN)
789 real HL(IM,JM),HK(IM,JM)
790 real HX2(IM,JM),HY2(IM,JM),HXY(IM,JM),HLPRIM(IM,JM)
792 real PI,CERTH,DELXN,DELTAY,XNSUM,XLAND
793 real xfp,yfp,xfpyfp,xfp2,yfp2
794 real hi0,hip1,hj0,hjp1,hijax,hi1j1
795 real LONO(4),LATO(4),LONI,LATI
796 real LONO_RAD(4), LATO_RAD(4)
797 integer i,j,i1,j1,i2,jst,jen,numx,i0,ip1,ijax
803 print*,
"- CREATE PRINCIPLE COORDINATES." 809 deltay = certh / float(jmn)
812 glat(j) = -90. + (j-1) * delxn + delxn * 0.5
813 deltax(j) = deltay * cos(glat(j)*d2r)
847 lono(2) = lon_c(i+1,j)
848 lono(3) = lon_c(i+1,j+1)
849 lono(4) = lon_c(i,j+1)
851 lato(2) = lat_c(i+1,j)
852 lato(3) = lat_c(i+1,j+1)
853 lato(4) = lat_c(i,j+1)
856 call get_index(imn,jmn,4,lono,lato,delxn,jst,jen,ilist,numx)
858 do j1 = jst, jen;
do i2 = 1, numx
861 lati = -90 + j1*delxn
863 lono_rad,lato_rad))
then 868 if (i1 - 1 .le. 0 ) i0 = i0 + imn
869 if (i1 - 1 .gt. imn) i0 = i0 - imn
872 if (i1 + 1 .le. 0 ) ip1 = ip1 + imn
873 if (i1 + 1 .gt. imn) ip1 = ip1 - imn
875 xland = xland + float(zslm(i1,j1))
878 hi0 = float(zavg(i0,j1))
879 hip1 = float(zavg(ip1,j1))
881 if(hi0 .lt. -990.) hi0 = 0.0
882 if(hip1 .lt. -990.) hip1 = 0.0
884 xfp = 0.5 * ( hip1 - hi0 ) / deltax(j1)
885 xfp2 = xfp2 + 0.25 * ( ( hip1 - hi0 )/deltax(j1) )** 2
889 if ( j1 .ne. 1 .and. j1 .ne. jmn )
then 890 hj0 = float(zavg(i1,j1-1))
891 hjp1 = float(zavg(i1,j1+1))
892 if(hj0 .lt. -990.) hj0 = 0.0
893 if(hjp1 .lt. -990.) hjp1 = 0.0
895 yfp = 0.5 * ( hjp1 - hj0 ) / deltay
896 yfp2 = yfp2 + 0.25 * ( ( hjp1 - hj0 )/deltay )**2
902 elseif ( j1 .eq. 1 )
then 904 if (ijax .le. 0 ) ijax = ijax + imn
905 if (ijax .gt. imn) ijax = ijax - imn
907 hijax = float(zavg(ijax,j1))
908 hi1j1 = float(zavg(i1,j1))
909 if(hijax .lt. -990.) hijax = 0.0
910 if(hi1j1 .lt. -990.) hi1j1 = 0.0
912 yfp = 0.5 * ( ( 0.5 * ( hijax - hi1j1 ) ) )/deltay
913 yfp2 = yfp2 + 0.25 * ( ( 0.5 * ( hijax - hi1j1) ) / deltay )**2
917 elseif ( j1 .eq. jmn )
then 919 if (ijax .le. 0 ) ijax = ijax + imn
920 if (ijax .gt. imn) ijax = ijax - imn
921 hijax = float(zavg(ijax,j1))
922 hi1j1 = float(zavg(i1,j1))
923 if(hijax .lt. -990.) hijax = 0.0
924 if(hi1j1 .lt. -990.) hi1j1 = 0.0
926 yfp = 0.5 * (0.5 * ( hijax - hi1j1) )/deltay
927 yfp2 = yfp2 + 0.25 * ( (0.5 * (hijax - hi1j1) ) / deltay )**2
932 xfpyfp = xfpyfp + xfp * yfp
943 xnsum_gt_1 :
IF(xnsum.GT.1.)
THEN 944 IF(slm(i,j).NE.0.)
THEN 946 hx2(i,j) = xfp2 / xland
947 hy2(i,j) = yfp2 / xland
948 hxy(i,j) = xfpyfp / xland
950 hx2(i,j) = xfp2 / xnsum
951 hy2(i,j) = yfp2 / xnsum
952 hxy(i,j) = xfpyfp / xnsum
957 print *,
" I,J,i1,j1:", i,j,i1,j1,xland,slm(i,j)
958 print *,
" xfpyfp,xfp2,yfp2:",xfpyfp,xfp2,yfp2
959 print *,
" HX2,HY2,HXY:",hx2(i,j),hy2(i,j),hxy(i,j)
965 hk(i,j) = 0.5 * ( hx2(i,j) + hy2(i,j) )
966 hl(i,j) = 0.5 * ( hx2(i,j) - hy2(i,j) )
967 hlprim(i,j) = sqrt(hl(i,j)*hl(i,j) + hxy(i,j)*hxy(i,j))
968 IF( hl(i,j).NE. 0. .AND. slm(i,j) .NE. 0. )
THEN 970 theta(i,j) = 0.5 * atan2(hxy(i,j),hl(i,j)) / d2r
974 sigma2(i,j) = ( hk(i,j) + hlprim(i,j) )
975 if ( sigma2(i,j) .GE. 0. )
then 976 sigma(i,j) = sqrt(sigma2(i,j) )
977 if (sigma2(i,j) .ne. 0. .and. &
978 hk(i,j) .GE. hlprim(i,j) ) &
979 gamma(i,j) = sqrt( (hk(i,j) - hlprim(i,j)) / sigma2(i,j) )
985 print *,
" I,J,THETA,SIGMA,GAMMA,",i,j,theta(i,j),sigma(i,j),gamma(i,j)
986 print *,
" HK,HL,HLPRIM:",hk(i,j),hl(i,j),hlprim(i,j)
1023 SUBROUTINE makeoa2(ZAVG,zslm,VAR,OA4,OL,ELVMAX,ORO,&
1024 IM,JM,IMN,JMN,lon_c,lat_c,lon_t,lat_t,dx,dy, &
1025 is_south_pole,is_north_pole )
1034 integer,
intent(in) :: im,jm,imn,jmn
1035 integer,
intent(in) :: zavg(imn,jmn),zslm(imn,jmn)
1037 logical,
intent(in) :: is_south_pole(im,jm), is_north_pole(im,jm)
1039 real,
intent(in) :: dx(im,jm), dy(im,jm)
1040 real,
intent(in) :: lon_c(im+1,jm+1), lat_c(im+1,jm+1)
1041 real,
intent(in) :: lon_t(im,jm), lat_t(im,jm)
1042 real,
intent(in) :: oro(im,jm), var(im,jm)
1044 real,
intent(out) :: ol(im,jm,4),oa4(im,jm,4)
1045 real,
intent(out) :: elvmax(im,jm)
1047 real,
parameter :: MISSING_VALUE = -9999.
1048 real,
parameter :: D2R = 3.14159265358979/180.
1050 integer :: i,j,ilist(imn),numx,i1,j1,ii1
1051 integer :: jst, jen, kwd
1055 real :: lono(4),lato(4),loni,lati
1056 real :: lono_rad(4), lato_rad(4)
1057 real :: delxn,hc,height,xnpu,xnpd,t
1058 real :: lon,lat,dlon,dlat,dlat_old
1059 real :: lon1,lat1,lon2,lat2
1060 real :: xnsum11,xnsum12,xnsum21,xnsum22
1061 real :: hc_11, hc_12, hc_21, hc_22
1062 real :: xnsum1_11,xnsum1_12,xnsum1_21,xnsum1_22
1063 real :: xnsum2_11,xnsum2_12,xnsum2_21,xnsum2_22
1065 print*,
"- CREATE ASYMETRY AND LENGTH SCALE." 1072 glat(j) = -90. + (j-1) * delxn + delxn * 0.5
1074 print*,
'- IM=',im,
' JM=',jm,
' IMN=',imn,
' JMN=',jmn
1080 elvmax(i,j) = oro(i,j)
1084 elvmax(i,j) = zmax(i,j)
1095 hc = 1116.2 - 0.878 * var(i,j)
1096 lono(1) = lon_c(i,j)
1097 lono(2) = lon_c(i+1,j)
1098 lono(3) = lon_c(i+1,j+1)
1099 lono(4) = lon_c(i,j+1)
1100 lato(1) = lat_c(i,j)
1101 lato(2) = lat_c(i+1,j)
1102 lato(3) = lat_c(i+1,j+1)
1103 lato(4) = lat_c(i,j+1)
1104 lono_rad = lono * d2r
1105 lato_rad = lato * d2r
1106 call get_index(imn,jmn,4,lono,lato,delxn,jst,jen,ilist,numx)
1107 do j1 = jst, jen;
do ii1 = 1, numx
1110 lati = -90 + j1*delxn
1112 lono_rad,lato_rad))
then 1114 height = float(zavg(i1,j1))
1115 IF(height.LT.-990.) height = 0.0
1116 IF ( height .gt. oro(i,j) )
then 1117 if ( height .gt. zmax(i,j) )zmax(i,j) = height
1127 elvmax(i,j) = zmax(i,j)
1159 if(is_north_pole(i,j))
then 1160 print*,
"- SET OA1 = 0 AND OL=0 AT I,J=", i,j
1165 else if(is_south_pole(i,j))
then 1166 print*,
"- SET OA1 = 0 AND OL=1 AT I,J=", i,j
1177 if( lat-dlat*0.5<-90.)
then 1178 print*,
"- AT I,J =", i,j, lat, dlat, lat-dlat*0.5
1179 print*,
"FATAL ERROR: lat-dlat*0.5<-90." 1182 if( lat+dlat*2 > 90.)
then 1185 print*,
"- AT I,J=",i,j,
" ADJUST DLAT FROM ", &
1186 dlat_old,
" TO ", dlat
1194 if(lat1<-90 .or. lat2>90)
then 1195 print*,
"- AT UPPER LEFT I=,J=", i, j, lat, dlat,lat1,lat2
1197 xnsum11 =
get_xnsum(lon1,lat1,lon2,lat2,imn,jmn,glat, &
1205 if(lat1<-90 .or. lat2>90)
then 1206 print*,
"- AT LOWER LEFT I=,J=", i, j, lat, dlat,lat1,lat2
1208 xnsum12 =
get_xnsum(lon1,lat1,lon2,lat2,imn,jmn,glat, &
1216 if(lat1<-90 .or. lat2>90)
then 1217 print*,
"- AT UPPER RIGHT I=,J=", i, j, lat, dlat,lat1,lat2
1219 xnsum21 =
get_xnsum(lon1,lat1,lon2,lat2,imn,jmn,glat, &
1227 if(lat1<-90 .or. lat2>90)
then 1228 print*,
"- AT LOWER RIGHT I=,J=", i, j, lat, dlat,lat1,lat2
1231 xnsum22 =
get_xnsum(lon1,lat1,lon2,lat2,imn,jmn,glat, &
1234 xnpu = xnsum11 + xnsum12
1235 xnpd = xnsum21 + xnsum22
1236 IF (xnpd .NE. xnpu) oa4(i,j,1) = 1. - xnpd / max(xnpu , 1.)
1238 xnpu = xnsum11 + xnsum21
1239 xnpd = xnsum12 + xnsum22
1240 IF (xnpd .NE. xnpu) oa4(i,j,2) = 1. - xnpd / max(xnpu , 1.)
1242 xnpu = xnsum11 + (xnsum12+xnsum21)*0.5
1243 xnpd = xnsum22 + (xnsum12+xnsum21)*0.5
1244 IF (xnpd .NE. xnpu) oa4(i,j,3) = 1. - xnpd / max(xnpu , 1.)
1246 xnpu = xnsum12 + (xnsum11+xnsum22)*0.5
1247 xnpd = xnsum21 + (xnsum11+xnsum22)*0.5
1248 IF (xnpd .NE. xnpu) oa4(i,j,4) = 1. - xnpd / max(xnpu , 1.)
1257 if(lat1<-90 .or. lat2>90)
then 1258 print*,
"- AT UPPER LEFT I=,J=", i, j, lat, dlat,lat1,lat2
1260 call get_xnsum2(lon1,lat1,lon2,lat2,imn,jmn,glat, &
1261 zavg,delxn, xnsum1_11, xnsum2_11, hc_11)
1268 if(lat1<-90 .or. lat2>90)
then 1269 print*,
"- AT LOWER LEFT I=,J=", i, j, lat, dlat,lat1,lat2
1271 call get_xnsum2(lon1,lat1,lon2,lat2,imn,jmn,glat, &
1272 zavg,delxn, xnsum1_12, xnsum2_12, hc_12)
1279 if(lat1<-90 .or. lat2>90)
then 1280 print*,
"- AT UPPER RIGHT I=,J=", i, j, lat, dlat,lat1,lat2
1282 call get_xnsum2(lon1,lat1,lon2,lat2,imn,jmn,glat, &
1283 zavg,delxn, xnsum1_21, xnsum2_21, hc_21)
1290 if(lat1<-90 .or. lat2>90)
then 1291 print*,
"- AT LOWER RIGHT I=,J=", i, j, lat, dlat,lat1,lat2
1293 call get_xnsum2(lon1,lat1,lon2,lat2,imn,jmn,glat, &
1294 zavg,delxn, xnsum1_22, xnsum2_22, hc_22)
1296 ol(i,j,3) = (xnsum1_22+xnsum1_11)/(xnsum2_22+xnsum2_11)
1297 ol(i,j,4) = (xnsum1_12+xnsum1_21)/(xnsum2_12+xnsum2_21)
1305 if(lat1<-90 .or. lat2>90)
then 1306 print*,
"- AT UPPER LEFT I=,J=", i, j, lat, dlat,lat1,lat2
1308 call get_xnsum3(lon1,lat1,lon2,lat2,imn,jmn,glat, &
1309 zavg,delxn, xnsum1_11, xnsum2_11, hc_11)
1316 if(lat1<-90 .or. lat2>90)
then 1317 print*,
"- AT LOWER LEFT I=,J=", i, j, lat, dlat,lat1,lat2
1320 call get_xnsum3(lon1,lat1,lon2,lat2,imn,jmn,glat, &
1321 zavg,delxn, xnsum1_12, xnsum2_12, hc_12)
1328 if(lat1<-90 .or. lat2>90)
then 1329 print*,
"- AT UPPER RIGHT I=,J=", i, j, lat, dlat,lat1,lat2
1331 call get_xnsum3(lon1,lat1,lon2,lat2,imn,jmn,glat, &
1332 zavg,delxn, xnsum1_21, xnsum2_21, hc_21)
1339 if(lat1<-90 .or. lat2>90)
then 1340 print*,
"- AT LOWER RIGHT I=,J=", i, j, lat, dlat,lat1,lat2
1343 call get_xnsum3(lon1,lat1,lon2,lat2,imn,jmn,glat, &
1344 zavg,delxn, xnsum1_22, xnsum2_22, hc_22)
1346 ol(i,j,1) = (xnsum1_11+xnsum1_21)/(xnsum2_11+xnsum2_21)
1347 ol(i,j,2) = (xnsum1_21+xnsum1_22)/(xnsum2_21+xnsum2_22)
1356 oa4(i,j,kwd) = sign( min( abs(t), 1. ), t )
subroutine, public minmax(im, jm, a, title, imax, jmax)
Print out the maximum and minimum values of an array and optionally pass back the i/j location of the...
subroutine tersub(IM, JM, EFAC, OUTGRID, MASK_ONLY, EXTERNAL_MASK_FILE)
Driver routine to compute terrain.
subroutine makemt2(ZAVG, ZSLM, ORO, SLM, VAR, VAR4, IM, JM, IMN, JMN, lon_c, lat_c, lake_frac, land_frac)
Create the orography, standard deviation of orography and the convexity on a model tile...
subroutine, public 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 makeoa2(ZAVG, zslm, VAR, OA4, OL, ELVMAX, ORO, 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, public qc_orog_by_ramp(imn, jmn, zavg, zslm)
Quality control the global orography and landmask data over Antarctica using RAMP data...
real function, public 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, public read_mdl_grid_file(mdl_grid_file, im, jm, geolon, geolon_c, geolat, geolat_c, dx, dy, is_north_pole, is_south_pole)
Read the grid dimensions from the model 'grid' file.
Module containing utilities that read and write data.
subroutine, public 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...
logical function, public inside_a_polygon(lon1, lat1, npts, lon2, lat2)
Check if a point is inside a polygon.
subroutine, public read_global_orog(imn, jmn, glob)
Read input global 30-arc second orography data.
subroutine, public read_mdl_dims(mdl_grid_file, im, jm)
Read the grid dimensions from the model 'grid' file.
subroutine, public read_global_mask(imn, jmn, mask)
Read input global 30-arc second land mask data.
real function, public get_lat_angle(dy)
Convert the 'y' direction distance of a cubed-sphere grid point to the corresponding distance in lati...
subroutine makepc2(ZAVG, ZSLM, THETA, GAMMA, SIGMA, IM, JM, IMN, JMN, lon_c, lat_c, SLM)
Make the principle coordinates - slope of orography, anisotropy, angle of mountain range with respect...
subroutine, public remove_isolated_pts(im, jm, slm, oro, var, var4, oa, ol)
Remove isolated model points.
Module containing utilites used by the orog program.
subroutine, public 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...
subroutine make_mask(zslm, slm, land_frac, im, jm, imn, jmn, lon_c, lat_c)
Create the land-mask, land fraction.
subroutine, public write_netcdf(im, jm, slm, land_frac, oro, hprime, ntiles, tile, geolon, geolat, lon, lat)
Write out orography file in netcdf format.
real function, public timef()
Get the date/time from the system clock.
real function, public get_lon_angle(dx, lat_in)
Convert the 'x' direction distance of a cubed-sphere grid point to the corresponding distance in long...
subroutine, public read_mask(merge_file, slm, land_frac, lake_frac, im, jm)
Read the land mask file.
subroutine, public write_mask_netcdf(im, jm, slm, land_frac, ntiles, tile, geolon, geolat)
Write the land mask file.