advect_tools.F90 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  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-MP !
  11. !-----------------------------------------------------------------------------
  12. !BOP
  13. !
  14. ! !MODULE: ADVECT_TOOLS
  15. !
  16. ! !DESCRIPTION:
  17. !\\
  18. !\\
  19. ! !INTERFACE:
  20. !
  21. MODULE ADVECT_TOOLS
  22. !
  23. ! !USES:
  24. !
  25. USE GO, ONLY : gol, goPr, goErr ! General Object messaging
  26. USE TM5_DISTGRID, ONLY : DGRID, Get_DistGrid
  27. IMPLICIT NONE
  28. PRIVATE
  29. !
  30. ! !PUBLIC MEMBER FUNCTIONS:
  31. !
  32. PUBLIC :: ADVECT_M !
  33. PUBLIC :: M2PHLB1 ! convert air mass to pressure
  34. !
  35. ! !REVISION HISTORY:
  36. ! 15 Nov 2011 - P. Le Sager - adapted to TM5-MP
  37. !
  38. ! !REMARKS:
  39. !
  40. !EOP
  41. !------------------------------------------------------------------------
  42. CONTAINS
  43. !--------------------------------------------------------------------------
  44. ! TM5-MP !
  45. !--------------------------------------------------------------------------
  46. !BOP
  47. !
  48. ! !IROUTINE: M2PHLB1
  49. !
  50. ! !DESCRIPTION: Get pressure at box centers (phlb_dat%data) and at the
  51. ! surface (sp_dat%data) from air mass (m_dat%data). Only for
  52. ! region #1!
  53. !\\
  54. !\\
  55. ! !INTERFACE:
  56. !
  57. SUBROUTINE M2PHLB1
  58. !
  59. ! !USES:
  60. !
  61. use binas, only : grav
  62. use dims
  63. use global_data, only : region_dat
  64. use meteodata, only : sp_dat, phlb_dat, m_dat
  65. use partools, only : par_reduce, isRoot
  66. !
  67. ! !REVISION HISTORY:
  68. ! mk december 1998
  69. ! 15 Nov 2011 - P. Le Sager - adapted for TM5-MP
  70. !
  71. ! !REMARKS:
  72. ! (1) Note: first, we calculate the surface pressure in p(im,jm), then
  73. ! using the hybrid coordinate system, calculate phlb(im,jm,lmp1)
  74. ! (2) Different from PressureToMass from meteo.F90, where phlb_dat%data is
  75. ! filled directly from m_dat%data (and not from at & bt), and where
  76. ! spm_dat%data (and not sp_dat%data) is filled.
  77. ! (3) Special routine for region 1.
  78. !
  79. !EOP
  80. !------------------------------------------------------------------------
  81. !BOC
  82. real,dimension(:,:,:), pointer :: m, phlb
  83. real,dimension(:,:,:), pointer :: p
  84. real,dimension(:), pointer :: dxyp
  85. integer :: i, j, l, i1, i2, j1, j2, halo, lmr, region, st
  86. real :: maxdiff, maxval_one, maxdiff_all, maxval_all
  87. real :: mnew
  88. real, allocatable, dimension(:,:) :: pold, phelp
  89. !--------
  90. ! start
  91. !--------
  92. region = 1
  93. CALL GET_DISTGRID( dgrid(1), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  94. halo=2 ! same as p
  95. allocate( pold( i1-halo:i2+halo, j1-halo:j2+halo) )
  96. allocate( phelp( i1-halo:i2+halo, j1-halo:j2+halo) )
  97. dxyp => region_dat(region)%dxyp
  98. p => sp_dat(region)%data
  99. m => m_dat(region)%data
  100. phlb => phlb_dat(region)%data
  101. lmr = lm(region)
  102. pold = p(:,:,1)
  103. phelp = zero
  104. p = zero
  105. do l= 1, lmr
  106. do j= j1, j2
  107. do i= i1, i2
  108. phelp(i,j) = phelp(i,j) + m(i,j,l)*grav/dxyp(j)
  109. end do
  110. end do
  111. end do
  112. ! surface pressure
  113. p(:,:,1) = phelp
  114. ! pressure at half level boundaries:
  115. do l = 1, lmr+1
  116. phlb(:,:,l) = at(l) + bt(l)*p(:,:,1)
  117. end do
  118. !--------
  119. ! check
  120. !--------
  121. if (okdebug) then
  122. maxdiff = 0.0
  123. do l = 1, lmr
  124. do j = j1, j2
  125. do i = i1, i2
  126. mnew=(phlb(i,j,l)-phlb(i,j,l+1))*dxyp(j)/grav
  127. maxdiff = max(maxdiff,abs(mnew-m(i,j,l))/mnew)
  128. end do
  129. end do
  130. end do
  131. maxval_one=maxval(abs( p(i1:i2,j1:j2,1)- pold(i1:i2,j1:j2) ) / pold(i1:i2,j1:j2) )
  132. call Par_Reduce( maxdiff, 'MAX', maxdiff_all, st )
  133. call Par_Reduce( maxval_one, 'MAX', maxval_all, st )
  134. if ( isRoot ) then
  135. write(gol,*) 'm2phlb1: maxdiff (mnew-m)/mnew :',maxdiff_all ; call goPr
  136. write(gol,*) 'm2phlb1: max pressure difference (%) :',maxval_all ; call goPr
  137. endif
  138. end if
  139. !--------
  140. ! clean
  141. !--------
  142. nullify(p)
  143. nullify(m)
  144. nullify(phlb)
  145. nullify(dxyp)
  146. deallocate(phelp,pold)
  147. END SUBROUTINE M2PHLB1
  148. !EOC
  149. !--------------------------------------------------------------------------
  150. ! TM5-MP !
  151. !--------------------------------------------------------------------------
  152. !BOP
  153. !
  154. ! !IROUTINE: ADVECT_M
  155. !
  156. ! !DESCRIPTION:
  157. !\\
  158. !\\
  159. ! !INTERFACE:
  160. !
  161. subroutine advect_m(region, ntimes)
  162. !
  163. ! !USES:
  164. !
  165. use binas, only : grav
  166. use dims
  167. use global_data, only : region_dat, wind_dat
  168. use meteodata, only : m_dat, sp_dat
  169. use partools, only : isRoot
  170. !
  171. ! !INPUT PARAMETERS:
  172. !
  173. integer,intent(in) :: region,ntimes
  174. !
  175. ! !REVISION HISTORY:
  176. ! 15 Nov 2011 - P. Le Sager - modified for mpi lat-lon domain decomposition
  177. !
  178. ! !REMARKS:
  179. !
  180. !EOP
  181. !------------------------------------------------------------------------
  182. !BOC
  183. real, dimension(:,:,:), pointer :: m,am,bm,cm
  184. real, dimension(:,:,:), pointer :: p
  185. real, dimension(:) , pointer :: dxyp
  186. real, dimension(:,:,:), allocatable :: mnew, msave
  187. real, dimension(:,:) , allocatable :: pnew
  188. integer :: n,i,j,l, i1, i2, j1, j2, lmr
  189. real :: ss,so
  190. ! start
  191. if(isRoot) then
  192. write(gol,*) 'advect_m: called for region ', region ; call goPr
  193. write(gol,*) 'advect_m: ntimes ', ntimes ; call goPr
  194. endif
  195. CALL GET_DISTGRID( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  196. lmr = lm(region)
  197. allocate( mnew( i1:i2, j1:j2, lmr))
  198. allocate(msave( i1:i2, j1:j2, lmr))
  199. allocate( pnew( i1:i2, j1:j2 ))
  200. m => m_dat(region)%data
  201. am => wind_dat(region)%am
  202. bm => wind_dat(region)%bm
  203. cm => wind_dat(region)%cm
  204. p => sp_dat(region)%data
  205. dxyp => region_dat(region)%dxyp
  206. msave = m(i1:i2, j1:j2, 1:lmr)
  207. mnew = m(i1:i2, j1:j2, 1:lmr)
  208. do i=1,ntimes
  209. mnew = mnew + revert*am(i1-1:i2-1, i1:i2 , 1:lmr ) & !east !ADJ re-inserted the revert CMK
  210. - revert*am( i1:i2 , i1:i2 , 1:lmr ) & !west
  211. + revert*bm( i1:i2 , i1:i2 , 1:lmr ) & !south
  212. - revert*bm( i1:i2 , i1+1:i2+1, 1:lmr ) & !north
  213. + revert*cm( i1:i2 , i1:i2 , 0:lmr-1) & !lower
  214. - revert*cm( i1:i2 , i1:i2 , 1:lmr ) !upper
  215. end do
  216. pnew = 0.0
  217. do l= 1, lmr
  218. do j=j1, j2
  219. do i=i1, i2
  220. pnew(i,j) = pnew(i,j) + mnew(i,j,l)*grav/dxyp(j)
  221. end do
  222. end do
  223. end do
  224. p(i1:i2, j1:j2, 1 ) = pnew !return new pressure for testing
  225. m(i1:i2, j1:j2, 1:lmr) = mnew
  226. nullify(m)
  227. nullify(am)
  228. nullify(bm)
  229. nullify(cm)
  230. nullify(p)
  231. nullify(dxyp)
  232. deallocate(pnew)
  233. deallocate(mnew)
  234. deallocate(msave)
  235. end subroutine advect_m
  236. !EOC
  237. end module advect_tools