Skip to content

Commit

Permalink
changed names
Browse files Browse the repository at this point in the history
  • Loading branch information
janmandel committed Sep 5, 2007
1 parent 08b7261 commit 7b72b87
Show file tree
Hide file tree
Showing 7 changed files with 927 additions and 17 deletions.
26 changes: 9 additions & 17 deletions wrfv2_fire/phys/Makefile
Expand Up @@ -61,11 +61,10 @@ MODULES = \
module_fr_cawfe_fuel.o \
module_fire_debug_output.o \
# module_fr_spread_model.o \
module_fr_spread_core.o \
module_fr_propagate.o \
module_fr_fuelused.o \
module_fr_spread_util.o \
module_fr_wrfstubs.o
module_fr_sfire_core.o \
module_fr_sfire_prop.o \
module_fr_sfire_fuel.o \
module_fr_sfire_util.o

OBJS =

Expand Down Expand Up @@ -271,20 +270,13 @@ module_fr_spread_model.o: \
../share/module_model_constants.o \
../frame/module_wrf_error.o \
module_fr_cawfe_fuel.o \
module_fr_wrfstubs.o \
module_fr_spread_core.o \
module_fr_spread_util.o

module_fr_spread_util.o: \
module_fr_wrfstubs.o \

module_fr_wrfstubs.o: \
../frame/module_wrf_error.o \
module_fr_sfire_core.o \
module_fr_sfire_util.o

module_fr_spread_core.o: \
module_fr_wrfstubs.o \
module_fr_fuelused.o \
module_fr_propagate.o
module_fr_sfire_util.o \
module_fr_sfire_fuel.o \
module_fr_sfire_prop.o

module_fire_debug_output.o: \
../frame/module_domain.o \
Expand Down
151 changes: 151 additions & 0 deletions wrfv2_fire/phys/module_fr_sfire_core.F
@@ -0,0 +1,151 @@
module module_fr_spread_core
!
!*** Jan Mandel August 2007 email: jmandel@ucar.edu or Jan.Mandel@gmail.com
!
contains

subroutine fire_spread_core( ids,ide,jds,jde,ims,ime,jms,jme,&
time_start,time_end,fire_dx,fire_dy,fuel_time, &
vx,vy,r, &
phi,tign,frac_lost,frac_end)

!*** purpose
!
! Dynamical core of the fire spread model, insulated from the physics.
! References the fire grid ONLY. Keep separated from the coupling
! with atm. model and data input.
!

use module_fr_sfire_fuel
use module_fr_sfire_prop

implicit none

!*** arguments

integer, intent(in) :: ids,ide,jds,jde,ims,ime,jms,jme
real, intent(inout), dimension(ims:ime,jms:jme)::phi,tign ! state
real, intent(in), dimension(ims:ime,jms:jme)::vx,vy,r
real, intent(in), dimension(ims:ime-1,jms:jme-1)::fuel_time
real, intent(out), dimension(ims:ime-1,jms:jme-1)::frac_lost,frac_end
real, intent(in):: time_start,time_end,fire_dx,fire_dy

! argument intent description (unit) lives at
!
! ids,ide,jds,jde in mesh domain dimensions (1)
! ims,ime,jms,jme in mesh aray dimensions (1)
! time_start in the starting time (s)
! time_end in the ending time (s)
! fire_dx,fire_dy in fire mesh spacings (m)
! fuel_time in time fuel burns down to 1/e (s) cells
! vx,vy in the wind velocity (m/s) nodes
! r in the spread rate w/o wind (m/s) nodes
! phi inout level function (state) (1) nodes
! tign inout ignition time (state) (s) nodes
! frac_lost out the fuel fraction decrease (1) cells
! frac_end out the fuel fraction at the end (1) cells

! ***NOTE: vx,vy,r will be replaced by a call to a speed function in future.***
! The speed function will be called for the spread rate at points of fireline.
! A version of such level set code is in progress.

!*** description

! This is a dynamical core of the fire spread model, insulated from the physics.
! The physics should be done in the pre- and postprocessing, and in
! the speed function for the fireline propagation (future).
!
! The state of the model is the level function phi, which determines the fire
! area, and the ignition time tign, both interpolated from values at nodes.
! The fire area is the level set where phi <= 0. The fireline is where phi=0.
! The array tign outside of the fire area is not set or referenced.
! The state should be preserved between the calls, and it can be modified by
! data assimilation. All other quantities are derived from the state in each call.
!
! The level function evolves the fireline with the speed in the normal direction given by
! the spread rate r and the normal component of the wind. The level set method
! takes care of of various special cases automagically, such as ignition of a cell
! surrounded by cells that all completely burning, and merging of approaching firelines.
!
! The fuel fraction is estimated from the the ignition times assuming
! exponential decrease since ignition with decrease of fule fraction to 1/e in
! fuel_tim. The ignition times at nodes are interpolated linearly from the
! evolving level function at the start and at the end, i.e. by assuming that the
! value of the level function at a point varies linearly with time.
!
! ***NOTE: If a narrow band scheme is used to advance the level function in time
! then the firelines at time_start and time_end must fit within the band
! at either time, and level function values away from the band should be set
! to some large positive and negative constants to assure that the ignition times
! in the area between the firelines are set reasonably. This is also important
! when the level function is used for data assimilation. ***
!
! It is the responsibility of the caller to:
!
! before the call
! - polulate all cells with the proper fuel_time coefficient
! - interpolate and correct atmospheric winds
!
! after the call
! - compute the fluxes from the fuel fraction burned
! and sum up the the fluxes over atmopheric grid cells
!
!*** local
real, dimension(ims:ime-1,jms:jme-1)::frac_start
real, dimension(ims:ime,jms:jme)::phi_start
real::dummy
integer::i,j
real, dimension(ids:ide,jds:jde)::phi_d,vx_d,vy_d,r_d


!*** executable

! compute the fuel fraction at time_start
call fuel_left(ids,ide,jds,jde,ims,ime,jms,jme, &
phi,tign,fuel_time,time_start,frac_start)

! save the level function for interpolation between the old and the new one later
do i=ids,ide
do j=jds,jde
phi_start(i,j)=phi(i,j)
enddo
enddo

! advance the level function from time_start to time_end
! prop_ls will be replaced anyway, do not bother adding overlaps
phi_d=phi(ids:ide,jds:jde)
vx_d=vx(ids:ide,jds:jde)
vy_d=vy(ids:ide,jds:jde)
r_d=r(ids:ide,jds:jde)
call prop_ls(ids,ide,jds,jde,phi_d,dummy,time_start,time_end,vx_d,vy_d,r_d,fire_dx,fire_dy)
phi(ids:ide,jds:jde)=phi_d

! set ignition time at the nodes the fireline moved over
do j=jds,jde
do i=ids,ide
if(phi_start(i,j)>0 .and. .not. phi(i,j)>0)then
! node was not burning at start but it is burning at end
! interpolate from the level functions at start and at end
! phi_start(i,j) is the level function value at time_start
! phi(i,j) is the level function value at time_end
! 0 is the level function value at tign(i,j)
tign(i,j)=time_start + (time_end-time_start) &
* phi_start(i,j) / (phi_start(i,j) - phi(i,j))
endif
enddo
enddo

! compute the fuel fraction at time_end
call fuel_left(ids,ide,jds,jde,ims,ime,jms,jme, &
phi,tign,fuel_time,time_end,frac_end)

! compute the fuel fraction lost
do j=jds,jde-1
do i=ids,ide-1
frac_lost(i,j)=frac_end(i,j)-frac_start(i,j)
enddo
enddo

end subroutine fire_spread_core

end module module_fr_spread_core
126 changes: 126 additions & 0 deletions wrfv2_fire/phys/module_fr_sfire_fuel.F
@@ -0,0 +1,126 @@
module module_fr_sfire_fuel

private
public:: fuel_left

contains

subroutine fuel_left(ids,ide,jds,jde,ims,ime,jms,jme,phi,tign,w,tnow,fuel_frac)
implicit none

!*** purpose: determine fraction of fuel remaining

!*** Jan Mandel August 2007 email: jmandel@ucar.edu or Jan.Mandel@gmail.com

!*** arguments

integer, intent(in) :: ids,ide,jds,jde,ims,ime,jms,jme
real, intent(in), dimension(ims:ime,jms:jme)::phi,tign
real, intent(in), dimension(ims:ime-1,jms:jme-1)::w
real, intent(in):: tnow
real, intent(out), dimension(ims:ime-1,jms:jme-1)::fuel_frac

! ids,ide,jds,jde in mesh domain dimensions (1)
! ims,ime,jms,jme in mesh aray dimensions (1)
! phi in level function, at nodes
! tign in ignition time, at nodes
! w in time constant of fuel, per cell
! tnow in time now
! fuel_frac out fraction of fuel remaining

!*** Description
! The area burning is given by the condition P(x,y) <= 0, where the function P is
! interpolated from the values of phi at mesh nodes,
! P(dx*(i-1),dy*(j-1))=phi(i,j).
!
! The time since ignition in location (x,y) is the function T, interpolated in
! each mesh cell from the values T(dx*(i-1),dy*(j-1))=tign(i,j) at the nodes
! where phi(i,j)<=0, and T(x,y)=tnow on all points on the grid lines where P(x,y) = 0.
! The values of tign(i,j) where phi(i,j)>0 are ignored.
!
! The subroutine computes for each mesh cell [dx*(i-1),dx*i] by [dy*(j-1),dy*j]
! an approximation of the average of exp(-T(x,y)/w(i,j)) over the burning area
! in the cell, that is an approximation of the integral
!
! /\
! 1 | T(x,y)-tnow
! fuel_frac(i,j) = ----- | exp( - ------------ ) dxdy
! dx*dy | w(i,j)
! \/
! dx*(i-1)<x<dx*(i+1)
! dy*(j-1)<y<dy*(j+1)
! phi(x,y)<=0
!
! When the cell is not burning at all (all phi>=0), then fuel_frac(i,j)=1.
! Because of symmetries, the result should not depend on the mesh spacing dx dy
! so dx and dy are not in the argument list.
!
! Example:
!
! phi<0 phi>0
! (i,j+1)-----O--(i+1,j+1) O = points on the fireline, T=tnow
! | \ | A = the burning area for computing
! | \| fuel_frac(i,j)
! | A O
! | |
! | |
! (i,j)---------(i+1,j)
! phi<0 phi<0
!
! Approximations allowed:
! The fireline can be approximated by straight line(s).
! When all cell is burning, approximation by 1 point Gaussian quadrature is OK.
!
! Requirements:
! The output should be a continuous function of the arrays phi and tign whenever
! phi(i,j)=0 implies tign(i,j)=tnow.
! The output should be invariant to the symmetries of the input in each cell.
! Arbitrary combinations of the signs of phi(i,j) should work.
! The result should be at least 1st order accurate, i.e. exact when
! exp(T) is replaced by a linear function equal to one at the fireline
!
! IMPORTANT: follow WRF coding conventions
! http://www.mmm.ucar.edu/wrf/WG2/WRF_conventions.html

!*** local

integer::i,j
real,dimension(ims:ime,jms:jme)::t,ap
real:: ta,pf,aps,ps,a

! a very crude approximation - replace by a better code
! just an idea - not debugged yet

do j=jds,jde ! note the order of indices for fast execution
do i=ids,ide
if (phi(i,j)>0) then
t(i,j)=1.0 ! add missing values - should be > tnow what the hell
else
t(i,j)=exp(tign(i,j)-tnow)
endif
ap(i,j)=abs(phi(i,j))
enddo
enddo

do j=jds,jde-1
do i=ids,ide-1 ! it is OK to introduce extra scalars, just as fast

! average unscaled fuel fraction since ignition
ta=0.25d0*(t(i+1,j+1)+t(i+1,j)+t(i,j+1)+t(i,j))
ps=phi(i+1,j+1)+phi(i+1,j)+phi(i,j+1)+phi(i,j)
aps=ap(i+1,j+1)+ ap(i+1,j)+ ap(i,j+1)+ ap(i,j)

! a=0 if all phi>0, 1 if all <0, transition except when all phi=0
if (aps>0.0 .or. aps<0.0) then ! never compare =0.0, slow
a=(-ps/aps+1.0)*0.5d0
else ! for fast code, the else clause should happen less often
a=0.5d0 ! just to have something, if all phi=0 it is junk anyway
endif

fuel_frac(i,j)=a*ta**(1.0/w(i,j))+(1.0-a)
enddo
enddo

end subroutine fuel_left

end module module_fr_sfire_fuel
6 changes: 6 additions & 0 deletions wrfv2_fire/phys/module_fr_sfire_level.F
@@ -0,0 +1,6 @@
module module_fr_level
! Minjeong Kim, Min.Kim@cudenver.edu

! the narrow band level set code comes here

end module module_fr_level

0 comments on commit 7b72b87

Please sign in to comment.