redgridZoom.F90 58 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787
  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. !
  7. #include "tm5.inc"
  8. !
  9. !-----------------------------------------------------------------------------
  10. ! TM5 !
  11. !-----------------------------------------------------------------------------
  12. !BOP
  13. !
  14. ! !MODULE: REDGRIDZOOM
  15. !
  16. ! !DESCRIPTION:
  17. !\\
  18. !\\
  19. ! !INTERFACE:
  20. !
  21. MODULE REDGRIDZOOM
  22. !
  23. ! !USES:
  24. !
  25. use GO , only : gol, goErr, goPr
  26. use binas, only : pi
  27. use dims, only : nregions, im, jm, okdebug
  28. implicit none
  29. private
  30. !
  31. ! !PUBLIC MEMBER FUNCTIONS:
  32. !
  33. public :: uni2red_mf, redgrid_init, redgrid_done, calc_pdiff
  34. public :: uni2red, red2uni, red2uni_em
  35. #ifdef secmom
  36. public :: uni2red_2nd, red2uni_em_2nd
  37. #endif
  38. !
  39. ! !PUBLIC DATA MEMBERS:
  40. !
  41. public :: nred, nredmax, clustsize, grid_reduced, idle_xadv
  42. public :: jred, imredj
  43. public :: mfl_alt1, m_alt1, rm_alt1, rxm_alt1, rym_alt1, rzm_alt1
  44. integer, parameter :: nredmax=60
  45. logical :: grid_reduced=.true.
  46. logical :: idle_xadv=.false. ! proc is idle during x-advection (possible if reduced grid with npe_lon/=1)
  47. ! the number of reduced latitude circles per region on the current proc
  48. integer, dimension(nregions) :: nred=0
  49. ! number of joined cells per latitude circle and region
  50. integer, allocatable :: clustsize(:,:) ! j1:j2,nregions
  51. ! reduced dimension......
  52. integer, allocatable :: imredj(:,:) ! j1:j2,nregions
  53. ! latitaude numbers where the reduction applies
  54. integer, dimension(nredmax,nregions) :: jred
  55. ! alternate mass array (used on row_roots, to deal with reduced grid). With and w/o halo.
  56. real, dimension(:,:,:), target, allocatable :: mfl_alt1, m_alt1
  57. real, dimension(:,:,:,:), target, allocatable :: rm_alt1, rxm_alt1, rym_alt1, rzm_alt1
  58. real, dimension(:,:,:), allocatable :: mfl_alt2, m_alt2
  59. real, dimension(:,:,:,:), allocatable :: rm_alt2
  60. !
  61. ! !PRIVATE DATA MEMBERS:
  62. !
  63. character(len=*), parameter :: mname = 'redgridZoom'
  64. real, parameter :: dl = 2.0*pi/im(1)
  65. real, parameter :: dp = pi/jm(1)
  66. real, parameter :: epsx = epsilon(0.0)
  67. !
  68. ! !REVISION HISTORY:
  69. ! 20 Dec 2012 - Ph Le Sager - TM5-MP version.
  70. !
  71. ! !REMARKS:
  72. !
  73. !EOP
  74. !------------------------------------------------------------------------
  75. CONTAINS
  76. ! Fortran code for Split-rg (reduced grid) scheme for advection on the
  77. ! globe.
  78. !
  79. ! VERSION: 1.1
  80. ! DATE: November 12, 1998
  81. !
  82. ! Version 1.0 Dated October 19, 1998.
  83. ! Version 1.1 Corrected red2uni routine and added new uni2red_m
  84. ! routine.
  85. ! (Orography effects were erroneously not taken into
  86. ! account in the reduced to uniform grid conversion)
  87. !
  88. ! This code solves the discrete advection equation for the tracer
  89. ! mass, with the wind field specified in air mass fluxes:
  90. !
  91. ! dtracm/dt = (
  92. ! mu chi (i-half) - mu chi (i+half)
  93. ! mv chi (j-half) - mv chi (j+half)
  94. ! mw chi (k-half) - mw chi (k+half) )
  95. !
  96. ! where
  97. !
  98. ! tracm = tracer mass
  99. ! mu, mv, mw = air mass fluxes
  100. ! chi = tracm / mass = tracer mixing ratio
  101. ! mass = air mass
  102. !
  103. ! The integer values of indices i, j, and k correspond to cell centers.
  104. !
  105. ! See:
  106. !
  107. ! Petersen, A.C., E.J. Spee, H. van Dop, and W. Hundsdorfer,
  108. ! An evaluation and intercomparison of four new advection schemes
  109. ! for use in global chemistry models,
  110. ! Journal of Geophysical Research, 103, 19253-19269, 1998.
  111. !
  112. ! Written by Edwin Spee, CWI, Amsterdam, The Netherlands
  113. !
  114. ! Parts of the code are written by
  115. ! Joke Blom and Willem Hundsdorfer (CWI) and
  116. !
  117. ! The advection routine is called in the following way:
  118. !
  119. ! call advect_split(tracm, mu, mv, mw, mass, dt)
  120. !
  121. ! tracm = tracer mass real(im,jm,lm,ntracet) [kg]
  122. !
  123. ! mu = longitudinal mass flux real(im,jm,lm) [kg/s]
  124. ! (defined on eastward side of grid
  125. ! cells; for all grid cells)
  126. !
  127. ! mv = latitudinal mass flux real(im,jm,lm) [kg/s]
  128. ! (defined on southward side of grid
  129. ! cells; only j=2,..,jm are used)
  130. !
  131. ! mw = vertical massflux real(im,jm,lm) [kg/s]
  132. ! (defined on upper side of grid cell;
  133. ! only l=1,..,lm-1 are used since it is
  134. ! assumed that there is no flux across
  135. ! the top of the model)
  136. !
  137. ! The number of latitudinal elements actually used for mu, mv, and mw
  138. ! depends on the advection grid; for mv this number is the determined
  139. ! by the latitude row with the largest number of cells bordering a
  140. ! certain cell-bounding latitude circle.
  141. !
  142. ! mass = air mass real(im,jm,lm) [kg]
  143. !
  144. ! dt = timestep real [s]
  145. !
  146. ! The physical units were chosen for compatibility with the TM3 model
  147. ! but can be changed for other global tracer models, provided that
  148. ! the calculation of the fluxes is done with an equivalent of tracer
  149. ! mixing ratios and not of tracer concentrations (make for other tracer
  150. ! models, if necessary, the appropriate changes in the routines
  151. ! split_lab, split_phi, and split_eta, where now tracer mixing ratios
  152. ! are calculated as tracm / mass; also the grid transformations as done
  153. ! in advect_split are different for tracer mass and concentration).
  154. !
  155. ! The longitude is counted from west to east, the latitude from south
  156. ! to north, and the height from surface to top.
  157. !
  158. ! The variables tracm, mu, mv, mw and mass should be declared in
  159. ! the calling program under any name; dt is a parameter. The
  160. ! parameters im, jm, and lm denote the number of grid cells in
  161. ! longitudinal, latitudinal, and vertical direction, respectively.
  162. ! ntracet is the number of transported tracers. The letters 'u', 'v',
  163. ! and 'w' for the three dimensions are in the code often replaced by
  164. ! 'l', 'p', and 'e', denoting the coordinates lambda, phi, and eta,
  165. ! respectively (see Petersen et al. 1998). The advection scheme works
  166. ! in principle with any grid and coordinate system of the main model.
  167. ! However, in the current implementation (made for the TM3 model) the
  168. ! variables tracm and mass are assumed to be defined in the main
  169. ! program on a uniform grid with polar cap, and the variables mu, mv,
  170. ! and mw on the advection grid (i.e., reduced grid with polar cap).
  171. ! Locally in the advection routines a transformation of tracm and mass,
  172. ! if necessary, is made to the advection grid. Please contact us for
  173. ! information on the changes that have to be made to work with other
  174. ! main model grids. Depending on the interests of users, we intend to
  175. ! generalize the code with respect to the main model grid in the next
  176. ! version.
  177. !
  178. ! The following parameters and variables, related to the specification
  179. ! of the advection grid are used by the routines of the advection
  180. ! scheme:
  181. !
  182. ! integer, parameter :: nredmax = 10
  183. ! real, parameter :: dl = 2.0 * pi / im
  184. ! real, parameter :: dp = pi / jm
  185. ! integer nred
  186. ! integer clustsize(0:nredmax),
  187. ! jred(-nredmax:nredmax+1),imredj(jm)
  188. ! real maxtau
  189. ! integer advsub
  190. !
  191. ! nredmax = maximum number of grid reductions per hemisphere
  192. ! (in this implementation the minimum number of grid
  193. ! reductions per hemisphere equals one, since use is
  194. ! made of polar caps)
  195. ! dl = longitudinal uniform grid cell size in lambda
  196. ! coordinates
  197. ! dp = latitudinal grid cell size in phi coordinates
  198. ! nred = number of grid reductions
  199. ! clustsize = array with the ratio im / imred, as a function of the
  200. ! absolute value of the latitude zone index, where imred
  201. ! is the actually used number of cells in the longitudinal
  202. ! direction for the given latitude zone
  203. ! jred = latitude number where grid reduction starts (seen from
  204. ! SP), as a function of the reduction zone index
  205. ! imredj(j) = number of cells for latitude #j
  206. ! maxtau = time step such that CFL <= 1 in all directions (given
  207. ! the directional splitting, see routine advect_split)
  208. ! advsub = largest integer such that dtadv / advsub <= maxtau,
  209. ! with dtadv the advection time step in operator splitting
  210. !
  211. ! The advection grid variables for the reduced grid are automatically
  212. ! set by the following line:
  213. !
  214. ! call redgrid_init(clustsize, jred, imredj, nred, nredmax, im, jm,
  215. ! . pi, .false.)
  216. !
  217. ! The variables maxtau and advsub should be set each time new mass
  218. ! fluxes (wind fields) are available in the model through
  219. !
  220. ! call split_maxtau(mu, mv, mw, mass, dtadv)
  221. !
  222. ! where dtadv is the advection time step in the main model.
  223. !
  224. ! Furthermore, some routines in the advection scheme need information
  225. ! on the machine precision. The following variable is used for this
  226. ! purpose:
  227. !
  228. ! real, parameter :: epsx = epsilon(0.0)
  229. !
  230. ! The value of epsx is dependent on the computing platform that is used.
  231. ! epsilon is a Fortran 90 intrinsic function. For example, for our Cray
  232. ! C90 eps is about 1e-14.
  233. !
  234. ! The above-mentioned parameters and variables are assumed to be
  235. ! declared in the module global_data (Fortran 90) or in some common
  236. ! block (Fortran 77). The current implementation (Fortran 90) uses the
  237. ! statements
  238. !
  239. ! use global_data
  240. ! implicit none
  241. !
  242. ! If Fortran 77 is preferred one should define a common block or
  243. ! use an existing common block to include the above-given parameters
  244. ! and variables, e.g.
  245. !
  246. ! implicit none
  247. ! (declarations as given in the above)
  248. ! common/advgrid/nredmax,dl,dp,nred,clustsize,jred,maxtau,advsub
  249. !
  250. ! Also the parameters im, jm, lm, ntracet, pi, twopi (= 2 * pi), and
  251. ! eps are assumed to be declared in the module global_data.
  252. !
  253. ! --------------------------
  254. ! Example of a reduced grid
  255. ! --------------------------
  256. !
  257. ! NP=North Pole
  258. ! SP=South Pole
  259. ! EQ=Equator
  260. ! | grid boundary in longitudal direction
  261. ! o cell center
  262. ! j imredj clustsize latitude zone
  263. ! NP| o | 13 1 12 3
  264. ! | o | o | o | 12 3 4 2
  265. ! | o | o | o | o | o | o | 11 6 2 1
  266. ! | o | o | o | o | o | o | 10 6 2 1
  267. ! |o|o|o|o|o|o|o|o|o|o|o|o| 9 12 1 0
  268. ! |o|o|o|o|o|o|o|o|o|o|o|o| 8 12 1 0
  269. ! EQ|o|o|o|o|o|o|o|o|o|o|o|o| 7 12 1 0
  270. ! |o|o|o|o|o|o|o|o|o|o|o|o| 6 12 1 0
  271. ! |o|o|o|o|o|o|o|o|o|o|o|o| 5 12 1 0
  272. ! | o | o | o | o | o | o | 4 6 2 -1
  273. ! | o | o | o | o | o | o | 3 6 2 -1
  274. ! | o | o | o | 2 3 4 -2
  275. ! SP| o | 1 1 12 -3
  276. !
  277. ! This grid would have
  278. ! im = 12, jm = 13, nred = 3
  279. !
  280. ! jred(-3) = 1 by definition
  281. ! jred(-2) = 2
  282. ! jred(-1) = 3
  283. ! jred( 0) = 5
  284. ! jred( 1) =10
  285. ! jred( 2) =12
  286. ! jred( 3) =13
  287. ! jred( 4) =14=jm+1 by definition
  288. !
  289. ! clustsize(3) = 12
  290. ! clustsize(2) = 4
  291. ! clustsize(1) = 2
  292. ! clustsize(0) = 1
  293. !CMK total new definition to allow zoom regios..
  294. ! nred(nregions) :: number of reduced latitudes circles < jm(region)
  295. ! nredmax :: maximum number of reduced latitude circles...
  296. ! clustsize(nredmax.nregions) :: number of joined cells for n'th circle
  297. ! jred(nredmax.nregions) :: corresponding j value in 1...jm(region) array
  298. ! imredj(nredmax.nregions) :: 'new' im value for the reduced grid...
  299. !CMK
  300. !PLS new definitions for TM5-MP
  301. ! nred(nregions) :: number of reduced latitudes circles on current tile (ie proc) and region
  302. ! nredmax :: maximum number of reduced latitude circles
  303. ! clustsize(j1:j2, nregions) :: number of joined cells for J'th circle (default=1=no_cluster=no_reduced_grid)
  304. ! jred (nredmax, nregions) :: j value for 1...nred(region) in 1..jmr
  305. ! imredj (j1:j2, nregions) :: 'new' im value for the reduced grid, default to im(region)
  306. !PLS
  307. !--------------------------------------------------------------------------
  308. ! TM5 !
  309. !--------------------------------------------------------------------------
  310. !BOP
  311. !
  312. ! !IROUTINE: uni2red_mf
  313. !
  314. ! !DESCRIPTION: Converts mass fluxes mfl from uniform grid to reduced grid
  315. !\\
  316. !\\
  317. ! !INTERFACE:
  318. !
  319. subroutine uni2red_mf(region,i1,i2,j1,j2, status)
  320. !
  321. ! !USES:
  322. !
  323. use dims, only : lm, im
  324. use global_data, only : wind_dat
  325. use partools, only : isRowRoot, npe_lon
  326. use tm5_distgrid, only : dgrid, gather_j_band
  327. !
  328. ! !INPUT PARAMETERS:
  329. !
  330. integer,intent(in) :: region,i1,i2,j1,j2
  331. !
  332. ! !OUTPUT PARAMETERS:
  333. !
  334. integer, intent(out) :: status
  335. !
  336. ! !REVISION HISTORY:
  337. ! Written by Edwin Spee, CWI, Amsterdam, The Netherlands
  338. ! cmk changed.....
  339. ! 20 Dec 2012 - Ph Le Sager - TM5-MP version
  340. !
  341. ! !REMARKS:
  342. ! - no need to check on tile bounds, zero-trip loop for jreg does the job
  343. !EOP
  344. !------------------------------------------------------------------------
  345. !BOC
  346. character(len=*), parameter :: rname = mname//'/uni2red_mf'
  347. real,dimension(:,:,:),pointer :: mfl, mfl_alt
  348. integer :: clust_size, i, j, l, jreg
  349. integer :: lmr, imr, halo
  350. ! -- start
  351. mfl => wind_dat(region)%am
  352. halo=wind_dat(region)%halo
  353. imr=im(region)
  354. lmr=lm(region)
  355. ! Two scenarios
  356. if (npe_lon /= 1) then
  357. !
  358. ! decomposition along longitudes => work on row_root
  359. !
  360. if (nred(region)/=0) then ! some reduce grid on this tile
  361. ! array to gather (remove halo)
  362. allocate(mfl_alt( i1:i2, j1:j2, 0:lmr+1))
  363. mfl_alt = mfl(i1:i2,j1:j2,:)
  364. CALL GATHER_J_BAND(dgrid(region), mfl_alt, mfl_alt2, status, jref=j1, rowcom=.true.)
  365. IF_NOTOK_RETURN(status=1)
  366. if (isRowRoot) then
  367. mfl_alt1(1:imr,:,:) = mfl_alt2
  368. mfl_alt1( 0,:,:) = mfl_alt1(imr,:,:)
  369. mfl_alt1( -1,:,:) = mfl_alt1(imr-1,:,:)
  370. mfl_alt1(imr+1,:,:) = mfl_alt1(1,:,:)
  371. !PLS mfl_alt1(imr+2,:,:) = mfl_alt1(2,:,:) ! full on
  372. do l=1,lmr
  373. do jreg = 1,nred(region) ! loop over the reduced latitudes
  374. j = jred(jreg,region) ! latitude
  375. clust_size = clustsize(j,region) ! clustersize
  376. do i=1,imredj(j,region)
  377. mfl_alt1(i,j,l) = mfl_alt1(i*clust_size,j,l) ! compress mfl
  378. end do
  379. do i=imredj(j,region)+1,im(region)
  380. mfl_alt1(i,j,l) = -1.0
  381. end do
  382. ! Update boundary condition. Only meaningful for x-cyclic regions (which is the
  383. ! only possibility in TM5-MP).
  384. mfl_alt1( 0,j,l)=mfl_alt1(imredj(j,region),j,l)
  385. mfl_alt1(-1,j,l)=mfl_alt1(imredj(j,region)-1,j,l) ! needed to limit mpi comm in advectx__slopes.F90
  386. mfl_alt1(imredj(j,region)+1,j,l)=mfl_alt1(1,j,l) ! needed to limit mpi comm in advectx__slopes.F90
  387. end do
  388. end do
  389. endif
  390. deallocate( mfl_alt )
  391. endif
  392. else
  393. !
  394. ! Reduced grid without longitudinal decomposition
  395. !
  396. do l=1,lmr
  397. do jreg = 1,nred(region) ! loop over the reduced latitudes
  398. j = jred(jreg,region) ! latitude
  399. clust_size = clustsize(j,region) ! clustersize
  400. do i=1,imredj(j,region)
  401. mfl(i,j,l) = mfl(i*clust_size,j,l) ! compress mfl
  402. end do
  403. do i=imredj(j,region)+1,im(region)
  404. mfl(i,j,l) = -1.0
  405. end do
  406. ! Update boundary condition. Only meaningful for x-cyclic regions (which is the
  407. ! only possibility in TM5-MP).
  408. mfl( 0,j,l)=mfl(imredj(j,region),j,l)
  409. mfl(-1,j,l)=mfl(imredj(j,region)-1,j,l) ! needed to limit mpi comm in advectx__slopes.F90
  410. mfl(imredj(j,region)+1,j,l)=mfl(1,j,l) ! needed to limit mpi comm in advectx__slopes.F90
  411. end do
  412. end do
  413. endif
  414. nullify(mfl)
  415. status=0
  416. end subroutine uni2red_mf
  417. !EOC
  418. !--------------------------------------------------------------------------
  419. ! TM5 !
  420. !--------------------------------------------------------------------------
  421. !BOP
  422. !
  423. ! !IROUTINE: REDGRID_INIT
  424. !
  425. ! !DESCRIPTION: allocate work arrays, read settings from rc file and fill
  426. ! reduced grid parameters (clustsize, jred, and imredj) for
  427. ! current region and tile.
  428. !\\
  429. !\\
  430. ! !INTERFACE:
  431. !
  432. SUBROUTINE REDGRID_INIT( region, status )
  433. !
  434. ! !USES:
  435. !
  436. use GO, only : TrcFile, Init, Done, ReadRc
  437. use dims, only : lm, im
  438. use global_data, only : wind_dat
  439. use tracer_data, only : mass_dat
  440. use meteodata , only : m_dat
  441. use chem_param, only : ntracet
  442. use tm5_distgrid, only : dgrid, Get_DistGrid
  443. use partools, only : isRowRoot, npe_lon
  444. use global_data, only : rcfile
  445. !
  446. ! !INPUT PARAMETERS:
  447. !
  448. integer, intent(in) :: region
  449. !
  450. ! !OUTPUT PARAMETERS:
  451. !
  452. integer, intent(out) :: status
  453. !
  454. ! !REVISION HISTORY:
  455. ! Written by Edwin Spee, CWI, Amsterdam, The Netherlands, based on work of Joke Blom.
  456. ! 20 Dec 2012 - Ph Le Sager - TM5-MP
  457. !
  458. ! !REMARKS:
  459. !
  460. !EOP
  461. !------------------------------------------------------------------------
  462. !BOC
  463. character(len=*), parameter :: rname = mname//'/redgrid_init'
  464. integer :: j, i1, i2, j1, j2, imr, lmr, halo
  465. character(len=256) :: fname, line
  466. type(TrcFile) :: rcF
  467. ! --- begin -----------------------------
  468. ! Open rcfile
  469. call Init( rcF, rcfile, status )
  470. IF_NOTOK_RETURN(status=1)
  471. ! grid reduction ?
  472. call ReadRc( rcF, 'proces.advection.reduced', grid_reduced, status )
  473. IF_NOTOK_RETURN(status=1)
  474. if (grid_reduced) then
  475. ! Arrays
  476. CALL GET_DISTGRID( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  477. allocate( clustsize(j1:j2, nregions))
  478. allocate( imredj(j1:j2, nregions))
  479. call Read_RedGrid_rc( region, status )
  480. IF_NOTOK_RETURN(status=1)
  481. ! Extra arrays to work on row_root (only if really needed)
  482. if (nred(region)/=0 .and. (npe_lon/=1)) then
  483. if (isRowRoot) then
  484. imr = im(region)
  485. lmr = lm(region)
  486. halo= wind_dat(1)%halo
  487. allocate(mfl_alt1( 1-halo:imr+halo, j1:j2, 0:lmr+1))
  488. allocate(mfl_alt2( imr, j1:j2, 0:lmr+1))
  489. halo= m_dat(1)%halo
  490. allocate( m_alt1( 1-halo:imr+halo, j1:j2, lmr))
  491. allocate( m_alt2( imr, j1:j2, lmr))
  492. halo= mass_dat(1)%halo
  493. allocate(rm_alt1( 1-halo:imr+halo, j1:j2, lmr, ntracet))
  494. allocate(rm_alt2( imr, j1:j2, lmr, ntracet))
  495. #ifdef slopes
  496. allocate(rxm_alt1( 1-halo:imr+halo, j1:j2, lmr, ntracet))
  497. allocate(rym_alt1( 1-halo:imr+halo, j1:j2, lmr, ntracet))
  498. allocate(rzm_alt1( 1-halo:imr+halo, j1:j2, lmr, ntracet))
  499. #endif
  500. else
  501. idle_xadv=.true.
  502. allocate(mfl_alt2(1,1,1) )
  503. allocate( m_alt2(1,1,1) )
  504. allocate( rm_alt2(1,1,1,1))
  505. endif
  506. endif
  507. endif
  508. ! close
  509. call Done( rcF, status )
  510. IF_NOTOK_RETURN(status=1)
  511. status = 0
  512. END SUBROUTINE REDGRID_INIT
  513. !EOC
  514. !--------------------------------------------------------------------------
  515. ! TM5 !
  516. !--------------------------------------------------------------------------
  517. !BOP
  518. !
  519. ! !IROUTINE: REDGRID_DONE
  520. !
  521. ! !DESCRIPTION: deallocate work arrays
  522. !\\
  523. !\\
  524. ! !INTERFACE:
  525. !
  526. SUBROUTINE REDGRID_DONE( status )
  527. !
  528. ! !USES:
  529. !
  530. use partools, only : isRowRoot, npe_lon
  531. !
  532. ! !OUTPUT PARAMETERS:
  533. !
  534. integer, intent(out) :: status
  535. !
  536. ! !REMARKS: used only for region=1, in a hardcoded way
  537. !
  538. !EOP
  539. !------------------------------------------------------------------------
  540. !BOC
  541. character(len=*), parameter :: rname = mname//'/redgrid_done'
  542. ! --- begin -----------------------------
  543. if (grid_reduced) then
  544. deallocate( clustsize)
  545. deallocate( imredj)
  546. if (nred(1)/=0 .and. (npe_lon/=1)) then
  547. if (isRowRoot) then
  548. deallocate(mfl_alt1)
  549. deallocate(mfl_alt2)
  550. deallocate( m_alt1)
  551. deallocate( m_alt2)
  552. deallocate( rm_alt1)
  553. deallocate( rm_alt2)
  554. #ifdef slopes
  555. deallocate(rxm_alt1)
  556. deallocate(rym_alt1)
  557. deallocate(rzm_alt1)
  558. #endif
  559. else
  560. deallocate(mfl_alt2)
  561. deallocate( m_alt2)
  562. deallocate( rm_alt2)
  563. endif
  564. endif
  565. endif
  566. status = 0
  567. END SUBROUTINE REDGRID_DONE
  568. !EOC
  569. !--------------------------------------------------------------------------
  570. ! TM5 !
  571. !--------------------------------------------------------------------------
  572. !BOP
  573. !
  574. ! !IROUTINE: READ_REDGRID_RC
  575. !
  576. ! !DESCRIPTION:
  577. !\\
  578. !\\
  579. ! !INTERFACE:
  580. !
  581. subroutine Read_RedGrid_rc( region, status )
  582. !
  583. ! !USES:
  584. !
  585. use GO, only : TrcFile, Init, Done, ReadRc
  586. use global_data, only : rcfile
  587. use dims, only : region_name, ybeg, yend, dy, yref
  588. use tm5_distgrid, only : dgrid, Get_DistGrid
  589. use partools, only : isRoot
  590. !
  591. ! !INPUT PARAMETERS:
  592. !
  593. integer, intent(in) :: region
  594. !
  595. ! !OUTPUT PARAMETERS:
  596. !
  597. integer, intent(out) :: status
  598. !
  599. ! !REVISION HISTORY:
  600. ! 20 Dec 2012 - Ph Le Sager - TM5-MP version
  601. ! 6 Jun 2013 - P. Le Sager - check for consecutive 1-cell rings
  602. !
  603. ! !REMARKS:
  604. !
  605. !EOP
  606. !------------------------------------------------------------------------
  607. !BOC
  608. character(len=*), parameter :: rname = mname//'/Read_RedGrid_rc'
  609. type(TrcFile) :: rcF
  610. integer :: imr, jmr, xam, nim
  611. integer :: i,j, i1, i2, j1, j2
  612. integer :: jband
  613. integer :: nred_nh, nred_sh
  614. integer, allocatable :: ncombs_nh(:), ncombs_sh(:)
  615. real :: y0, y1
  616. ! --- begin ----------------------------------------
  617. ! number of lats
  618. imr = im(region)
  619. jmr = jm(region)
  620. ! open settings:
  621. call Init( rcF, rcfile, status )
  622. IF_NOTOK_RETURN(status=1)
  623. ! number of reduced lat bands:
  624. call ReadRc( rcF, 'region.'//trim(region_name(region))//'.redgrid.nh.n', nred_nh, status )
  625. IF_NOTOK_RETURN(status=1)
  626. ! number of reduced lat bands:
  627. call ReadRc( rcF, 'region.'//trim(region_name(region))//'.redgrid.sh.n', nred_sh, status )
  628. IF_NOTOK_RETURN(status=1)
  629. ! total number of reduced bands
  630. nred(region) = nred_nh + nred_sh
  631. ! local bound
  632. CALL GET_DISTGRID( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  633. ! reduced grid ?
  634. if ( nred(region) > 0 ) then
  635. if ( nred(region) > nredmax ) then
  636. write (gol,'("problem with reduced grid. nred > nredmax")'); call goErr
  637. TRACEBACK; status=1; return
  638. end if
  639. ! test done, reset
  640. nred(region)=0
  641. ! to read number of combined cells per lat band
  642. allocate( ncombs_sh(jmr) )
  643. ncombs_sh=1
  644. allocate( ncombs_nh(jmr) )
  645. ! southern hemisphere
  646. if ( nred_sh > 0 ) then
  647. call ReadRc( rcF, 'region.'//trim(region_name(region))//'.redgrid.sh.comb', ncombs_sh(1:nred_sh), status )
  648. IF_NOTOK_RETURN(status=1)
  649. end if
  650. ! northern hemisphere
  651. if ( nred_nh > 0 ) then
  652. call ReadRc( rcF, 'region.'//trim(region_name(region))//'.redgrid.nh.comb', ncombs_nh(1:nred_nh), status )
  653. IF_NOTOK_RETURN(status=1)
  654. do jband= 1, nred_nh
  655. ncombs_sh(jmr-jband+1) = ncombs_nh(jband)
  656. end do
  657. end if
  658. ! fill work arrays
  659. clustsize(:,region) = ncombs_sh(j1:j2)
  660. nred(region) = count(clustsize(:,region)/=1)
  661. jred(1:nred(region), region) = pack((/(j,j=j1,j2)/), clustsize(:,region)/=1)
  662. imredj(:,region) = imr ! default
  663. do i=1,nred(region)
  664. j = jred(i, region)
  665. imredj(j,region) = imr/clustsize(j,region)
  666. end do
  667. ! Testing (global)
  668. do j = 1, jmr
  669. ! check if number of combined cells matches with grid:
  670. if ( modulo(imr,ncombs_sh(j)) /= 0 ) then
  671. write (gol,'("number of combined cells not ok:")') ; call goErr
  672. write (gol,'(" region : ",i2," ",a)') region, trim(region_name(region)) ; call goErr
  673. write (gol,'(" lat band : ",i4)') j ; call goErr
  674. write (gol,'(" combined cells : ",i4)') ncombs_sh(j) ; call goErr
  675. write (gol,'(" im : ",i4)') imr ; call goErr
  676. TRACEBACK; status=1; return
  677. end if
  678. ! check with previous ...
  679. if ( j > 1 ) then
  680. xam=max(ncombs_sh(j-1),ncombs_sh(j))
  681. nim=min(ncombs_sh(j-1),ncombs_sh(j))
  682. if ( modulo(xam,nim) /= 0 ) then
  683. write (gol,'("number of combined cells does match with previous:")') ; call goErr
  684. write (gol,'(" region : ",i2," ",a)') region, trim(region_name(region)) ; call goErr
  685. write (gol,'(" lat band : ",i4)') j ; call goErr
  686. write (gol,'(" combined cells : ",i4)') ncombs_sh(j) ; call goErr
  687. write (gol,'(" previous : ",i4)') ncombs_sh(j-1) ; call goErr
  688. TRACEBACK; status=1; return
  689. end if
  690. end if
  691. ! check for consecutive rings with a single reduced grid cell
  692. if ( j > 1 ) then
  693. if ( ncombs_sh(j-1)==imr .and. ncombs_sh(j)==imr ) then
  694. write (gol,'("Consecutive rings with a single reduced grid cell detected:")') ; call goErr
  695. write (gol,'(" region : ",i2," ",a)') region, trim(region_name(region)) ; call goErr
  696. write (gol,'(" lat band : ",i4)') j ; call goErr
  697. write (gol,'(" combined cells : ",i4)') ncombs_sh(j) ; call goErr
  698. write (gol,'(" previous : ",i4)') ncombs_sh(j-1) ; call goErr
  699. TRACEBACK; status=1; return
  700. end if
  701. end if
  702. end do
  703. ! Verbose
  704. if (isRoot) then
  705. write (gol,'(" [Reduced grid] Region """,a,""":")') trim(region_name(region)); call goPr
  706. write (gol,'(" [Reduced grid] - Uniform grid: no. of cells in each latitude band: ",i3,".")') imr; call goPr
  707. do j=1,jmr
  708. if ( ncombs_sh(j) /= 1 ) then
  709. y0=ybeg(region)+(dy/yref(region))*(j-1)
  710. y1=ybeg(region)+(dy/yref(region))*j
  711. write (gol,'(" [Reduced grid] - from ",f6.2," to ",f6.2," degrees latitude: ",i3," cells.")') &
  712. y0,y1,ncombs_sh(j); call goPr
  713. end if
  714. end do
  715. end if
  716. deallocate( ncombs_sh )
  717. deallocate( ncombs_nh )
  718. else
  719. write (gol,'("No reduced grid for region :",a)') trim(region_name(region)); call goPr
  720. nred(region) = 0
  721. end if
  722. ! Done
  723. call Done( rcF, status )
  724. IF_NOTOK_RETURN(status=1)
  725. status = 0
  726. END SUBROUTINE READ_REDGRID_RC
  727. !EOC
  728. !--------------------------------------------------------------------------
  729. ! TM5 !
  730. !--------------------------------------------------------------------------
  731. !BOP
  732. !
  733. ! !IROUTINE: CALC_PDIFF
  734. !
  735. ! !DESCRIPTION: calculate max pressure difference, accounting for reduce
  736. ! grid if used.
  737. !\\
  738. !\\
  739. ! !INTERFACE:
  740. !
  741. SUBROUTINE CALC_PDIFF( region, pdiffmax )
  742. !
  743. ! !USES:
  744. !
  745. use meteodata, only : sp_dat, sp1_dat
  746. use tm5_distgrid, only : dgrid, Get_DistGrid
  747. use partools, only : isRowRoot, npe_lon
  748. !
  749. ! !INPUT PARAMETERS:
  750. !
  751. integer, intent(in) :: region
  752. !
  753. ! !OUTPUT PARAMETERS:
  754. !
  755. real, intent(out) :: pdiffmax ! max pressure difference
  756. !
  757. ! !REVISION HISTORY:
  758. ! 20 Dec 2012 - Ph Le Sager - TM5-MP version
  759. !
  760. ! !REMARKS:
  761. !
  762. !EOP
  763. !------------------------------------------------------------------------
  764. !BOC
  765. integer :: lrg, i, j, ratio, idx, iu, i1, i2, j1, j2
  766. real :: work, work1
  767. real, pointer :: p(:,:,:), pold(:,:,:)
  768. !---- start
  769. p => sp_dat(region)%data
  770. pold => sp1_dat(region)%data
  771. pdiffmax = 0.0
  772. ! local bound
  773. CALL GET_DISTGRID( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  774. ! if no reduced grid
  775. if ( .not. grid_reduced ) then
  776. pdiffmax = maxval(abs(p(i1:i2,j1:j2,1)-pold(i1:i2,j1:j2,1)))
  777. else
  778. if (npe_lon==1) then
  779. ! first maximum over the reduced grid
  780. do lrg = 1,nred(region)
  781. j = jred(lrg,region)
  782. ratio = clustsize(j,region)
  783. do i = 1,imredj(j,region)
  784. work = 0.0
  785. work1 = 0.0
  786. do iu = 1,ratio
  787. idx = (i-1)*ratio+iu
  788. work = work + p(idx,j,1)
  789. work1 = work1 + pold(idx,j,1)
  790. end do
  791. pdiffmax=max(pdiffmax,abs(work-work1)/ratio)
  792. end do
  793. end do
  794. ! now the pressure difference in the non-reduced part
  795. j2loop: do j=j1,j2
  796. if(imredj(j,region).ne.im(region)) cycle j2loop !if reduced...skip
  797. i2loop: do i=i1,i2 ! should be same as 1,im(region) by design
  798. pdiffmax = max(pdiffmax,abs(p(i,j,1)-pold(i,j,1)))
  799. end do i2loop
  800. end do j2loop
  801. else
  802. if (nred(region)/=0) then
  803. jloop:do j=j1,j2
  804. if(imredj(j,region).ne.im(region)) then
  805. ! this requires gathering of sp_dat and sp1_dat across mpi tasks - just skip it (FIXME?)
  806. cycle jloop
  807. else
  808. pdiffmax = max( pdiffmax, maxval(abs(p(i1:i2,j,1)-pold(i1:i2,j,1))) )
  809. endif
  810. enddo jloop
  811. else
  812. pdiffmax = maxval(abs(p(i1:i2,j1:j2,1)-pold(i1:i2,j1:j2,1)))
  813. endif
  814. endif
  815. end if
  816. end subroutine calc_pdiff
  817. !EOC
  818. !--------------------------------------------------------------------------
  819. ! TM5 !
  820. !--------------------------------------------------------------------------
  821. !BOP
  822. !
  823. ! !IROUTINE: UNI2RED
  824. !
  825. ! !DESCRIPTION: transforms data (air mass & tracers) from uniform grid to reduced grid
  826. !\\
  827. !\\
  828. ! !INTERFACE:
  829. !
  830. subroutine uni2red( region, i1, i2, j1, j2, status)
  831. !
  832. ! !USES:
  833. !
  834. use dims, only : im,jm,lm
  835. use meteodata , only : m_dat
  836. use tracer_data, only : mass_dat
  837. use chem_param, only : ntracet
  838. use partools, only : isRowRoot, npe_lon
  839. use tm5_distgrid, only : dgrid, gather_j_band
  840. !
  841. ! !INPUT PARAMETERS:
  842. !
  843. integer, intent(in) :: region,i1,i2,j1,j2
  844. !
  845. ! !OUTPUT PARAMETERS:
  846. !
  847. integer, intent(out) :: status
  848. !
  849. ! !REVISION HISTORY:
  850. ! written by mike botchev, march-june 1999
  851. ! modified by Maarten Krol, dec 2002
  852. ! 20 Dec 2012 - Ph Le Sager - TM5-MP
  853. !
  854. ! !REMARKS:
  855. !
  856. !EOP
  857. !------------------------------------------------------------------------
  858. !BOC
  859. character(len=*), parameter :: rname = mname//'_MOD_uni2red'
  860. real,dimension(:,:,:,:),pointer :: rm, rm_alt
  861. #ifdef slopes
  862. real,dimension(:,:,:,:),pointer :: rxm,rym,rzm
  863. #endif
  864. real,dimension(:,:,:), pointer :: m, m_alt
  865. integer :: i,ie,is,j,l,lrg,redfact,n, imr, lmr, halo
  866. real :: summ,sumrm
  867. ! -------------- start
  868. m => m_dat(region)%data
  869. rm => mass_dat(region)%rm
  870. #ifdef slopes
  871. rxm => mass_dat(region)%rxm
  872. rym => mass_dat(region)%rym
  873. rzm => mass_dat(region)%rzm
  874. #endif
  875. imr=im(region)
  876. lmr=lm(region)
  877. ! Two scenarios
  878. if (npe_lon /= 1) then
  879. !
  880. ! decomposition along longitudes => work on row_root
  881. !
  882. if (nred(region)/=0) then ! some reduce grid on this tile
  883. halo=m_dat(region)%halo
  884. ! local array to gather (remove i-halo)
  885. allocate( m_alt( i1:i2, j1:j2, lmr))
  886. allocate(rm_alt( i1:i2, j1:j2, lmr, ntracet))
  887. m_alt = m(i1:i2,j1:j2,:)
  888. CALL GATHER_J_BAND(dgrid(region), m_alt, m_alt2, status, jref=j1, rowcom=.true.)
  889. IF_NOTOK_RETURN(status=1)
  890. if (isRowRoot) then
  891. m_alt1( 1:imr,:,:) = m_alt2
  892. m_alt1( 0,:,:) = m_alt1( imr,:,:)
  893. m_alt1( -1,:,:) = m_alt1(imr-1,:,:)
  894. !PLS m_alt1( imr+1,:,:) = m_alt1(1,:,:)
  895. !PLS m_alt1( imr+2,:,:) = m_alt1(2,:,:)
  896. endif
  897. rm_alt = rm(i1:i2,j1:j2,:,:)
  898. CALL GATHER_J_BAND(dgrid(region), rm_alt, rm_alt2, status, jref=j1, rowcom=.true.)
  899. IF_NOTOK_RETURN(status=1)
  900. if (isRowRoot) then
  901. rm_alt1( 1:imr,:,:,:) = rm_alt2
  902. rm_alt1( 0,:,:,:) = rm_alt1( imr,:,:,:)
  903. rm_alt1( -1,:,:,:) = rm_alt1(imr-1,:,:,:)
  904. !PLS rm_alt1( imr+1,:,:,:) = rm_alt1( 1,:,:,:)
  905. !PLS rm_alt1( imr+2,:,:,:) = rm_alt1( 2,:,:,:)
  906. endif
  907. #ifdef slopes
  908. rm_alt = rxm(i1:i2,j1:j2,:,:)
  909. CALL GATHER_J_BAND(dgrid(region), rm_alt, rm_alt2, status, jref=j1, rowcom=.true.)
  910. IF_NOTOK_RETURN(status=1)
  911. if (isRowRoot) then
  912. rxm_alt1( 1:imr,:,:,:) = rm_alt2
  913. rxm_alt1( 0,:,:,:) = rm_alt1( imr,:,:,:)
  914. rxm_alt1( -1,:,:,:) = rm_alt1(imr-1,:,:,:)
  915. !PLS rxm_alt1( imr+1,:,:,:) = rm_alt1( 1,:,:,:)
  916. !PLS rxm_alt1( imr+2,:,:,:) = rm_alt1( 2,:,:,:)
  917. endif
  918. rm_alt = rym(i1:i2,j1:j2,:,:)
  919. CALL GATHER_J_BAND(dgrid(region), rm_alt, rm_alt2, status, jref=j1, rowcom=.true.)
  920. IF_NOTOK_RETURN(status=1)
  921. if (isRowRoot) then
  922. rym_alt1( 1:imr,:,:,:) = rm_alt2
  923. rym_alt1( 0,:,:,:) = rm_alt1( imr,:,:,:)
  924. rym_alt1( -1,:,:,:) = rm_alt1(imr-1,:,:,:)
  925. !PLS rym_alt1( imr+1,:,:,:) = rm_alt1( 1,:,:,:)
  926. !PLS rym_alt1( imr+2,:,:,:) = rm_alt1( 2,:,:,:)
  927. endif
  928. rm_alt = rzm(i1:i2,j1:j2,:,:)
  929. CALL GATHER_J_BAND(dgrid(region), rm_alt, rm_alt2, status, jref=j1, rowcom=.true.)
  930. IF_NOTOK_RETURN(status=1)
  931. if (isRowRoot) then
  932. rzm_alt1( 1:imr,:,:,:) = rm_alt2
  933. rzm_alt1( 0,:,:,:) = rm_alt1( imr,:,:,:)
  934. rzm_alt1( -1,:,:,:) = rm_alt1(imr-1,:,:,:)
  935. !PLS rzm_alt1( imr+1,:,:,:) = rm_alt1( 1,:,:,:)
  936. !PLS rzm_alt1( imr+2,:,:,:) = rm_alt1( 2,:,:,:)
  937. endif
  938. #endif
  939. if (isRowRoot) then
  940. do lrg=1,nred(region)
  941. j = jred(lrg,region)
  942. redfact=clustsize(j,region)
  943. do l=1,lmr
  944. ! air mass
  945. do i = 1,imredj(j,region)
  946. ! the is:ie array section will be reduced to i
  947. is = (i-1)*redfact + 1
  948. ie = i*redfact
  949. summ = sum(m_alt1(is:ie,j,l))
  950. m_alt1(i,j,l) = summ
  951. end do
  952. ! tracers
  953. do n=1, ntracet
  954. do i = 1,imredj(j,region)
  955. is = (i-1)*redfact + 1
  956. ie = i*redfact
  957. sumrm = sum(rm_alt1(is:ie,j,l,n))
  958. rm_alt1(i,j,l,n) = sumrm
  959. #ifdef slopes
  960. sumrm = sum(rxm_alt1(is:ie,j,l,n))
  961. rxm_alt1(i,j,l,n) = sumrm
  962. sumrm = sum(rym_alt1(is:ie,j,l,n))
  963. rym_alt1(i,j,l,n) = sumrm
  964. sumrm = sum(rzm_alt1(is:ie,j,l,n))
  965. rzm_alt1(i,j,l,n) = sumrm
  966. #endif
  967. end do
  968. ! JFM: set remaining masses to zero
  969. ! for consistency with adjoint
  970. do i = imredj(j,region)+1, im(region)
  971. rm_alt1(i,j,l,n) = 0.
  972. #ifdef slopes
  973. rxm_alt1(i,j,l,n) = 0.
  974. rym_alt1(i,j,l,n) = 0.
  975. rzm_alt1(i,j,l,n) = 0.
  976. #endif
  977. end do
  978. end do
  979. end do !l
  980. enddo
  981. endif
  982. deallocate(m_alt, rm_alt)
  983. endif
  984. else
  985. !
  986. ! Reduced grid without longitudinal decomposition
  987. !
  988. do lrg=1,nred(region)
  989. j = jred(lrg,region)
  990. redfact=clustsize(j,region)
  991. do l=1,lmr
  992. ! air mass
  993. do i = 1,imredj(j,region)
  994. ! the is:ie array section will be reduced to i
  995. is = (i-1)*redfact + 1
  996. ie = i*redfact
  997. summ = sum(m(is:ie,j,l))
  998. m(i,j,l) = summ
  999. end do
  1000. !cmkm_uni(is:ie,j,l) = m_uni(is:ie,j,l)/summ
  1001. ! use as distribution function
  1002. ! when transferring back from reduced--->uniform grid...
  1003. ! these summations mean that mixing ratio and the
  1004. ! the slopes are averaged out within the is:ie section
  1005. ! with m(is:ie,...) taken as the weights
  1006. ! tracers
  1007. do n=1, ntracet
  1008. do i = 1,imredj(j,region)
  1009. is = (i-1)*redfact + 1
  1010. ie = i*redfact
  1011. sumrm = sum(rm(is:ie,j,l,n))
  1012. rm(i,j,l,n) = sumrm
  1013. #ifdef slopes
  1014. sumrm = sum(rxm(is:ie,j,l,n))
  1015. rxm(i,j,l,n) = sumrm
  1016. sumrm = sum(rym(is:ie,j,l,n))
  1017. rym(i,j,l,n) = sumrm
  1018. sumrm = sum(rzm(is:ie,j,l,n))
  1019. rzm(i,j,l,n) = sumrm
  1020. #endif
  1021. end do
  1022. ! JFM: set remaining masses to zero
  1023. ! for consistency with adjoint
  1024. do i = imredj(j,region)+1, im(region)
  1025. rm(i,j,l,n) = 0.
  1026. #ifdef slopes
  1027. rxm(i,j,l,n) = 0.
  1028. rym(i,j,l,n) = 0.
  1029. rzm(i,j,l,n) = 0.
  1030. #endif
  1031. end do
  1032. end do
  1033. !put periodic boundary...
  1034. end do !l
  1035. end do !redgrid...
  1036. endif
  1037. nullify(m)
  1038. nullify(rm)
  1039. #ifdef slopes
  1040. nullify(rxm)
  1041. nullify(rym)
  1042. nullify(rzm)
  1043. #endif
  1044. status=0
  1045. end subroutine uni2red
  1046. !EOC
  1047. #ifdef secmom
  1048. !--------------------------------------------------------------------------
  1049. ! TM5 !
  1050. !--------------------------------------------------------------------------
  1051. !BOP
  1052. !
  1053. ! !IROUTINE: uni2red_2nd
  1054. !
  1055. ! !DESCRIPTION: Transforms data from uniform grid to reduced grid. @nd
  1056. ! moments version.
  1057. !\\
  1058. !\\
  1059. ! !INTERFACE:
  1060. !
  1061. subroutine uni2red_2nd(region)
  1062. !
  1063. ! !USES:
  1064. !
  1065. use dims
  1066. use meteodata, only : m_dat
  1067. use global_data, only : mass_dat
  1068. use chem_param, only : ntracet
  1069. !
  1070. ! !INPUT PARAMETERS:
  1071. !
  1072. integer,intent(in) :: region
  1073. !
  1074. ! !REVISION HISTORY:
  1075. ! written by mike botchev, march-june 1999
  1076. ! modified by Maarten Krol, dec 2002
  1077. ! 20 Dec 2012 - Ph Le Sager -
  1078. !
  1079. ! !REMARKS:
  1080. !
  1081. !EOP
  1082. !------------------------------------------------------------------------
  1083. !BOC
  1084. real, dimension(:,:,:,:), pointer :: rm, rxm,rym,rzm, rxxm, rxym, rxzm, ryym, ryzm, rzzm
  1085. real, dimension(:,:,:), pointer :: m
  1086. integer i,ie,is,j,l,lrg,redfact,n,lmr
  1087. real summ,sumrm
  1088. ! start
  1089. m => m_dat(region)%data
  1090. rm => mass_dat(region)%rm
  1091. rxm => mass_dat(region)%rxm
  1092. rym => mass_dat(region)%rym
  1093. rzm => mass_dat(region)%rzm
  1094. rxxm => mass_dat(region)%rxxm
  1095. rxym => mass_dat(region)%rxym
  1096. rxzm => mass_dat(region)%rxzm
  1097. ryym => mass_dat(region)%ryym
  1098. ryzm => mass_dat(region)%ryzm
  1099. rzzm => mass_dat(region)%rzzm
  1100. lmr=lm(region)
  1101. do lrg=1,nred(region)
  1102. j = jred(lrg,region)
  1103. redfact=clustsize(j,region)
  1104. do l=1,lmr
  1105. do i = 1,imredj(j,region)
  1106. ! the is:ie array section will be reduced to i
  1107. is = (i-1)*redfact + 1
  1108. ie = i*redfact
  1109. summ = sum(m(is:ie,j,l))
  1110. m(i,j,l) = summ
  1111. !cmkm_uni(is:ie,j,l) = m_uni(is:ie,j,l)/summ
  1112. ! use as distribution function
  1113. ! when transferring back from reduced--->uniform grid...
  1114. ! these summations mean that mixing ratio and the
  1115. ! the slopes are averaged out within the is:ie section
  1116. ! with m(is:ie,...) taken as the weights
  1117. do n=1,ntracet
  1118. !#endif
  1119. sumrm = sum(rm(is:ie,j,l,n))
  1120. rm(i,j,l,n) = sumrm
  1121. sumrm = sum(rxm(is:ie,j,l,n))
  1122. rxm(i,j,l,n) = sumrm
  1123. sumrm = sum(rym(is:ie,j,l,n))
  1124. rym(i,j,l,n) = sumrm
  1125. sumrm = sum(rzm(is:ie,j,l,n))
  1126. rzm(i,j,l,n) = sumrm
  1127. sumrm = sum(rxxm(is:ie,j,l,n))
  1128. rxxm(i,j,l,n) = sumrm
  1129. sumrm = sum(rxym(is:ie,j,l,n))
  1130. rxym(i,j,l,n) = sumrm
  1131. sumrm = sum(rxzm(is:ie,j,l,n))
  1132. rxzm(i,j,l,n) = sumrm
  1133. sumrm = sum(ryym(is:ie,j,l,n))
  1134. ryym(i,j,l,n) = sumrm
  1135. sumrm = sum(ryzm(is:ie,j,l,n))
  1136. ryzm(i,j,l,n) = sumrm
  1137. sumrm = sum(rzzm(is:ie,j,l,n))
  1138. rzzm(i,j,l,n) = sumrm
  1139. end do !n
  1140. end do !i
  1141. !put periodic boundary...
  1142. end do !l
  1143. end do !redgrid...
  1144. nullify(m)
  1145. nullify(rm)
  1146. nullify(rxm)
  1147. nullify(rym)
  1148. nullify(rzm)
  1149. nullify(rxxm)
  1150. nullify(rxym)
  1151. nullify(rxzm)
  1152. nullify(ryym)
  1153. nullify(ryzm)
  1154. nullify(rzzm)
  1155. end subroutine uni2red_2nd
  1156. !EOC
  1157. #endif
  1158. !--------------------------------------------------------------------------
  1159. ! TM5 !
  1160. !--------------------------------------------------------------------------
  1161. !BOP
  1162. !
  1163. ! !IROUTINE: RED2UNI
  1164. !
  1165. ! !DESCRIPTION: transforms data from reduced grid back to uniform grid
  1166. !\\
  1167. !\\
  1168. ! !INTERFACE:
  1169. !
  1170. subroutine red2uni(region, i1, i2, j1, j2, halo, m_uni, status)
  1171. !
  1172. ! !USES:
  1173. !
  1174. use dims, only : im, lm
  1175. use tracer_data, only : mass_dat
  1176. use meteodata, only : m_dat
  1177. use chem_param, only : ntracet
  1178. use partools, only : isRowRoot, npe_lon
  1179. use tm5_distgrid, only : dgrid, scatter_j_band, gather_j_band, update_halo_jband
  1180. !
  1181. ! !INPUT PARAMETERS:
  1182. !
  1183. integer, intent(in) :: region, i1, i2, j1, j2, halo
  1184. real, intent(in) :: m_uni(i1-halo:,j1-halo:,1:)
  1185. !
  1186. ! !OUTPUT PARAMETERS:
  1187. !
  1188. integer, intent(out) :: status
  1189. !
  1190. ! !REVISION HISTORY:
  1191. ! written by mike botchev, march-june 1999
  1192. ! 20 Dec 2012 - Ph Le Sager - TM5-MP version
  1193. !
  1194. ! !REMARKS:
  1195. !
  1196. !EOP
  1197. !------------------------------------------------------------------------
  1198. !BOC
  1199. character(len=*), parameter :: rname = mname//'_MOD_red2uni'
  1200. ! local
  1201. real,dimension(:,:,:,:),pointer :: rm, rm_
  1202. #ifdef slopes
  1203. real,dimension(:,:,:,:),pointer :: rxm,rym,rzm
  1204. #endif
  1205. real,dimension(:,:,:) ,pointer :: m, m_, m_alt
  1206. integer :: i, ie, is, j, l, lrg, n, redfact, imr, lmr, nt, halo_r
  1207. real :: hi, mass, mass_coord, rmm, slope, m_old
  1208. character(len=5) :: distr_mode
  1209. ! start
  1210. nt=ntracet
  1211. imr=im(region)
  1212. lmr=lm(region)
  1213. m => m_dat(region)%data
  1214. rm => mass_dat(region)%rm
  1215. #ifdef slopes
  1216. rxm => mass_dat(region)%rxm
  1217. rym => mass_dat(region)%rym
  1218. rzm => mass_dat(region)%rzm
  1219. #endif
  1220. ! Two scenarios
  1221. if (npe_lon /= 1) then
  1222. !
  1223. ! decomposition along longitudes => work on row_root
  1224. !
  1225. if (nred(region)/=0) then
  1226. ! gather m_uni on row_root, where we redistribute the masses
  1227. allocate(m_(i1:i2,j1:j2,1:lmr))
  1228. m_ = m_uni(i1:i2,j1:j2,1:lmr)
  1229. CALL GATHER_J_BAND(dgrid(region), m_, m_alt2, status, jref=j1, rowcom=.true.)
  1230. IF_NOTOK_RETURN(status=1)
  1231. if (isRowRoot) then
  1232. do lrg=1,nred(region)
  1233. j = jred(lrg,region)
  1234. redfact=clustsize(j,region)
  1235. !m(1:imr,j,:)= m_alt2(:,j,:)
  1236. do l=1,lmr
  1237. do i=imredj(j,region),1,-1
  1238. is = (i-1)*redfact + 1
  1239. ie = i*redfact
  1240. mass=m_alt1(i,j,l)
  1241. do n=1,nt
  1242. rmm = rm_alt1(i,j,l,n)
  1243. rm_alt1(is:ie,j,l,n)= m_alt2(is:ie,j,l)/mass* rmm
  1244. #ifdef slopes
  1245. rmm = rxm_alt1(i,j,l,n)
  1246. rxm_alt1(is:ie,j,l,n)= m_alt2(is:ie,j,l)/mass * rmm
  1247. ! rym and rzm are always distributed uniformly:
  1248. rmm = rym_alt1(i,j,l,n)
  1249. rym_alt1(is:ie,j,l,n)= m_alt2(is:ie,j,l)/mass * rmm
  1250. rmm = rzm_alt1(i,j,l,n)
  1251. rzm_alt1(is:ie,j,l,n)= m_alt2(is:ie,j,l)/mass * rmm
  1252. #endif
  1253. end do
  1254. end do
  1255. enddo
  1256. enddo
  1257. endif
  1258. ! scatter results
  1259. if (nred(region)< (j2-j1+1)) then
  1260. if (isRowRoot) m_alt2 = m_alt1(1:imr,:,:)
  1261. CALL SCATTER_J_BAND(dgrid(region), m_, m_alt2, status, jref=j1, rowcom=.true.)
  1262. IF_NOTOK_RETURN(status=1)
  1263. m(i1:i2,j1:j2,:) = m_
  1264. endif
  1265. allocate(rm_( i1:i2, j1:j2, lmr, ntracet))
  1266. if (isRowRoot) rm_alt2 = rm_alt1(1:imr,:,:,:)
  1267. CALL SCATTER_J_BAND(dgrid(region), rm_, rm_alt2, status, jref=j1, rowcom=.true.)
  1268. IF_NOTOK_RETURN(status=1)
  1269. rm(i1:i2,j1:j2,:,:) = rm_
  1270. #ifdef slopes
  1271. if (isRowRoot) rm_alt2 = rxm_alt1(1:imr,:,:,:)
  1272. CALL SCATTER_J_BAND(dgrid(region), rm_, rm_alt2, status, jref=j1, rowcom=.true.)
  1273. IF_NOTOK_RETURN(status=1)
  1274. rxm(i1:i2,j1:j2,:,:) = rm_
  1275. if (isRowRoot) rm_alt2 = rym_alt1(1:imr,:,:,:)
  1276. CALL SCATTER_J_BAND(dgrid(region), rm_, rm_alt2, status, jref=j1, rowcom=.true.)
  1277. IF_NOTOK_RETURN(status=1)
  1278. rym(i1:i2,j1:j2,:,:) = rm_
  1279. if (isRowRoot) rm_alt2 = rzm_alt1(1:imr,:,:,:)
  1280. CALL SCATTER_J_BAND(dgrid(region), rm_, rm_alt2, status, jref=j1, rowcom=.true.)
  1281. IF_NOTOK_RETURN(status=1)
  1282. rzm(i1:i2,j1:j2,:,:) = rm_
  1283. #endif
  1284. ! (2) bands with reduced grid, just use m_uni
  1285. do lrg=1,nred(region)
  1286. j = jred(lrg,region)
  1287. m(:,j,:)= m_uni(:,j,:)
  1288. end do
  1289. ! update halo
  1290. halo_r = mass_dat(region)%halo
  1291. call UPDATE_HALO_JBAND(dgrid(region), m, m_dat(region)%halo, status )
  1292. call UPDATE_HALO_JBAND(dgrid(region), rm(:,:,:,1:nt), halo_r, status )
  1293. #ifdef slopes
  1294. call UPDATE_HALO_JBAND(dgrid(region), rxm, halo_r, status )
  1295. call UPDATE_HALO_JBAND(dgrid(region), rym, halo_r, status )
  1296. call UPDATE_HALO_JBAND(dgrid(region), rzm, halo_r, status )
  1297. #endif
  1298. deallocate(m_,rm_)
  1299. endif
  1300. else
  1301. !
  1302. ! Reduced grid without longitudinal decomposition
  1303. !
  1304. do lrg=1,nred(region)
  1305. j = jred(lrg,region)
  1306. redfact=clustsize(j,region)
  1307. do l=1,lmr
  1308. do i = imredj(j,region),1,-1
  1309. ! the i cell will be distributed within the is:ie array section
  1310. is = (i-1)*redfact + 1
  1311. ie = i*redfact
  1312. !m_uni is the mass-distribution in the non-reduced grid/divided by
  1313. !the reduced_grid mass. This is used as distribution function!....
  1314. mass=m(i,j,l)
  1315. m(is:ie,j,l)= m_uni(is:ie,j,l)
  1316. do n=1,nt
  1317. rmm = rm(i,j,l,n)
  1318. rm(is:ie,j,l,n)= m_uni(is:ie,j,l)/mass* rmm
  1319. #ifdef slopes
  1320. rmm = rxm(i,j,l,n)
  1321. rxm(is:ie,j,l,n)= m_uni(is:ie,j,l)/mass * rmm
  1322. ! rym and rzm are always distributed uniformly:
  1323. rmm = rym(i,j,l,n)
  1324. rym(is:ie,j,l,n)= m_uni(is:ie,j,l)/mass * rmm
  1325. rmm = rzm(i,j,l,n)
  1326. rzm(is:ie,j,l,n)= m_uni(is:ie,j,l)/mass * rmm
  1327. #endif
  1328. end do
  1329. end do
  1330. ! update cell(0,...) according to the periodic bc's:
  1331. rm(0,j,l,1:nt) = rm(im(region),j,l,1:nt)
  1332. #ifdef slopes
  1333. rxm(0,j,l,:) = rxm(im(region),j,l,:)
  1334. rym(0,j,l,:) = rym(im(region),j,l,:)
  1335. rzm(0,j,l,:) = rzm(im(region),j,l,:)
  1336. #endif
  1337. m(0,j,l) = m(im(region),j,l)
  1338. end do
  1339. end do
  1340. endif
  1341. nullify(m)
  1342. nullify(rm)
  1343. #ifdef slopes
  1344. nullify(rxm)
  1345. nullify(rym)
  1346. nullify(rzm)
  1347. #endif
  1348. end subroutine red2uni
  1349. !EOC
  1350. !--------------------------------------------------------------------------
  1351. ! TM5 !
  1352. !--------------------------------------------------------------------------
  1353. !BOP
  1354. !
  1355. ! !IROUTINE: RED2UNI_EM
  1356. !
  1357. ! !DESCRIPTION: transforms data from reduced grid back to uniform grid,
  1358. ! using EQUAL MASSES instead of reduced mass array (m_uni).
  1359. !\\
  1360. !\\
  1361. ! !INTERFACE:
  1362. !
  1363. subroutine red2uni_em(region)
  1364. !
  1365. !USES:
  1366. !
  1367. use dims
  1368. use meteodata , only : m_dat
  1369. use tracer_data, only : mass_dat
  1370. use chem_param, only : ntracet
  1371. !
  1372. ! !INPUT PARAMETERS:
  1373. !
  1374. integer,intent(in) :: region
  1375. !
  1376. ! !REVISION HISTORY:
  1377. ! written by mike botchev, march-june 1999
  1378. ! 20 Dec 2012 - Ph Le Sager - TM5-MP version
  1379. !
  1380. ! !REMARKS:
  1381. !
  1382. !EOP
  1383. !------------------------------------------------------------------------
  1384. !BOC
  1385. real,dimension(:,:,:,:),pointer :: rm
  1386. #ifdef slopes
  1387. real,dimension(:,:,:,:),pointer :: rxm,rym,rzm
  1388. #endif
  1389. real,dimension(:,:,:) ,pointer :: m
  1390. integer i,ie,ii,is,j,l,lrg,n,redfact,lmr
  1391. real hi,mass,mass_coord,rmm,slope,m_old
  1392. character(len=5) distr_mode
  1393. !------------ start
  1394. lmr=lm(region)
  1395. m => m_dat(region)%data
  1396. rm => mass_dat(region)%rm
  1397. #ifdef slopes
  1398. rxm => mass_dat(region)%rxm
  1399. rym => mass_dat(region)%rym
  1400. rzm => mass_dat(region)%rzm
  1401. #endif
  1402. distr_mode = 'unfrm' ! 'slope' or 'unfrm'
  1403. do lrg=1,nred(region)
  1404. j = jred(lrg,region)
  1405. redfact=clustsize(j,region)
  1406. do l=1,lmr
  1407. do i = imredj(j,region),1,-1
  1408. ! the i cell will be distributed within the is:ie array section
  1409. is = (i-1)*redfact + 1
  1410. ie = i*redfact
  1411. !m_uni is the mass-distribution in the non-reduced grid/divided by
  1412. !the reduced_grid mass. This is used as distribution function!....
  1413. mass=m(i,j,l); m(is:ie,j,l)= mass/(ie-is+1)
  1414. if (distr_mode=='unfrm') then
  1415. ! mixing ratio and x-slope will be UNiFoRMly distributed
  1416. ! within is:ie
  1417. do n=1,ntracet
  1418. rmm = rm(i,j,l,n)
  1419. rm(is:ie,j,l,n)= m(is:ie,j,l)/mass* rmm
  1420. #ifdef slopes
  1421. rmm = rxm(i,j,l,n)
  1422. rxm(is:ie,j,l,n)= m(is:ie,j,l)/mass * rmm
  1423. ! rym and rzm are always distributed uniformly:
  1424. rmm = rym(i,j,l,n)
  1425. rym(is:ie,j,l,n)= m(is:ie,j,l)/mass * rmm
  1426. rmm = rzm(i,j,l,n)
  1427. rzm(is:ie,j,l,n)= m(is:ie,j,l)/mass * rmm
  1428. #endif
  1429. end do
  1430. end if
  1431. !cmkelseif(distr_mode=='slope') then
  1432. end do
  1433. ! update cell(0,...) according to the periodic bc's:
  1434. rm(0,j,l,1:ntracet) = rm(im(region),j,l,1:ntracet)
  1435. #ifdef slopes
  1436. rxm(0,j,l,:) = rxm(im(region),j,l,:)
  1437. rym(0,j,l,:) = rym(im(region),j,l,:)
  1438. rzm(0,j,l,:) = rzm(im(region),j,l,:)
  1439. #endif
  1440. m(0,j,l) = m(im(region),j,l)
  1441. end do
  1442. end do
  1443. nullify(m)
  1444. nullify(rm)
  1445. #ifdef slopes
  1446. nullify(rxm)
  1447. nullify(rym)
  1448. nullify(rzm)
  1449. #endif
  1450. end subroutine red2uni_em
  1451. !EOC
  1452. #ifdef secmom
  1453. !--------------------------------------------------------------------------
  1454. ! TM5 !
  1455. !--------------------------------------------------------------------------
  1456. !BOP
  1457. !
  1458. ! !IROUTINE: red2uni_em_2nd
  1459. !
  1460. ! !DESCRIPTION: transforms data from reduced grid back to uniform grid
  1461. !\\
  1462. !\\
  1463. ! !INTERFACE:
  1464. !
  1465. subroutine red2uni_em_2nd(region)
  1466. !
  1467. ! !USES:
  1468. !
  1469. use dims
  1470. use meteodata, only : m_dat
  1471. use global_data, only : mass_dat
  1472. use chem_param, only : ntracet
  1473. !
  1474. ! !INPUT PARAMETERS:
  1475. !
  1476. integer,intent(in) :: region
  1477. !
  1478. ! !REVISION HISTORY:
  1479. ! written by mike botchev, march-june 1999
  1480. ! 20 Dec 2012 - Ph Le Sager - TM5-MP version
  1481. !
  1482. ! !REMARKS:
  1483. !
  1484. !EOP
  1485. !------------------------------------------------------------------------
  1486. !BOC
  1487. real,dimension(:,:,:,:),pointer :: rm,rxm,rym,rzm, rxxm, rxym, rxzm, ryym, ryzm, rzzm
  1488. real,dimension(:,:,:) ,pointer :: m
  1489. integer i,ie,ii,is,j,l,lrg,n,redfact,lmr
  1490. real hi,mass,mass_coord,rmm,slope,m_old
  1491. character(len=5) distr_mode
  1492. ! ----- start
  1493. lmr=lm(region)
  1494. m => m_dat(region)%data
  1495. rm => mass_dat(region)%rm
  1496. rxm => mass_dat(region)%rxm
  1497. rym => mass_dat(region)%rym
  1498. rzm => mass_dat(region)%rzm
  1499. rxxm => mass_dat(region)%rxxm
  1500. rxym => mass_dat(region)%rxym
  1501. rxzm => mass_dat(region)%rxzm
  1502. ryym => mass_dat(region)%ryym
  1503. ryzm => mass_dat(region)%ryzm
  1504. rzzm => mass_dat(region)%rzzm
  1505. distr_mode = 'unfrm' ! 'slope' or 'unfrm'
  1506. do lrg=1,nred(region)
  1507. j = jred(lrg,region)
  1508. redfact=clustsize(j,region)
  1509. do l=1,lmr
  1510. do i = imredj(j,region),1,-1
  1511. ! the i cell will be distributed within the is:ie array section
  1512. is = (i-1)*redfact + 1
  1513. ie = i*redfact
  1514. !m_uni is the mass-distribution in the non-reduced grid/divided by
  1515. !the reduced_grid mass. This is used as distribution function!....
  1516. mass=m(i,j,l); m(is:ie,j,l)= mass/(ie-is+1)
  1517. if (distr_mode=='unfrm') then
  1518. ! mixing ratio and x-slope will be UNiFoRMly distributed
  1519. ! within is:ie
  1520. !#ifdef MPI
  1521. ! do n=1,ntracetloc
  1522. !#else
  1523. do n=1,ntracet
  1524. !#endif
  1525. rmm = rm(i,j,l,n)
  1526. rm(is:ie,j,l,n)= m(is:ie,j,l)/mass* rmm
  1527. rmm = rxm(i,j,l,n)
  1528. rxm(is:ie,j,l,n)= m(is:ie,j,l)/mass * rmm
  1529. ! rym and rzm are always distributed uniformly:
  1530. rmm = rym(i,j,l,n)
  1531. rym(is:ie,j,l,n)= m(is:ie,j,l)/mass * rmm
  1532. rmm = rzm(i,j,l,n)
  1533. rzm(is:ie,j,l,n)= m(is:ie,j,l)/mass * rmm
  1534. rmm = rxxm(i,j,l,n)
  1535. rxxm(is:ie,j,l,n)= m(is:ie,j,l)/mass * rmm
  1536. rmm = rxym(i,j,l,n)
  1537. rxym(is:ie,j,l,n)= m(is:ie,j,l)/mass * rmm
  1538. rmm = rxzm(i,j,l,n)
  1539. rxzm(is:ie,j,l,n)= m(is:ie,j,l)/mass * rmm
  1540. rmm = ryym(i,j,l,n)
  1541. ryym(is:ie,j,l,n)= m(is:ie,j,l)/mass * rmm
  1542. rmm = ryzm(i,j,l,n)
  1543. ryzm(is:ie,j,l,n)= m(is:ie,j,l)/mass * rmm
  1544. rmm = rzzm(i,j,l,n)
  1545. rzzm(is:ie,j,l,n)= m(is:ie,j,l)/mass * rmm
  1546. end do
  1547. end if
  1548. !cmkelseif(distr_mode=='slope') then
  1549. end do
  1550. ! update cell(0,...) according to the periodic bc's:
  1551. rm(0,j,l,1:ntracet) = rm(im(region),j,l,1:ntracet)
  1552. rxm(0,j,l,:) = rxm(im(region),j,l,:)
  1553. rym(0,j,l,:) = rym(im(region),j,l,:)
  1554. rzm(0,j,l,:) = rzm(im(region),j,l,:)
  1555. m(0,j,l) = m(im(region),j,l)
  1556. end do
  1557. end do
  1558. nullify(m)
  1559. nullify(rm)
  1560. nullify(rxm)
  1561. nullify(rym)
  1562. nullify(rzm)
  1563. nullify(rxxm)
  1564. nullify(rxym)
  1565. nullify(rxzm)
  1566. nullify(ryym)
  1567. nullify(ryzm)
  1568. nullify(rzzm)
  1569. end subroutine red2uni_em_2nd
  1570. !EOC
  1571. #endif
  1572. end module redgridZoom