8 integer, parameter :: MAX_DOMAINS = 21
11 integer :: iproj_type, n_domains, io_form_output, dyn_opt
12 integer :: i, j, max_dom, funit, io_form_geogrid
13 integer :: interval_seconds
15 integer, dimension(MAX_DOMAINS) :: parent_grid_ratio, parent_id, ixdim, jydim
16 integer, dimension(MAX_DOMAINS) :: i_parent_start, j_parent_start, &
17 s_we, e_we, s_sn, e_sn, &
18 start_year, start_month, start_day, start_hour, &
19 end_year, end_month, end_day, end_hour
20 logical, dimension(MAX_DOMAINS) :: active_grid
22 real :: known_lat, known_lon, stand_lon, truelat1, truelat2, known_x, known_y, &
23 dxkm, dykm, ref_lat, ref_lon, ref_x, ref_y
25 real :: ri, rj, rlats, rlons, rlate, rlone
27 real :: rparent_gridpts
28 real :: xa,xb,ya,yb,xxa,xxy,yya,yyb
29 real :: xs, xe, ys, ye
30 integer :: jproj, jgrid, jlts, iusout, idot, ier
31 integer :: ltype , idom
33 real, dimension(MAX_DOMAINS) :: parent_ll_x, parent_ll_y, parent_ur_x, parent_ur_y
35 character (len=128) :: geog_data_path, opt_output_from_geogrid_path, opt_geogrid_tbl_path
36 character (len=128), dimension(MAX_DOMAINS) :: geog_data_res
37 character (len=128) :: map_proj
38 character (len=128), dimension(MAX_DOMAINS) :: start_date, end_date
39 character (len=3) :: wrf_core
40 character (len=1) :: gridtype
42 logical :: do_tiled_output
43 integer :: debug_level
48 type (proj_info) :: map_projection
50 namelist /share/ wrf_core, max_dom, start_date, end_date, &
51 start_year, end_year, start_month, end_month, &
52 start_day, end_day, start_hour, end_hour, &
53 interval_seconds, io_form_geogrid, opt_output_from_geogrid_path, &
54 debug_level, active_grid, nocolons
55 namelist /geogrid/ parent_id, parent_grid_ratio, &
56 i_parent_start, j_parent_start, s_we, e_we, s_sn, e_sn, &
57 map_proj, ref_x, ref_y, ref_lat, ref_lon, &
58 truelat1, truelat2, stand_lon, dx, dy, &
59 geog_data_res, geog_data_path, opt_geogrid_tbl_path
61 ! Set defaults for namelist variables
66 geog_data_path = 'NOT_SPECIFIED'
78 geog_data_res(i) = 'default'
80 parent_grid_ratio(i) = INVALID
93 start_date(i) = '0000-00-00_00:00:00'
94 end_date(i) = '0000-00-00_00:00:00'
96 opt_output_from_geogrid_path = './'
97 opt_geogrid_tbl_path = 'geogrid/'
98 interval_seconds = INVALID
100 ! Read parameters from Fortran namelist
102 inquire(unit=funit, opened=is_used)
103 if (.not. is_used) exit
105 open(funit,file='namelist.wps',status='old',form='formatted',err=1000)
118 ! Convert wrf_core to uppercase letters
120 if (ichar(wrf_core(i:i)) >= 97) wrf_core(i:i) = char(ichar(wrf_core(i:i))-32)
123 ! Before doing anything else, we must have a valid grid type
125 if (wrf_core == 'ARW') then
128 else if (wrf_core == 'NMM') then
133 if (gridtype /= 'C' .and. gridtype /= 'E') then
134 write(6,*) 'A valid wrf_core must be specified in the namelist. '// &
135 'Currently, only "ARW" and "NMM" are supported.'
139 if (max_dom > MAX_DOMAINS) then
140 write(6,*) 'In namelist, max_dom must be <= ',MAX_DOMAINS,'. To run with more'// &
141 ' than ',MAX_DOMAINS,' domains, increase the MAX_DOMAINS parameter.'
145 ! Every domain must have a valid parent id
147 if (parent_id(i) <= 0 .or. parent_id(i) >= i) then
148 write(6,*) 'In namelist, the parent_id of domain ',i,' must be in '// &
149 'the range 1 to ',i-1
154 ! Convert map_proj to uppercase letters
156 if (ichar(map_proj(i:i)) >= 97) map_proj(i:i) = char(ichar(map_proj(i:i))-32)
159 ! Assign parameters to module variables
160 if ((index(map_proj, 'LAMBERT') /= 0) .and. &
161 (len_trim(map_proj) == len('LAMBERT'))) then
167 else if ((index(map_proj, 'MERCATOR') /= 0) .and. &
168 (len_trim(map_proj) == len('MERCATOR'))) then
169 iproj_type = PROJ_MERC
174 else if ((index(map_proj, 'POLAR') /= 0) .and. &
175 (len_trim(map_proj) == len('POLAR'))) then
178 polat=SIGN(90., ref_lat)
181 else if ((index(map_proj, 'ROTATED_LL') /= 0) .and. &
182 (len_trim(map_proj) == len('ROTATED_LL'))) then
183 iproj_type = PROJ_ROTLL
186 write(6,*) 'In namelist, invalid map_proj specified. Valid '// &
187 'projections are "lambert", "mercator", "polar", '// &
195 ixdim(i) = e_we(i) - s_we(i) + 1
196 jydim(i) = e_sn(i) - s_sn(i) + 1
199 ! If the user hasn't supplied a known_x and known_y, assume the center of domain 1
200 if (known_x == NAN) known_x = ixdim(1) / 2.
201 if (known_y == NAN) known_y = jydim(1) / 2.
203 ! Checks specific to C grid
204 if (gridtype == 'C') then
206 ! C grid does not support the rotated lat/lon projection
207 if (iproj_type == PROJ_ROTLL) then
208 write(6,*) 'Rotated lat/lon projection is not supported for the ARW core. '// &
209 'Valid projecitons are "lambert", "mercator", and "polar".'
213 ! Check that nests have an acceptable number of grid points in each dimension
215 rparent_gridpts = real(ixdim(i)-1)/real(parent_grid_ratio(i))
216 if (floor(rparent_gridpts) /= ceiling(rparent_gridpts)) then
217 write(6,*) 'For nest ',i,' (e_we-s_we+1) must be one greater than an '// &
218 'integer multiple of the parent_grid_ratio.'
219 write(6,*) 'Current values are s_we(i) = ',s_we(i),' e_we(i) = ',e_we(i)
220 isize = nint(real(ixdim(i)-1)/real(parent_grid_ratio(i)))
221 write(6,*) 'An e_we = ',isize * parent_grid_ratio(i) + 1,' might work'
224 rparent_gridpts = real(jydim(i)-1)/real(parent_grid_ratio(i))
225 if (floor(rparent_gridpts) /= ceiling(rparent_gridpts)) then
226 write(6,*) 'For nest ',i,' (e_sn-s_sn+1) must be one greater than an '// &
227 'integer multiple of the parent_grid_ratio.'
228 write(6,*) ' Current values are, s_sn(i) = ',s_sn(i),' e_sn(i) = ',e_sn(i)
229 isize = nint(real(jydim(i)-1)/real(parent_grid_ratio(i)))
230 write(6,*) 'An e_sn = ',isize * parent_grid_ratio(i) + 1,' might work'
236 ! Checks specific to E grid
237 if (gridtype == 'E') then
239 ! E grid supports only the rotated lat/lon projection
240 if (iproj_type /= PROJ_ROTLL) then
241 write(6,*) 'Rotated lat/lon is the only supported projection for the NMM core.'
245 ! Check that the parent_grid_ratio is set to 3 for all nests
247 if (parent_grid_ratio(i) /= 3) then
248 write(6,*) 'The parent_grid_ratio must be set to 3 for the NMM core.'
253 CALL plot_e_grid ( ref_lat , -1. * ref_lon , &
257 parent_id , parent_grid_ratio , &
258 i_parent_start , j_parent_start )
263 parent_ll_x(i) = real(i_parent_start(i))
264 parent_ll_y(i) = real(j_parent_start(i))
265 parent_ur_x(i) = real(i_parent_start(i))+real(ixdim(i))/real(parent_grid_ratio(i))-1.
266 parent_ur_y(i) = real(j_parent_start(i))+real(jydim(i))/real(parent_grid_ratio(i))-1.
269 call map_init(map_projection)
271 call map_set(iproj_type, map_projection, &
283 call ij_to_latlon(map_projection, 0.5, 0.5, rlats, rlons)
284 call ij_to_latlon(map_projection, real(e_we(1))-0.5, real(e_sn(1))-0.5, rlate, rlone)
289 call gscr(1, 0, 1.00, 1.00, 1.00)
290 call gscr(1, 1, 0.00, 0.00, 0.00)
292 ! Do not grind them with details
298 call supmap(jproj,polat,stand_lon,rot,&
299 rlats,rlons,rlate,rlone, &
300 jlts,jgrid,iusout,idot,ier)
302 call setusv('LW',1000)
303 call perim(e_we(1)-1,1,e_sn(1)-1,1)
304 call getset(xa,xb,ya,yb,xxa,xxy,yya,yyb,ltype)
305 call set (xa,xb,ya,yb, &
306 1.,real(e_we(1)),1.,real(e_sn(1)),ltype)
308 do idom = 2 , max_dom
309 call getxy ( xs, xe, ys, ye, &
312 parent_id , parent_grid_ratio , &
313 i_parent_start , j_parent_start )
314 call line ( xs , ys , xe , ys )
315 call line ( xe , ys , xe , ye )
316 call line ( xe , ye , xs , ye )
317 call line ( xs , ye , xs , ys )
323 write(6,*) 'Creating plot in NCAR Graphics metafile...'
328 write(6,*) ' *** Successful completion of program plotgrids.exe *** '
333 1000 write(6,*) 'Error opening namelist.wps'
336 end program plotgrids
338 subroutine getxy ( xs, xe, ys, ye, &
339 dom_id , num_domains , &
341 parent_id , parent_grid_ratio , &
342 i_parent_start , j_parent_start )
346 integer , intent(in) :: dom_id
347 integer , intent(in) :: num_domains
348 integer , intent(in) , dimension(num_domains):: e_we , e_sn , &
349 parent_id , parent_grid_ratio , &
350 i_parent_start , j_parent_start
351 real , intent(out) :: xs, xe, ys, ye
366 xs = (i_parent_start(idom) + xs -1 ) / &
367 real(parent_grid_ratio(parent_id(idom)))
368 xe = xe / real(parent_grid_ratio(idom))
370 ys = (j_parent_start(idom) + ys -1 ) / &
371 real(parent_grid_ratio(parent_id(idom)))
372 ye = ye / real(parent_grid_ratio(idom))
374 idom = parent_id(idom)
375 if ( idom .EQ. 1 ) then
388 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
389 !!!!!! E GRID MAP INFO BELOW !!!!!!!!!!!!!!
390 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
392 SUBROUTINE plot_e_grid ( rlat0d , rlon0d , dphd , dlmd, &
395 parent_id , parent_grid_ratio , &
396 i_parent_start , j_parent_start )
398 ! This routine generates a gmeta file of the area covered by an Arakawa e-grid.
399 ! We assume that NCAR Graphics has not been called yet (and will be closed
400 ! upon exit). The required input fields are as from the WPS namelist file.
404 ! 15 April 2005 NCEP/EMC
405 ! The Code and some instructions are provided by Tom BLACK to
406 ! NCAR/DTC Meral Demirtas
408 ! 4 May 2005 NCAR/DTC Meral DEMIRTAS
409 ! - An include file (plot_inc) is added to get
411 ! Central latitute and longnitute: RLAT0D,RLON0D
412 ! Horizontal resolution: DPHD, DLMD
417 ! Remove non-mapping portions
418 ! Make part of WPS domain plotting utility
421 ! Pass additional arguments to enable plotting of nests
423 ! Input map parameters for E grid.
425 REAL , INTENT(IN) :: rlat0d , & ! latitude of grid center (degrees)
426 rlon0d ! longitude of grid center (degrees, times -1)
428 REAL , INTENT(IN) :: dphd , & ! angular distance between rows (degrees)
429 dlmd ! angular distance between adjacent H and V points (degrees)
431 INTEGER , INTENT(in) :: n_domains ! number of domains
432 INTEGER , INTENT(in) , DIMENSION(n_domains):: e_we , &
435 parent_grid_ratio , &
444 INTEGER :: im, & ! number of H points in odd rows
445 jm , & ! number of rows
451 INTEGER :: imt , imtjm
452 REAL :: latlft,lonlft,latrgt,lonrgt
464 ! Get lat and lon of left and right points.
466 CALL corners ( rlat1d,rlon1d,im,jm,rlat0d,rlon0d,dphd,dlmd,&
467 ngpwe,ngpsn,ilowl,jlowl,latlft,lonlft,latrgt,lonrgt)
469 ! With corner points, make map background.
471 CALL mapbkg_egrid ( imt,jm,ilowl,jlowl,ngpwe,ngpsn,&
472 rlat0d,rlon0d,latlft,lonlft,latrgt,lonrgt,&
476 parent_id,parent_grid_ratio,&
477 i_parent_start,j_parent_start)
479 END SUBROUTINE plot_e_grid
481 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
483 SUBROUTINE corners ( glatd,glond,im,jm,tph0d,tlm0d,dphd,dlmd,&
484 ngpwe,ngpsn,ilowl,jlowl,glatl,glonl,glatr,glonr)
488 REAL , INTENT(IN) :: glatd,glond,tph0d,tlm0d,dphd,dlmd,&
489 glatl,glonl,glatr,glonr
491 INTEGER , INTENT(IN) :: im,jm,ngpwe,ngpsn
492 INTEGER , INTENT(OUT) :: ilowl,jlowl
496 REAL , PARAMETER :: d2r = 1.74532925E-2 , r2D = 1./D2R
498 REAL :: glat , glon , dph , dlm , tph0 , tlm0
499 REAL :: x , y , z , tlat , tlon , tlat1 , tlat2 , tlon1 , tlon2
501 REAL :: dlm1 , dlm2 , d1 , d2 , d3 , d4 , dmin
503 INTEGER :: jmt , ii , jj , iuppr , juppr
504 INTEGER :: nrow , ncol
508 ! Convert from geodetic to transformed coordinates (degrees).
517 x = COS(tph0) * COS(glat) * COS(glon-tlm0)+SIN(tph0) * SIN(glat)
518 y = -COS(glat) * SIN(glon-tlm0)
519 z = COS(tph0) * SIN(glat)-SIN(tph0) * COS(glat) * COS(glon-tlm0)
520 tlat = r2d * ATAN(z/SQRT(x*x + y*y))
521 tlon = r2d * ATAN(y/x)
523 ! Find the real (non-integer) row and column of the input location on
539 tlat1 = (nrow-jmt) * dph
541 tlon1 = (ncol-im) * dlm
547 d1 = ACOS(COS(tlat) * COS(tlat1) * COS(dlm1)+SIN(tlat) * SIN(tlat1))
548 d2 = ACOS(COS(tlat) * COS(tlat2) * COS(dlm1)+SIN(tlat) * SIN(tlat2))
549 d3 = ACOS(COS(tlat) * COS(tlat2) * COS(dlm2)+SIN(tlat) * SIN(tlat2))
550 d4 = ACOS(COS(tlat) * COS(tlat1) * COS(dlm2)+SIN(tlat) * SIN(tlat1))
552 dmin = MIN(d1,d2,d3,d4)
554 IF ( ABS(dmin-d1) .LT. 1.e-6 ) THEN
557 ELSE IF ( ABS(dmin-d2) .LT. 1.e-6 ) THEN
560 ELSE IF ( ABS(dmin-d3) .LT. 1.e-6 ) THEN
563 ELSE IF ( ABS(dmin-d4) .LT. 1.e-6 ) THEN
568 ! Now find the i and j of the lower left corner of the desired grid
569 ! region and of the upper right.
576 ! Find their geodetic coordinates.
578 CALL e2t2g(ilowl,jlowl,im,jm,tph0d,tlm0d,dphd,dlmd,glatl,glonl)
579 CALL e2t2g(iuppr,juppr,im,jm,tph0d,tlm0d,dphd,dlmd,glatr,glonr)
581 END SUBROUTINE corners
583 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
585 SUBROUTINE mapbkg_egrid ( imt,jm,ilowl,jlowl,ngpwe,ngpsn,&
586 rlat0d,rlon0d,glatl,glonl,glatr,glonr,&
590 parent_id,parent_grid_ratio,&
591 i_parent_start , j_parent_start )
595 INTEGER , INTENT(in) :: n_domains
596 INTEGER , INTENT(in) , DIMENSION(n_domains):: e_we , e_sn , &
597 parent_id , parent_grid_ratio , &
598 i_parent_start , j_parent_start
602 CHARACTER (LEN=97) :: string
604 REAL :: xs, xe, ys, ye
606 ! Yet more center lon messing around, hoo boy.
611 ! Open up NCAR Graphics
617 ! Make the background white, and the foreground black.
619 CALL gscr ( 1 , 0 , 1., 1., 1. )
620 CALL gscr ( 1 , 1 , 0., 0., 0. )
622 ! Line width default thickness.
624 CALL setusv('LW',1000)
626 ! Make map outline a solid line, not dots.
631 ! Map outlines are political and states.
633 CALL mapstc('OU','PS')
635 ! Cylindrical equidistant.
637 CALL maproj('CE',rlat0d,clonx,0.)
639 ! Specify corner points.
641 CALL mapset('CO',glatl,glonl,glatr,glonr)
643 ! Lat lon lines every 5 degrees.
647 ! Map takes up this much real estate.
649 CALL mappos( 0.05 , 0.95 , 0.05 , 0.95 )
651 ! Initialize and draw map.
656 ! Line width twice default thickness.
658 CALL setusv('LW',2000)
660 ! Add approx grid point tick marks
662 CALL perim(((imt+3)/2)-1,1,jm-1,1)
664 ! Line width default thickness.
666 CALL setusv('LW',1000)
668 ! Put on a quicky description.
670 WRITE ( string , FMT = '("E-GRID E_WE = ",I4,", E_SN = ",I4 , &
671 &", DX = ",F6.4,", DY = ",F6.4 , &
672 &", REF_LAT = ",F8.3,", REF_LON = ",F8.3)') &
673 (imt+3)/2,jm+1,dlmd,dphd,rlat0d,-1.*rlon0d
674 CALL getset(xa,xb,ya,yb,xxa,xxy,yya,yyb,ltype)
675 CALL pchiqu(xxa,yya-(yyb-yya)/20.,string,8.,0.,-1.)
676 CALL set (xa,xb,ya,yb,&
677 1.,real(e_we(1)),1.,real(e_sn(1)),ltype)
679 ! Line width twice default thickness.
681 CALL setusv('LW',2000)
683 ! Draw a box for each nest.
686 call getxy ( xs, xe, ys, ye, &
689 parent_id , parent_grid_ratio , &
690 i_parent_start , j_parent_start )
692 call line ( xs , ys , xe , ys )
693 call line ( xe , ys , xe , ye )
694 call line ( xe , ye , xs , ye )
695 call line ( xs , ye , xs , ys )
700 ! Close workstation and NCAR Grpahics.
705 END SUBROUTINE mapbkg_egrid
707 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
709 SUBROUTINE e2t2g ( ncol,nrow,im,jm,tph0d,tlm0d,dphd,dlmd,glatd,glond)
713 REAL , PARAMETER :: D2R=1.74532925E-2 , R2D=1./D2R
720 !*** FIND THE TRANSFORMED LAT (POSITIVE NORTH) AND LON (POSITIVE EAST)
722 TLATD=(NROW-(JM+1)/2)*DPHD
725 !*** NOW CONVERT TO GEODETIC LAT (POSITIVE NORTH) AND LON (POSITIVE EAST)
729 ARG1=SIN(TLATR)*COS(TPH0)+COS(TLATR)*SIN(TPH0)*COS(TLONR)
732 ARG2=COS(TLATR)*COS(TLONR)/(COS(GLATR)*COS(TPH0))- &
734 IF(ABS(ARG2).GT.1.)ARG2=ABS(ARG2)/ARG2
736 IF(TLOND.GT.0.)FCTR=-1.
737 GLOND=TLM0D+FCTR*ACOS(ARG2)*R2D