Line data Source code
1 : !===============================================================================
2 : ! Dust for Modal Aerosol Model
3 : !===============================================================================
4 : module dust_model
5 : use shr_kind_mod, only: r8 => shr_kind_r8, cl => shr_kind_cl
6 : use spmd_utils, only: masterproc
7 : use cam_abortutils, only: endrun
8 : use modal_aero_data, only: ntot_amode, ndst=>nDust
9 : use cam_logfile, only: iulog
10 : use shr_dust_emis_mod,only: is_dust_emis_zender, is_zender_soil_erod_from_atm
11 :
12 : implicit none
13 : private
14 :
15 : public :: dust_names
16 : public :: dust_nbin
17 : public :: dust_nnum
18 : public :: dust_indices
19 : public :: dust_emis
20 : public :: dust_readnl
21 : public :: dust_init
22 : public :: dust_active
23 :
24 : integer, protected :: dust_nbin != 2
25 : integer, protected :: dust_nnum != 2
26 : character(len=6), protected, allocatable :: dust_names(:)
27 :
28 : real(r8), allocatable :: dust_dmt_grd(:)
29 : real(r8), allocatable :: dust_emis_sclfctr(:)
30 :
31 : integer , protected, allocatable :: dust_indices(:)
32 : real(r8), allocatable :: dust_dmt_vwr(:)
33 : real(r8), allocatable :: dust_stk_crc(:)
34 :
35 : real(r8) :: dust_emis_fact = 0._r8 ! tuning parameter for dust emissions
36 : character(len=cl) :: soil_erod_file = 'none' ! full pathname for soil erodibility dataset
37 :
38 : logical :: dust_active = .false.
39 :
40 : contains
41 :
42 : !=============================================================================
43 : ! reads dust namelist options
44 : !=============================================================================
45 1536 : subroutine dust_readnl(nlfile)
46 :
47 : use namelist_utils, only: find_group_name
48 : use spmd_utils, only: mpicom, masterprocid, mpi_character, mpi_real8, mpi_success
49 : use shr_dust_emis_mod, only: shr_dust_emis_readnl
50 :
51 : character(len=*), intent(in) :: nlfile ! filepath for file containing namelist input
52 :
53 : ! Local variables
54 : integer :: unitn, ierr
55 : character(len=*), parameter :: subname = 'dust_readnl'
56 :
57 : namelist /dust_nl/ dust_emis_fact, soil_erod_file
58 :
59 : !-----------------------------------------------------------------------------
60 :
61 : ! Read namelist
62 1536 : if (masterproc) then
63 2 : open( newunit=unitn, file=trim(nlfile), status='old' )
64 2 : call find_group_name(unitn, 'dust_nl', status=ierr)
65 2 : if (ierr == 0) then
66 2 : read(unitn, dust_nl, iostat=ierr)
67 2 : if (ierr /= 0) then
68 0 : call endrun(subname // ':: ERROR reading namelist')
69 : end if
70 : end if
71 2 : close(unitn)
72 : end if
73 :
74 : ! Broadcast namelist variables
75 1536 : call mpi_bcast(soil_erod_file, len(soil_erod_file), mpi_character, masterprocid, mpicom, ierr)
76 1536 : if (ierr/=mpi_success) then
77 0 : call endrun(subname//' MPI_BCAST ERROR: soil_erod_file')
78 : end if
79 1536 : call mpi_bcast(dust_emis_fact, 1, mpi_real8, masterprocid, mpicom, ierr)
80 1536 : if (ierr/=mpi_success) then
81 0 : call endrun(subname//' MPI_BCAST ERROR: dust_emis_fact')
82 : end if
83 :
84 1536 : call shr_dust_emis_readnl(mpicom, 'drv_flds_in')
85 :
86 1536 : if ((soil_erod_file /= 'none') .and. (.not.is_zender_soil_erod_from_atm())) then
87 0 : call endrun(subname//': should not specify soil_erod_file if Zender soil erosion is not in CAM')
88 : end if
89 :
90 1536 : if (masterproc) then
91 2 : if (is_dust_emis_zender()) then
92 0 : write(iulog,*) subname,': Zender_2003 dust emission method is being used.'
93 : end if
94 2 : if (is_zender_soil_erod_from_atm()) then
95 0 : write(iulog,*) subname,': Zender soil erod file is handled in atm'
96 0 : write(iulog,*) subname,': soil_erod_file = ',trim(soil_erod_file)
97 0 : write(iulog,*) subname,': dust_emis_fact = ',dust_emis_fact
98 : end if
99 : end if
100 :
101 1536 : end subroutine dust_readnl
102 :
103 : !=============================================================================
104 : !=============================================================================
105 1536 : subroutine dust_init()
106 : use soil_erod_mod, only: soil_erod_init
107 : use constituents, only: cnst_get_ind
108 : use rad_constituents, only: rad_cnst_get_info
109 : use dust_common, only: dust_set_params
110 :
111 : integer :: l, m, mm, ndx, nspec
112 : character(len=32) :: spec_name
113 : integer, parameter :: mymodes(7) = (/ 2, 1, 3, 4, 5, 6, 7 /) ! tricky order ...
114 :
115 1536 : dust_nbin = ndst
116 1536 : dust_nnum = ndst
117 :
118 4608 : allocate( dust_names(2*ndst) )
119 4608 : allocate( dust_indices(2*ndst) )
120 4608 : allocate( dust_dmt_grd(ndst+1) )
121 4608 : allocate( dust_emis_sclfctr(ndst) )
122 3072 : allocate( dust_dmt_vwr(ndst) )
123 3072 : allocate( dust_stk_crc(ndst) )
124 :
125 1536 : if ( ntot_amode == 3 ) then
126 0 : dust_dmt_grd(:) = (/ 0.1e-6_r8, 1.0e-6_r8, 10.0e-6_r8/)
127 0 : dust_emis_sclfctr(:) = (/ 0.011_r8,0.989_r8 /)
128 1536 : elseif ( ntot_amode == 4 .or. ntot_amode == 5 ) then
129 7680 : dust_dmt_grd(:) = (/ 0.01e-6_r8, 0.1e-6_r8, 1.0e-6_r8, 10.0e-6_r8 /) ! Aitken dust
130 6144 : dust_emis_sclfctr(:) = (/ 1.65E-05_r8, 0.011_r8, 0.989_r8 /) ! Aitken dust
131 0 : else if( ntot_amode == 7 ) then
132 0 : dust_dmt_grd(:) = (/ 0.1e-6_r8, 2.0e-6_r8, 10.0e-6_r8/)
133 0 : dust_emis_sclfctr(:) = (/ 0.13_r8, 0.87_r8 /)
134 : endif
135 :
136 : ndx = 0
137 7680 : do mm = 1, ntot_amode
138 6144 : m = mymodes(mm)
139 6144 : call rad_cnst_get_info(0, m, nspec=nspec)
140 30720 : do l = 1, nspec
141 23040 : call rad_cnst_get_info(0, m, l, spec_name=spec_name )
142 29184 : if (spec_name(:3) == 'dst') then
143 4608 : ndx=ndx+1
144 4608 : dust_names(ndx) = spec_name
145 4608 : dust_names(ndst+ndx) = 'num_'//spec_name(5:)
146 4608 : call cnst_get_ind(dust_names( ndx), dust_indices( ndx))
147 4608 : call cnst_get_ind(dust_names(ndst+ndx), dust_indices(ndst+ndx))
148 : endif
149 : enddo
150 : enddo
151 :
152 1536 : dust_active = any(dust_indices(:) > 0)
153 1536 : if (.not.dust_active) return
154 :
155 1536 : if (is_zender_soil_erod_from_atm()) then
156 0 : call soil_erod_init( dust_emis_fact, soil_erod_file )
157 : end if
158 :
159 1536 : call dust_set_params( dust_nbin, dust_dmt_grd, dust_dmt_vwr, dust_stk_crc )
160 :
161 1536 : end subroutine dust_init
162 :
163 : !===============================================================================
164 : !===============================================================================
165 1489176 : subroutine dust_emis( ncol, lchnk, dust_flux_in, cflx, soil_erod )
166 : use soil_erod_mod, only : soil_erod_fact
167 1536 : use soil_erod_mod, only : soil_erodibility
168 : use mo_constants, only : dust_density
169 : use physconst, only : pi
170 :
171 : ! args
172 : integer, intent(in) :: ncol, lchnk
173 : real(r8), intent(in) :: dust_flux_in(:,:)
174 : real(r8), intent(inout) :: cflx(:,:)
175 : real(r8), intent(out) :: soil_erod(:)
176 :
177 : ! local vars
178 : integer :: i, m, idst, inum
179 : real(r8) :: x_mton
180 : real(r8),parameter :: soil_erod_threshold = 0.1_r8
181 :
182 : ! set dust emissions
183 :
184 1489176 : if (is_zender_soil_erod_from_atm()) then
185 0 : col_loop1: do i = 1,ncol
186 0 : soil_erod(i) = soil_erodibility( i, lchnk )
187 0 : if( soil_erod(i) .lt. soil_erod_threshold ) soil_erod(i) = 0._r8
188 :
189 : ! rebin and adjust dust emissons.
190 0 : do m = 1,dust_nbin
191 0 : idst = dust_indices(m)
192 0 : cflx(i,idst) = sum( -dust_flux_in(i,:) ) &
193 0 : * dust_emis_sclfctr(m)*soil_erod(i)/dust_emis_fact*1.15_r8
194 0 : x_mton = 6._r8 / (pi * dust_density * (dust_dmt_vwr(m)**3._r8))
195 0 : inum = dust_indices(m+dust_nbin)
196 0 : cflx(i,inum) = cflx(i,idst)*x_mton
197 : enddo
198 : enddo col_loop1
199 : else ! Leung emissions
200 :
201 24865776 : col_loop2: do i = 1,ncol
202 : ! rebin and adjust dust emissons.
203 94995576 : do m = 1,dust_nbin
204 70129800 : idst = dust_indices(m)
205 :
206 140259600 : cflx(i,idst) = sum( -dust_flux_in(i,:) ) &
207 490908600 : * dust_emis_sclfctr(m) / dust_emis_fact
208 70129800 : x_mton = 6._r8 / (pi * dust_density * (dust_dmt_vwr(m)**3._r8))
209 70129800 : inum = dust_indices(m+dust_nbin)
210 93506400 : cflx(i,inum) = cflx(i,idst)*x_mton
211 : enddo
212 : enddo col_loop2
213 : end if
214 :
215 1489176 : end subroutine dust_emis
216 :
217 : end module dust_model
|