4 ! This is the main driver for the standalone moisture model. To compile,
5 ! create a make.inc file in this directory from one of the example
6 ! make.inc.* files. Make sure to set NETCDF to the prefix path of your
7 ! netcdf installation. Then, type `make moisture` to create moisture.exe.
9 ! This program requires one or more wrfout files to run. It relies on
10 ! surface variables T2, Q2, and PSFC to be computed from the WRF run,
11 ! which generally requires a nonzero sfclay option. The command line
12 ! syntax for this program is:
14 ! ./moisture.exe [-r] wrfout1 [wrfout2 [wrfout3 [...]]]
16 ! -r, when present indicates a restart run. The program will open up a
17 ! previous output file named moisture.nc and use the last time step
18 ! present in that file to initialize a new run.
20 ! The wrfout files specified on the command line must be in sequential
21 ! order, but they can contain overlapping time steps. This is useful
22 ! for outputs from operational reanalysis runs. When two files contain
23 ! data for the same time step, this program will always use the second
24 ! file (with time step closer to the reanalysis).
26 ! For every time step computed by this program, it will output surface
27 ! fields to moisture.nc, a netcdf file with similar conventions as a
31 use module_fr_sfire_util, only : crash
36 ! size parameters that depend on WRF
37 integer,parameter::TIMESTRLEN=19,nfmc=5
39 ! if true, the program will only output moisture fields
40 ! but the outputs cannot be used for restarting
41 logical,parameter::smalloutput=.false.
43 ! model array allocation size for compatibility with WRF
44 integer,save:: ims,ime,jms,jme
46 ! model array domain size
47 integer,save::its,ite,jts,jte
49 ! initially set to false to indicate that the sizes above
50 ! have not been initialized
51 logical,private,save::initialized=.false.
53 ! a simple data structure to group together all variables used
54 ! by the moisture model at a particular time step
57 real,pointer,dimension(:,:,:)::fmc_gc,fmc_equi,fmc_tend
58 real,pointer,dimension(:,:)::t2,q2,psfc,rainc,rainnc, &
59 t2_old,q2_old,psfc_old,rain_old,rh_fire
63 ! rain accumulation variable
64 real,pointer,dimension(:,:)::rain_accum,rain_zero
67 ! a data structure that contains metadata information about a
70 ! number of time steps in the file
73 ! array of time stamps contained in the file
74 type(ESMF_Time),dimension(:),pointer::times
76 ! the start time of the simulation
77 type(ESMF_Time)::starttime
85 subroutine initialize_and_check(filename,wrffile)
86 ! open a file and initialize an ncfile type
87 ! if module is not initialized, then initialize
88 ! otherwise check that sizes are consistent
90 ! the name of the file to open
91 character(len=*),intent(in)::filename
93 ! ncfile type initialized on output
94 type(ncfile),intent(out)::wrffile
96 ! local variables dealing with netcdf i/o
97 integer::dimidx,dimidy,dimidtime,dimidfuel
99 integer::nx,ny,nfuel,i,rc
100 character(len=TIMESTRLEN),dimension(:),allocatable::timestr
101 character(len=TIMESTRLEN)::stimestr
103 ! open the file and collect metadata
104 call check(nf90_open(filename,nf90_nowrite,wrffile%ncid))
105 call check(nf90_inq_dimid(wrffile%ncid,'west_east', dimidx))
106 call check(nf90_inq_dimid(wrffile%ncid,'south_north',dimidy))
107 call check(nf90_inq_dimid(wrffile%ncid,'Time',dimidtime))
108 call check(nf90_inquire_dimension(wrffile%ncid,dimidx,len=nx))
109 call check(nf90_inquire_dimension(wrffile%ncid,dimidy,len=ny))
110 call check(nf90_inquire_dimension(wrffile%ncid,dimidtime,len=wrffile%ntime))
112 if(.not.initialized)then
113 ! the ESMF time modules need to be initialized on first call
114 call ESMF_Initialize(defaultCalKind=ESMF_CAL_GREGORIAN)
116 ! on first call set module level variables containing array sizes
127 ! on later calls check that the file sizes are consistant with the sizes
129 if( (nx.ne.ime-ims+1) .or. &
130 (ny.ne.jme-jms+1) ) then
131 call crash('Incompatible file: '//trim(filename))
135 ! allocate memory for ncfile data type
136 allocate(wrffile%times(wrffile%ntime))
137 allocate(timestr(wrffile%ntime))
139 call check(nf90_inq_varid(wrffile%ncid,'Times',varidtime))
140 call check(nf90_get_var(wrffile%ncid,varidtime,timestr))
142 ! go through all time stamps in the file and store them as ESMF types
144 call parse_wrf_time(timestr(i),wrffile%times(i))
148 call check(nf90_get_att(wrffile%ncid,NF90_GLOBAL,'START_DATE',stimestr))
149 call parse_wrf_time(stimestr,wrffile%starttime)
154 end subroutine initialize_and_check
158 ! called at then end of execution to free allocated memory
160 end subroutine alldone
162 subroutine destroy_file(wrffile)
164 ! free memory allocated in a ncfile data structure
165 type(ncfile),intent(inout)::wrffile
166 call check(nf90_close(wrffile%ncid))
167 deallocate(wrffile%times)
169 end subroutine destroy_file
171 subroutine initialize_vars(vars)
173 ! Allocate memory for the model arrays
174 type(ncvars),intent(inout)::vars
175 if(.not.initialized)then
176 call crash('Module not initialized')
178 allocate(vars%fmc_gc(ims:ime,1:nfmc,jms:jme))
179 allocate(vars%fmc_equi(ims:ime,1:nfmc,jms:jme))
180 allocate(vars%fmc_tend(ims:ime,1:nfmc,jms:jme))
181 allocate(vars%t2(ims:ime,jms:jme))
182 allocate(vars%q2(ims:ime,jms:jme))
183 allocate(vars%psfc(ims:ime,jms:jme))
184 allocate(vars%rainc(ims:ime,jms:jme))
185 allocate(vars%rainnc(ims:ime,jms:jme))
186 allocate(vars%t2_old(ims:ime,jms:jme))
187 allocate(vars%q2_old(ims:ime,jms:jme))
188 allocate(vars%psfc_old(ims:ime,jms:jme))
189 allocate(vars%rain_old(ims:ime,jms:jme))
190 allocate(vars%rh_fire(ims:ime,jms:jme))
191 allocate(vars%rain_accum(ims:ime,jms:jme))
192 allocate(vars%rain_zero(ims:ime,jms:jme))
193 vars%rain_accum(:,:)=0.
194 vars%rain_zero(:,:)=0.
195 end subroutine initialize_vars
197 subroutine destroy_vars(vars)
199 ! free memory from model arrays
200 type(ncvars),intent(inout)::vars
201 deallocate(vars%fmc_gc)
202 deallocate(vars%fmc_equi)
203 deallocate(vars%fmc_tend)
206 deallocate(vars%psfc)
207 deallocate(vars%rainc)
208 deallocate(vars%rainnc)
209 deallocate(vars%t2_old)
210 deallocate(vars%q2_old)
211 deallocate(vars%psfc_old)
212 deallocate(vars%rain_old)
213 deallocate(vars%rh_fire)
214 deallocate(vars%rain_accum)
215 deallocate(vars%rain_zero)
216 end subroutine destroy_vars
218 subroutine create_output(filename)
220 ! create an output netcdf file with metadata initialized
221 ! for the model being run.... does not write any data
222 character(len=*),intent(in)::filename
224 integer::ncid,nxid,nyid,timeid,fuelid,dateid
228 call check(nf90_create(filename,nf90_clobber,ncid))
231 call check(nf90_def_dim(ncid,'west_east',ime-ims+1,nxid))
232 call check(nf90_def_dim(ncid,'south_north',jme-jms+1,nyid))
233 call check(nf90_def_dim(ncid,'Time',nf90_unlimited,timeid))
234 call check(nf90_def_dim(ncid,'fuel_moisture_classes_stag',nfmc,fuelid))
235 call check(nf90_def_dim(ncid,'DateStrLen',TIMESTRLEN,dateid))
238 call check(nf90_def_var(ncid,'Times',NF90_CHAR,(/dateid,timeid/),tmp))
239 call check(nf90_def_var(ncid,'FMC_GC',NF90_REAL,(/nxid,nyid,fuelid,timeid/),tmp))
240 if(.not.smalloutput)then
241 call check(nf90_def_var(ncid,'FMC_EQUI',NF90_REAL,(/nxid,nyid,fuelid,timeid/),tmp))
242 call check(nf90_def_var(ncid,'FMC_TEND',NF90_REAL,(/nxid,nyid,fuelid,timeid/),tmp))
243 call check(nf90_def_var(ncid,'T2',NF90_REAL,(/nxid,nyid,timeid/),tmp))
244 call check(nf90_def_var(ncid,'Q2',NF90_REAL,(/nxid,nyid,timeid/),tmp))
245 call check(nf90_def_var(ncid,'PSFC',NF90_REAL,(/nxid,nyid,timeid/),tmp))
246 call check(nf90_def_var(ncid,'RAIN',NF90_REAL,(/nxid,nyid,timeid/),tmp))
247 call check(nf90_def_var(ncid,'RH_FIRE',NF90_REAL,(/nxid,nyid,timeid/),tmp))
249 call check(nf90_close(ncid))
250 end subroutine create_output
252 subroutine write_output(filename,vars)
254 ! write arrays from the model into a preinitialized output file
255 character(len=*),intent(in)::filename
256 type(ncvars),intent(in)::vars
258 integer::ncid,varid,dimid,itime
259 character(len=TIMESTRLEN)::timestr
260 real,dimension(:,:,:),allocatable::tmp
262 ! allocate temporary memory for transposing 3D arrays
263 allocate(tmp(its:ite,jts:jte,1:nfmc))
265 print*,'writing output to '//trim(filename)
266 call check(nf90_open(filename,NF90_WRITE,ncid))
268 ! get the number of time frames already present and set the
269 ! output time frame to the end of the file
270 call check(nf90_inq_dimid(ncid,'Time',dimid))
271 call check(nf90_inquire_dimension(ncid,dimid,len=itime))
275 call check(nf90_inq_varid(ncid,'Times',varid))
276 call ESMF_TimeGet(vars%time,timeString=timestr)
277 call check(nf90_put_var(ncid,varid,timestr, &
278 start=(/1,itime/),count=(/TIMESTRLEN,1/)))
281 call check(nf90_inq_varid(ncid,'FMC_GC',varid))
282 call transpose_var(vars%fmc_gc,tmp)
283 call check(nf90_put_var(ncid,varid,tmp, &
284 start=(/its,jts,1,itime/),count=(/ite,jte,nfmc,1/)))
286 ! the following variables are diagnostic only, but useful for restarting
287 if(.not.smalloutput)then
289 call check(nf90_inq_varid(ncid,'FMC_EQUI',varid))
290 call transpose_var(vars%fmc_equi,tmp)
291 call check(nf90_put_var(ncid,varid,tmp, &
292 start=(/its,jts,1,itime/),count=(/ite,jte,nfmc,1/)))
294 call check(nf90_inq_varid(ncid,'FMC_TEND',varid))
295 call transpose_var(vars%fmc_tend,tmp)
296 call check(nf90_put_var(ncid,varid,tmp, &
297 start=(/its,jts,1,itime/),count=(/ite,jte,nfmc,1/)))
299 call check(nf90_inq_varid(ncid,'T2',varid))
300 call check(nf90_put_var(ncid,varid,vars%t2, &
301 start=(/its,jts,itime/),count=(/ite,jte,1/)))
303 call check(nf90_inq_varid(ncid,'Q2',varid))
304 call check(nf90_put_var(ncid,varid,vars%q2, &
305 start=(/its,jts,itime/),count=(/ite,jte,1/)))
307 call check(nf90_inq_varid(ncid,'PSFC',varid))
308 call check(nf90_put_var(ncid,varid,vars%psfc, &
309 start=(/its,jts,itime/),count=(/ite,jte,1/)))
311 call check(nf90_inq_varid(ncid,'RAIN',varid))
312 call check(nf90_put_var(ncid,varid,vars%rain_accum, &
313 start=(/its,jts,itime/),count=(/ite,jte,1/)))
315 call check(nf90_inq_varid(ncid,'RH_FIRE',varid))
316 call check(nf90_put_var(ncid,varid,vars%rh_fire, &
317 start=(/its,jts,itime/),count=(/ite,jte,1/)))
321 ! free allocated memory
322 call check(nf90_close(ncid))
324 end subroutine write_output
326 subroutine read_file(wrffile,atime,vars,ierr,restart)
328 ! read array data for the model from a file
329 type(ncfile),intent(in)::wrffile ! initialized ncfile object
330 integer,intent(in)::atime ! the time step in the file to read
331 type(ncvars),intent(inout)::vars ! on return contains data from the file
332 integer,intent(out)::ierr ! error flag, 0 on success, otherwise read error
333 logical,optional,intent(in)::restart ! if this a restart, we will read fmc_gc
335 integer::varid,i,j,k,itime
337 real,dimension(:,:,:),allocatable::tmp
338 real,dimension(ims:ime,jms:jme)::rainold
341 if(present(restart))then
345 ! if the time step is unspecified (<= 0) then
346 ! just read the last time step
350 itime=size(wrffile%times)
352 vars%time=wrffile%times(itime)
354 ! read FMC_GC if it is present (generally, this test will
355 ! only pass when we are reading for a restart)
356 if(r.and.nf90_inq_varid(wrffile%ncid,'FMC_GC',varid).eq.0)then
357 allocate(tmp(its:ite,jts:jte,nfmc))
358 call check(nf90_get_var(wrffile%ncid,varid,tmp, &
359 start=(/its,jts,1,itime/), count=(/ite,jte,nfmc,1/)))
360 call transpose_var(tmp,vars%fmc_gc)
364 ! read variables that should always be present
365 call check(nf90_inq_varid(wrffile%ncid,'T2',varid))
366 call check(nf90_get_var(wrffile%ncid,varid,vars%t2, &
367 start=(/its,jts,itime/), count=(/ite,jte,1/)))
369 call check(nf90_inq_varid(wrffile%ncid,'Q2',varid))
370 call check(nf90_get_var(wrffile%ncid,varid,vars%q2, &
371 start=(/its,jts,itime/), count=(/ite,jte,1/)))
373 call check(nf90_inq_varid(wrffile%ncid,'PSFC',varid))
374 call check(nf90_get_var(wrffile%ncid,varid,vars%psfc, &
375 start=(/its,jts,itime/), count=(/ite,jte,1/)))
377 if(nf90_inq_varid(wrffile%ncid,'RAINC',varid).eq.0)then
378 call check(nf90_get_var(wrffile%ncid,varid,vars%rainc, &
379 start=(/its,jts,itime/), count=(/ite,jte,1/)))
382 call check(nf90_get_var(wrffile%ncid,varid,rainold, &
383 start=(/its,jts,itime-1/),count=(/ite,jte,1/)))
384 vars%rainc(:,:)=vars%rainc(:,:)-rainold(:,:)
387 call check(nf90_inq_varid(wrffile%ncid,'RAINNC',varid))
388 call check(nf90_get_var(wrffile%ncid,varid,vars%rainnc, &
389 start=(/its,jts,itime/), count=(/ite,jte,1/)))
392 call check(nf90_get_var(wrffile%ncid,varid,rainold, &
393 start=(/its,jts,itime-1/),count=(/ite,jte,1/)))
394 vars%rainnc(:,:)=vars%rainnc(:,:)-rainold(:,:)
397 call check(nf90_inq_varid(wrffile%ncid,'RAIN',varid))
398 call check(nf90_get_var(wrffile%ncid,varid,vars%rainc, &
399 start=(/its,jts,itime/), count=(/ite,jte,1/)))
403 call check(nf90_get_var(wrffile%ncid,varid,rainold, &
404 start=(/its,jts,itime-1/),count=(/ite,jte,1/)))
405 vars%rainc(:,:)=vars%rainc(:,:)-rainold(:,:)
409 ! calculate total rain accumulation for this moisture run
410 vars%rain_accum(:,:)=vars%rain_accum(:,:) + vars%rainc(:,:) + vars%rainnc(:,:)
412 ! here we preempt any model errors by detecting if the data is correct
413 ! if not, the main code will skip this time step and move on to the
415 if(any(vars%t2.le.0).or.any(vars%q2.lt.0).or.any(vars%psfc.le.0))then
420 end subroutine read_file
422 subroutine transpose_var(A,B)
424 ! do a transpose on a 3D array to account for different
425 ! storage conventions between wrf output and runtime
427 real,dimension(:,:,:),intent(in)::A
428 real,dimension(:,:,:),intent(out)::B
431 if( size(A,1).ne.size(B,1) .or. &
432 size(A,2).ne.size(B,3) .or. &
433 size(A,3).ne.size(B,2) )then
434 call crash('Invalid array sizes in transpose')
443 end subroutine transpose_var
445 subroutine parse_wrf_time(wrfstr,time)
446 ! parse a wrf time string into an esmf time class
447 ! example wrf time string: "2011-01-01_00:00:00"
449 character(len=TIMESTRLEN),intent(in)::wrfstr
450 type(ESMF_Time),intent(out)::time
452 integer::year,month,day,hour,minute,second
453 character(len=1)::a1,a2,a3,a4,a5
455 read(wrfstr,'(I04,A1,I02,A1,I02,A1,I02,A1,I02,A1,I02)') &
456 year,a1,month,a2,day,a3,hour,a4,minute,a5,second
457 call ESMF_TimeSet(time,YY=year,MM=month,DD=day,H=hour,M=minute,S=second)
458 end subroutine parse_wrf_time
460 subroutine get_next_timestep(files,ifile,istep)
461 ! choose a file and time step within the file to use
462 ! for the next call to the moisture model
464 ! This assumes files are in sequential order, and
465 ! allows for reanalysis runs where there may be
466 ! time step overlaps from one file to the next.
467 ! Here, we prefer to move on to the next file
468 ! rather than the next time step in the old file
469 ! to use model arrays closer to reanalysis.
470 ! If there is no overlap, this routine will
471 ! increment from one file to the next as expected.
473 ! This subroutine will return istep=ifile=0, when
474 ! there are no more steps to process.
476 type(ncfile),dimension(:),intent(in)::files
477 integer,intent(inout)::ifile,istep
480 type(ESMF_Time)::time1,time2,time3
483 ! for initialization only
488 nstep=size(files(ifile)%times)
489 time1=files(ifile)%times(istep)
491 if(istep+1.le.size(files(ifile)%times))then
492 time2=files(ifile)%times(istep+1)
499 if(ifile+1.le.nfile)then
500 ! if there is another file after the current one
501 time3=files(ifile+1)%times(1)
503 ! if there is not another file pick next time step in current file
508 if(time2.ge.time3)then
509 ! if next file has a time step closer to the current time
510 ! or if there are no more time steps in the current file,
515 ! otherwise use the next step in the current file
520 if(ifile.gt.nfile.or.istep.gt.size(files(ifile)%times))then
521 ! make sure the current time step is valid
526 end subroutine get_next_timestep
528 subroutine check(status)
529 integer,intent(in)::status
530 ! check a netcdf status code for error
531 if(status.ne.nf90_noerr) then
532 call crash(trim(nf90_strerror(status)))
536 end module moisture_util
538 program moisture_main
540 use module_fr_sfire_phys, only: advance_moisture, init_fuel_cats, moisture_classes
541 use module_fr_sfire_util, only: fire_print_msg
545 integer::fmoist_init=2
547 integer::istep,i,iglobal
550 integer :: numarg,ifile,ii,nfile,s,sn,sd,ierr
551 character(len=120) :: wrfoutfname
552 character(len=*),parameter :: outputfname='moisture.nc'
553 character(len=64)::timediffstr
555 type(ncfile),dimension(:),allocatable::wrffile
556 type(ncfile)::wrfoutfile
558 type(ESMF_Time)::oldtime,timenow,starttime
559 type(ESMF_TimeInterval)::timedt
561 integer,parameter::iprint=100,jprint=100
563 real::hours,t,q,p,rain
564 real,dimension(5)::fmc_equi,fmc_tend,fmc_gc
565 logical,parameter::debugprint=.false.
566 integer,parameter::debugfile=8
568 #ifndef GFORTRAN_IARGC
569 integer,external::iargc
572 1 format(a4,a8, a6, a9, a6 ,a8, a6, 5(a5,i1,a8,i1,a5,i1))
573 2 format(a4,a8, a6, a9, a6 ,a8, a6, 5(a6,a9,a6))
574 3 format(i4,f8.2,f6.1,f9.1,f6.3,f8.1,f6.3,5(f6.3,f9.1,f6.3))
577 open(debugfile,file='moisture_output.txt',form='formatted',status='unknown')
578 write(debugfile,1)'Step','Time', 'T','P','Q','RAIN','RH',('EQUI',k,'TLAG',k,'FMC',k,k=1,moisture_classes)
579 write(debugfile,2)' ','hours','K','Pa','kg/kg','mm','1',('kg/kg','hours','kg/kg',k=1,moisture_classes)
583 ! parse commandline argument for wrfout file name
586 if(numarg .lt. 1)then
587 print*, 'usage: ./moisture.exe [-r] wrfout1 [wrfout2 [wrfout3 [...]]]'
591 ! check for restart flag
592 call getarg(1,wrfoutfname)
594 ! allocate local storage for wrfout metadata
595 if(trim(wrfoutfname).eq.'-r')then
596 allocate(wrffile(numarg-1))
598 allocate(wrffile(numarg))
601 ! open files and populate ncfile objects for each
602 ! check that the sizes are consistent
606 call getarg(i,wrfoutfname)
607 if(trim(wrfoutfname).eq.'-r')then
609 call initialize_and_check(outputfname,wrfoutfile)
611 print*,'using: '//trim(wrfoutfname)
613 call initialize_and_check(wrfoutfname,wrffile(nfile))
617 ! allocate memore for model arrays
618 call initialize_vars(vars)
620 oldtime=wrffile(1)%times(1)
623 ! if this isn't a restart run, we need to create
624 ! a new output file, clobber anything that might
625 ! be there, otherwise we append data to the restart
627 call create_output(outputfname)
629 ! model initialization calls
631 call init_fuel_cats(.true.)
632 print *,moisture_classes,' moisture classes'
634 ! initialize various looping indices
639 ! get the first file/time step we will read
640 call get_next_timestep(wrffile,ifile,ii)
642 starttime=wrfoutfile%times(size(wrfoutfile%times))
644 starttime=wrffile(1)%times(1)
647 ! for restarts, we have to find the first time step in the
648 ! wrfout's after the the time in the restart
649 do while(restart.and.wrffile(ifile)%times(ii).le.starttime)
650 call get_next_timestep(wrffile,ifile,ii)
651 if(ifile.eq.0)goto 1000
655 ! after all the initialization code, we crash here if there are no
656 ! new time steps to read
658 call crash('no new time steps available')
661 ! let's tell the user what we are doing
662 print*,'starting at file ',ifile,' step ',ii
663 call ESMF_TimeGet(wrffile(ifile)%times(ii),TimeString=timediffstr)
664 print*,'wrffile time=',trim(timediffstr)
665 call ESMF_TimeGet(starttime,TimeString=timediffstr)
666 print*,'(re)start time=',trim(timediffstr)
668 ! get the next target time step
669 call get_next_timestep(wrffile,ifile,ii)
673 ! main program loop, go until get_next_timestep returns ifile==0
676 ! keep track of the number of loops we have made
680 ! read initialization data
682 call read_file(wrfoutfile,-1,vars,ierr,restart=.true.)
684 call crash('invalid restart file')
688 call read_file(wrffile(ifile),ii,vars,ierr)
690 print*,'invalid data: skipping file ',ifile,' step ',ii
695 ! increment time keeping
697 timenow=wrffile(ifile)%times(ii)
699 ! let's tell the user what we are doing
700 print*,'reading file ',ifile,' of ',nfile
701 print*,'time step ',ii,' of ',wrffile(ifile)%ntime
702 call ESMF_TimeGet(timenow,timeString=timediffstr)
703 print*,'time: ',trim(timediffstr)
706 dt=0. ! required on initialization
709 if(timenow.lt.oldtime)then
710 call crash('Negative time step detected.')
712 ! get the number of seconds that the model needs to advance
713 timedt=timenow-oldtime
714 call ESMF_TimeIntervalGet(timedt,S=s,sn=sn,sd=sd,TimeString=timediffstr)
716 dt=dble(s)+dble(sn)/dble(sd)
724 call advance_moisture( &
725 initialize, & ! initialize timestepping. true on the first call at time 0, then false
726 ims,ime, jms,jme, & ! memory dimensions
727 its,ite, jts,jte, & ! tile dimensions
728 nfmc, & ! dimension of moisture fields
729 dt, & ! timestep = time step time elapsed from the last call
730 vars%rain_accum, vars%rain_zero, & ! accumulated rain
731 vars%t2, vars%q2, vars%psfc, & ! temperature (K), vapor contents (kg/kg), pressure (Pa) at the surface
732 vars%rain_old, & ! previous value of accumulated rain
733 vars%t2_old, vars%q2_old, vars%psfc_old, & ! previous values of the atmospheric state at surface
734 vars%rh_fire, & ! relative humidity diagnostics
735 vars%fmc_gc, & ! fuel moisture by class, updated
736 vars%fmc_equi, & ! fuel moisture equilibrium by class, for diagnostics only
737 vars%fmc_tend & ! fuel moisture tendency by classe, for diagnostics only
742 t=vars%t2(iprint,jprint)
743 q=vars%q2(iprint,jprint)
744 p=vars%psfc(iprint,jprint)
745 rain=vars%rain_accum(iprint,jprint) + vars%rain_zero(iprint,jprint)
746 fmc_equi(:)=vars%fmc_equi(iprint,:,jprint)
747 fmc_tend(:)=vars%fmc_tend(iprint,:,jprint)
748 fmc_gc(:)=vars%fmc_gc(iprint,:,jprint)
749 write(debugfile,3)iglobal,hours,t,p,q,rain, &
750 vars%rh_fire(iprint,jprint), &
751 (fmc_equi(k),fmc_tend(k),fmc_gc(k), &
752 k=1,moisture_classes)
754 ! write the results to the output file
755 call write_output(outputfname,vars)
757 10001 continue ! we skip to here on invalid data
759 ! after the first pass through the loop, nothing special needs to be done
760 ! for restart runs, so turn of the restart flag here
764 call get_next_timestep(wrffile,ifile,ii)
766 enddo ! end main loop
768 ! free up allocated memory
769 call destroy_vars(vars)
771 call destroy_file(wrffile(i))
774 end program moisture_main