1 ! MODULE module_intermediate_nmm
3 ! This module contains routines that feed parent grid variables to the
4 ! intermediate grid when doing up-interpolation. This is needed by
5 ! the new NMM interpolation routines, which require certain variables
6 ! on the target domain in order to do log(P)-space vertical
9 ! This module is also used during forcing (parent->nest boundary) to
10 ! copy variables to the intermediate domain that may not otherwise be
11 ! copied by the forcing routines.
13 ! Author: Samuel Trahan
16 ! Aug 2012 - written by Sam Trahan for up-interpolation
17 ! Sep 2012 - updated to also work with forcing (parent->nest bdy)
19 module module_intermediate_nmm
20 #if (NMM_CORE == 1 && NMM_NEST==1)
22 SUBROUTINE parent_to_inter_part1 ( grid, intermediate_grid, ngrid, config_flags )
23 USE module_state_description
24 USE module_domain, ONLY : domain, get_ijk_from_grid
25 USE module_configure, ONLY : grid_config_rec_type
26 USE module_dm, ONLY : ntasks, ntasks_x, ntasks_y, itrace, local_communicator, mytask, &
27 ipe_save, jpe_save, ips_save, jps_save, get_dm_max_halo_width, &
28 nest_pes_x, nest_pes_y, &
29 intercomm_active, nest_task_offsets, &
30 mpi_comm_to_mom, mpi_comm_to_kid, which_kid!, &
31 !push_communicators_for_domain,pop_communicators_for_domain
37 TYPE(domain), POINTER :: grid
38 TYPE(domain), POINTER :: intermediate_grid
39 TYPE(domain), POINTER :: ngrid
41 INTEGER i,j,pig,pjg,cm,cn,nig,njg,retval,k,ioffset,ierr
42 INTEGER iparstrt,jparstrt,sw
43 TYPE (grid_config_rec_type) :: config_flags
45 INTEGER :: cids, cide, cjds, cjde, ckds, ckde, &
46 cims, cime, cjms, cjme, ckms, ckme, &
47 cips, cipe, cjps, cjpe, ckps, ckpe
48 INTEGER :: iids, iide, ijds, ijde, ikds, ikde, &
49 iims, iime, ijms, ijme, ikms, ikme, &
50 iips, iipe, ijps, ijpe, ikps, ikpe
51 INTEGER :: nids, nide, njds, njde, nkds, nkde, &
52 nims, nime, njms, njme, nkms, nkme, &
53 nips, nipe, njps, njpe, nkps, nkpe
55 INTEGER idim1,idim2,idim3,idim4,idim5,idim6,idim7
57 INTEGER icoord, jcoord, idim_cd, jdim_cd, pgr
58 INTEGER local_comm, myproc, nproc
59 INTEGER thisdomain_max_halo_width
61 ! CALL wrf_get_dm_communicator ( local_comm )
62 CALL wrf_get_myproc( myproc )
63 CALL wrf_get_nproc( nproc )
65 CALL get_ijk_from_grid ( grid , &
66 cids, cide, cjds, cjde, ckds, ckde, &
67 cims, cime, cjms, cjme, ckms, ckme, &
68 cips, cipe, cjps, cjpe, ckps, ckpe )
69 CALL get_ijk_from_grid ( intermediate_grid , &
70 iids, iide, ijds, ijde, ikds, ikde, &
71 iims, iime, ijms, ijme, ikms, ikme, &
72 iips, iipe, ijps, ijpe, ikps, ikpe )
73 CALL get_ijk_from_grid ( ngrid , &
74 nids, nide, njds, njde, nkds, nkde, &
75 nims, nime, njms, njme, nkms, nkme, &
76 nips, nipe, njps, njpe, nkps, nkpe )
78 CALL nl_get_parent_grid_ratio ( ngrid%id, pgr )
79 CALL nl_get_i_parent_start ( intermediate_grid%id, iparstrt )
80 CALL nl_get_j_parent_start ( intermediate_grid%id, jparstrt )
81 CALL nl_get_shw ( intermediate_grid%id, sw )
82 icoord = iparstrt - sw
83 jcoord = jparstrt - sw
84 idim_cd = iide - iids + 1
85 jdim_cd = ijde - ijds + 1
87 nlev = ckde - ckds + 1
89 CALL get_dm_max_halo_width ( ngrid%id , thisdomain_max_halo_width )
90 CALL wrf_dm_nestexchange_init
92 IF ( grid%active_this_task ) THEN
94 CALL rsl_lite_to_child_info( msize*4 &
95 ,cips,cipe,cjps,cjpe &
96 ,iids,iide,ijds,ijde &
97 ,nids,nide,njds,njde &
99 ,nest_task_offsets(ngrid%id) &
100 ,nest_pes_x(grid%id) &
101 ,nest_pes_y(grid%id) &
102 ,nest_pes_x(intermediate_grid%id) &
103 ,nest_pes_y(intermediate_grid%id) &
104 ,thisdomain_max_halo_width &
108 DO while ( retval .eq. 1 )
109 IF ( SIZE(grid%hres_fis) .GT. 1 ) THEN ! okay for intermediate_grid too. see comment in gen_comms.c
110 xv(1)=grid%hres_fis(pig,pjg)
111 CALL rsl_lite_to_child_msg(4,xv)
113 IF ( SIZE(grid%sm) .GT. 1 ) THEN ! okay for intermediate_grid too. see comment in gen_comms.c
114 xv(1)=grid%sm(pig,pjg)
115 CALL rsl_lite_to_child_msg(4,xv)
117 IF ( SIZE(grid%pd) .GT. 1 ) THEN ! okay for intermediate_grid too. see comment in gen_comms.c
118 xv(1)=grid%pd(pig,pjg)
119 CALL rsl_lite_to_child_msg(4,xv)
121 IF ( SIZE(grid%fis) .GT. 1 ) THEN ! okay for intermediate_grid too. see comment in gen_comms.c
122 xv(1)=grid%fis(pig,pjg)
123 CALL rsl_lite_to_child_msg(4,xv)
125 CALL rsl_lite_to_child_info( msize*4 &
126 ,cips,cipe,cjps,cjpe &
127 ,iids,iide,ijds,ijde &
128 ,nids,nide,njds,njde &
130 ,nest_task_offsets(ngrid%id) &
131 ,nest_pes_x(grid%id) &
132 ,nest_pes_y(grid%id) &
133 ,nest_pes_x(intermediate_grid%id) &
134 ,nest_pes_y(intermediate_grid%id) &
135 ,thisdomain_max_halo_width &
140 ENDIF ! grid%active_this_task
142 IF ( intercomm_active( grid%id ) ) THEN ! I am parent
143 local_comm = mpi_comm_to_kid( which_kid(ngrid%id), grid%id )
144 ioffset = nest_task_offsets(ngrid%id)
145 ELSE IF ( intercomm_active( ngrid%id ) ) THEN ! I am nest
146 local_comm = mpi_comm_to_mom( ngrid%id )
147 ioffset = nest_task_offsets(ngrid%id)
150 IF ( grid%active_this_task .OR. ngrid%active_this_task ) THEN
151 #if defined(DM_PARALLEL) && !defined(STUBMPI)
152 CALL mpi_comm_rank(local_comm,myproc,ierr)
153 CALL mpi_comm_size(local_comm,nproc,ierr)
155 CALL rsl_lite_bcast_msgs( myproc, nest_pes_x(grid%id)*nest_pes_y(grid%id), &
156 nest_pes_x(ngrid%id)*nest_pes_y(ngrid%id), &
157 ioffset, local_comm )
161 END SUBROUTINE parent_to_inter_part1
163 SUBROUTINE parent_to_inter_part2 ( grid, ngrid, config_flags )
164 USE module_state_description
165 USE module_domain, ONLY : domain, get_ijk_from_grid
166 USE module_configure, ONLY : grid_config_rec_type
167 USE module_dm, ONLY : ntasks, ntasks_x, ntasks_y, itrace, local_communicator, mytask, &
168 ipe_save, jpe_save, ips_save, jps_save, get_dm_max_halo_width!, &
169 !push_communicators_for_domain,pop_communicators_for_domain
171 USE module_comm_dm, ONLY : HALO_NMM_INT_UP_sub
174 TYPE(domain), POINTER :: grid
175 TYPE(domain), POINTER :: cgrid
176 TYPE(domain), POINTER :: ngrid
179 INTEGER i,j,pig,pjg,cm,cn,nig,njg,retval,k
180 TYPE (grid_config_rec_type) :: config_flags
182 INTEGER :: cids, cide, cjds, cjde, ckds, ckde, &
183 cims, cime, cjms, cjme, ckms, ckme, &
184 cips, cipe, cjps, cjpe, ckps, ckpe
185 INTEGER :: nids, nide, njds, njde, nkds, nkde, &
186 nims, nime, njms, njme, nkms, nkme, &
187 nips, nipe, njps, njpe, nkps, nkpe
188 INTEGER :: ids, ide, jds, jde, kds, kde, &
189 ims, ime, jms, jme, kms, kme, &
190 ips, ipe, jps, jpe, kps, kpe
192 INTEGER idim1,idim2,idim3,idim4,idim5,idim6,idim7
193 REAL dummy_xs, dummy_xe, dummy_ys, dummy_ye
197 CALL get_ijk_from_grid ( grid , &
198 cids, cide, cjds, cjde, ckds, ckde, &
199 cims, cime, cjms, cjme, ckms, ckme, &
200 cips, cipe, cjps, cjpe, ckps, ckpe )
202 IF ( ngrid%active_this_task ) THEN
203 nlev = ckde - ckds + 1
204 !write(0,*) 'IN parent_to_inter_part2'
205 CALL rsl_lite_from_parent_info(pig,pjg,retval)
206 DO while ( retval .eq. 1 )
207 !write(0,*) 'top of loop'
208 IF ( SIZE(grid%hres_fis) .GT. 1 ) THEN ! okay for intermediate_grid too. see comment in gen_comms.c
209 CALL rsl_lite_from_parent_msg(4,xv)
210 grid%hres_fis(pig,pjg) = xv(1)
213 IF ( SIZE(grid%sm) .GT. 1 ) THEN ! okay for intermediate_grid too. see comment in gen_comms.c
214 CALL rsl_lite_from_parent_msg(4,xv)
215 grid%sm(pig,pjg) = xv(1)
218 IF ( SIZE(grid%pd) .GT. 1 ) THEN ! okay for intermediate_grid too. see comment in gen_comms.c
219 CALL rsl_lite_from_parent_msg(4,xv)
220 grid%pd(pig,pjg) = xv(1)
223 IF ( SIZE(grid%fis) .GT. 1 ) THEN ! okay for intermediate_grid too. see comment in gen_comms.c
224 CALL rsl_lite_from_parent_msg(4,xv)
225 grid%fis(pig,pjg) = xv(1)
227 !write(0,*) 'call rsl_lite_from_parent_info'
228 CALL rsl_lite_from_parent_info(pig,pjg,retval)
229 !write(0,*) 'back with retval=',retval
233 !write(0,*) 'out of loop'
235 CALL get_ijk_from_grid ( grid , &
236 ids, ide, jds, jde, kds, kde, &
237 ims, ime, jms, jme, kms, kme, &
238 ips, ipe, jps, jpe, kps, kpe )
240 CALL push_communicators_for_domain( grid%id )
241 #include "HALO_NMM_INT_UP.inc"
242 CALL pop_communicators_for_domain
245 CALL wrf_dm_nestexchange_init
247 END SUBROUTINE parent_to_inter_part2
249 end module module_intermediate_nmm