updated top-level README and version_decl for V4.4.2 (#1795)
[WRF.git] / share / track_driver.F
blob4711cd61832d2f2060c2e41c7e91f912357f5186
1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2 ! This routine prints out the current value of variables at all specified
3 !   track locations that are within the current patch.
5 ! Jeff Lee -- 25 June 2009
6 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
7 SUBROUTINE track_driver( grid )
9    USE module_domain
10    USE module_configure
11    USE module_state_description
12    USE module_scalar_tables
13    USE module_model_constants
14    USE module_date_time
16    IMPLICIT NONE
18    ! Arguments
19    TYPE (domain), INTENT(INOUT) :: grid
20 #if ( EM_CORE == 1 )
21    LOGICAL, EXTERNAL :: wrf_dm_on_monitor
23    ! Local variables
25    INTEGER :: level
26    INTEGER :: level_stag
27    INTEGER :: level_zref
28    INTEGER :: num_tuv
29    INTEGER :: num_rad
30    INTEGER :: m, n, i
31    INTEGER :: ix, iy
32    TYPE(WRFU_Time) :: xcurrent_time, track_time_test 
33    CHARACTER (LEN=132) :: message
34    CHARACTER (LEN=19) :: xcurrent_timestr
35    CHARACTER (LEN=19) :: chem_name
36    
37 !============================================================================================
38    
39    IF ( grid%track_loc_domain <= 0 ) RETURN     ! no valid location
41 #if ( DA_CORE != 1 )
42    IF ( grid%dfi_opt /= DFI_NODFI .AND. grid%dfi_stage /= DFI_FST ) RETURN
43 #endif
45 ! get the next valid track time
47    n = grid%track_next_time
49    IF ( grid%track_next_time > grid%track_loc_domain ) RETURN   ! all track locations done
51 ! get the track time
53    CALL wrf_atotime( grid%track_time_domain(n), track_time_test )
55 ! get the current time
57    CALL domain_clock_get( grid, current_time=xcurrent_time, current_timestr=xcurrent_timestr )
59    IF ( track_time_test .NE. xcurrent_time ) RETURN  ! track time does not match current time
61 ! track time matches current time
63    write(message,*) 'track_driver: current_time = ',xcurrent_timestr 
64    call wrf_message( trim(message) )
66    level      = grid%em32-grid%sm32
67    level_stag = grid%em32-grid%sm32+1
68 #if (WRF_CHEM == 1)
69    level_zref = model_config_rec%track_tuv_lev
70    num_tuv    = model_config_rec%track_tuv_num
71    num_rad    = model_config_rec%track_rad_num 
72 #endif
74    ix = grid%track_i(n)
75    iy = grid%track_j(n)
76   
77       IF (grid%sp31 <= ix .AND. ix <= grid%ep31 .AND. &
78           grid%sp33 <= iy .AND. iy <= grid%ep33) THEN
80 !-- output chemical species
82 #if ( WRF_CHEM == 1 )
83          IF ( model_config_rec%chem_opt(grid%id) > 0 .and. grid%track_chem_num > 0 ) THEN
84            do m= 1,grid%track_chem_num
85             chem_name = TRIM(model_config_rec%track_chem_name(m))
86               do i = 1, num_chem
87                 if (chem_name .eq. TRIM(chem_dname_table( grid%id, i ))) then
88                   grid%track_chem(m,n,grid%sm32:grid%em32-1) = grid%chem(ix,grid%sm32:grid%em32-1,iy,i)
90 !                 print*,'track_chem_name,pointer = ',chem_name, i
91 !                 print*,'track_chem =',grid%track_chem(m,n,grid%sm32:grid%em32-1)
92                   exit
93                 end if
94               end do
95            end do
97            grid%track_o31d  (n,grid%sm32:grid%em32-1) = grid%ph_o31d  (ix,grid%sm32:grid%em32-1,iy)
98            grid%track_o33p  (n,grid%sm32:grid%em32-1) = grid%ph_o33p  (ix,grid%sm32:grid%em32-1,iy)
99            grid%track_no2   (n,grid%sm32:grid%em32-1) = grid%ph_no2   (ix,grid%sm32:grid%em32-1,iy)
100            grid%track_hno2  (n,grid%sm32:grid%em32-1) = grid%ph_hno2  (ix,grid%sm32:grid%em32-1,iy)
101            grid%track_hno3  (n,grid%sm32:grid%em32-1) = grid%ph_hno3  (ix,grid%sm32:grid%em32-1,iy)
102            grid%track_h2o2  (n,grid%sm32:grid%em32-1) = grid%ph_h2o2  (ix,grid%sm32:grid%em32-1,iy)
103            grid%track_ch3o2h(n,grid%sm32:grid%em32-1) = grid%ph_ch3o2h(ix,grid%sm32:grid%em32-1,iy)
105            if (model_config_rec%phot_opt(grid%id) == 3) then
106              do i = 1, num_rad
107                grid%track_radfld(n,i,1:level_zref) = grid%radfld(ix,1:level_zref,iy,i)
108              end do
110              do i = 1, num_tuv
111                grid%track_adjcoe(n,i,1:level_zref) = grid%adjcoe(ix,1:level_zref,iy,i)
112                grid%track_phrate(n,i,1:level_zref) = grid%phrate(ix,1:level_zref,iy,i)
113              end do
114            endif
115          END IF         
116 #endif
118 !-- output met
120          grid%track_z(n,grid%sm32:grid%em32-1)      = grid%z(ix,grid%sm32:grid%em32-1,iy)
121          grid%track_p(n,grid%sm32:grid%em32-1)      = grid%p(ix,grid%sm32:grid%em32-1,iy) + &
122                                                     grid%pb(ix,grid%sm32:grid%em32-1,iy)
123          if ( grid%use_theta_m == 1 ) then
124             grid%track_t(n,grid%sm32:grid%em32-1)   = (grid%t_2(ix,grid%sm32:grid%em32-1,iy) + t0 ) * &
125                                                     (grid%track_p(n,grid%sm32:grid%em32-1)/p1000mb)**rcp / &
126                                                     (1.+R_v/R_d*grid%moist(ix,grid%sm32:grid%em32-1,iy,P_QV))
127          else
128             grid%track_t(n,grid%sm32:grid%em32-1)   = (grid%t_2(ix,grid%sm32:grid%em32-1,iy) + t0 ) * &
129                                                     (grid%track_p(n,grid%sm32:grid%em32-1)/p1000mb)**rcp
130          end if
131          grid%track_u(n,grid%sm32:grid%em32-1)      = (grid%u_2(ix,grid%sm32:grid%em32-1,iy) + &
132                                                      grid%u_2(ix+1,grid%sm32:grid%em32-1,iy) )*0.5
133          grid%track_v(n,grid%sm32:grid%em32-1)      = (grid%v_2(ix,grid%sm32:grid%em32-1,iy) + &
134                                                      grid%v_2(ix,grid%sm32:grid%em32-1,iy+1) )*0.5
135          grid%track_w(n,grid%sm32:grid%em32)      = grid%w_2(ix,grid%sm32:grid%em32,iy)
136          grid%track_rh(n,grid%sm32:grid%em32-1)     = MIN( 1.00,grid%moist(ix,grid%sm32:grid%em32-1,iy,P_QV) /      &
137                                                     (3.80*exp(17.27*(grid%track_t(n,grid%sm32:grid%em32-1)-273.)/ &
138                                                     (grid%track_t(n,grid%sm32:grid%em32-1)-36.))/                 &
139                                                     (.01*grid%track_p(n,grid%sm32:grid%em32-1)))   )
140          grid%track_alt(n,grid%sm32:grid%em32-1)    = grid%alt(ix,grid%sm32:grid%em32-1,iy)
141          grid%track_qcloud(n,grid%sm32:grid%em32-1) = grid%moist(ix,grid%sm32:grid%em32-1,iy,P_QC)
142          grid%track_qrain (n,grid%sm32:grid%em32-1) = grid%moist(ix,grid%sm32:grid%em32-1,iy,P_QR)
143          grid%track_qice  (n,grid%sm32:grid%em32-1) = grid%moist(ix,grid%sm32:grid%em32-1,iy,P_QI)
144          grid%track_qsnow (n,grid%sm32:grid%em32-1) = grid%moist(ix,grid%sm32:grid%em32-1,iy,P_QS)
145          grid%track_qgraup(n,grid%sm32:grid%em32-1) = grid%moist(ix,grid%sm32:grid%em32-1,iy,P_QG)
146          grid%track_qvapor(n,grid%sm32:grid%em32-1) = grid%moist(ix,grid%sm32:grid%em32-1,iy,P_QV)
148 !        print*,'track_z =',grid%track_z(n,grid%sm32:grid%em32-1)
149        
150       ELSE
152 !--      this section must have.
154 !-- output chem
156 #if ( WRF_CHEM == 1 )
158          IF ( model_config_rec%chem_opt(grid%id) > 0 .and. grid%track_chem_num > 0 ) THEN
159            do m= 1,grid%track_chem_num
160             grid%track_chem(m,n,grid%sm32:grid%em32-1) = 1.E30
161            end do
163            grid%track_o31d  (n,grid%sm32:grid%em32-1) = 1.E30
164            grid%track_o33p  (n,grid%sm32:grid%em32-1) = 1.E30
165            grid%track_no2   (n,grid%sm32:grid%em32-1) = 1.E30
166            grid%track_hno2  (n,grid%sm32:grid%em32-1) = 1.E30
167            grid%track_hno3  (n,grid%sm32:grid%em32-1) = 1.E30
168            grid%track_h2o2  (n,grid%sm32:grid%em32-1) = 1.E30
169            grid%track_ch3o2h(n,grid%sm32:grid%em32-1) = 1.E30
171            if (model_config_rec%phot_opt(grid%id) == 3) then
172              grid%track_radfld(n,1:num_rad,1:level_zref) = 1.E30
173              grid%track_adjcoe(n,1:num_tuv,1:level_zref) = 1.E30
174              grid%track_phrate(n,1:num_tuv,1:level_zref) = 1.E30
175            end if
176          ENDIF     
177 #endif
179 !-- output met
181          grid%track_z     (n,grid%sm32:grid%em32-1) = 1.E30
182          grid%track_p     (n,grid%sm32:grid%em32-1) = 1.E30
183          grid%track_t     (n,grid%sm32:grid%em32-1) = 1.E30
184          grid%track_u     (n,grid%sm32:grid%em32-1) = 1.E30
185          grid%track_v     (n,grid%sm32:grid%em32-1) = 1.E30
186          grid%track_w     (n,grid%sm32:grid%em32) = 1.E30
187          grid%track_rh    (n,grid%sm32:grid%em32-1) = 1.E30
188          grid%track_alt   (n,grid%sm32:grid%em32-1) = 1.E30
190          grid%track_qcloud(n,grid%sm32:grid%em32-1) = 1.E30
191          grid%track_qrain (n,grid%sm32:grid%em32-1) = 1.E30
192          grid%track_qice  (n,grid%sm32:grid%em32-1) = 1.E30
193          grid%track_qsnow (n,grid%sm32:grid%em32-1) = 1.E30
194          grid%track_qgraup(n,grid%sm32:grid%em32-1) = 1.E30
195          grid%track_qvapor(n,grid%sm32:grid%em32-1) = 1.E30
197       END IF
199 !-- write output to file
201 !     write (*,*) 'grid%track_next_time = ', grid%track_next_time
203    if ( grid%track_next_time == grid%track_loc_domain ) then
204 !     write (*,*) 'grid%track_loc_domain = ', grid%track_loc_domain
205 !     write (*,*) 'track_driver: calling write_track'
207       call write_track(grid)
209       write (*,*) 'track_driver: DONE write_track'
210    end if
212    grid%track_next_time = grid%track_next_time + 1
214 #endif
216 END SUBROUTINE track_driver
219 SUBROUTINE write_track( grid )
221    USE module_dm
222    USE module_domain
223    USE module_configure
225    IMPLICIT NONE
227    ! Arguments
229    TYPE (domain), INTENT(INOUT) :: grid
230 #if ( EM_CORE == 1 )
231    LOGICAL, EXTERNAL :: wrf_dm_on_monitor
232    INTEGER, EXTERNAL :: get_unused_unit
234    ! Local variables
236    INTEGER :: level
237    INTEGER :: level_stag
238    INTEGER :: level_zref
239    INTEGER :: num_tuv
240    INTEGER :: num_rad
241    INTEGER :: m,n
242    INTEGER :: i
243    INTEGER :: ncid
244    INTEGER :: astat
245    CHARACTER (LEN=19) :: track_output
246    CHARACTER (LEN=19) :: chem_name
248    character (len=40) :: description
249    character (len=40) :: units
251    integer, parameter :: DateStrLen = 19
252    integer            :: time_dim
253    integer            :: level_dim
254    integer            :: level_stag_dim
255    integer            :: level_zref_dim
256    integer            :: rad_dim
257    integer            :: tuv_dim
258    integer            :: Times_dim
259    integer            :: var_dim(3)
260    integer            :: var_id
261    integer            :: start(3)
262    integer            :: count(3) 
264 #ifdef DM_PARALLEL
265    REAL, ALLOCATABLE, DIMENSION(:,:)   :: track_buf2
266 #if ( WRF_CHEM == 1 )
267    REAL, ALLOCATABLE, DIMENSION(:,:,:) :: track_buf3
268 #endif
269 #endif
271 !====================================================================================
272 #if 1
273 !We actually always need to include 'netcdf.inc',
274 !as this routine won't compile without netcdf.
275 include 'netcdf.inc'
276 #else
277 #ifdef NETCDF
278 include 'netcdf.inc'
279 #endif
280 #endif
283    IF ( grid%track_loc_domain .LE. 0 ) RETURN
285 #if ( DA_CORE != 1 )
286    IF ( grid%dfi_opt /= DFI_NODFI .AND. grid%dfi_stage /= DFI_FST ) RETURN
287 #endif
289    level      = grid%em32 - grid%sm32
290    level_stag = grid%em32 - grid%sm32 + 1  
291 #if (WRF_CHEM == 1)
292    level_zref = model_config_rec%track_tuv_lev
293    num_tuv    = model_config_rec%track_tuv_num
294    num_rad    = model_config_rec%track_rad_num
295 #endif
297 #ifdef DM_PARALLEL
299    ALLOCATE(track_buf2(grid%track_loc_in, level))
301 !--put z output in grid%track_z(:,:)
302 !z 
303    track_buf2(:,:) = grid%track_z(:,:)
304    CALL wrf_dm_min_reals(track_buf2(:,:),grid%track_z(:,:),grid%track_loc_in*level)
306    track_buf2(:,:) = grid%track_p(:,:)
307    CALL wrf_dm_min_reals(track_buf2(:,:),grid%track_p(:,:),grid%track_loc_in*level)
309    track_buf2(:,:) = grid%track_t(:,:)
310    CALL wrf_dm_min_reals(track_buf2(:,:),grid%track_t(:,:),grid%track_loc_in*level)
312    track_buf2(:,:) = grid%track_u(:,:)
313    CALL wrf_dm_min_reals(track_buf2(:,:),grid%track_u(:,:),grid%track_loc_in*level)
315    track_buf2(:,:) = grid%track_v(:,:)
316    CALL wrf_dm_min_reals(track_buf2(:,:),grid%track_v(:,:),grid%track_loc_in*level)
318 !  track_buf2(:,:) = grid%track_w(:,:)
319 !  CALL wrf_dm_min_reals(track_buf2(:,:),grid%track_w(:,:),grid%track_loc_in*level)
321    track_buf2(:,:) = grid%track_rh(:,:)
322    CALL wrf_dm_min_reals(track_buf2(:,:),grid%track_rh(:,:),grid%track_loc_in*level)
323 !alt
324    track_buf2(:,:) = grid%track_alt(:,:)
325    CALL wrf_dm_min_reals(track_buf2(:,:),grid%track_alt(:,:),grid%track_loc_in*level)
326 !qcloud
327    track_buf2(:,:) = grid%track_qcloud(:,:)
328    CALL wrf_dm_min_reals(track_buf2(:,:),grid%track_qcloud(:,:),grid%track_loc_in*level)
329 !qrain
330    track_buf2(:,:) = grid%track_qrain(:,:)
331    CALL wrf_dm_min_reals(track_buf2(:,:),grid%track_qrain(:,:),grid%track_loc_in*level)
332 !qice
333    track_buf2(:,:) = grid%track_qice(:,:)
334    CALL wrf_dm_min_reals(track_buf2(:,:),grid%track_qice(:,:),grid%track_loc_in*level)
335 !qsnow
336    track_buf2(:,:) = grid%track_qsnow(:,:)
337    CALL wrf_dm_min_reals(track_buf2(:,:),grid%track_qsnow(:,:),grid%track_loc_in*level)
338 !qgraup
339    track_buf2(:,:) = grid%track_qgraup(:,:)
340    CALL wrf_dm_min_reals(track_buf2(:,:),grid%track_qgraup(:,:),grid%track_loc_in*level)
341 !qvapor
342    track_buf2(:,:) = grid%track_qvapor(:,:)
343    CALL wrf_dm_min_reals(track_buf2(:,:),grid%track_qvapor(:,:),grid%track_loc_in*level)
345 #if ( WRF_CHEM == 1 )
346    IF (model_config_rec%chem_opt(grid%id) > 0) THEN
347 !o31d
348    track_buf2(:,:) = grid%track_o31d(:,:)
349    CALL wrf_dm_min_reals(track_buf2(:,:),grid%track_o31d(:,:),grid%track_loc_in*level)
350 !o33p
351    track_buf2(:,:) = grid%track_o33p(:,:)
352    CALL wrf_dm_min_reals(track_buf2(:,:),grid%track_o33p(:,:),grid%track_loc_in*level)
353 !no2
354    track_buf2(:,:) = grid%track_no2(:,:)
355    CALL wrf_dm_min_reals(track_buf2(:,:),grid%track_no2(:,:),grid%track_loc_in*level)
356 !hno2
357    track_buf2(:,:) = grid%track_hno2(:,:)
358    CALL wrf_dm_min_reals(track_buf2(:,:),grid%track_hno2(:,:),grid%track_loc_in*level)
359 !hno3
360    track_buf2(:,:) = grid%track_hno3(:,:)
361    CALL wrf_dm_min_reals(track_buf2(:,:),grid%track_hno3(:,:),grid%track_loc_in*level)
362 !h2o2
363    track_buf2(:,:) = grid%track_h2o2(:,:)
364    CALL wrf_dm_min_reals(track_buf2(:,:),grid%track_h2o2(:,:),grid%track_loc_in*level)
365 !ch3o2h
366    track_buf2(:,:) = grid%track_ch3o2h(:,:)
367    CALL wrf_dm_min_reals(track_buf2(:,:),grid%track_ch3o2h(:,:),grid%track_loc_in*level)
369    END IF
370 #endif
372    DEALLOCATE(track_buf2)
374    ALLOCATE(track_buf2(grid%track_loc_in, level_stag))
376    track_buf2(:,:) = grid%track_w(:,:)
377    CALL wrf_dm_min_reals(track_buf2(:,:),grid%track_w(:,:),grid%track_loc_in*level_stag)
379    DEALLOCATE(track_buf2)
381 #if ( WRF_CHEM == 1 )
383 !--put chem output in grid%track_chem(:,:,:)
384 !chem
385    IF ( model_config_rec%chem_opt(grid%id) > 0 .and. grid%track_chem_num > 0 ) THEN
387    ALLOCATE(track_buf3(grid%track_chem_num, grid%track_loc_in, level))
389    track_buf3(:,:,:) = grid%track_chem(:,:,:)
390    CALL wrf_dm_min_reals(track_buf3(:,:,:),grid%track_chem(:,:,:),grid%track_chem_num*grid%track_loc_in*level)
392    DEALLOCATE(track_buf3)
394    if (model_config_rec%phot_opt(grid%id) == 3) then
395 !radfld
396    ALLOCATE(track_buf3(grid%track_loc_in, num_rad, level_zref))
398    track_buf3(:,:,:) = grid%track_radfld(:,:,:)
399    CALL wrf_dm_min_reals(track_buf3(:,:,:),grid%track_radfld(:,:,:),grid%track_loc_in*num_rad*level_zref)
401    DEALLOCATE(track_buf3)
403    ALLOCATE(track_buf3(grid%track_loc_in, num_tuv, level_zref))
404 !adjcoe
405    track_buf3(:,:,:) = grid%track_adjcoe(:,:,:)
406    CALL wrf_dm_min_reals(track_buf3(:,:,:),grid%track_adjcoe(:,:,:),grid%track_loc_in*num_tuv*level_zref)
407 !phrate
408    track_buf3(:,:,:) = grid%track_phrate(:,:,:)
409    CALL wrf_dm_min_reals(track_buf3(:,:,:),grid%track_phrate(:,:,:),grid%track_loc_in*num_tuv*level_zref)
411    DEALLOCATE(track_buf3)
412    
413    end if
415    END IF
416 #endif
418 #endif
420    IF ( wrf_dm_on_monitor() ) THEN
422 !--   get output unit
424 !     ncid = get_unused_unit()
425 !     if ( ncid <= 0 ) then
426 !        call wrf_error_fatal('write_track: ERROR: could not find a free Fortran unit.')
427 !     end if
429 !--   get output file name
431       write (track_output,'(A)') trim('wrfout_track_d00')
432       i = len_trim(track_output)
433       write ( track_output(i-1:i), '(I2.2)') grid%id
435 !--   create necdf file
437       astat = NF_CREATE(track_output, NF_CLOBBER, ncid)
438       if (astat .ne. NF_NOERR) then
439          call wrf_abort
440       end if
442 !--   define dimensions
444       astat = NF_DEF_DIM(ncid, 'time'       , NF_UNLIMITED , time_dim )
445       astat = NF_DEF_DIM(ncid, 'level'      , level        , level_dim)
446       astat = NF_DEF_DIM(ncid, 'DateStrLen' , DateStrLen   , Times_dim)
447       astat = NF_DEF_DIM(ncid, 'level_stag' , level_stag   , level_stag_dim)
449 #if ( WRF_CHEM == 1 )
450       IF ( model_config_rec%chem_opt(grid%id) > 0 .and. model_config_rec%phot_opt(grid%id) == 3 ) THEN
451       astat = NF_DEF_DIM(ncid, 'level_zref' , level_zref   , level_zref_dim)
452       astat = NF_DEF_DIM(ncid, 'num_rad'    , num_rad      , rad_dim)
453       astat = NF_DEF_DIM(ncid, 'num_tuv'    , num_tuv      , tuv_dim)
454       END IF
455 #endif
457 !--   define Times variable
459       var_dim(1) = Times_dim
460       var_dim(2) = time_dim
462       astat = NF_DEF_VAR(ncid,'Times', NF_CHAR, 2, var_dim(1:2), var_id)
464 !--   define 1-D variables
466 #if ( WRF_CHEM == 1 )
467       IF ( model_config_rec%chem_opt(grid%id) > 0 .and. model_config_rec%phot_opt(grid%id) == 3 ) THEN
469       description = 'Wavelength'
470       units       = ''
471       astat = NF_DEF_VAR(ncid, 'wc'   , NF_REAL, 1, rad_dim, var_id  )
472       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
473       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
474 !zref
475       description = 'Reference height'
476       units       = 'km'
477       astat = NF_DEF_VAR(ncid, 'zref'   , NF_REAL, 1, level_zref_dim, var_id  )
478       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
479       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
481       END IF
482 #endif
484 !lat
485       description = 'LATITUDE, SOUTH IS NEGATIVE'
486       units       = 'degree_north'
487       astat = NF_DEF_VAR(ncid, 'lat'   , NF_REAL, 1, time_dim, var_id  )
488       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
489       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
490 !lon
491       description = 'LONGITUDE, WEST IS NEGATIVE'
492       units       = 'degree_east'
493       astat = NF_DEF_VAR(ncid, 'lon'   , NF_REAL, 1, time_dim, var_id  )
494       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
495       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
496 !grid_i
497       description = 'grid_i, longitude direction '
498       units       = ''
499       astat = NF_DEF_VAR(ncid, 'grid_i'   , NF_INT, 1, time_dim, var_id  )
500       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
501       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
502 !grid_j
503       description = 'grid_j, latitude direction '
504       units       = ''
505       astat = NF_DEF_VAR(ncid, 'grid_j'   , NF_INT, 1, time_dim, var_id  )
506       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
507       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
508 !ele
509       description = 'elevation'
510       units       = 'm'
511       astat = NF_DEF_VAR(ncid, 'ele'   , NF_REAL, 1, time_dim, var_id  )
512       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
513       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
515 !--   define 2-D variables
517       var_dim(1) = level_dim
518       var_dim(2) = time_dim
520       description = 'height'
521       units       = 'm'
522       astat = NF_DEF_VAR(ncid, 'z', NF_REAL, 2 , var_dim(1:2), var_id )
523       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
524       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
526       description = 'pressure'
527       units       = 'Pa'
528       astat = NF_DEF_VAR(ncid, 'p', NF_REAL, 2 , var_dim(1:2), var_id )
529       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
530       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
532       description = 'temperature'
533       units       = 'K'
534       astat = NF_DEF_VAR(ncid, 't', NF_REAL, 2 , var_dim(1:2), var_id )
535       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
536       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
538       description = 'x-wind component'
539       units       = 'm s-1'
540       astat = NF_DEF_VAR(ncid, 'u', NF_REAL, 2 , var_dim(1:2), var_id )
541       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
542       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
544       description = 'y-wind component'
545       units       = 'm s-1'
546       astat = NF_DEF_VAR(ncid, 'v', NF_REAL, 2 , var_dim(1:2), var_id )
547       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
548       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
550 !     description = 'z-wind component'
551 !     units       = 'm s-1'
552 !     astat = NF_DEF_VAR(ncid, 'w', NF_REAL, 2 , var_dim(1:2), var_id )
553 !     astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
554 !     astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
556       description = 'relative humidity'
557       units       = 'fraction'
558       astat = NF_DEF_VAR(ncid, 'rh', NF_REAL, 2 , var_dim(1:2), var_id )
559       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
560       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
561 !alt
562       description = 'inverse density'
563       units       = 'm3 Kg-1'
564       astat = NF_DEF_VAR(ncid, 'alt', NF_REAL, 2 , var_dim(1:2), var_id )
565       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
566       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
567 !qcloud
568       description = 'Cloud water mixing ratio'
569       units       = 'kg kg-1'
570       astat = NF_DEF_VAR(ncid, 'qcloud', NF_REAL, 2 , var_dim(1:2), var_id )
571       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
572       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
573 !qrain
574       description = 'Rain water mixing ratio'
575       units       = 'kg kg-1'
576       astat = NF_DEF_VAR(ncid, 'qrain', NF_REAL, 2 , var_dim(1:2), var_id )
577       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
578       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
579 !qice
580       description = 'Ice mixing ratio'
581       units       = 'kg kg-1'
582       astat = NF_DEF_VAR(ncid, 'qice', NF_REAL, 2 , var_dim(1:2), var_id )
583       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
584       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
585 !qsnow
586       description = 'Snow mixing ratio'
587       units       = 'kg kg-1'
588       astat = NF_DEF_VAR(ncid, 'qsnow', NF_REAL, 2 , var_dim(1:2), var_id )
589       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
590       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
591 !qgraup
592       description = 'Graupel mixing ratio'
593       units       = 'kg kg-1'
594       astat = NF_DEF_VAR(ncid, 'qgraup', NF_REAL, 2 , var_dim(1:2), var_id )
595       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
596       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
597 !qvapor
598       description = 'Water vapor mixing ratio'
599       units       = 'kg kg-1'
600       astat = NF_DEF_VAR(ncid, 'qvapor', NF_REAL, 2 , var_dim(1:2), var_id )
601       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
602       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
604 #if ( WRF_CHEM == 1 )
606       IF ( model_config_rec%chem_opt(grid%id) > 0 .and. grid%track_chem_num > 0 ) THEN
607 !chem
608       units       = 'ppmv'
609       do m= 1,grid%track_chem_num
610          chem_name = trim(model_config_rec%track_chem_name(m))
611          description = trim(chem_name) // ' concentration'
612          astat = NF_DEF_VAR(ncid, trim(chem_name), NF_REAL, 2, var_dim(1:2), var_id )
613          astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
614          astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
615       end do
617       units       = 'min-1'
618 !o31d
619       chem_name   = 'photr_o31d' 
620       description = 'O31D Photolysis Rate'
621       astat = NF_DEF_VAR(ncid, trim(chem_name), NF_REAL, 2, var_dim(1:2), var_id )
622       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
623       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
624 !o33p
625       chem_name   = 'photr_o33p' 
626       description = 'O33P Photolysis Rate'
627       astat = NF_DEF_VAR(ncid, trim(chem_name), NF_REAL, 2, var_dim(1:2), var_id )
628       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
629       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
630 !no2
631       chem_name   = 'photr_no2' 
632       description = 'NO2 Photolysis Rate'
633       astat = NF_DEF_VAR(ncid, trim(chem_name), NF_REAL, 2, var_dim(1:2), var_id )
634       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
635       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
636 !hno2
637       chem_name   = 'photr_hno2' 
638       description = 'HNO2 Photolysis Rate'
639       astat = NF_DEF_VAR(ncid, trim(chem_name), NF_REAL, 2, var_dim(1:2), var_id )
640       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
641       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
642 !hno3
643       chem_name   = 'photr_hno3' 
644       description = 'HNO3 Photolysis Rate'
645       astat = NF_DEF_VAR(ncid, trim(chem_name), NF_REAL, 2, var_dim(1:2), var_id )
646       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
647       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
648 !h2o2
649       chem_name   = 'photr_h2o2' 
650       description = 'H2O2 Photolysis Rate'
651       astat = NF_DEF_VAR(ncid, trim(chem_name), NF_REAL, 2, var_dim(1:2), var_id )
652       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
653       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
654 !ch3o2h
655       chem_name   = 'photr_ch3o2h' 
656       description = 'CH3O2H Photolysis Rate'
657       astat = NF_DEF_VAR(ncid, trim(chem_name), NF_REAL, 2, var_dim(1:2), var_id )
658       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
659       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
661       if (model_config_rec%phot_opt(grid%id) == 3 ) then
663       units       = ''
664 !radfld
665       var_dim(1) = level_zref_dim
666       var_dim(2) = rad_dim
667       var_dim(3) = time_dim
668       chem_name   = 'radfld' 
669       description = 'radfld'
670       astat = NF_DEF_VAR(ncid, trim(chem_name), NF_REAL, 3, var_dim(1:3), var_id )
671       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
672       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
673 !adjcoe
674       var_dim(1) = level_zref_dim
675       var_dim(2) = tuv_dim
676       var_dim(3) = time_dim
677       chem_name   = 'adjcoe' 
678       description = 'adjcoe'
679       astat = NF_DEF_VAR(ncid, trim(chem_name), NF_REAL, 3, var_dim(1:3), var_id )
680       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
681       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
682 !phrate
683       var_dim(1) = level_zref_dim
684       var_dim(2) = tuv_dim
685       var_dim(3) = time_dim
686       chem_name   = 'phrate' 
687       description = 'phrate'
688       astat = NF_DEF_VAR(ncid, trim(chem_name), NF_REAL, 3, var_dim(1:3), var_id )
689       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
690       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
692       end if
694       END IF
695 #endif
698       var_dim(1) = level_stag_dim
699       var_dim(2) = time_dim
700       description = 'z-wind component'
701       units       = 'm s-1'
702       astat = NF_DEF_VAR(ncid, 'w', NF_REAL, 2 , var_dim(1:2), var_id )
703       astat = NF_PUT_ATT_TEXT(ncid,var_id,'description', len_trim(description),description)
704       astat = NF_PUT_ATT_TEXT(ncid,var_id,'units',       len_trim(units),      units      )
706 ! --  end define
708       astat = NF_ENDDEF(ncid)
710 !--   write Times variable
711 !Times
712       start(1) = 1
713       start(2) = 1
714       count(1) = DateStrLen
715       count(2) = 1
717       astat = NF_INQ_VARID(ncid,'Times',var_id)
718       do m= 1,grid%track_loc_domain
719          start(2) = m
720          astat = NF_PUT_VARA_TEXT(ncid,var_id,start,count,grid%track_time_domain(m))
721       end do
722       write (*,*) 'var_id,grid%track_time_domain = ', var_id,grid%track_time_domain
724 !--   write 1-D variables
726 #if ( WRF_CHEM == 1 )
727       IF ( model_config_rec%chem_opt(grid%id) > 0 .and. grid%track_chem_num > 0 ) THEN
728       if ( model_config_rec%phot_opt(grid%id) == 3 )then
730       start(2) = 1
731       count(2) = num_rad
733       astat = NF_INQ_VARID(ncid,'wc',var_id)
734       astat = NF_PUT_VARA_REAL(ncid,var_id,start(2),count(2),grid%track_wc)
735 !zref
736       start(2) = 1
737       count(2) = level_zref
739       astat = NF_INQ_VARID(ncid,'zref',var_id)
740       astat = NF_PUT_VARA_REAL(ncid,var_id,start(2),count(2),grid%track_zref)
742       end if
744       END IF
745 #endif
747 !lat
748       start(2) = 1
749       count(2) = grid%track_loc_domain
751       astat = NF_INQ_VARID(ncid,'lat',var_id)
752       astat = NF_PUT_VARA_REAL(ncid,var_id,start(2),count(2),grid%track_lat_domain)
753       write (*,*) 'var_id,grid%track_lat_domain = ', var_id,grid%track_lat_domain
754 !lon
755       astat = NF_INQ_VARID(ncid,'lon',var_id)
756       astat = NF_PUT_VARA_REAL(ncid,var_id,start(2),count(2),grid%track_lon_domain)
757       write (*,*) 'var_id,grid%track_lon_domain = ', var_id,grid%track_lon_domain
758 !grid_i
759       astat = NF_INQ_VARID(ncid,'grid_i',var_id)
760       astat = NF_PUT_VARA_INT(ncid,var_id,start(2),count(2),grid%track_i)
761 !grid_j
762       astat = NF_INQ_VARID(ncid,'grid_j',var_id)
763       astat = NF_PUT_VARA_INT(ncid,var_id,start(2),count(2),grid%track_j)
764 !ele
765       astat = NF_INQ_VARID(ncid,'ele',var_id)
766       astat = NF_PUT_VARA_REAL(ncid,var_id,start(2),count(2),grid%track_ele)
767       write (*,*) 'var_id,grid%track_ele = ', var_id,grid%track_ele
769 !--   write 2-D variables
771       start(1) = 1
772       start(2) = 1
773       count(1) = level
774       count(2) = 1
776       astat = NF_INQ_VARID(ncid,'z',var_id)
777       do m= 1,grid%track_loc_domain
778          start(2) = m
779          astat = NF_PUT_VARA_REAL(ncid,var_id,start(1:2),count(1:2),grid%track_z(m,:))
780       end do
782       astat = NF_INQ_VARID(ncid,'p',var_id)
783       do m= 1,grid%track_loc_domain
784          start(2) = m
785          astat = NF_PUT_VARA_REAL(ncid,var_id,start(1:2),count(1:2),grid%track_p(m,:))
786       end do
788       astat = NF_INQ_VARID(ncid,'t',var_id)
789       do m= 1,grid%track_loc_domain
790          start(2) = m
791          astat = NF_PUT_VARA_REAL(ncid,var_id,start(1:2),count(1:2),grid%track_t(m,:))
792       end do
794       astat = NF_INQ_VARID(ncid,'u',var_id)
795       do m= 1,grid%track_loc_domain
796          start(2) = m
797          astat = NF_PUT_VARA_REAL(ncid,var_id,start(1:2),count(1:2),grid%track_u(m,:))
798       end do
800       astat = NF_INQ_VARID(ncid,'v',var_id)
801       do m= 1,grid%track_loc_domain
802          start(2) = m
803          astat = NF_PUT_VARA_REAL(ncid,var_id,start(1:2),count(1:2),grid%track_v(m,:))
804       end do
806 !     astat = NF_INQ_VARID(ncid,'w',var_id)
807 !     do m= 1,grid%track_loc_domain
808 !        start(2) = m
809 !        astat = NF_PUT_VARA_REAL(ncid,var_id,start(1:2),count(1:2),grid%track_w(m,:))
810 !     end do
812       astat = NF_INQ_VARID(ncid,'rh',var_id)
813       do m= 1,grid%track_loc_domain
814          start(2) = m
815          astat = NF_PUT_VARA_REAL(ncid,var_id,start(1:2),count(1:2),grid%track_rh(m,:))
816       end do
817 !alt
818       astat = NF_INQ_VARID(ncid,'alt',var_id)
819       do m= 1,grid%track_loc_domain
820          start(2) = m
821          astat = NF_PUT_VARA_REAL(ncid,var_id,start(1:2),count(1:2),grid%track_alt(m,:))
822       end do
823 !qcloud
824       astat = NF_INQ_VARID(ncid,'qcloud',var_id)
825       do m= 1,grid%track_loc_domain
826          start(2) = m
827          astat = NF_PUT_VARA_REAL(ncid,var_id,start(1:2),count(1:2),grid%track_qcloud(m,:))
828       end do
829 !qrain
830       astat = NF_INQ_VARID(ncid,'qrain',var_id)
831       do m= 1,grid%track_loc_domain
832          start(2) = m
833          astat = NF_PUT_VARA_REAL(ncid,var_id,start(1:2),count(1:2),grid%track_qrain(m,:))
834       end do
835 !qice
836       astat = NF_INQ_VARID(ncid,'qice',var_id)
837       do m= 1,grid%track_loc_domain
838          start(2) = m
839          astat = NF_PUT_VARA_REAL(ncid,var_id,start(1:2),count(1:2),grid%track_qice(m,:))
840       end do
841 !qsnow
842       astat = NF_INQ_VARID(ncid,'qsnow',var_id)
843       do m= 1,grid%track_loc_domain
844          start(2) = m
845          astat = NF_PUT_VARA_REAL(ncid,var_id,start(1:2),count(1:2),grid%track_qsnow(m,:))
846       end do
847 !qgraup
848       astat = NF_INQ_VARID(ncid,'qgraup',var_id)
849       do m= 1,grid%track_loc_domain
850          start(2) = m
851          astat = NF_PUT_VARA_REAL(ncid,var_id,start(1:2),count(1:2),grid%track_qgraup(m,:))
852       end do
853 !qvapor
854       astat = NF_INQ_VARID(ncid,'qvapor',var_id)
855       do m= 1,grid%track_loc_domain
856          start(2) = m
857          astat = NF_PUT_VARA_REAL(ncid,var_id,start(1:2),count(1:2),grid%track_qvapor(m,:))
858       end do
860 #if ( WRF_CHEM == 1 )
861 !chem
862       IF ( model_config_rec%chem_opt(grid%id) > 0 .and. grid%track_chem_num > 0 ) THEN
864       do n= 1,grid%track_chem_num
865          chem_name = trim(model_config_rec%track_chem_name(n))
866          astat = NF_INQ_VARID(ncid,trim(chem_name),var_id)
868          do m= 1,grid%track_loc_domain
869             start(2) = m
870             astat = NF_PUT_VARA_REAL(ncid,var_id,start(1:2),count(1:2),grid%track_chem(n,m,:))          
871          end do
873 !        write (*,*) 'n, var_id, chem_name = ', n, var_id, trim(chem_name)
874       end do
876 !o31d
877       astat = NF_INQ_VARID(ncid,'photr_o31d',var_id)
878       do m= 1,grid%track_loc_domain
879          start(2) = m
880          astat = NF_PUT_VARA_REAL(ncid,var_id,start(1:2),count(1:2),grid%track_o31d(m,:))
881       end do
882 !o33p
883       astat = NF_INQ_VARID(ncid,'photr_o33p',var_id)
884       do m= 1,grid%track_loc_domain
885          start(2) = m
886          astat = NF_PUT_VARA_REAL(ncid,var_id,start(1:2),count(1:2),grid%track_o33p(m,:))
887       end do
888 !no2
889       astat = NF_INQ_VARID(ncid,'photr_no2',var_id)
890       do m= 1,grid%track_loc_domain
891          start(2) = m
892          astat = NF_PUT_VARA_REAL(ncid,var_id,start(1:2),count(1:2),grid%track_no2(m,:))
893       end do
894 !hno2
895       astat = NF_INQ_VARID(ncid,'photr_hno2',var_id)
896       do m= 1,grid%track_loc_domain
897          start(2) = m
898          astat = NF_PUT_VARA_REAL(ncid,var_id,start(1:2),count(1:2),grid%track_hno2(m,:))
899       end do
900 !hno3
901       astat = NF_INQ_VARID(ncid,'photr_hno3',var_id)
902       do m= 1,grid%track_loc_domain
903          start(2) = m
904          astat = NF_PUT_VARA_REAL(ncid,var_id,start(1:2),count(1:2),grid%track_hno3(m,:))
905       end do
906 !h2o2
907       astat = NF_INQ_VARID(ncid,'photr_h2o2',var_id)
908       do m= 1,grid%track_loc_domain
909          start(2) = m
910          astat = NF_PUT_VARA_REAL(ncid,var_id,start(1:2),count(1:2),grid%track_h2o2(m,:))
911       end do
912 !ch3o2h
913       astat = NF_INQ_VARID(ncid,'photr_ch3o2h',var_id)
914       do m= 1,grid%track_loc_domain
915          start(2) = m
916          astat = NF_PUT_VARA_REAL(ncid,var_id,start(1:2),count(1:2),grid%track_ch3o2h(m,:))
917       end do
919       if (model_config_rec%phot_opt(grid%id) == 3 ) then
920 !radfld
921       start(1) = 1
922       start(2) = 1
923       start(3) = 1
924       count(1) = level_zref
925       count(2) = 1
926       count(3) = 1
928       astat = NF_INQ_VARID(ncid,'radfld',var_id)
929       do m= 1,grid%track_loc_domain
930       do n= 1,num_rad
931          start(2) = n
932          start(3) = m
933          astat = NF_PUT_VARA_REAL(ncid,var_id,start(1:3),count(1:3),grid%track_radfld(m,n,:))
934       end do
935       end do
936 !adjcoe
937       astat = NF_INQ_VARID(ncid,'adjcoe',var_id)
938       do m= 1,grid%track_loc_domain
939       do n= 1,num_tuv
940          start(2) = n
941          start(3) = m
942          astat = NF_PUT_VARA_REAL(ncid,var_id,start(1:3),count(1:3),grid%track_adjcoe(m,n,:))
943       end do
944       end do
945 !phrate
946       astat = NF_INQ_VARID(ncid,'phrate',var_id)
947       do m= 1,grid%track_loc_domain
948       do n= 1,num_tuv
949          start(2) = n
950          start(3) = m
951          astat = NF_PUT_VARA_REAL(ncid,var_id,start(1:3),count(1:3),grid%track_phrate(m,n,:))
952       end do
953       end do
955       end if
957       END IF
958 #endif
961       start(1) = 1
962       start(2) = 1
963       count(1) = level_stag
964       count(2) = 1
966       astat = NF_INQ_VARID(ncid,'w',var_id)
967       do m= 1,grid%track_loc_domain
968          start(2) = m
969          astat = NF_PUT_VARA_REAL(ncid,var_id,start(1:2),count(1:2),grid%track_w(m,:))
970       end do
972 !--   close output unit
974       astat = NF_CLOSE(ncid)
976    END IF
978    grid%track_next_time = 1
979 #endif
981 END SUBROUTINE write_track
983 SUBROUTINE calc_track_locations( grid )
985    USE module_domain
986    USE module_configure
987    USE module_dm
988    USE module_llxy
990    IMPLICIT NONE
992    ! Arguments
993    TYPE (domain), INTENT(INOUT) :: grid
994 #if ( EM_CORE == 1 )
995    ! Externals
996    LOGICAL, EXTERNAL :: wrf_dm_on_monitor
998    ! Local variables
999    INTEGER :: track_loc_temp
1000    INTEGER :: i, k, iunit
1001    REAL :: track_rx, track_ry
1002    REAL :: known_lat, known_lon
1003    CHARACTER (LEN=132) :: message
1004    TYPE (PROJ_INFO) :: track_proj
1005    TYPE (grid_config_rec_type) :: config_flags
1007    INTEGER :: ids, ide, jds, jde, kds, kde,        &
1008               ims, ime, jms, jme, kms, kme,        &
1009               ips, ipe, jps, jpe, kps, kpe,        &
1010               imsx, imex, jmsx, jmex, kmsx, kmex,  &
1011               ipsx, ipex, jpsx, jpex, kpsx, kpex,  &
1012               imsy, imey, jmsy, jmey, kmsy, kmey,  &
1013               ipsy, ipey, jpsy, jpey, kpsy, kpey
1015    IF ( grid%track_loc <= 0 ) then
1016      RETURN
1017    ENDIF
1019 #if ( DA_CORE != 1 )
1020    IF ( grid%dfi_stage == DFI_FST ) THEN
1021 #endif
1022      CALL get_ijk_from_grid ( grid ,                               &
1023                               ids, ide, jds, jde, kds, kde,        &
1024                               ims, ime, jms, jme, kms, kme,        &
1025                               ips, ipe, jps, jpe, kps, kpe,        &
1026                               imsx, imex, jmsx, jmex, kmsx, kmex,  &
1027                               ipsx, ipex, jpsx, jpex, kpsx, kpex,  &
1028                               imsy, imey, jmsy, jmey, kmsy, kmey,  &
1029                               ipsy, ipey, jpsy, jpey, kpsy, kpey )
1030    
1031      CALL model_to_grid_config_rec ( grid%id , model_config_rec , config_flags )
1032    
1033 ! Set up map transformation structure
1034      CALL map_init(track_proj)
1035    
1036      IF (ips <= 1 .AND. 1 <= ipe .AND. &
1037          jps <= 1 .AND. 1 <= jpe) THEN
1038         known_lat = grid%xlat(1,1)
1039         known_lon = grid%xlong(1,1)
1040      ELSE
1041         known_lat = 9999.
1042         known_lon = 9999.
1043      ENDIF
1044      known_lat = wrf_dm_min_real(known_lat)
1045      known_lon = wrf_dm_min_real(known_lon)
1046    
1047 ! Mercator
1048    IF (config_flags%map_proj == PROJ_MERC) THEN
1049      CALL map_set(PROJ_MERC, track_proj,                &
1050                       truelat1 = config_flags%truelat1, &
1051                       lat1     = known_lat,             &
1052                       lon1     = known_lon,             &
1053                       knowni   = 1.,                    &
1054                       knownj   = 1.,                    &
1055                       dx       = config_flags%dx)
1056    
1057 ! Lambert conformal
1058    ELSE IF (config_flags%map_proj == PROJ_LC) THEN
1059      CALL map_set(PROJ_LC, track_proj,                   &
1060                       truelat1 = config_flags%truelat1,  &
1061                       truelat2 = config_flags%truelat2,  &
1062                       stdlon   = config_flags%stand_lon, &
1063                       lat1     = known_lat,              &
1064                       lon1     = known_lon,              &
1065                       knowni   = 1.,                     &
1066                       knownj   = 1.,                     &
1067                       dx       = config_flags%dx)
1068    
1069 ! Polar stereographic
1070    ELSE IF (config_flags%map_proj == PROJ_PS) THEN
1071      CALL map_set(PROJ_PS, track_proj,                   &
1072                       truelat1 = config_flags%truelat1,  &
1073                       stdlon   = config_flags%stand_lon, &
1074                       lat1     = known_lat,              &
1075                       lon1     = known_lon,              &
1076                       knowni   = 1.,                     &
1077                       knownj   = 1.,                     &
1078                       dx       = config_flags%dx)
1079    
1080 ! Cassini (global ARW)
1081    ELSE IF (config_flags%map_proj == PROJ_CASSINI) THEN
1082      CALL map_set(PROJ_CASSINI, track_proj,                             &
1083                       latinc   = grid%dy*360.0/(2.0*EARTH_RADIUS_M*PI), &
1084                       loninc   = grid%dx*360.0/(2.0*EARTH_RADIUS_M*PI), & 
1085                       lat1     = known_lat,                             &
1086                       lon1     = known_lon,                             &
1087 ! We still need to get POLE_LAT and POLE_LON metadata variables before
1088 !   this will work for rotated poles.
1089                       lat0     = 90.0,                                  &
1090                       lon0     = 0.0,                                   &
1091                       knowni   = 1.,                                    &
1092                       knownj   = 1.,                                    &
1093                       stdlon   = config_flags%stand_lon)
1095 ! Rotated latitude-longitude
1096    ELSE IF (config_flags%map_proj == PROJ_ROTLL) THEN
1097      CALL map_set(PROJ_ROTLL, track_proj,                       &
1098 ! I have no idea how this should work for NMM nested domains
1099                       ixdim    = grid%e_we-1,                   &
1100                       jydim    = grid%e_sn-1,                   &
1101                       phi      = real(grid%e_sn-2)*grid%dy/2.0, &
1102                       lambda   = real(grid%e_we-2)*grid%dx,     &
1103                       lat1     = config_flags%cen_lat,          &
1104                       lon1     = config_flags%cen_lon,          &
1105                       latinc   = grid%dy,                       &
1106                       loninc   = grid%dx,                       &
1107                       stagger  = HH)
1108    
1109    ENDIF
1111    IF (.NOT. grid%track_have_calculated) THEN
1112      grid%track_have_calculated = .TRUE.
1113      WRITE(message, '(A46,I3)') 'Computing track locations inside model domain ', grid%id
1114      CALL wrf_message(message)
1116 !--------------------------------------------------------
1117 ! initialize
1118 !--------------------------------------------------------
1120      grid%track_next_time = 1
1121 !--------------------------------------------------------
1122 ! Determine track locations inside model domain and the corresponding model grid
1123 !--------------------------------------------------------
1124      track_loc_temp = 0
1125      DO k = 1,grid%track_loc
1126        CALL latlon_to_ij(track_proj, grid%track_lat_in(k), grid%track_lon_in(k), track_rx, track_ry)
1127        track_loc_temp = track_loc_temp + 1
1128 !--------------------------------------------------------
1129 ! found the corresponding model grid
1130 !--------------------------------------------------------
1131        grid%track_i(track_loc_temp) = NINT(track_rx)
1132        grid%track_j(track_loc_temp) = NINT(track_ry)
1133 !--------------------------------------------------------
1134 ! found the corresponding track time
1135 !--------------------------------------------------------
1136        grid%track_time_domain(track_loc_temp) = grid%track_time_in(k)
1137 !--------------------------------------------------------
1138 ! Is point outside of domain (or on the edge of domain)? -- don't count
1139 !--------------------------------------------------------
1140        IF (grid%track_i(track_loc_temp) < ids .OR. grid%track_i(track_loc_temp) > ide .OR. &
1141            grid%track_j(track_loc_temp) < jds .OR. grid%track_j(track_loc_temp) > jde) THEN
1142          track_loc_temp = track_loc_temp - 1   
1143        ENDIF
1144      ENDDO
1146 !--------------------------------------------------------
1147 ! put the total valid track locations into grid%track_loc_domain
1148 !--------------------------------------------------------
1149      grid%track_loc_domain = track_loc_temp
1150 !--------------------------------------------------------
1151 ! found the corresponding model lat and lon and elevation
1152 !--------------------------------------------------------
1153      DO k = 1,grid%track_loc_domain
1154 !--------------------------------------------------------
1155 ! If location is outside of patch, we need to get lat/lon of track grid cell from another patch
1156 !--------------------------------------------------------
1157        IF (grid%track_i(k) < ips .OR. grid%track_i(k) > ipe .OR. &
1158            grid%track_j(k) < jps .OR. grid%track_j(k) > jpe) THEN
1159          grid%track_lat_domain(k) = 1.E30
1160          grid%track_lon_domain(k) = 1.E30
1161          grid%track_ele(k) = 1.E30
1162        ELSE
1163          grid%track_lat_domain(k) = grid%xlat(grid%track_i(k),grid%track_j(k))
1164          grid%track_lon_domain(k) = grid%xlong(grid%track_i(k),grid%track_j(k))
1165          grid%track_ele(k) = grid%ht(grid%track_i(k),grid%track_j(k))
1166        ENDIF
1168 #if DM_PARALLEL
1169        grid%track_ele(k)         = wrf_dm_min_real(grid%track_ele(k))
1170        grid%track_lat_domain(k)  = wrf_dm_min_real(grid%track_lat_domain(k))
1171        grid%track_lon_domain(k)  = wrf_dm_min_real(grid%track_lon_domain(k))
1173        call wrf_dm_bcast_string(grid%track_time_domain(k), 19)
1174 #endif
1175      END DO
1177      write(message,*) 'calc_track_locations: valid track locations in the model domain ', grid%track_loc_domain
1178      call wrf_message( trim(message) )
1179    
1180     ENDIF
1181 #if ( DA_CORE != 1 )
1182    ENDIF
1183 #endif
1184 #endif
1186 END SUBROUTINE calc_track_locations