boundary.F90 58 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560
  1. #define TRACEBACK write (gol,'("in ",a," (",a,", line",i5,")")') rname, __FILE__, __LINE__; call goErr
  2. #define IF_NOTOK_RETURN(action) if (status/=0) then; TRACEBACK; action; return; end if
  3. #define IF_ERROR_RETURN(action) if (status> 0) then; TRACEBACK; action; return; end if
  4. #include "tm5.inc"
  5. !-----------------------------------------------------------------------------
  6. ! TM5 !
  7. !-----------------------------------------------------------------------------
  8. !BOP
  9. !
  10. ! !MODULE: BOUNDARY
  11. !
  12. ! !DESCRIPTION: Set up boundary conditions:
  13. !
  14. ! O3, O3S and CH4 are relaxed to climatology at stratospheric layers
  15. !
  16. ! For O3: MSR2 = Multi Sensor Reanalysis v2
  17. ! Source MSR : www.temis.nl; Allaart, van der A, manuscript in preparation, 2009)
  18. ! Source MSR2: FIXME
  19. !
  20. ! For CH4 we use Climatology HALOE CH4, October 1991 to August 2002 by:
  21. ! Technical note: A stratospheric climatology for O3, H2O, CH4, NOx, HCl
  22. ! and HF derived from HALOE measurements by J.-U. Grooss and J. M.
  23. ! Russell III, Atmospheric Chemistry and Physics, 5, 2797-2807, 2005
  24. ! SRef-ID: 1680-7324/acp/2005-5-2797
  25. !
  26. ! HNO3 is prescribed at level lm using HNO3:03 ratios from ODIN (fallback on UARS).
  27. !
  28. ! CO is nudged using the ODIN ratio of CO/O3 @ 3 levels (JEW, 2014).
  29. !
  30. ! Note about ODIN datasets: a slow relaxation between monthly mean values
  31. ! is incorporated to improve on the large variability which exists between
  32. ! consecutive months (JEW, 2014).
  33. !\\
  34. !\\
  35. ! !INTERFACE:
  36. !
  37. MODULE BOUNDARY
  38. !
  39. ! !USES:
  40. !
  41. USE GO, ONLY : gol, goPr, goErr, goLabel
  42. USE TM5_DISTGRID, ONLY : dgrid, Get_DistGrid, gather, scatter_i_band
  43. USE DIMS, ONLY : nregions, idate
  44. USE chem_param, ONLY : ntracet
  45. USE global_types, ONLY : d23_data, d3_data
  46. #ifdef with_budgets
  47. USE budget_global, ONLY : nbudg, nbud_vg, nzon_vg, budg_dat
  48. #endif
  49. IMPLICIT NONE
  50. PRIVATE
  51. PUBLIC :: BOUNDARY_INIT, BOUNDARY_DONE, BOUNDARY_APPLY
  52. !
  53. ! !PUBLIC DATA MEMBERS:
  54. !
  55. LOGICAL, PUBLIC :: use_o3du
  56. TYPE(d23_data), PUBLIC :: o3du(nregions) ! optionally used in photolysis only
  57. !
  58. ! !PRIVATE DATA MEMBERS:
  59. !
  60. ! Flags for O3, CO and CH4 stratospheric nudging
  61. LOGICAL :: use_MSR
  62. LOGICAL :: use_HALOE
  63. LOGICAL :: use_ODIN
  64. character(len=256) :: o3vmr_dirname
  65. character(len=256) :: o3du_dirname
  66. character(len=256) :: ch4vmr_dirname
  67. character(len=256) :: covmr_dirname
  68. ! Volume Mixing Ratio and Ratio, and values in DU
  69. TYPE(d23_data) :: o3vmrpm(nregions)
  70. TYPE(d23_data) :: o3vmr(nregions)
  71. TYPE(d23_data) :: o3vmrnm(nregions)
  72. TYPE(d23_data) :: ch4vmrpm(nregions)
  73. TYPE(d23_data) :: ch4vmr(nregions)
  74. TYPE(d23_data) :: ch4vmrnm(nregions)
  75. TYPE(d23_data) :: o3ratpm(nregions)
  76. TYPE(d23_data) :: o3rat(nregions)
  77. TYPE(d23_data) :: o3ratnm(nregions)
  78. TYPE(d23_data) :: ch4ratpm(nregions)
  79. TYPE(d23_data) :: ch4rat(nregions)
  80. TYPE(d23_data) :: ch4ratnm(nregions)
  81. TYPE(d23_data) :: odin_hno3_o3(nregions) ! hno3/o3 ratio at 4 pressure levels
  82. TYPE(d23_data) :: odin_hno3_o3_pm(nregions) ! hno3/o3 ratio at 4 pressure levels (previous month)
  83. TYPE(d23_data) :: odin_hno3_o3_nm(nregions) ! hno3/o3 ratio at 4 pressure levels (next month)
  84. TYPE(d23_data) :: odin_co_o3(nregions) ! co/o3 ratio at 4 pressure levels
  85. TYPE(d23_data) :: odin_co_o3_pm(nregions) ! co/o3 ratio at 4 pressure levels (previous month)
  86. TYPE(d23_data) :: odin_co_o3_nm(nregions) ! co/o3 ratio at 4 pressure levels (next month)
  87. real, allocatable :: wrk2d_ML(:,:) ! 2D work array, model levels
  88. real, allocatable :: wrk2d_4L(:,:) ! 2D work array, 4 levels
  89. real, allocatable :: wrk3dpm_ML(:,:,:), wrk3d_ML(:,:,:), wrk3dnm_ML(:,:,:)! 3D work array, model levels
  90. real, allocatable :: wrk3dratio(:,:,:)
  91. real, allocatable :: wrk3dratiopm(:,:,:) ! for smoothing CO and HNO3 values at monthly scale
  92. real, allocatable :: wrk3drationm(:,:,:) ! for smoothing CO and HNO3 values at monthly scale
  93. #ifdef with_budgets
  94. ! REAL, DIMENSION(nregions) :: sum_stratosphere
  95. REAL, PUBLIC :: budstratg(nbudg, nbud_vg, ntracet)
  96. #endif
  97. integer :: itim_init, itim_appl ! Timers id
  98. CHARACTER(len=*), PARAMETER :: mname = 'boundary'
  99. !
  100. ! !REVISION HISTORY:
  101. ! 15 Jun 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  102. ! 03 Mar 2014 - J. E. Williams - added nudging for CO from ODIN measurements
  103. !
  104. ! !REMARKS:
  105. ! (1) All reference to sum_stratosphere have been commented, since the
  106. ! variable is neither printed nor saved nor used to compute something
  107. ! else.
  108. !EOP
  109. !------------------------------------------------------------------------
  110. CONTAINS
  111. !--------------------------------------------------------------------------
  112. ! TM5 !
  113. !--------------------------------------------------------------------------
  114. !BOP
  115. !
  116. ! !IROUTINE: BOUNDARY_INIT
  117. !
  118. ! !DESCRIPTION: Act as both INIT and MONTHLY_UPDATE methods.
  119. !
  120. ! As INIT : read settings from rc file & allocate data.
  121. ! As MONTHLY_UPDATE : read data in.
  122. !
  123. ! Called at run start and at start of every month (from
  124. ! sources_sinks/sources_sinks_init & ss_monthly_update).
  125. !\\
  126. !\\
  127. ! !INTERFACE:
  128. !
  129. SUBROUTINE BOUNDARY_INIT( first, status )
  130. !
  131. ! !USES:
  132. !
  133. USE GO, ONLY : TrcFile, Init, Done, ReadRc
  134. USE GO, ONLY : GO_Timer_Def, GO_Timer_End, GO_Timer_Start
  135. USE dims, ONLY : im, jm, lm, lme, okdebug, idate, iglbsfc
  136. USE dims, ONLY : nregions, nlat180, nlon360
  137. USE global_data, ONLY : rcfile, inputdir
  138. USE partools, ONLY : isRoot, par_broadcast
  139. USE MDF, ONLY : MDF_Open, MDF_HDF4, MDF_READ, MDF_Inq_VarID, MDF_Get_Var, MDF_Close
  140. USE binas, ONLY : p0
  141. USE GO, ONLY : TrcFile, Init, Done, ReadRc
  142. USE Grid, ONLY : FillGrid, Fill3D
  143. USE Grid, ONLY : TLevelInfo
  144. USE Grid, ONLY : TllGridInfo, Init, Done
  145. USE MeteoData, ONLY : global_lli, lli_z, levi
  146. !
  147. ! !INPUT PARAMETERS:
  148. !
  149. LOGICAL, INTENT(in) :: first ! is a new run
  150. !
  151. ! !OUTPUT PARAMETERS:
  152. !
  153. INTEGER, INTENT(out) :: status
  154. !
  155. ! !REVISION HISTORY:
  156. ! 13 Dec 2010 - P. Le Sager - bug fix in reading o3du : use correct
  157. ! number of levels to read data, and allow vertical
  158. ! regridding of O3du.
  159. ! 23 Mar 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  160. ! - fixed : now run longer than a month have correct boundary
  161. !
  162. !EOP
  163. !------------------------------------------------------------------------
  164. !BOC
  165. CHARACTER(len=*), PARAMETER :: rname = mname//'/Boundary_Init'
  166. INTEGER, PARAMETER :: avg_field = 1
  167. INTEGER, DIMENSION(2), PARAMETER :: msr2_valid = (/1979, 2015/) ! 2013-15 are GOME2 data
  168. CHARACTER(len=9) :: rgtype
  169. TYPE(TrcFile) :: rcF
  170. character(len=256) :: o3vmr_fnamepm, o3vmr_fname, o3vmr_fnamenm, o3du_fname
  171. character(len=256) :: ch4vmr_fnamepm, ch4vmr_fname, ch4vmr_fnamenm
  172. CHARACTER(len=256) :: filemon
  173. CHARACTER(len=4) :: ecstring
  174. INTEGER :: nmw, i1, i2, j2, j1, hid, varid
  175. INTEGER :: i,j,lmr, inp_levs, k
  176. INTEGER :: valid_year_pm, valid_year, valid_year_nm
  177. REAL*4 :: field3d_r4(nlat180,4,12)
  178. INTEGER :: nm, pm
  179. TYPE(TLevelInfo) :: LeviX, src_lev
  180. ! some arrays on 1x1 resolution
  181. REAL, ALLOCATABLE :: field3d_pm(:,:,:), field3d(:,:,:), field3d_nm(:,:,:), field3d_h(:,:,:)
  182. REAL, ALLOCATABLE :: sp_z(:,:)
  183. !
  184. ! Scaling on HALOE climatology from 2000
  185. !
  186. REAL,Dimension(37) :: RCP6_CH4_STRAT ! covers 1999-2035
  187. data RCP6_CH4_STRAT /1.00, 1.00, 1.0043444078, 1.0099155518, 1.0159814566, 1.021545823, 1.0269678609, 1.032430564, &
  188. 1.037717051, 1.0432000868, 1.0489868922, 1.0547802041, 1.0604597888, 1.0660828758, &
  189. 1.071659984, 1.0772118797, 1.0827461809, 1.0882515012, 1.0937098125, 1.0991152047, &
  190. 1.1044713649, 1.1097834167, 1.1150356906, 1.1202446152, 1.1254644653, 1.1307196942, &
  191. 1.1360154799, 1.1413492741, 1.146701693, 1.1520482561, 1.1573782007, 1.1626917436, &
  192. 1.1679937104, 1.1733492199, 1.1788363765, 1.1844880647, 1.1903212557/
  193. ! --- begin ----------------------------------------
  194. CALL goLabel(rname)
  195. !--------------------------------------------------
  196. ! ** TRUE INIT : only once
  197. !--------------------------------------------------
  198. IF ( FIRST ) THEN
  199. ! read settings from rcfile:
  200. CALL Init( rcF, rcfile, status )
  201. IF_NOTOK_RETURN(status=1)
  202. CALL ReadRc( rcF, 'input.climat.MSR', use_MSR, status, default=.FALSE. )
  203. IF_ERROR_RETURN(status=1)
  204. CALL ReadRc( rcF, 'input.climat.o3vmr', o3vmr_dirname, status )
  205. IF_NOTOK_RETURN(status=1)
  206. CALL ReadRc( rcF, 'input.climat.use_o3du', use_o3du, status, default=.FALSE. )
  207. IF_ERROR_RETURN(status=1)
  208. IF (use_o3du) THEN
  209. CALL ReadRc( rcF, 'input.climat.o3du', o3du_dirname, status )
  210. IF_NOTOK_RETURN(status=1)
  211. ENDIF
  212. CALL ReadRc( rcF, 'input.climat.HALOE', use_HALOE, status, default=.FALSE. )
  213. IF_ERROR_RETURN(status=1)
  214. IF (use_HALOE) THEN
  215. CALL ReadRc( rcF, 'input.climat.ch4vmr', ch4vmr_dirname, status )
  216. IF_NOTOK_RETURN(status=1)
  217. ENDIF
  218. CALL ReadRc( rcF, 'input.climat.ODIN', use_ODIN, status, default=.FALSE. )
  219. IF_ERROR_RETURN(status=1)
  220. IF (use_ODIN) THEN
  221. CALL ReadRc( rcF, 'input.climat.covmr', covmr_dirname, status )
  222. IF_NOTOK_RETURN(status=1)
  223. ENDIF
  224. CALL Done( rcF, status )
  225. IF_NOTOK_RETURN(status=1)
  226. ! Allocate
  227. CALL Get_DistGrid( dgrid(1), J_STRT=j1, J_STOP=j2 ) ! grid size
  228. lmr = lm(1)
  229. IF (use_o3du) THEN
  230. ALLOCATE( o3du(1)%d23(j1:j2, lmr) )
  231. o3du(1)%d23 = 0.0
  232. END IF
  233. allocate( o3ratpm (1)%d23( j1:j2, lmr) )
  234. allocate( o3rat (1)%d23( j1:j2, lmr) )
  235. allocate( o3ratnm (1)%d23( j1:j2, lmr) )
  236. allocate( ch4ratpm (1)%d23( j1:j2, lmr) )
  237. allocate( ch4rat (1)%d23( j1:j2, lmr) )
  238. allocate( ch4ratnm (1)%d23( j1:j2, lmr) )
  239. allocate( odin_hno3_o3 (1)%d23( j1:j2, 4) )
  240. allocate( odin_hno3_o3_pm(1)%d23( j1:j2, 4) )
  241. allocate( odin_hno3_o3_nm(1)%d23( j1:j2, 4) )
  242. allocate( o3vmrpm (1)%d23( j1:j2, lmr) )
  243. allocate( o3vmr (1)%d23( j1:j2, lmr) )
  244. allocate( o3vmrnm (1)%d23( j1:j2, lmr) )
  245. allocate( ch4vmrpm (1)%d23( j1:j2, lmr) )
  246. allocate( ch4vmr (1)%d23( j1:j2, lmr) ) ! only if Haloe
  247. allocate( ch4vmrnm (1)%d23( j1:j2, lmr) )
  248. allocate( odin_co_o3 (1)%d23( j1:j2, 4) )
  249. allocate( odin_co_o3_pm(1)%d23( j1:j2, 4) )
  250. allocate( odin_co_o3_nm(1)%d23( j1:j2, 4) )
  251. ! work arrays
  252. IF (isRoot) THEN
  253. allocate( wrk3dpm_ML (1, jm(1), lmr) )
  254. allocate( wrk3d_ML (1, jm(1), lmr) )
  255. allocate( wrk3dnm_ML (1, jm(1), lmr) )
  256. allocate( wrk3dratio(1, jm(1), 4) )
  257. allocate( wrk3dratiopm(1, jm(1), 4) )
  258. allocate( wrk3drationm(1, jm(1), 4) )
  259. allocate( wrk2d_ML ( jm(1), lmr) )
  260. allocate( wrk2d_4L ( jm(1), 4) )
  261. ELSE
  262. allocate( wrk3dpm_ML (1,1,1) )
  263. allocate( wrk3d_ML (1,1,1) )
  264. allocate( wrk3dnm_ML (1,1,1) )
  265. allocate( wrk3dratio(1,1,1) )
  266. allocate( wrk3dratiopm(1,1,1) )
  267. allocate( wrk3drationm(1,1,1) )
  268. ALLOCATE( wrk2d_ML(1,1) )
  269. ALLOCATE( wrk2d_4L(1,1) )
  270. END IF
  271. ! safety
  272. o3ratpm(1)%d23 = 0.0 ; o3rat(1)%d23 = 0.0 ; o3ratnm(1)%d23 = 0.0
  273. ch4ratpm(1)%d23 = 0.0 ; ch4rat(1)%d23 = 0.0 ; ch4ratnm(1)%d23 = 0.0
  274. odin_hno3_o3_pm(1)%d23 = 0.0 ; odin_hno3_o3(1)%d23 = 0.0 ; odin_hno3_o3_nm(1)%d23 = 0.0
  275. odin_co_o3_pm(1)%d23 = 0.0 ; odin_co_o3 (1)%d23 = 0.0 ; odin_co_o3_nm(1)%d23 = 0.0
  276. ! Budgets init
  277. !--------------------------------------------------
  278. #ifdef with_budgets
  279. ! sum_stratosphere(1) = 0.0
  280. budstratg(:,:,:) = 0.0
  281. #endif
  282. ! Timers
  283. call GO_Timer_Def( itim_init, 'boundary init', status )
  284. IF_NOTOK_RETURN(status=1)
  285. call GO_Timer_Def( itim_appl, 'boundary appl', status )
  286. IF_NOTOK_RETURN(status=1)
  287. ELSE
  288. ! start timing
  289. call GO_Timer_Start( itim_init, status )
  290. IF_NOTOK_RETURN(status=1)
  291. !--------------------------------------------------
  292. ! ** OZONE CLIMATOLOGIES
  293. !--------------------------------------------------
  294. ! Define vertical grid of original met fields (MSR2 only on 60 levels for now)
  295. ecstring='ec60'
  296. IF (isRoot) THEN
  297. CALL Init(LeviX, ecstring, status)
  298. IF_NOTOK_RETURN(status=1)
  299. ENDIF
  300. ! to read data on root on the iglbsfc grid
  301. !nlat180 = dgrid(iglbsfc)%jm_region ! use get_distgrid to get that
  302. inp_levs = 60 ! lme
  303. !--------------------------------------------------
  304. ! ** o3 vmr
  305. !--------------------------------------------------
  306. ROOT : IF (isRoot) THEN
  307. ! read the meridional data
  308. IF (use_MSR) THEN
  309. allocate( field3D_pm (1, nlat180, inp_levs) )
  310. allocate( field3D (1, nlat180, inp_levs) )
  311. allocate( field3D_nm (1, nlat180, inp_levs) )
  312. allocate( field3d_h (1, nlat180, inp_levs) )
  313. field3d_pm=0.0 ; field3d=0.0 ; field3d_nm=0.0 ; field3d_h=0.0
  314. nmw=idate(2) ! pick out right month in file
  315. ! filename (includes year and nb of levels)
  316. valid_year = MIN(msr2_valid(2), MAX(idate(1), msr2_valid(1)))
  317. valid_year_pm = MAX(valid_year-1, msr2_valid(1))
  318. valid_year_nm = MIN(valid_year+1, msr2_valid(2))
  319. ! Currently available: 1979-2012
  320. WRITE(o3vmr_fnamepm,'(a,"msr2_o3vmr",i4,"_",i2,".hdf")')TRIM(o3vmr_dirname),valid_year_pm,inp_levs
  321. WRITE(o3vmr_fname,' (a,"msr2_o3vmr",i4,"_",i2,".hdf")')TRIM(o3vmr_dirname),valid_year, inp_levs
  322. WRITE(o3vmr_fnamenm,'(a,"msr2_o3vmr",i4,"_",i2,".hdf")')TRIM(o3vmr_dirname),valid_year_nm,inp_levs
  323. !
  324. ! January
  325. !
  326. if(nmw .eq. 1) then
  327. CALL MDF_Open( TRIM(o3vmr_fnamepm), MDF_HDF4, MDF_READ, hid, status )
  328. IF_NOTOK_RETURN(status=1)
  329. CALL MDF_Inq_VarID( hid, 'ozone12', varid, status )
  330. IF_NOTOK_RETURN(status=1)
  331. CALL MDF_Get_Var( hid, varid, field3d_h(1,:,:), status )
  332. IF_NOTOK_RETURN(status=1)
  333. CALL MDF_Close( hid, status )
  334. IF_NOTOK_RETURN(status=1)
  335. ! Flip the data over (upside down), since leviX, associated with
  336. ! field3d when regridding below (Fill3D), is flipped w/r/t to levi
  337. ! [it is the case, since ecstring starts with "ec" and not "tm"
  338. ! --see grid_type_hyb.F90--]
  339. DO k=1,inp_levs
  340. field3d_pm(1,:,k)=field3d_h(1,:,inp_levs+1-k)
  341. ENDDO
  342. CALL MDF_Open( TRIM(o3vmr_fname), MDF_HDF4, MDF_READ, hid, status )
  343. IF_NOTOK_RETURN(status=1)
  344. CALL MDF_Inq_VarID( hid, 'ozone1', varid, status )
  345. IF_NOTOK_RETURN(status=1)
  346. CALL MDF_Get_Var( hid, varid, field3d_h(1,:,:), status )
  347. IF_NOTOK_RETURN(status=1)
  348. DO k=1,inp_levs
  349. field3d(1,:,k)=field3d_h(1,:,inp_levs+1-k)
  350. ENDDO
  351. CALL MDF_Inq_VarID( hid, 'ozone2', varid, status )
  352. IF_NOTOK_RETURN(status=1)
  353. CALL MDF_Get_Var( hid, varid, field3d_h(1,:,:), status )
  354. IF_NOTOK_RETURN(status=1)
  355. CALL MDF_Close( hid, status )
  356. IF_NOTOK_RETURN(status=1)
  357. DO k=1,inp_levs
  358. field3d_nm(1,:,k)=field3d_h(1,:,inp_levs+1-k)
  359. ENDDO
  360. src_lev = leviX
  361. rgtype = 'mass-aver'
  362. deallocate( field3d_h )
  363. endif
  364. !
  365. ! Here the previous and next monthly fields are located in the same year
  366. !
  367. if(nmw .gt. 1 .and. nmw .lt. 12) then
  368. ! field name (has month: ozone1, ozone2, ..., ozone12)
  369. IF (nmw.LT.11) THEN
  370. nmw=idate(2)-1
  371. WRITE(filemon,'(a,i1)')'ozone',nmw
  372. ELSE
  373. nmw=idate(2)-1
  374. WRITE(filemon,'(a,i2)')'ozone',nmw
  375. ENDIF
  376. CALL MDF_Open( TRIM(o3vmr_fname), MDF_HDF4, MDF_READ, hid, status )
  377. IF_NOTOK_RETURN(status=1)
  378. CALL MDF_Inq_VarID( hid, TRIM(filemon), varid, status )
  379. IF_NOTOK_RETURN(status=1)
  380. CALL MDF_Get_Var( hid, varid, field3d_h(1,:,:), status )
  381. IF_NOTOK_RETURN(status=1)
  382. ! Flip the data over (upside down), since leviX, associated with
  383. ! field3d when regridding below (Fill3D), is flipped w/r/t to levi
  384. ! [it is the case, since ecstring starts with "ec" and not "tm"
  385. ! --see grid_type_hyb.F90--]
  386. DO k=1,inp_levs
  387. field3d_pm(1,:,k)=field3d_h(1,:,inp_levs+1-k)
  388. ENDDO
  389. nmw=idate(2)
  390. ! field name (has month: ozone1, ozone2, ..., ozone12)
  391. IF (nmw.LT.10) THEN
  392. WRITE(filemon,'(a,i1)')'ozone', nmw
  393. ELSE
  394. WRITE(filemon,'(a,i2)')'ozone', nmw
  395. ENDIF
  396. CALL MDF_Inq_VarID( hid, TRIM(filemon), varid, status )
  397. IF_NOTOK_RETURN(status=1)
  398. CALL MDF_Get_Var( hid, varid, field3d_h(1,:,:), status )
  399. IF_NOTOK_RETURN(status=1)
  400. DO k=1,inp_levs
  401. field3d(1,:,k)=field3d_h(1,:,inp_levs+1-k)
  402. ENDDO
  403. ! field name (has month: ozone1, ozone2, ..., ozone12)
  404. IF (nmw.LT.9) THEN
  405. nmw=idate(2)+1
  406. WRITE(filemon,'(a,i1)')'ozone',nmw
  407. ELSE
  408. nmw=idate(2)+1
  409. WRITE(filemon,'(a,i2)')'ozone',nmw
  410. ENDIF
  411. CALL MDF_Inq_VarID( hid, TRIM(filemon), varid, status )
  412. IF_NOTOK_RETURN(status=1)
  413. CALL MDF_Get_Var( hid, varid, field3d_h(1,:,:), status )
  414. IF_NOTOK_RETURN(status=1)
  415. CALL MDF_Close( hid, status )
  416. IF_NOTOK_RETURN(status=1)
  417. DO k=1,inp_levs
  418. field3d_nm(1,:,k)=field3d_h(1,:,inp_levs+1-k)
  419. ENDDO
  420. src_lev = leviX
  421. rgtype = 'mass-aver'
  422. deallocate( field3d_h )
  423. nmw=idate(2)
  424. endif
  425. !
  426. ! December
  427. !
  428. if(nmw .eq. 12) then
  429. nmw=idate(2)-1
  430. WRITE(filemon,'(a,i2)')'ozone',nmw
  431. CALL MDF_Open( TRIM(o3vmr_fname), MDF_HDF4, MDF_READ, hid, status )
  432. IF_NOTOK_RETURN(status=1)
  433. CALL MDF_Inq_VarID( hid,TRIM(filemon), varid, status )
  434. IF_NOTOK_RETURN(status=1)
  435. CALL MDF_Get_Var( hid, varid, field3d_h(1,:,:), status )
  436. IF_NOTOK_RETURN(status=1)
  437. ! Flip the data over (upside down), since leviX, associated with
  438. ! field3d when regridding below (Fill3D), is flipped w/r/t to levi
  439. ! [it is the case, since ecstring starts with "ec" and not "tm"
  440. ! --see grid_type_hyb.F90--]
  441. DO k=1,inp_levs
  442. field3d_pm(1,:,k)=field3d_h(1,:,inp_levs+1-k)
  443. ENDDO
  444. nmw=12
  445. WRITE(filemon,'(a,i2)')'ozone',nmw
  446. CALL MDF_Inq_VarID( hid,TRIM(filemon) , varid, status )
  447. IF_NOTOK_RETURN(status=1)
  448. CALL MDF_Get_Var( hid, varid, field3d_h(1,:,:), status )
  449. IF_NOTOK_RETURN(status=1)
  450. CALL MDF_Close( hid, status )
  451. IF_NOTOK_RETURN(status=1)
  452. DO k=1,inp_levs
  453. field3d(1,:,k)=field3d_h(1,:,inp_levs+1-k)
  454. ENDDO
  455. nmw=1
  456. WRITE(filemon,'(a,i1)')'ozone',nmw
  457. CALL MDF_Open( TRIM(o3vmr_fnamenm), MDF_HDF4, MDF_READ, hid, status )
  458. IF_NOTOK_RETURN(status=1)
  459. CALL MDF_Inq_VarID( hid, TRIM(filemon), varid, status )
  460. IF_NOTOK_RETURN(status=1)
  461. CALL MDF_Get_Var( hid, varid, field3d_h(1,:,:), status )
  462. IF_NOTOK_RETURN(status=1)
  463. CALL MDF_Close( hid, status )
  464. IF_NOTOK_RETURN(status=1)
  465. DO k=1,inp_levs
  466. field3d_nm(1,:,k)=field3d_h(1,:,inp_levs+1-k)
  467. ENDDO
  468. src_lev = leviX
  469. rgtype = 'mass-aver'
  470. deallocate( field3d_h )
  471. endif
  472. ELSE ! use other file already remapped to model levels (e.g. o3vmr2000_tropo25.hdf)
  473. allocate( field3d(1, nlat180, lm(1) ))
  474. field3d=0.0
  475. o3vmr_fname=o3vmr_dirname
  476. CALL MDF_Open( TRIM(o3vmr_fname), MDF_HDF4, MDF_READ, hid, status )
  477. IF_NOTOK_RETURN(status=1)
  478. CALL MDF_Get_Var( hid, idate(2), field3d(1,:,:), status )
  479. IF_NOTOK_RETURN(status=1)
  480. CALL MDF_Close( hid, status )
  481. IF_NOTOK_RETURN(status=1)
  482. src_lev = levi
  483. rgtype = 'area-aver'
  484. ENDIF
  485. ! Coarsen/distribute to each 1 resolution
  486. ALLOCATE( sp_z(1,jm(1)) ) ! dummy surface pressure:
  487. sp_z = p0 ! 1e5 Pa
  488. CALL Fill3D( lli_z(1), levi, 'n', sp_z, wrk3dpm_ML, &
  489. lli_z(iglbsfc), src_lev, field3d_pm, rgtype, status )
  490. CALL Fill3D( lli_z(1), levi, 'n', sp_z, wrk3d_ML, &
  491. lli_z(iglbsfc), src_lev, field3d, rgtype, status )
  492. CALL Fill3D( lli_z(1), levi, 'n', sp_z, wrk3dnm_ML, &
  493. lli_z(iglbsfc), src_lev, field3d_nm, rgtype, status )
  494. IF_NOTOK_RETURN(status=1)
  495. deallocate( sp_z )
  496. deallocate( field3d_pm)
  497. deallocate( field3d )
  498. deallocate( field3d_nm)
  499. END IF ROOT
  500. ! scatter along latitude direction, then broadcast
  501. wrk2d_ML = wrk3dpm_ML(1,:,:) ! reshape
  502. CALL SCATTER_I_BAND( dgrid(1), o3vmrpm(1)%d23, wrk2d_ML, status )
  503. IF_NOTOK_RETURN(status=1)
  504. CALL PAR_BROADCAST( o3vmrpm(1)%d23, status, row=.TRUE. )
  505. IF_NOTOK_RETURN(status=1)
  506. wrk2d_ML = wrk3d_ML(1,:,:) ! reshape
  507. CALL SCATTER_I_BAND( dgrid(1), o3vmr(1)%d23, wrk2d_ML, status )
  508. IF_NOTOK_RETURN(status=1)
  509. CALL PAR_BROADCAST( o3vmr(1)%d23, status, row=.TRUE. )
  510. IF_NOTOK_RETURN(status=1)
  511. wrk2d_ML = wrk3dnm_ML(1,:,:) ! reshape
  512. CALL SCATTER_I_BAND( dgrid(1), o3vmrnm(1)%d23, wrk2d_ML, status )
  513. IF_NOTOK_RETURN(status=1)
  514. CALL PAR_BROADCAST( o3vmrnm(1)%d23, status, row=.TRUE. )
  515. IF_NOTOK_RETURN(status=1)
  516. !--------------------------------------------------
  517. ! ** O3 DU
  518. !--------------------------------------------------
  519. IF (use_o3du) THEN
  520. IF(isRoot) THEN
  521. ! o3du only required for 40 or 62 levels
  522. inp_levs = lme
  523. ALLOCATE( field3d (1, nlat180, inp_levs) )
  524. ALLOCATE( field3d_h(1, nlat180, inp_levs) )
  525. nmw=idate(2) ! pick out right month in file
  526. WRITE(o3du_fname,'(a,"msr2_o3du",i4,"_",i2,".hdf")')TRIM(o3du_dirname),idate(1),inp_levs
  527. IF (nmw.LT.10) THEN
  528. WRITE(filemon,'(a,i1)')'ozone', idate(2)
  529. ELSE
  530. WRITE(filemon,'(a,i2)')'ozone', idate(2)
  531. ENDIF
  532. CALL MDF_Open( TRIM(o3du_fname), MDF_HDF4, MDF_READ, hid, status )
  533. IF_NOTOK_RETURN(status=1)
  534. CALL MDF_Inq_VarID( hid, TRIM(filemon), varid, status )
  535. IF_NOTOK_RETURN(status=1)
  536. CALL MDF_Get_Var( hid, varid, field3d_h, status )
  537. IF_NOTOK_RETURN(status=1)
  538. CALL MDF_Close( hid, status )
  539. IF_NOTOK_RETURN(status=1)
  540. ! flip data so that they are on the leviX levels
  541. DO k=1,inp_levs
  542. field3d(1,:,k)=field3d_h(1,:,inp_levs+1-k)
  543. ENDDO
  544. ! remap to model levels
  545. ALLOCATE( sp_z(1,jm(1)) )
  546. sp_z = p0 ! 1e5 Pa
  547. CALL Fill3D( lli_z(1), levi, 'n', sp_z, wrk3d_ML, &
  548. lli_z(iglbsfc), leviX, field3d, 'area-aver', status )
  549. IF_NOTOK_RETURN(status=1)
  550. DEALLOCATE( sp_z )
  551. DEALLOCATE( field3d )
  552. DEALLOCATE( field3d_h )
  553. END IF
  554. ! scatter along latitude direction, then broadcast
  555. wrk2d_ML = wrk3d_ML(1,:,:)
  556. CALL SCATTER_I_BAND( dgrid(1), o3du(1)%d23, wrk2d_ML, status )
  557. IF_NOTOK_RETURN(status=1)
  558. CALL PAR_BROADCAST( o3du(1)%d23, status, row=.TRUE. )
  559. IF_NOTOK_RETURN(status=1)
  560. ENDIF ! use_o3du
  561. !--------------------------------------------------
  562. ! ** CH4 HALOE
  563. !--------------------------------------------------
  564. IF (use_HALOE) THEN
  565. IF(isRoot) THEN
  566. inp_levs = lme
  567. allocate( field3d_pm (1, nlat180, inp_levs) )
  568. allocate( field3d (1, nlat180, inp_levs) )
  569. allocate( field3d_nm (1, nlat180, inp_levs) )
  570. allocate( field3d_h (1, nlat180, inp_levs) )
  571. field3d_pm=0.0 ; field3d=0.0 ; field3d_nm=0.0 ; field3d_h=0.0
  572. !
  573. ! For each month, data are read, then flipped over (upside down), otherwise Fill3D
  574. ! doesn't work properly, and scaled up to account for growth from 2000.
  575. !
  576. ! - Previous month
  577. !
  578. if(idate(2) .eq. 1) then
  579. nmw=12
  580. WRITE(filemon,'(a,i2)')'haloe',nmw
  581. else
  582. nmw=idate(2)-1
  583. if(idate(2) .lt. 11) WRITE(filemon,'(a,i1)')'haloe',nmw
  584. if(idate(2) .gt. 10) WRITE(filemon,'(a,i2)')'haloe',nmw
  585. endif
  586. !
  587. WRITE(ch4vmr_fname,'(a,"haloe_ch4vmr_",i2,".hdf")')TRIM(ch4vmr_dirname),inp_levs
  588. CALL MDF_Open( TRIM(ch4vmr_fname), MDF_HDF4, MDF_READ, hid, status )
  589. IF_NOTOK_RETURN(status=1)
  590. CALL MDF_Inq_VarID( hid, TRIM(filemon), varid, status )
  591. IF_NOTOK_RETURN(status=1)
  592. CALL MDF_Get_Var( hid, varid, field3d_h(1,:,:), status )
  593. IF_NOTOK_RETURN(status=1)
  594. valid_year = MIN(2035,MAX(idate(1)-1,1999))
  595. DO k=1,inp_levs
  596. field3d_pm(1,:,k)=field3d_h(1,:,inp_levs+1-k)*RCP6_CH4_STRAT(valid_year-1998)
  597. ENDDO
  598. !
  599. ! - Current month
  600. !
  601. nmw=idate(2)
  602. IF (nmw.LT.10) THEN
  603. WRITE(filemon,'(a,i1)')'haloe', nmw
  604. ELSE
  605. WRITE(filemon,'(a,i2)')'haloe', nmw
  606. ENDIF
  607. CALL MDF_Inq_VarID( hid, TRIM(filemon), varid, status )
  608. IF_NOTOK_RETURN(status=1)
  609. CALL MDF_Get_Var( hid, varid, field3d_h(1,:,:), status )
  610. IF_NOTOK_RETURN(status=1)
  611. valid_year = MIN(2035,MAX(idate(1),1999))
  612. DO k=1,inp_levs
  613. field3d(1,:,k)=field3d_h(1,:,inp_levs+1-k)*RCP6_CH4_STRAT(valid_year-1998)
  614. ENDDO
  615. !
  616. ! - Next month
  617. !
  618. nmw=idate(2)+1
  619. valid_year = MIN(2035,MAX(idate(1),1999))
  620. if(idate(2) .eq. 12) then
  621. nmw=1
  622. valid_year = MIN(2035,MAX(idate(1)+1,1999))
  623. endif
  624. if(nmw .lt. 10) WRITE(filemon,'(a,i1)')'haloe', nmw
  625. if(nmw .gt. 9) WRITE(filemon,'(a,i2)')'haloe', nmw
  626. CALL MDF_Inq_VarID( hid, TRIM(filemon), varid, status )
  627. IF_NOTOK_RETURN(status=1)
  628. CALL MDF_Get_Var( hid, varid, field3d_h(1,:,:), status )
  629. IF_NOTOK_RETURN(status=1)
  630. CALL MDF_Close( hid, status )
  631. IF_NOTOK_RETURN(status=1)
  632. DO k=1,inp_levs
  633. field3d_nm(1,:,k)=field3d_h(1,:,inp_levs+1-k)*RCP6_CH4_STRAT(valid_year-1998)
  634. ENDDO
  635. !
  636. ! Coarsen or distribute on region #1 the three datasets
  637. !
  638. ALLOCATE( sp_z(1,jm(1)) )
  639. sp_z = p0 ! 1e5 Pa
  640. CALL Fill3D( lli_z(1), levi, 'n', sp_z, wrk3dpm_ML, &
  641. lli_z(iglbsfc), leviX, field3d_pm, 'mass-aver', status )
  642. CALL Fill3D( lli_z(1), levi, 'n', sp_z, wrk3d_ML, &
  643. lli_z(iglbsfc), leviX, field3d, 'mass-aver', status )
  644. CALL Fill3D( lli_z(1), levi, 'n', sp_z, wrk3dnm_ML, &
  645. lli_z(iglbsfc), leviX, field3d_nm, 'mass-aver', status )
  646. IF_NOTOK_RETURN(status=1)
  647. ! clear allocatables
  648. deallocate( sp_z )
  649. deallocate( field3d_pm )
  650. deallocate( field3d )
  651. deallocate( field3d_nm )
  652. deallocate( field3d_h )
  653. END IF ! Read & Regrid on Root
  654. ! Scatter along latitude direction, then broadcast to other cores in same zonal band
  655. wrk2d_ML = wrk3dpm_ML(1,:,:)
  656. CALL SCATTER_I_BAND( dgrid(1), ch4vmrpm(1)%d23, wrk2d_ML, status )
  657. IF_NOTOK_RETURN(status=1)
  658. CALL PAR_BROADCAST( ch4vmrpm(1)%d23, status, row=.TRUE. )
  659. IF_NOTOK_RETURN(status=1)
  660. wrk2d_ML = wrk3d_ML(1,:,:)
  661. CALL SCATTER_I_BAND( dgrid(1), ch4vmr(1)%d23, wrk2d_ML, status )
  662. IF_NOTOK_RETURN(status=1)
  663. CALL PAR_BROADCAST( ch4vmr(1)%d23, status, row=.TRUE. )
  664. IF_NOTOK_RETURN(status=1)
  665. wrk2d_ML = wrk3dnm_ML(1,:,:)
  666. CALL SCATTER_I_BAND( dgrid(1), ch4vmrnm(1)%d23, wrk2d_ML, status )
  667. IF_NOTOK_RETURN(status=1)
  668. CALL PAR_BROADCAST( ch4vmrnm(1)%d23, status, row=.TRUE. )
  669. IF_NOTOK_RETURN(status=1)
  670. ENDIF ! use_HALO
  671. !--------------------------------------------------
  672. ! ** ODIN climatology : HNO3/O3 and CO/O3 ratios
  673. !--------------------------------------------------
  674. IF (use_ODIN) then
  675. inp_levs=4
  676. !--------------------------------------------------
  677. ! * ODIN climatology : HNO3/O3
  678. !--------------------------------------------------
  679. IF ( isRoot ) THEN
  680. ! open, read ratio
  681. CALL MDF_Open( TRIM(covmr_dirname)//'/ODIN_Climatology_HNO3_O3_4levels.hdf', MDF_HDF4, MDF_READ, hid, status )
  682. IF_NOTOK_RETURN(status=1)
  683. CALL MDF_Inq_VarID( hid, 'Ratio', varid, status )
  684. IF_NOTOK_RETURN(status=1)
  685. CALL MDF_Get_Var( hid,varid, field3d_r4, status )
  686. IF_NOTOK_RETURN(status=1)
  687. pm=idate(2)-1
  688. ! previous month
  689. allocate( field3d(1,nlat180,4) )
  690. if(idate(2) .eq. 1) field3d(1,:,:)=field3d_r4(:,:,12)
  691. if(idate(2) .gt. 1) field3d(1,:,:)=field3d_r4(:,:,pm)
  692. ! remap
  693. DO i=1,inp_levs
  694. CALL FillGrid( lli_z(1), 'n', wrk3dratiopm(:,:,i), &
  695. lli_z(iglbsfc), 'n', field3d(:,:,i), 'area-aver', status )
  696. IF_NOTOK_RETURN(status=1)
  697. END DO
  698. ! current month
  699. field3d(1,:,:)=field3d_r4(:,:,idate(2))
  700. ! remap
  701. DO i=1,inp_levs
  702. CALL FillGrid( lli_z(1), 'n', wrk3dratio(:,:,i), &
  703. lli_z(iglbsfc), 'n', field3d(:,:,i), 'area-aver', status )
  704. IF_NOTOK_RETURN(status=1)
  705. END DO
  706. nm=idate(2)+1
  707. if(idate(2) .lt. 12) field3d(1,:,:)=field3d_r4(:,:,nm)
  708. if(idate(2) .eq. 12) field3d(1,:,:)=field3d_r4(:,:,1)
  709. ! remap
  710. DO i=1,inp_levs
  711. CALL FillGrid( lli_z(1), 'n', wrk3drationm(:,:,i), &
  712. lli_z(iglbsfc), 'n', field3d(:,:,i), 'area-aver', status )
  713. IF_NOTOK_RETURN(status=1)
  714. END DO
  715. CALL MDF_Close( hid, status )
  716. IF_NOTOK_RETURN(status=1)
  717. DEALLOCATE( field3d )
  718. END IF ! root
  719. ! Scatter along latitude direction, then broadcast to other cores in same zonal band
  720. wrk2d_4L = wrk3dratiopm(1,:,:)
  721. CALL SCATTER_I_BAND( dgrid(1), odin_hno3_o3_pm(1)%d23(:,:), wrk2d_4L, status )
  722. IF_NOTOK_RETURN(status=1)
  723. CALL PAR_BROADCAST( odin_hno3_o3_pm(1)%d23, status, row=.TRUE. )
  724. IF_NOTOK_RETURN(status=1)
  725. wrk2d_4L = wrk3dratio(1,:,:)
  726. CALL SCATTER_I_BAND( dgrid(1), odin_hno3_o3(1)%d23(:,:), wrk2d_4L, status )
  727. IF_NOTOK_RETURN(status=1)
  728. CALL PAR_BROADCAST( odin_hno3_o3(1)%d23, status, row=.TRUE. )
  729. IF_NOTOK_RETURN(status=1)
  730. wrk2d_4L = wrk3drationm(1,:,:)
  731. CALL SCATTER_I_BAND( dgrid(1), odin_hno3_o3_nm(1)%d23(:,:), wrk2d_4L, status )
  732. IF_NOTOK_RETURN(status=1)
  733. CALL PAR_BROADCAST( odin_hno3_o3_nm(1)%d23, status, row=.TRUE. )
  734. IF_NOTOK_RETURN(status=1)
  735. !--------------------------------------------------
  736. ! * ODIN climatology : CO O3
  737. !--------------------------------------------------
  738. IF ( isRoot ) THEN
  739. ! open, read ratio
  740. CALL MDF_Open(TRIM(covmr_dirname)//'ODIN_CO_O3_ratio_4levels.hdf', MDF_HDF4, MDF_READ, hid, status )
  741. IF_NOTOK_RETURN(status=1)
  742. CALL MDF_Inq_VarID( hid, 'CO_O3_ratio', varid, status )
  743. IF_NOTOK_RETURN(status=1)
  744. CALL MDF_Get_Var( hid, varid, field3d_r4, status )
  745. IF_NOTOK_RETURN(status=1)
  746. allocate( field3d(1,nlat180,4) ) ! 1D array along latitude
  747. pm=idate(2)-1
  748. ! previous month
  749. if(idate(2) .eq. 1) field3d(1,:,:)=field3d_r4(:,:,12)
  750. if(idate(2) .gt. 1) field3d(1,:,:)=field3d_r4(:,:,pm)
  751. ! remap
  752. DO i=1,inp_levs
  753. CALL FillGrid( lli_z(1), 'n', wrk3dratiopm(:,:,i), &
  754. lli_z(iglbsfc), 'n', field3d(:,:,i), 'area-aver', status )
  755. IF_NOTOK_RETURN(status=1)
  756. END DO
  757. ! current month
  758. field3d(1,:,:)=field3d_r4(:,:,idate(2))
  759. ! remap
  760. DO i=1,inp_levs
  761. CALL FillGrid( lli_z(1), 'n', wrk3dratio(:,:,i), &
  762. lli_z(iglbsfc), 'n', field3d(:,:,i), 'area-aver', status )
  763. IF_NOTOK_RETURN(status=1)
  764. END DO
  765. nm=idate(2)+1
  766. ! correct month
  767. if(idate(2) .lt. 12) field3d(1,:,:)=field3d_r4(:,:,nm)
  768. if(idate(2) .eq. 12) field3d(1,:,:)=field3d_r4(:,:,1)
  769. ! remap
  770. DO i=1,inp_levs
  771. CALL FillGrid( lli_z(1), 'n', wrk3drationm(:,:,i), &
  772. lli_z(iglbsfc), 'n', field3d(:,:,i), 'area-aver', status )
  773. IF_NOTOK_RETURN(status=1)
  774. END DO
  775. CALL MDF_Close( hid, status )
  776. IF_NOTOK_RETURN(status=1)
  777. deallocate( field3d )
  778. END IF ! root
  779. ! scatter along latitude direction, then broadcast
  780. wrk2d_4L = wrk3dratiopm(1,:,:)
  781. CALL SCATTER_I_BAND( dgrid(1), odin_co_o3_pm(1)%d23(:,:), wrk2d_4L, status )
  782. IF_NOTOK_RETURN(status=1)
  783. CALL PAR_BROADCAST( odin_co_o3_pm(1)%d23, status, row=.TRUE. )
  784. IF_NOTOK_RETURN(status=1)
  785. wrk2d_4L = wrk3dratio(1,:,:)
  786. CALL SCATTER_I_BAND( dgrid(1), odin_co_o3(1)%d23(:,:), wrk2d_4L, status )
  787. IF_NOTOK_RETURN(status=1)
  788. CALL PAR_BROADCAST( odin_co_o3(1)%d23, status, row=.TRUE. )
  789. IF_NOTOK_RETURN(status=1)
  790. ! scatter along latitude direction, then broadcast
  791. wrk2d_4L = wrk3drationm(1,:,:)
  792. CALL SCATTER_I_BAND( dgrid(1), odin_co_o3_nm(1)%d23(:,:), wrk2d_4L, status )
  793. IF_NOTOK_RETURN(status=1)
  794. CALL PAR_BROADCAST( odin_co_o3_nm(1)%d23, status, row=.TRUE. )
  795. IF_NOTOK_RETURN(status=1)
  796. ELSE
  797. !--------------------------------------------------
  798. ! ** UARS climatology : HNO3 O3 (Fallback on this one if we are not using ODIN)
  799. !--------------------------------------------------
  800. IF ( isRoot ) THEN
  801. ALLOCATE( field3d(1,nlat180,1) ) ! 1D array along latitude
  802. field3d = 0.0
  803. CALL MDF_Open( TRIM(inputdir)//'/boundary/HNO3_top/uars_ratio.hdf', MDF_HDF4, MDF_READ, hid, status )
  804. IF_NOTOK_RETURN(status=1)
  805. CALL MDF_Get_Var( hid, idate(2), field3d(:,:,1), status )
  806. IF_NOTOK_RETURN(status=1)
  807. CALL MDF_Close( hid, status )
  808. IF_NOTOK_RETURN(status=1)
  809. ! remap
  810. CALL FillGrid( lli_z(1), 'n', wrk3dratio(:,:,1), &
  811. lli_z(iglbsfc), 'n', field3d(:,:,1), 'area-aver', status )
  812. IF_NOTOK_RETURN(status=1)
  813. DEALLOCATE( field3d )
  814. END IF ! root
  815. ! scatter along latitude direction, then broadcast
  816. wrk2d_ML(:,1) = wrk3dratio(1,:,1)
  817. CALL SCATTER_I_BAND( dgrid(1), odin_hno3_o3(1)%d23(:,1), wrk2d_ML(:,1), status )
  818. IF_NOTOK_RETURN(status=1)
  819. CALL PAR_BROADCAST( odin_hno3_o3(1)%d23(:,1), status, row=.TRUE. )
  820. IF_NOTOK_RETURN(status=1)
  821. ENDIF
  822. ! **
  823. IF (isRoot) THEN
  824. CALL Done( LeviX, status )
  825. IF_NOTOK_RETURN(status=1)
  826. ENDIF
  827. ! end timing:
  828. call GO_Timer_End( itim_init, status )
  829. IF_NOTOK_RETURN(status=1)
  830. END IF
  831. CALL goLabel()
  832. status = 0
  833. END SUBROUTINE BOUNDARY_INIT
  834. !EOC
  835. !--------------------------------------------------------------------------
  836. ! TM5 !
  837. !--------------------------------------------------------------------------
  838. !BOP
  839. !
  840. ! !IROUTINE: BOUNDARY_DONE
  841. !
  842. ! !DESCRIPTION: deallocate arrays (budgets gathering/reduction is done in
  843. ! chemistry/chemistry_done)
  844. !\\
  845. !\\
  846. ! !INTERFACE:
  847. !
  848. SUBROUTINE BOUNDARY_DONE( status )
  849. !
  850. ! !OUTPUT PARAMETERS:
  851. !
  852. INTEGER, INTENT(out) :: status
  853. !
  854. ! !REVISION HISTORY:
  855. ! 15 Jun 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  856. !
  857. !EOP
  858. !------------------------------------------------------------------------
  859. !BOC
  860. CHARACTER(len=*), PARAMETER :: rname = mname//'/Boundary_Done'
  861. ! --- begin ----------------------------------------
  862. CALL goLabel(rname)
  863. IF (use_o3du) deallocate( o3du(1)%d23 )
  864. deallocate( o3vmrpm (1)%d23 )
  865. deallocate( o3vmr (1)%d23 )
  866. deallocate( o3vmrnm (1)%d23 )
  867. deallocate( ch4vmrpm (1)%d23 )
  868. deallocate( ch4vmr (1)%d23 )
  869. deallocate( ch4vmrnm (1)%d23 )
  870. deallocate( o3ratpm (1)%d23 )
  871. deallocate( o3rat (1)%d23 )
  872. deallocate( o3ratnm (1)%d23 )
  873. deallocate( ch4ratpm (1)%d23 )
  874. deallocate( ch4rat (1)%d23 )
  875. deallocate( ch4ratnm (1)%d23 )
  876. deallocate( odin_hno3_o3 (1)%d23 )
  877. deallocate( odin_hno3_o3_pm(1)%d23 )
  878. deallocate( odin_hno3_o3_nm(1)%d23 )
  879. deallocate( odin_co_o3 (1)%d23 )
  880. deallocate( odin_co_o3_pm (1)%d23 )
  881. deallocate( odin_co_o3_nm (1)%d23 )
  882. deallocate( wrk3dpm_ML )
  883. deallocate( wrk3d_ML )
  884. deallocate( wrk3dnm_ML )
  885. deallocate( wrk3dratio )
  886. deallocate( wrk3dratiopm )
  887. deallocate( wrk3drationm )
  888. deallocate( wrk2d_ML )
  889. deallocate( wrk2d_4L )
  890. CALL goLabel()
  891. status = 0
  892. END SUBROUTINE BOUNDARY_DONE
  893. !EOC
  894. !--------------------------------------------------------------------------
  895. ! TM5 !
  896. !--------------------------------------------------------------------------
  897. !BOP
  898. !
  899. ! !IROUTINE: BOUNDARY_APPLY
  900. !
  901. ! !DESCRIPTION:
  902. !\\
  903. !\\
  904. ! !INTERFACE:
  905. !
  906. SUBROUTINE BOUNDARY_APPLY( region, status )
  907. !
  908. ! !USES:
  909. !
  910. USE dims, ONLY : im, jm, lm
  911. USE dims, ONLY : ybeg
  912. USE dims, ONLY : xref, yref, tref
  913. USE dims, ONLY : at, bt
  914. USE dims, ONLY : dx, dy
  915. USE dims, ONLY : nsrce
  916. USE dims, ONLY : okdebug
  917. USE dims, ONLY : sec_day,sec_month
  918. USE toolbox, ONLY : lvlpress
  919. USE chem_param, ONLY : io3, io3s, ich4, ihno3, ico
  920. USE chem_param, ONLY : xmair, xmhno3, xmo3, xmch4, xmco, fscale, ra
  921. USE meteodata, ONLY : m_dat
  922. USE global_data, ONLY : region_dat, mass_dat
  923. USE partools, ONLY : par_reduce_element
  924. use GO, ONLY : GO_Timer_End, GO_Timer_Start
  925. !
  926. ! !INPUT PARAMETERS:
  927. !
  928. INTEGER, INTENT(in) :: region
  929. !
  930. ! !OUTPUT PARAMETERS:
  931. !
  932. INTEGER, INTENT(out) :: status
  933. !
  934. ! !REVISION HISTORY:
  935. ! 23 Mar 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  936. !
  937. !EOP
  938. !------------------------------------------------------------------------
  939. !BOC
  940. CHARACTER(len=*), PARAMETER :: rname = mname//'/Boundary_Apply'
  941. ! Nudging coefficients for O3 and CH4
  942. REAL, PARAMETER :: gnud_pole = 2.894e-6 ! 1 / (4 days)
  943. REAL, PARAMETER :: gnud_hilat = 3.858e-6 ! 1 / (3 days)
  944. REAL, PARAMETER :: gnud_trop = 4.630e-6 ! 1 / (2.5 days)
  945. ! Nudging coefficients for HNO3 and CO (tested by B. Maasakkers, see KNMI internship report)
  946. REAL, PARAMETER :: gnud_hno3_5hpa = 2.315e-6 ! 1 / (5 days)
  947. REAL, PARAMETER :: gnud_hno3_10hpa = 5.587e-7 ! 1 / (10 days)
  948. REAL, PARAMETER :: gnud_hno3_28hpa = 1.987e-7 ! 1 / (60 days)
  949. REAL, PARAMETER :: gnud_hno3_43hpa = 2.572e-7 ! 1 / (45 days)
  950. REAL,DIMENSION(:,:,:), POINTER :: m, ppm
  951. REAL,DIMENSION(:,:,:,:), POINTER :: rm
  952. REAL,DIMENSION(:,:), ALLOCATABLE :: znl_lcl, zonal_glbl ! zonal (total or average), local and global
  953. INTEGER :: lmr, nlevels, nudge_lev, daystep
  954. INTEGER :: i, j, l, ipos, nzone, nzone_v, n, lm_min, nday
  955. REAL :: pr, dtime, dyy, xlat, gnud, o3za, ch4za, coza
  956. REAL :: rmold, rmold1, rmold2, z, z1, z2, rmobs, rmobs1, rmobs2
  957. INTEGER :: lsave, i1, i2, j1, j2
  958. REAL :: fraction_pm, fraction_cm, fraction_nm, daily_scale
  959. REAL :: diffmin, pressure(4), gnud_hno3(4), gnud_co(4)
  960. REAL :: nudgeFactor, tm5_o3_hno3_mix_ratio, tm5_o3_co_mix_ratio
  961. !
  962. ! no. days from 20th month till end
  963. !
  964. REAL, DIMENSION(12) :: nday_em = (/11.0, 8.0, 11.0, 10.0, 11.0, 10.0, 11.0, 11.0, 10.0, 11.0, 10.0, 11.0/)
  965. ! --- Begin ----------------------------------
  966. ! O3, O3S and CH4 are relaxed to climatology at stratospheric layers
  967. ! HNO3 is prescribed at level lm using ODIN or UARS HNO3:03 ratios
  968. ! CO is prescribed at level lm using ODIN CO:03 ratios
  969. ! start timing:
  970. call GO_Timer_Start( itim_appl, status )
  971. IF_NOTOK_RETURN(status=1)
  972. CALL goLabel(rname)
  973. CALL Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  974. lmr=lm(region)
  975. dtime=nsrce/(2*tref(region))
  976. dyy=dy/yref(region) !gridsize at current region
  977. rm => mass_dat(region)%rm
  978. m => m_dat (region)%data
  979. nday=sec_month/sec_day
  980. !
  981. ! Define the fractions from the previous and next months
  982. ! For the period 10-20th of each month fraction_cm=1.0
  983. !
  984. fraction_pm = 0.0 ; fraction_nm = 0.0 ; fraction_cm = 1.0
  985. if(idate(3) .lt. 10) then
  986. fraction_pm = 1.0-((idate(3)+nday_em(idate(2)))/((nday_em(idate(2))+10)))
  987. fraction_cm = 1.0-fraction_pm
  988. endif
  989. if(idate(3) .gt. 20) then
  990. fraction_nm = 0.5*(real(idate(3))-20.5)/(real(nday)-20.0)
  991. fraction_cm = 1.0-fraction_nm
  992. endif
  993. ! ---------------------------------------------------------------------
  994. ! Get the NUDGING FACTORS
  995. ! ---------------------------------------------------------------------
  996. ! Only for the global domain, for which we are sure a good Zonal Average
  997. ! can be calculated. The nudging factors are given by the ratio between
  998. ! the climatological zonal mean and the observed zonal mean.
  999. IF (region==1) THEN
  1000. ! Calculate the ratio of the climatology and the zonal mean model field.
  1001. ! The concentration at a given longitude is relaxed towards the ratio of
  1002. ! climatology and zonal mean model field multiplied by the model value
  1003. ALLOCATE( zonal_glbl(j1:j2, lm(1)) )
  1004. ALLOCATE( znl_lcl (j1:j2, lm(1)) )
  1005. ALLOCATE( ppm(i1:i2, j1:j2, lm(1)) )
  1006. ! ------ O3
  1007. ppm = 1e6*fscale(io3)*rm(i1:i2,j1:j2,:,io3)/m(i1:i2,j1:j2,:) ! into ppmv
  1008. znl_lcl=sum(ppm,dim=1) ! total zonal O3 in ppmv (local: i.e. only tile is accounted for)
  1009. CALL PAR_REDUCE_ELEMENT(znl_lcl, 'SUM', zonal_glbl, status, all=.true., row=.true.)
  1010. IF_NOTOK_RETURN(status=1)
  1011. ! zonal average
  1012. zonal_glbl = zonal_glbl/im(1)
  1013. DO l=1,lm(1)
  1014. DO j=j1,j2
  1015. !ratio clim/obs
  1016. IF ( zonal_glbl(j,l) == 0.0 ) THEN
  1017. o3ratpm(1)%d23(j,l) = 0.0
  1018. o3rat (1)%d23(j,l) = 0.0
  1019. o3ratnm(1)%d23(j,l) = 0.0
  1020. ELSE
  1021. o3ratpm(1)%d23(j,l) = o3vmrpm(1)%d23(j,l)/zonal_glbl(j,l)
  1022. o3rat (1)%d23(j,l) = o3vmr(1) %d23(j,l)/zonal_glbl(j,l)
  1023. o3ratnm(1)%d23(j,l) = o3vmrnm(1)%d23(j,l)/zonal_glbl(j,l)
  1024. END IF
  1025. ENDDO
  1026. ENDDO
  1027. ! ------ CH4
  1028. IF (use_HALOE) THEN ! else CH4rat remains 0 everywhere
  1029. ppm=1e6*fscale(ich4)*rm(i1:i2,j1:j2,:,ich4)/m(i1:i2,j1:j2,:)
  1030. znl_lcl=sum(ppm,dim=1) ! total zonal (local: i.e. tile only)
  1031. CALL PAR_REDUCE_ELEMENT(znl_lcl, 'SUM', zonal_glbl, status, all=.true., row=.true.)
  1032. IF_NOTOK_RETURN(status=1)
  1033. ! zonal average
  1034. zonal_glbl=zonal_glbl/im(1)
  1035. DO l=1,lm(1)
  1036. DO j=j1, j2
  1037. ! climatology/model ratio
  1038. IF ( zonal_glbl(j,l) == 0.0 ) THEN
  1039. CH4ratpm(1)%d23(j,l) = 0.0
  1040. CH4rat (1)%d23(j,l) = 0.0
  1041. CH4ratnm(1)%d23(j,l) = 0.0
  1042. ELSE
  1043. CH4ratpm(1)%d23(j,l) = ch4vmrpm(1)%d23(j,l)/zonal_glbl(j,l)
  1044. CH4rat (1)%d23(j,l) = ch4vmr (1)%d23(j,l)/zonal_glbl(j,l)
  1045. CH4ratnm(1)%d23(j,l) = ch4vmrnm(1)%d23(j,l)/zonal_glbl(j,l)
  1046. END IF
  1047. ENDDO
  1048. ENDDO
  1049. END IF
  1050. DEALLOCATE( ppm, znl_lcl, zonal_glbl)
  1051. ENDIF
  1052. ! ---------------------------------------------------------------------
  1053. ! Apply to O3 and CH4
  1054. ! ---------------------------------------------------------------------
  1055. DO j=j1,j2
  1056. xlat = ybeg(region) + (j+0.5)*dyy
  1057. IF (ABS(xlat) <= 30.0) THEN
  1058. lm_min = LVLPRESS(region, 4500., 98400.)
  1059. gnud = gnud_trop
  1060. ELSEIF(ABS(xlat)<66.0 ) THEN
  1061. lm_min = LVLPRESS(region, 9500., 98400.)
  1062. gnud = gnud_hilat
  1063. ELSE
  1064. lm_min = LVLPRESS(region, 12000., 98400.)
  1065. gnud = gnud_pole
  1066. ENDIF
  1067. DO l=lm_min,lm(region)
  1068. DO i=i1,i2
  1069. !
  1070. ! CMK: strictly spoken, the procedure om multi PEs is somewhat different.
  1071. ! Now they are independently nudged towards the same ZA!
  1072. ! In the long run, this will be the same! (hopefully) (FIXME : vraag MK wat betekend dat)
  1073. !
  1074. #ifndef without_o3_nudging
  1075. if(idate(3) .lt. 10) &
  1076. daily_scale = ((o3ratpm(region)%d23(j,l)*fraction_pm) + (o3rat(region)%d23(j,l)*fraction_cm))
  1077. if(idate(3) .gt. 9 .and. idate(3) .lt. 21) &
  1078. daily_scale = o3rat(region)%d23(j,l)
  1079. if(idate(3) .gt. 20) &
  1080. daily_scale = ((o3ratnm(region)%d23(j,l)*fraction_nm) + (o3rat(region)%d23(j,l)*fraction_cm))
  1081. rmobs = rm(i,j,l,io3)*daily_scale ! correct za
  1082. rmold = rm(i,j,l,io3) ! uncorrected value
  1083. z = (rmold+dtime*gnud*rmobs)/(1.+dtime*gnud) ! new concentration
  1084. rm(i,j,l,io3) = z
  1085. rmobs1 = rm(i,j,l,io3s)*daily_scale ! correct za
  1086. rmold1 = rm(i,j,l,io3s) ! uncorrected value
  1087. z1 = (rmold1+dtime*gnud*rmobs1)/(1.+dtime*gnud) ! new concentration
  1088. rm(i,j,l,io3s) = z1
  1089. #endif
  1090. if(idate(3) .lt. 10) &
  1091. daily_scale=((ch4ratpm(region)%d23(j,l)*fraction_pm) + (ch4rat(region)%d23(j,l)*fraction_cm))
  1092. if(idate(3) .gt. 9 .and. idate(3) .lt. 21) &
  1093. daily_scale=ch4rat(region)%d23(j,l)
  1094. if(idate(3) .gt. 20) &
  1095. daily_scale=((ch4ratnm(region)%d23(j,l)*fraction_nm)+ (ch4rat(region)%d23(j,l)*fraction_cm))
  1096. rmobs2 = rm(i,j,l,ich4)*daily_scale ! correct za
  1097. rmold2 = rm(i,j,l,ich4) ! uncorrected value
  1098. z2 = (rmold2+dtime*gnud*rmobs2)/(1.+dtime*gnud) ! new concentration
  1099. rm(i,j,l,ich4) = z2
  1100. #ifdef with_budgets
  1101. ! stratospheric budget....
  1102. nzone=budg_dat(region)%nzong(i,j) !global budget
  1103. nzone_v=nzon_vg(l)
  1104. #ifndef without_o3_nudging
  1105. budstratg(nzone,nzone_v,io3) = budstratg(nzone,nzone_v,io3) + (z-rmold)/xmo3*1e3 ! mole
  1106. budstratg(nzone,nzone_v,io3s) = budstratg(nzone,nzone_v,io3s) + (z1-rmold1)/xmo3*1e3 ! mole
  1107. #endif
  1108. budstratg(nzone,nzone_v,ich4) = budstratg(nzone,nzone_v,ich4) + (z2-rmold2)/xmch4*1e3 ! mole
  1109. ! #ifndef without_o3_nudging
  1110. ! IF( io3 == 1 ) THEN
  1111. ! sum_stratosphere(region) = sum_stratosphere(region) + z-rmold
  1112. ! END IF
  1113. ! IF ( io3s == 1 ) THEN
  1114. ! sum_stratosphere(region) = sum_stratosphere(region) + z1-rmold1
  1115. ! END IF
  1116. ! #endif
  1117. ! IF ( ich4 == 1 ) THEN
  1118. ! sum_stratosphere(region) = sum_stratosphere(region) + z2-rmold2
  1119. ! END IF
  1120. #endif /* BUDGETS */
  1121. END DO!i
  1122. END DO !l
  1123. END DO !j
  1124. !-------------------------------------------
  1125. ! set constraints for HNO3
  1126. !-------------------------------------------
  1127. IF (use_ODIN) then
  1128. nlevels=3 ! limit nudging to 3 top levels
  1129. pressure=(/550.0, 1122.0, 2820.0, 4365.0/) ! hPa
  1130. gnud_hno3 = (/gnud_hno3_5hpa, gnud_hno3_10hpa, gnud_hno3_28hpa, 0./)
  1131. ELSE
  1132. nlevels=1
  1133. pressure=(/1000.0, 0., 0., 0./) ! hPa
  1134. gnud_hno3 = (/gnud_hno3_10hpa, 0., 0., 0./)
  1135. ENDIF
  1136. DO nudge_lev=1,nlevels
  1137. lsave = 0 ! locate level closest to pressure[nudge_lev] hPa
  1138. diffmin = 1e10
  1139. DO l=1,lm(region)
  1140. pr = 0.5*(at(l)+at(l+1)) + 0.5*(bt(l)+bt(l+1))*1e5 ! pressure centre box
  1141. IF(ABS(pr-pressure(nudge_lev)) < diffmin) THEN
  1142. diffmin = ABS(pr-pressure(nudge_lev))
  1143. lsave = l
  1144. ENDIF
  1145. ENDDO
  1146. IF (use_ODIN) then
  1147. DO j=j1,j2
  1148. !
  1149. ! Smooth ratio between months to avoid spurious jumps in record
  1150. ! "daily_scale" is the time-interpolated ODIN climatology of the [HNO3]/[O3] ratio of mixing ratios
  1151. !
  1152. if ( idate(3) .lt. 10 ) &
  1153. daily_scale = odin_hno3_o3_pm(region)%d23(j,nudge_lev) * fraction_pm + &
  1154. odin_hno3_o3 (region)%d23(j,nudge_lev) * fraction_cm
  1155. if ( idate(3) .gt. 9 .and. idate(3) .lt. 21 ) &
  1156. daily_scale = odin_hno3_o3(region)%d23(j,nudge_lev)
  1157. if ( idate(3) .gt. 20 ) &
  1158. daily_scale = odin_hno3_o3_nm(region)%d23(j,nudge_lev) * fraction_nm + &
  1159. odin_hno3_o3 (region)%d23(j,nudge_lev) * fraction_cm
  1160. DO i=i1,i2
  1161. ! Include ratio of fscale factors, which convert from mass to mixing ratio
  1162. tm5_o3_hno3_mix_ratio = ( rm(i,j,lsave,io3) * fscale(io3) ) / ( rm(i,j,lsave,ihno3) * fscale(ihno3) )
  1163. nudgeFactor = ( 1.0 + dtime*gnud_hno3(NUDGE_LEV)*daily_scale*tm5_o3_hno3_mix_ratio ) / &
  1164. ( 1.0 + dtime*gnud_hno3(NUDGE_LEV) )
  1165. rmold = rm(i,j,lsave,ihno3)
  1166. z = rmold * nudgeFactor
  1167. rm(i,j,lsave,ihno3) = z
  1168. #ifdef with_budgets
  1169. ! stratospheric budget....
  1170. nzone=budg_dat(region)%nzong(i,j) !global budget
  1171. nzone_v=nzon_vg(lsave)
  1172. budstratg(nzone,nzone_v,ihno3)=budstratg(nzone,nzone_v,ihno3)+(z-rmold)/xmhno3*1e3 !mole
  1173. ! IF(ihno3 ==1) sum_stratosphere(region) = sum_stratosphere(region) + z-rmold
  1174. #endif
  1175. ENDDO!i
  1176. ENDDO!j
  1177. ELSE
  1178. DO j=j1,j2
  1179. DO i=i1,i2
  1180. rmold = rm(i,j,lsave,ihno3)
  1181. rmobs = rm(i,j,lsave,io3) * odin_hno3_o3(region)%d23(j,nudge_lev)
  1182. z = (rmold+dtime*gnud_hno3(NUDGE_LEV)*rmobs) / (1.+dtime*gnud_hno3(NUDGE_LEV)) !new concentration
  1183. rm(i,j,lsave,ihno3) = z
  1184. #ifdef with_budgets
  1185. ! stratospheric budget....
  1186. nzone=budg_dat(region)%nzong(i,j) !global budget
  1187. nzone_v=nzon_vg(lsave)
  1188. budstratg(nzone,nzone_v,ihno3)=budstratg(nzone,nzone_v,ihno3)+(z-rmold)/xmhno3*1e3 !mole
  1189. ! IF(ihno3 ==1) sum_stratosphere(region) = sum_stratosphere(region) + z-rmold
  1190. #endif
  1191. ENDDO!i
  1192. ENDDO!j
  1193. ENDIF
  1194. ENDDO ! nudge levels
  1195. ! This is not used (i.e. the global budget is not printed nor saved) so
  1196. ! this is commented. NOTE also that this should be moved to
  1197. ! chemistry/chemistry_done if ever used [PLS, 23-maart-2012]
  1198. !#ifdef with_budgets
  1199. ! CALL PAR_REDUCE(sum_stratosphere(region), 'SUM', sum_stratosphere(region), status)
  1200. ! IF_NOTOK_RETURN(status=1)
  1201. !#endif
  1202. !-------------------------------------------
  1203. ! Set constraints for CO nudging
  1204. !-------------------------------------------
  1205. IF (USE_ODIN) THEN
  1206. nlevels=3 ! limit nudging to 3 top levels
  1207. pressure=(/550.0, 1122.0, 2820.0, 4365.0/) ! hPa
  1208. gnud_co = (/gnud_hno3_5hpa, gnud_hno3_10hpa, gnud_hno3_28hpa, gnud_hno3_28hpa/)
  1209. DO nudge_lev=1,nlevels
  1210. lsave = 0 ! locate level closest to pressure level that is nudged
  1211. diffmin = 1e10
  1212. DO l=1,lm(region)
  1213. pr = 0.5*(at(l)+at(l+1)) + 0.5*(bt(l)+bt(l+1))*1e5 ! pressure centre box
  1214. IF(ABS(pr-1000.0) < diffmin) THEN
  1215. diffmin = ABS(pr-pressure(nudge_lev))
  1216. lsave = l
  1217. ENDIF
  1218. ENDDO
  1219. DO j=j1,j2
  1220. !
  1221. ! Smooth ratio between months to avoid spurious jumps in record
  1222. ! "daily_scale" is the time-interpolated ODIN climatology of the [CO]/[O3] ratio of mixing ratios
  1223. !
  1224. if ( idate(3) .lt. 10 ) &
  1225. daily_scale = odin_co_o3_pm(region)%d23(j,nudge_lev) * fraction_pm + &
  1226. odin_co_o3 (region)%d23(j,nudge_lev) * fraction_cm
  1227. if ( idate(3) .gt. 9 .and. idate(3) .lt. 21 ) &
  1228. daily_scale = odin_co_o3(region)%d23(j,nudge_lev)
  1229. if ( idate(3) .gt. 20 ) &
  1230. daily_scale = odin_co_o3_nm(region)%d23(j,nudge_lev) * fraction_nm + &
  1231. odin_co_o3 (region)%d23(j,nudge_lev) * fraction_cm
  1232. DO i=i1,i2
  1233. ! Include ratio of fscale factors, which convert from mass to mixing ratio
  1234. tm5_o3_co_mix_ratio = ( rm(i,j,lsave,io3) * fscale(io3) ) / ( rm(i,j,lsave,ico) * fscale(ico) )
  1235. nudgeFactor = ( 1.0 + dtime*gnud_co(NUDGE_LEV)*daily_scale*tm5_o3_co_mix_ratio ) / &
  1236. ( 1.0 + dtime*gnud_co(NUDGE_LEV) )
  1237. rmold = rm(i,j,lsave,ico)
  1238. z = rmold * nudgeFactor
  1239. rm(i,j,lsave,ico) = z
  1240. #ifdef with_budgets
  1241. ! stratospheric budget....
  1242. nzone=budg_dat(region)%nzong(i,j) !global budget
  1243. nzone_v=nzon_vg(lsave)
  1244. budstratg(nzone,nzone_v,ico)=budstratg(nzone,nzone_v,ico)+(z-rmold)/xmco*1e3 !mole
  1245. ! IF(ico ==1) sum_stratosphere(region) = sum_stratosphere(region) + z-rmold
  1246. #endif
  1247. ENDDO!i
  1248. ENDDO!j
  1249. ENDDO ! nudge levels
  1250. ENDIF
  1251. NULLIFY(rm)
  1252. NULLIFY(m)
  1253. ! end timing:
  1254. call GO_Timer_End( itim_appl, status )
  1255. IF_NOTOK_RETURN(status=1)
  1256. CALL goLabel()
  1257. status = 0
  1258. END SUBROUTINE BOUNDARY_APPLY
  1259. !EOC
  1260. END MODULE BOUNDARY