user_output_mmix.F90 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  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 (rcode/=0) then; TRACEBACK; action; return; end if
  5. #define IF_ERROR_RETURN(action) if (rcode> 0) then; TRACEBACK; action; return; end if
  6. !
  7. #include "tm5.inc"
  8. #include "output.inc"
  9. !
  10. !----------------------------------------------------------------------------
  11. ! TM5 !
  12. !----------------------------------------------------------------------------
  13. !BOP
  14. !
  15. ! !MODULE: USER_OUTPUT_MMIX
  16. !
  17. ! !DESCRIPTION: Handles initialisation, accumulation and output of monthly
  18. ! mean tracers mixing ratio, temperature, and pressure.
  19. ! For run shorter than a month, average is done over the
  20. ! duration of the run.
  21. !\\
  22. !\\
  23. ! !INTERFACE:
  24. !
  25. MODULE USER_OUTPUT_MMIX
  26. !
  27. ! !USES:
  28. !
  29. use GO, only : gol, goPr, goErr, goBug, goLabel
  30. use dims !, mname_dims=>mname
  31. use chem_param, only: ntrace, nstd
  32. IMPLICIT NONE
  33. PRIVATE
  34. !
  35. ! !PUBLIC MEMBER FUNCTIONS:
  36. !
  37. public :: mmix_Init, mmix_Done ! object life cycle
  38. public :: accumulate_mmix ! accumulate data
  39. public :: reset_mmix ! reset data
  40. public :: write_mmix ! write data
  41. public :: mmix_dat, w_mmix
  42. !
  43. ! !PUBLIC TYPES:
  44. !
  45. type, public :: mmix_data
  46. real,dimension(:,:,:,:),pointer :: rmmix
  47. real,dimension(:,:,:,:),pointer :: std_mmix
  48. real,dimension(:,:,:),pointer :: tempm
  49. real,dimension(:,:),pointer :: presm
  50. end type mmix_data
  51. type(mmix_data), dimension(nregions), target :: mmix_dat ! accumulated data
  52. real, dimension(nregions) :: w_mmix ! accumulated weight
  53. integer, dimension(6) :: startdate
  54. character(len=*), parameter :: mname = 'user_output_mmix'
  55. !
  56. ! !REVISION HISTORY:
  57. ! 16 Nov 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  58. !
  59. ! !REMARKS:
  60. !
  61. !EOP
  62. !------------------------------------------------------------------------
  63. CONTAINS
  64. !--------------------------------------------------------------------------
  65. ! TM5 !
  66. !--------------------------------------------------------------------------
  67. !BOP
  68. !
  69. ! !IROUTINE: MMIX_INIT
  70. !
  71. ! !DESCRIPTION: Allocate and set to 0 fields to accumulate.
  72. !\\
  73. !\\
  74. ! !INTERFACE:
  75. !
  76. SUBROUTINE MMIX_INIT(rcode)
  77. !
  78. ! !USES:
  79. !
  80. use tm5_distgrid, only : dgrid, Get_DistGrid
  81. !
  82. ! !OUTPUT PARAMETERS:
  83. !
  84. integer, intent(out) :: rcode
  85. !
  86. ! !REVISION HISTORY:
  87. ! 16 Nov 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  88. !
  89. !EOP
  90. !------------------------------------------------------------------------
  91. !BOC
  92. character(len=*), parameter :: rname = mname//'/Init_mmix'
  93. integer :: region, i1, i2, j1, j2
  94. call goLabel(rname)
  95. do region=1,nregions
  96. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  97. allocate(mmix_dat(region)%rmmix (i1:i2, j1:j2, lm(region), ntrace) )
  98. allocate(mmix_dat(region)%std_mmix(i1:i2, j1:j2, lm(region), nstd) )
  99. allocate(mmix_dat(region)%tempm (i1:i2, j1:j2, lm(region)) )
  100. allocate(mmix_dat(region)%presm (i1:i2, j1:j2) )
  101. w_mmix(region) = 0.0
  102. mmix_dat(region)%rmmix = 0.0
  103. mmix_dat(region)%std_mmix = 0.0
  104. mmix_dat(region)%presm = 0.0
  105. mmix_dat(region)%tempm = 0.0
  106. end do
  107. startdate = idatei ! start of model run
  108. call goLabel(); rcode=0
  109. end subroutine mmix_Init
  110. !EOC
  111. !--------------------------------------------------------------------------
  112. ! TM5 !
  113. !--------------------------------------------------------------------------
  114. !BOP
  115. !
  116. ! !IROUTINE: MMIX_DONE
  117. !
  118. ! !DESCRIPTION: deallocate data
  119. !\\
  120. !\\
  121. ! !INTERFACE:
  122. !
  123. SUBROUTINE MMIX_DONE(rcode)
  124. !
  125. ! !OUTPUT PARAMETERS:
  126. !
  127. integer, intent(out) :: rcode
  128. !
  129. ! !REVISION HISTORY:
  130. !
  131. !EOP
  132. !------------------------------------------------------------------------
  133. !BOC
  134. character(len=*), parameter :: rname = mname//'/mmix_Done'
  135. integer :: region
  136. call goLabel( rname )
  137. do region = 1,nregions
  138. deallocate ( mmix_dat(region)%rmmix )
  139. deallocate ( mmix_dat(region)%std_mmix)
  140. deallocate ( mmix_dat(region)%tempm )
  141. deallocate ( mmix_dat(region)%presm )
  142. end do
  143. call goLabel(); rcode=0
  144. END SUBROUTINE MMIX_DONE
  145. !EOC
  146. !--------------------------------------------------------------------------
  147. ! TM5 !
  148. !--------------------------------------------------------------------------
  149. !BOP
  150. !
  151. ! !IROUTINE: RESET_MMIX
  152. !
  153. ! !DESCRIPTION: reset to zero all accumulated fields
  154. !\\
  155. !\\
  156. ! !INTERFACE:
  157. !
  158. SUBROUTINE RESET_MMIX( rcode )
  159. !
  160. ! !OUTPUT PARAMETERS:
  161. !
  162. integer, intent(out) :: rcode
  163. !
  164. ! !REVISION HISTORY:
  165. !
  166. !EOP
  167. !------------------------------------------------------------------------
  168. !BOC
  169. character(len=*), parameter :: rname = mname//'/reset_mmix'
  170. integer :: region
  171. call goLabel( rname )
  172. do region=1,nregions
  173. w_mmix(region) = 0.0
  174. mmix_dat(region)%rmmix = 0.0
  175. mmix_dat(region)%std_mmix = 0.0
  176. mmix_dat(region)%presm = 0.0
  177. mmix_dat(region)%tempm = 0.0
  178. enddo
  179. startdate = idate
  180. ! ok
  181. call goLabel(); rcode=0
  182. END SUBROUTINE RESET_MMIX
  183. !EOC
  184. !--------------------------------------------------------------------------
  185. ! TM5 !
  186. !--------------------------------------------------------------------------
  187. !BOP
  188. !
  189. ! !IROUTINE: ACCUMULATE_MMIX
  190. !
  191. ! !DESCRIPTION: accumulates fields
  192. !\\
  193. !\\
  194. ! !INTERFACE:
  195. !
  196. SUBROUTINE ACCUMULATE_MMIX( region, rcode)
  197. !
  198. ! !USES:
  199. !
  200. !use dims, only : lm, okdebug, ndyn, ndyn_max
  201. use chem_param, only : istd , nstd, ntrace, ntracet, ntrace_chem
  202. use global_data, only : region_dat, mass_dat, chem_dat
  203. use meteodata , only : sp_dat, temper_dat, m_dat
  204. use partools, only : isRoot
  205. use tm5_distgrid, only : dgrid, Get_DistGrid
  206. !
  207. ! !INPUT PARAMETERS:
  208. !
  209. integer, intent(in) :: region
  210. !
  211. ! !OUTPUT PARAMETERS:
  212. !
  213. integer, intent(out) :: rcode
  214. !
  215. ! !REVISION HISTORY:
  216. ! 16 Nov 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  217. !
  218. !EOP
  219. !------------------------------------------------------------------------
  220. !BOC
  221. character(len=*), parameter :: rname = mname//'/accumulate_mmix'
  222. real,dimension(:,:,:,:),pointer :: rm, rmmix, std_mmix, rmc
  223. real,dimension(:,:,:), pointer :: t, tempm, m
  224. real,dimension(:,:,:), pointer :: p
  225. real,dimension(:,:), pointer :: presm
  226. integer,dimension(:,:), pointer :: zoomed
  227. integer :: n, i1, i2, j1, j2, itrace, i,j,l
  228. real :: weight
  229. ! start
  230. call goLabel( rname )
  231. if (newmonth.and.(.not.newsrun)) then
  232. call write_mmix(rcode)
  233. IF_NOTOK_RETURN(rcode=1)
  234. call reset_mmix(rcode)
  235. IF_NOTOK_RETURN(rcode=1)
  236. endif
  237. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  238. ! debug
  239. if (region /= 1) then
  240. print*, rname//" - unexpected region - FIXME ZOOM"; rcode=1
  241. IF_NOTOK_RETURN(rcode=1)
  242. end if
  243. ! input
  244. rm => mass_dat(region)%rm(i1:i2,j1:j2,:,:)
  245. if ( ntrace_chem > 0 ) rmc => chem_dat(region)%rm(i1:i2,j1:j2,:,:)
  246. m => m_dat(region)%data(i1:i2,j1:j2,:)
  247. t => temper_dat(region)%data(i1:i2,j1:j2,:)
  248. p => sp_dat(region)%data(i1:i2,j1:j2,:)
  249. ! output
  250. rmmix => mmix_dat(region)%rmmix
  251. std_mmix => mmix_dat(region)%std_mmix
  252. tempm => mmix_dat(region)%tempm
  253. presm => mmix_dat(region)%presm
  254. weight = float(ndyn)/float(ndyn_max)
  255. ! mmix....
  256. do n=1, ntracet
  257. rmmix(:,:,:,n) = rmmix(:,:,:,n) + weight*rm(:,:,:,n)/m(:,:,:)
  258. end do
  259. ! non-transported tracers, if any
  260. if ( ntrace_chem > 0 ) then
  261. do n= ntracet+1, ntracet+ntrace_chem
  262. rmmix(:,:,:,n) = rmmix(:,:,:,n) + weight*rmc(:,:,:,n-ntracet)/m(:,:,:)
  263. end do
  264. end if
  265. ! stdt deviations
  266. do n=1,nstd
  267. itrace = istd(n)
  268. std_mmix(:,:,:,n) = std_mmix(:,:,:,n) + weight*(rm(:,:,:,itrace)/m(:,:,:))**2
  269. end do
  270. ! met fields
  271. tempm = tempm + weight*t
  272. presm = presm + weight*p(:,:,1)
  273. w_mmix(region) = w_mmix(region) + weight
  274. if ( okdebug ) print*, 'accumulate_mmix: region ',region, &
  275. '; w_mmix',w_mmix(region)
  276. nullify(m)
  277. nullify(rm)
  278. nullify(t)
  279. nullify(p)
  280. nullify(rmmix)
  281. nullify(std_mmix)
  282. nullify(presm)
  283. nullify(tempm)
  284. ! ok
  285. call goLabel(); rcode=0
  286. END SUBROUTINE ACCUMULATE_MMIX
  287. !EOC
  288. !--------------------------------------------------------------------------
  289. ! TM5 !
  290. !--------------------------------------------------------------------------
  291. !BOP
  292. !
  293. ! !IROUTINE: WRITE_MMIX
  294. !
  295. ! !DESCRIPTION: Write to file mean fields defined in this module, plus all
  296. ! essential model parameters
  297. !\\
  298. !\\
  299. ! !INTERFACE:
  300. !
  301. SUBROUTINE WRITE_MMIX( rcode )
  302. !
  303. ! !USES:
  304. !
  305. use chem_param
  306. #ifdef with_hdf4
  307. use io_hdf
  308. #endif
  309. use datetime, only : tstamp
  310. use global_data, only : outdir
  311. use ParTools, only : Par_Barrier, isRoot
  312. use User_Output_Common, only : User_Output_Check_Overwrite
  313. !
  314. ! !INPUT/OUTPUT PARAMETERS:
  315. !
  316. integer, intent(inout) :: rcode
  317. !
  318. ! !REVISION HISTORY:
  319. ! 16 Nov 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  320. !
  321. !EOP
  322. !------------------------------------------------------------------------
  323. !BOC
  324. character(len=*), parameter :: rname = mname//'/write_mmix'
  325. #ifdef with_hdf4
  326. integer :: istat, sfsnatt, sfscatt, io, sfstart
  327. integer :: sfend
  328. #endif
  329. integer :: region
  330. integer :: i,j,l,n,k,ind
  331. !integer,dimension(6) ::
  332. character(len=12) :: name
  333. character(len=200):: FFilename
  334. ! start
  335. call goLabel( rname )
  336. REG : do region=nregions,1,-1
  337. #ifdef with_hdf4
  338. IOroot : if ( isRoot ) then
  339. write (FFilename,'(a,"/mmix_",i4.4,3i2.2,"_",i4.4,3i2.2,"_",a,".hdf")') &
  340. ! trim(outdir), idatei(1:4), idatee(1:4),trim(region_name(region))
  341. trim(outdir), startdate(1:4), idate(1:4),trim(region_name(region))
  342. ! check existence ...
  343. call User_Output_Check_Overwrite( trim(FFilename), rcode )
  344. IF_NOTOK_RETURN(rcode=1)
  345. ! open
  346. io = sfstart(FFilename,DFACC_CREATE)
  347. if ( io < 0 ) then
  348. write (gol,'("While starting mmix file")'); call goErr
  349. write (gol,'("Filename:",a)') trim(Ffilename); call goErr
  350. write (gol,'("IIO unit:",i10)') io; call goErr
  351. write (gol,'("in program")'); call goErr; rcode=1; return
  352. end if
  353. !write (gol,'("write_mmix: io unit",i10)') io; call goPr
  354. istat = sfsnatt(io,'itau', DFNT_INT32, 1, itau)
  355. istat = sfsnatt(io,'nregions', DFNT_INT32, 1, nregions)
  356. istat = sfscatt(io,'region_name', DFNT_CHAR, &
  357. len_trim(region_name(region)), trim(region_name(region)) )
  358. istat = sfsnatt(io,'im', DFNT_INT32, 1, im(region))
  359. istat = sfsnatt(io,'jm', DFNT_INT32, 1, jm(region))
  360. istat = sfsnatt(io,'lm', DFNT_INT32, 1, lm(region))
  361. istat = sfsnatt(io,'dx', DFNT_FLOAT64, 1, dx/xref(region))
  362. istat = sfsnatt(io,'dy', DFNT_FLOAT64, 1, dy/yref(region))
  363. istat = sfsnatt(io,'dz', DFNT_FLOAT64, 1, dz/zref(region))
  364. istat = sfsnatt(io,'xbeg', DFNT_INT32, 1, xbeg(region))
  365. istat = sfsnatt(io,'xend', DFNT_INT32, 1, xend(region))
  366. istat = sfsnatt(io,'ybeg', DFNT_INT32, 1, ybeg(region))
  367. istat = sfsnatt(io,'yend', DFNT_INT32, 1, yend(region))
  368. istat = sfsnatt(io,'zbeg', DFNT_INT32, 1, zbeg(region))
  369. istat = sfsnatt(io,'zend', DFNT_INT32, 1, zend(region))
  370. if(region/=1) then
  371. istat = sfsnatt(io,'ibeg', DFNT_INT32, 1, ibeg(region))
  372. istat = sfsnatt(io,'iend', DFNT_INT32, 1, iend(region))
  373. istat = sfsnatt(io,'jbeg', DFNT_INT32, 1, jbeg(region))
  374. istat = sfsnatt(io,'jend', DFNT_INT32, 1, jend(region))
  375. istat = sfsnatt(io,'lbeg', DFNT_INT32, 1, lbeg(region))
  376. istat = sfsnatt(io,'lend', DFNT_INT32, 1, lend(region))
  377. end if
  378. istat = sfsnatt(io,'xref', DFNT_INT32, 1, xref(region))
  379. istat = sfsnatt(io,'yref', DFNT_INT32, 1, yref(region))
  380. istat = sfsnatt(io,'zref', DFNT_INT32, 1, zref(region))
  381. istat = sfsnatt(io,'tref', DFNT_INT32, 1, tref(region))
  382. istat = sfsnatt(io,'ntrace',DFNT_INT32, 1, ntrace)
  383. istat = sfsnatt(io,'ntracet',DFNT_INT32, 1, ntracet)
  384. istat = sfsnatt(io,'nstd',DFNT_INT32, 1, nstd)
  385. istat = sfsnatt(io,'idate' ,DFNT_INT32, 6, idate)
  386. istat = sfsnatt(io,'istart', DFNT_INT32, 1, istart)
  387. istat = sfsnatt(io,'ndyn_max', DFNT_INT32, 1, ndyn_max)
  388. istat = sfsnatt(io,'nconv', DFNT_INT32, 1, nconv)
  389. istat = sfsnatt(io,'ndiag', DFNT_INT32, 1, ndiag)
  390. istat = sfsnatt(io,'nchem', DFNT_INT32, 1, nchem)
  391. istat = sfsnatt(io,'nsrce', DFNT_INT32, 1, nsrce)
  392. istat = sfsnatt(io,'nread', DFNT_INT32, 1, nread)
  393. istat = sfsnatt(io,'nwrite',DFNT_INT32, 1, nwrite)
  394. istat = sfsnatt(io,'ninst', DFNT_INT32, 1, ninst)
  395. istat = sfsnatt(io,'ncheck',DFNT_INT32, 1, ncheck)
  396. istat = sfsnatt(io,'ndiff', DFNT_INT32, 1, ndiff)
  397. istat = sfsnatt(io,'itaui', DFNT_INT32, 1, itaui)
  398. istat = sfsnatt(io,'itaue', DFNT_INT32, 1, itaue)
  399. istat = sfsnatt(io,'itaut', DFNT_INT32, 1, itaut)
  400. istat = sfsnatt(io,'itau0', DFNT_INT32, 1, itau0)
  401. istat = sfsnatt(io,'idatei' , DFNT_INT32, 6, idatei)
  402. istat = sfsnatt(io,'idatee' , DFNT_INT32, 6, idatee)
  403. istat = sfsnatt(io,'idatet' , DFNT_INT32, 6, idatet)
  404. istat = sfsnatt(io,'idate0' , DFNT_INT32, 6, idate0)
  405. istat = sfsnatt(io,'icalendo' ,DFNT_INT32, 1, icalendo)
  406. istat = sfsnatt(io,'iyear0' , DFNT_INT32, 1, iyear0)
  407. istat = sfsnatt(io,'julday0' , DFNT_INT32, 1, julday0)
  408. istat = sfsnatt(io,'ndiagp1' , DFNT_INT32, 1, ndiagp1)
  409. istat = sfsnatt(io,'ndiagp2' , DFNT_INT32, 1, ndiagp2)
  410. istat = sfsnatt(io,'nstep' , DFNT_INT32, 1, nstep)
  411. istat = sfsnatt(io,'cpu0' , DFNT_FLOAT64, 1, cpu0)
  412. istat = sfsnatt(io,'cpu1' , DFNT_FLOAT64, 1, cpu1)
  413. istat = sfsnatt(io,'ra' , DFNT_FLOAT64, ntracet, ra)
  414. istat = sfsnatt(io,'fscale' , DFNT_FLOAT64, ntrace, fscale)
  415. istat = sfscatt(io,'names' , DFNT_CHAR, ntrace*tracer_name_len, names)
  416. istat = sfsnatt(io,'areag' , DFNT_FLOAT64, 1, areag)
  417. istat = sfsnatt(io,'czeta' , DFNT_FLOAT64, 1, czeta)
  418. istat = sfsnatt(io,'czetak' , DFNT_FLOAT64, 1, czetak)
  419. istat = sfscatt(io,'xlabel' , DFNT_CHAR, 160, xlabel)
  420. istat = sfsnatt(io,'istd' , DFNT_INT32, nstd, istd)
  421. istat = sfsnatt(io,'newyr' , DFNT_INT32, 1, newyr)
  422. istat = sfsnatt(io,'newmonth', DFNT_INT32, 1, newmonth)
  423. istat = sfsnatt(io,'newday' , DFNT_INT32, 1, newday)
  424. istat = sfsnatt(io,'newsrun' , DFNT_INT32, 1, newsrun)
  425. ! istat = sfsnatt(io,'cdebug' , DFNT_INT32, 1, cdebug)
  426. istat = sfsnatt(io,'limits' , DFNT_INT32, 1, limits)
  427. istat = sfsnatt(io,'nregions' , DFNT_INT32, 1, nregions)
  428. istat = sfsnatt(io,'w_mmix' , DFNT_FLOAT64, 1, w_mmix(region))
  429. istat = sfsnatt(io,'at' , DFNT_FLOAT64,lm(1)+1, at)
  430. istat = sfsnatt(io,'bt' , DFNT_FLOAT64,lm(1)+1, bt)
  431. #ifdef slopes
  432. #ifndef secmom
  433. istat = sfscatt(io,'adv_scheme' , DFNT_CHAR, 5, 'slope')
  434. #else
  435. istat = sfscatt(io,'adv_scheme' , DFNT_CHAR, 5, '2nd_m')
  436. #endif
  437. #endif
  438. istat = sfsnatt(io,'nsplitsteps' , DFNT_INT32, 1, nsplitsteps)
  439. istat = sfscatt(io,'splitorder' , DFNT_CHAR, nsplitsteps, splitorder)
  440. end if IOroot
  441. CALL WRITEMMIX_REGION( region, rcode )
  442. IF_NOTOK_RETURN(rcode=1)
  443. call par_barrier
  444. if ( isRoot ) then
  445. write(gol,'("write mmix: sfend returns",i4)') sfend(io) ; call goPr
  446. endif
  447. #else
  448. write (gol,'("not compiled with hdf4")'); call goErr
  449. TRACEBACK; rcode=1; return
  450. #endif // with_hdf4
  451. END DO REG
  452. ! ok
  453. call goLabel(); rcode=0
  454. CONTAINS
  455. !------------------------------------------------------------------------
  456. ! TM5 !
  457. !------------------------------------------------------------------------
  458. !BOP
  459. !
  460. ! !IROUTINE: WRITEMMIX_REGION
  461. !
  462. ! !DESCRIPTION: Write to file mean fields defined in this module
  463. !\\
  464. !\\
  465. ! !INTERFACE:
  466. !
  467. SUBROUTINE WRITEMMIX_REGION( region, rcode )
  468. !
  469. ! !USES:
  470. !
  471. use global_data, only : region_dat
  472. use tm5_distgrid, only : dgrid, Get_DistGrid, gather
  473. use ParTools, only : isRoot
  474. !
  475. ! !INPUT PARAMETERS:
  476. !
  477. integer,intent(in) :: region
  478. !
  479. ! !INPUT/OUTPUT PARAMETERS:
  480. !
  481. integer, intent(inout) :: rcode
  482. !
  483. ! !REVISION HISTORY:
  484. ! 17 Nov 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  485. !
  486. ! !REMARKS:
  487. !
  488. !EOP
  489. !---------------------------------------------------------------------
  490. !BOC
  491. character(len=*), parameter :: rname = mname//'/write_mmix_region'
  492. real,dimension(:,:,:,:),pointer :: rmmix, std_mmix
  493. real,dimension(:,:,:) ,pointer :: tempm
  494. real,dimension(:,:) ,pointer :: presm
  495. real,dimension(:,:,:,:),allocatable :: rmmix_glb
  496. real,dimension(:,:,:,:),allocatable :: std_mmix_glb
  497. integer :: imr, jmr, lmr, nsend, i1, i2, j1, j2, n
  498. real :: ahelp,ahelp1
  499. ! start
  500. call goLabel( rname )
  501. #ifdef with_hdf4
  502. ! global and local indices
  503. imr = im(region)
  504. jmr = jm(region)
  505. lmr = lm(region)
  506. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  507. ! array to gather data
  508. if (isRoot) then
  509. allocate( rmmix_glb(imr,jmr,lmr,ntrace) )
  510. allocate(std_mmix_glb(imr,jmr,lmr,nstd) )
  511. else
  512. allocate( rmmix_glb(1,1,1,1) )
  513. allocate(std_mmix_glb(1,1,1,1) )
  514. end if
  515. ! shortcut
  516. rmmix => mmix_dat(region)%rmmix
  517. std_mmix => mmix_dat(region)%std_mmix
  518. tempm => mmix_dat(region)%tempm
  519. presm => mmix_dat(region)%presm
  520. !
  521. !write(gol,'("writemmix_region: w_mmix",f12.2)') w_mmix(region); call goPr
  522. if ( w_mmix(region) > 2 ) then
  523. ! scale stdt deviation tracers
  524. do k= 1,nstd
  525. do l= 1,lmr
  526. do j=j1,j2
  527. do i=i1,i2
  528. n = istd(k)
  529. ahelp = rmmix(i,j,l,n)
  530. ahelp1= fscale(n) * &
  531. (std_mmix(i,j,l,k) - ahelp*ahelp/w_mmix(region) ) / &
  532. (w_mmix(region)-1)
  533. std_mmix(i,j,l,k)=max(1e-35,ahelp1)
  534. end do
  535. end do
  536. end do
  537. end do
  538. ! scale tracers
  539. do n=1,ntrace
  540. rmmix(:,:,:,n) = fscale(n) * rmmix(:,:,:,n)/w_mmix(region)
  541. end do
  542. ! scale temperature and pressure
  543. tempm = tempm/w_mmix(region)
  544. presm = presm/w_mmix(region)
  545. ! GATHER AND WRITE METEO
  546. call gather(dgrid(region), tempm, rmmix_glb(:,:,:,1), 0, rcode)
  547. IF_NOTOK_RETURN(rcode=1)
  548. if (isRoot) then
  549. call io_write3d_32d(io,imr,'LON'//trim(region_name(region)), &
  550. jmr,'LAT'//trim(region_name(region)),lmr, &
  551. 'HYBRID',rmmix_glb(1:imr,1:jmr,1:lmr,1),'tempm',idate)
  552. end if
  553. call gather(dgrid(region), presm, rmmix_glb(:,:,1,1), 0, rcode)
  554. IF_NOTOK_RETURN(rcode=1)
  555. if (isRoot) then
  556. call io_write2d_32d(io,imr,'LON'//trim(region_name(region)), &
  557. jmr,'LAT'//trim(region_name(region)), &
  558. rmmix_glb(1:imr,1:jmr,1,1),'presm',idate)
  559. end if
  560. ! gather & write mmix
  561. call gather(dgrid(region), rmmix, rmmix_glb, 0, rcode)
  562. IF_NOTOK_RETURN(rcode=1)
  563. if (isRoot) then
  564. do n=1,ntrace
  565. name=names(n)
  566. call io_write3d_32d(io,imr,'LON'//trim(region_name(region)), &
  567. jmr,'LAT'//trim(region_name(region)),lmr,'HYBRID', &
  568. rmmix_glb(1:imr,1:jmr,1:lmr,n),name,idate)
  569. end do
  570. end if
  571. ! gather and write stdt dev
  572. call gather(dgrid(region), std_mmix, std_mmix_glb, 0, rcode)
  573. IF_NOTOK_RETURN(rcode=1)
  574. if (isRoot) then
  575. do k=1,nstd
  576. n = istd(k)
  577. name = 'std_'//names(n)
  578. call io_write3d_32d(io,imr,'LON'//trim(region_name(region)), &
  579. jmr,'LAT'//trim(region_name(region)),lmr,'HYBRID', &
  580. std_mmix_glb(1:imr,1:jmr,1:lmr,k),name,idate)
  581. end do
  582. end if
  583. else
  584. write(gol,'("writemmix_region: NO WRITING! just avoided division by zero!")') ; call goPr
  585. end if
  586. deallocate(rmmix_glb)
  587. deallocate(std_mmix_glb)
  588. nullify(rmmix)
  589. nullify(std_mmix)
  590. nullify(tempm)
  591. nullify(presm)
  592. #else
  593. write (gol,'("not compiled with hdf4")'); call goErr
  594. TRACEBACK; rcode=1; return
  595. #endif // with_hdf4
  596. ! ok
  597. call goLabel(); rcode=0
  598. END SUBROUTINE WRITEMMIX_REGION
  599. !EOC
  600. END SUBROUTINE WRITE_MMIX
  601. !EOC
  602. END MODULE USER_OUTPUT_MMIX