2 !WRF:MEDIATION_LAYER:FIRE_MODEL
3 ! Routines dealing with the atmosphere
5 module module_fr_fire_atm
7 use module_model_constants, only: cp,xlv
8 use module_fr_fire_util
9 use module_state_description, only: num_tracer
10 use module_state_description, only: p_fire_smoke
14 ! DME subroutine for passive tracers
15 subroutine add_fire_tracer_emissions( &
16 tracer_opt,dt,dx,dy, &
17 ifms,ifme,jfms,jfme, &
18 ifts,ifte,jtfs,jfte, &
19 ids,ide,kds,kde,jds,jde, &
20 ims,ime,kms,kme,jms,jme, &
21 its,ite,kts,kte,jts,jte, &
24 tracer,fire_tracer_smoke &
29 integer,intent(in)::tracer_opt
30 real,intent(in)::fire_tracer_smoke
31 real,intent(in)::dt,dx,dy
32 integer,intent(in)::ifms,ifme,jfms,jfme,ifts,ifte,jtfs,jfte,ids,ide,kds,kde,jds,jde,ims,ime,kms,kme,jms,jme,its,ite,kts,kte,jts,jte
33 real,intent(in)::rho(ims:ime,kms:kme,jms:jme),dz8w(ims:ime,kms:kme,jms:jme)
34 real,intent(in),dimension(ifms:ifme,jfms:jfme)::burnt_area_dt,fgip
35 real,intent(inout)::tracer(ims:ime,kms:kme,jms:jme,num_tracer)
37 integer::isz1,jsz1,isz2,jsz2,ir,jr
38 integer::i,j,ibase,jbase,i_f,ioff,j_f,joff
49 do j=max(jds+1,jts),min(jte,jde-2)
51 do i=max(ids+1,its),min(ite,ide-2)
57 if (num_tracer >0)then
58 emis=avgw*fire_tracer_smoke*burnt_area_dt(i_f,j_f)*fgip(i_f,j_f)*1000/(rho(i,kts,j)*dz8w(i,kts,j)) ! g_smoke/kg_air
59 tracer(i,kts,j,p_fire_smoke)=tracer(i,kts,j,p_fire_smoke)+emis
66 end subroutine add_fire_tracer_emissions
72 SUBROUTINE fire_tendency( &
73 ids,ide, kds,kde, jds,jde, & ! dimensions
74 ims,ime, kms,kme, jms,jme, &
75 its,ite, kts,kte, jts,jte, &
76 grnhfx,grnqfx,canhfx,canqfx, & ! heat fluxes summed up to atm grid
77 alfg,alfc,z1can, & ! coeffients, properties, geometry
78 zs,z_at_w,dz8w,mu,c1h,c2h,rho, &
79 rthfrten,rqvfrten) ! theta and Qv tendencies
81 ! This routine is atmospheric physics
82 ! it does NOT go into module_fr_fire_phys because it is not related to fire physical processes
84 ! --- this routine takes fire generated heat and moisture fluxes and
85 ! calculates their influence on the theta and water vapor
86 ! --- note that these tendencies are valid at the Arakawa-A location
90 ! --- incoming variables
92 INTEGER , INTENT(in) :: ids,ide, kds,kde, jds,jde, &
93 ims,ime, kms,kme, jms,jme, &
94 its,ite, kts,kte, jts,jte
96 REAL, INTENT(in), DIMENSION( ims:ime,jms:jme ) :: grnhfx,grnqfx ! W/m^2
97 REAL, INTENT(in), DIMENSION( ims:ime,jms:jme ) :: canhfx,canqfx ! W/m^2
98 REAL, INTENT(in), DIMENSION( ims:ime,jms:jme ) :: zs ! topography (m abv sealvl)
99 REAL, INTENT(in), DIMENSION( ims:ime,jms:jme ) :: mu ! dry air mass (Pa)
100 REAL, INTENT(in), DIMENSION( kms:kme ) :: c1h, c2h ! Hybrid coordinate weights
102 REAL, INTENT(in), DIMENSION( ims:ime,kms:kme,jms:jme ) :: z_at_w ! m abv sealvl
103 REAL, INTENT(in), DIMENSION( ims:ime,kms:kme,jms:jme ) :: dz8w ! dz across w-lvl
104 REAL, INTENT(in), DIMENSION( ims:ime,kms:kme,jms:jme ) :: rho ! density
106 REAL, INTENT(in) :: alfg ! extinction depth surface fire heat (m)
107 REAL, INTENT(in) :: alfc ! extinction depth crown fire heat (m)
108 REAL, INTENT(in) :: z1can ! height of crown fire heat release (m)
110 ! --- outgoing variables
112 REAL, INTENT(out), DIMENSION( ims:ime,kms:kme,jms:jme ) :: &
113 rthfrten, & ! theta tendency from fire (in mass units)
114 rqvfrten ! Qv tendency from fire (in mass units)
115 ! --- local variables
118 INTEGER :: i_st,i_en, j_st,j_en, k_st,k_en
124 REAL :: fact_g, fact_c
125 REAL :: alfg_i, alfc_i
127 REAL, DIMENSION( its:ite,kts:kte,jts:jte ) :: hfx,qfx
129 !! character(len=128)::msg
132 do k=kts,min(kte+1,kde)
141 ! --- set some local constants
144 cp_i = 1./cp ! inverse of specific heat
145 xlv_i = 1./xlv ! inverse of latent heat
149 !!write(msg,'(8e11.3)')cp,cp_i,xlv,xlv_i,alfg,alfc,z1can
152 call print_2d_stats(its,ite,jts,jte,ims,ime,jms,jme,grnhfx,'fire_tendency:grnhfx')
153 call print_2d_stats(its,ite,jts,jte,ims,ime,jms,jme,grnqfx,'fire_tendency:grnqfx')
155 ! --- set loop indicies : note that
157 i_st = MAX(its,ids+1)
158 i_en = MIN(ite,ide-1)
160 k_en = MIN(kte,kde-1)
161 j_st = MAX(jts,jds+1)
162 j_en = MIN(jte,jde-1)
164 ! --- distribute fluxes
170 ! --- set z (in meters above ground)
172 z_w = z_at_w(i,k,j) - zs(i,j) ! should be zero when k=k_st
176 fact_g = cp_i * EXP( - alfg_i * z_w )
177 IF ( z_w < z1can ) THEN
180 fact_c = cp_i * EXP( - alfc_i * (z_w - z1can) )
182 hfx(i,k,j) = fact_g * grnhfx(i,j) + fact_c * canhfx(i,j)
184 !! write(msg,2)i,k,j,z_w,grnhfx(i,j),hfx(i,k,j)
185 !!2 format('hfx:',3i4,6e11.3)
190 fact_g = xlv_i * EXP( - alfg_i * z_w )
191 IF (z_w < z1can) THEN
194 fact_c = xlv_i * EXP( - alfc_i * (z_w - z1can) )
196 qfx(i,k,j) = fact_g * grnqfx(i,j) + fact_c * canqfx(i,j)
198 !! if(hfx(i,k,j).ne.0. .or. qfx(i,k,j) .ne. 0.)then
199 !! write(msg,1)i,k,j,hfx(i,k,j),qfx(i,k,j)
200 !!1 format('tend:',3i6,2e11.3)
208 ! --- add flux divergence to tendencies
210 ! multiply by dry air mass (mu) to eliminate the need to
211 ! call sr. calculate_phy_tend (in dyn_em/module_em.F)
217 rho_i = 1./rho(i,k,j)
219 rthfrten(i,k,j) = - (c1h(k)*mu(i,j)+c2h(k)) * rho_i * (hfx(i,k+1,j)-hfx(i,k,j)) / dz8w(i,k,j)
220 rqvfrten(i,k,j) = - (c1h(k)*mu(i,j)+c2h(k)) * rho_i * (qfx(i,k+1,j)-qfx(i,k,j)) / dz8w(i,k,j)
226 call print_3d_stats(its,ite,kts,kte,jts,jte,ims,ime,kms,kme,jms,jme,rthfrten,'fire_tendency:rthfrten')
227 call print_3d_stats(its,ite,kts,kte,jts,jte,ims,ime,kms,kme,jms,jme,rqvfrten,'fire_tendency:rqvfrten')
231 END SUBROUTINE fire_tendency
237 end module module_fr_fire_atm