io_save.F90 76 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134
  1. !### macro's #####################################################
  2. !
  3. #define TRACEBACK write (gol,'("in ",a," (",a,", line",i5,")")') rname, __FILE__, __LINE__; call goErr
  4. #define IF_NOTOK_RETURN(action) if (status/=0) then; TRACEBACK; action; return; end if
  5. #define IF_ERROR_RETURN(action) if (status> 0) then; TRACEBACK; action; return; end if
  6. #define IF_NOTOK_MDF(action) if (status/=0) then; TRACEBACK; action; call MDF_CLose(fid,status); status=1; return; end if
  7. !
  8. #include "tm5.inc"
  9. !
  10. !-----------------------------------------------------------------------------
  11. ! TM5-MP !
  12. !-----------------------------------------------------------------------------
  13. !BOP
  14. !
  15. ! !MODULE: IO_SAVE
  16. !
  17. ! !DESCRIPTION: Contains routines to read HDF emissions files and
  18. ! the main model state (as replacement for restart file).
  19. !\\
  20. !\\
  21. ! !INTERFACE:
  22. !
  23. MODULE IO_SAVE
  24. !
  25. ! !USES:
  26. !
  27. use GO, only : gol, goErr, goPr, goBug
  28. use GO, only : TrcFile, InitRc => Init, DoneRc => Done, ReadRc
  29. use global_data, only : rcfile
  30. IMPLICIT NONE
  31. PRIVATE
  32. !
  33. ! !PUBLIC MEMBER FUNCTIONS:
  34. !
  35. PUBLIC :: READHDFMMR ! Read mmix from "old save file" (istart=4 )
  36. PUBLIC :: READ_MMIX ! Read mmix file (mean mixing ratio of transported tracers) (istart=5 )
  37. PUBLIC :: READ_SAVE_FILE_30 ! Read save-file (mixing ratio, opt. slopes, of transported tracers) (istart=30)
  38. PUBLIC :: READ_SAVE_FILE ! Read save file (mass of all tracers, grid info) (istart=31)
  39. PUBLIC :: WRITE_SAVE_FILE ! Write save-file (to be read with read_save_file)
  40. PUBLIC :: READ_HDF4 ! Read a record from hdf file (new way)
  41. PUBLIC :: READTM3HDF ! Read a record from hdf file (old way, a la TM3)
  42. PUBLIC :: READ_SCATTER_HDF ! Read a record from hdf file, and do the MPI scattering
  43. !
  44. ! !PRIVATE DATA MEMBERS:
  45. !
  46. character(len=*), parameter :: mname = 'io_save'
  47. type(TrcFile) :: rcF
  48. integer :: fid ! file id for IF_NOTOK_MDF macro
  49. !
  50. ! !INTERFACE:
  51. !
  52. INTERFACE READ_HDF4
  53. MODULE PROCEDURE READ_HDF4_2DR
  54. END INTERFACE
  55. !
  56. ! !REVISION HISTORY:
  57. ! 16 Nov 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  58. !
  59. ! !REMARKS:
  60. ! (1) The READTM3 routines are kept for quick fix when converting old code.
  61. ! All new code should use the MDF module to read any data.
  62. !
  63. !EOP
  64. !------------------------------------------------------------------------
  65. CONTAINS
  66. !--------------------------------------------------------------------------
  67. ! TM5 !
  68. !--------------------------------------------------------------------------
  69. !BOP
  70. !
  71. ! !IROUTINE: READ_HDF4_2DR
  72. !
  73. ! !DESCRIPTION: read one 2D record of real from an HDF4 file.
  74. !
  75. !\\
  76. !\\
  77. ! !INTERFACE:
  78. !
  79. SUBROUTINE READ_HDF4_2DR(fname, odata, status, dir, vname, vid)
  80. !
  81. ! !USES:
  82. !
  83. USE MDF, ONLY : MDF_Open, MDF_HDF4, MDF_READ, MDF_Inq_VarID, MDF_Get_Var, MDF_Close
  84. USE global_data, ONLY : inputdir
  85. !
  86. ! !INPUT PARAMETERS:
  87. !
  88. character(len=*), intent(in) :: fname ! name of HDF file to read
  89. character(len=*), intent(in), optional :: dir ! dir where file is. Default is "inputdir"
  90. character(len=*), intent(in), optional :: vname ! record name. Default is to use record #0.
  91. integer, intent(in), optional :: vid ! record id #. Default is to use record #0.
  92. !
  93. ! !OUTPUT PARAMETERS:
  94. !
  95. real, intent(out) :: odata(:,:)
  96. integer, intent(out) :: status
  97. !
  98. ! !REVISION HISTORY:
  99. ! 28 Mar 2012 - P. Le Sager - v0
  100. !
  101. ! !REMARKS:
  102. ! (1) This wrapper around MDF routines is only for convenience: a lot of
  103. ! calls for the chemistry emissions, and participate to the effort
  104. ! of getting rid of file_hdf.f90 routine, in favor of the MDF module.
  105. ! (2) By default **FIRST** record is read, unless another variable number
  106. ! (vid) and/or variable name (vname) is passed. If both vid and vname
  107. ! are passed, vname is ignored.
  108. !
  109. !EOP
  110. !------------------------------------------------------------------------
  111. !BOC
  112. character(len=*), parameter :: rname = mname//'/read_hdf4_2dr'
  113. character(len=512):: Lvname, Ldir
  114. integer :: Lvid
  115. !--- check input
  116. Ldir=inputdir
  117. if(present(dir)) Ldir=dir
  118. Lvname=''
  119. if(present(vname)) Lvname=vname
  120. Lvid=1
  121. if (present(vid)) then
  122. Lvid=vid
  123. Lvname=''
  124. end if
  125. !--- read
  126. CALL MDF_Open( trim(Ldir)//'/'//TRIM(fname), MDF_HDF4, MDF_READ, fid, status )
  127. IF_NOTOK_RETURN(status=1)
  128. if (len(trim(Lvname))/=0) then
  129. CALL MDF_Inq_VarID( fid, TRIM(Lvname), Lvid, status )
  130. IF_NOTOK_MDF(status=1)
  131. end if
  132. CALL MDF_Get_Var( fid, Lvid, odata, status )
  133. IF_NOTOK_MDF(status=1)
  134. CALL MDF_Close( fid, status )
  135. IF_NOTOK_RETURN(status=1)
  136. status=0
  137. END SUBROUTINE READ_HDF4_2DR
  138. !EOC
  139. ! ======================================================================
  140. !WP! this subroutine reads HDF emissions files on
  141. ! 1x1 degree resolution and returns the specified field.
  142. !WP! input for this subroutine are:
  143. !WP!
  144. !WP! filename --> name of hdf file to be opened or read
  145. !MK! rank --> rank of the dataset (1,2,3)
  146. !WP! im_emis --> x-DIMENSION of requested field
  147. !WP! jm_emis --> y-DIMENSION of requested field
  148. !WP! lm_emis --> z-DIMENSION of requested field
  149. !WP! month --> the month to read (0 for january or simply the first field)
  150. !WP! field --> the field (im_emis,jm_emis,lm_emis) to put the values in
  151. !WP! field_name --> the name of the field to match the one in the HDF file
  152. !WP!
  153. !WP! The routine checks the dimensions and reports the succes/failure.
  154. subroutine readtm3hdf( filename, rank, im_emis, jm_emis, lm_emis, &
  155. month, field, field_name, idt )
  156. use file_hdf, only : THdfFile, Init, Done
  157. use io_hdf , only : FAIL
  158. use io_hdf , only : io_read2d_32g, io_read3d_32g
  159. use toolbox , only : escape_tm
  160. ! --- in/out --------------------------------------
  161. character(len=*),intent(in) :: filename
  162. character(len=*),intent(in) :: field_name
  163. integer,intent(in) :: rank
  164. integer,intent(in) :: month
  165. integer,intent(in) :: im_emis, jm_emis, lm_emis
  166. real,dimension(im_emis,jm_emis,lm_emis),intent(out) :: field
  167. integer,dimension(6),optional :: idt
  168. ! --- local ----------------------------------------
  169. type(THdfFile) :: hdf
  170. integer :: status
  171. integer :: idx
  172. real, allocatable :: field1d(:) ! first dim will be 1
  173. real, allocatable :: field2d(:,:)
  174. real, allocatable :: field3d(:,:,:)
  175. ! --- begin -------------------------------------------
  176. ! open hdf file:
  177. call Init( hdf, trim(filename), 'read', status )
  178. if (status/=0) call escape_tm('ERROR in readtm3hdf')
  179. !FD hdf files indices run from 0 ...n-1
  180. idx = month
  181. select case(rank)
  182. case(1) ! latitudional field
  183. allocate(field1d(jm_emis))
  184. if(present(idt)) call io_read2d_32g(hdf%id,im_emis,jm_emis,field1d,field_name, status,idate=idt)
  185. if(.not.present(idt)) call io_read2d_32g(hdf%id,im_emis,jm_emis,field1d,field_name, status,index=idx)
  186. if ( status /= 0 ) then
  187. write(gol,*) 'readtm3hdf: io_read2d_32g failed:' ; call goPr
  188. write(gol,*) 'readtm3hdf: filename : ', trim(filename) ; call goPr
  189. write(gol,*) 'readtm3hdf: rank : ', rank ; call goPr
  190. write(gol,*) 'readtm3hdf: im_emis : ', im_emis ; call goPr
  191. write(gol,*) 'readtm3hdf: jm_emis : ', jm_emis ; call goPr
  192. write(gol,*) 'readtm3hdf: lm_emis : ', lm_emis ; call goPr
  193. write(gol,*) 'readtm3hdf: month : ', month ; call goPr
  194. write(gol,*) 'readtm3hdf: field_name : ', trim(field_name); call goPr
  195. if (present(idt)) write(gol,*) 'readtm3hdf: idt : ', idt; call goPr
  196. call escape_tm('readtm3hdf: Error reading HDF file 1D')
  197. end if
  198. field(1,:,1)=field1d
  199. deallocate(field1d)
  200. case(2) ! 2D surface field
  201. allocate(field2d(im_emis,jm_emis))
  202. if(present(idt)) call io_read2d_32g(hdf%id,im_emis,jm_emis,field2d,field_name, status,idate=idt)
  203. if(.not.present(idt)) call io_read2d_32g(hdf%id,im_emis,jm_emis,field2d,field_name, status,index=idx)
  204. if ( status /= 0 ) then
  205. write(gol,*) 'readtm3hdf: io_read2d_32g failed:' ; call goPr
  206. write(gol,*) 'readtm3hdf: filename : ', trim(filename) ; call goPr
  207. write(gol,*) 'readtm3hdf: rank : ', rank ; call goPr
  208. write(gol,*) 'readtm3hdf: im_emis : ', im_emis ; call goPr
  209. write(gol,*) 'readtm3hdf: jm_emis : ', jm_emis ; call goPr
  210. write(gol,*) 'readtm3hdf: lm_emis : ', lm_emis ; call goPr
  211. write(gol,*) 'readtm3hdf: month : ', month ; call goPr
  212. write(gol,*) 'readtm3hdf: field_name : ', trim(field_name) ; call goPr
  213. if (present(idt)) write(gol,*) 'readtm3hdf: idt : ', idt ; call goPr
  214. call escape_tm('readtm3hdf: Error reading HDF file 2D')
  215. endif
  216. field(:,:,1)=field2d
  217. deallocate(field2d)
  218. case (3) ! 3D field
  219. allocate(field3d(im_emis,jm_emis,lm_emis))
  220. if(present(idt)) call io_read3d_32g(hdf%id,im_emis,jm_emis,lm_emis,field3d,field_name, status,idate=idt)
  221. if(.not.present(idt)) call io_read3d_32g(hdf%id,im_emis,jm_emis,lm_emis,field3d,field_name, status,index=idx)
  222. if ( status /= 0 ) then
  223. write(gol,*) 'readtm3hdf: io_read2d_32g failed:' ; call goPr
  224. write(gol,*) 'readtm3hdf: filename : ', trim(filename) ; call goPr
  225. write(gol,*) 'readtm3hdf: rank : ', rank ; call goPr
  226. write(gol,*) 'readtm3hdf: im_emis : ', im_emis ; call goPr
  227. write(gol,*) 'readtm3hdf: jm_emis : ', jm_emis ; call goPr
  228. write(gol,*) 'readtm3hdf: lm_emis : ', lm_emis ; call goPr
  229. write(gol,*) 'readtm3hdf: month : ', month ; call goPr
  230. write(gol,*) 'readtm3hdf: field_name : ', trim(field_name) ; call goPr
  231. if (present(idt)) write(gol,*) 'readtm3hdf: idt : ', idt ; call goPr
  232. call escape_tm('readtm3hdf: Error reading HDF file 3D')
  233. endif
  234. field(:,:,:)=field3d
  235. deallocate(field3d)
  236. case (23) ! 2D field lat-pres
  237. allocate(field2d(jm_emis,lm_emis))
  238. if(present(idt)) call io_read2d_32g(hdf%id,jm_emis,lm_emis,field2d,field_name, status,idate=idt)
  239. if(.not.present(idt)) call io_read2d_32g(hdf%id,jm_emis,lm_emis,field2d,field_name, status,index=idx)
  240. if ( status /= 0 ) then !might be due to (1,jm,lm) file!
  241. write(gol,*) 'readtm3hdf: try shape : ', 1, jm_emis, lm_emis
  242. allocate(field3d(1,jm_emis,lm_emis))
  243. if ( present(idt) ) then
  244. call io_read3d_32g(hdf%id,1,jm_emis,lm_emis,field3d,field_name, status,idate=idt)
  245. else
  246. call io_read3d_32g(hdf%id,1,jm_emis,lm_emis,field3d,field_name, status,index=idx)
  247. end if
  248. if ( status /= 0 ) then
  249. write(gol,*) 'readtm3hdf: io_read2d_32g failed:' ; call goPr
  250. write(gol,*) 'readtm3hdf: filename : ', trim(filename) ; call goPr
  251. write(gol,*) 'readtm3hdf: rank : ', rank ; call goPr
  252. write(gol,*) 'readtm3hdf: im_emis : ', im_emis ; call goPr
  253. write(gol,*) 'readtm3hdf: jm_emis : ', jm_emis ; call goPr
  254. write(gol,*) 'readtm3hdf: lm_emis : ', lm_emis ; call goPr
  255. write(gol,*) 'readtm3hdf: month : ', month ; call goPr
  256. write(gol,*) 'readtm3hdf: field_name : ', trim(field_name) ; call goPr
  257. if (present(idt)) write(gol,*) 'readtm3hdf: idt : ', idt ; call goPr
  258. call escape_tm('readtm3hdf: Error reading HDF file 23')
  259. end if
  260. field(:,:,:)=field3d
  261. deallocate(field3d)
  262. else
  263. field(1,:,:)=field2d
  264. end if
  265. deallocate(field2d)
  266. case default
  267. write (gol,*) 'readtm3hdf: Please check the rank of the required field,', &
  268. ' must be 1,2,3, or 23'; call goPr
  269. end select
  270. ! close:
  271. call Done( hdf, status )
  272. if (status/=0) call escape_tm('ERROR in readtm3hdf')
  273. !if ( idx >= 0 ) then
  274. ! write (gol,*) 'readtm3hdf: ',trim(filename),' ; ds#= ',idx+1; call goPr
  275. ! write (gol,*) 'readtm3hdf: total month sum after reading the full field', &
  276. ! sum(field)/1e9 ,' (x1e9) '; call goPr
  277. !end if
  278. end subroutine readtm3hdf
  279. !--------------------------------------------------------------------------
  280. ! TM5 !
  281. !--------------------------------------------------------------------------
  282. !BOP
  283. !
  284. ! !IROUTINE: READ_SCATTER_HDF
  285. !
  286. ! !DESCRIPTION: simple adaptation of readtm3hdf to use MDF module, and
  287. ! scatter data.
  288. !\\
  289. !\\
  290. ! !INTERFACE:
  291. !
  292. SUBROUTINE READ_SCATTER_HDF( filename, rank, region, i1, j1, field, status, &
  293. idx, field_name, idt )
  294. !
  295. ! !USES:
  296. !
  297. use partools, only : isRoot
  298. use tm5_distgrid, only : dgrid, Get_DistGrid, scatter
  299. !
  300. ! !INPUT PARAMETERS:
  301. !
  302. character(len=*), intent(in) :: filename ! HDF4 file to read
  303. integer, intent(in) :: rank ! 1,2,.. [only 2 implemented for now]
  304. integer, intent(in) :: region, i1, j1 ! region and local array start index
  305. integer, intent(in), optional :: idx ! variable id in [1..nmax]
  306. character(len=*), intent(in), optional :: field_name ! variable name, ignored if idx set
  307. integer, intent(in), optional :: idt(6) ! date [not implemented]
  308. !
  309. ! !OUTPUT PARAMETERS:
  310. !
  311. real, intent(out) :: field(i1:,j1:) ! scattered read data
  312. integer, intent(out) :: status
  313. !
  314. ! !REVISION HISTORY:
  315. ! 23 Jan 2012 - P. Le Sager - for lat-lon mpi decomposition
  316. !
  317. ! !REMARKS:
  318. ! (1) tested only with rank=2 (see dry_deposition.F90)
  319. ! (2) not all features of readtm3hdf are available, but probably also
  320. ! not needed... will add as needed.
  321. !EOP
  322. !------------------------------------------------------------------------
  323. !BOC
  324. character(len=*), parameter :: rname = mname//'/read_scatter_hdf'
  325. integer :: im_emis, jm_emis
  326. real, allocatable :: field1d(:)
  327. real, allocatable :: field2d(:,:)
  328. ! --- begin -------------------------------------------
  329. CALL GET_DISTGRID( DGRID(region), I_WRLD=im_emis, J_WRLD=jm_emis )
  330. status=0
  331. READ: if (isRoot) then
  332. allocate(field2d(im_emis,jm_emis))
  333. field2D=0.
  334. select case(rank)
  335. ! case(1) ! latitudional field
  336. !
  337. ! allocate(field1d(jm_emis))
  338. ! if(present(idt)) call io_read2d_32g(hdf%id,im_emis,jm_emis,field1d,field_name, status,idate=idt)
  339. ! if(.not.present(idt)) call io_read2d_32g(hdf%id,im_emis,jm_emis,field1d,field_name, status,index=idx)
  340. ! if ( status /= 0 ) then
  341. ! write(gol,*) 'readtm3hdf: io_read2d_32g failed:'
  342. ! write(gol,*) 'readtm3hdf: filename : ', trim(filename)
  343. ! write(gol,*) 'readtm3hdf: rank : ', rank
  344. ! write(gol,*) 'readtm3hdf: im_emis : ', im_emis
  345. ! write(gol,*) 'readtm3hdf: jm_emis : ', jm_emis
  346. ! write(gol,*) 'readtm3hdf: month : ', month
  347. ! write(gol,*) 'readtm3hdf: field_name : ', trim(field_name)
  348. ! if (present(idt)) write(gol,*) 'readtm3hdf: idt : ', idt
  349. ! call escape_tm('readtm3hdf: Error reading HDF file 1D')
  350. ! end if
  351. ! field2D(1,:)=field1d
  352. ! deallocate(field1d)
  353. case(2) ! 2D surface field
  354. call READ_HDF4(filename, field2d, status, dir='', vname=field_name, vid=idx)
  355. IF_NOTOK_RETURN(status=1)
  356. case default
  357. write (gol,*) rname//' : Please check the rank of the required field,', &
  358. ' must be 1,2,3, or 23'; call goPr
  359. status=1
  360. end select
  361. else
  362. allocate(field2d(1,1))
  363. end if READ
  364. call SCATTER( dgrid(region), field, field2d, 0, status)
  365. IF_NOTOK_RETURN(status=1)
  366. deallocate(field2d)
  367. END SUBROUTINE READ_SCATTER_HDF
  368. !EOC
  369. !--------------------------------------------------------------------------
  370. ! TM5 !
  371. !--------------------------------------------------------------------------
  372. !BOP
  373. !
  374. ! !IROUTINE: READ_SAVE_FILE_30
  375. !
  376. ! !DESCRIPTION: reads initial MIXING RATIO (+ slopes, and second moments if
  377. ! they are switched on) of TRANSPORTED tracers from HDF-4
  378. ! "save files". The save file must be specified in rc file with key:
  379. !
  380. ! start.30.<region-name>
  381. !
  382. ! No regridding available.
  383. !
  384. ! Used for istart=30.
  385. !\\
  386. !\\
  387. ! !INTERFACE:
  388. !
  389. SUBROUTINE READ_SAVE_FILE_30( region, file_name, status )
  390. !
  391. ! !USES:
  392. !
  393. use io_hdf
  394. use dims, only : im, jm, lm
  395. use global_data, only : mass_dat
  396. use meteodata , only : m_dat
  397. use chem_param, only : ntracet
  398. use partools, only : isRoot
  399. use tm5_distgrid, only : dgrid, Get_DistGrid, scatter
  400. !
  401. ! !INPUT PARAMETERS:
  402. !
  403. integer, intent(in) :: region
  404. character(len=*), intent(in) :: file_name
  405. !
  406. ! !OUTPUT PARAMETERS:
  407. !
  408. integer, intent(out) :: status
  409. !
  410. ! !REVISION HISTORY:
  411. ! 4 Oct 2011 - P. Le Sager - TM5-MP version
  412. !
  413. ! !REMARKS:
  414. ! (1) no zoom (must put from_file stuff back in)
  415. ! (2) FIXME: not tested...
  416. !
  417. !EOP
  418. !------------------------------------------------------------------------
  419. !BOC
  420. character(len=*), parameter :: rname = mname//'/read_save_file_30'
  421. real,dimension(:,:,:,:),pointer :: rm
  422. real,dimension(:,:,:,:),pointer :: rxm,rym,rzm
  423. #ifdef secmom
  424. real,dimension(:,:,:,:),pointer :: rxxm,rxym,rxzm,ryym,ryzm,rzzm
  425. #endif
  426. real,dimension(:,:,:),pointer :: m
  427. integer :: io, sfstart
  428. integer :: istat
  429. integer :: sfend
  430. integer :: i,j,l,n
  431. integer :: imr,jmr,lmr, halo
  432. real,dimension(:,:,:,:), allocatable :: field
  433. real,dimension(:,:,:), allocatable :: msave, msave_local
  434. integer :: i1, i2, j1, j2
  435. ! --- begin --------------------------------
  436. m => m_dat(region)%data
  437. rm => mass_dat(region)%rm
  438. #ifdef slopes
  439. rxm => mass_dat(region)%rxm
  440. rym => mass_dat(region)%rym
  441. rzm => mass_dat(region)%rzm
  442. #ifdef secmom
  443. rxxm => mass_dat(region)%rxxm
  444. rxym => mass_dat(region)%rxym
  445. rxzm => mass_dat(region)%rxzm
  446. ryym => mass_dat(region)%ryym
  447. ryzm => mass_dat(region)%ryzm
  448. rzzm => mass_dat(region)%rzzm
  449. #endif
  450. #endif
  451. halo = mass_dat(region)%halo
  452. ! global array
  453. imr = im(region) ; jmr = jm(region) ; lmr = lm(region)
  454. if ( isRoot ) then
  455. allocate(field(imr, jmr, lmr, ntracet))
  456. field = 0.0
  457. allocate(msave(imr,jmr,lmr))
  458. else
  459. allocate(field(1,1,1,1))
  460. allocate(msave(1,1,1))
  461. end if
  462. ! local indices
  463. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  464. allocate(msave_local(i1:i2,j1:j2,lmr))
  465. ! read on root
  466. if ( isRoot ) then
  467. io = sfstart( file_name, DFACC_READ )
  468. if ( io == FAIL ) then
  469. write(gol,*) 'Read_save_file_30 : Could not open file '// trim(file_name) ; call goPr
  470. call goErr
  471. TRACEBACK ; status=1 ; return
  472. end if
  473. write(gol,'("Read_save_file_30: opened for READ access: ",a)') trim(file_name); call goPr
  474. call io_read3d_32g(io,imr,jmr,lmr,msave,'m',status)
  475. IF_NOTOK_RETURN(status=1)
  476. call io_read4d_32g(io,imr,jmr,lmr,ntracet, field,'rm',status)
  477. ! try again
  478. if( status /= 0 .and. ntracet == 1 ) then
  479. call io_read3d_32g(io,imr,jmr,lmr,field,'rm',status)
  480. end if
  481. IF_NOTOK_RETURN(write (*,'("read_save_file_30: Read rm, status = ",i6)') status)
  482. end if !root
  483. ! get local chunk
  484. call SCATTER( dgrid(region), rm, field, halo, status)
  485. IF_NOTOK_RETURN(status=1)
  486. field = 0.0
  487. call SCATTER( dgrid(region), msave_local, msave, 0, status)
  488. IF_NOTOK_RETURN(status=1)
  489. #ifdef slopes
  490. if ( isRoot ) then
  491. call io_read4d_32g(io,imr,jmr,lmr,ntracet,field,'rxm',status)
  492. if ( status /= 0 .and. ntracet == 1 ) then
  493. call io_read3d_32g(io,imr,jmr,lmr,field,'rxm',status)
  494. end if
  495. IF_NOTOK_RETURN(write (*,'("read_save_file_30: status = ",i6)') status)
  496. end if
  497. ! get local chunk
  498. call SCATTER( dgrid(region), rxm, field, halo, status)
  499. IF_NOTOK_RETURN(status=1)
  500. field = 0.0
  501. if(isRoot) then
  502. call io_read4d_32g(io,imr,jmr,lmr,ntracet,field,'rym',status)
  503. if ( status /= 0 .and. ntracet == 1 ) then
  504. call io_read3d_32g(io,imr,jmr,lmr,field,'rym',status)
  505. end if
  506. IF_NOTOK_RETURN(write (*,'("read_save_file_30: status = ",i6)') status)
  507. end if !root
  508. ! get local chunk
  509. call SCATTER( dgrid(region), rym, field, halo, status)
  510. IF_NOTOK_RETURN(status=1)
  511. field = 0.0
  512. if ( isRoot ) then
  513. call io_read4d_32g(io,imr,jmr,lmr,ntracet,field,'rzm',status)
  514. if ( status /= 0 .and. ntracet == 1 ) then
  515. call io_read3d_32g(io,imr,jmr,lmr,field,'rzm',status)
  516. end if
  517. IF_NOTOK_RETURN(write (*,'("read_save_file_30: status = ",i6)') status)
  518. end if
  519. ! get local chunk
  520. call SCATTER( dgrid(region), rzm, field, halo, status)
  521. IF_NOTOK_RETURN(status=1)
  522. ! reset
  523. field = 0.0
  524. #endif
  525. ! >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  526. ! >>> second moments
  527. ! >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  528. #ifdef secmom
  529. if ( isRoot) then
  530. call io_read4d_32g(io,imr,jmr,lmr,ntracet,field,'rxxm',status)
  531. if ( status /= 0 .and. ntracet == 1 ) then
  532. call io_read3d_32g(io,imr,jmr,lmr,field,'rxxm',status)
  533. end if
  534. IF_NOTOK_RETURN(write (*,'("read_save_file_30: status = ",i6)') status)
  535. endif
  536. call SCATTER( dgrid(region), rxxm, field, halo, status)
  537. IF_NOTOK_RETURN(status=1)
  538. field = 0.0
  539. if(isRoot) then
  540. call io_read4d_32g(io,imr,jmr,lmr,ntracet,field,'rxym',status)
  541. if ( status /= 0 .and. ntracet == 1 ) then
  542. call io_read3d_32g(io,imr,jmr,lmr,field,'rxym',status)
  543. end if
  544. IF_NOTOK_RETURN(write (*,'("read_save_file_30: status = ",i6)') status)
  545. endif
  546. call SCATTER( dgrid(region), rxym, field, halo, status)
  547. IF_NOTOK_RETURN(status=1)
  548. field = 0.0
  549. if(isRoot) then
  550. call io_read4d_32g(io,imr,jmr,lmr,ntracet,field,'rxzm',status)
  551. if ( status /= 0 .and. ntracet == 1 ) then
  552. call io_read3d_32g(io,imr,jmr,lmr,field,'rxzm',status)
  553. end if
  554. IF_NOTOK_RETURN(write (*,'("read_save_file_30: status = ",i6)') status)
  555. endif
  556. call SCATTER( dgrid(region), rxzm, field, halo, status)
  557. IF_NOTOK_RETURN(status=1)
  558. field = 0.0
  559. if(isRoot) then
  560. call io_read4d_32g(io,imr,jmr,lmr,ntracet,field,'ryym',status)
  561. if ( status /= 0 .and. ntracet == 1 ) then
  562. call io_read3d_32g(io,imr,jmr,lmr,field,'ryym',status)
  563. end if
  564. IF_NOTOK_RETURN(write (*,'("read_save_file_30: status = ",i6)') status)
  565. endif
  566. call SCATTER( dgrid(region), ryym, field, halo, status)
  567. IF_NOTOK_RETURN(status=1)
  568. field = 0.0
  569. if(isRoot) then
  570. call io_read4d_32g(io,imr,jmr,lmr,ntracet,field,'ryzm',status)
  571. if ( status /= 0 .and. ntracet == 1 ) then
  572. call io_read3d_32g(io,imr,jmr,lmr,field,'ryzm',status)
  573. end if
  574. IF_NOTOK_RETURN(write (*,'("read_save_file_30: status = ",i6)') status)
  575. endif
  576. call SCATTER( dgrid(region), ryzm, field, halo, status)
  577. IF_NOTOK_RETURN(status=1)
  578. ! reset
  579. field = 0.0
  580. if(isRoot) then
  581. call io_read4d_32g(io,imr,jmr,lmr,ntracet,field,'rzzm',status)
  582. if ( status /= 0 .and. ntracet == 1 ) then
  583. call io_read3d_32g(io,imr,jmr,lmr,field,'rzzm',status)
  584. end if
  585. IF_NOTOK_RETURN(write (*,'("read_save_file_30: status = ",i6)') status)
  586. endif
  587. call SCATTER( dgrid(region), rzzm, field, halo, status)
  588. IF_NOTOK_RETURN(status=1)
  589. field = 0.0
  590. #endif
  591. ! <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  592. ! <<< end second moments
  593. ! <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  594. if ( isRoot ) then
  595. istat = sfend(io)
  596. if ( istat /= FAIL ) then
  597. write(gol,'("read_save_file_30: ... file closed")') ; call goPr
  598. write(gol,'("read_save_file_30: ")') ; call goPr
  599. else
  600. TRACEBACK ; status=1 ; return
  601. end if
  602. end if
  603. ! CONVERSION
  604. ! rm/msave ---> mixing ratio on file. mr*m --> something back in kilo's
  605. if ( isRoot ) then
  606. write(gol,*) 'read_save_file_30: Maximum ratio of the air masses:', &
  607. maxval(abs(msave/m(1:imr,1:jmr,1:lmr))) ; call goPr
  608. write(gol,*) 'read_save_file_30: Minimum ratio of the air masses:', &
  609. minval(abs(msave/m(1:imr,1:jmr,1:lmr))) ; call goPr
  610. end if
  611. do n = 1, ntracet
  612. do l = 1, lmr
  613. rm(i1:i2,j1:j2,l,n) = rm (i1:i2,j1:j2,l,n)*m(i1:i2,j1:j2,l)/msave_local(i1:i2,j1:j2,l)
  614. #ifdef slopes
  615. rxm(i1:i2,j1:j2,l,n) = rxm(i1:i2,j1:j2,l,n)*m(i1:i2,j1:j2,l)/msave_local(i1:i2,j1:j2,l)
  616. rym(i1:i2,j1:j2,l,n) = rym(i1:i2,j1:j2,l,n)*m(i1:i2,j1:j2,l)/msave_local(i1:i2,j1:j2,l)
  617. rzm(i1:i2,j1:j2,l,n) = rzm(i1:i2,j1:j2,l,n)*m(i1:i2,j1:j2,l)/msave_local(i1:i2,j1:j2,l)
  618. #ifdef secmom
  619. rxxm(i1:i2,j1:j2,l,n) = rxxm(i1:i2,j1:j2,l,n)*m(i1:i2,j1:j2,l)/msave_local(i1:i2,j1:j2,l)
  620. rxym(i1:i2,j1:j2,l,n) = rxym(i1:i2,j1:j2,l,n)*m(i1:i2,j1:j2,l)/msave_local(i1:i2,j1:j2,l)
  621. rxzm(i1:i2,j1:j2,l,n) = rxzm(i1:i2,j1:j2,l,n)*m(i1:i2,j1:j2,l)/msave_local(i1:i2,j1:j2,l)
  622. ryym(i1:i2,j1:j2,l,n) = ryym(i1:i2,j1:j2,l,n)*m(i1:i2,j1:j2,l)/msave_local(i1:i2,j1:j2,l)
  623. ryzm(i1:i2,j1:j2,l,n) = ryzm(i1:i2,j1:j2,l,n)*m(i1:i2,j1:j2,l)/msave_local(i1:i2,j1:j2,l)
  624. rzzm(i1:i2,j1:j2,l,n) = rzzm(i1:i2,j1:j2,l,n)*m(i1:i2,j1:j2,l)/msave_local(i1:i2,j1:j2,l)
  625. #endif
  626. #endif
  627. end do
  628. end do
  629. ! cleanup
  630. deallocate(msave, msave_local)
  631. deallocate(field)
  632. nullify(m)
  633. nullify(rm)
  634. #ifdef slopes
  635. nullify(rxm)
  636. nullify(rym)
  637. nullify(rzm)
  638. #ifdef secmom
  639. nullify(rxxm)
  640. nullify(rxym)
  641. nullify(rxzm)
  642. nullify(ryym)
  643. nullify(ryzm)
  644. nullify(rzzm)
  645. #endif
  646. #endif
  647. END SUBROUTINE READ_SAVE_FILE_30
  648. !EOC
  649. !--------------------------------------------------------------------------
  650. ! TM5 !
  651. !--------------------------------------------------------------------------
  652. !BOP
  653. !
  654. ! !IROUTINE: READHDFMMR
  655. !
  656. ! !DESCRIPTION: read tracer mixing ratio from so-called "old save" file and
  657. ! uses air mass to convert to mass, in order to initialize the
  658. ! model.
  659. !
  660. ! Used with option istart=4
  661. !\\
  662. !\\
  663. ! !INTERFACE:
  664. !
  665. SUBROUTINE READHDFMMR( region, file_name, status )
  666. !
  667. ! !USES:
  668. !
  669. use dims, only : im, jm, lm, nregions, datadir, region_name
  670. use io_hdf
  671. use global_data, only : mass_dat
  672. use meteodata , only : m_dat
  673. use chem_param, only : fscale, ntracet
  674. use tm5_distgrid, only : dgrid, Get_DistGrid, scatter
  675. use partools, only : isRoot
  676. !
  677. ! !INPUT PARAMETERS:
  678. !
  679. integer, intent(in) :: region
  680. character(len=*), intent(in) :: file_name
  681. !
  682. ! !OUTPUT PARAMETERS:
  683. !
  684. integer, intent(out) :: status
  685. !
  686. ! !REVISION HISTORY:
  687. ! 4 Jul 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition (FIXME: not tested)
  688. !
  689. ! !REMARKS:
  690. ! (1) similar to read_mmix, but all tranported tracers are read at once.
  691. ! That is: no check on tracers name, and order of tracer matters,
  692. ! which depends on the number of processors in TM5 v3.
  693. ! (2) All tracers must be in the file, and the 4D array should be the
  694. ! second dataset.
  695. !
  696. !EOP
  697. !------------------------------------------------------------------------
  698. !BOC
  699. character(len=*), parameter :: rname = mname//'/readhdfmmr'
  700. real, dimension(:,:,:,:), pointer :: rm
  701. real, dimension(:,:,:), pointer :: m
  702. integer :: io, sfstart, ifail, sds_id
  703. integer :: n_datasets, n_file_attrs
  704. integer :: istat, attributes, num_type
  705. integer :: sffinfo, sfselect, sfginfo
  706. integer :: sfend, sfrnatt, sfrcatt, sffattr
  707. integer, dimension(6) :: idate_save
  708. integer, dimension(nregions) :: im_file,jm_file,lm_file
  709. integer :: ntrace_file
  710. character(len=80) :: msg_file
  711. integer :: ind,n,i,j,l,offsetn
  712. real,dimension(:,:,:,:), allocatable :: field
  713. ! start
  714. m => m_dat(region)%data
  715. rm => mass_dat(region)%rm
  716. #ifdef slopes
  717. mass_dat(region)%rxm = 0.
  718. mass_dat(region)%rym = 0.
  719. mass_dat(region)%rzm = 0.
  720. #ifdef secmom
  721. mass_dat(region)%rxxm = 0.
  722. mass_dat(region)%rxym = 0.
  723. mass_dat(region)%rxzm = 0.
  724. mass_dat(region)%ryym = 0.
  725. mass_dat(region)%ryzm = 0.
  726. mass_dat(region)%rzzm = 0.
  727. #endif
  728. #endif
  729. if (isRoot) then
  730. allocate(field(im(region),jm(region),lm(region),ntracet))
  731. else
  732. allocate(field(1,1,1,1))
  733. end if
  734. ! Read on root
  735. if ( isRoot ) then
  736. io = sfstart( file_name, DFACC_READ )
  737. if ( io == -1 ) then
  738. write(gol,*)'readhdfmmr: Could not open file:'//file_name ; call goErr
  739. TRACEBACK; status=1; return
  740. end if
  741. ind = 1 ! select 1st dataset....(0 = m)
  742. istat = sffinfo(io, n_datasets, n_file_attrs)
  743. write(gol,*) 'readhdfmmr: Number of datasets and attributes', &
  744. n_datasets, n_file_attrs ; call goPr
  745. call io_read4d_32g(io,im(region),jm(region),lm(region),ntracet, &
  746. field,'rm',ifail,index=ind)
  747. if ( ifail /= 0 .and. ntracet == 1 ) then
  748. call io_read3d_32g(io,im(region),jm(region),lm(region), &
  749. field,'rm',ifail,index=ind)
  750. end if
  751. if ( ifail /= 0 ) then
  752. write(gol,*) 'readhdfmmr: '//trim(file_name) ; call goErr
  753. write(gol,*)'readhdfmmr: Failed to read fields'; call goErr
  754. TRACEBACK; status=1; return
  755. end if
  756. write(gol,*) 'readhdfmmr: Read rm, ifail = ', ifail
  757. istat = sfend(io)
  758. if (istat /= FAIL) then
  759. write(gol,*)'readhdfmmr: ... file closed' ; call goErr
  760. write(gol,*)' ' ; call goPr
  761. else
  762. write(gol,*)'readhdfmmr: ERROR in restart from HDF file'; call goErr
  763. TRACEBACK; status=1; return
  764. end if
  765. end if ! root
  766. call SCATTER( dgrid(region), rm, field, mass_dat(region)%halo, status)
  767. do n=1,ntracet
  768. rm(:,:,:,n) = rm(:,:,:,n)*m(:,:,:)/fscale(n)
  769. end do
  770. deallocate(field)
  771. nullify(m)
  772. nullify(rm)
  773. END SUBROUTINE READHDFMMR
  774. !EOC
  775. !--------------------------------------------------------------------------
  776. ! TM5 !
  777. !--------------------------------------------------------------------------
  778. !BOP
  779. !
  780. ! !IROUTINE: READ_MMIX
  781. !
  782. ! !DESCRIPTION: read mean mixing ratio of TRANSPORTED tracers from an "mmix hdf
  783. ! file" and uses air mass to convert to mass. Missing tracers
  784. ! are set to 0.0
  785. !
  786. ! Used with option istart=5.
  787. !\\
  788. !\\
  789. ! !INTERFACE:
  790. !
  791. SUBROUTINE READ_MMIX( region, file_name, status )
  792. !
  793. ! !USES:
  794. !
  795. use dims, only : im, jm, lm, nregions, datadir, region_name, parent
  796. use io_hdf
  797. use global_data, only : mass_dat
  798. use meteodata , only : m_dat
  799. use chem_param, only : fscale, ntracet, names
  800. use tm5_distgrid, only : dgrid, Get_DistGrid, scatter
  801. use ParTools, only : isRoot
  802. !
  803. ! !INPUT PARAMETERS:
  804. !
  805. integer, intent(in) :: region
  806. character(len=*), intent(in) :: file_name
  807. !
  808. ! !OUTPUT PARAMETERS:
  809. !
  810. integer, intent(out) :: status
  811. !
  812. ! !REVISION HISTORY:
  813. ! 4 Jul 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition (FIXME: not tested)
  814. !
  815. ! !REMARKS:
  816. !
  817. ! (1) This is typically the choice for combining different versions
  818. ! or extending the number of tracers.
  819. ! (2) The compounds are searched by name. If not in the mmix file
  820. ! the field is initialized as zero.
  821. !
  822. !EOP
  823. !------------------------------------------------------------------------
  824. !BOC
  825. character(len=*), parameter :: rname = mname//'/read_mmix'
  826. real,dimension(:,:,:,:),pointer :: rm
  827. #ifdef slopes
  828. real,dimension(:,:,:,:),pointer :: rxm,rym,rzm
  829. #endif
  830. real,dimension(:,:,:),pointer :: m
  831. integer :: io, sfstart, ifail, sds_id
  832. integer :: n_datasets, n_file_attrs
  833. integer :: istat, attributes, num_type
  834. integer :: sffinfo, sfselect, sfginfo
  835. integer :: sfend, sfrnatt, sfrcatt, sffattr
  836. integer,dimension(6) :: idate_save
  837. integer,dimension(nregions) :: im_file,jm_file,lm_file
  838. integer :: ntrace_file
  839. character(len=80) :: msg_file
  840. integer :: ind,n,i,j,l,from_file, my_parent
  841. real,dimension(:,:,:,:), allocatable :: field
  842. real,dimension(:,:,:), allocatable :: field3d
  843. ! start
  844. m => m_dat(region)%data
  845. rm => mass_dat(region)%rm
  846. #ifdef slopes
  847. rxm => mass_dat(region)%rxm
  848. rym => mass_dat(region)%rym
  849. rzm => mass_dat(region)%rzm
  850. #endif
  851. rm = 0.0
  852. #ifdef slopes
  853. rxm = 0.0
  854. rym = 0.0
  855. rzm = 0.0
  856. #endif
  857. if (isRoot) then
  858. allocate(field(im(region),jm(region),lm(region),ntracet))
  859. else
  860. allocate(field(1,1,1,1))
  861. end if
  862. ! Read on root
  863. if ( isRoot ) then
  864. from_file = 1
  865. allocate(field3d(im(region),jm(region),lm(region)))
  866. io = sfstart(file_name, DFACC_READ)
  867. if ( io == FAIL ) then
  868. my_parent = parent(region)
  869. if ( my_parent == 0 ) then
  870. write(gol,*)'read_mmix : Could not open file and no parent '// &
  871. 'available :'//file_name ; call goErr
  872. TRACEBACK; status=1; return
  873. else
  874. ! FIXME : this is not going anywhere
  875. from_file = 0
  876. write(gol,*) 'readhdf: Trying to initialise '//trim(region_name(region))// &
  877. ' from parent....'; call goPr
  878. endif
  879. endif
  880. if ( from_file == 1 ) then ! read from file:
  881. write(gol,*) 'read_mmix: ',file_name,'... opened for READ access.' ; call goPr
  882. istat = sffinfo(io, n_datasets, n_file_attrs)
  883. write(gol,*) 'read_mmix: Number of datasets and attributes', n_datasets, n_file_attrs
  884. call goPr
  885. do n = 1, ntracet
  886. call io_read3d_32(io, im(region), jm(region), lm(region), field3d, names(n), ifail)
  887. if (ifail == 0) then
  888. field(1:im(region), 1:jm(region), 1:lm(region), n) = field3d
  889. else
  890. write(gol,*) 'Read_mmix:', names(n), ' not found in dataset --> 0.0 ' ; call goPr
  891. field(1:im(region), 1:jm(region), 1:lm(region), n) = tiny(1.0)
  892. endif
  893. enddo
  894. istat = sfend(io)
  895. if (istat /= FAIL) then
  896. write(gol,*)'read_mmix: ... file closed' ; call goPr
  897. write(gol,*)' '; call goPr
  898. else
  899. write(gol,*)'read_mmix: ERROR in restart from HDF file'; call goErr
  900. TRACEBACK; status=1; return
  901. end if
  902. deallocate(field3d) ! no longer needed
  903. endif ! from file
  904. endif ! root
  905. call SCATTER( dgrid(region), rm, field, mass_dat(region)%halo, status)
  906. ! Convert from mmix to kg tracer
  907. do n = 1, ntracet
  908. rm(:,:,:,n) = rm(:,:,:,n)*m/fscale(n)
  909. end do
  910. #ifdef slopes
  911. rxm = 0.0 ; rym = 0.0 ; rzm = 0.0
  912. #endif
  913. ! Done
  914. deallocate(field)
  915. nullify(m, rm)
  916. #ifdef slopes
  917. nullify(rxm, rym, rzm)
  918. #endif
  919. END SUBROUTINE READ_MMIX
  920. !EOC
  921. !--------------------------------------------------------------------------
  922. ! TM5 !
  923. !--------------------------------------------------------------------------
  924. !BOP
  925. !
  926. ! !IROUTINE: READ_SAVE_FILE
  927. !
  928. ! !DESCRIPTION: Read mass of both transpoted AND short lived species from so
  929. ! -called "save file". No slopes, but regridding to model
  930. ! resolution is available, since grid information is also read.
  931. !
  932. ! Used with istart=31 option.
  933. !\\
  934. !\\
  935. ! !INTERFACE:
  936. !
  937. SUBROUTINE READ_SAVE_FILE( region, fname, status, tm4 )
  938. !
  939. ! !USES:
  940. !
  941. use file_hdf , only : THdfFile, TSds, Init, Done, ReadAttribute, ReadData
  942. use grid , only : TllGridInfo, TLevelInfo, Init, Done, Fill3D
  943. use dims , only : im, jm, lm
  944. use chem_param , only : ntrace, ntracet, fscale, names, ntrace_chem
  945. use partools , only : root, ierr, my_real, localComm, isRoot
  946. use global_data , only : mass_dat, chem_dat
  947. use meteodata , only : global_lli, levi, sp_dat, m_dat
  948. use tm5_distgrid, only : dgrid, Get_DistGrid, gather, scatter
  949. !
  950. ! !INPUT PARAMETERS:
  951. !
  952. integer, intent(in) :: region
  953. character(len=*), intent(in) :: fname
  954. logical, intent(in), optional :: tm4
  955. !
  956. ! !OUTPUT PARAMETERS:
  957. !
  958. integer, intent(out) :: status
  959. !
  960. ! !REVISION HISTORY:
  961. ! 4 Oct 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  962. !
  963. ! !REMARKS:
  964. ! (1) tracers not found in the file are left unchanged (ie to their initialized values)
  965. !
  966. !EOP
  967. !------------------------------------------------------------------------
  968. !BOC
  969. character(len=*), parameter :: rname = mname//'/Read_save_file'
  970. ! 31 (from 60) layer defintition for TM4 save files:
  971. real, parameter :: at_tm4_60_31(0:31) = (/ &
  972. 0., 7.367743, 467.333588, 1385.912598, 2887.696533, &
  973. 4941.778320, 6144.314941, 8802.356445, 10209.500977, 11632.758789, &
  974. 14411.124023, 15706.447266, 16899.468750, 17961.357422, 18864.750000, &
  975. 19584.330078, 20097.402344, 20384.480469, 20222.205078, 19755.109375, &
  976. 19027.695313, 18045.183594, 16819.474609, 15379.805664, 13775.325195, &
  977. 12077.446289, 10376.126953, 8765.053711, 6018.019531, 3960.291504, &
  978. 2082.273926, 0./)
  979. real, parameter :: bt_tm4_60_31(0:31) = (/ &
  980. 1.00000000, 0.99401945, 0.96764523, 0.93194032, 0.87965691, &
  981. 0.81125343, 0.77159661, 0.68326861, 0.63554746, 0.58616841, &
  982. 0.48477158, 0.43396294, 0.38389215, 0.33515489, 0.28832296, &
  983. 0.24393314, 0.20247590, 0.16438432, 0.09967469, 0.07353383, &
  984. 0.05169041, 0.03412116, 0.02067788, 0.01114291, 0.00508112, &
  985. 0.00181516, 0.00046139, 0.00007582, 0.00000000, 0.00000000, &
  986. 0.00000000, 0.00000000/)
  987. ! 34 (from 91) layer defintition for TM4 save files:
  988. real, parameter :: at_tm4_91_34(0:34) = (/ &
  989. 0.000000, 6.575628, 336.772369, 1297.656128, 3010.146973, &
  990. 5422.802734, 8356.252930, 11543.166992, 14665.645508, 17385.595703, &
  991. 19348.775391, 20319.011719, 20348.916016, 19919.796875, 19184.544922, &
  992. 18191.029297, 16990.623047, 15638.053711, 14192.009766, 12713.897461, &
  993. 11262.484375, 9873.560547, 8564.624023, 7341.469727, 6199.839355, &
  994. 4663.776367, 3358.425781, 2292.155518, 1463.163940, 857.945801, &
  995. 450.685791, 204.637451, 76.167656, 21.413612, 0.000000/)
  996. real, parameter :: bt_tm4_91_34(0:34) = (/ &
  997. 1.000000, 0.994204, 0.973466, 0.935157, 0.875518, &
  998. 0.795385, 0.698224, 0.589317, 0.475016, 0.362203, &
  999. 0.259554, 0.176091, 0.112979, 0.080777, 0.055474, &
  1000. 0.036227, 0.022189, 0.012508, 0.006322, 0.002765, &
  1001. 0.001000, 0.000279, 0.000055, 0.000000, 0.000000, &
  1002. 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, &
  1003. 0.000000, 0.000000, 0.000000, 0.000000, 0.000000/)
  1004. ! 34 (from standard) layer defintition for TM4 save files:
  1005. real, parameter :: at_tm4_std_34(0:34) = (/ &
  1006. 0., 7.367743, 210.393890, 855.361755, &
  1007. 2063.779785, 3850.913330, 6144.314941, 8802.356445, &
  1008. 11632.758789, 14411.124023, 16899.468750, 17961.357422, &
  1009. 18864.750000, 19584.330078, 20097.402344, 20384.480469, &
  1010. 20429.863281, 20222.205078, 19755.109375, 19027.695313, &
  1011. 18045.183594, 16819.474609, 15379.805664, 13775.325195, &
  1012. 12077.446289, 10376.126953, 8765.053711, 7306.631348, &
  1013. 6018.019531, 3960.291504, 1680.640259, 713.218079, &
  1014. 298.495789, 95.636963, 0./)
  1015. real, parameter :: bt_tm4_std_34(0:34) = (/ &
  1016. 1.00000000, 0.99401945, 0.97966272, 0.95182151, &
  1017. 0.90788388, 0.84737492, 0.77159661, 0.68326861, &
  1018. 0.58616841, 0.48477158, 0.38389215, 0.33515489, &
  1019. 0.28832296, 0.24393314, 0.20247590, 0.16438432, &
  1020. 0.13002251, 0.09967469, 0.07353383, 0.05169041, &
  1021. 0.03412116, 0.02067788, 0.01114291, 0.00508112, &
  1022. 0.00181516, 0.00046139, 0.00007582, 0.00000000, &
  1023. 0.00000000, 0.00000000, 0.00000000, 0.00000000, &
  1024. 0.00000000, 0.00000000, 0.00000000/)
  1025. ! --- local -------------------------------
  1026. integer :: imr, jmr, lmr
  1027. real, dimension(:,:,:), pointer :: sp
  1028. real, dimension(:,:,:), pointer :: m
  1029. type(THdfFile) :: hdf
  1030. type(TSds) :: sds_rm, sds_rmc
  1031. integer :: n, ns
  1032. integer :: ntrace_in, ntracet_in
  1033. integer :: n_in, nl
  1034. character(len=8), allocatable :: names_in(:)
  1035. integer :: xbeg_in, ybeg_in
  1036. real :: dx_in, dy_in
  1037. integer :: im_in, jm_in, lm_in
  1038. real, allocatable :: at_in(:), bt_in(:)
  1039. type(TllGridInfo) :: lli_in
  1040. type(TLevelInfo) :: levi_in
  1041. real, allocatable :: rm_in(:,:,:,:), sp_gbl(:,:,:)
  1042. real, allocatable :: rmt(:,:,:,:),rms(:,:,:,:)
  1043. integer :: l
  1044. logical :: with_tm4
  1045. ! --- begin -------------------------------
  1046. ! global grid sizes
  1047. imr = im(region)
  1048. jmr = jm(region)
  1049. lmr = lm(region)
  1050. ! set pointers
  1051. sp => sp_dat(region)%data ! surface pressure
  1052. m => m_dat(region)%data ! air mass
  1053. ! special input ?
  1054. with_tm4 = .false.
  1055. if ( present(tm4) ) with_tm4 = tm4
  1056. ! temporary global storage
  1057. if (isRoot) then
  1058. allocate( rmt(imr,jmr,lmr,ntracet ) )
  1059. allocate( rms(imr,jmr,lmr,ntrace_chem) )
  1060. allocate( sp_gbl(imr,jmr,1) )
  1061. else
  1062. allocate( rmt(1,1,1,1) )
  1063. allocate( rms(1,1,1,1) )
  1064. allocate(sp_gbl(1,1,1))
  1065. endif
  1066. ! init to 0 in case of not found in file
  1067. rmt=tiny(0.)
  1068. rms=tiny(0.)
  1069. call gather( dgrid(region), sp, sp_gbl, sp_dat(region)%halo, status) ! get global surf pressure
  1070. IF_NOTOK_RETURN(status=1)
  1071. ! read on root (until we implement the stride in reading)
  1072. if ( isRoot ) then
  1073. ! open hdf file
  1074. call Init( hdf, fname, 'read', status )
  1075. IF_NOTOK_RETURN(status=1)
  1076. ! read list with tracer names in file:
  1077. call ReadAttribute( hdf, 'ntrace', ntrace_in, status )
  1078. IF_NOTOK_RETURN(status=1)
  1079. call ReadAttribute( hdf, 'ntracet', ntracet_in, status )
  1080. IF_NOTOK_RETURN(status=1)
  1081. allocate( names_in(ntrace_in) )
  1082. call ReadAttribute( hdf, 'names', names_in, status )
  1083. IF_NOTOK_RETURN(status=1)
  1084. ! read level definition
  1085. call ReadAttribute( hdf, 'lm', lm_in, status )
  1086. IF_NOTOK_RETURN(status=1)
  1087. allocate( at_in(0:lm_in) )
  1088. allocate( bt_in(0:lm_in) )
  1089. if ( with_tm4 ) then
  1090. select case ( lm_in )
  1091. case ( 31 )
  1092. at_in = at_tm4_60_31
  1093. bt_in = bt_tm4_60_31
  1094. case ( 34 )
  1095. at_in = at_tm4_std_34
  1096. bt_in = bt_tm4_std_34
  1097. case default
  1098. write (gol,'("input from TM4 save file implemented for 60-31 and 91-34levels only ...")'); call goErr
  1099. TRACEBACK; status=1; return
  1100. end select
  1101. else
  1102. call ReadAttribute( hdf, 'at', at_in, status )
  1103. IF_NOTOK_RETURN(status=1)
  1104. call ReadAttribute( hdf, 'bt', bt_in, status )
  1105. IF_NOTOK_RETURN(status=1)
  1106. end if
  1107. call Init( levi_in, lm_in, at_in, bt_in, status )
  1108. IF_NOTOK_RETURN(status=1)
  1109. deallocate( at_in )
  1110. deallocate( bt_in )
  1111. ! read grid definition:
  1112. call ReadAttribute( hdf, 'im', im_in, status )
  1113. IF_NOTOK_RETURN(status=1)
  1114. call ReadAttribute( hdf, 'jm', jm_in, status )
  1115. IF_NOTOK_RETURN(status=1)
  1116. if ( with_tm4 ) then
  1117. xbeg_in = -180.0
  1118. dx_in = 360.0/im_in
  1119. ybeg_in = -90.0
  1120. dy_in = 180.0/jm_in
  1121. else
  1122. call ReadAttribute( hdf, 'xbeg', xbeg_in, status )
  1123. IF_NOTOK_RETURN(status=1)
  1124. call ReadAttribute( hdf, 'dx', dx_in, status )
  1125. IF_NOTOK_RETURN(status=1)
  1126. call ReadAttribute( hdf, 'ybeg', ybeg_in, status )
  1127. IF_NOTOK_RETURN(status=1)
  1128. call ReadAttribute( hdf, 'dy', dy_in, status )
  1129. IF_NOTOK_RETURN(status=1)
  1130. end if
  1131. call Init( lli_in, xbeg_in+0.5*dx_in, dx_in, im_in, &
  1132. ybeg_in+0.5*dy_in, dy_in, jm_in, status )
  1133. IF_NOTOK_RETURN(status=1)
  1134. ! temporary storage:
  1135. allocate( rm_in(im_in,jm_in,lm_in,1) )
  1136. ! open tracer masses:
  1137. call Init( sds_rm, hdf, 'rm', status )
  1138. IF_NOTOK_RETURN(status=1)
  1139. if ( .not. with_tm4 ) then
  1140. call Init( sds_rmc, hdf, 'rmc', status )
  1141. if(status /= 0) write (gol,'("WARNING - No short lived tracer array found in save file...continuing execution")')
  1142. call goPr
  1143. end if
  1144. ! loop over all tracers:
  1145. do n = 1, ntrace
  1146. ! search input record:
  1147. n_in = -1
  1148. do nl = 1, ntrace_in
  1149. if ( names(n) == names_in(nl) ) then
  1150. n_in = nl
  1151. exit
  1152. end if
  1153. end do
  1154. ! not found ?
  1155. if ( n_in < 0 ) then
  1156. if ( n <= ntracet ) then
  1157. write (gol,'("WARNING - transported tracer not found in save file:")')
  1158. else
  1159. write (gol,'("WARNING - short-lived tracer not found in save file:")')
  1160. end if
  1161. call goPr
  1162. write (gol,'("WARNING - file : ",a)') trim(fname) ; call goPr
  1163. write (gol,'("WARNING - tracer : ",i3," ",a)') n, trim(names(n)) ; call goPr
  1164. if ( n <= ntracet ) then
  1165. write (gol,'(" initialised tracer ",i2,x,a,"; max mass : ",e10.3)') n, names(n), maxval(rmt(:,:,:,n))
  1166. else
  1167. ns = n-ntracet
  1168. write (gol,'(" initialised tracer ",i2,x,a,"; max mass : ",e10.3)') n, names(n), maxval(rms(:,:,:,ns))
  1169. endif
  1170. call goPr
  1171. cycle
  1172. end if
  1173. ! transported or short lived ?
  1174. if ( n <= ntracet ) then
  1175. ! read 3D tracer field from rm or rmc:
  1176. if ( n_in <= ntracet_in ) then
  1177. call ReadData( sds_rm, rm_in, status, start=(/0,0,0,n_in-1/) ) ! kg
  1178. IF_NOTOK_RETURN(status=1)
  1179. else
  1180. call ReadData( sds_rmc, rm_in, status, start=(/0,0,0,n_in-ntracet_in-1/) ) ! kg
  1181. IF_NOTOK_RETURN(status=1)
  1182. end if
  1183. ! expand polar cell for TM4 files ...
  1184. if ( with_tm4 ) then
  1185. do l = 1, lm_in
  1186. rm_in(:, 1,l,1) = rm_in(1, 1,l,1) / im_in
  1187. rm_in(:,jm_in,l,1) = rm_in(1,jm_in,l,1) / im_in
  1188. end do
  1189. end if
  1190. ! regrid from saved grid to current model grid
  1191. call Fill3D( global_lli(region), levi, 'n', sp_gbl(1:imr,1:jmr,1), rmt(1:imr,1:jmr,1:lmr,n), &
  1192. lli_in, levi_in, rm_in(:,:,:,1), 'sum', status )
  1193. IF_NOTOK_RETURN(status=1)
  1194. ! info
  1195. write (gol,'(" initialised tracer ",i2,x,a,"; max mass : ",e10.3)') n, names(n), maxval(rmt(:,:,:,n))
  1196. call goPr
  1197. !Need to gather "m" globally to get VMR
  1198. ! maxval(rmt(1:imr,1:jmr,1:lmr,n)/m_gbl(1:imr,1:jmr,1:lmr)*fscale(n)); call goPr
  1199. else
  1200. ! short lived tracer
  1201. ! read 3D tracer field:
  1202. if ( with_tm4 ) then
  1203. ! tm4 save files have short lived tracers in rm
  1204. call ReadData( sds_rm, rm_in, status, start=(/0,0,0,n_in-1/) ) ! kg
  1205. IF_NOTOK_RETURN(status=1)
  1206. ! expand polar cell ...
  1207. do l = 1, lm_in
  1208. rm_in(:, 1,l,1) = rm_in(1, 1,l,1) / im_in
  1209. rm_in(:,jm_in,l,1) = rm_in(1,jm_in,l,1) / im_in
  1210. end do
  1211. else
  1212. ! read 3D tracer field from rm or rmc:
  1213. if ( n_in <= ntracet_in ) then
  1214. call ReadData( sds_rm, rm_in, status, start=(/0,0,0,n_in-1/) ) ! kg
  1215. IF_NOTOK_RETURN(status=1)
  1216. else
  1217. call ReadData( sds_rmc, rm_in, status, start=(/0,0,0,n_in-ntracet_in-1/) ) ! kg
  1218. IF_NOTOK_RETURN(status=1)
  1219. end if
  1220. end if
  1221. ! regrid from saved grid to current model grid
  1222. ns = n-ntracet
  1223. call Fill3D( global_lli(region), levi, 'n', sp_gbl(1:imr,1:jmr,1), rms(1:imr,1:jmr,1:lmr,ns), &
  1224. lli_in, levi_in, rm_in(:,:,:,1), 'sum', status )
  1225. IF_NOTOK_RETURN(status=1)
  1226. ! info
  1227. write (gol,'(" initialised tracer ",i2,x,a,"; max mass : ",e10.3)') n, names(n), maxval(rms(1:imr,1:jmr,1:lmr,ns))
  1228. call goPr
  1229. !Need to gather "m" globally to get VMR
  1230. ! maxval(rms(1:imr,1:jmr,1:lmr,ns)/m(1:imr,1:jmr,1:lmr)*fscale(n)); call goPr
  1231. end if
  1232. end do
  1233. ! cleanup
  1234. deallocate( names_in )
  1235. deallocate( rm_in )
  1236. ! done with grid
  1237. call Done( lli_in, status )
  1238. IF_NOTOK_RETURN(status=1)
  1239. call Done( levi_in, status )
  1240. IF_NOTOK_RETURN(status=1)
  1241. ! close data sets
  1242. call Done( sds_rm, status )
  1243. IF_NOTOK_RETURN(status=1)
  1244. if ( .not. with_tm4 ) then
  1245. call Done( sds_rmc, status )
  1246. end if
  1247. ! close hdf file (all pe)
  1248. call Done( hdf, status )
  1249. IF_NOTOK_RETURN(status=1)
  1250. end if
  1251. ! distribute
  1252. call scatter( dgrid(region), mass_dat(region)%rm, rmt, mass_dat(region)%halo, status)
  1253. IF_NOTOK_RETURN(status=1)
  1254. call scatter( dgrid(region), chem_dat(region)%rm, rms, chem_dat(region)%halo, status)
  1255. IF_NOTOK_RETURN(status=1)
  1256. ! done
  1257. deallocate( rmt, rms, sp_gbl )
  1258. status = 0
  1259. END SUBROUTINE READ_SAVE_FILE
  1260. !EOC
  1261. !--------------------------------------------------------------------------
  1262. ! TM5 !
  1263. !--------------------------------------------------------------------------
  1264. !BOP
  1265. !
  1266. ! !IROUTINE: WRITE_SAVE_FILE
  1267. !
  1268. ! !DESCRIPTION: save all essential model parameters and fields in a HDF
  1269. ! file. This so-called "save file" is created only if no
  1270. ! restart is written at the end of the run. It can be read
  1271. ! (with READ_SAVE_FILE) to initialize a run, by using
  1272. ! istart=31 option.
  1273. !\\
  1274. !\\
  1275. ! !INTERFACE:
  1276. !
  1277. SUBROUTINE WRITE_SAVE_FILE( msg, file_name, status )
  1278. !
  1279. ! !USES:
  1280. !
  1281. use file_hdf , only : THdfFile, Init, Done, WriteAttribute, TSds, SetDim, WriteData
  1282. use dims , only : nregions, region_name
  1283. use dims , only : im, jm, lm
  1284. use dims , only : dx, xref, xbeg, xend, ibeg, iend
  1285. use dims , only : dy, yref, ybeg, yend, jbeg, jend
  1286. use dims , only : dz, zref, zbeg, zend, lbeg, lend
  1287. use dims , only : areag
  1288. use dims , only : czeta, czetak
  1289. use dims , only : itau, itaui, itaue, itau0, itaut
  1290. use dims , only : idate, idatei, idatee, idate0, idatet
  1291. use dims , only : icalendo, iyear0, julday0
  1292. use dims , only : newyr, newmonth, newday, newsrun
  1293. use dims , only : tref
  1294. use dims , only : ndyn, nconv, ndiag, nchem, nsrce
  1295. use dims , only : nread, ninst, ncheck, ndiff, ndiagp1, ndiagp2, nstep
  1296. use dims , only : nwrite
  1297. use dims , only : istart
  1298. use dims , only : cpu0, cpu1
  1299. use dims , only : xlabel
  1300. use dims , only : limits
  1301. use dims , only : at, bt
  1302. use dims , only : nsplitsteps, splitorder
  1303. use global_data, only : mass_dat, chem_dat
  1304. use meteodata , only : m_dat
  1305. use chem_param , only : ntrace, ntrace_chem, ntracet, ra, names, fscale
  1306. use chem_param , only : nstd, istd
  1307. use io_hdf, only : io_write
  1308. use datetime, only : tstamp
  1309. use global_data, only : outdir
  1310. use tm5_distgrid, only : dgrid, Get_DistGrid, GATHER
  1311. use ParTools, only : isRoot
  1312. !
  1313. ! !INPUT PARAMETERS:
  1314. !
  1315. character(len=*), intent(in) :: file_name ! base filename if not found in rc file
  1316. character(len=*), intent(in) :: msg ! message attribute
  1317. !
  1318. ! !OUTPUT PARAMETERS:
  1319. !
  1320. integer, intent(out) :: status ! return code
  1321. !
  1322. ! !REVISION HISTORY:
  1323. !
  1324. ! 11 Nov 2011 - P. Le Sager - adapted for adapted for lon-lat MPI domain decomposition
  1325. !
  1326. ! !REMARKS:
  1327. !
  1328. !EOP
  1329. !------------------------------------------------------------------------
  1330. !BOC
  1331. character(len=*), parameter :: rname = mname//'/Write_save_file'
  1332. ! --- local ----------------------------------
  1333. real, dimension(:,:,:,:), pointer :: rm
  1334. #ifdef slopes
  1335. real, dimension(:,:,:,:), pointer :: rxm,rym,rzm
  1336. #ifdef secmom
  1337. real, dimension(:,:,:,:), pointer :: rxxm,rxym,rxzm,ryym,ryzm,rzzm
  1338. #endif
  1339. #endif
  1340. real, dimension(:,:,:,:), pointer :: rmc
  1341. real, dimension(:,:,:,:), allocatable :: glbfield
  1342. type(THdfFile) :: hdf
  1343. type(TSds) :: sds
  1344. integer :: region, imr, jmr, lmr, i, n, I1, J1, IH1, halo
  1345. character(len=64) :: msg_file
  1346. character(len=256) :: fname
  1347. character(len=32 ) :: key
  1348. ! --- begin -----------------------------------
  1349. call InitRc( rcF, rcfile, status )
  1350. IF_NOTOK_RETURN(status=1)
  1351. do region = 1,nregions
  1352. if ( isRoot ) then
  1353. ! try if filename for istart.3 was specified in rcfile:
  1354. write (key,'("start.3.",a)') trim(region_name(region))
  1355. call ReadRc( rcF, key, fname, status, default='file_name_empty' )
  1356. if(status == -1) then ! no specific istart.3 file name found, use default name
  1357. write (fname,'(a,"_",i4.4,3i2.2,"_",a,".hdf")') trim(file_name), idate(1:4), trim(region_name(region))
  1358. else
  1359. write (gol,*) 'Using save file names from rc-file start.3.* values'; call goPr
  1360. endif
  1361. call Init( hdf, trim(fname), 'create', status )
  1362. IF_NOTOK_RETURN(status=1)
  1363. call WriteAttribute( hdf, 'itau' , itau , status )
  1364. IF_NOTOK_RETURN(status=1)
  1365. call WriteAttribute( hdf, 'nregions' , nregions , status )
  1366. IF_NOTOK_RETURN(status=1)
  1367. call WriteAttribute( hdf, 'region_name', trim(region_name(region)), status )
  1368. IF_NOTOK_RETURN(status=1)
  1369. call WriteAttribute( hdf, 'im' , im(region) , status )
  1370. IF_NOTOK_RETURN(status=1)
  1371. call WriteAttribute( hdf, 'jm' , jm(region) , status )
  1372. IF_NOTOK_RETURN(status=1)
  1373. call WriteAttribute( hdf, 'lm' , lm(region) , status )
  1374. IF_NOTOK_RETURN(status=1)
  1375. call WriteAttribute( hdf, 'dx' , dx/xref(region) , status )
  1376. IF_NOTOK_RETURN(status=1)
  1377. call WriteAttribute( hdf, 'dy' , dy/yref(region) , status )
  1378. IF_NOTOK_RETURN(status=1)
  1379. call WriteAttribute( hdf, 'dz' , dz/zref(region) , status )
  1380. IF_NOTOK_RETURN(status=1)
  1381. call WriteAttribute( hdf, 'xbeg' , xbeg(region) , status )
  1382. IF_NOTOK_RETURN(status=1)
  1383. call WriteAttribute( hdf, 'xend' , xend(region) , status )
  1384. IF_NOTOK_RETURN(status=1)
  1385. call WriteAttribute( hdf, 'ybeg' , ybeg(region) , status )
  1386. IF_NOTOK_RETURN(status=1)
  1387. call WriteAttribute( hdf, 'yend' , yend(region) , status )
  1388. IF_NOTOK_RETURN(status=1)
  1389. call WriteAttribute( hdf, 'zbeg' , zbeg(region) , status )
  1390. IF_NOTOK_RETURN(status=1)
  1391. call WriteAttribute( hdf, 'zend' , zend(region) , status )
  1392. IF_NOTOK_RETURN(status=1)
  1393. if ( region /= 1 ) then
  1394. call WriteAttribute( hdf, 'ibeg', ibeg(region), status )
  1395. IF_NOTOK_RETURN(status=1)
  1396. call WriteAttribute( hdf, 'iend', iend(region), status )
  1397. IF_NOTOK_RETURN(status=1)
  1398. call WriteAttribute( hdf, 'jbeg', jbeg(region), status )
  1399. IF_NOTOK_RETURN(status=1)
  1400. call WriteAttribute( hdf, 'jend', jend(region), status )
  1401. IF_NOTOK_RETURN(status=1)
  1402. call WriteAttribute( hdf, 'lbeg', lbeg(region), status )
  1403. IF_NOTOK_RETURN(status=1)
  1404. call WriteAttribute( hdf, 'lend', lend(region), status )
  1405. IF_NOTOK_RETURN(status=1)
  1406. end if
  1407. call WriteAttribute( hdf, 'xref' , xref(region), status )
  1408. IF_NOTOK_RETURN(status=1)
  1409. call WriteAttribute( hdf, 'yref' , yref(region), status )
  1410. IF_NOTOK_RETURN(status=1)
  1411. call WriteAttribute( hdf, 'zref' , zref(region), status )
  1412. IF_NOTOK_RETURN(status=1)
  1413. call WriteAttribute( hdf, 'tref' , tref(region), status )
  1414. IF_NOTOK_RETURN(status=1)
  1415. call WriteAttribute( hdf, 'ntracet' , ntracet , status )
  1416. IF_NOTOK_RETURN(status=1)
  1417. call WriteAttribute( hdf, 'ntrace ' , ntrace , status )
  1418. IF_NOTOK_RETURN(status=1)
  1419. call WriteAttribute( hdf, 'nstd' , nstd , status )
  1420. IF_NOTOK_RETURN(status=1)
  1421. call WriteAttribute( hdf, 'idate' , idate , status )
  1422. IF_NOTOK_RETURN(status=1)
  1423. call WriteAttribute( hdf, 'istart' , istart , status )
  1424. IF_NOTOK_RETURN(status=1)
  1425. call WriteAttribute( hdf, 'ndyn' , ndyn , status )
  1426. IF_NOTOK_RETURN(status=1)
  1427. call WriteAttribute( hdf, 'nconv' , nconv , status )
  1428. IF_NOTOK_RETURN(status=1)
  1429. call WriteAttribute( hdf, 'ndiag' , ndiag , status )
  1430. IF_NOTOK_RETURN(status=1)
  1431. call WriteAttribute( hdf, 'nchem' , nchem , status )
  1432. IF_NOTOK_RETURN(status=1)
  1433. call WriteAttribute( hdf, 'nsrce' , nsrce , status )
  1434. IF_NOTOK_RETURN(status=1)
  1435. call WriteAttribute( hdf, 'nread' , nread , status )
  1436. IF_NOTOK_RETURN(status=1)
  1437. call WriteAttribute( hdf, 'nwrite' , nwrite , status )
  1438. IF_NOTOK_RETURN(status=1)
  1439. call WriteAttribute( hdf, 'ninst' , ninst , status )
  1440. IF_NOTOK_RETURN(status=1)
  1441. call WriteAttribute( hdf, 'ncheck' , ncheck , status )
  1442. IF_NOTOK_RETURN(status=1)
  1443. call WriteAttribute( hdf, 'ndiff' , ndiff , status )
  1444. IF_NOTOK_RETURN(status=1)
  1445. call WriteAttribute( hdf, 'itaui' , itaui , status )
  1446. IF_NOTOK_RETURN(status=1)
  1447. call WriteAttribute( hdf, 'itaue' , itaue , status )
  1448. IF_NOTOK_RETURN(status=1)
  1449. call WriteAttribute( hdf, 'itaut' , itaut , status )
  1450. IF_NOTOK_RETURN(status=1)
  1451. call WriteAttribute( hdf, 'itau0' , itau0 , status )
  1452. IF_NOTOK_RETURN(status=1)
  1453. call WriteAttribute( hdf, 'idatei' , idatei , status )
  1454. IF_NOTOK_RETURN(status=1)
  1455. call WriteAttribute( hdf, 'idatee' , idatee , status )
  1456. IF_NOTOK_RETURN(status=1)
  1457. call WriteAttribute( hdf, 'idatet' , idatet , status )
  1458. IF_NOTOK_RETURN(status=1)
  1459. call WriteAttribute( hdf, 'idate0' , idate0 , status )
  1460. IF_NOTOK_RETURN(status=1)
  1461. call WriteAttribute( hdf, 'icalendo' , icalendo , status )
  1462. IF_NOTOK_RETURN(status=1)
  1463. call WriteAttribute( hdf, 'iyear0' , iyear0 , status )
  1464. IF_NOTOK_RETURN(status=1)
  1465. call WriteAttribute( hdf, 'julday0' , julday0 , status )
  1466. IF_NOTOK_RETURN(status=1)
  1467. call WriteAttribute( hdf, 'ndiagp1' , ndiagp1 , status )
  1468. IF_NOTOK_RETURN(status=1)
  1469. call WriteAttribute( hdf, 'ndiagp2' , ndiagp2 , status )
  1470. IF_NOTOK_RETURN(status=1)
  1471. call WriteAttribute( hdf, 'nstep' , nstep , status )
  1472. IF_NOTOK_RETURN(status=1)
  1473. call WriteAttribute( hdf, 'cpu0' , cpu0 , status )
  1474. IF_NOTOK_RETURN(status=1)
  1475. call WriteAttribute( hdf, 'cpu1' , cpu1 , status )
  1476. IF_NOTOK_RETURN(status=1)
  1477. call WriteAttribute( hdf, 'ra' , ra , status )
  1478. IF_NOTOK_RETURN(status=1)
  1479. call WriteAttribute( hdf, 'fscale' , fscale , status )
  1480. IF_NOTOK_RETURN(status=1)
  1481. call WriteAttribute( hdf, 'names' , names , status )
  1482. IF_NOTOK_RETURN(status=1)
  1483. call WriteAttribute( hdf, 'areag' , areag , status )
  1484. IF_NOTOK_RETURN(status=1)
  1485. call WriteAttribute( hdf, 'czeta' , czeta , status )
  1486. IF_NOTOK_RETURN(status=1)
  1487. call WriteAttribute( hdf, 'czetak' , czetak , status )
  1488. IF_NOTOK_RETURN(status=1)
  1489. call WriteAttribute( hdf, 'xlabel' , xlabel , status )
  1490. IF_NOTOK_RETURN(status=1)
  1491. call WriteAttribute( hdf, 'istd' , istd , status )
  1492. IF_NOTOK_RETURN(status=1)
  1493. call WriteAttribute( hdf, 'newyr' , newyr , status )
  1494. IF_NOTOK_RETURN(status=1)
  1495. call WriteAttribute( hdf, 'newmonth' , newmonth , status )
  1496. IF_NOTOK_RETURN(status=1)
  1497. call WriteAttribute( hdf, 'newday' , newday , status )
  1498. IF_NOTOK_RETURN(status=1)
  1499. call WriteAttribute( hdf, 'newsrun' , newsrun , status )
  1500. IF_NOTOK_RETURN(status=1)
  1501. ! call WriteAttribute( hdf, 'cdebug' , cdebug , status )
  1502. ! IF_NOTOK_RETURN(status=1)
  1503. call WriteAttribute( hdf, 'limits' , limits , status )
  1504. IF_NOTOK_RETURN(status=1)
  1505. call WriteAttribute( hdf, 'at' , at , status )
  1506. IF_NOTOK_RETURN(status=1)
  1507. call WriteAttribute( hdf, 'bt' , bt , status )
  1508. IF_NOTOK_RETURN(status=1)
  1509. call WriteAttribute( hdf, 'nsplitsteps', nsplitsteps , status )
  1510. IF_NOTOK_RETURN(status=1)
  1511. call WriteAttribute( hdf, 'splitorder' , splitorder , status )
  1512. IF_NOTOK_RETURN(status=1)
  1513. msg_file = msg
  1514. call WriteAttribute( hdf, 'msg', msg_file, status )
  1515. IF_NOTOK_RETURN(status=1)
  1516. end if ! root all PEs from here
  1517. ! Short cuts
  1518. !----------------------
  1519. rm => mass_dat(region)%rm
  1520. #ifdef slopes
  1521. rxm => mass_dat(region)%rxm
  1522. rym => mass_dat(region)%rym
  1523. rzm => mass_dat(region)%rzm
  1524. #ifdef secmom
  1525. rxxm => mass_dat(region)%rxxm
  1526. rxym => mass_dat(region)%rxym
  1527. rxzm => mass_dat(region)%rxzm
  1528. ryym => mass_dat(region)%ryym
  1529. ryzm => mass_dat(region)%ryzm
  1530. rzzm => mass_dat(region)%rzzm
  1531. #endif
  1532. #endif
  1533. ! Local & global bounds
  1534. !-----------------------
  1535. call Get_DistGrid( dgrid(region), I_STRT=i1, J_STRT=j1, I_STRT_HALO=ih1 )
  1536. halo = i1-ih1
  1537. imr = im(region) ; jmr = jm(region) ; lmr = lm(region)
  1538. ! Allocate global array
  1539. !----------------------
  1540. if (isRoot) then
  1541. allocate( glbfield( imr, jmr, lmr, ntracet) )
  1542. glbfield = 0.0
  1543. else
  1544. allocate( glbfield(1,1,1,1) )
  1545. end if
  1546. ! M (Air mass)
  1547. !----------------------
  1548. CALL GATHER( dgrid(region), m_dat(region)%data, glbfield(:,:,:,1), m_dat(region)%halo, status )
  1549. IF_ERROR_RETURN(status=1)
  1550. if ( isRoot ) then
  1551. call Init( sds, hdf, 'm', (/imr,jmr,lmr/), 'real(4)', status )
  1552. call SetDim(sds,0,'LON'//region_name(region),'deg',(/(xbeg(region)+(i+0.5)*dx/xref(region),i=0,imr-1)/),status)
  1553. call SetDim(sds,1,'LAT'//region_name(region),'deg',(/(ybeg(region)+(i+0.5)*dy/yref(region),i=0,jmr-1)/),status)
  1554. call SetDim(sds,2,'HYBRID','number',(/(i,i=1,lmr)/),status)
  1555. call WriteData(sds, glbfield(:,:,:,1), status)
  1556. call Done(sds,status)
  1557. IF_ERROR_RETURN(status=1)
  1558. end if
  1559. ! RM (transported tracer masses)
  1560. !-----------------------------
  1561. CALL GATHER( dgrid(region), rm, glbfield, halo, status )
  1562. IF_ERROR_RETURN(status=1)
  1563. if ( isRoot ) then
  1564. call Init( sds, hdf, 'rm', (/imr,jmr,lmr,ntracet/), 'real(4)', status )
  1565. call SetDim(sds,0,'LON'//region_name(region),'deg',(/(xbeg(region)+(i+0.5)*dx/xref(region),i=0,imr-1)/),status)
  1566. call SetDim(sds,1,'LAT'//region_name(region),'deg',(/(ybeg(region)+(i+0.5)*dy/yref(region),i=0,jmr-1)/),status)
  1567. call SetDim(sds,2,'HYBRID','number',(/(i,i=1,lmr)/),status)
  1568. call SetDim(sds,3,'ntracet','None',(/(i,i=1,ntracet)/),status)
  1569. call WriteData(sds,glbfield,status)
  1570. call Done(sds,status)
  1571. IF_ERROR_RETURN(status=1)
  1572. end if
  1573. #ifdef slopes
  1574. ! RXM
  1575. !-----------------------------
  1576. CALL GATHER( dgrid(region), rxm, glbfield, halo, status )
  1577. IF_ERROR_RETURN(status=1)
  1578. if ( isRoot ) then
  1579. call Init( sds, hdf, 'rxm', (/imr,jmr,lmr,ntracet/), 'real(4)', status )
  1580. call SetDim(sds,0,'LON'//region_name(region),'deg',(/(xbeg(region)+(i+0.5)*dx/xref(region),i=0,imr-1)/),status)
  1581. call SetDim(sds,1,'LAT'//region_name(region),'deg',(/(ybeg(region)+(i+0.5)*dy/yref(region),i=0,jmr-1)/),status)
  1582. call SetDim(sds,2,'HYBRID','number',(/(i,i=1,lmr)/),status)
  1583. call SetDim(sds,3,'ntracet','None',(/(i,i=1,ntracet)/),status)
  1584. call WriteData(sds,glbfield,status)
  1585. call Done(sds,status)
  1586. IF_ERROR_RETURN(status=1)
  1587. end if
  1588. ! RYM
  1589. !-----------------------------
  1590. CALL GATHER( dgrid(region), rym, glbfield, halo, status )
  1591. IF_ERROR_RETURN(status=1)
  1592. if ( isRoot ) then
  1593. call Init( sds, hdf, 'rym', (/imr,jmr,lmr,ntracet/), 'real(4)', status )
  1594. call SetDim(sds,0,'LON'//region_name(region),'deg',(/(xbeg(region)+(i+0.5)*dx/xref(region),i=0,imr-1)/),status)
  1595. call SetDim(sds,1,'LAT'//region_name(region),'deg',(/(ybeg(region)+(i+0.5)*dy/yref(region),i=0,jmr-1)/),status)
  1596. call SetDim(sds,2,'HYBRID','number',(/(i,i=1,lmr)/),status)
  1597. call SetDim(sds,3,'ntracet','None',(/(i,i=1,ntracet)/),status)
  1598. call WriteData(sds,glbfield,status)
  1599. call Done(sds,status)
  1600. IF_ERROR_RETURN(status=1)
  1601. end if
  1602. ! RZM
  1603. !-----------------------------
  1604. CALL GATHER( dgrid(region), rzm, glbfield, halo, status )
  1605. IF_ERROR_RETURN(status=1)
  1606. if ( isRoot ) then
  1607. call Init( sds, hdf, 'rzm', (/imr,jmr,lmr,ntracet/), 'real(4)', status )
  1608. call SetDim(sds,0,'LON'//region_name(region),'deg',(/(xbeg(region)+(i+0.5)*dx/xref(region),i=0,imr-1)/),status)
  1609. call SetDim(sds,1,'LAT'//region_name(region),'deg',(/(ybeg(region)+(i+0.5)*dy/yref(region),i=0,jmr-1)/),status)
  1610. call SetDim(sds,2,'HYBRID','number',(/(i,i=1,lmr)/),status)
  1611. call SetDim(sds,3,'ntracet','None',(/(i,i=1,ntracet)/),status)
  1612. call WriteData(sds,glbfield,status)
  1613. call Done(sds,status)
  1614. IF_ERROR_RETURN(status=1)
  1615. end if
  1616. #ifdef secmom
  1617. ! second moments
  1618. ! RXXM
  1619. !-----------------------------
  1620. CALL GATHER( dgrid(region), rxxm, glbfield, halo, status )
  1621. IF_ERROR_RETURN(status=1)
  1622. if ( isRoot ) then
  1623. call Init( sds, hdf, 'rxxm', (/imr,jmr,lmr,ntracet/), 'real(4)', status )
  1624. call SetDim(sds,0,'LON'//region_name(region),'deg',(/(xbeg(region)+(i+0.5)*dx/xref(region),i=0,imr-1)/),status)
  1625. call SetDim(sds,1,'LAT'//region_name(region),'deg',(/(ybeg(region)+(i+0.5)*dy/yref(region),i=0,jmr-1)/),status)
  1626. call SetDim(sds,2,'HYBRID','number',(/(i,i=1,lmr)/),status)
  1627. call SetDim(sds,3,'ntracet','None',(/(i,i=1,ntracet)/),status)
  1628. call WriteData(sds,glbfield,status)
  1629. call Done(sds,status)
  1630. IF_ERROR_RETURN(status=1)
  1631. end if
  1632. ! RXYM
  1633. !-----------------------------
  1634. CALL GATHER( dgrid(region), rxym, glbfield, halo, status )
  1635. IF_ERROR_RETURN(status=1)
  1636. if ( isRoot ) then
  1637. call Init( sds, hdf, 'rxym', (/imr,jmr,lmr,ntracet/), 'real(4)', status )
  1638. call SetDim(sds,0,'LON'//region_name(region),'deg',(/(xbeg(region)+(i+0.5)*dx/xref(region),i=0,imr-1)/),status)
  1639. call SetDim(sds,1,'LAT'//region_name(region),'deg',(/(ybeg(region)+(i+0.5)*dy/yref(region),i=0,jmr-1)/),status)
  1640. call SetDim(sds,2,'HYBRID','number',(/(i,i=1,lmr)/),status)
  1641. call SetDim(sds,3,'ntracet','None',(/(i,i=1,ntracet)/),status)
  1642. call WriteData(sds,glbfield,status)
  1643. call Done(sds,status)
  1644. IF_ERROR_RETURN(status=1)
  1645. end if
  1646. ! RXZM
  1647. !-----------------------------
  1648. CALL GATHER( dgrid(region), rxzm, glbfield, halo, status )
  1649. IF_ERROR_RETURN(status=1)
  1650. if ( isRoot ) then
  1651. call Init( sds, hdf, 'rxzm', (/imr,jmr,lmr,ntracet/), 'real(4)', status )
  1652. call SetDim(sds,0,'LON'//region_name(region),'deg',(/(xbeg(region)+(i+0.5)*dx/xref(region),i=0,imr-1)/),status)
  1653. call SetDim(sds,1,'LAT'//region_name(region),'deg',(/(ybeg(region)+(i+0.5)*dy/yref(region),i=0,jmr-1)/),status)
  1654. call SetDim(sds,2,'HYBRID','number',(/(i,i=1,lmr)/),status)
  1655. call SetDim(sds,3,'ntracet','None',(/(i,i=1,ntracet)/),status)
  1656. call WriteData(sds,glbfield,status)
  1657. call Done(sds,status)
  1658. IF_ERROR_RETURN(status=1)
  1659. end if
  1660. ! RYYM
  1661. !-----------------------------
  1662. CALL GATHER( dgrid(region), ryym, glbfield, halo, status )
  1663. IF_ERROR_RETURN(status=1)
  1664. if ( isRoot) then
  1665. call Init( sds, hdf, 'ryym', (/imr,jmr,lmr,ntracet/), 'real(4)', status )
  1666. call SetDim(sds,0,'LON'//region_name(region),'deg',(/(xbeg(region)+(i+0.5)*dx/xref(region),i=0,imr-1)/),status)
  1667. call SetDim(sds,1,'LAT'//region_name(region),'deg',(/(ybeg(region)+(i+0.5)*dy/yref(region),i=0,jmr-1)/),status)
  1668. call SetDim(sds,2,'HYBRID','number',(/(i,i=1,lmr)/),status)
  1669. call SetDim(sds,3,'ntracet','None',(/(i,i=1,ntracet)/),status)
  1670. call WriteData(sds,glbfield,status)
  1671. call Done(sds,status)
  1672. IF_ERROR_RETURN(status=1)
  1673. end if
  1674. ! RYZM
  1675. !-----------------------------
  1676. CALL GATHER( dgrid(region), ryzm, glbfield, halo, status )
  1677. IF_ERROR_RETURN(status=1)
  1678. if ( isRoot) then
  1679. call Init( sds, hdf, 'ryzm', (/imr,jmr,lmr,ntracet/), 'real(4)', status )
  1680. call SetDim(sds,0,'LON'//region_name(region),'deg',(/(xbeg(region)+(i+0.5)*dx/xref(region),i=0,imr-1)/),status)
  1681. call SetDim(sds,1,'LAT'//region_name(region),'deg',(/(ybeg(region)+(i+0.5)*dy/yref(region),i=0,jmr-1)/),status)
  1682. call SetDim(sds,2,'HYBRID','number',(/(i,i=1,lmr)/),status)
  1683. call SetDim(sds,3,'ntracet','None',(/(i,i=1,ntracet)/),status)
  1684. call WriteData(sds,glbfield,status)
  1685. call Done(sds,status)
  1686. IF_ERROR_RETURN(status=1)
  1687. endif
  1688. ! RZZM
  1689. !-----------------------------
  1690. CALL GATHER( dgrid(region), rzzm, glbfield, halo, status )
  1691. IF_ERROR_RETURN(status=1)
  1692. if ( isRoot) then
  1693. call Init( sds, hdf, 'rzzm', (/imr,jmr,lmr,ntracet/), 'real(4)', status )
  1694. call SetDim(sds,0,'LON'//region_name(region),'deg',(/(xbeg(region)+(i+0.5)*dx/xref(region),i=0,imr-1)/),status)
  1695. call SetDim(sds,1,'LAT'//region_name(region),'deg',(/(ybeg(region)+(i+0.5)*dy/yref(region),i=0,jmr-1)/),status)
  1696. call SetDim(sds,2,'HYBRID','number',(/(i,i=1,lmr)/),status)
  1697. call SetDim(sds,3,'ntracet','None',(/(i,i=1,ntracet)/),status)
  1698. call WriteData(sds,glbfield,status)
  1699. call Done(sds,status)
  1700. IF_ERROR_RETURN(status=1)
  1701. endif
  1702. #endif
  1703. #endif
  1704. ! clear
  1705. deallocate(glbfield)
  1706. nullify(rm)
  1707. #ifdef slopes
  1708. nullify(rxm)
  1709. nullify(rym)
  1710. nullify(rzm)
  1711. #ifdef secmom
  1712. nullify(rxxm)
  1713. nullify(rxym)
  1714. nullify(rxzm)
  1715. nullify(ryym)
  1716. nullify(ryzm)
  1717. nullify(rzzm)
  1718. #endif
  1719. #endif
  1720. ! SHORT LIVED TRACERS if any
  1721. ! ----------------------------
  1722. if ( ntrace_chem > 0 ) then
  1723. ! allocate global array
  1724. if (isRoot) then
  1725. allocate(glbfield(imr,jmr,lmr,ntrace_chem))
  1726. else
  1727. allocate(glbfield(1,1,1,1))
  1728. end if
  1729. ! tracer mass
  1730. rmc => chem_dat(region)%rm
  1731. CALL GATHER( dgrid(region), rmc, glbfield, 0, status )
  1732. IF_NOTOK_RETURN(status=1)
  1733. if ( isRoot ) then
  1734. ! write tracers
  1735. call io_write( hdf%id, imr,'LON'//region_name(region),&
  1736. jmr,'LAT'//region_name(region), &
  1737. lmr,'HYBRID',ntrace_chem,'NTRACE_CHEM',glbfield,'rmc')
  1738. end if
  1739. ! clear
  1740. nullify(rmc)
  1741. deallocate(glbfield)
  1742. end if ! ntrace_chem > 0
  1743. ! Close
  1744. !-------
  1745. if ( isRoot ) then
  1746. call Done( hdf, status )
  1747. IF_NOTOK_RETURN(status=1)
  1748. end if
  1749. end do !regions...
  1750. ! -------
  1751. ! Done
  1752. ! -------
  1753. call DoneRc( rcF, status )
  1754. IF_NOTOK_RETURN(status=1)
  1755. ! ok
  1756. status = 0
  1757. END SUBROUTINE WRITE_SAVE_FILE
  1758. !EOC
  1759. END MODULE IO_SAVE