2 ! SFIRE - Spread fire model in WRF-Fire
4 !*** Jan Mandel August 2007 - March 2011
5 !*** email: Jan.Mandel@gmail.com
7 ! For support please subscribe to the wrf-fire mailing list at NCAR at
8 ! http://mailman.ucar.edu/mailman/listinfo/wrf-fire
9 ! or go to http://www.openwfm.org/wiki/WRF-Fire_user_support
11 ! Current drafts of the technical documentation and
12 ! user's guide can be found at
14 ! http://www.openwfm.org/wiki/WRF-Fire_documentation
15 ! http://www.openwfm.org/wiki/WRF-Fire_publications
17 ! This module is the only entry point from WRF-ARW to the wildland
18 ! fire model. The call to sfire_driver advances the fire model by
19 ! one timestep. The fire model inputs the wind and outputs
20 ! temperature and humidity tendencies. The fire model also inputs a
21 ! number of constant arrays (fuel data, topography). Additional
22 ! arguments are model state (for data assimilation) and constant arrays
23 ! the model gives to WRF for safekeeping because it is not allowed
26 ! This code as of mid-2011 is described in [1]. If you use this code,
27 ! please acknowledge our work by citing [1].
32 ! The fire physics code is adapted from the CAWFE code [2].
33 ! The coupling with WRF is adapted from a code by Ned Patton,
34 ! coupling a Fortran 90 port of the CAWFE fire module to WRF [3].
35 ! Support of refined fire grids in WRF was provided by John Michalakes.
36 ! Jonathan D. Beezley has set up and maintained the WRF build and
37 ! execution environment, provided software engineering infrastructure
38 ! including synchronization with the WRF repository, and was responsibe
39 ! for all aspects of WRF modification. UCD students Minjeong Kim and
40 ! Volodymyr Kondratenko have contributed to the implementation of the
41 ! fire propagation by the level set method.
45 ! [1] Jan Mandel, Jonathan D. Beezley, and Adam K. Kochanski, "Coupled
46 ! atmosphere-wildland fire modeling with WRF 3.3 and SFIRE 2011,
47 ! Geoscientific Model Development (GMD) 4, 591-610, 2011.
48 ! doi:10.5194/gmd-4-591-2011
50 ! [2] T. L. Clark, J. Coen, and D. Latham, Description of a coupled
51 ! atmosphere-fire model, Intl. J. Wildland Fire, vol. 13, pp. 49-64,
54 ! [3] Edward G. Patton and Janice L. Coen, WRF-Fire: A Coupled
55 ! Atmosphere-Fire Module for WRF, Preprints of Joint MM5/Weather
56 ! Research and Forecasting Model Users' Workshop, Boulder, CO,
57 ! June 22-25, 2004, pp. 221-223, NCAR
59 ! ---------------------------------------------
63 ! For current activity and development trends please check out
64 ! http://ccm.ucdenver.edu/wiki/User:Jmandel/blog
65 ! http://www.openwfm.org/wiki/WRF-Fire_development_notes
68 module module_fr_sfire_driver
69 ! use this module for standalone call, you only need to provide some mock-up wrf modules
71 use module_fr_sfire_model, only: sfire_model
72 use module_fr_sfire_phys, only: fire_params, init_fuel_cats, fuel_moisture, &
73 advance_moisture, moisture_classes, &
75 use module_fr_sfire_atm, only: apply_windrf,interpolate_wind2fire_height,interpolate_atm2fire, &
76 interpolate_z2fire,setup_wind_log_interpolation
77 use module_fr_sfire_util
78 !use module_fr_sfire_util, only: lines_type,fire_max_lines
79 ! Driver layer modules
81 USE module_dm , ONLY : ntasks_x,ntasks_y,local_communicator,mytask,ntasks,wrf_dm_sum_reals
82 USE module_comm_dm , ONLY : halo_fire_fuel_sub, halo_fire_tign_sub, halo_fire_wind_f_sub, &
83 halo_fire_wind_a_sub, halo_fire_ph_sub, halo_fire_zsf_sub, halo_fire_longlat_sub, &
84 halo_fire_phb_sub, halo_fire_z0_sub, halo_fire_lfn_sub, HALO_FIRE_MAG_sub, HALO_FIRE_MFG_sub, &
87 use module_fr_sfire_atm, only: read_emissions_table, add_fire_emissions
91 USE module_domain, only: domain
92 USE module_configure, only: grid_config_rec_type
93 use module_model_constants, only: reradius, & ! 1/earth radiusw
100 public sfire_driver_em,use_atm_vars,set_flags, &
101 set_fp_from_grid, fire_ignition_convert
102 public ifun_beg, ifun_step, ifun_end
104 logical:: use_atm_vars=.true. ! interpolate wind from atm mesh and average output fluxes back
105 logical:: interpolate_long_lat=.true. ! get fxlong fxlat by interpolation
107 logical:: fmoist_run, fmoist_interp, fire_run ! which kind of model to run overall
109 integer, parameter:: ifun_beg=1, ifun_step=3, ifun_end=6
113 ! to write debugging information
116 subroutine sfire_driver_em ( grid , config_flags &
117 ,time_step_start,dt &
118 ,fire_ifun_start,fire_ifun_end,tsteps &
119 ,ids,ide, kds,kde, jds,jde &
120 ,ims,ime, kms,kme, jms,jme &
121 ,ips,ipe, kps,kpe, jps,jpe &
122 ,ifds,ifde, jfds,jfde &
123 ,ifms,ifme, jfms,jfme &
124 ,ifps,ifpe, jfps,jfpe &
128 !*** purpose: driver from grid structure
134 TYPE(domain) , TARGET :: grid ! state
135 TYPE (grid_config_rec_type) , INTENT(IN) :: config_flags ! namelist
136 real, intent(in):: time_step_start, dt
137 integer, intent(in):: fire_ifun_start,fire_ifun_end,tsteps ! driver cycle controls
138 integer, intent(in):: &
139 ids,ide, kds,kde, jds,jde, &
140 ims,ime, kms,kme, jms,jme, &
141 ips,ipe, kps,kpe, jps,jpe, &
142 ifds,ifde, jfds,jfde, &
143 ifms,ifme, jfms,jfme, &
145 real,dimension(ims:ime, kms:kme, jms:jme),intent(in), optional::rho,z_at_w,dz8w
148 TYPE(lines_type):: ignition, hfx
149 integer::fire_ifun,ir,jr,istep,itimestep,i,ipe1,kpe1,jpe1,j
151 real, dimension(ifms:ifme, jfms:jfme)::lfn_out
152 real:: corner_ll,corner_ul,corner_ur,corner_lr, max_u, max_v, max_w, max_rho, min_rho
153 character(len=128)msg
154 type(fire_params)::fp
157 logical:: run_advance_moisture,run_fuel_moisture, moisture_initializing
164 call sfire_debug_hook(config_flags%fire_debug_hook_sec)
166 if(fire_ifun_start.le.1)call print_id ! print id only once, during initialization
169 ! **** THE FOLLOWING REALLY SHOULD BE DONE ONCE NOT EVERY TIMESTEP
171 ! populate our structures from wrf
173 call set_fp_from_grid(grid,fp)
175 ! copy configuration flags to sfire internal structures
176 call set_flags(config_flags)
180 call fire_ignition_convert (config_flags,ignition, &
181 grid%fxlong, grid%fxlat, &
182 ifds,ifde, jfds,jfde, &
183 ifms,ifme, jfms,jfme, &
184 ifps,ifpe, jfps,jfpe )
185 call fire_hfx_convert (config_flags,hfx)
187 ! store computed mesh units
188 grid%unit_fxlong = ignition%unit_fxlong
189 grid%unit_fxlat = ignition%unit_fxlat
192 #ifndef SFIRE_STANDALONE
194 ! see what we got from wrf
195 !! need to replace ipe by min(ide-1,ipe) and similarly jpe
197 if(fire_print_msg.ge.2 .and. fire_ifun_start .gt. 1)then
203 max_u=fun_real(REAL_AMAX, &
204 ims,ime,kms,kme,jms,jme, & ! memory dims
205 ids,ide,kds,kde,jds,jde, & ! domain dims
206 ips,ipe1,kps,kpe1,jps,jpe1, & ! patch or tile dims
207 1,0,0, & ! staggering
210 max_v=fun_real(REAL_AMAX, &
211 ims,ime,kms,kme,jms,jme, & ! memory dims
212 ids,ide,kds,kde,jds,jde, & ! domain dims
213 ips,ipe1,kps,kpe1,jps,jpe1, & ! patch or tile dims
214 0,0,1, & ! staggering
217 max_w=fun_real(REAL_AMAX, &
218 ims,ime,kms,kme,jms,jme, & ! memory dims
219 ids,ide,kds,kde,jds,jde, & ! domain dims
220 ips,ipe1,kps,kpe1,jps,jpe1, & ! patch or tile dims
221 0,1,0, & ! staggering
224 !write(msg,93)time_step_start,'Maximal u v w wind',max_u,max_v,max_w,'m/s'
226 !write(msg,92)time_step_start,'Min and max rho ',min_rho,max_rho,'kg/m^3'
229 write(msg,91)time_step_start,'Maximal u wind ',max_u,'m/s'
231 write(msg,91)time_step_start,'Maximal v wind ',max_v,'m/s'
233 write(msg,91)time_step_start,'Maximal w wind ',max_w,'m/s'
236 if (present(rho)) then
238 max_rho=fun_real(REAL_MAX, &
239 ims,ime,kms,kme,jms,jme, & ! memory dims
240 ids,ide,kds,kde,jds,jde, & ! domain dims
241 ips,ipe1,kps,kpe1,jps,jpe1, & ! patch or tile dims
242 0,0,0, & ! staggering
245 min_rho=fun_real(REAL_MIN, &
246 ims,ime,kms,kme,jms,jme, & ! memory dims
247 ids,ide,kds,kde,jds,jde, & ! domain dims
248 ips,ipe1,kps,kpe1,jps,jpe1, & ! patch or tile dims
249 0,0,0, & ! staggering
253 write(msg,91)time_step_start,'Minimal rho ',min_rho,'kg/m^3'
255 write(msg,91)time_step_start,'Maximal rho ',max_rho,'kg/m^3'
261 93 format('Time ',f11.3,' s ',a,3e12.3,1x,a)
262 92 format('Time ',f11.3,' s ',a,2e12.3,1x,a)
263 91 format('Time ',f11.3,' s ',a,e12.3,1x,a)
271 ir=grid%sr_x ! refinement ratio
273 write(msg,'(a,2i4)')'fire mesh refinement ratios', ir,jr
275 if(ir.le.0.or.jr.le.0)then
276 call crash('fire mesh refinement ratio must be positive')
278 itimestep=grid%itimestep
279 restart=config_flags%restart .or. config_flags%cycling .or. config_flags%fire_restart ! skip state initialization
283 ! **** moisture model
285 ! decide what to run - moisture, interpolation, or fire model itself
286 fmoist_run = config_flags%fmoist_run
287 fmoist_interp = config_flags%fmoist_interp
288 if(fire_fmc_read.ne.0.and.fmoist_run)call crash('fmoist_run=T requires fire_fmc_read=0')
289 fire_run = .not. config_flags%fmoist_only
292 moisture_time = time_step_start
293 run_advance_moisture = .false. ! default
294 run_fuel_moisture = .false. ! default
295 moisture_initializing = fire_ifun_start < 3
300 if(moisture_initializing)then
301 if(fire_ifun_end>2)call crash('initialization must be run separately')
302 grid%fmoist_lasttime=moisture_time ! initialize the last time the model has run to start of run
303 grid%fmoist_nexttime=moisture_time
304 call message('moisture initialization')
305 run_advance_moisture = .true.
306 else ! regular timestep
307 if(config_flags%fmoist_freq > 0)then ! regular timestep. go by multiples?
308 if(mod(grid%itimestep,config_flags%fmoist_freq) .eq. 0)then
309 write(msg,'(a,i10,a,i10)')'moisture model runs because timestep ',grid%itimestep,' is a multiple of ',config_flags%fmoist_freq
311 run_advance_moisture = .true.
314 if(.not. moisture_time < grid%fmoist_nexttime) then ! no, by time interval
315 write(msg,'(a,f12.2,a)')'moisture model runs because time ',grid%fmoist_nexttime,'s has arrived'
317 run_advance_moisture = .true.
320 if(run_advance_moisture)then ! decide on timing
321 dt_moisture = moisture_time - grid%fmoist_lasttime ! Time since moisture model run the last time. Should be long.
322 grid%fmoist_lasttime = moisture_time
323 if(config_flags%fmoist_freq > 0)then
324 write(msg,'(a,f12.2,a,i10,a)')'moisture time step is ',dt_moisture,'s running every ',config_flags%fmoist_freq,' steps'
327 grid%fmoist_nexttime = moisture_time + config_flags%fmoist_dt
328 write(msg,'(a,f12.2,a,f12.2,a)')'moisture time step is ',dt_moisture,'s next run at ',grid%fmoist_nexttime,'s'
331 if(fmoist_interp)then
332 call message('moisture interpolation to fuels will run because moisture model does')
333 run_fuel_moisture=.true.
337 elseif(itimestep.eq.1.and.fmoist_interp)then
338 call message('initializing, moisture interpolation to fuels will run from input data')
339 run_fuel_moisture=.true.
342 !$OMP CRITICAL(SFIRE_DRIVER_CRIT)
343 write(msg,'(a,i1,a,i1,a,l1)') &
344 'sfire_driver_em: ifun from ',fire_ifun_start,' to ',fire_ifun_end,' restart=',restart
345 !$OMP END CRITICAL(SFIRE_DRIVER_CRIT)
348 do istep=0,tsteps ! istep >0 is for testing only, exit after the first call
349 itimestep = grid%itimestep + istep ! in the first call, do fire_test_steps steps of the fire model
351 do fire_ifun=fire_ifun_start,fire_ifun_end
353 ! 1 = moisture_initialize run pass 1: interpolate height to zsf=terrain
354 ! 2 = initialize run pass 2: set fuel data, terrain gradient
355 ! 3 = initialize timestep: interpolate winds, check for ignition, time step on moisture model
356 ! 4 = do one timestep
357 ! 5 = copy timestep output to input
358 ! 6 = compute output fluxes
364 if(fire_ifun.eq.1)then
366 ! halo exchange on topography
367 #include "HALO_FIRE_LONGLAT.inc"
368 !! if(fire_topo_from_atm.eq.1)then
369 !!#include "HALO_FIRE_HT.inc"
371 ! base geopotential and roughness
372 #include "HALO_FIRE_PHB.inc"
373 #include "HALO_FIRE_Z0.inc"
374 if(kfmc_ndwi > 0 .and. fndwi_from_ndwi .eq.1)then
375 #include "HALO_FIRE_NDWI.inc"
378 elseif(fire_ifun.eq.2)then
379 ! halo exchange on zsf width 2
380 #include "HALO_FIRE_ZSF.inc"
382 if(config_flags%chem_opt>0 .or. config_flags%tracer_opt > 0)then
383 ! need reading fuel categories first
384 call read_emissions_table(config_flags%chem_opt,config_flags%tracer_opt)
388 elseif(fire_ifun.eq.3)then
389 ! halo exchange on atm winds and geopotential, width 1 for interpolation
390 #include "HALO_FIRE_WIND_A.inc"
391 #include "HALO_FIRE_PH.inc"
393 elseif(fire_ifun.eq.4)then
394 ! halo exchange on fire winds width 2 for a 2-step RK method
395 #include "HALO_FIRE_WIND_F.inc"
397 if(run_fuel_moisture)then
398 ! have interpolated to the fire grid
399 #include "HALO_FIRE_MFG.inc"
402 elseif(fire_ifun.eq.6)then
403 ! computing fuel_left needs ignition time from neighbors
404 #include "HALO_FIRE_TIGN.inc"
405 call message('halo exchange on lfn width 2')
406 #include "HALO_FIRE_LFN.inc"
411 ! print *,'dt: ',dt,grid%dt,' diff ', dt-grid%dt
412 ! need domain by 1 smaller, in last row.col winds are not set properly
413 call sfire_driver_phys ( &
415 ids,ide-1, kds,kde, jds,jde-1, &
416 ims,ime, kms,kme, jms,jme, &
417 ips,min(ipe,ide-1), kps,kpe, jps,min(jpe,jde-1), &
418 ifds,ifde-ir, jfds,jfde-jr, &
419 ifms,ifme, jfms,jfme, &
420 ifps,min(ifpe,ifde-ir), jfps,min(jfpe,jfde-jr), &
421 ir,jr, & ! atm/fire grid ratio
422 grid%num_tiles, & ! atm grid tiling
423 grid%i_start,min(grid%i_end,ide-1), &
424 grid%j_start,min(grid%j_end,jde-1), &
425 itimestep,restart,config_flags%fire_fuel_read,config_flags%fire_fuel_cat, & ! in scalars
426 time_step_start,dt,grid%dx,grid%dy, &
427 grid%u_frame,grid%v_frame, &
428 config_flags%fire_ext_grnd,config_flags%fire_ext_crwn,config_flags%fire_crwn_hgt, &
429 ignition,hfx, & ! lines
430 grid%u_2,grid%v_2, & ! atm arrays in
431 grid%ph_2,grid%phb, & ! geopotential
432 grid%z0, & ! roughness height
433 grid%ht, & ! terrain height
434 grid%xlong,grid%xlat, & ! coordinates of atm grid centers, for ignition location
435 grid%lfn,grid%tign_g,grid%fuel_frac, & ! state arrays, fire grid
436 grid%fire_area, & ! redundant, for display, fire grid
437 grid%fuel_frac_burnt, &
438 lfn_out, & ! work - one timestep
439 grid%avg_fuel_frac, & ! out redundant arrays, atm grid
440 grid%grnhfx,grid%grnqfx,grid%canhfx,grid%canqfx, & ! out redundant arrays, atm grid
442 grid%fgrnhfx,grid%fgrnqfx,grid%fcanhfx,grid%fcanqfx, & ! out redundant arrays, atm grid
443 grid%ros,grid%flineint,grid%flineint2, & ! diagnostic variables
444 grid%f_ros0,grid%f_rosx,grid%f_rosy,grid%f_ros,& ! fire risk spread
445 grid%f_int,grid%f_lineint,grid%f_lineint2, & ! fire risk intensities
446 grid%f_ros11,grid%f_ros12,grid%f_ros13,grid%f_ros21, & ! fire spread in nodal directions
447 grid%f_ros23,grid%f_ros31,grid%f_ros32,grid%f_ros33, & ! fire spread in nodal directions
448 grid%fxlong,grid%fxlat, &
450 grid%nfuel_cat, & ! input, or internal for safekeeping
452 grid%fz0, grid%fwh, &
453 fp, & ! structure with pointers passed to spread rate calculation
454 config_flags%nfmc, & ! moisture model variables start
455 run_advance_moisture,run_fuel_moisture,dt_moisture, & ! moisture model control
456 config_flags%fmep_decay_tlag, & ! moisture extended model assim. diffs decay time lag
457 grid%rainc, grid%rainnc, & ! accumulated rain from different sources
458 grid%t2, grid%q2, grid%psfc, & ! temperature (K), vapor contents (kg/kg), pressure (Pa) at the surface
459 grid%rain_old, & ! previous value of accumulated rain
460 grid%t2_old, grid%q2_old, grid%psfc_old, & ! previous values of the atmospheric state at surface
461 grid%rh_fire, & ! relative humidity, diagnostics
462 grid%fmc_gc, & ! fuel moisture fields updated, by class, assumed set to something reasonable
463 grid%fmep, & ! fuel moisture extended model parameters
464 grid%fmc_equi, & ! fuel moisture fields updated, by class, equilibrium diagnostic
465 grid%fmc_lag, & ! fuel moisture fields updated, by class, tendency diagnostic
466 fp%fmc_g, & ! write-only alias. need to exit before using fp again
473 if(fire_ifun.eq.2)then
474 ! halo exchange on all fuel data width 2
475 #include "HALO_FIRE_FUEL.inc"
476 ! fire state was initialized
477 call message('halo exchange on lfn width 2')
478 #include "HALO_FIRE_LFN.inc"
480 if(run_fuel_moisture)then
481 if(fire_ifun.eq.3)then
482 ! prepare for interpolation to the fire grid
483 #include "HALO_FIRE_MAG.inc"
489 if(fire_ifun.eq.6)then
490 if(config_flags%chem_opt>0 .or. config_flags%tracer_opt>0)then
491 if(.not.(present(rho).and.present(dz8w)))then
492 call crash('sfire_driver_em: must have rho and dz8w to call add_fire_emissions')
494 call add_fire_emissions( &
495 config_flags%chem_opt,config_flags%tracer_opt,dt,grid%dx,grid%dy, &
496 ifms,ifme,jfms,jfme, &
497 ifps,ifpe,jfps,jfpe, & ! use patch instead of tile
498 ids,ide,kds,kde,jds,jde, &
499 ims,ime,kms,kme,jms,jme, &
500 ips,ipe,kps,kpe,jps,jpe, &
501 rho,dz8w, & ! from atmosphere state
502 grid%fgip, grid%fuel_frac_burnt, grid%nfuel_cat, & ! from fire state
503 grid%chem,grid%tracer) ! update/output
511 if(tsteps>0)call crash('sfire_driver_em: test run of uncoupled fire model completed')
512 call time_end('sfire')
514 end subroutine sfire_driver_em
520 subroutine sfire_driver_phys (ifun, &
521 ids,ide, kds,kde, jds,jde, & ! atm grid dimensions
522 ims,ime, kms,kme, jms,jme, &
523 ips,ipe, kps,kpe, jps,jpe, &
524 ifds, ifde, jfds, jfde, & ! fire grid dimensions
525 ifms, ifme, jfms, jfme, &
526 ifps, ifpe, jfps, jfpe, & ! fire patch in - will use smaller
527 ir,jr, & ! atm/fire grid ratio
528 num_tiles,i_start,i_end,j_start,j_end, & ! atm grid tiling
529 itimestep,restart,ifuelread,nfuel_cat0, & ! in scalars
530 time_step_start,dt,dx,dy, & ! in scalars
532 fire_ext_grnd,fire_ext_crwn,fire_crwn_hgt, &
533 ignition,hfx, & ! lines
534 u,v, & ! in arrays, atm grid
538 lfn,tign,fuel_frac, & ! state arrays, fire grid
539 fire_area, & ! redundant state, fire grid
541 lfn_out, & ! out level set function
543 grnhfx,grnqfx,canhfx,canqfx, & ! out redundant arrays, atm grid
544 uah,vah, & ! out atm grid
545 fgrnhfx,fgrnqfx,fcanhfx,fcanqfx, & ! out redundant arrays, fire grid
546 ros,flineint,flineint2, & ! diagnostic variables
547 f_ros0,f_rosx,f_rosy,f_ros, & ! fire risk spread
548 f_int,f_lineint,f_lineint2, & ! fire risk intensities
549 f_ros11,f_ros12,f_ros13,f_ros21, & ! fire spread in nodal directions
550 f_ros23,f_ros31,f_ros32,f_ros33, & ! fire spread in nodal directions
553 nfuel_cat, & ! in array, data, fire grid, or constant internal
554 fuel_time, & ! save constant internal data, fire grid
557 nfmc, & ! number of fuel moisture classes
558 run_advance_moisture,run_fuel_moisture,dt_moisture,& ! moisture model control
559 fmep_decay_tlag, & ! moist. extended model assim. diffs time lag
560 rainc,rainnc, & ! accumulated rain from different sources
561 t2, q2, psfc, & ! temperature (K), vapor contents (kg/kg), pressure (Pa) at the surface
562 rain_old, & ! previous value of accumulated rain
563 t2_old, q2_old, psfc_old, & ! previous values of the atmospheric state at surface
564 rh_fire, & ! relative humidity, diagnostics
565 fmc_gc, & ! fuel moisture fields updated, by class, assumed set to something reasonable
566 fmep, & ! fuel moisture extended model parameters
567 fmc_equi, & ! fuel moisture fields updated, by class equilibrium diagnostic
568 fmc_lag, & ! fuel moisture fields updated, by class tendency diagnostic
569 fmc_g, & ! fuel moisture, alias of fp%fmc_g
571 fndwi) ! ndwi on fire grid
578 integer, intent(in)::ifun, &
579 ids,ide, kds,kde, jds,jde, & ! atm domain bounds
580 ims,ime, kms,kme, jms,jme, & ! atm memory bounds
581 ips,ipe, kps,kpe, jps,jpe, & ! atm patch bounds
582 ifds, ifde, jfds, jfde, & ! fire domain bounds
583 ifms, ifme, jfms, jfme, & ! fire memory bounds
584 ifps, ifpe, jfps, jfpe, & ! fire patch bounds
585 ir,jr, & ! atm/fire grid refinement ratio
586 nfmc, & ! number of fuel moisture classes
587 itimestep, & ! number of this timestep
588 ifuelread, & ! how to initialize nfuel_cat:
589 ! -1=not at all, done outside
593 nfuel_cat0, & ! fuel category to initialize everything to
594 num_tiles ! number of tiles
596 logical, intent(in)::restart
598 integer,dimension(num_tiles),intent(in) :: i_start,i_end,j_start,j_end ! atm grid tiling
601 time_step_start, & ! time step start
602 dt, & ! time step length
603 dx,dy, & ! atm grid step
604 u_frame,v_frame, & ! velocity offset
605 fire_crwn_hgt, & ! lowest height crown fire heat is released (m)
606 fire_ext_grnd, & ! extinction depth of ground fire heat (m)
607 fire_ext_crwn ! and for the canopy (m)
610 TYPE (lines_type), intent(inout):: ignition,hfx
612 real,intent(in),dimension(ims:ime,kms:kme,jms:jme)::u,v, & ! wind velocity (m/s) (staggered atm grid)
613 ph, phb ! geopotential (w-points atm grid)
614 real,intent(in),dimension(ims:ime, jms:jme):: z0, & ! roughness height
616 real,intent(out),dimension(ims:ime,jms:jme)::&
617 uah, & ! atm wind at fire_wind_height, diagnostics
618 vah ! atm wind at fire_wind_height, diagnostics
620 real, dimension(ims:ime, jms:jme), intent(inout)::xlong, xlat, ndwi ! inout because of extension at bdry
622 real, intent(inout), dimension(ifms:ifme,jfms:jfme):: & ! fuel data; can be also set inside (cell based, fire grid)
626 real, intent(inout), dimension(ifms:ifme, jfms:jfme):: &
627 lfn,tign,fuel_frac, & ! state: level function, ign time, fuel left
628 lfn_out ! fire wind velocities
630 real, intent(out), dimension(ifms:ifme, jfms:jfme):: &
631 fire_area, & ! fraction of each cell burning
634 real, intent(out), dimension(ims:ime, jms:jme):: & ! redundant arrays, for display purposes only (atm grid)
635 avg_fuel_frac, & ! average fuel fraction
636 grnhfx, & ! heat flux from ground fire (W/m^2)
637 grnqfx, & ! moisture flux from ground fire (W/m^2)
638 canhfx, & ! heat flux from crown fire (W/m^2)
639 canqfx ! moisture flux from crown fire (W/m^2)
641 real, intent(out), dimension(ifms:ifme, jfms:jfme):: & ! redundant arrays, for display only, fire grid
642 fgrnhfx, & ! heat flux from ground fire (W/m^2)
643 fgrnqfx, & ! moisture flux from ground fire (W/m^2)
644 fcanhfx, & ! heat flux from crown fire (W/m^2)
645 fcanqfx, & ! moisture flux from crown fire (W/m^2)
646 ros,flineint,flineint2, & ! diagnostic variables
647 f_ros0,f_rosx,f_rosy,f_ros, & ! fire risk spread
648 f_int,f_lineint,f_lineint2, & ! fire risk intensities
649 f_ros11,f_ros12,f_ros13,f_ros21, & ! fire spread in nodal directions
650 f_ros23,f_ros31,f_ros32,f_ros33 ! fire spread in nodal directions
653 ! moisture model arguments
654 logical, intent(in)::run_advance_moisture,run_fuel_moisture
655 real, intent(in)::dt_moisture
656 real, intent(in)::fmep_decay_tlag
657 real, intent(in), dimension(ims:ime,jms:jme):: t2, q2, psfc, rainc, rainnc
658 real, intent(inout), dimension(ims:ime,jms:jme):: t2_old, q2_old, psfc_old, rain_old
659 real, intent(out),dimension(ims:ime,jms:jme):: rh_fire
660 real, intent(inout), dimension(ims:ime,nfmc,jms:jme):: fmc_gc
661 real, intent(inout), dimension(ims:ime,2,jms:jme):: fmep
662 real, intent(out), dimension(ims:ime,nfmc,jms:jme):: fmc_equi,fmc_lag
663 real, intent(inout), dimension(ifms:ifme,jfms:jfme):: fmc_g
667 ! ***** data (constant in time) *****
669 real, dimension(ifms:ifme, jfms:jfme), intent(inout)::fxlong,fxlat, & ! fire mesh coordinates
671 real, intent(out), dimension(ifms:ifme, jfms:jfme)::fuel_time ! fire params arrays
673 type(fire_params),intent(inout)::fp
676 real :: dxf,dyf,time_start,latm, s
677 integer :: its,ite,jts,jte,kts,kte, & ! tile
678 ij,i,j,k,id,pid,ipe1,jpe1,ite1,jte1, &
680 ifts,ifte,jfts,jfte ! fire tile
681 character(len=128)::msg
683 real, parameter::zero=0.
687 ! time - assume dt does not change
688 ! time_start = (itimestep-1) * dt ! timestep 1 starts at 0
689 ! print *,'time_start: ',time_start,time_step_start,' diff ', time_start-time_step_start
690 time_start = time_step_start ! use the time passed from wrf
697 !$OMP CRITICAL(SFIRE_DRIVER_CRIT)
698 write(msg,'(a,i5)')'sfire_driver_phys stage ',ifun
700 write(msg,'(a,2f15.6)')'atmosphere mesh step:',dx,dy
702 write(msg,'(a,2f15.6)')'fire mesh step: ',dxf,dyf
704 write(msg,7001)'atm domain ','ids',ids,ide,jds,jde
706 write(msg,7001)'atm memory ','ims',ims,ime,jms,jme
708 write(msg,7001)'atm patch ','ips',ips,ipe,jps,jpe
710 write(msg,7001)'fire domain ','ifds',ifds,ifde,jfds,jfde
712 write(msg,7001)'fire memory ','ifms',ifms,ifme,jfms,jfme
714 write(msg,7001)'fire patch ','ifps',ifps,ifpe,jfps,jfpe
716 !$OMP END CRITICAL(SFIRE_DRIVER_CRIT)
718 ! check mesh dimensions
719 call check_fmesh(ids,ide,ifds,ifde,ir,'id') ! check if atm and fire grids line up
720 call check_fmesh(jds,jde,jfds,jfde,jr,'jd')
721 call check_fmesh(ips,ipe,ifps,ifpe,ir,'ip')
722 call check_fmesh(jps,jpe,jfps,jfpe,jr,'jp')
723 call check_mesh_2dim(ips,ipe,jps,jpe,ims,ime,jms,jme) ! check if atm patch fits in atm array
724 call check_mesh_2dim(ifps,ifpe,jfps,jfpe,ifms,ifme,jfms,jfme) ! check if fire patch fits in fire array
725 call check_mesh_2dim(ips,ipe,jps,jpe,ids,ide,jds,jde) ! check if atm patch fits in atm domain
726 call check_mesh_2dim(ifps,ifpe,jfps,jfpe,ifds,ifde,jfds,jfde) ! check if fire patch fits in fire domain
729 if(fire_print_file.gt.0)then
730 if(itimestep.le.fire_print_file.or.mod(itimestep,fire_print_file).eq.0)pid=itimestep ! print 1-fire_print_file then every fire_print_file-th
735 call init_fuel_cats(fmoist_run .or. fmoist_interp) ! properties of fuel categories and moisture classes from namelist.fire
739 call print_chsum(itimestep,ims,ime,kms,kme,jms,jme,ids,ide,kds,kde,jds,jde,ips,ipe,kps,kpe,jps,jpe,1,0,0,u,'u')
740 call print_chsum(itimestep,ims,ime,kms,kme,jms,jme,ids,ide,kds,kde,jds,jde,ips,ipe,kps,kpe,jps,jpe,0,0,1,v,'v')
741 call print_chsum(itimestep,ims,ime,kms,kme,jms,jme,ids,ide,kds,kde,jds,jde,ips,ipe,kps,kpe,jps,jpe,0,1,0,ph,'ph')
744 call print_chsum(itimestep,ifms,ifme,1,1,jfms,jfme,ifds,ifde,1,1,jfds,jfde,ifps,ifpe,1,1,jfps,jfpe,0,0,0,lfn,'lfn')
745 call print_chsum(itimestep,ifms,ifme,1,1,jfms,jfme,ifds,ifde,1,1,jfds,jfde,ifps,ifpe,1,1,jfps,jfpe,0,0,0,tign,'tign')
748 ! fake atm tile bounds
752 ! staggered atm patch bounds
753 ipe1=ifval(ipe.eq.ide,ipe+1,ipe)
754 jpe1=ifval(jpe.eq.jde,jpe+1,jpe)
756 ! set up fire tiles & interpolate to fire grid
757 !$OMP PARALLEL DO PRIVATE(ij,its,ite,jts,jte,ite1,jte1,ifts,ifte,jfts,jfte,msg,id) &
758 !$OMP SCHEDULE(STATIC)
761 id = ifval(pid.ne.0,pid+ij*10000,0) ! for print
764 its = i_start(ij) ! start atmospheric tile in i
765 ite = i_end(ij) ! end atmospheric tile in i
766 jts = j_start(ij) ! start atmospheric tile in j
767 jte = j_end(ij) ! end atmospheric tile in j
768 ifts= (its-ids)*ir+ifds ! start fire tile in i
769 ifte= (ite-ids+1)*ir+ifds-1 ! end fire tile in i
770 jfts= (jts-jds)*jr+jfds ! start fire tile in j
771 jfte= (jte-jds+1)*jr+jfds-1 ! end fire tile in j
773 ! staggered atm tile bounds
774 ite1=ifval(ite.eq.ide,ite+1,ite)
775 jte1=ifval(jte.eq.jde,jte+1,jte)
777 !$OMP CRITICAL(SFIRE_DRIVER_CRIT)
778 write(msg,'(a,i3,1x,a,i7,1x,a,i3)')'tile=',ij,' id=',id,' ifun=',ifun
780 write(msg,7001)'atm tile ','its',its,ite,jts,jte
782 write(msg,7001)'fire tile ','ifts',ifts,ifte,jfts,jfte
784 !$OMP END CRITICAL(SFIRE_DRIVER_CRIT)
787 call check_mesh_2dim(its,ite,jts,jte,ips,ipe,jps,jpe) ! check if atm tile fits in atm patch
788 call check_mesh_2dim(ifts,ifte,jfts,jfte,ifps,ifpe,jfps,jfpe) ! check if fire tile fits in fire patch
789 call check_mesh_2dim(ifts-2,ifte+2,jfts-2,jfte+2,ifms,ifme,jfms,jfme)! check if fire node tile fits in memory
792 !$OMP CRITICAL(SFIRE_DRIVER_CRIT)
793 write(msg,'(a,i6,a,2(f15.6,a))')'time step',itimestep,' at',time_start,' duration',dt,'s'
795 7001 format(a,' dimensions ',a4,':',i6,' to ',i6,' by ',i6,' to ',i6)
796 write(msg,'(a,2i9)')'refinement ratio:',ir,jr
797 !$OMP END CRITICAL(SFIRE_DRIVER_CRIT)
799 if(run_advance_moisture)then
802 ! one timestep of the moisture model
803 call message('advance_moisture start')
804 call advance_moisture( &
805 itimestep.eq.1, & ! initialize?
806 ims,ime, jms,jme, & ! memory dimensions
807 its,ite, jts,jte, & ! tile dimensions
808 nfmc, & ! number of moisture fields
809 dt_moisture, & ! moisture model time step
810 fmep_decay_tlag, & ! moisture extended model assim. diffs decay tlag
811 rainc, rainnc, & ! accumulated rain
812 t2, q2, psfc, & ! temperature (K), vapor contents (kg/kg), pressure (Pa) at the surface
813 rain_old, & ! previous value of accumulated rain
814 t2_old, q2_old, psfc_old, & ! previous values of the atmospheric state at surface
815 rh_fire, & ! relative humidity, diagnostics
816 fmc_gc, & ! fuel moisture fields updated, by class, assumed set to something reasonable
817 fmep, & ! fuel moisture extended model parameters
818 fmc_equi, & ! fuel moisture fields updated, by class equilibrium diagnostic
819 fmc_lag & ! fuel moisture fields updated, by class tendency diagnostic
821 call message('advance_moisture end')
827 if(ifun.eq.2)then ! interpolate
831 call message('restart - interpolation skipped')
834 if(kfmc_ndwi > 0 .and. fndwi_from_ndwi .eq.1)then
835 call print_2d_stats(ips,ipe,jps,jpe,ims,ime,jms,jme,fndwi,'driver:ndwi')
836 call interpolate_z2fire(id,0, & ! for debug output, <= 0 no output, extend strip
837 ids,ide, jds,jde, & ! atm grid dimensions
841 ifds, ifde, jfds, jfde, & ! fire grid dimensions
842 ifms, ifme, jfms, jfme, &
843 ifts,ifte,jfts,jfte, &
844 ir,jr, & ! atm/fire grid ratio
845 ndwi, & ! atm grid arrays in
846 fndwi) ! fire grid arrays out
847 call print_2d_stats(ifps,ifpe,jfps,jfpe,ifms,ifme,jfms,jfme,fndwi,'driver:fndwi')
850 ! call print_2d_stats(ips,ipe,jps,jpe,ims,ime,jms,jme,zs,'driver:zs')
852 ! ! interpolate terrain height
853 ! if(fire_topo_from_atm.eq.1)then
854 ! call interpolate_z2fire(id,1, & ! for debug output, <= 0 no output
855 ! ids,ide, jds,jde, & ! atm grid dimensions
856 ! ims,ime, jms,jme, &
859 ! ifds, ifde, jfds, jfde, & ! fire grid dimensions
860 ! ifms, ifme, jfms, jfme, &
861 ! ifts,ifte,jfts,jfte, &
862 ! ir,jr, & ! atm/fire grid ratio
863 ! zs, & ! atm grid arrays in
864 ! fp%zsf) ! fire grid arrays out
866 !!$OMP CRITICAL(SFIRE_DRIVER_CRIT)
867 ! write(msg,'(a,i3,a)')'fire_topo_from_atm=',fire_topo_from_atm,' assuming ZSF set, interpolation skipped'
868 !!$OMP END CRITICAL(SFIRE_DRIVER_CRIT)
871 if(ignition%longlat .eq.0)then
872 ! set ideal fire mesh coordinates - used for ignition only
873 ! do not forget to set unit_fxlong, unit_fxlat outside of parallel loop
874 !call set_ideal_coord( dxf,dyf, &
875 ! ifds,ifde,jfds,jfde, &
876 ! ifms,ifme,jfms,jfme, &
877 ! ifts,ifte,jfts,jfte, &
879 !call set_ideal_coord( dx,dy, &
884 elseif(use_atm_vars)then
885 ! assume halo xlong xlat
886 ! interpolate nodal coordinates
889 call write_array_m(its,ite,jts,jte,ims,ime,jms,jme,xlat,'xlat',id)
890 call write_array_m(its,ite,jts,jte,ims,ime,jms,jme,xlong,'xlong',id)
893 if (interpolate_long_lat)then
894 call message('Intepolating node longitude and latitude to fire mesh')
895 call interpolate_z2fire(id,1, & ! for debug output, <= 0 no output
896 ids,ide, jds,jde, & ! atm grid dimensions
900 ifds, ifde, jfds, jfde, & ! fire grid dimensions
901 ifms, ifme, jfms, jfme, &
902 ifts,ifte,jfts,jfte, &
903 ir,jr, & ! atm/fire grid ratio
904 xlat, & ! atm grid arrays in
905 fxlat) ! fire grid arrays out
907 call interpolate_z2fire(id,1, & ! for debug output, <= 0 no output
908 ids,ide, jds,jde, & ! atm grid dimensions
912 ifds, ifde, jfds, jfde, & ! fire grid dimensions
913 ifms, ifme, jfms, jfme, &
914 ifts,ifte,jfts,jfte, &
915 ir,jr, & ! atm/fire grid ratio
916 xlong, & ! atm grid arrays in
917 fxlong) ! fire grid arrays out
920 ! after the loop where zsf created exited and all synced
921 call print_2d_stats(ifts,ifte,jfts,jfte,ifms,ifme,jfms,jfme,fp%zsf,'driver_phys:zsf')
923 ! cannot initialize moisture model because T2 Q2 PSFC are not set yet
927 elseif(ifun.eq.3)then ! interpolate winds to the fire grid
931 call write_array_m(its,ite,jts,jte,ims,ime,jms,jme,z0,'z0',id)
932 call write_array_m3(its,ite1,kts,kde-1,jts,jte,ims,ime,kms,kme,jms,jme,u,'u_2',id)
933 call write_array_m3(its,ite,kts,kde-1,jts,jte1,ims,ime,kms,kme,jms,jme,v,'v_2',id)
934 call write_array_m3(its,ite,kts,kde,jts,jte,ims,ime,kms,kme,jms,jme,ph,'ph_2',id)
935 call write_array_m3(its,ite,kts,kde,jts,jte,ims,ime,kms,kme,jms,jme,phb,'phb',id)
937 if(fire_wind_log_interp.eq.4)then
938 call print_2d_stats(its,ite,jts,jte,ims,ime,jms,jme,z0,'driver_phys:z0')
939 call interpolate_atm2fire(id, & ! flag for debug output
940 ids,ide, kds,kde, jds,jde, & ! atm grid dimensions
941 ims,ime, kms,kme, jms,jme, &
944 ifds, ifde, jfds, jfde, & ! fire grid dimensions
945 ifms, ifme, jfms, jfme, &
946 ifps, ifpe, jfps, jfpe, & ! fire patch bounds
947 ifts, ifte, jfts, jfte, &
948 ir,jr, & ! atm/fire grid ratio
949 u_frame, v_frame, & ! velocity frame correction
950 u,v, & ! 3D atm grid arrays in
952 z0,zs, & ! 2D atm grid arrays in
953 uah,vah, & ! 2D atm grid out
954 fp%vx,fp%vy) ! fire grid arrays out
957 ifms,ifme,jfms,jfme, &
958 ifts,ifte,jfts,jfte, &
959 nfuel_cat,fp%vx,fp%vy)
962 call print_2d_stats(ifts,ifte,jfts,jfte,ifms,ifme,jfms,jfme,fz0,'driver_phys:fz0')
963 call interpolate_wind2fire_height(id, & ! to identify debugging prints and files if needed
964 ids,ide, kds,kde, jds,jde, & ! atm grid dimensions
965 ims,ime, kms,kme, jms,jme, &
968 ifds, ifde, jfds, jfde, & ! fire grid dimensions
969 ifms, ifme, jfms, jfme, &
970 ifps, ifpe, jfps, jfpe, & ! fire patch bounds
971 ifts,ifte,jfts,jfte, &
972 ir,jr, & ! atm/fire grid ratio
973 u_frame, v_frame, & ! velocity frame correction
974 u,v,ph,phb, & ! input atmospheric arrays
975 fz0,fwh, & ! input fire arrays
976 fp%vx,fp%vy) ! output fire arrays
978 if(fire_use_windrf.eq.1)then
980 ifms,ifme,jfms,jfme, &
981 ifts,ifte,jfts,jfte, &
982 nfuel_cat,fp%vx,fp%vy)
990 elseif(ifun.eq.4)then
992 ! interpolate and compute weighted average to get the fuel moisture
993 !! print *,'ifun=4, run_fuel_moisture=',run_fuel_moisture
994 if(run_fuel_moisture)then
995 call message('fuel_moisture start')
996 call fuel_moisture( &
997 id, & ! for prints and maybe file names
999 ids,ide, jds,jde, & ! atm grid dimensions
1003 ifds, ifde, jfds, jfde, & ! fire grid dimensions
1004 ifms, ifme, jfms, jfme, &
1005 ifts,ifte,jfts,jfte, &
1006 ir,jr, & ! atm/fire grid ratio
1007 nfuel_cat, & ! fuel data
1008 fndwi, & ! satellite sensing interpolated on fire grid
1009 fmc_gc, & ! moisture contents by class on atmospheric grid
1010 fmc_g & ! weighted fuel moisture contents on fire grid
1012 call message('fuel_moisture end')
1015 call print_2d_stats(ifts,ifte,jfts,jfte,ifms,ifme,jfms,jfme,fmc_g,'driver_phys:fmc_g')
1020 call sfire_model (id,ifun,restart, &
1021 run_fuel_moisture, & ! if fuel moisture needs to be updated
1022 ifuelread,nfuel_cat0, & ! initialize fuel categories
1023 ifds,ifde,jfds,jfde, & ! fire domain dims
1024 ifms,ifme,jfms,jfme, & ! fire memory dims
1025 ifps,ifpe,jfps,jfpe, &
1026 ifts,ifte,jfts,jfte, & ! fire patch dims
1027 time_start,dt, & ! time and increment
1028 dxf,dyf, & ! fire mesh spacing
1029 ignition,hfx, & ! description of ignition lines
1030 fxlong,fxlat, & ! fire mesh coordinates
1031 fire_hfx, & ! given heat flux
1032 lfn,lfn_out,tign,fuel_frac, & ! state: level function, ign time, fuel left
1033 fire_area, & ! output: fraction of cell burning
1034 fuel_frac_burnt, & ! output: fuel fraction burned in this step
1035 fgrnhfx,fgrnqfx, & ! output: heat fluxes
1036 ros,flineint,flineint2, & ! diagnostic variables
1037 f_ros0,f_rosx,f_rosy,f_ros, & ! fire risk spread
1038 f_int,f_lineint,f_lineint2, & ! fire risk intensities
1039 nfuel_cat, & ! fuel data per point
1040 fuel_time,fwh,fz0, & ! save derived internal data
1041 fp & ! fire coefficients
1045 call setup_wind_log_interpolation( &
1046 ids,ide, jds,jde, & ! atm grid dimensions
1050 ifds, ifde, jfds, jfde, & ! fire grid dimensions
1051 ifms, ifme, jfms, jfme, &
1052 ifts,ifte,jfts,jfte, &
1053 ir,jr, & ! atm/fire grid ratio
1054 z0, & ! atm grid arrays in
1055 nfuel_cat, & ! fuel data per point
1056 fz0,fwh) ! fire arrays out
1059 elseif(ifun.eq.6)then
1061 ! populate the rate of spread in the 8 directions
1064 f_ros11(i,j)=fire_rate_of_spread( dxf*(1-2), dyf*(1-2), i,j,fp)
1065 f_ros12(i,j)=fire_rate_of_spread( dxf*(1-2), dyf*(2-2), i,j,fp)
1066 f_ros13(i,j)=fire_rate_of_spread( dxf*(1-2), dyf*(3-2), i,j,fp)
1067 f_ros21(i,j)=fire_rate_of_spread( dxf*(2-2), dyf*(1-2), i,j,fp)
1068 f_ros23(i,j)=fire_rate_of_spread( dxf*(2-2), dyf*(3-2), i,j,fp)
1069 f_ros31(i,j)=fire_rate_of_spread( dxf*(3-2), dyf*(1-2), i,j,fp)
1070 f_ros32(i,j)=fire_rate_of_spread( dxf*(3-2), dyf*(2-2), i,j,fp)
1071 f_ros33(i,j)=fire_rate_of_spread( dxf*(3-2), dyf*(3-2), i,j,fp)
1074 call print_2d_stats(ifts,ifte,jfts,jfte,ifms,ifme,jfms,jfme,f_ros11,'driver_phys:f_ros11')
1075 call print_2d_stats(ifts,ifte,jfts,jfte,ifms,ifme,jfms,jfme,f_ros12,'driver_phys:f_ros12')
1076 call print_2d_stats(ifts,ifte,jfts,jfte,ifms,ifme,jfms,jfme,f_ros13,'driver_phys:f_ros13')
1077 call print_2d_stats(ifts,ifte,jfts,jfte,ifms,ifme,jfms,jfme,f_ros21,'driver_phys:f_ros21')
1078 call print_2d_stats(ifts,ifte,jfts,jfte,ifms,ifme,jfms,jfme,f_ros23,'driver_phys:f_ros23')
1079 call print_2d_stats(ifts,ifte,jfts,jfte,ifms,ifme,jfms,jfme,f_ros31,'driver_phys:f_ros31')
1080 call print_2d_stats(ifts,ifte,jfts,jfte,ifms,ifme,jfms,jfme,f_ros32,'driver_phys:f_ros32')
1081 call print_2d_stats(ifts,ifte,jfts,jfte,ifms,ifme,jfms,jfme,f_ros33,'driver_phys:f_ros33')
1083 ! heat fluxes into the atmosphere
1085 call print_2d_stats(ifts,ifte,jfts,jfte,ifms,ifme,jfms,jfme,fgrnhfx,'fire_driver:fgrnhfx')
1086 call print_2d_stats(ifts,ifte,jfts,jfte,ifms,ifme,jfms,jfme,fgrnqfx,'fire_driver:fgrnqfx')
1088 ! sum the fluxes over atm cells
1089 if(use_atm_vars)then
1090 call sum_2d_cells( &
1091 ifms,ifme,jfms,jfme, &
1092 ifts,ifte,jfts,jfte, &
1094 ims, ime, jms, jme, &
1097 call sum_2d_cells( &
1098 ifms,ifme,jfms,jfme, &
1099 ifts,ifte,jfts,jfte, &
1101 ims, ime, jms, jme, &
1104 !comment out the next call to get results as before commit 55fd92051196b796891b60cb7ec1c4bdb8800078
1105 call sum_2d_cells( &
1106 ifms,ifme,jfms,jfme, &
1107 ifts,ifte,jfts,jfte, &
1109 ims, ime, jms, jme, &
1113 !$OMP CRITICAL(SFIRE_DRIVER_CRIT)
1114 write(msg,'(a,f6.3)')'fire-atmosphere feedback scaling ',fire_atm_feedback
1115 !$OMP end CRITICAL(SFIRE_DRIVER_CRIT)
1120 ! scale ground fluxes to get the averages
1121 avg_fuel_frac(i,j)=avg_fuel_frac(i,j)*s
1122 grnhfx(i,j)=fire_atm_feedback*grnhfx(i,j)*s
1123 grnqfx(i,j)=fire_atm_feedback*grnqfx(i,j)*s
1124 ! we do not have canopy fluxes yet...
1130 call print_2d_stats(its,ite,jts,jte,ims,ime,jms,jme,grnhfx,'fire_driver:grnhfx')
1131 call print_2d_stats(its,ite,jts,jte,ims,ime,jms,jme,grnqfx,'fire_driver:grnqfx')
1138 !$OMP END PARALLEL DO
1143 call write_array_m(ips,ipe,jps,jpe,ims,ime,jms,jme,zs,'zs',pid)
1144 call write_array_m(ifps,ifpe,jfps,jfpe,ifms,ifme,jfms,jfme,fp%zsf,'zsf',pid)
1150 call print_3d_stats_by_slice(ips,ipe,1,moisture_classes,jps,jpe,ims,ime,1,nfmc,jms,jme,fmc_gc,'fmc_gc')
1151 call print_chsum(itimestep,ims,ime,1,nfmc,jms,jme,ids,ide,1,moisture_classes,jds,jde,ips,ipe,1,moisture_classes,jps,jpe,0,0,0,fmc_gc,'fmc_gc')
1156 call print_chsum(itimestep,ifms,ifme,1,1,jfms,jfme,ifds,ifde,1,1,jfds,jfde,ifps,ifpe,1,1,jfps,jfpe,0,0,0,fmc_g,'fmc_g')
1157 !call print_chsum(itimestep,ims,ime,1,1,jms,jme,ids,ide,1,1,jds,jde,ips,ipe,1,1,jps,jpe,1,0,0,uah,'uah')
1158 !call print_chsum(itimestep,ims,ime,1,1,jms,jme,ids,ide,1,1,jds,jde,ips,ipe,1,1,jps,jpe,0,0,1,vah,'vah')
1159 call print_chsum(itimestep,ifms,ifme,1,1,jfms,jfme,ifds,ifde,1,1,jfds,jfde,ifps,ifpe,1,1,jfps,jfpe,0,0,0,fp%vx,'uf')
1160 call print_chsum(itimestep,ifms,ifme,1,1,jfms,jfme,ifds,ifde,1,1,jfds,jfde,ifps,ifpe,1,1,jfps,jfpe,0,0,0,fp%vy,'vf')
1161 call print_chsum(itimestep,ifms,ifme,1,1,jfms,jfme,ifds,ifde,1,1,jfds,jfde,ifps,ifpe,1,1,jfps,jfpe,0,0,0,lfn,'lfn')
1162 call print_chsum(itimestep,ifms,ifme,1,1,jfms,jfme,ifds,ifde,1,1,jfds,jfde,ifps,ifpe,1,1,jfps,jfpe,0,0,0,tign,'tign')
1166 ! call write_array_m(ips,ipe1,jps,jpe,ims,ime,jms,jme,uah,'uah',pid)
1167 ! call write_array_m(ips,ipe,jps,jpe1,ims,ime,jms,jme,vah,'vah',pid)
1168 call write_array_m(ips,ipe,jps,jpe,ims,ime,jms,jme,grnhfx,'grnhfx',pid)
1169 call write_array_m(ips,ipe,jps,jpe,ims,ime,jms,jme,grnqfx,'grnqfx',pid)
1170 call write_array_m3(ips,ipe1,kds,kde+1,jps,jpe,ims,ime,kms,kme,jms,jme,u,'u',pid)
1171 call write_array_m3(ips,ipe,kds,kde+1,jps,jpe1,ims,ime,kms,kme,jms,jme,v,'v',pid)
1172 call write_array_m(ifps,ifpe,jfps,jfpe,ifms,ifme,jfms,jfme,fp%vx,'uf',pid)
1173 call write_array_m(ifps,ifpe,jfps,jfpe,ifms,ifme,jfms,jfme,fp%vy,'vf',pid)
1181 call write_array_m(ifps,ifpe,jfps,jfpe,ifms,ifme,jfms,jfme,lfn,'lfn',pid)
1182 call write_array_m(ifps,ifpe,jfps,jfpe,ifms,ifme,jfms,jfme,tign,'tign',pid)
1188 call print_chsum(itimestep,ifms,ifme,1,1,jfms,jfme,ifds,ifde,1,1,jfds,jfde,ifps,ifpe,1,1,jfps,jfpe,0,0,0,fgrnhfx,'fgrnhfx')
1189 call print_chsum(itimestep,ifms,ifme,1,1,jfms,jfme,ifds,ifde,1,1,jfds,jfde,ifps,ifpe,1,1,jfps,jfpe,0,0,0,fgrnqfx,'fgrnqfx')
1190 call print_chsum(itimestep,ims,ime,1,1,jms,jme,ids,ide,1,1,jds,jde,ips,ipe,1,1,jps,jpe,0,0,0,grnhfx,'grnhfx')
1191 call print_chsum(itimestep,ims,ime,1,1,jms,jme,ids,ide,1,1,jds,jde,ips,ipe,1,1,jps,jpe,0,0,0,grnqfx,'grnqfx')
1194 call write_array_m(ips,ipe,jps,jpe,ims,ime,jms,jme,grnhfx,'grnhfx',pid)
1195 call write_array_m(ips,ipe,jps,jpe,ims,ime,jms,jme,grnqfx,'grnqfx',pid)
1196 call write_array_m(ifps,ifpe,jfps,jfpe,ifms,ifme,jfms,jfme,fuel_frac,'fuel_frac',pid)
1197 call write_array_m(ifps,ifpe,jfps,jfpe,ifms,ifme,jfms,jfme,fgrnhfx,'fgrnhfx',pid)
1198 call write_array_m(ifps,ifpe,jfps,jfpe,ifms,ifme,jfms,jfme,fgrnqfx,'fgrnqfx',pid)
1203 end subroutine sfire_driver_phys
1209 subroutine check_fmesh(ids,ide,ifds,ifde,ir,s)
1210 !*** purpose: check if fire and atm meshes line up
1213 integer, intent(in)::ids,ide,ifds,ifde,ir
1214 character(len=*),intent(in)::s
1216 character(len=128)msg
1218 if ((ide-ids+1)*ir.ne.(ifde-ifds+1))then
1219 !$OMP CRITICAL(SFIRE_DRIVER_CRIT)
1220 write(msg,1)s,ids,ide,ifds,ifde,ir
1221 1 format('module_fr_sfire_driver: incompatible bounds ',a,' atm ',i5,':',i5,' fire ',i5,':',i5,' ratio ',i3)
1222 !$OMP END CRITICAL(SFIRE_DRIVER_CRIT)
1225 end subroutine check_fmesh
1227 subroutine fire_ignition_convert (config_flags,ignition, &
1229 ifds,ifde, jfds,jfde, &
1230 ifms,ifme, jfms,jfme, &
1231 ifps,ifpe, jfps,jfpe )
1233 ! create ignition arrays from scalar flags
1235 TYPE (grid_config_rec_type) , INTENT(IN) :: config_flags
1236 TYPE (lines_type), INTENT(OUT):: ignition ! any values from input discarded
1237 integer::ifds,ifde, jfds,jfde, &
1238 ifms,ifme, jfms,jfme, &
1239 ifps,ifpe, jfps,jfpe
1240 real, dimension(ifms:ifme,jfms:jfme):: fxlong,fxlat
1243 logical:: real,ideal
1244 character(len=128)msg
1245 real:: corner_longlat(2,2,2), corner_longlat_1(8), corner_longlat_2(8),lon(2),lat(2)
1246 real, dimension(2,2):: corner_long,corner_lat ! coordinates of fire mesh corner cells
1251 ignition%max_lines=5 ! number of lines that have entries in the namelist
1252 ignition%num_lines=config_flags%fire_num_ignitions
1254 ! this is only until I figure out how to input arrays through the namelist...
1255 if(fire_max_lines.lt.ignition%max_lines)call crash('fire_max_lines too small')
1257 ! figure out which kind of coordinates from the first given
1258 ideal=config_flags%fire_ignition_start_x1 .ne.0. .or. config_flags%fire_ignition_start_y1 .ne. 0.
1259 real=config_flags%fire_ignition_start_lon1 .ne. 0. .or. config_flags%fire_ignition_start_lat1 .ne. 0.
1260 if(ideal)call message('Using ideal ignition coordinates, m from the lower left domain corner')
1261 if(real)call message('Using real ignition coordinates, longitude and latitude')
1262 if(ideal.and.real)call crash('Only one of the ideal or real coordinates may be given')
1264 ignition%longlat=0 ! default, if no ignition
1266 ! use values from _x and _y variables
1268 ignition%line(1)%start_x=config_flags%fire_ignition_start_x1
1269 ignition%line(1)%start_y=config_flags%fire_ignition_start_y1
1270 ignition%line(1)%end_x=config_flags%fire_ignition_end_x1
1271 ignition%line(1)%end_y=config_flags%fire_ignition_end_y1
1272 ignition%line(2)%start_x=config_flags%fire_ignition_start_x2
1273 ignition%line(2)%start_y=config_flags%fire_ignition_start_y2
1274 ignition%line(2)%end_x=config_flags%fire_ignition_end_x2
1275 ignition%line(2)%end_y=config_flags%fire_ignition_end_y2
1276 ignition%line(3)%start_x=config_flags%fire_ignition_start_x3
1277 ignition%line(3)%start_y=config_flags%fire_ignition_start_y3
1278 ignition%line(3)%end_x=config_flags%fire_ignition_end_x3
1279 ignition%line(3)%end_y=config_flags%fire_ignition_end_y3
1280 ignition%line(4)%start_x=config_flags%fire_ignition_start_x4
1281 ignition%line(4)%start_y=config_flags%fire_ignition_start_y4
1282 ignition%line(4)%end_x=config_flags%fire_ignition_end_x4
1283 ignition%line(4)%end_y=config_flags%fire_ignition_end_y4
1284 ignition%line(5)%start_x=config_flags%fire_ignition_start_x5
1285 ignition%line(5)%start_y=config_flags%fire_ignition_start_y5
1286 ignition%line(5)%end_x=config_flags%fire_ignition_end_x5
1287 ignition%line(5)%end_y=config_flags%fire_ignition_end_y5
1290 ! use values from _long and _lat
1292 ignition%line(1)%start_x=config_flags%fire_ignition_start_lon1
1293 ignition%line(1)%start_y=config_flags%fire_ignition_start_lat1
1294 ignition%line(1)%end_x=config_flags%fire_ignition_end_lon1
1295 ignition%line(1)%end_y=config_flags%fire_ignition_end_lat1
1296 ignition%line(2)%start_x=config_flags%fire_ignition_start_lon2
1297 ignition%line(2)%start_y=config_flags%fire_ignition_start_lat2
1298 ignition%line(2)%end_x=config_flags%fire_ignition_end_lon2
1299 ignition%line(2)%end_y=config_flags%fire_ignition_end_lat2
1300 ignition%line(3)%start_x=config_flags%fire_ignition_start_lon3
1301 ignition%line(3)%start_y=config_flags%fire_ignition_start_lat3
1302 ignition%line(3)%end_x=config_flags%fire_ignition_end_lon3
1303 ignition%line(3)%end_y=config_flags%fire_ignition_end_lat3
1304 ignition%line(4)%start_x=config_flags%fire_ignition_start_lon4
1305 ignition%line(4)%start_y=config_flags%fire_ignition_start_lat4
1306 ignition%line(4)%end_x=config_flags%fire_ignition_end_lon4
1307 ignition%line(4)%end_y=config_flags%fire_ignition_end_lat4
1308 ignition%line(5)%start_x=config_flags%fire_ignition_start_lon5
1309 ignition%line(5)%start_y=config_flags%fire_ignition_start_lat5
1310 ignition%line(5)%end_x=config_flags%fire_ignition_end_lon5
1311 ignition%line(5)%end_y=config_flags%fire_ignition_end_lat5
1313 ! common to both cases
1314 ignition%line(1)%ros=config_flags%fire_ignition_ros1
1315 ignition%line(1)%radius=config_flags%fire_ignition_radius1
1316 ignition%line(1)%start_time=config_flags%fire_ignition_start_time1
1317 ignition%line(1)%end_time=config_flags%fire_ignition_end_time1
1318 ignition%line(2)%ros=config_flags%fire_ignition_ros2
1319 ignition%line(2)%radius=config_flags%fire_ignition_radius2
1320 ignition%line(2)%start_time=config_flags%fire_ignition_start_time2
1321 ignition%line(2)%end_time=config_flags%fire_ignition_end_time2
1322 ignition%line(3)%ros=config_flags%fire_ignition_ros3
1323 ignition%line(3)%radius=config_flags%fire_ignition_radius3
1324 ignition%line(3)%start_time=config_flags%fire_ignition_start_time3
1325 ignition%line(3)%end_time=config_flags%fire_ignition_end_time3
1326 ignition%line(4)%ros=config_flags%fire_ignition_ros4
1327 ignition%line(4)%radius=config_flags%fire_ignition_radius4
1328 ignition%line(4)%start_time=config_flags%fire_ignition_start_time4
1329 ignition%line(4)%end_time=config_flags%fire_ignition_end_time4
1330 ignition%line(5)%ros=config_flags%fire_ignition_ros5
1331 ignition%line(5)%radius=config_flags%fire_ignition_radius5
1332 ignition%line(5)%start_time=config_flags%fire_ignition_start_time5
1333 ignition%line(5)%end_time=config_flags%fire_ignition_end_time5
1335 call postprocess_lines(ignition,'ros',config_flags)
1337 ! get the coordinates of the corner cells
1339 if(ifds.eq.ifps.and.jfds.eq.jfps)then
1340 corner_longlat(1,1,1)=fxlong(ifps,jfps)
1341 corner_longlat(1,1,2)=fxlat(ifps,jfps)
1343 if(ifds.eq.ifps.and.jfde.eq.jfpe)then
1344 corner_longlat(1,2,1)=fxlong(ifps,jfpe)
1345 corner_longlat(1,2,2)=fxlat(ifps,jfpe)
1347 if(ifde.eq.ifpe.and.jfds.eq.jfps)then
1348 corner_longlat(2,1,1)=fxlong(ifpe,jfps)
1349 corner_longlat(2,1,2)=fxlat(ifpe,jfps)
1351 if(ifde.eq.ifpe.and.jfde.eq.jfpe)then
1352 corner_longlat(2,2,1)=fxlong(ifpe,jfpe)
1353 corner_longlat(2,2,2)=fxlat(ifpe,jfpe)
1355 corner_longlat_1=reshape(corner_longlat,(/8/))
1357 call wrf_dm_sum_reals(corner_longlat_1,corner_longlat_2)
1359 corner_longlat_2=corner_longlat_1
1361 corner_longlat=reshape(corner_longlat_2,(/2,2,2/))
1362 corner_long=corner_longlat(1:2,1:2,1)
1363 corner_lat=corner_longlat(1:2,1:2,2)
1364 if(fire_print_msg.ge.2)then
1367 write(msg,'(a,2i2,a,2f14.8)')'corner',i,j,' coordinates ',corner_long(i,j),corner_lat(i,j)
1372 lon(1)=(corner_long(1,1)+corner_long(1,2))/2.
1373 lon(2)=(corner_long(2,1)+corner_long(2,2))/2.
1374 lat(1)=(corner_lat(1,1)+corner_lat(2,1))/2.
1375 lat(2)=(corner_lat(1,2)+corner_lat(2,2))/2.
1376 if(fire_print_msg.ge.2)then
1377 write(msg,'(4(a,f14.8))')'coordinates ',lon(1),':',lon(2),',',lat(1),':',lat(2)
1381 do i=1,ignition%num_lines
1382 call check_ignition_coordinate(ignition%line(i)%start_x,lon(1),lon(2))
1383 call check_ignition_coordinate(ignition%line(i)%start_y,lat(1),lat(2))
1384 call check_ignition_coordinate(ignition%line(i)%end_x,lon(1),lon(2))
1385 call check_ignition_coordinate(ignition%line(i)%end_y,lat(1),lat(2))
1388 if (fire_ignition_clamp>0) then
1389 do i=1,ignition%num_lines
1390 call clamp_to_grid(ignition%line(i)%start_x,lon(1),lon(2),ifds,ifde,ignition%line(i)%start_x,ii)
1391 call clamp_to_grid(ignition%line(i)%start_y,lat(1),lat(2),jfds,jfde,ignition%line(i)%start_y,jj)
1393 call clamp_to_grid(ignition%line(i)%end_x,lon(1),lon(2),ifds,ifde,ignition%line(i)%end_x,ii)
1394 call clamp_to_grid(ignition%line(i)%end_y,lat(1),lat(2),jfds,jfde,ignition%line(i)%end_y,jj)
1396 ! for now, ii jj ignored. In future replace by fxlong(ii,jj), fxlat(ii,jj) to guard against rounding
1400 subroutine display_clamp
1401 character(len=128)::msg
1403 if(ii>=ifps.and.ii<=ifpe.and.jj>=jfps.and.jj<=jfpe)then
1404 write(msg,'(a,2f14.8,a,2i6)')'grid node ',fxlong(ii,jj),fxlat(ii,jj),' index',ii,jj
1407 end subroutine display_clamp
1408 end subroutine fire_ignition_convert
1410 subroutine check_ignition_coordinate(x,x1,x2)
1412 real, intent(in)::x,x1,x2
1413 character(len=128)::msg
1414 if (.not.(x>x1 .and. x<x2))then
1415 write(msg,'(a,f14.8,a,2f14.8)')'ignition point coordinate',x,' must be inside the bounds',x1,x2
1418 end subroutine check_ignition_coordinate
1420 subroutine clamp_to_grid(x,x1,x2,i1,i2,xout,iout)
1421 !*** round point on uniform mesh to a mesh node
1423 real, intent(in)::x,x1,x2
1424 integer, intent(in)::i1,i2
1425 real, intent(out)::xout
1426 integer, intent(out)::iout
1428 character(len=128)::msg
1436 if(fire_print_msg.ge.2)then
1437 write(msg,'(a,f14.8,a,f14.8,a,i6)')'coordinate ',x,' clamped to ',xr,' index',iout
1441 end subroutine clamp_to_grid
1445 subroutine postprocess_lines(lines,value_name,config_flags)
1446 ! count lines, fill endpoints, print stats
1448 type(lines_type), intent(inout)::lines
1449 character(len=3), intent(in)::value_name
1450 TYPE (grid_config_rec_type) , INTENT(IN) :: config_flags ! namelist
1454 real::lat_ctr,lon_ctr
1455 character(len=128)msg,f2,f3
1460 ! find the last line that has positive radius and reset num_lines if needed
1461 if(lines%line(i)%radius.gt.0.)lines%num_lines=i
1462 ! expand ignition data given as zero
1463 if(lines%line(i)%end_x.eq.0.)lines%line(i)%end_x=lines%line(i)%start_x
1464 if(lines%line(i)%end_y.eq.0.)lines%line(i)%end_y=lines%line(i)%start_y
1465 if(lines%line(i)%end_time.eq.0.)lines%line(i)%end_time=lines%line(i)%start_time
1468 if(lines%longlat .eq. 0)then
1471 lines%unit_fxlong=1.
1473 ! will set fire mesh coordinates to uniform mesh below
1476 lat_ctr=config_flags%cen_lat
1477 lon_ctr=config_flags%cen_lon
1478 ! 1 degree in m (approximate OK)
1479 lines%unit_fxlat=pi2/(360.*reradius) ! earth circumference in m / 360 degrees
1480 lines%unit_fxlong=cos(lat_ctr*pi2/360.)*lines%unit_fxlat ! latitude
1483 if(fire_print_msg.ge.2)then
1484 !$OMP CRITICAL(SFIRE_DRIVER_CRIT)
1485 if(lines%longlat .eq. 0)then
1486 write(msg,1)'start x','start y','end x','end y','start t','end t',value_name,'radius'
1488 write(msg,1)'start lon','start lat','end lon','end lat','start time','end time',value_name,'radius'
1492 do i=1,lines%num_lines
1493 select case (value_name)
1495 value = lines%line(i)%ros
1499 value = lines%line(i)%hfx_value
1500 f2='(4f10.3,2f9.2,e9.2,f9.2)'
1501 f3='(4f10.5,2f9.2,e9.2,f9.2)'
1503 call crash('postprocess_lines: bad value_name '//value_name)
1505 if(lines%longlat .eq. 0)then
1506 write(msg,f2)lines%line(i)%start_x, lines%line(i)%start_y, &
1507 lines%line(i)%end_x, lines%line(i)%end_y, &
1508 lines%line(i)%start_time, lines%line(i)%end_time, &
1509 value, lines%line(i)%radius
1511 write(msg,f3)lines%line(i)%start_x, lines%line(i)%start_y, &
1512 lines%line(i)%end_x, lines%line(i)%end_y, &
1513 lines%line(i)%start_time, lines%line(i)%end_time, &
1514 value, lines%line(i)%radius
1517 if(lines%line(i)%start_time > lines%line(i)%end_time)then
1518 call crash('start time may not be after end time')
1521 !$OMP END CRITICAL(SFIRE_DRIVER_CRIT)
1523 end subroutine postprocess_lines
1526 subroutine fire_hfx_convert (config_flags,hfx)
1528 ! create heat flux line(s) from scalar flags
1530 TYPE (grid_config_rec_type) , INTENT(IN) :: config_flags
1531 TYPE (lines_type), INTENT(OUT):: hfx ! any values from input discarded
1534 logical:: real,ideal
1535 real::lat_ctr,lon_ctr
1536 character(len=128)msg
1538 ! this is only until I figure out how to input arrays through the namelist...
1539 hfx%num_lines=config_flags%fire_hfx_num_lines
1540 if(fire_max_lines.lt.hfx%num_lines)call crash('fire_max_lines too small')
1542 ! figure out which kind of coordinates from the first given
1543 ideal=config_flags%fire_hfx_start_x1 .ne.0. .or. config_flags%fire_hfx_start_y1 .ne. 0.
1544 real=config_flags%fire_hfx_start_lon1 .ne. 0. .or. config_flags%fire_hfx_start_lat1 .ne. 0.
1545 if(ideal)call message('Using ideal heat flux line coordinates, m from the lower left domain corner')
1546 if(real)call message('Using real heat flux line coordinates, longitude and latitude')
1547 if(ideal.and.real)call crash('Only one of the ideal or real coordinates may be given')
1549 hfx%longlat=0 ! default, if no ignition
1551 ! use values from _x and _y variables
1553 hfx%line(1)%start_x=config_flags%fire_hfx_start_x1
1554 hfx%line(1)%start_y=config_flags%fire_hfx_start_y1
1555 hfx%line(1)%end_x=config_flags%fire_hfx_end_x1
1556 hfx%line(1)%end_y=config_flags%fire_hfx_end_y1
1559 ! use values from _long and _lat
1561 hfx%line(1)%start_x=config_flags%fire_hfx_start_lon1
1562 hfx%line(1)%start_y=config_flags%fire_hfx_start_lat1
1563 hfx%line(1)%end_x=config_flags%fire_hfx_end_lon1
1564 hfx%line(1)%end_y=config_flags%fire_hfx_end_lat1
1566 ! common to both cases
1567 hfx%line(1)%radius=config_flags%fire_hfx_radius1
1568 hfx%line(1)%start_time=config_flags%fire_hfx_start_time1
1569 hfx%line(1)%end_time=config_flags%fire_hfx_end_time1
1570 hfx%line(1)%trans_time=config_flags%fire_hfx_trans_time1
1571 hfx%line(1)%hfx_value=config_flags%fire_hfx_value1
1573 call postprocess_lines(hfx,'hfx',config_flags)
1575 end subroutine fire_hfx_convert
1577 subroutine set_flags(config_flags)
1578 USE module_configure
1580 TYPE (grid_config_rec_type) , INTENT(IN) :: config_flags
1581 ! copy flags from wrf to module_fr_sfire_util
1582 ! for instructions how to add a flag see the top of module_fr_sfire_util.F
1584 fire_perimeter_time = config_flags%fire_perimeter_time
1585 fire_print_msg = config_flags%fire_print_msg
1586 fire_print_file = config_flags%fire_print_file
1587 fuel_left_method = config_flags%fire_fuel_left_method
1588 fuel_left_irl = config_flags%fire_fuel_left_irl
1589 fuel_left_jrl = config_flags%fire_fuel_left_jrl
1590 fire_atm_feedback = config_flags%fire_atm_feedback
1591 fire_hfx_given = config_flags%fire_hfx_given
1592 fire_hfx_num_lines = config_flags%fire_hfx_num_lines
1593 fire_hfx_latent_part = config_flags%fire_hfx_latent_part
1594 boundary_guard = config_flags%fire_boundary_guard
1595 fire_back_weight = config_flags%fire_back_weight
1596 fire_grows_only = config_flags%fire_grows_only
1597 fire_upwinding = config_flags%fire_upwinding
1598 fire_viscosity = config_flags%fire_viscosity
1599 fire_lfn_ext_up = config_flags%fire_lfn_ext_up
1600 fire_test_steps = config_flags%fire_test_steps
1601 !fire_topo_from_atm = config_flags%fire_topo_from_atm
1602 fire_advection = config_flags%fire_advection
1603 fire_wind_log_interp = config_flags%fire_wind_log_interp
1604 fire_use_windrf = config_flags%fire_use_windrf
1605 fire_fmc_read = config_flags%fire_fmc_read
1606 fire_ignition_clamp = config_flags%fire_ignition_clamp
1607 kfmc_ndwi = config_flags%kfmc_ndwi
1608 fndwi_from_ndwi = config_flags%fndwi_from_ndwi
1610 end subroutine set_flags
1613 !*****************************
1617 subroutine set_fp_from_grid(grid,fp)
1619 type(domain),intent(in)::grid
1620 type(fire_params),intent(out)::fp
1622 ! pointers to be passed to fire spread formulas
1623 fp%vx => grid%uf ! fire winds
1624 fp%vy => grid%vf ! fire winds
1625 fp%zsf => grid%zsf ! terrain height
1626 fp%dzdxf => grid%dzdxf ! terrain grad
1627 fp%dzdyf => grid%dzdyf ! terrain grad
1628 fp%bbb => grid%bbb ! spread formula coeff
1629 fp%phisc => grid%phisc ! spread formula coeff
1630 fp%phiwc => grid%phiwc ! spread formula coeff
1631 fp%r_0 => grid%r_0 ! spread formula coeff
1632 fp%fgip => grid%fgip ! spread formula coeff
1633 fp%ischap => grid%ischap ! spread formula coeff
1634 fp%fuel_time => grid%fuel_time ! time for fuel to burn to 1/e
1635 fp%fmc_g => grid%fmc_g ! fuel moisture, ground
1636 fp%nfuel_cat => grid%nfuel_cat ! fuel category
1639 end subroutine set_fp_from_grid
1643 character(len=128)::id,msg
1644 #include "sfire_id.inc"
1646 call message(msg,level=1)
1647 end subroutine print_id
1649 end module module_fr_sfire_driver