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, &
69 else if (iprojection == PROJ_MERC) then
70 call map_set(iprojection, proj_stack(SOURCE_PROJ), &
71 truelat1=user_truelat1, &
72 lat1=user_known_lat, &
73 lon1=user_known_lon, &
74 knowni=user_known_x, &
75 knownj=user_known_y, &
79 else if (iprojection == PROJ_CYL) then
80 call mprintf(.true.,ERROR,'Should not have PROJ_CYL as projection for ' &
81 //'source data in push_source_projection()')
83 else if (iprojection == PROJ_CASSINI) then
84 call mprintf(.true.,ERROR,'Should not have PROJ_CASSINI as projection for ' &
85 //'source data in push_source_projection()')
87 else if (iprojection == PROJ_LC) then
88 call map_set(iprojection, proj_stack(SOURCE_PROJ), &
89 truelat1=user_truelat1, &
90 truelat2=user_truelat2, &
91 stdlon=user_stand_lon, &
92 lat1=user_known_lat, &
93 lon1=user_known_lon, &
94 knowni=user_known_x, &
95 knownj=user_known_y, &
99 else if (iprojection == PROJ_ALBERS_NAD83) then
100 call map_set(iprojection, proj_stack(SOURCE_PROJ), &
101 truelat1=user_truelat1, &
102 truelat2=user_truelat2, &
103 stdlon=user_stand_lon, &
104 lat1=user_known_lat, &
105 lon1=user_known_lon, &
106 knowni=user_known_x, &
107 knownj=user_known_y, &
109 r_earth=earth_radius)
111 else if (iprojection == PROJ_PS) then
112 call map_set(iprojection, proj_stack(SOURCE_PROJ), &
113 truelat1=user_truelat1, &
114 stdlon=user_stand_lon, &
115 lat1=user_known_lat, &
116 lon1=user_known_lon, &
117 knowni=user_known_x, &
118 knownj=user_known_y, &
120 r_earth=earth_radius)
122 else if (iprojection == PROJ_PS_WGS84) then
123 call map_set(iprojection, proj_stack(SOURCE_PROJ), &
124 truelat1=user_truelat1, &
125 stdlon=user_stand_lon, &
126 lat1=user_known_lat, &
127 lon1=user_known_lon, &
128 knowni=user_known_x, &
129 knownj=user_known_y, &
131 r_earth=earth_radius)
133 else if (iprojection == PROJ_GAUSS) then
134 call map_set(iprojection, proj_stack(SOURCE_PROJ), &
135 lat1=user_known_lat, &
136 lon1=user_known_lon, &
137 nlat=nint(user_dlat), &
139 r_earth=earth_radius)
141 else if (iprojection == PROJ_ROTLL) then
142 ! BUG: Implement this projection.
146 end subroutine push_source_projection
149 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
150 ! Name: pop_source_projection
153 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
154 subroutine pop_source_projection()
158 SOURCE_PROJ = SOURCE_PROJ+1
160 call mprintf((SOURCE_PROJ > 0), ERROR, &
161 'In pop_user_projection(), projection stack has overflowed.')
163 end subroutine pop_source_projection
167 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
168 ! Name: set_domain_projection
171 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
172 subroutine set_domain_projection(iprojection, user_stand_lon, user_truelat1, user_truelat2, &
173 user_dxkm, user_dykm, user_dlat, user_dlon, &
174 user_xdim, user_ydim, user_known_x, &
175 user_known_y, user_known_lat, user_known_lon, &
176 user_pole_lat, user_pole_lon, earth_radius)
181 integer, intent(in) :: iprojection
182 integer, intent(in) :: user_xdim, user_ydim
183 real, intent(in) :: user_stand_lon, user_truelat1, user_truelat2, &
184 user_dxkm, user_dykm, user_dlat, user_dlon, &
185 user_known_x, user_known_y, user_known_lat, user_known_lon, &
186 user_pole_lat, user_pole_lon
187 real, intent(in), optional :: earth_radius
189 current_nest_number = 1
191 call map_init(proj_stack(current_nest_number))
193 if (iprojection == PROJ_LATLON) then
194 call map_set(iprojection, proj_stack(current_nest_number), &
195 lat1=user_known_lat, &
196 lon1=user_known_lon, &
199 r_earth=earth_radius)
201 else if (iprojection == PROJ_MERC) then
202 call map_set(iprojection, proj_stack(current_nest_number), &
203 truelat1=user_truelat1, &
204 lat1=user_known_lat, &
205 lon1=user_known_lon, &
206 knowni=user_known_x, &
207 knownj=user_known_y, &
209 r_earth=earth_radius)
211 else if (iprojection == PROJ_CYL) then
212 call map_set(iprojection, proj_stack(current_nest_number), &
215 stdlon=user_stand_lon, &
216 r_earth=earth_radius)
218 else if (iprojection == PROJ_CASSINI) then
219 call map_set(iprojection, proj_stack(current_nest_number), &
224 stdlon=user_stand_lon, &
225 lat1=user_known_lat, &
226 lon1=user_known_lon, &
227 lat0=user_pole_lat, &
228 lon0=user_pole_lon, &
229 knowni=user_known_x, &
230 knownj=user_known_y, &
231 r_earth=earth_radius)
233 else if (iprojection == PROJ_LC) then
234 call map_set(iprojection, proj_stack(current_nest_number), &
235 truelat1=user_truelat1, &
236 truelat2=user_truelat2, &
237 stdlon=user_stand_lon, &
238 lat1=user_known_lat, &
239 lon1=user_known_lon, &
240 knowni=user_known_x, &
241 knownj=user_known_y, &
243 r_earth=earth_radius)
245 else if (iprojection == PROJ_ALBERS_NAD83) then
246 call map_set(iprojection, proj_stack(current_nest_number), &
247 truelat1=user_truelat1, &
248 truelat2=user_truelat2, &
249 stdlon=user_stand_lon, &
250 lat1=user_known_lat, &
251 lon1=user_known_lon, &
252 knowni=user_known_x, &
253 knownj=user_known_y, &
255 r_earth=earth_radius)
257 else if (iprojection == PROJ_PS) then
258 call map_set(iprojection, proj_stack(current_nest_number), &
259 truelat1=user_truelat1, &
260 stdlon=user_stand_lon, &
261 lat1=user_known_lat, &
262 lon1=user_known_lon, &
263 knowni=user_known_x, &
264 knownj=user_known_y, &
266 r_earth=earth_radius)
268 else if (iprojection == PROJ_PS_WGS84) then
269 call map_set(iprojection, proj_stack(current_nest_number), &
270 truelat1=user_truelat1, &
271 stdlon=user_stand_lon, &
272 lat1=user_known_lat, &
273 lon1=user_known_lon, &
274 knowni=user_known_x, &
275 knownj=user_known_y, &
278 else if (iprojection == PROJ_GAUSS) then
279 call map_set(iprojection, proj_stack(current_nest_number), &
280 lat1=user_known_lat, &
281 lon1=user_known_lon, &
282 nlat=nint(user_dlat), &
284 r_earth=earth_radius)
286 else if (iprojection == PROJ_ROTLL) then
287 call map_set(iprojection, proj_stack(current_nest_number), &
292 lat1=user_known_lat, &
293 lon1=user_known_lon, &
297 r_earth=earth_radius)
301 end subroutine set_domain_projection
306 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
307 ! Name: compute_nest_locations
309 ! Purpose: This routine computes the variables necessary in determining the
310 ! location of all nests without reference to the parent or coarse domains.
311 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
312 subroutine compute_nest_locations()
318 real :: temp_known_x, temp_known_y, temp_known_lat, temp_known_lon, &
319 temp_dxkm, temp_dykm, temp_dlat, temp_dlon
321 ! Set location of coarse/mother domain
322 call map_init(proj_stack(1))
324 if (iproj_type == PROJ_LATLON) then
325 call map_set(iproj_type, proj_stack(1), &
331 else if (iproj_type == PROJ_MERC) then
332 call map_set(iproj_type, proj_stack(1), &
340 else if (iproj_type == PROJ_CYL) then
341 call map_set(iproj_type, proj_stack(1), &
346 else if (iproj_type == PROJ_CASSINI) then
347 call map_set(iproj_type, proj_stack(1), &
360 else if (iproj_type == PROJ_LC) then
361 call map_set(iproj_type, proj_stack(1), &
371 else if (iproj_type == PROJ_ALBERS_NAD83) then
372 call map_set(iproj_type, proj_stack(1), &
382 else if (iproj_type == PROJ_PS) then
383 call map_set(iproj_type, proj_stack(1), &
392 else if (iproj_type == PROJ_PS_WGS84) then
393 call map_set(iproj_type, proj_stack(1), &
402 else if (iproj_type == PROJ_GAUSS) then
403 call map_set(iproj_type, proj_stack(current_nest_number), &
409 else if (iproj_type == PROJ_ROTLL) then
410 call map_set(iproj_type, proj_stack(1), &
423 ! Now we can compute lat/lon <-> x/y for coarse domain
424 call select_domain(1)
426 ! Call a recursive procedure to find the lat/lon of the centerpoint for
430 temp_known_x = real(ixdim(i))/2.
431 temp_known_y = real(jydim(i))/2.
433 call find_known_latlon(i, temp_known_x, temp_known_y, &
434 temp_known_lat, temp_known_lon, &
435 temp_dxkm, temp_dykm, temp_dlat, temp_dlon)
437 if (iproj_type == PROJ_LATLON) then
438 call map_set(iproj_type, proj_stack(i), &
439 lat1=temp_known_lat, &
440 lon1=temp_known_lon, &
444 else if (iproj_type == PROJ_MERC) then
445 call map_set(iproj_type, proj_stack(i), &
447 lat1=temp_known_lat, &
448 lon1=temp_known_lon, &
449 knowni=temp_known_x, &
450 knownj=temp_known_y, &
453 else if (iproj_type == PROJ_CYL) then
454 call mprintf(.true.,ERROR,'Don''t know how to do nesting with PROJ_CYL ' &
455 //'in compute_nest_locations()')
457 else if (iproj_type == PROJ_CASSINI) then
458 call map_set(iproj_type, proj_stack(i), &
464 knowni=temp_known_x, &
465 knownj=temp_known_y, &
468 lat1=temp_known_lat, &
471 else if (iproj_type == PROJ_LC) then
472 call map_set(iproj_type, proj_stack(i), &
476 lat1=temp_known_lat, &
477 lon1=temp_known_lon, &
478 knowni=temp_known_x, &
479 knownj=temp_known_y, &
482 else if (iproj_type == PROJ_ALBERS_NAD83) then
483 call map_set(iproj_type, proj_stack(i), &
487 lat1=temp_known_lat, &
488 lon1=temp_known_lon, &
489 knowni=temp_known_x, &
490 knownj=temp_known_y, &
493 else if (iproj_type == PROJ_PS) then
494 call map_set(iproj_type, proj_stack(i), &
497 lat1=temp_known_lat, &
498 lon1=temp_known_lon, &
499 knowni=temp_known_x, &
500 knownj=temp_known_y, &
503 else if (iproj_type == PROJ_PS_WGS84) then
504 call map_set(iproj_type, proj_stack(i), &
507 lat1=temp_known_lat, &
508 lon1=temp_known_lon, &
509 knowni=temp_known_x, &
510 knownj=temp_known_y, &
513 else if (iproj_type == PROJ_GAUSS) then
514 call map_set(iproj_type, proj_stack(current_nest_number), &
515 lat1=temp_known_lat, &
516 lon1=temp_known_lon, &
517 nlat=nint(temp_dykm), &
520 else if (iproj_type == PROJ_ROTLL) then
521 ! BUG: Implement this projection.
527 end subroutine compute_nest_locations
530 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
531 ! Name: find_known_latlon
533 ! Purpose: This recursive routine computes the latitude and longitude for a
534 ! specified x/y location in the given nest number, and also computes the
537 ! NOTE: This routine assumes that xytoll will work correctly for the
539 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
540 recursive subroutine find_known_latlon(n, rx, ry, rlat, rlon, dx, dy, dlat, dlon)
545 integer, intent(in) :: n
546 real, intent(in) :: rx, ry
547 real, intent(out) :: rlat, rlon, dx, dy, dlat, dlon
550 real :: x_in_parent, y_in_parent
552 if (n == 1) then ! Stopping case for the recursion
558 call ij_to_latlon(proj_stack(current_nest_number), rx, ry, rlat, rlon)
562 else ! Recursive case
564 x_in_parent = (rx - ((parent_grid_ratio(n)+1.)/2.)) &
565 / parent_grid_ratio(n) + parent_ll_x(n)
566 y_in_parent = (ry - ((parent_grid_ratio(n)+1.)/2.)) &
567 / parent_grid_ratio(n) + parent_ll_y(n)
569 call find_known_latlon(parent_id(n), x_in_parent, y_in_parent, rlat, rlon, dx, dy, dlat, dlon)
571 dx = dx / parent_grid_ratio(n)
572 dy = dy / parent_grid_ratio(n)
573 dlat = dlat / parent_grid_ratio(n)
574 dlon = dlon / parent_grid_ratio(n)
577 end subroutine find_known_latlon
580 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
581 ! Name: compute_nest_level_info
583 ! Purpose: This routine computes the parameters describing a nesting level for
585 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
586 subroutine compute_nest_level_info()
591 integer :: i, nest_level, temp
592 type (list) :: level_list
594 call list_init(level_list)
596 ! Set location of coarse/mother domain
597 call map_init(proj_stack(1))
599 call map_set(PROJ_ROTLL, proj_stack(1), &
610 parent_ur_x(1) = real(ixdim(1))
611 parent_ur_y(1) = real(jydim(1))
615 nest_level = get_nest_level(i)
617 if (.not. list_search(level_list, ikey=nest_level, ivalue=temp)) then
619 call list_insert(level_list, ikey=nest_level, ivalue=nest_level)
621 ixdim(nest_level) = ixdim(1)*(3**(nest_level-1))-(3**(nest_level-1)-1)
622 jydim(nest_level) = jydim(1)*(3**(nest_level-1))-(3**(nest_level-1)-1)
624 parent_ur_x(nest_level) = ixdim(nest_level)
625 parent_ur_y(nest_level) = jydim(nest_level)
627 call map_set(PROJ_ROTLL, proj_stack(nest_level), &
628 ixdim = ixdim(nest_level), &
629 jydim = jydim(nest_level), &
634 latinc=(dykm/real((3**(nest_level-1)))), &
635 loninc=(dxkm/real((3**(nest_level-1)))), &
641 call list_destroy(level_list)
643 end subroutine compute_nest_level_info
646 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
647 ! Name: get_domain_resolution
650 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
651 subroutine get_domain_resolution(dom_dx, dom_dy)
656 real, intent(out) :: dom_dx, dom_dy
658 ! The proj_info structure only stores dx, so set both dom_dx and dom_dy to dx
659 dom_dx = proj_stack(current_nest_number)%dx
660 dom_dy = proj_stack(current_nest_number)%dx
662 end subroutine get_domain_resolution
665 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
666 ! Name: get_nest_level
668 ! Purpose: This function returns, given a grid ID number, the nesting level of
669 ! that domain; the coarse domain is taken to have nesting level 1.
670 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
671 function get_nest_level(i)
676 integer, intent(in) :: i
682 integer :: get_nest_level
684 ! If argument is the coarse domain, return
690 if (i > MAX_DOMAINS) then
691 call mprintf(.true., ERROR, &
692 'get_nest_level() called with invalid grid ID of %i.',i1=i)
695 ! If not the coarse domain, then nesting level is at least 2
696 ! Yes, this looks silly. But we do not have a grid_id array, so
697 ! we must check on parent_id
701 do while (parent_id(j) /= 1)
703 get_nest_level = get_nest_level + 1
706 if (get_nest_level > MAX_DOMAINS) then
707 call mprintf(.true., ERROR, &
708 'Spooky nesting setup encountered in get_nest_level().')
712 end function get_nest_level
716 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
717 ! Name: select_domain
719 ! Purpose: This routine is used to select which nest x/y <-> lat/lon
720 ! conversions will be with respect to. For example, selecting domain 2 will
721 ! cause the llxy routine to compute x/y locations with respect to domain 2
723 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
724 subroutine select_domain(domain_num)
729 integer, intent(in) :: domain_num
732 if (domain_num > n_domains) then
733 call mprintf(.true.,ERROR,'In select_domain(), selected domain is greater than n_domains.')
737 if (domain_num > 1) then
738 call mprintf(.true.,ERROR,'In select_domain(), selected domain is greater than 1.')
742 current_nest_number = domain_num
744 end subroutine select_domain
747 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
748 ! Name: iget_selected_domain
750 ! Purpose: This function returns the number of the currently selected nest.
751 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
752 function iget_selected_domain()
757 integer :: iget_selected_domain
759 iget_selected_domain = current_nest_number
761 end function iget_selected_domain
764 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
768 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
769 subroutine lltoxy(xlat, xlon, x, y, stagger, comp_ll)
774 integer, intent(in) :: stagger
775 real, intent(in) :: xlat, xlon
776 real, intent(out) :: x, y
777 logical, optional, intent(in) :: comp_ll
780 logical :: save_comp_ll
782 ! Account for grid staggering
783 if (stagger == HH) then
784 proj_stack(current_nest_number)%stagger = HH
785 else if (stagger == VV) then
786 proj_stack(current_nest_number)%stagger = VV
789 if (present(comp_ll)) then
790 save_comp_ll = proj_stack(current_nest_number)%comp_ll
791 proj_stack(current_nest_number)%comp_ll = comp_ll
794 call latlon_to_ij(proj_stack(current_nest_number), xlat, xlon, x, y)
796 if (present(comp_ll)) then
797 proj_stack(current_nest_number)%comp_ll = save_comp_ll
800 ! Account for grid staggering
801 if (stagger == U) then
803 else if (stagger == V) then
807 end subroutine lltoxy
810 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
814 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
815 subroutine xytoll(x, y, xlat, xlon, stagger, comp_ll)
820 integer, intent(in) :: stagger
821 real, intent(in) :: x, y
822 real, intent(out) :: xlat, xlon
823 logical, optional, intent(in) :: comp_ll
827 logical :: save_comp_ll
829 ! Account for grid staggering; we cannot modify x and y, so modify local
831 if (stagger == U) then
834 else if (stagger == V) then
837 else if (stagger == HH) then
838 proj_stack(current_nest_number)%stagger = HH
841 else if (stagger == VV) then
842 proj_stack(current_nest_number)%stagger = VV
850 if (present(comp_ll)) then
851 save_comp_ll = proj_stack(current_nest_number)%comp_ll
852 proj_stack(current_nest_number)%comp_ll = comp_ll
855 call ij_to_latlon(proj_stack(current_nest_number), rx, ry, xlat, xlon)
857 if (present(comp_ll)) then
858 proj_stack(current_nest_number)%comp_ll = save_comp_ll
861 end subroutine xytoll
863 end module llxy_module