3 !----------------------------------------------------------------------
4 ! Purpose: Generates boundary file by using wrfinput
6 ! Input : fg -- first time level wrfinput generated by real
7 ! fg02 -- second time level wrfinput generated by real
8 ! wrfbdy_ref -- reference boundary file generated by real
10 ! Output : wrfbdy_out -- the output boundary file
12 ! Notes : 1. variable name and attributes, dimension name, bdy_width
14 ! 2. domain size and time come from fg
15 ! 3. boundary and tendency are calculated by using fg & fg02
16 ! 4. the output boundary file only contain the 1st time level
18 ! jliu@ucar.edu , 2011-12-15
19 !----------------------------------------------------------------------
25 integer :: i
, n
, offset
, bdyfrq
, domainsize
, fg_jd
, fg02_jd
27 integer :: ncid
, ncidfg
, ncidfg02
, ncidwrfbdy
, ncidvarbdy
, varid
, varid_out
, status
28 integer :: nDims
, nVars
, nGlobalAtts
, numsAtts
29 integer :: dLen
, attLen
, xtype
, unlimDimID
30 integer :: bdy_width
, varbdy_dimID
, wrfbdy_dimID
, fg_dimID
, vTimes_ID
, MSF_ID
31 integer :: MU_fgID
, MU_fg02ID
, MUB_fgID
, MUB_fg02ID
, fg_varid
, fg02_varid
, tenid
33 integer, dimension(4) :: dsizes
34 integer, dimension(4), target
:: start_u
, start_v
, start_mass
35 integer, dimension(4) :: cnt_4d
, map_4d
36 integer, dimension(3) :: start_3d
, cnt_3d
, map_3d
37 integer, dimension(3), target
:: start_msfu
, start_msfv
, cnt_msfu
, cnt_msfv
, map_msfu
, map_msfv
38 integer, dimension(:), pointer :: start_msf
, cnt_msf
, map_msf
, start_4d
40 integer :: south_north
, south_north_stag
41 integer :: west_east
, west_east_stag
42 integer :: bottom_top
, bottom_top_stag
44 integer, dimension(nf90_max_var_dims
) :: vDimIDs
45 integer, dimension(:), allocatable
:: vdimsizes
46 integer, dimension(:,:,:,:), allocatable
:: iVar
48 real, dimension(:,:,:,:), allocatable
:: fVar_fg
, fVar_fg02
, Tend
49 real, dimension(:,:,:), allocatable
, target
:: MU_fg
, MU_fg02
, MUB_fg
, MUB_fg02
, MSF
51 real, dimension(:,:,:), pointer :: MU_fgptr
, MU_fg02ptr
, MUB_fgptr
, MUB_fg02ptr
, MSF_ptr
53 character (len
= 19), dimension(:), allocatable
:: times
54 character (len
= 19) :: fg_time
, fg02_time
55 character (len
= 5) :: tenname
56 character (len
= NF90_MAX_NAME
) :: vNam
, dNam
, attNam
57 character (len
= 9) :: MSF_NAME
58 character (len
= 255) :: err_msg
=""
59 character (len
=8) :: i_char
60 character (len
=255) :: arg
= ""
61 character (len
=255) :: appname
=""
62 character (len
=255) :: fg
= "fg"
63 character (len
=255) :: fg02
= "fg02"
64 character (len
=255) :: wrfbdy
= "wrfbdy_ref"
65 character (len
=255) :: varbdy
= "wrfbdy_out"
67 logical :: reverse
, couple
, stag
71 call getarg(0, appname
)
72 n
=index(appname
, '/', BACK
=.true
.)
73 appname
= trim(appname(n
+1:))
77 select
case ( trim(arg
) )
91 Write(*,*) "Usage : "//trim(appname
)//" [-fg filename] [-fg02 filename] [-bdy filename] [-o outputfile] [-h]"
92 Write(*,*) " -fg Optional, 1st time levle first guess file, default - fg"
93 Write(*,*) " -fg02 Optional, 2nd time levle first guess file, default - fg02"
94 Write(*,*) " -bdy Optional, reference boundary file comes from real, default - wrfbdy_ref"
95 Write(*,*) " -o Optional, output boundary file, default - varbdy_out"
96 Write(*,*) " -h Show this usage"
102 status
= nf90_open(fg
, NF90_NOWRITE
, ncidfg
)
103 if ( status
/= nf90_noerr
) then
104 err_msg
="Failed to open "//trim(fg
)
105 call nf90_handle_err(status
, err_msg
)
108 status
= nf90_open(fg02
, NF90_NOWRITE
, ncidfg02
)
109 if ( status
/= nf90_noerr
) then
110 err_msg
="Failed to open "//trim(fg02
)
111 call nf90_handle_err(status
, err_msg
)
114 status
= nf90_inq_varid(ncidfg
, "Times", vTimes_ID
)
115 if ( status
/= nf90_noerr
) then
116 err_msg
="Please make sure fg has a vaild Times variable"
117 call nf90_handle_err(status
, err_msg
)
120 status
= nf90_get_var(ncidfg
, vTimes_ID
, fg_time
)
121 if ( status
/= nf90_noerr
) then
122 err_msg
="Please make sure fg has a vaild Time value"
123 call nf90_handle_err(status
, err_msg
)
126 status
= nf90_inq_varid(ncidfg02
, "Times", vTimes_ID
)
127 if ( status
/= nf90_noerr
) then
128 err_msg
="Please make sure fg02 has a vaild Times variable"
129 call nf90_handle_err(status
, err_msg
)
132 status
= nf90_get_var(ncidfg02
, vTimes_ID
, fg02_time
)
133 if ( status
/= nf90_noerr
) then
134 err_msg
="Please make sure fg02 has a vaild Time value"
135 call nf90_handle_err(status
, err_msg
)
138 status
= nf90_open(wrfbdy
, NF90_NOWRITE
, ncidwrfbdy
)
139 if ( status
/= nf90_noerr
) then
140 err_msg
="Failed to open "//trim(wrfbdy
)
141 call nf90_handle_err(status
, err_msg
)
144 status
= nf90_create(varbdy
, NF90_CLOBBER
, ncidvarbdy
)
145 if ( status
/= nf90_noerr
) then
146 err_msg
="Please make sure have write access"
147 call nf90_handle_err(status
, err_msg
)
150 bdyfrq
= datediff(fg_time
, fg02_time
)
152 select
case ( bdyfrq
)
156 Write (*,*) "***WARNNING : time levle of fg is LATER then fg02's.***"
159 write(i_char
, '(i8)') bdyfrq
161 Write(*,*) " Input :"
162 Write(*,*) " fg "//fg_time
163 Write(*,*) " fg02 "//fg02_time
164 Write(*,*) " Reference bdy "//trim(wrfbdy
)
165 Write(*,*) "Output : "
166 Write(*,*) " wrfbdy_out "//fg_time
167 Write(*,*) " bdyfrq ",adjustl(i_char
)
169 status
= nf90_inquire(ncidfg
, nAttributes
=nGlobalAtts
)
171 status
= nf90_inq_attname(ncidfg
, NF90_GLOBAL
, i
, attNam
)
172 status
= nf90_copy_att(ncidfg
, NF90_GLOBAL
, attNam
, ncidvarbdy
, NF90_GLOBAL
)
175 status
= nf90_inquire(ncidwrfbdy
, nDims
, nVars
, nGlobalAtts
, unlimDimID
)
176 if ( status
/= nf90_noerr
) then
177 err_msg
="Please make sure have a valid wrf boundary file"
178 call nf90_handle_err(status
, err_msg
)
181 allocate (vdimsizes(nDims
), stat
=status
)
185 status
= nf90_inquire_dimension(ncidwrfbdy
, i
, name
=dNam
, len
= dLen
)
188 select
case (trim(dNam
))
190 status
= nf90_inq_dimid(ncidfg
, dNam
, fg_dimID
)
191 status
= nf90_inquire_dimension(ncidfg
, fg_dimID
, len
=dLen
)
193 south_north
= vdimsizes(i
)
195 status
= nf90_inq_dimid(ncidfg
, dNam
, fg_dimID
)
196 status
= nf90_inquire_dimension(ncidfg
, fg_dimID
, len
=dLen
)
198 west_east
= vdimsizes(i
)
199 case ("south_north_stag")
200 status
= nf90_inq_dimid(ncidfg
, dNam
, fg_dimID
)
201 status
= nf90_inquire_dimension(ncidfg
, fg_dimID
, len
=dLen
)
203 south_north_stag
= vdimsizes(i
)
204 case ("west_east_stag")
205 status
= nf90_inq_dimid(ncidfg
, dNam
, fg_dimID
)
206 status
= nf90_inquire_dimension(ncidfg
, fg_dimID
, len
=dLen
)
208 west_east_stag
= vdimsizes(i
)
210 status
= nf90_inq_dimid(ncidfg
, dNam
, fg_dimID
)
211 status
= nf90_inquire_dimension(ncidfg
, fg_dimID
, len
=dLen
)
213 bottom_top
= vdimsizes(i
)
214 case ("bottom_top_stag")
215 status
= nf90_inq_dimid(ncidfg
, dNam
, fg_dimID
)
216 status
= nf90_inquire_dimension(ncidfg
, fg_dimID
, len
=dLen
)
218 bottom_top_stag
= vdimsizes(i
)
221 allocate(times(vdimsizes(i
)), stat
=status
)
226 if ( i
== unlimDimID
) dLen
= NF90_UNLIMITED
228 status
= nf90_def_dim(ncidvarbdy
, dNam
, dLen
, varbdy_dimID
)
232 status
= nf90_inq_varid(ncidfg
, "MU" , MU_fgID
)
233 status
= nf90_inq_varid(ncidfg
, "MUB", MUB_fgID
)
234 status
= nf90_inq_varid(ncidfg02
, "MU" , MU_fg02ID
)
235 status
= nf90_inq_varid(ncidfg02
, "MUB", MUB_fg02ID
)
237 status
= nf90_inq_varid(ncidfg
, "Times", vTimes_ID
)
241 status
= nf90_inquire_variable(ncidwrfbdy
,varid
,name
=vNam
,xtype
=xtype
,ndims
=nDims
,dimids
=vDimIDs
,natts
=numsAtts
)
242 status
= nf90_def_var(ncidvarbdy
, trim(vNam
), xtype
, vDimIDs(1:nDims
), varid_out
)
243 if ( status
/= nf90_noerr
) then
244 err_msg
="Failed to define variable : "//trim(vNam
)
245 call nf90_handle_err(status
, err_msg
)
249 status
= nf90_inq_attname(ncidwrfbdy
, varid
, i
, attNam
)
250 status
= nf90_copy_att(ncidwrfbdy
, varid
, trim(attNam
), ncidvarbdy
, varid_out
)
251 if ( status
/= nf90_noerr
) then
252 err_msg
="Failed to copy att : "//trim(attNam
)
253 call nf90_handle_err(status
, err_msg
)
259 status
= nf90_enddef(ncidvarbdy
)
263 status
= nf90_inquire_variable(ncidwrfbdy
,varid
,name
=vNam
,xtype
=xtype
,ndims
=nDims
,dimids
=vDimIDs
)
264 if ( status
/= nf90_noerr
) then
265 err_msg
="Failed to inquire varialbe '"//trim(vNam
)//"' for wrfbdy"
266 call nf90_handle_err(status
, err_msg
)
271 dsizes(i
) = vdimsizes(vDimIDs(i
))
274 offset
= index(vNam
, '_', BACK
=.True
.)
275 if ( offset
<= 0 ) offset
= Len(Trim(vNam
))
278 ! U (west_east_stag, south_north, bottom_top, time)
279 ! V (west_east, south_north_stag, bottom_top, time)
280 ! T, QVAPOR (west_east, south_north, bottom_top, time)
281 ! PH (west_east, south_north, bottom_top_stag, time)
282 ! MU (west_east, south_north, time)
283 ! MAPFAC_U (west_east_stag, south_north, time)
284 ! MAPFAC_V (west_east, south_north_stag, time)
287 ! U (south_north, bottom_top, bdy_width, time)
288 ! V (south_north_stag, bottom_top, bdy_width, time)
289 ! T, QVAPOR (south_north, bottom_top, bdy_width, time)
290 ! PH (south_north, bottom_top_stag, bdy_width, time)
291 ! MU (south_north, bdy_width, time)
293 ! U (west_east_stag, bottom_top, bdy_width, time)
294 ! V (west_east, bottom_top, bdy_width, time)
295 ! T, QVAPOR (west_east, bottom_top, bdy_width, time)
296 ! PH (west_east, bottom_top_stag, bdy_width, time)
297 ! MU (west_east, bdy_width, time)
299 select
case (Trim(vNam(offset
:)))
300 case ("_BXS") ! West Boundary
301 start_u
= (/1,1,1,1/)
302 start_v
= (/1,1,1,1/)
303 start_mass
= (/1,1,1,1/)
305 start_msfu
= (/1,1,1/)
306 start_msfv
= (/1,1,1/)
308 cnt_4d
= (/dsizes(3),dsizes(1),dsizes(2),1/)
309 cnt_3d
= (/bdy_width
,south_north
,1/)
310 cnt_msfu
= (/bdy_width
,south_north
,1/)
311 cnt_msfv
= (/bdy_width
,south_north_stag
,1/)
313 map_4d
= (/dsizes(1)*dsizes(2), 1, dsizes(1), dsizes(1)*dsizes(2)*dsizes(3)/)
314 map_3d
= (/south_north
, 1, bdy_width
*south_north
/)
315 map_msfu
= (/south_north
, 1, bdy_width
*south_north
/)
316 map_msfv
= (/south_north_stag
, 1, bdy_width
*south_north_stag
/)
320 case ("_BXE") ! East Boundary
321 start_u
= (/west_east_stag
- bdy_width
+ 1, 1, 1, 1/)
322 start_v
= (/west_east
- bdy_width
+ 1, 1, 1, 1/)
323 start_mass
= (/west_east
- bdy_width
+ 1, 1, 1, 1/)
324 start_3d
= (/west_east
- bdy_width
+ 1, 1, 1/)
325 start_msfu
= (/west_east_stag
- bdy_width
+ 1, 1, 1/)
326 start_msfv
= (/west_east
- bdy_width
+ 1, 1, 1/)
328 cnt_4d
= (/dsizes(3),dsizes(1),dsizes(2),1/)
329 cnt_3d
= (/bdy_width
,south_north
,1/)
330 cnt_msfu
= (/bdy_width
,south_north
,1/)
331 cnt_msfv
= (/bdy_width
,south_north_stag
,1/)
333 map_4d
= (/dsizes(1)*dsizes(2), 1, dsizes(1), dsizes(1)*dsizes(2)*dsizes(3)/)
334 map_3d
= (/south_north
, 1, bdy_width
*south_north
/)
335 map_msfu
= (/south_north
, 1, bdy_width
*south_north
/)
336 map_msfv
= (/south_north_stag
, 1, bdy_width
*south_north_stag
/)
340 case ("_BYE") ! North Boundary
341 start_u
= (/1, south_north
- bdy_width
+ 1, 1, 1/)
342 start_v
= (/1, south_north_stag
- bdy_width
+ 1, 1, 1/)
343 start_mass
= (/1, south_north
- bdy_width
+ 1, 1, 1/)
344 start_3d
= (/1, south_north
- bdy_width
+ 1, 1/)
345 start_msfu
= (/1, south_north
- bdy_width
+ 1, 1/)
346 start_msfv
= (/1, south_north_stag
- bdy_width
+ 1, 1/)
348 cnt_4d
= (/dsizes(1),dsizes(3),dsizes(2),1/)
349 cnt_3d
= (/west_east
, bdy_width
,1/)
350 cnt_msfu
= (/west_east_stag
, bdy_width
,1/)
351 cnt_msfv
= (/west_east
, bdy_width
,1/)
353 map_4d
= (/1, dsizes(1)*dsizes(2), dsizes(1), dsizes(3)*dsizes(1)*dsizes(2)/)
354 map_3d
= (/1, west_east
, west_east
*bdy_width
/)
355 map_msfu
= (/1, west_east_stag
, west_east_stag
*bdy_width
/)
356 map_msfv
= (/1, west_east
, west_east
*bdy_width
/)
361 case ("_BYS") ! South Boundary
362 start_u
= (/1, 1, 1, 1/)
363 start_v
= (/1, 1, 1, 1/)
364 start_mass
= (/1, 1, 1, 1/)
365 start_3d
= (/1, 1, 1/)
366 start_msfu
= (/1, 1, 1/)
367 start_msfv
= (/1, 1, 1/)
369 cnt_4d
= (/dsizes(1),dsizes(3),dsizes(2),1/)
370 cnt_3d
= (/west_east
, bdy_width
,1/)
371 cnt_msfu
= (/west_east_stag
, bdy_width
,1/)
372 cnt_msfv
= (/west_east
, bdy_width
,1/)
374 map_4d
= (/1, dsizes(1)*dsizes(2), dsizes(1), dsizes(3)*dsizes(1)*dsizes(2)/)
375 map_3d
= (/1, west_east
, west_east
*bdy_width
/)
376 map_msfu
= (/1, west_east_stag
, west_east_stag
*bdy_width
/)
377 map_msfv
= (/1, west_east
, west_east
*bdy_width
/)
382 case ("_BTXS", "_BTXE","_BTYS","_BTYE")
388 if (vNam(1:offset
) == "Times") then
391 n
= index(vNam
, "bdytime")
393 select
case (vNam(n
-4:n
-1))
402 status
= nf90_get_var(ncid
, vTimes_ID
, times
)
403 status
= nf90_put_var(ncidvarbdy
, varid
, times
)
406 Write(*,*) "Processing for "//trim(vNam
)
410 allocate(MU_fg (dsizes(1),bdy_width
,1), stat
=status
)
411 allocate(MU_fg02 (dsizes(1),bdy_width
,1), stat
=status
)
412 allocate(MUB_fg (dsizes(1),bdy_width
,1), stat
=status
)
413 allocate(MUB_fg02(dsizes(1),bdy_width
,1), stat
=status
)
414 allocate(MSF (dsizes(1),bdy_width
,1), stat
=status
)
416 allocate(Tend(dsizes(1), dsizes(2), dsizes(3), dsizes(4)), stat
=status
)
418 if ( dsizes(1) == west_east_stag
.or
. dsizes(1) == south_north_stag
) then
419 MU_fgptr
=> MU_fg (2:,:,:)
420 MU_fg02ptr
=> MU_fg02 (2:,:,:)
421 MUB_fgptr
=> MUB_fg (2:,:,:)
422 MUB_fg02ptr
=> MUB_fg02(2:,:,:)
426 MU_fg02ptr
=> MU_fg02
428 MUB_fg02ptr
=> MUB_fg02
432 err_msg
="Failed to get variable : "//trim(vNam
)
433 status
= nf90_get_var(ncidfg
, MU_fgID
, MU_fgptr
, start
=start_3d
, count
=cnt_3d
, map=map_3d
)
434 if ( status
/= nf90_noerr
) call nf90_handle_err(status
, err_msg
)
436 status
= nf90_get_var(ncidfg02
, MU_fg02ID
, MU_fg02ptr
, start
=start_3d
,count
=cnt_3d
, map=map_3d
)
437 if(status
/= nf90_noerr
) call nf90_handle_err(status
,err_msg
)
439 status
= nf90_get_var(ncidfg
, MUB_fgID
, MUB_fgptr
, start
=start_3d
, count
=cnt_3d
,map=map_3d
)
440 if(status
/= nf90_noerr
) call nf90_handle_err(status
,err_msg
)
442 status
= nf90_get_var(ncidfg02
, MUB_fg02ID
, MUB_fg02ptr
, start
=start_3d
, count
=cnt_3d
, map=map_3d
)
443 if(status
/= nf90_noerr
) call nf90_handle_err(status
, err_msg
)
445 err_msg
="Failed to inquire tendency id for "//trim(vNam
)//" for output file"
446 status
= nf90_inq_varid(ncidvarbdy
, vNam(1:offset
-1)//tenname
, tenid
)
447 if(status
/= nf90_noerr
) call nf90_handle_err(status
, err_msg
)
450 MU_fg
= MU_fg (:,bdy_width
:1:-1,:)
451 MU_fg02
= MU_fg02 (:,bdy_width
:1:-1,:)
452 MUB_fg
= MUB_fg (:,bdy_width
:1:-1,:)
453 MUB_fg02
= MUB_fg02(:,bdy_width
:1:-1,:)
456 select
case (vNam(1:offset
))
459 MU_fg (1,:,:) = MU_fg (2,:,:)
460 MU_fg02 (1,:,:) = MU_fg02 (2,:,:)
461 MUB_fg (1,:,:) = MUB_fg (2,:,:)
462 MUB_fg02(1,:,:) = MUB_fg02(2,:,:)
464 MU_fg (2:dsizes(1)-1,:,:) = (MU_fg (2:dsizes(1)-1,:,:) + MU_fg (3:dsizes(1),:,:))*0.5
465 MU_fg02 (2:dsizes(1)-1,:,:) = (MU_fg02 (2:dsizes(1)-1,:,:) + MU_fg02 (3:dsizes(1),:,:))*0.5
466 MUB_fg (2:dsizes(1)-1,:,:) = (MUB_fg (2:dsizes(1)-1,:,:) + MUB_fg (3:dsizes(1),:,:))*0.5
467 MUB_fg02(2:dsizes(1)-1,:,:) = (MUB_fg02(2:dsizes(1)-1,:,:) + MUB_fg02(3:dsizes(1),:,:))*0.5
469 MU_fg (:,2:bdy_width
,:) = (MU_fg (:,1:bdy_width
-1,:) + MU_fg (:,2:bdy_width
,:))*0.5
470 MU_fg02 (:,2:bdy_width
,:) = (MU_fg02 (:,1:bdy_width
-1,:) + MU_fg02 (:,2:bdy_width
,:))*0.5
471 MUB_fg (:,2:bdy_width
,:) = (MUB_fg (:,1:bdy_width
-1,:) + MUB_fg (:,2:bdy_width
,:))*0.5
472 MUB_fg02(:,2:bdy_width
,:) = (MUB_fg02(:,1:bdy_width
-1,:) + MUB_fg02(:,2:bdy_width
,:))*0.5
475 if ( vNam(1:offset
) == "U_" ) then
477 start_msf
=> start_msfu
480 MSF_NAME
= "MAPFAC_U"
483 start_msf
=> start_msfv
486 MSF_NAME
= "MAPFAC_V"
489 status
= nf90_inq_varid(ncidfg
, MSF_NAME
, MSF_ID
)
490 err_msg
="Failed to get varialbe MSF"
491 status
= nf90_get_var(ncidfg
, MSF_ID
, MSF
, start
=start_msf
, count
=cnt_msf
, map=map_msf
)
492 if(status
/= nf90_noerr
) call nf90_handle_err(status
, err_msg
)
494 if ( reverse
) MSF
= MSF(:,bdy_width
:1:-1,:)
496 case ("T_","PH_","QVAPOR_")
498 start_4d
=> start_mass
500 status
= nf90_inq_varid(ncidvarbdy
, "MU"//tenname
, tenid
)
501 Tend(:,:,:,1) = ( MU_fg02
- MU_fg
) / bdyfrq
502 status
= nf90_put_var(ncidvarbdy
, varid
, MU_fg
)
503 !status = nf90_put_var(ncidvarbdy, varid, MU_fg02)
504 err_msg
="Failed to put variable "//trim(vNam
)
505 if(status
/= nf90_noerr
) call nf90_handle_err(status
,err_msg
)
506 status
= nf90_put_var(ncidvarbdy
, tenid
, Tend(:,:,:,1))
507 err_msg
="Failed to put tendency for "//trim(vNam
)
508 if(status
/= nf90_noerr
) call nf90_handle_err(status
,err_msg
)
516 allocate(fVar_fg( dsizes(1), dsizes(2), dsizes(3), dsizes(4) ), stat
=status
)
518 status
= nf90_put_var(ncidvarbdy
, varid
, fVar_fg
)
519 err_msg
="Failed to put variable "//trim(vNam
)
520 if(status
/= nf90_noerr
) call nf90_handle_err(status
,err_msg
)
521 status
= nf90_put_var(ncidvarbdy
, tenid
, Tend
)
522 err_msg
="Failed to put tendency for "//trim(vNam
)
523 if(status
/= nf90_noerr
) call nf90_handle_err(status
,err_msg
)
526 allocate(iVar( dsizes(1), dsizes(2), dsizes(3), dsizes(4) ), stat
=status
)
528 status
= nf90_put_var(ncidvarbdy
, varid
, iVar
)
529 err_msg
="Failed to put variable "//trim(vNam
)
530 if(status
/= nf90_noerr
) call nf90_handle_err(status
,err_msg
)
531 status
= nf90_put_var(ncidvarbdy
, tenid
, Tend
)
532 err_msg
="Failed to put tendency for "//trim(vNam
)
533 if(status
/= nf90_noerr
) call nf90_handle_err(status
,err_msg
)
535 end select
! end of xtype
537 end select
! end of vNam
541 allocate( fVar_fg(dsizes(1), dsizes(2), dsizes(3), dsizes(4)), stat
=status
)
542 allocate(fVar_fg02(dsizes(1), dsizes(2), dsizes(3), dsizes(4)), stat
=status
)
544 err_msg
="Failed to inquire variable id for "//vNam(1:offset
-1)//" for fg"
545 status
= nf90_inq_varid(ncidfg
, vNam(1:offset
-1), fg_varid
)
546 if(status
/= nf90_noerr
) call nf90_handle_err(status
,err_msg
)
548 err_msg
="Failed to inquire variable id for "//vNam(1:offset
-1)//" for fg02"
549 status
= nf90_inq_varid(ncidfg02
, vNam(1:offset
-1), fg02_varid
)
550 if(status
/= nf90_noerr
) call nf90_handle_err(status
, err_msg
)
552 err_msg
="Failed to inquire tendency id for "//trim(vNam(1:offset
-1))//" for output file"
553 status
= nf90_inq_varid(ncidvarbdy
, vNam(1:offset
-1)//tenname
, tenid
)
554 if(status
/= nf90_noerr
) call nf90_handle_err(status
,err_msg
)
556 err_msg
="Failed to get variable "//vNam(1:offset
-1)//" from fg"
557 status
= nf90_get_var(ncidfg
, fg_varid
, fVar_fg
, start
=start_4d
, count
=cnt_4d
, map=map_4d
)
558 if(status
/= nf90_noerr
) call nf90_handle_err(status
,err_msg
)
560 err_msg
="Failed to get variable "//vNam(1:offset
-1)//" from fg02"
561 status
= nf90_get_var(ncidfg02
, fg02_varid
, fVar_fg02
, start
=start_4d
, count
=cnt_4d
, map=map_4d
)
562 if(status
/= nf90_noerr
) call nf90_handle_err(status
,err_msg
)
564 MU_fg
= MU_fg
+ MUB_fg
565 MU_fg02
= MU_fg02
+ MUB_fg
566 !MU_fg02 = MU_fg02 + MUB_fg02
569 fVar_fg
= fVar_fg (:,:,bdy_width
:1:-1,:)
570 fVar_fg02
= fVar_fg02(:,:,bdy_width
:1:-1,:)
574 fVar_fg(:,i
,:,:) = (fVar_fg (:,i
,:,:) * MU_fg
) / MSF
575 fVar_fg02(:,i
,:,:) = (fVar_fg02(:,i
,:,:) * MU_fg02
) / MSF
578 Tend
= ( fVar_fg02
- fVar_fg
) / bdyfrq
580 err_msg
="Failed to put variable "//trim(vNam
)
581 status
= nf90_put_var(ncidvarbdy
, varid
, fVar_fg
)
582 !status = nf90_put_var(ncidvarbdy, varid, fVar_fg02)
583 if(status
/= nf90_noerr
) call nf90_handle_err(status
,err_msg
)
585 err_msg
="Failed to put tendency for "//trim(vNam
)
586 status
= nf90_put_var(ncidvarbdy
, tenid
, Tend
)
587 if(status
/= nf90_noerr
) call nf90_handle_err(status
,err_msg
)
590 deallocate (fVar_fg02
)
597 NULLIFY (MUB_fg02ptr
)
604 deallocate (MUB_fg02
)
608 end select
! end of nDims
614 status
= nf90_close(ncidfg
)
615 status
= nf90_close(ncidfg02
)
616 status
= nf90_close(ncidwrfbdy
)
617 status
= nf90_close(ncidvarbdy
)
619 Write(*,*) "Boundary file generated successfully"
623 subroutine nf90_handle_err(status
, err_msg
)
624 integer, intent (in
) :: status
625 character (len
=*), intent(in
) :: err_msg
627 if(status
/= nf90_noerr
) then
628 print *, trim(nf90_strerror(status
))
629 print *, trim(err_msg
)
632 end subroutine nf90_handle_err
634 function jd(yyyy
, mm
, dd
) result(ival
)
636 integer, intent(in
) :: yyyy
637 integer, intent(in
) :: mm
638 integer, intent(in
) :: dd
641 ! DATE ROUTINE JD(YYYY, MM, DD) CONVERTS CALENDER DATE TO
642 ! JULIAN DATE. SEE CACM 1968 11(10):657, LETTER TO THE
643 ! EDITOR BY HENRY F. FLIEGEL AND THOMAS C. VAN FLANDERN.
644 ! EXAMPLE JD(1970, 1, 1) = 2440588
646 ival
= dd
- 32075 + 1461*(yyyy
+4800+(mm
-14)/12)/4 + &
647 367*(mm
-2-((mm
-14)/12)*12)/12 - 3*((yyyy
+4900+(mm
-14)/12)/100)/4
652 function datediff(date_1
, date_2
) result(ival
)
654 character(len
=*), intent(in
) :: date_1
655 character(len
=*), intent(in
) :: date_2
658 integer :: yyyy
,mm
,dd
659 integer :: hh1
,nn1
,ss1
660 integer :: hh2
,nn2
,ss2
663 ! date string : yyyy-mm-dd_hh:mm:ss
664 ! calculate the difference between date_1 and date_2 in seconds
666 read(date_1(1:19), '(i4,5(1x,i2))') &
667 yyyy
, mm
, dd
, hh1
, nn1
, ss1
671 read(date_2(1:19), '(i4,5(1x,i2))') &
672 yyyy
, mm
, dd
, hh2
, nn2
, ss2
676 ival
=(jd2
-jd1
)*86400 + ( hh2
-hh1
)*3600 + (nn2
-nn1
)*60 + (ss2
-ss1
)
679 end function datediff