Skip to content

Commit a936459

Browse files
danrosen25masih-egrantfirl
authored
Add two way fire coupling to fv3atm (#815)
* add fire_behavior smoke coupling and flags and export variables for fire behavior * added: inst_pres_levels, inst_geop_levels, inst_zonal_wind_levels, inst_merid_wind_levels, inst_surface_roughness, inst_temp_height2m, inst_spec_humid_height2m, inst_pres_height_surface, mean_prec_rate, inst_rainfall_amount * add fire behavior tendencies to physics * add hflx_fire and evap_fire to FV3 imports * added surface emissions fire_smoke imports and initialized the variables and fsmoke tracer index --------- Co-authored-by: masih <[email protected]> Co-authored-by: Grant Firl <[email protected]>
1 parent 40e014f commit a936459

File tree

6 files changed

+168
-15
lines changed

6 files changed

+168
-15
lines changed

Diff for: atmos_model.F90

+75
Original file line numberDiff line numberDiff line change
@@ -3121,6 +3121,54 @@ subroutine assign_importdata(jdat, rc)
31213121
endif
31223122
endif
31233123

3124+
fldname = 'hflx_fire'
3125+
if (trim(impfield_name) == trim(fldname)) then
3126+
findex = queryImportFields(fldname)
3127+
if (importFieldsValid(findex)) then
3128+
!$omp parallel do default(shared) private(i,j,nb,ix)
3129+
do j=jsc,jec
3130+
do i=isc,iec
3131+
nb = Atm_block%blkno(i,j)
3132+
ix = Atm_block%ixp(i,j)
3133+
im = GFS_control%chunk_begin(nb)+ix-1
3134+
GFS_sfcprop%hflx_fire(im) = datar82d(i-isc+1,j-jsc+1)
3135+
enddo
3136+
enddo
3137+
endif
3138+
endif
3139+
3140+
fldname = 'evap_fire'
3141+
if (trim(impfield_name) == trim(fldname)) then
3142+
findex = queryImportFields(fldname)
3143+
if (importFieldsValid(findex)) then
3144+
!$omp parallel do default(shared) private(i,j,nb,ix)
3145+
do j=jsc,jec
3146+
do i=isc,iec
3147+
nb = Atm_block%blkno(i,j)
3148+
ix = Atm_block%ixp(i,j)
3149+
im = GFS_control%chunk_begin(nb)+ix-1
3150+
GFS_sfcprop%evap_fire(im) = datar82d(i-isc+1,j-jsc+1)
3151+
enddo
3152+
enddo
3153+
endif
3154+
endif
3155+
3156+
fldname = 'smoke_fire'
3157+
if (trim(impfield_name) == trim(fldname)) then
3158+
findex = queryImportFields(fldname)
3159+
if (importFieldsValid(findex)) then
3160+
!$omp parallel do default(shared) private(i,j,nb,ix)
3161+
do j=jsc,jec
3162+
do i=isc,iec
3163+
nb = Atm_block%blkno(i,j)
3164+
ix = Atm_block%ixp(i,j)
3165+
im = GFS_control%chunk_begin(nb)+ix-1
3166+
GFS_sfcprop%smoke_fire(im) = datar82d(i-isc+1,j-jsc+1)
3167+
enddo
3168+
enddo
3169+
endif
3170+
endif
3171+
31243172
! write post merge import data to NetCDF file.
31253173
if (GFS_control%cpl_imp_dbg) then
31263174
call ESMF_FieldGet(importFields(n), grid=grid, rc=rc)
@@ -3294,6 +3342,21 @@ subroutine setup_exportdata(rc)
32943342
do nb = 1, Atm_block%nblks
32953343
select case (trim(fieldname))
32963344
!--- Instantaneous quantities
3345+
! Instantaneous mean layer pressure (Pa)
3346+
case ('inst_pres_levels')
3347+
call block_data_copy_or_fill(datar83d, GFS_statein%prsl, zeror8, Atm_block, nb, offset=GFS_Control%chunk_begin(nb), rc=localrc)
3348+
! Instantaneous geopotential at model layer centers (m2 s-2)
3349+
case ('inst_geop_levels')
3350+
call block_data_copy_or_fill(datar83d, GFS_statein%phil, zeror8, Atm_block, nb, offset=GFS_Control%chunk_begin(nb), rc=localrc)
3351+
! Instantaneous zonal wind (m s-1)
3352+
case ('inst_zonal_wind_levels')
3353+
call block_data_copy_or_fill(datar83d, GFS_statein%ugrs, zeror8, Atm_block, nb, offset=GFS_Control%chunk_begin(nb), rc=localrc)
3354+
! Instantaneous meridional wind (m s-1)
3355+
case ('inst_merid_wind_levels')
3356+
call block_data_copy_or_fill(datar83d, GFS_statein%vgrs, zeror8, Atm_block, nb, offset=GFS_Control%chunk_begin(nb), rc=localrc)
3357+
! Instantaneous surface roughness length (cm)
3358+
case ('inst_surface_roughness')
3359+
call block_data_copy(datar82d, GFS_sfcprop%zorl, Atm_block, nb, offset=GFS_Control%chunk_begin(nb), rc=localrc)
32973360
! Instantaneous u wind (m/s) 10 m above ground
32983361
case ('inst_zonal_wind_height10m')
32993362
call block_data_copy(datar82d, GFS_coupling%u10mi_cpl, Atm_block, nb, offset=GFS_Control%chunk_begin(nb), rc=localrc)
@@ -3378,6 +3441,9 @@ subroutine setup_exportdata(rc)
33783441
! Land/Sea mask (sea:0,land:1)
33793442
case ('inst_land_sea_mask', 'slmsk')
33803443
call block_data_copy(datar82d, GFS_sfcprop%slmsk, Atm_block, nb, offset=GFS_Control%chunk_begin(nb), rc=localrc)
3444+
! Total precipitation amount in each time step
3445+
case ('inst_rainfall_amount')
3446+
call block_data_copy(datar82d, GFS_sfcprop%tprcp, Atm_block, nb, offset=GFS_Control%chunk_begin(nb), rc=localrc)
33813447
!--- Mean quantities
33823448
! MEAN Zonal compt of momentum flux (N/m**2)
33833449
case ('mean_zonal_moment_flx_atm')
@@ -3430,6 +3496,15 @@ subroutine setup_exportdata(rc)
34303496
! MEAN NET sfc uv+vis diffused flux (W/m**2)
34313497
case ('mean_net_sw_vis_dif_flx')
34323498
call block_data_copy(datar82d, GFS_coupling%nvisdf_cpl, Atm_block, nb, rtime, spval, offset=GFS_Control%chunk_begin(nb), rc=localrc)
3499+
! MEAN precipitation rate (kg/m2/s)
3500+
case ('mean_prec_rate')
3501+
call block_data_copy(datar82d, GFS_sfcprop%tprcp, Atm_block, nb, rtimek, spval, offset=GFS_Control%chunk_begin(nb), rc=localrc)
3502+
! MEAN convective precipitation rate (kg/m2/s)
3503+
case ('mean_prec_rate_conv')
3504+
call block_data_copy(datar82d, GFS_coupling%rainc_cpl, Atm_block, nb, rtimek, spval, offset=GFS_Control%chunk_begin(nb), rc=localrc)
3505+
! MEAN snow precipitation rate (kg/m2/s)
3506+
case ('mean_fprec_rate')
3507+
call block_data_copy(datar82d, GFS_coupling%snow_cpl, Atm_block, nb, rtimek, spval, offset=GFS_Control%chunk_begin(nb), rc=localrc)
34333508
! oceanfrac used by atm to calculate fluxes
34343509
case ('openwater_frac_in_atm')
34353510
call block_data_combine_fractions(datar82d, GFS_sfcprop%oceanfrac, GFS_sfcprop%fice, Atm_block, nb, offset=GFS_Control%chunk_begin(nb), rc=localrc)

Diff for: ccpp/data/GFS_typedefs.F90

+29-6
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,11 @@ module GFS_typedefs
297297
real (kind=kind_phys), pointer :: hflx (:) => null() !<
298298
real (kind=kind_phys), pointer :: qss (:) => null() !<
299299

300+
!--- fire_behavior
301+
real (kind=kind_phys), pointer :: hflx_fire (:) => null() !< kinematic surface upward sensible heat flux of fire
302+
real (kind=kind_phys), pointer :: evap_fire (:) => null() !< kinematic surface upward latent heat flux of fire
303+
real (kind=kind_phys), pointer :: smoke_fire (:) => null() !< smoke emission of fire
304+
300305
!-- In/Out
301306
real (kind=kind_phys), pointer :: maxupmf(:) => null() !< maximum up draft mass flux for Grell-Freitas
302307
real (kind=kind_phys), pointer :: conv_act(:) => null() !< convective activity counter for Grell-Freitas
@@ -766,6 +771,7 @@ module GFS_typedefs
766771
logical :: cpllnd !< default no cpllnd collection
767772
logical :: cpllnd2atm !< default no lnd->atm coupling
768773
logical :: rrfs_sd !< default no rrfs_sd collection
774+
logical :: cpl_fire !< default no fire_behavior collection
769775
logical :: use_cice_alb !< default .false. - i.e. don't use albedo imported from the ice model
770776
logical :: cpl_imp_mrg !< default no merge import with internal forcings
771777
logical :: cpl_imp_dbg !< default no write import data to file post merge
@@ -1485,6 +1491,7 @@ module GFS_typedefs
14851491
integer :: nto2 !< tracer index for oxygen
14861492
integer :: ntwa !< tracer index for water friendly aerosol
14871493
integer :: ntia !< tracer index for ice friendly aerosol
1494+
integer :: ntfsmoke !< tracer index for fire smoke
14881495
integer :: ntsmoke !< tracer index for smoke
14891496
integer :: ntdust !< tracer index for dust
14901497
integer :: ntcoarsepm !< tracer index for coarse PM
@@ -2864,6 +2871,16 @@ subroutine sfcprop_create (Sfcprop, Model)
28642871
Sfcprop%lu_qfire = clear_val
28652872
endif
28662873

2874+
!--- if fire_behavior is on
2875+
if(Model%cpl_fire) then
2876+
allocate (Sfcprop%hflx_fire (IM))
2877+
allocate (Sfcprop%evap_fire (IM))
2878+
allocate (Sfcprop%smoke_fire (IM))
2879+
Sfcprop%hflx_fire = zero
2880+
Sfcprop%evap_fire = zero
2881+
Sfcprop%smoke_fire = zero
2882+
endif
2883+
28672884
end subroutine sfcprop_create
28682885

28692886

@@ -2923,7 +2940,7 @@ subroutine coupling_create (Coupling, Model)
29232940
Coupling%tsfc_radtime = clear_val
29242941
endif
29252942

2926-
if (Model%cplflx .or. Model%do_sppt .or. Model%cplchm .or. Model%ca_global .or. Model%cpllnd) then
2943+
if (Model%cplflx .or. Model%do_sppt .or. Model%cplchm .or. Model%ca_global .or. Model%cpllnd .or. Model%cpl_fire) then
29272944
allocate (Coupling%rain_cpl (IM))
29282945
allocate (Coupling%snow_cpl (IM))
29292946
Coupling%rain_cpl = clear_val
@@ -2952,7 +2969,7 @@ subroutine coupling_create (Coupling, Model)
29522969
! Coupling%zorlwav_cpl = clear_val
29532970
! endif
29542971

2955-
if (Model%cplflx .or. Model%cpllnd) then
2972+
if (Model%cplflx .or. Model%cpllnd .or. Model%cpl_fire) then
29562973
allocate (Coupling%dlwsfci_cpl (IM))
29572974
allocate (Coupling%dswsfci_cpl (IM))
29582975
allocate (Coupling%dlwsfc_cpl (IM))
@@ -2986,7 +3003,7 @@ subroutine coupling_create (Coupling, Model)
29863003
Coupling%nvisdf_cpl = clear_val
29873004
end if
29883005

2989-
if (Model%cplflx) then
3006+
if (Model%cplflx .or. Model%cpl_fire) then
29903007
!--- incoming quantities
29913008
allocate (Coupling%slimskin_cpl (IM))
29923009
allocate (Coupling%dusfcin_cpl (IM))
@@ -3151,7 +3168,7 @@ subroutine coupling_create (Coupling, Model)
31513168
Coupling%pfl_lsan = clear_val
31523169
endif
31533170

3154-
if (Model%cplchm .or. Model%cplflx .or. Model%cpllnd) then
3171+
if (Model%cplchm .or. Model%cplflx .or. Model%cpllnd .or. Model%cpl_fire) then
31553172
!--- accumulated convective rainfall
31563173
allocate (Coupling%rainc_cpl (IM))
31573174
Coupling%rainc_cpl = clear_val
@@ -3359,6 +3376,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, &
33593376
logical :: cpllnd = .false. !< default no cpllnd collection
33603377
logical :: cpllnd2atm = .false. !< default no cpllnd2atm coupling
33613378
logical :: rrfs_sd = .false. !< default no rrfs_sd collection
3379+
logical :: cpl_fire = .false. !< default no fire behavior colleciton
33623380
logical :: use_cice_alb = .false. !< default no cice albedo
33633381
logical :: cpl_imp_mrg = .false. !< default no merge import with internal forcings
33643382
logical :: cpl_imp_dbg = .false. !< default no write import data to file post merge
@@ -4006,7 +4024,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, &
40064024
!--- coupling parameters
40074025
cplflx, cplice, cplocn2atm, cplwav, cplwav2atm, cplaqm, &
40084026
cplchm, cpllnd, cpllnd2atm, cpl_imp_mrg, cpl_imp_dbg, &
4009-
rrfs_sd, use_cice_alb, &
4027+
cpl_fire, rrfs_sd, use_cice_alb, &
40104028
#ifdef IDEA_PHYS
40114029
lsidea, weimer_model, f107_kp_size, f107_kp_interval, &
40124030
f107_kp_skip_size, f107_kp_data_size, f107_kp_read_in_start, &
@@ -4379,6 +4397,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, &
43794397

43804398
!--- RRFS-SD
43814399
Model%rrfs_sd = rrfs_sd
4400+
Model%cpl_fire = cpl_fire
43824401
Model%dust_drylimit_factor = dust_drylimit_factor
43834402
Model%dust_moist_correction = dust_moist_correction
43844403
Model%dust_moist_opt = dust_moist_opt
@@ -5191,12 +5210,14 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, &
51915210
Model%nqrimef = get_tracer_index(Model%tracer_names, 'q_rimef', Model%me, Model%master, Model%debug)
51925211
Model%ntwa = get_tracer_index(Model%tracer_names, 'liq_aero', Model%me, Model%master, Model%debug)
51935212
Model%ntia = get_tracer_index(Model%tracer_names, 'ice_aero', Model%me, Model%master, Model%debug)
5213+
if (Model%cpl_fire) then
5214+
Model%ntfsmoke = get_tracer_index(Model%tracer_names, 'fsmoke', Model%me, Model%master, Model%debug)
5215+
endif
51945216
if (Model%rrfs_sd) then
51955217
Model%ntsmoke = get_tracer_index(Model%tracer_names, 'smoke', Model%me, Model%master, Model%debug)
51965218
Model%ntdust = get_tracer_index(Model%tracer_names, 'dust', Model%me, Model%master, Model%debug)
51975219
Model%ntcoarsepm = get_tracer_index(Model%tracer_names, 'coarsepm', Model%me, Model%master, Model%debug)
51985220
endif
5199-
52005221
!--- initialize parameters for atmospheric chemistry tracers
52015222
call Model%init_chemistry(tracer_types)
52025223

@@ -6502,6 +6523,7 @@ subroutine control_print(Model)
65026523
print *, ' cpllnd : ', Model%cpllnd
65036524
print *, ' cpllnd2atm : ', Model%cpllnd2atm
65046525
print *, ' rrfs_sd : ', Model%rrfs_sd
6526+
print *, ' cpl_fire : ', Model%cpl_fire
65056527
print *, ' use_cice_alb : ', Model%use_cice_alb
65066528
print *, ' cpl_imp_mrg : ', Model%cpl_imp_mrg
65076529
print *, ' cpl_imp_dbg : ', Model%cpl_imp_dbg
@@ -6973,6 +6995,7 @@ subroutine control_print(Model)
69736995
print *, ' nto2 : ', Model%nto2
69746996
print *, ' ntwa : ', Model%ntwa
69756997
print *, ' ntia : ', Model%ntia
6998+
print *, ' ntfsmoke : ', Model%ntfsmoke
69766999
print *, ' ntsmoke : ', Model%ntsmoke
69777000
print *, ' ntdust : ', Model%ntdust
69787001
print *, ' ntcoarsepm : ', Model%ntcoarsepm

Diff for: ccpp/data/GFS_typedefs.meta

+41-5
Original file line numberDiff line numberDiff line change
@@ -2363,6 +2363,30 @@
23632363
type = real
23642364
kind = kind_phys
23652365
active = (do_smoke_coupling)
2366+
[hflx_fire]
2367+
standard_name = kinematic_surface_upward_sensible_heat_flux_of_fire
2368+
long_name = kinematic surface upward sensible heat flux of fire
2369+
units = K m s-1
2370+
dimensions = (horizontal_loop_extent)
2371+
type = real
2372+
kind = kind_phys
2373+
active = (do_fire_coupling)
2374+
[evap_fire]
2375+
standard_name = surface_upward_specific_humidity_flux_of_fire
2376+
long_name = kinematic surface upward latent heat flux of fire
2377+
units = kg kg-1 m s-1
2378+
dimensions = (horizontal_loop_extent)
2379+
type = real
2380+
kind = kind_phys
2381+
active = (do_fire_coupling)
2382+
[smoke_fire]
2383+
standard_name = smoke_emission_of_fire
2384+
long_name = smoke emission of fire
2385+
units = kg m-2
2386+
dimensions = (horizontal_loop_extent)
2387+
type = real
2388+
kind = kind_phys
2389+
active = (do_fire_coupling)
23662390

23672391
########################################################################
23682392
[ccpp-table-properties]
@@ -2472,15 +2496,15 @@
24722496
dimensions = (horizontal_dimension)
24732497
type = real
24742498
kind = kind_phys
2475-
active = (flag_for_surface_flux_coupling .or. flag_for_chemistry_coupling .or. flag_for_land_coupling)
2499+
active = (flag_for_surface_flux_coupling .or. flag_for_chemistry_coupling .or. flag_for_land_coupling .or. do_fire_coupling)
24762500
[snow_cpl]
24772501
standard_name = cumulative_lwe_thickness_of_snow_amount_for_coupling
24782502
long_name = total snow precipitation
24792503
units = m
24802504
dimensions = (horizontal_dimension)
24812505
type = real
24822506
kind = kind_phys
2483-
active = (flag_for_surface_flux_coupling .or. flag_for_stochastic_physics_perturbations .or. flag_for_chemistry_coupling .or. flag_for_global_cellular_automata .or. flag_for_land_coupling)
2507+
active = (flag_for_surface_flux_coupling .or. flag_for_stochastic_physics_perturbations .or. flag_for_chemistry_coupling .or. flag_for_global_cellular_automata .or. flag_for_land_coupling .or. do_fire_coupling)
24842508
[dusfc_cpl]
24852509
standard_name = cumulative_surface_x_momentum_flux_for_coupling_multiplied_by_timestep
24862510
long_name = cumulative sfc x momentum flux multiplied by timestep
@@ -2744,15 +2768,15 @@
27442768
dimensions = (horizontal_dimension)
27452769
type = real
27462770
kind = kind_phys
2747-
active = (flag_for_surface_flux_coupling .or. flag_for_air_quality_coupling)
2771+
active = (flag_for_surface_flux_coupling .or. flag_for_air_quality_coupling .or. do_fire_coupling)
27482772
[q2mi_cpl]
27492773
standard_name = specific_humidity_at_2m_for_coupling
27502774
long_name = instantaneous Q2m
27512775
units = kg kg-1
27522776
dimensions = (horizontal_dimension)
27532777
type = real
27542778
kind = kind_phys
2755-
active = (flag_for_surface_flux_coupling .or. flag_for_air_quality_coupling)
2779+
active = (flag_for_surface_flux_coupling .or. flag_for_air_quality_coupling .or. do_fire_coupling)
27562780
[u10mi_cpl]
27572781
standard_name = x_wind_at_10m_for_coupling
27582782
long_name = instantaneous U10m
@@ -2784,7 +2808,7 @@
27842808
dimensions = (horizontal_dimension)
27852809
type = real
27862810
kind = kind_phys
2787-
active = (flag_for_surface_flux_coupling .or. flag_for_air_quality_coupling .or. flag_for_land_coupling)
2811+
active = (flag_for_surface_flux_coupling .or. flag_for_air_quality_coupling .or. flag_for_land_coupling .or. do_fire_coupling)
27882812
[ulwsfcin_cpl]
27892813
standard_name = surface_upwelling_longwave_flux_from_coupled_process
27902814
long_name = surface upwelling LW flux for coupling
@@ -3634,6 +3658,12 @@
36343658
units = flag
36353659
dimensions = ()
36363660
type = logical
3661+
[cpl_fire]
3662+
standard_name = do_fire_coupling
3663+
long_name = flag controlling fire_behavior collection (default off)
3664+
units = flag
3665+
dimensions = ()
3666+
type = logical
36373667
[cpl_imp_mrg]
36383668
standard_name = flag_for_merging_imported_data
36393669
long_name = flag controlling cpl_imp_mrg for imported data (default off)
@@ -6549,6 +6579,12 @@
65496579
units = index
65506580
dimensions = ()
65516581
type = integer
6582+
[ntfsmoke]
6583+
standard_name = index_for_fire_smoke_in_tracer_concentration_array
6584+
long_name = tracer index for fire smoke
6585+
units = index
6586+
dimensions = ()
6587+
type = integer
65526588
[ntdust]
65536589
standard_name = index_for_dust_in_tracer_concentration_array
65546590
long_name = tracer index for dust

Diff for: ccpp/driver/GFS_diagnostics.F90

+13
Original file line numberDiff line numberDiff line change
@@ -4653,6 +4653,19 @@ subroutine GFS_externaldiag_populate (ExtDiag, Model, Statein, Stateout, Sfcprop
46534653
enddo
46544654
end if thompson_extended_diagnostics
46554655

4656+
if (Model%cpl_fire .and. Model%ntfsmoke>0) then
4657+
idx = idx + 1
4658+
ExtDiag(idx)%axes = 3
4659+
ExtDiag(idx)%name = 'fsmoke'
4660+
ExtDiag(idx)%desc = 'smoke concentration'
4661+
ExtDiag(idx)%unit = 'kg kg-1'
4662+
ExtDiag(idx)%mod_name = 'gfs_phys'
4663+
allocate (ExtDiag(idx)%data(nblks))
4664+
do nb = 1,nblks
4665+
ExtDiag(idx)%data(nb)%var3 => Statein%qgrs(Model%chunk_begin(nb):Model%chunk_end(nb),:,Model%ntfsmoke)
4666+
enddo
4667+
endif
4668+
46564669
if (Model%rrfs_sd .and. Model%ntsmoke>0) then
46574670

46584671
idx = idx + 1

0 commit comments

Comments
 (0)