emission_dms.F90 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743
  1. !
  2. #define TRACEBACK write (gol,'("in ",a," (",a,", line",i5,")")') rname, __FILE__, __LINE__; call goErr
  3. #define IF_NOTOK_RETURN(action) if (status/=0) then; TRACEBACK; action; return; end if
  4. #define IF_ERROR_RETURN(action) if (status> 0) then; TRACEBACK; action; return; end if
  5. !
  6. #include "tm5.inc"
  7. !
  8. !-----------------------------------------------------------------------------
  9. ! TM5 !
  10. !-----------------------------------------------------------------------------
  11. !BOP
  12. !
  13. ! !MODULE: EMISSION_DMS
  14. !
  15. ! !DESCRIPTION:
  16. !\\
  17. !\\
  18. ! !INTERFACE:
  19. !
  20. MODULE EMISSION_DMS
  21. !
  22. ! !USES:
  23. !
  24. use GO, only : gol, goErr, goPr
  25. use tm5_distgrid, only : dgrid, get_distgrid, scatter, gather
  26. use partools, only : isRoot
  27. use dims, only : nregions
  28. use global_types, only : emis_data, d3_data
  29. IMPLICIT NONE
  30. PRIVATE
  31. !
  32. ! !PUBLIC MEMBER FUNCTIONS:
  33. !
  34. public :: emission_dms_init ! allocate
  35. public :: emission_dms_declare ! read monthly input
  36. public :: emission_dms_apply ! distribute & add emissions to tracer array
  37. public :: emission_dms_done ! deallocate
  38. public :: getDMS ! compute DMS from ocean
  39. !
  40. ! !PRIVATE DATA MEMBERS:
  41. !
  42. character(len=*), parameter :: mname = 'emission_dms'
  43. type(emis_data), dimension(nregions), target :: dms_land, dms_sea ! land and sea flux
  44. type(emis_data), dimension(nregions), target :: dms_tool ! work array
  45. real, dimension(:,:), allocatable :: dms_conc ! 1x1 ocean concentrations (nmol/L)
  46. ! The original calculation of the ocean DMS source was based on:
  47. ! - Climatology of sea water concentrations from Kettle et al., GBC, 1999
  48. ! - Exchange rate based on piston velocity from Liss and Merlivat, 1986
  49. ! (Air-sea gas exchange rates: Introduction and synthesis,
  50. ! The Role of Air-Sea Exchange in Geochemical Cycling,
  51. ! P. B. Menard, 113–127, D. Reidel, Norwell, Mass.)
  52. ! - The assumption that below -20 degrees C, there is 100% ice cover
  53. ! The updated scheme instead uses:
  54. ! - Climatology of sea water concentrations from Lana et al., GBC, 2011
  55. ! - Exchange rate based on piston velocity from Wanninkhof et al., 2014.
  56. ! - Masking of emissions based on fractional ice cover directly
  57. !
  58. ! Optionally, it is possible to calculate the Schmidt number
  59. ! based on the actual sea surface temperature
  60. ! instead of the 2-m air temperature.
  61. ! However, approximating SST by t2m
  62. ! has only a small impact on the results:
  63. ! In a simulation driven by ERA-Interim for the year 2010,
  64. ! it reduces the global annual source of DMS by -2.3%,
  65. ! while the pattern remains nearly identical.
  66. ! For practical reasons (in particular because the current set of
  67. ! fields received in EC-Earth does not include SST),
  68. ! the 2-m temperature is therefore used by default,
  69. ! also in the new implementation.
  70. !
  71. ! We have also kept another simplification of the original implementations:
  72. ! - The sea water concentrations change discontinuously
  73. ! from month to month, following the input climatology.
  74. ! This could be improved by applying a linear interpolation
  75. ! between consecutive month.
  76. ! Given the short lifetimes of DMS and SO2 (on the order of a day),
  77. ! this may have a (small) impact on sulfate production.
  78. !
  79. ! The new scheme is turned on by default.
  80. ! For testing purposes, one can revert to the old scheme by setting use_old to true.
  81. logical, parameter :: use_old = .false. ! default value
  82. !logical, parameter :: use_old = .true. ! testing only
  83. !
  84. ! !REVISION HISTORY:
  85. ! 1 Oct 2010 - Achim Strunk - standardized routines name, new apply method
  86. ! 22 Jun 2012 - Ph. Le Sager - adapted for lon-lat MPI domain decomposition
  87. !
  88. ! !REMARKS:
  89. ! (1) see getDMS
  90. !
  91. !EOP
  92. !------------------------------------------------------------------------
  93. CONTAINS
  94. !--------------------------------------------------------------------------
  95. ! TM5 !
  96. !--------------------------------------------------------------------------
  97. !BOP
  98. !
  99. ! !IROUTINE: EMISSION_DMS_INIT
  100. !
  101. ! !DESCRIPTION: Allocate space needed to handle the emissions.
  102. !\\
  103. !\\
  104. ! !INTERFACE:
  105. !
  106. SUBROUTINE EMISSION_DMS_INIT( status )
  107. !
  108. ! !USES:
  109. !
  110. use dims, only : im, jm, iglbsfc
  111. !
  112. ! !OUTPUT PARAMETERS:
  113. !
  114. integer, intent(out) :: status
  115. !
  116. ! !REVISION HISTORY:
  117. ! 1 Oct 2010 - Achim Strunk - extracted from old 'declare' routine
  118. ! 22 Jun 2012 - Ph. Le Sager - adapted for lon-lat MPI domain decomposition
  119. !
  120. !EOP
  121. !------------------------------------------------------------------------
  122. !BOC
  123. character(len=*), parameter :: rname = mname//'/Emission_DMS_Init'
  124. integer :: region
  125. integer :: imr, jmr, i1, i2, j1, j2
  126. ! --- begin --------------------------------------
  127. CALL GET_DISTGRID( dgrid(iglbsfc), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  128. allocate( dms_conc(i1:i2, j1:j2) )
  129. do region = 1, nregions
  130. CALL GET_DISTGRID( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  131. imr = im(region) ; jmr = jm(region)
  132. allocate(dms_land(region)%surf(i1:i2,j1:j2))
  133. allocate(dms_sea (region)%surf(i1:i2,j1:j2))
  134. ! work array used in coarsen/scatter
  135. if (isRoot) then
  136. allocate(dms_tool(region)%surf(imr, jmr ))
  137. else
  138. allocate(dms_tool(region)%surf(1, 1))
  139. end if
  140. enddo
  141. status = 0
  142. END SUBROUTINE EMISSION_DMS_INIT
  143. !EOC
  144. !--------------------------------------------------------------------------
  145. ! TM5 !
  146. !--------------------------------------------------------------------------
  147. !BOP
  148. !
  149. ! !IROUTINE: EMISSION_DMS_DONE
  150. !
  151. ! !DESCRIPTION: Deallocate space needed to handle the emissions.
  152. !\\
  153. !\\
  154. ! !INTERFACE:
  155. !
  156. SUBROUTINE EMISSION_DMS_DONE( status )
  157. !
  158. ! !OUTPUT PARAMETERS:
  159. !
  160. integer, intent(out) :: status
  161. !
  162. ! !REVISION HISTORY:
  163. ! 1 Oct 2010 - Achim Strunk - rename old 'free_emission_dms'
  164. !
  165. !EOP
  166. !------------------------------------------------------------------------
  167. !BOC
  168. character(len=*), parameter :: rname = mname//'/Emission_DMS_Done'
  169. integer :: region
  170. ! --- begin ---------------------------------
  171. do region = 1, nregions
  172. deallocate( dms_land (region)%surf)
  173. deallocate( dms_tool (region)%surf)
  174. deallocate( dms_sea (region)%surf)
  175. end do
  176. deallocate(dms_conc)
  177. status = 0
  178. END SUBROUTINE EMISSION_DMS_DONE
  179. !EOC
  180. !--------------------------------------------------------------------------
  181. ! TM5 !
  182. !--------------------------------------------------------------------------
  183. !BOP
  184. !
  185. ! !IROUTINE: EMISSION_DMS_DECLARE
  186. !
  187. ! !DESCRIPTION: Opens, reads and evaluates input files (per month).
  188. ! Land surface fluxes from vegetation and soils
  189. ! are based on the dataset from Spiro et al. (JGR, 1992).
  190. ! Ocean concentrations are used to retrieve fluxes by
  191. ! temperature and wind speed.
  192. ! Emissions from biomass burning are provided for CMIP6
  193. ! but have not been included, because their contribution
  194. ! is likely very small. It would require extra coding
  195. ! to include these.
  196. !\\
  197. !\\
  198. ! !INTERFACE:
  199. !
  200. SUBROUTINE EMISSION_DMS_DECLARE( status )
  201. !
  202. ! !USES:
  203. !
  204. USE MDF, ONLY : MDF_Open, MDF_HDF4, MDF_READ, MDF_Get_Var, MDF_Close
  205. USE MDF, ONLY : MDF_NETCDF, MDF_Inq_VarID
  206. use toolbox, only : coarsen_emission
  207. use dims, only : idate, sec_month, sec_year, iglbsfc, nlat180, nlon360
  208. use chem_param, only : xms
  209. use emission_data, only : msg_emis, emis_input_dir_dms
  210. !
  211. ! !OUTPUT PARAMETERS:
  212. !
  213. integer, intent(out) :: status
  214. !
  215. ! !REVISION HISTORY:
  216. ! 1 Oct 2010 - Achim Strunk - updated to emission standard
  217. ! 22 Jun 2012 - Ph. Le Sager - adapted for lon-lat MPI domain decomposition
  218. !
  219. !EOP
  220. !------------------------------------------------------------------------
  221. !BOC
  222. character(len=*), parameter :: rname = mname//'/declare_emission_dms'
  223. integer :: region, i1, i2, j1, j2, nlatsrc, nlonsrc
  224. integer, parameter :: add_field=0
  225. integer, parameter :: amonth=2
  226. real :: year2month
  227. integer :: hid, varid
  228. ! work array on 1x1 resolution
  229. real, dimension(:,:), allocatable :: glb_dms_conc
  230. ! --- begin ---------------------------------
  231. year2month = sec_month/sec_year ! scale factor for yearly total to specific month
  232. nlatsrc = nlat180 ! or dgrid(iglbsfc)%jm_region, accessible thru get_distgrid(...)
  233. nlonsrc = nlon360 ! or dgrid(iglbsfc)%im_region, accessible thru get_distgrid(...)
  234. ! to deal with sea water at 1x1
  235. if(isRoot)then
  236. allocate(glb_dms_conc(nlonsrc,nlatsrc))
  237. else
  238. allocate(glb_dms_conc(1,1))
  239. end if
  240. !
  241. ! DMS emissions from landsurface
  242. ! DMS seawater concentrations. The actual flux is a function of windspeed and temperature
  243. ! and is calculated each time step. The resolution dependency needs to be checked.
  244. ! We will use the 10m winds on 1x1 resolution.....
  245. !
  246. write(gol,'(" EMISS-INFO ------------- read DMS emissions -------------")'); call goPr
  247. if (isRoot) then
  248. ! monthly emissions from Land Spiro dataset
  249. CALL MDF_Open( trim(emis_input_dir_dms)//'/DMSland.hdf', MDF_HDF4, MDF_READ, hid, status )
  250. IF_NOTOK_RETURN(status=1)
  251. CALL MDF_Get_Var( hid, idate(2), glb_dms_conc, status )
  252. IF_NOTOK_RETURN(status=1)
  253. CALL MDF_Close( hid, status )
  254. IF_NOTOK_RETURN(status=1)
  255. call msg_emis(amonth, 'SPIRO', 'vegetation/soil', 'DMS', xms, sum(glb_dms_conc))
  256. call coarsen_emission('dms_land', nlonsrc, nlatsrc, glb_dms_conc, dms_tool, add_field, status)
  257. IF_NOTOK_RETURN(status=1)
  258. ! seawater concentrations
  259. if (use_old) then
  260. CALL MDF_Open( trim(emis_input_dir_dms)//'/DMSconc.hdf', MDF_HDF4, MDF_READ, hid, status )
  261. IF_NOTOK_RETURN(status=1)
  262. CALL MDF_Get_Var( hid, idate(2), glb_dms_conc, status )
  263. IF_NOTOK_RETURN(status=1)
  264. else
  265. CALL MDF_Open( trim(emis_input_dir_dms)//'/DMS_ocean_conc.nc', MDF_NETCDF, MDF_READ, hid, status )
  266. IF_NOTOK_RETURN(status=1)
  267. CALL MDF_Inq_VarID( hid, trim('DMS'), varid, status )
  268. IF_ERROR_RETURN(status=1)
  269. CALL MDF_Get_Var( hid, varid, glb_dms_conc, status, start=(/1,1,idate(2)/) )
  270. IF_NOTOK_RETURN(status=1)
  271. endif
  272. CALL MDF_Close( hid, status )
  273. IF_NOTOK_RETURN(status=1)
  274. end if
  275. do region = 1, nregions
  276. call scatter(dgrid(region), dms_land(region)%surf, dms_tool(region)%surf, 0, status)
  277. IF_NOTOK_RETURN(status=1)
  278. end do
  279. call scatter(dgrid(iglbsfc), dms_conc, glb_dms_conc, 0, status)
  280. IF_NOTOK_RETURN(status=1)
  281. deallocate(glb_dms_conc)
  282. ! ok
  283. status = 0
  284. END SUBROUTINE EMISSION_DMS_DECLARE
  285. !EOC
  286. !--------------------------------------------------------------------------
  287. ! TM5 !
  288. !--------------------------------------------------------------------------
  289. !BOP
  290. !
  291. ! !IROUTINE: EMISSION_DMS_APPLY
  292. !
  293. ! !DESCRIPTION: Take monthly emissions, and
  294. ! - split them vertically
  295. ! - apply time splitting factors
  296. ! - add them up (add_3d)
  297. !\\
  298. !\\
  299. ! !INTERFACE:
  300. !
  301. SUBROUTINE EMISSION_DMS_APPLY( region, status )
  302. !
  303. ! !USES:
  304. !
  305. use dims, only : okdebug, itaur, nsrce, tref
  306. use dims, only : im, jm, lm
  307. use datetime, only : tau2date
  308. use emission_data, only : emission_vdist_by_sector
  309. use emission_data, only : do_add_3d
  310. use chem_param, only : idms, xmdms, xms
  311. use emission_data, only : vd_class_name_len
  312. !
  313. ! !INPUT PARAMETERS:
  314. !
  315. integer, intent(in) :: region
  316. !
  317. ! !OUTPUT PARAMETERS:
  318. !
  319. integer, intent(out) :: status
  320. !
  321. ! !REVISION HISTORY:
  322. ! 1 Oct 2010 - Achim Strunk - updated to use new vertical distribution method
  323. ! 28 Mar 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  324. !
  325. !EOP
  326. !------------------------------------------------------------------------
  327. !BOC
  328. character(len=*), parameter :: rname = mname//'/emission_dms_apply'
  329. integer,dimension(6) :: idater
  330. real :: dtime, fraction
  331. integer :: imr, jmr, lmr, i1, i2, j1, j2
  332. type(d3_data) :: emis3d
  333. character(len=vd_class_name_len) :: splittype
  334. ! --- begin -----------------------------------------
  335. if( okdebug ) then
  336. write(gol,*) 'start of emission_dms_apply'; call goPr
  337. endif
  338. call tau2date(itaur(region),idater)
  339. dtime=float(nsrce)/(2*tref(region)) !emissions are added in two steps...XYZECCEZYX.
  340. if( okdebug ) then
  341. write(gol,*) 'emission_dms_apply in region ',region,' at date: ',idater, ' with time step:', dtime ; call goPr
  342. endif
  343. ! get a working structure for 3d emissions
  344. call get_distgrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  345. allocate( emis3d%d3(i1:i2,j1:j2,lm(region)) ) ; emis3d%d3 = 0.0
  346. ! default: no additional splitting
  347. fraction = 1.0
  348. ! ----------------------------------------------------------------------------------------
  349. ! distinguish here between sectors and whether they should have additional splitting
  350. ! if( ar5_sectors(lsec)%catname == 'biomassburning' ) fraction = fraction * bb_frac etc...
  351. ! ----------------------------------------------------------------------------------------
  352. splittype = 'surface'
  353. ! -------
  354. ! dms sea
  355. ! -------
  356. ! vertically distribute according to sector
  357. call emission_vdist_by_sector( splittype, 'DMS', region, dms_sea(region), emis3d, status )
  358. IF_NOTOK_RETURN(status=1;deallocate(emis3d%d3))
  359. ! add dataset
  360. call do_add_3d( region, idms, i1, j1, emis3d%d3, xmdms, xms, status, fraction )
  361. IF_NOTOK_RETURN(status=1)
  362. ! -------
  363. ! dms land
  364. ! -------
  365. emis3d%d3 = 0.0
  366. ! vertically distribute according to sector
  367. call emission_vdist_by_sector( splittype, 'DMS', region, dms_land(region), emis3d, status )
  368. IF_NOTOK_RETURN(status=1;deallocate(emis3d%d3))
  369. ! add dataset
  370. call do_add_3d( region, idms, i1, j1, emis3d%d3, xmdms, xms, status, fraction )
  371. IF_NOTOK_RETURN(status=1)
  372. if( okdebug ) then
  373. write(gol,*) 'end of emission_dms_apply'; call goPr
  374. endif
  375. deallocate( emis3d%d3 )
  376. ! OK
  377. status = 0
  378. END SUBROUTINE EMISSION_DMS_APPLY
  379. !EOC
  380. !--------------------------------------------------------------------------
  381. ! TM5 !
  382. !--------------------------------------------------------------------------
  383. !BOP
  384. !
  385. ! !IROUTINE: GETDMS
  386. !
  387. ! !DESCRIPTION: calculate the DMS flux based on high resolution ocean
  388. ! concentration and wind speeds and temperatures,
  389. ! and calculate the 'coarser' resolution fluxes from it
  390. !
  391. ! input needed: U2 and T2 on 1x1
  392. !\\
  393. !\\
  394. ! !INTERFACE:
  395. !
  396. SUBROUTINE GETDMS( status )
  397. !
  398. ! !USES:
  399. !
  400. use toolbox, only : coarsen_emission
  401. use binas, only : T0
  402. use meteodata, only : t2m_dat, u10m_dat, v10m_dat
  403. use meteodata, only : ci_dat, lsmask_dat, sst_dat
  404. use datetime, only : tau2date
  405. use Dims, only : itau, staggered, sec_year, sec_month, dxy11, iglbsfc, im, jm
  406. use chem_param, only : xms
  407. !
  408. ! !OUTPUT PARAMETERS:
  409. !
  410. integer, intent(out) :: status
  411. !
  412. ! !REVISION HISTORY:
  413. ! 22 Jun 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  414. !
  415. ! !REMARKS:
  416. ! (1) Required inputs: U2 and T2 on 1x1
  417. !
  418. !EOP
  419. !------------------------------------------------------------------------
  420. !BOC
  421. character(len=*), parameter :: rname = mname//'/getdms'
  422. real, dimension(:,:), allocatable :: emi_dms, emis_glb, u_wind, v_wind, temperature
  423. real :: xwind, zschmidt, resfac, tot_flux, kw, tt, xlon, xlat, piston_dms
  424. real :: prefac, norm, xsea, area_frac, emis_fac, k660, tt2
  425. integer :: i, j, l, region, i1, j1, i2, j2
  426. integer, dimension(6) :: idates
  427. integer, parameter :: level1=1, add_field=0
  428. integer :: nlatsrc, nlonsrc
  429. ! determine correction factor to account for less effective mixing
  430. ! at lower averaged windspeeds occuring at lower resolution
  431. CALL GET_DISTGRID( dgrid(iglbsfc), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  432. nlatsrc = jm(iglbsfc) ! or nlat180, or dgrid(iglbsfc)%jm_region, accessible thru get_distgrid(...)
  433. nlonsrc = im(iglbsfc) ! or nlon360, or dgrid(iglbsfc)%jm_region, accessible thru get_distgrid(...)
  434. if (iglbsfc /= 1) then ! assume no zoom region if region #1 is at 1x1 (see below)
  435. if (isRoot)then
  436. allocate(emis_glb (nlonsrc,nlatsrc))
  437. else
  438. allocate(emis_glb (1,1))
  439. end if
  440. end if
  441. allocate(emi_dms (i1:i2, j1:j2))
  442. allocate(u_wind (i1:i2, j1:j2))
  443. allocate(v_wind (i1:i2, j1:j2))
  444. allocate(temperature(i1:i2, j1:j2))
  445. call tau2date(itau+staggered,idates) !CMK at end 3-hourly interval
  446. if (use_old) then
  447. ! would be better to use SST in the old scheme also
  448. ! but using air temperature allows to reproduce the old implementation
  449. temperature = t2m_dat(iglbsfc)%data(:,:,1)
  450. else
  451. ! Choose either SST or 2-m air temperature
  452. ! If SST is used, it has to be set in sources_sinks.F90
  453. !temperature = sst_dat(iglbsfc)%data(:,:,1)
  454. temperature = t2m_dat(iglbsfc)%data(:,:,1)
  455. endif
  456. ! convert to celsius
  457. temperature = temperature - T0
  458. u_wind = u10m_dat(iglbsfc)%data(:,:,1)
  459. v_wind = v10m_dat(iglbsfc)%data(:,:,1)
  460. ! Resolution dependent tuning factor
  461. ! that can be used to account for variability in wind speed
  462. ! Currently set to 1.
  463. resfac=1.
  464. if (use_old) then
  465. ! THE RESOLUTION DEPENDENCY WITH PREVIOUS TM3 RUNS WAS AS FOLLOWS
  466. ! NEEDS TO BE CHECKED FD
  467. !FD if (jm.eq.24) resfac=1.32
  468. !FD if (jm.eq.48) resfac=1.065
  469. emi_dms=0.
  470. do j=j1,j2
  471. do i=i1,i2
  472. !
  473. ! ocean surface temperature is approximated by air surface temperature
  474. ! we assume that if temperature<-20. ! sea ice prevents DMS emissions (sea-ice data from ECMWF would be usefull)
  475. ! max ocean temperature is 28.0 C
  476. ! minumum ocean temperature 0. C
  477. !fd tt=min(28.,ts(i,j)-273.15) ! the original parameterisation needs the seawater temperature
  478. ! as a proxy we use the air temperature, but restrict it to 28 C.
  479. ! surface or 2m temperature of air is probably the best proxy.
  480. tt=min(28.0,temperature(i,j))
  481. if (dms_conc(i,j).gt.0..and.tt.gt.-20.) then
  482. ! TvN: don't know where this expression comes from
  483. zschmidt=max(0.0,3652.047271-246.99*TT+8.536397*TT*TT-0.124397*TT*TT*TT)
  484. xwind=sqrt(u_wind(i,j)**2+v_wind(i,j)**2)
  485. !
  486. ! Liss and Merlivat windspeed dependency of transfer velocity kw
  487. ! including correction for Schmidt number
  488. ! windspeed at middle of gridbox is used should be 10 m windspeed [m/s]
  489. if (xwind.le.3.6) then
  490. kw=0.17*xwind
  491. piston_dms=kw*(zschmidt/600.)**(-0.666)
  492. else !xwind>3.6)
  493. if (xwind.le.13.0) then
  494. kw=2.85*xwind-9.65
  495. piston_dms=kw*(zschmidt/600.)**(-0.5)
  496. else !xwind>13.0
  497. kw=5.9*xwind-49.3
  498. piston_dms=kw*(zschmidt/600.)**(-0.5)
  499. endif !x<13.0
  500. endif
  501. !
  502. ! cm/hr=> m/s * nmol/l=>mol/m3 * m2 * g S/mol=>g S/s
  503. !
  504. emi_dms(i,j)=resfac*piston_dms/360000.*dms_conc(i,j)*1e-6*dxy11(j)*xms
  505. endif !(dms_conc gt 0)
  506. enddo
  507. enddo
  508. else
  509. ! New parameterization based on Lana et al. and Wanninkhof et al.
  510. emi_dms=0.
  511. ! 1.e-6 converts nmol/L to mol/m3
  512. ! 1.e-2/3600. converts cm/hr to m/s
  513. ! xms converts mol to g S
  514. prefac = resfac * 1.e-6 * xms * 1.e-2 / 3600.
  515. do j=j1,j2
  516. norm = prefac * dxy11(j)
  517. do i=i1,i2
  518. ! Undefined values in the original input files
  519. ! of the DMS sea water concentrations have been set to -1.e9.
  520. ! These should be excluded.
  521. ! Locations with zero concentrations can be excluded as well.
  522. if (dms_conc(i,j) <= 0. ) cycle
  523. ! sea fraction
  524. xsea=1.-lsmask_dat(iglbsfc)%data(i,j,1)/100.
  525. ! DMS is emitted only over sea without ice cover
  526. area_frac = xsea * (1.-ci_dat(iglbsfc)%data(i,j,1))
  527. if (area_frac .lt. 1.e-10 ) cycle
  528. emis_fac = norm * area_frac
  529. ! Wind speed dependence from Wanninkhof et al.,
  530. ! Limnology and Oceanography: Methods, 351-362, 2014.
  531. ! "It should provide good estimates for most insoluble
  532. ! gases at intermediate wind speed ranges (3-15 m s–1).
  533. ! At low winds, non-wind effects such as chemical enhancement
  534. ! and thermal boundary layer processes influence gas transfer,
  535. ! and this quadratic relationship will underestimate gas transfer.
  536. ! At high winds (≈> 15 m s–1), bubble-enhanced exchange will
  537. ! affect gases differently depending on their solubility,
  538. ! and the relationship is only suitable for CO2
  539. ! under these conditions.
  540. ! The differences in physical and chemical processes
  541. ! in boundary layers and their impact on gases at high and low winds
  542. ! need to be taken into consideration when estimating uncertainty.
  543. ! Since over 94% of the winds over the ocean are in the 3-15 m s–1 range,
  544. ! the regional and global gas transfer velocities
  545. ! for gases listed in Table 1 can be determined
  546. ! using the above relationship."
  547. k660 = 0.251 * (u_wind(i,j)**2 + v_wind(i,j)**2)
  548. ! where k660 is in units cm/h.
  549. ! We prefer this relation above that proposed
  550. ! by Nightingale et al. (Glob. Biogeochem. Cycl., 2000):
  551. ! k600 = 0.333 * u_10m + 0.222 * (u_10m)^2
  552. ! The presence of the linear term enhances the transfer coefficient
  553. ! at low wind speeds, but this regime is of minor importance.
  554. ! The relation by Wanninkhof gives a higher transfer coefficient
  555. ! at moderate to high wind speeds.
  556. ! Because wind speed tends to be underestimated
  557. ! because of the coarse horizontal resolution,
  558. ! this could be an argument to use the formulation
  559. ! by Wanninkhof et al., which is also more recent.
  560. ! In both formulations, the transfer coefficient depends on temperature
  561. ! as the square root of the Schmidt number.
  562. ! We calculate the Schmidt number based on the fourth-order polynomial fit
  563. ! given in Wanninkhof et al. (2014) for sea water at 3.5% salinity.
  564. ! It is based on the data by Saltzman et al. (JGR, 1993),
  565. ! but is applicable over over a wider range of temperatures (–2°C to 40°C)
  566. ! than the third-order polynomial proposed by Saltzman et al. (0°C and 30°C).
  567. ! At the high end, the fourth order polynomial only weakly depends
  568. ! on temperature, and reaches a minimum at 43.78°C.
  569. ! Since the increase thereafter falls outside the range of the fit,
  570. ! we set the Schmidt number at higher temperatures
  571. ! equal to the value at 43.78°C.
  572. !
  573. ! Using the temperature dependence from Wanninkhof et al.,
  574. ! the transfer coefficient increases by less than about 3.2%
  575. ! per degree temperature increase.
  576. tt=min(43.78,temperature(i,j))
  577. tt2=tt*tt
  578. zschmidt=2855.7-177.63*tt+6.0438*tt2-0.11645*tt2*tt+0.00094743*tt2*tt2
  579. kw = k660 * (660./zschmidt)**0.5
  580. ! "DMS fluxes are generally parameterized assuming water side resitance only,
  581. ! but air side resistance can also be significant at cold temperatures
  582. ! and high wind speeds." (Lana et al.)
  583. ! Here the air side resistance is neglected:
  584. piston_dms = kw
  585. emi_dms(i,j)=emis_fac*piston_dms*dms_conc(i,j)
  586. enddo
  587. enddo
  588. endif
  589. !-----------------------------------------------------------
  590. ! Fill target array
  591. !-----------------------------------------------------------
  592. ! Test for optimization: if region #1 is at 1x1, assume no zoom region and skip call to coarsen and mpi comm
  593. if (iglbsfc == 1) then
  594. dms_sea(1)%surf = emi_dms*sec_month*1e-3 !expected in kgS/month
  595. else
  596. !-----------------------------------------------------------
  597. ! gather on 1x1, coarsen to other grid on root, then scatter
  598. !-----------------------------------------------------------
  599. ! FIXME-PERF : Need a coarsen that works independtly on each proc
  600. call gather(dgrid(iglbsfc), emi_dms, emis_glb, 0, status)
  601. IF_NOTOK_RETURN(status=1)
  602. if (isRoot) then
  603. ! FIXME : if really needed, write into budget - here, it gives too much output
  604. !write(gol,*)'the yearly sum of GETDMS would be ',sum(emis_glb) *1e-12*sec_year,' Tg S/a'; call goPr
  605. ! assume equal emissions over season
  606. call coarsen_emission('emi_dms', nlonsrc, nlatsrc, emis_glb, dms_tool, add_field, status)
  607. IF_NOTOK_RETURN(status=1)
  608. end if
  609. do region = 1, nregions
  610. call scatter(dgrid(region), dms_sea(region)%surf, dms_tool(region)%surf, 0, status)
  611. IF_NOTOK_RETURN(status=1)
  612. dms_sea(region)%surf = dms_sea(region)%surf*sec_month*1e-3 !expected in kgS/month
  613. enddo
  614. deallocate(emis_glb)
  615. end if
  616. !-----------------------------------------------------------
  617. deallocate(emi_dms)
  618. deallocate(temperature)
  619. deallocate(u_wind)
  620. deallocate(v_wind)
  621. END SUBROUTINE GETDMS
  622. !EOC
  623. END MODULE EMISSION_DMS