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 :
10 : implicit none
11 : private
12 :
13 : public :: dust_names
14 : public :: dust_nbin
15 : public :: dust_nnum
16 : public :: dust_indices
17 : public :: dust_emis
18 : public :: dust_readnl
19 : public :: dust_init
20 : public :: dust_active
21 :
22 : integer, protected :: dust_nbin != 2
23 : integer, protected :: dust_nnum != 2
24 : character(len=6), protected, allocatable :: dust_names(:)
25 :
26 : real(r8), allocatable :: dust_dmt_grd(:)
27 : real(r8), allocatable :: dust_emis_sclfctr(:)
28 :
29 : integer , protected, allocatable :: dust_indices(:)
30 : real(r8), allocatable :: dust_dmt_vwr(:)
31 : real(r8), allocatable :: dust_stk_crc(:)
32 :
33 : real(r8) :: dust_emis_fact = -1.e36_r8 ! tuning parameter for dust emissions
34 : character(len=cl) :: soil_erod_file = 'soil_erod_file' ! full pathname for soil erodibility dataset
35 :
36 : logical :: dust_active = .false.
37 :
38 : contains
39 :
40 : !=============================================================================
41 : ! reads dust namelist options
42 : !=============================================================================
43 1536 : subroutine dust_readnl(nlfile)
44 :
45 : use namelist_utils, only: find_group_name
46 : use units, only: getunit, freeunit
47 : use mpishorthand
48 :
49 : character(len=*), intent(in) :: nlfile ! filepath for file containing namelist input
50 :
51 : ! Local variables
52 : integer :: unitn, ierr
53 : character(len=*), parameter :: subname = 'dust_readnl'
54 :
55 : namelist /dust_nl/ dust_emis_fact, soil_erod_file
56 :
57 : !-----------------------------------------------------------------------------
58 :
59 : ! Read namelist
60 1536 : if (masterproc) then
61 2 : unitn = getunit()
62 2 : open( unitn, file=trim(nlfile), status='old' )
63 2 : call find_group_name(unitn, 'dust_nl', status=ierr)
64 2 : if (ierr == 0) then
65 2 : read(unitn, dust_nl, iostat=ierr)
66 2 : if (ierr /= 0) then
67 0 : call endrun(subname // ':: ERROR reading namelist')
68 : end if
69 : end if
70 2 : close(unitn)
71 2 : call freeunit(unitn)
72 : end if
73 :
74 : #ifdef SPMD
75 : ! Broadcast namelist variables
76 1536 : call mpibcast(dust_emis_fact, 1, mpir8, 0, mpicom)
77 1536 : call mpibcast(soil_erod_file, len(soil_erod_file), mpichar, 0, mpicom)
78 : #endif
79 :
80 1536 : end subroutine dust_readnl
81 :
82 : !=============================================================================
83 : !=============================================================================
84 1536 : subroutine dust_init()
85 : use soil_erod_mod, only: soil_erod_init
86 : use constituents, only: cnst_get_ind
87 : use rad_constituents, only: rad_cnst_get_info
88 : use dust_common, only: dust_set_params
89 :
90 : integer :: l, m, mm, ndx, nspec
91 : character(len=32) :: spec_name
92 : integer, parameter :: mymodes(7) = (/ 2, 1, 3, 4, 5, 6, 7 /) ! tricky order ...
93 :
94 1536 : dust_nbin = ndst
95 1536 : dust_nnum = ndst
96 :
97 4608 : allocate( dust_names(2*ndst) )
98 4608 : allocate( dust_indices(2*ndst) )
99 4608 : allocate( dust_dmt_grd(ndst+1) )
100 4608 : allocate( dust_emis_sclfctr(ndst) )
101 3072 : allocate( dust_dmt_vwr(ndst) )
102 3072 : allocate( dust_stk_crc(ndst) )
103 :
104 1536 : if ( ntot_amode == 3 ) then
105 0 : dust_dmt_grd(:) = (/ 0.1e-6_r8, 1.0e-6_r8, 10.0e-6_r8/)
106 0 : dust_emis_sclfctr(:) = (/ 0.011_r8,0.989_r8 /)
107 1536 : elseif ( ntot_amode == 4 .or. ntot_amode == 5 ) then
108 7680 : dust_dmt_grd(:) = (/ 0.01e-6_r8, 0.1e-6_r8, 1.0e-6_r8, 10.0e-6_r8 /) ! Aitken dust
109 6144 : dust_emis_sclfctr(:) = (/ 1.65E-05_r8, 0.011_r8, 0.989_r8 /) ! Aitken dust
110 0 : else if( ntot_amode == 7 ) then
111 0 : dust_dmt_grd(:) = (/ 0.1e-6_r8, 2.0e-6_r8, 10.0e-6_r8/)
112 0 : dust_emis_sclfctr(:) = (/ 0.13_r8, 0.87_r8 /)
113 : endif
114 :
115 : ndx = 0
116 7680 : do mm = 1, ntot_amode
117 6144 : m = mymodes(mm)
118 6144 : call rad_cnst_get_info(0, m, nspec=nspec)
119 30720 : do l = 1, nspec
120 23040 : call rad_cnst_get_info(0, m, l, spec_name=spec_name )
121 29184 : if (spec_name(:3) == 'dst') then
122 4608 : ndx=ndx+1
123 4608 : dust_names(ndx) = spec_name
124 4608 : dust_names(ndst+ndx) = 'num_'//spec_name(5:)
125 4608 : call cnst_get_ind(dust_names( ndx), dust_indices( ndx))
126 4608 : call cnst_get_ind(dust_names(ndst+ndx), dust_indices(ndst+ndx))
127 : endif
128 : enddo
129 : enddo
130 :
131 1536 : dust_active = any(dust_indices(:) > 0)
132 1536 : if (.not.dust_active) return
133 :
134 1536 : call soil_erod_init( dust_emis_fact, soil_erod_file )
135 :
136 1536 : call dust_set_params( dust_nbin, dust_dmt_grd, dust_dmt_vwr, dust_stk_crc )
137 :
138 1536 : end subroutine dust_init
139 :
140 : !===============================================================================
141 : !===============================================================================
142 58824 : subroutine dust_emis( ncol, lchnk, dust_flux_in, cflx, soil_erod )
143 1536 : use soil_erod_mod, only : soil_erod_fact
144 : use soil_erod_mod, only : soil_erodibility
145 : use mo_constants, only : dust_density
146 : use physconst, only : pi
147 :
148 : ! args
149 : integer, intent(in) :: ncol, lchnk
150 : real(r8), intent(in) :: dust_flux_in(:,:)
151 : real(r8), intent(inout) :: cflx(:,:)
152 : real(r8), intent(out) :: soil_erod(:)
153 :
154 : ! local vars
155 : integer :: i, m, idst, inum
156 : real(r8) :: x_mton
157 : real(r8),parameter :: soil_erod_threshold = 0.1_r8
158 :
159 : ! set dust emissions
160 :
161 982224 : col_loop: do i =1,ncol
162 :
163 923400 : soil_erod(i) = soil_erodibility( i, lchnk )
164 :
165 923400 : if( soil_erod(i) .lt. soil_erod_threshold ) soil_erod(i) = 0._r8
166 :
167 : ! rebin and adjust dust emissons..
168 3752424 : do m = 1,dust_nbin
169 :
170 2770200 : idst = dust_indices(m)
171 :
172 2770200 : cflx(i,idst) = sum( -dust_flux_in(i,:) ) &
173 16621200 : * dust_emis_sclfctr(m)*soil_erod(i)/soil_erod_fact*1.15_r8
174 :
175 2770200 : x_mton = 6._r8 / (pi * dust_density * (dust_dmt_vwr(m)**3._r8))
176 :
177 2770200 : inum = dust_indices(m+dust_nbin)
178 :
179 3693600 : cflx(i,inum) = cflx(i,idst)*x_mton
180 :
181 : enddo
182 :
183 : end do col_loop
184 :
185 58824 : end subroutine dust_emis
186 :
187 : end module dust_model
|