1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4 ! This module handles transformations between model grid coordinates and
5 ! latitude-longitude coordinates. The actual transformations are done through
6 ! the map_utils module.
8 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
15 use misc_definitions_module
18 integer, parameter :: MAX_SOURCE_LEVELS = 20
21 integer :: current_nest_number
22 integer :: SOURCE_PROJ = 0
23 ! The following arrays hold values for all available domains
24 ! NOTE: The entries in the arrays for "domain 0" are used for projection
25 ! information of user-specified source data
26 type (proj_info), dimension(-MAX_SOURCE_LEVELS:MAX_DOMAINS) :: proj_stack
28 ! The projection and domain that we have computed constants for
29 integer :: computed_proj = INVALID
30 integer :: computed_domain = INVALID
34 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
35 ! Name: push_source_projection
38 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
39 subroutine push_source_projection(iprojection, user_stand_lon, user_truelat1, user_truelat2, &
40 user_dxkm, user_dykm, user_dlat, user_dlon, user_known_x, &
41 user_known_y, user_known_lat, user_known_lon, earth_radius)
46 integer, intent(in) :: iprojection
47 real, intent(in) :: user_stand_lon, user_truelat1, user_truelat2, user_dxkm, user_dykm, &
48 user_dlat, user_dlon, &
49 user_known_x, user_known_y, user_known_lat, user_known_lon
50 real, intent(in), optional :: earth_radius
52 SOURCE_PROJ = SOURCE_PROJ-1
53 if (SOURCE_PROJ < -MAX_SOURCE_LEVELS) then
54 call mprintf(.true.,ERROR,'In push_user_projection(), too many levels of user projections.')
57 call map_init(proj_stack(SOURCE_PROJ))
59 if (iprojection == PROJ_LATLON) then
60 call map_set(iprojection, proj_stack(SOURCE_PROJ), &
61 lat1=user_known_lat, &
62 lon1=user_known_lon, &
63 knowni=user_known_x, &
64 knownj=user_known_y, &
65 nxmax=nint(360.0 / user_dlon), &
70 else if (iprojection == PROJ_MERC) then
71 call map_set(iprojection, proj_stack(SOURCE_PROJ), &
72 truelat1=user_truelat1, &
73 lat1=user_known_lat, &
74 lon1=user_known_lon, &
75 knowni=user_known_x, &
76 knownj=user_known_y, &
80 else if (iprojection == PROJ_CYL) then
81 call mprintf(.true.,ERROR,'Should not have PROJ_CYL as projection for ' &
82 //'source data in push_source_projection()')
84 else if (iprojection == PROJ_CASSINI) then
85 call mprintf(.true.,ERROR,'Should not have PROJ_CASSINI as projection for ' &
86 //'source data in push_source_projection()')
88 else if (iprojection == PROJ_LC) then
89 call map_set(iprojection, proj_stack(SOURCE_PROJ), &
90 truelat1=user_truelat1, &
91 truelat2=user_truelat2, &
92 stdlon=user_stand_lon, &
93 lat1=user_known_lat, &
94 lon1=user_known_lon, &
95 knowni=user_known_x, &
96 knownj=user_known_y, &
100 else if (iprojection == PROJ_ALBERS_NAD83) then
101 call map_set(iprojection, proj_stack(SOURCE_PROJ), &
102 truelat1=user_truelat1, &
103 truelat2=user_truelat2, &
104 stdlon=user_stand_lon, &
105 lat1=user_known_lat, &
106 lon1=user_known_lon, &
107 knowni=user_known_x, &
108 knownj=user_known_y, &
110 r_earth=earth_radius)
112 else if (iprojection == PROJ_PS) then
113 call map_set(iprojection, proj_stack(SOURCE_PROJ), &
114 truelat1=user_truelat1, &
115 stdlon=user_stand_lon, &
116 lat1=user_known_lat, &
117 lon1=user_known_lon, &
118 knowni=user_known_x, &
119 knownj=user_known_y, &
121 r_earth=earth_radius)
123 else if (iprojection == PROJ_PS_WGS84) then
124 call map_set(iprojection, proj_stack(SOURCE_PROJ), &
125 truelat1=user_truelat1, &
126 stdlon=user_stand_lon, &
127 lat1=user_known_lat, &
128 lon1=user_known_lon, &
129 knowni=user_known_x, &
130 knownj=user_known_y, &
132 r_earth=earth_radius)
134 else if (iprojection == PROJ_GAUSS) then
135 call map_set(iprojection, proj_stack(SOURCE_PROJ), &
136 lat1=user_known_lat, &
137 lon1=user_known_lon, &
138 nxmax=nint(360.0 / user_dlon), &
139 nlat=nint(user_dlat), &
141 r_earth=earth_radius)
143 else if (iprojection == PROJ_ROTLL) then
144 ! BUG: Implement this projection.
148 end subroutine push_source_projection
151 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
152 ! Name: pop_source_projection
155 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
156 subroutine pop_source_projection()
160 SOURCE_PROJ = SOURCE_PROJ+1
162 call mprintf((SOURCE_PROJ > 0), ERROR, &
163 'In pop_user_projection(), projection stack has overflowed.')
165 end subroutine pop_source_projection
169 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
170 ! Name: set_domain_projection
173 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
174 subroutine set_domain_projection(iprojection, user_stand_lon, user_truelat1, user_truelat2, &
175 user_dxkm, user_dykm, user_dlat, user_dlon, &
176 user_xdim, user_ydim, user_known_x, &
177 user_known_y, user_known_lat, user_known_lon, &
178 user_pole_lat, user_pole_lon, earth_radius)
183 integer, intent(in) :: iprojection
184 integer, intent(in) :: user_xdim, user_ydim
185 real, intent(in) :: user_stand_lon, user_truelat1, user_truelat2, &
186 user_dxkm, user_dykm, user_dlat, user_dlon, &
187 user_known_x, user_known_y, user_known_lat, user_known_lon, &
188 user_pole_lat, user_pole_lon
189 real, intent(in), optional :: earth_radius
191 current_nest_number = 1
193 call map_init(proj_stack(current_nest_number))
195 if (iprojection == PROJ_LATLON) then
196 call map_set(iprojection, proj_stack(current_nest_number), &
197 lat1=user_known_lat, &
198 lon1=user_known_lon, &
201 r_earth=earth_radius)
203 else if (iprojection == PROJ_MERC) then
204 call map_set(iprojection, proj_stack(current_nest_number), &
205 truelat1=user_truelat1, &
206 lat1=user_known_lat, &
207 lon1=user_known_lon, &
208 knowni=user_known_x, &
209 knownj=user_known_y, &
211 r_earth=earth_radius)
213 else if (iprojection == PROJ_CYL) then
214 call map_set(iprojection, proj_stack(current_nest_number), &
217 stdlon=user_stand_lon, &
218 r_earth=earth_radius)
220 else if (iprojection == PROJ_CASSINI) then
221 call map_set(iprojection, proj_stack(current_nest_number), &
226 stdlon=user_stand_lon, &
227 lat1=user_known_lat, &
228 lon1=user_known_lon, &
229 lat0=user_pole_lat, &
230 lon0=user_pole_lon, &
231 knowni=user_known_x, &
232 knownj=user_known_y, &
233 r_earth=earth_radius)
235 else if (iprojection == PROJ_LC) then
236 call map_set(iprojection, proj_stack(current_nest_number), &
237 truelat1=user_truelat1, &
238 truelat2=user_truelat2, &
239 stdlon=user_stand_lon, &
240 lat1=user_known_lat, &
241 lon1=user_known_lon, &
242 knowni=user_known_x, &
243 knownj=user_known_y, &
245 r_earth=earth_radius)
247 else if (iprojection == PROJ_ALBERS_NAD83) then
248 call map_set(iprojection, proj_stack(current_nest_number), &
249 truelat1=user_truelat1, &
250 truelat2=user_truelat2, &
251 stdlon=user_stand_lon, &
252 lat1=user_known_lat, &
253 lon1=user_known_lon, &
254 knowni=user_known_x, &
255 knownj=user_known_y, &
257 r_earth=earth_radius)
259 else if (iprojection == PROJ_PS) then
260 call map_set(iprojection, proj_stack(current_nest_number), &
261 truelat1=user_truelat1, &
262 stdlon=user_stand_lon, &
263 lat1=user_known_lat, &
264 lon1=user_known_lon, &
265 knowni=user_known_x, &
266 knownj=user_known_y, &
268 r_earth=earth_radius)
270 else if (iprojection == PROJ_PS_WGS84) then
271 call map_set(iprojection, proj_stack(current_nest_number), &
272 truelat1=user_truelat1, &
273 stdlon=user_stand_lon, &
274 lat1=user_known_lat, &
275 lon1=user_known_lon, &
276 knowni=user_known_x, &
277 knownj=user_known_y, &
280 else if (iprojection == PROJ_GAUSS) then
281 call map_set(iprojection, proj_stack(current_nest_number), &
282 lat1=user_known_lat, &
283 lon1=user_known_lon, &
284 nlat=nint(user_dlat), &
286 r_earth=earth_radius)
288 else if (iprojection == PROJ_ROTLL) then
289 call map_set(iprojection, proj_stack(current_nest_number), &
294 lat1=user_known_lat, &
295 lon1=user_known_lon, &
299 r_earth=earth_radius)
303 end subroutine set_domain_projection
308 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
309 ! Name: compute_nest_locations
311 ! Purpose: This routine computes the variables necessary in determining the
312 ! location of all nests without reference to the parent or coarse domains.
313 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
314 subroutine compute_nest_locations()
320 real :: temp_known_x, temp_known_y, temp_known_lat, temp_known_lon, &
321 temp_dxkm, temp_dykm, temp_dlat, temp_dlon
323 ! Set location of coarse/mother domain
324 call map_init(proj_stack(1))
326 if (iproj_type == PROJ_LATLON) then
327 call map_set(iproj_type, proj_stack(1), &
333 else if (iproj_type == PROJ_MERC) then
334 call map_set(iproj_type, proj_stack(1), &
342 else if (iproj_type == PROJ_CYL) then
343 call map_set(iproj_type, proj_stack(1), &
348 else if (iproj_type == PROJ_CASSINI) then
349 call map_set(iproj_type, proj_stack(1), &
362 else if (iproj_type == PROJ_LC) then
363 call map_set(iproj_type, proj_stack(1), &
373 else if (iproj_type == PROJ_ALBERS_NAD83) then
374 call map_set(iproj_type, proj_stack(1), &
384 else if (iproj_type == PROJ_PS) then
385 call map_set(iproj_type, proj_stack(1), &
394 else if (iproj_type == PROJ_PS_WGS84) then
395 call map_set(iproj_type, proj_stack(1), &
404 else if (iproj_type == PROJ_GAUSS) then
405 call map_set(iproj_type, proj_stack(current_nest_number), &
411 else if (iproj_type == PROJ_ROTLL) then
412 call map_set(iproj_type, proj_stack(1), &
425 ! Now we can compute lat/lon <-> x/y for coarse domain
426 call select_domain(1)
428 ! Call a recursive procedure to find the lat/lon of the centerpoint for
432 temp_known_x = real(ixdim(i))/2.
433 temp_known_y = real(jydim(i))/2.
435 call find_known_latlon(i, temp_known_x, temp_known_y, &
436 temp_known_lat, temp_known_lon, &
437 temp_dxkm, temp_dykm, temp_dlat, temp_dlon)
439 if (iproj_type == PROJ_LATLON) then
440 call map_set(iproj_type, proj_stack(i), &
441 lat1=temp_known_lat, &
442 lon1=temp_known_lon, &
446 else if (iproj_type == PROJ_MERC) then
447 call map_set(iproj_type, proj_stack(i), &
449 lat1=temp_known_lat, &
450 lon1=temp_known_lon, &
451 knowni=temp_known_x, &
452 knownj=temp_known_y, &
455 else if (iproj_type == PROJ_CYL) then
456 call mprintf(.true.,ERROR,'Don''t know how to do nesting with PROJ_CYL ' &
457 //'in compute_nest_locations()')
459 else if (iproj_type == PROJ_CASSINI) then
460 call map_set(iproj_type, proj_stack(i), &
466 knowni=temp_known_x, &
467 knownj=temp_known_y, &
470 lat1=temp_known_lat, &
473 else if (iproj_type == PROJ_LC) then
474 call map_set(iproj_type, proj_stack(i), &
478 lat1=temp_known_lat, &
479 lon1=temp_known_lon, &
480 knowni=temp_known_x, &
481 knownj=temp_known_y, &
484 else if (iproj_type == PROJ_ALBERS_NAD83) then
485 call map_set(iproj_type, proj_stack(i), &
489 lat1=temp_known_lat, &
490 lon1=temp_known_lon, &
491 knowni=temp_known_x, &
492 knownj=temp_known_y, &
495 else if (iproj_type == PROJ_PS) then
496 call map_set(iproj_type, proj_stack(i), &
499 lat1=temp_known_lat, &
500 lon1=temp_known_lon, &
501 knowni=temp_known_x, &
502 knownj=temp_known_y, &
505 else if (iproj_type == PROJ_PS_WGS84) then
506 call map_set(iproj_type, proj_stack(i), &
509 lat1=temp_known_lat, &
510 lon1=temp_known_lon, &
511 knowni=temp_known_x, &
512 knownj=temp_known_y, &
515 else if (iproj_type == PROJ_GAUSS) then
516 call map_set(iproj_type, proj_stack(current_nest_number), &
517 lat1=temp_known_lat, &
518 lon1=temp_known_lon, &
519 nlat=nint(temp_dykm), &
522 else if (iproj_type == PROJ_ROTLL) then
523 ! BUG: Implement this projection.
529 end subroutine compute_nest_locations
532 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
533 ! Name: find_known_latlon
535 ! Purpose: This recursive routine computes the latitude and longitude for a
536 ! specified x/y location in the given nest number, and also computes the
539 ! NOTE: This routine assumes that xytoll will work correctly for the
541 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
542 recursive subroutine find_known_latlon(n, rx, ry, rlat, rlon, dx, dy, dlat, dlon)
547 integer, intent(in) :: n
548 real, intent(in) :: rx, ry
549 real, intent(out) :: rlat, rlon, dx, dy, dlat, dlon
552 real :: x_in_parent, y_in_parent
554 if (n == 1) then ! Stopping case for the recursion
560 call ij_to_latlon(proj_stack(current_nest_number), rx, ry, rlat, rlon)
564 else ! Recursive case
566 x_in_parent = (rx - ((parent_grid_ratio(n)+1.)/2.)) &
567 / parent_grid_ratio(n) + parent_ll_x(n)
568 y_in_parent = (ry - ((parent_grid_ratio(n)+1.)/2.)) &
569 / parent_grid_ratio(n) + parent_ll_y(n)
571 call find_known_latlon(parent_id(n), x_in_parent, y_in_parent, rlat, rlon, dx, dy, dlat, dlon)
573 dx = dx / parent_grid_ratio(n)
574 dy = dy / parent_grid_ratio(n)
575 dlat = dlat / parent_grid_ratio(n)
576 dlon = dlon / parent_grid_ratio(n)
579 end subroutine find_known_latlon
582 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
583 ! Name: compute_nest_level_info
585 ! Purpose: This routine computes the parameters describing a nesting level for
587 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
588 subroutine compute_nest_level_info()
593 integer :: i, nest_level, temp
594 type (list) :: level_list
596 call list_init(level_list)
598 ! Set location of coarse/mother domain
599 call map_init(proj_stack(1))
601 call map_set(PROJ_ROTLL, proj_stack(1), &
612 parent_ur_x(1) = real(ixdim(1))
613 parent_ur_y(1) = real(jydim(1))
617 nest_level = get_nest_level(i)
619 if (.not. list_search(level_list, ikey=nest_level, ivalue=temp)) then
621 call list_insert(level_list, ikey=nest_level, ivalue=nest_level)
623 ixdim(nest_level) = ixdim(1)*(3**(nest_level-1))-(3**(nest_level-1)-1)
624 jydim(nest_level) = jydim(1)*(3**(nest_level-1))-(3**(nest_level-1)-1)
626 parent_ur_x(nest_level) = ixdim(nest_level)
627 parent_ur_y(nest_level) = jydim(nest_level)
629 call map_set(PROJ_ROTLL, proj_stack(nest_level), &
630 ixdim = ixdim(nest_level), &
631 jydim = jydim(nest_level), &
636 latinc=(dykm/real((3**(nest_level-1)))), &
637 loninc=(dxkm/real((3**(nest_level-1)))), &
643 call list_destroy(level_list)
645 end subroutine compute_nest_level_info
648 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
649 ! Name: get_domain_resolution
652 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
653 subroutine get_domain_resolution(dom_dx, dom_dy)
658 real, intent(out) :: dom_dx, dom_dy
660 ! The proj_info structure only stores dx, so set both dom_dx and dom_dy to dx
661 dom_dx = proj_stack(current_nest_number)%dx
662 dom_dy = proj_stack(current_nest_number)%dx
664 end subroutine get_domain_resolution
667 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
668 ! Name: get_nest_level
670 ! Purpose: This function returns, given a grid ID number, the nesting level of
671 ! that domain; the coarse domain is taken to have nesting level 1.
672 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
673 function get_nest_level(i)
678 integer, intent(in) :: i
684 integer :: get_nest_level
686 ! If argument is the coarse domain, return
692 if (i > MAX_DOMAINS) then
693 call mprintf(.true., ERROR, &
694 'get_nest_level() called with invalid grid ID of %i.',i1=i)
697 ! If not the coarse domain, then nesting level is at least 2
698 ! Yes, this looks silly. But we do not have a grid_id array, so
699 ! we must check on parent_id
703 do while (parent_id(j) /= 1)
705 get_nest_level = get_nest_level + 1
708 if (get_nest_level > MAX_DOMAINS) then
709 call mprintf(.true., ERROR, &
710 'Spooky nesting setup encountered in get_nest_level().')
714 end function get_nest_level
718 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
719 ! Name: select_domain
721 ! Purpose: This routine is used to select which nest x/y <-> lat/lon
722 ! conversions will be with respect to. For example, selecting domain 2 will
723 ! cause the llxy routine to compute x/y locations with respect to domain 2
725 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
726 subroutine select_domain(domain_num)
731 integer, intent(in) :: domain_num
734 if (domain_num > n_domains) then
735 call mprintf(.true.,ERROR,'In select_domain(), selected domain is greater than n_domains.')
739 if (domain_num > 1) then
740 call mprintf(.true.,ERROR,'In select_domain(), selected domain is greater than 1.')
744 current_nest_number = domain_num
746 end subroutine select_domain
749 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
750 ! Name: iget_selected_domain
752 ! Purpose: This function returns the number of the currently selected nest.
753 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
754 function iget_selected_domain()
759 integer :: iget_selected_domain
761 iget_selected_domain = current_nest_number
763 end function iget_selected_domain
766 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
770 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
771 subroutine lltoxy(xlat, xlon, x, y, stagger, comp_ll)
776 integer, intent(in) :: stagger
777 real, intent(in) :: xlat, xlon
778 real, intent(out) :: x, y
779 logical, optional, intent(in) :: comp_ll
782 logical :: save_comp_ll
784 ! Account for grid staggering
785 if (stagger == HH) then
786 proj_stack(current_nest_number)%stagger = HH
787 else if (stagger == VV) then
788 proj_stack(current_nest_number)%stagger = VV
791 if (present(comp_ll)) then
792 save_comp_ll = proj_stack(current_nest_number)%comp_ll
793 proj_stack(current_nest_number)%comp_ll = comp_ll
796 call latlon_to_ij(proj_stack(current_nest_number), xlat, xlon, x, y)
798 if (present(comp_ll)) then
799 proj_stack(current_nest_number)%comp_ll = save_comp_ll
802 ! Account for grid staggering
803 if (stagger == U) then
805 else if (stagger == V) then
809 end subroutine lltoxy
812 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
816 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
817 subroutine xytoll(x, y, xlat, xlon, stagger, comp_ll)
822 integer, intent(in) :: stagger
823 real, intent(in) :: x, y
824 real, intent(out) :: xlat, xlon
825 logical, optional, intent(in) :: comp_ll
829 logical :: save_comp_ll
831 ! Account for grid staggering; we cannot modify x and y, so modify local
833 if (stagger == U) then
836 else if (stagger == V) then
839 else if (stagger == HH) then
840 proj_stack(current_nest_number)%stagger = HH
843 else if (stagger == VV) then
844 proj_stack(current_nest_number)%stagger = VV
852 if (present(comp_ll)) then
853 save_comp_ll = proj_stack(current_nest_number)%comp_ll
854 proj_stack(current_nest_number)%comp_ll = comp_ll
857 call ij_to_latlon(proj_stack(current_nest_number), rx, ry, xlat, xlon)
859 if (present(comp_ll)) then
860 proj_stack(current_nest_number)%comp_ll = save_comp_ll
863 end subroutine xytoll
865 end module llxy_module