wrk_nemo.F90 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. MODULE wrk_nemo
  2. !!======================================================================
  3. !! *** MODULE wrk_nemo ***
  4. !! NEMO work space: define and allocate work-space arrays used in
  5. !! all components of NEMO
  6. !!======================================================================
  7. !! History : 4.0 ! 2011-01 (A Porter) Original code
  8. !!----------------------------------------------------------------------
  9. !!----------------------------------------------------------------------
  10. !! wrk_alloc : get work space arrays
  11. !! wrk_dealloc : release work space arrays
  12. !!
  13. !! 1d arrays:
  14. !! REAL(wp), POINTER, DIMENSION(:) :: arr1, arr2, ... arr10
  15. !! or
  16. !! INTEGER, POINTER, DIMENSION(:) :: arr1, arr2, ... arr10
  17. !! ...
  18. !! CALL wrk_alloc( nx, arr1, arr2, ... arr10, kistart = kistart )
  19. !! ...
  20. !! CALL wrk_dealloc( nx, arr1, arr2, ... arr10, kistart = kistart)
  21. !! with:
  22. !! - arr*: 1d arrays. real or (not and) integer
  23. !! - nx: size of the 1d arr* arrays
  24. !! - arr2, ..., arr10: optional parameters
  25. !! - kistart: optional parameter to lower bound of the 1st dimension (default = 1)
  26. !!
  27. !! 2d arrays:
  28. !! REAL(wp), POINTER, DIMENSION(:,:) :: arr1, arr2, ... arr10
  29. !! or
  30. !! INTEGER, POINTER, DIMENSION(:,:) :: arr1, arr2, ... arr10
  31. !! ...
  32. !! CALL wrk_alloc( nx, ny, arr1, arr2, ... arr10, kistart = kistart, kjstart = kjstart )
  33. !! ...
  34. !! CALL wrk_dealloc( nx, ny, arr1, arr2, ... arr10, kistart = kistart, kjstart = kjstart )
  35. !! with:
  36. !! - arr* 2d arrays. real or (not and) integer
  37. !! - nx, ny: size of the 2d arr* arrays
  38. !! - arr2, ..., arr10: optional parameters
  39. !! - kistart, kjstart: optional parameters to lower bound of the 1st/2nd dimension (default = 1)
  40. !!
  41. !! 3d arrays:
  42. !! REAL(wp), POINTER, DIMENSION(:,:,:) :: arr1, arr2, ... arr10
  43. !! or
  44. !! INTEGER, POINTER, DIMENSION(:,:,:) :: arr1, arr2, ... arr10
  45. !! ...
  46. !! CALL wrk_alloc( nx, ny, nz, arr1, arr2, ... arr10, kistart = kistart, kjstart = kjstart, kkstart = kkstart )
  47. !! ...
  48. !! CALL wrk_dealloc( nx, ny, nz, arr1, arr2, ... arr10, kistart = kistart, kjstart = kjstart, kkstart = kkstart )
  49. !! with:
  50. !! - arr* 3d arrays. real or (not and) integer
  51. !! - nx, ny, nz: size of the 3d arr* arrays
  52. !! - arr2, ..., arr10: optional parameters
  53. !! - kistart, kjstart, kkstart: optional parameters to lower bound of the 1st/2nd/3rd dimension (default = 1)
  54. !!
  55. !! 4d arrays:
  56. !! REAL(wp), POINTER, DIMENSION(:,:,:,:) :: arr1, arr2, ... arr10
  57. !! or
  58. !! INTEGER, POINTER, DIMENSION(:,:,:,:) :: arr1, arr2, ... arr10
  59. !! ...
  60. !! CALL wrk_alloc( nx, ny, nz, nl, arr1, arr2, ... arr10, &
  61. !! & kistart = kistart, kjstart = kjstart, kkstart = kkstart, klstart = klstart )
  62. !! ...
  63. !! CALL wrk_dealloc( nx, ny, nz, nl, arr1, arr2, ... arr10, &
  64. !! & kistart = kistart, kjstart = kjstart, kkstart = kkstart, klstart = klstart )
  65. !! with:
  66. !! - arr* 3d arrays. real or (not and) integer
  67. !! - nx, ny, nz, nl: size of the 4d arr* arrays
  68. !! - arr2, ..., arr10: optional parameters
  69. !! - kistart, kjstart, kkstart, klstart: optional parameters to lower bound of the 1st/2nd/3rd/4th dimension (default = 1)
  70. !!
  71. !!----------------------------------------------------------------------
  72. USE par_oce ! ocean parameters
  73. IMPLICIT NONE
  74. PRIVATE
  75. PUBLIC wrk_alloc, wrk_dealloc, wrk_list
  76. INTERFACE wrk_alloc
  77. MODULE PROCEDURE wrk_alloc_1dr, wrk_alloc_2dr, wrk_alloc_3dr, wrk_alloc_4dr, &
  78. & wrk_alloc_1di, wrk_alloc_2di, wrk_alloc_3di, wrk_alloc_4di
  79. END INTERFACE
  80. INTERFACE wrk_dealloc
  81. MODULE PROCEDURE wrk_dealloc_1dr, wrk_dealloc_2dr, wrk_dealloc_3dr, wrk_dealloc_4dr, &
  82. & wrk_dealloc_1di, wrk_dealloc_2di, wrk_dealloc_3di, wrk_dealloc_4di
  83. END INTERFACE
  84. INTEGER, PARAMETER :: jparray = 1000
  85. INTEGER, PARAMETER :: jpmaxdim = 4
  86. INTEGER, PARAMETER :: jpnotdefined = 0
  87. INTEGER, PARAMETER :: jpinteger = 1
  88. INTEGER, PARAMETER :: jpreal = 2
  89. TYPE leaf
  90. LOGICAL :: in_use
  91. INTEGER :: indic
  92. INTEGER , DIMENSION(:) , POINTER :: iwrk1d => NULL()
  93. INTEGER , DIMENSION(:,:) , POINTER :: iwrk2d => NULL()
  94. INTEGER , DIMENSION(:,:,:) , POINTER :: iwrk3d => NULL()
  95. INTEGER , DIMENSION(:,:,:,:), POINTER :: iwrk4d => NULL()
  96. REAL(wp), DIMENSION(:) , POINTER :: zwrk1d => NULL()
  97. REAL(wp), DIMENSION(:,:) , POINTER :: zwrk2d => NULL()
  98. REAL(wp), DIMENSION(:,:,:) , POINTER :: zwrk3d => NULL()
  99. REAL(wp), DIMENSION(:,:,:,:), POINTER :: zwrk4d => NULL()
  100. TYPE (leaf), POINTER :: next => NULL()
  101. TYPE (leaf), POINTER :: prev => NULL()
  102. END TYPE leaf
  103. TYPE branch
  104. INTEGER :: itype
  105. INTEGER, DIMENSION(jpmaxdim) :: ishape, istart
  106. TYPE(leaf), POINTER :: start => NULL()
  107. TYPE(leaf), POINTER :: current => NULL()
  108. END TYPE branch
  109. TYPE(branch), SAVE, DIMENSION(jparray) :: tree
  110. LOGICAL :: linit = .FALSE.
  111. LOGICAL :: ldebug = .FALSE.
  112. !!----------------------------------------------------------------------
  113. !! NEMO/OPA 4.0 , NEMO Consortium (2011)
  114. !! $Id: wrk_nemo.F90 6139 2018-11-22 12:07:52Z ufla $
  115. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  116. !!----------------------------------------------------------------------
  117. CONTAINS
  118. SUBROUTINE wrk_list
  119. ! to list 3d arrays in use, to be duplicated for all cases
  120. WRITE(*,*) 'Arrays in use :'
  121. ! CALL listage(tree_3d(1)%s_wrk_3d_start)
  122. WRITE(*,*) ''
  123. END SUBROUTINE wrk_list
  124. RECURSIVE SUBROUTINE listage(ptr)
  125. TYPE(leaf), POINTER, INTENT(in) :: ptr
  126. !
  127. IF( ASSOCIATED(ptr%next) ) CALL listage(ptr%next)
  128. WRITE(*,*) ptr%in_use, ptr%indic
  129. END SUBROUTINE listage
  130. SUBROUTINE wrk_alloc_1dr( kidim, p1d01, p1d02, p1d03, p1d04, p1d05, p1d06, p1d07, p1d08, p1d09, p1d10, kistart )
  131. INTEGER , INTENT(in ) :: kidim ! dimensions size
  132. REAL(wp), POINTER, DIMENSION(:), INTENT(inout) :: p1d01
  133. REAL(wp), POINTER, DIMENSION(:), INTENT(inout), OPTIONAL :: p1d02,p1d03,p1d04,p1d05,p1d06,p1d07,p1d08,p1d09,p1d10
  134. INTEGER , INTENT(in ), OPTIONAL :: kistart
  135. !
  136. CALL wrk_alloc_xd( kidim, 0, 0, 0, kistart, 1, 1, 1, &
  137. & p1d01 = p1d01, p1d02 = p1d02, p1d03 = p1d03, p1d04 = p1d04, p1d05 = p1d05, &
  138. & p1d06 = p1d06, p1d07 = p1d07, p1d08 = p1d08, p1d09 = p1d09, p1d10 = p1d10 )
  139. !
  140. #if defined key_init_alloc_zero
  141. p1d01 = 0
  142. if (PRESENT(p1d02)) p1d02 = 0
  143. if (PRESENT(p1d03)) p1d03 = 0
  144. if (PRESENT(p1d04)) p1d04 = 0
  145. if (PRESENT(p1d05)) p1d05 = 0
  146. if (PRESENT(p1d06)) p1d06 = 0
  147. if (PRESENT(p1d07)) p1d07 = 0
  148. if (PRESENT(p1d08)) p1d08 = 0
  149. if (PRESENT(p1d09)) p1d09 = 0
  150. if (PRESENT(p1d10)) p1d10 = 0
  151. #elif defined key_init_alloc_huge
  152. p1d01 = HUGE(p1d01)
  153. if (PRESENT(p1d02)) p1d02 = HUGE(p1d02)
  154. if (PRESENT(p1d03)) p1d03 = HUGE(p1d03)
  155. if (PRESENT(p1d04)) p1d04 = HUGE(p1d04)
  156. if (PRESENT(p1d05)) p1d05 = HUGE(p1d05)
  157. if (PRESENT(p1d06)) p1d06 = HUGE(p1d06)
  158. if (PRESENT(p1d07)) p1d07 = HUGE(p1d07)
  159. if (PRESENT(p1d08)) p1d08 = HUGE(p1d08)
  160. if (PRESENT(p1d09)) p1d09 = HUGE(p1d09)
  161. if (PRESENT(p1d10)) p1d10 = HUGE(p1d10)
  162. #endif
  163. !
  164. END SUBROUTINE wrk_alloc_1dr
  165. SUBROUTINE wrk_alloc_1di( kidim, k1d01, k1d02, k1d03, k1d04, k1d05, k1d06, k1d07, k1d08, k1d09, k1d10, kistart )
  166. INTEGER , INTENT(in ) :: kidim ! dimensions size
  167. INTEGER , POINTER, DIMENSION(:), INTENT(inout) :: k1d01
  168. INTEGER , POINTER, DIMENSION(:), INTENT(inout), OPTIONAL :: k1d02,k1d03,k1d04,k1d05,k1d06,k1d07,k1d08,k1d09,k1d10
  169. INTEGER , INTENT(in ), OPTIONAL :: kistart
  170. !
  171. CALL wrk_alloc_xd( kidim, 0, 0, 0, kistart, 1, 1, 1, &
  172. & k1d01 = k1d01, k1d02 = k1d02, k1d03 = k1d03, k1d04 = k1d04, k1d05 = k1d05, &
  173. & k1d06 = k1d06, k1d07 = k1d07, k1d08 = k1d08, k1d09 = k1d09, k1d10 = k1d10 )
  174. !
  175. END SUBROUTINE wrk_alloc_1di
  176. SUBROUTINE wrk_alloc_2dr( kidim, kjdim, p2d01, p2d02, p2d03, p2d04, p2d05, p2d06, p2d07, p2d08, p2d09, p2d10, kistart, kjstart )
  177. INTEGER , INTENT(in ) :: kidim, kjdim ! dimensions size
  178. REAL(wp), POINTER, DIMENSION(:,:), INTENT(inout) :: p2d01
  179. REAL(wp), POINTER, DIMENSION(:,:), INTENT(inout), OPTIONAL :: p2d02,p2d03,p2d04,p2d05,p2d06,p2d07,p2d08,p2d09,p2d10
  180. INTEGER , INTENT(in ), OPTIONAL :: kistart, kjstart
  181. !
  182. CALL wrk_alloc_xd( kidim, kjdim, 0, 0, kistart, kjstart, 1, 1, &
  183. & p2d01 = p2d01, p2d02 = p2d02, p2d03 = p2d03, p2d04 = p2d04, p2d05 = p2d05, &
  184. & p2d06 = p2d06, p2d07 = p2d07, p2d08 = p2d08, p2d09 = p2d09, p2d10 = p2d10 )
  185. !
  186. #if defined key_init_alloc_zero
  187. p2d01 = 0
  188. if (PRESENT(p2d02)) p2d02 = 0
  189. if (PRESENT(p2d03)) p2d03 = 0
  190. if (PRESENT(p2d04)) p2d04 = 0
  191. if (PRESENT(p2d05)) p2d05 = 0
  192. if (PRESENT(p2d06)) p2d06 = 0
  193. if (PRESENT(p2d07)) p2d07 = 0
  194. if (PRESENT(p2d08)) p2d08 = 0
  195. if (PRESENT(p2d09)) p2d09 = 0
  196. if (PRESENT(p2d10)) p2d10 = 0
  197. #elif defined key_init_alloc_huge
  198. p2d01 = HUGE(p2d01)
  199. if (PRESENT(p2d02)) p2d02 = HUGE(p2d02)
  200. if (PRESENT(p2d03)) p2d03 = HUGE(p2d03)
  201. if (PRESENT(p2d04)) p2d04 = HUGE(p2d04)
  202. if (PRESENT(p2d05)) p2d05 = HUGE(p2d05)
  203. if (PRESENT(p2d06)) p2d06 = HUGE(p2d06)
  204. if (PRESENT(p2d07)) p2d07 = HUGE(p2d07)
  205. if (PRESENT(p2d08)) p2d08 = HUGE(p2d08)
  206. if (PRESENT(p2d09)) p2d09 = HUGE(p2d09)
  207. if (PRESENT(p2d10)) p2d10 = HUGE(p2d10)
  208. #endif
  209. !
  210. END SUBROUTINE wrk_alloc_2dr
  211. SUBROUTINE wrk_alloc_2di( kidim, kjdim, k2d01, k2d02, k2d03, k2d04, k2d05, k2d06, k2d07, k2d08, k2d09, k2d10, kistart, kjstart )
  212. INTEGER , INTENT(in ) :: kidim, kjdim ! dimensions size
  213. INTEGER , POINTER, DIMENSION(:,:), INTENT(inout) :: k2d01
  214. INTEGER , POINTER, DIMENSION(:,:), INTENT(inout), OPTIONAL :: k2d02,k2d03,k2d04,k2d05,k2d06,k2d07,k2d08,k2d09,k2d10
  215. INTEGER , INTENT(in ), OPTIONAL :: kistart, kjstart
  216. !
  217. CALL wrk_alloc_xd( kidim, kjdim, 0, 0, kistart, kjstart, 1, 1, &
  218. & k2d01 = k2d01, k2d02 = k2d02, k2d03 = k2d03, k2d04 = k2d04, k2d05 = k2d05, &
  219. & k2d06 = k2d06, k2d07 = k2d07, k2d08 = k2d08, k2d09 = k2d09, k2d10 = k2d10 )
  220. !
  221. END SUBROUTINE wrk_alloc_2di
  222. SUBROUTINE wrk_alloc_3dr( kidim, kjdim, kkdim, p3d01, p3d02, p3d03, p3d04, p3d05, p3d06, p3d07, p3d08, p3d09, p3d10, &
  223. & kistart, kjstart, kkstart )
  224. INTEGER , INTENT(in ) :: kidim, kjdim, kkdim ! dimensions size
  225. REAL(wp), POINTER, DIMENSION(:,:,:), INTENT(inout) :: p3d01
  226. REAL(wp), POINTER, DIMENSION(:,:,:), INTENT(inout), OPTIONAL :: p3d02,p3d03,p3d04,p3d05,p3d06,p3d07,p3d08,p3d09,p3d10
  227. INTEGER , INTENT(in ), OPTIONAL :: kistart, kjstart, kkstart
  228. !
  229. CALL wrk_alloc_xd( kidim, kjdim, kkdim, 0, kistart, kjstart, kkstart, 1, &
  230. & p3d01 = p3d01, p3d02 = p3d02, p3d03 = p3d03, p3d04 = p3d04, p3d05 = p3d05, &
  231. & p3d06 = p3d06, p3d07 = p3d07, p3d08 = p3d08, p3d09 = p3d09, p3d10 = p3d10 )
  232. !
  233. #if defined key_init_alloc_zero
  234. p3d01 = 0
  235. if (PRESENT(p3d02)) p3d02 = 0
  236. if (PRESENT(p3d03)) p3d03 = 0
  237. if (PRESENT(p3d04)) p3d04 = 0
  238. if (PRESENT(p3d05)) p3d05 = 0
  239. if (PRESENT(p3d06)) p3d06 = 0
  240. if (PRESENT(p3d07)) p3d07 = 0
  241. if (PRESENT(p3d08)) p3d08 = 0
  242. if (PRESENT(p3d09)) p3d09 = 0
  243. if (PRESENT(p3d10)) p3d10 = 0
  244. #elif defined key_init_alloc_huge
  245. p3d01 = HUGE(p3d01)
  246. if (PRESENT(p3d02)) p3d02 = HUGE(p3d02)
  247. if (PRESENT(p3d03)) p3d03 = HUGE(p3d03)
  248. if (PRESENT(p3d04)) p3d04 = HUGE(p3d04)
  249. if (PRESENT(p3d05)) p3d05 = HUGE(p3d05)
  250. if (PRESENT(p3d06)) p3d06 = HUGE(p3d06)
  251. if (PRESENT(p3d07)) p3d07 = HUGE(p3d07)
  252. if (PRESENT(p3d08)) p3d08 = HUGE(p3d08)
  253. if (PRESENT(p3d09)) p3d09 = HUGE(p3d09)
  254. if (PRESENT(p3d10)) p3d10 = HUGE(p3d10)
  255. #endif
  256. !
  257. END SUBROUTINE wrk_alloc_3dr
  258. SUBROUTINE wrk_alloc_3di( kidim, kjdim, kkdim, k3d01, k3d02, k3d03, k3d04, k3d05, k3d06, k3d07, k3d08, k3d09, k3d10, &
  259. & kistart, kjstart, kkstart )
  260. INTEGER , INTENT(in ) :: kidim, kjdim, kkdim ! dimensions size
  261. INTEGER , POINTER, DIMENSION(:,:,:), INTENT(inout) :: k3d01
  262. INTEGER , POINTER, DIMENSION(:,:,:), INTENT(inout), OPTIONAL :: k3d02,k3d03,k3d04,k3d05,k3d06,k3d07,k3d08,k3d09,k3d10
  263. INTEGER , INTENT(in ), OPTIONAL :: kistart, kjstart, kkstart
  264. !
  265. CALL wrk_alloc_xd( kidim, kjdim, kkdim, 0, kistart, kjstart, kkstart, 1, &
  266. & k3d01 = k3d01, k3d02 = k3d02, k3d03 = k3d03, k3d04 = k3d04, k3d05 = k3d05, &
  267. & k3d06 = k3d06, k3d07 = k3d07, k3d08 = k3d08, k3d09 = k3d09, k3d10 = k3d10 )
  268. !
  269. END SUBROUTINE wrk_alloc_3di
  270. SUBROUTINE wrk_alloc_4dr( kidim, kjdim, kkdim, kldim, p4d01, p4d02, p4d03, p4d04, p4d05, p4d06, p4d07, p4d08, p4d09, p4d10, &
  271. & kistart, kjstart, kkstart, klstart )
  272. INTEGER , INTENT(in ) :: kidim, kjdim, kkdim, kldim ! dimensions size
  273. REAL(wp), POINTER, DIMENSION(:,:,:,:), INTENT(inout) :: p4d01
  274. REAL(wp), POINTER, DIMENSION(:,:,:,:), INTENT(inout), OPTIONAL :: p4d02,p4d03,p4d04,p4d05,p4d06,p4d07,p4d08,p4d09,p4d10
  275. INTEGER , INTENT(in ), OPTIONAL :: kistart, kjstart, kkstart, klstart
  276. !
  277. CALL wrk_alloc_xd( kidim, kjdim, kkdim, kldim, kistart, kjstart, kkstart, klstart, &
  278. & p4d01 = p4d01, p4d02 = p4d02, p4d03 = p4d03, p4d04 = p4d04, p4d05 = p4d05, &
  279. & p4d06 = p4d06, p4d07 = p4d07, p4d08 = p4d08, p4d09 = p4d09, p4d10 = p4d10 )
  280. !
  281. #if defined key_init_alloc_zero
  282. p4d01 = 0
  283. if (PRESENT(p4d02)) p4d02 = 0
  284. if (PRESENT(p4d03)) p4d03 = 0
  285. if (PRESENT(p4d04)) p4d04 = 0
  286. if (PRESENT(p4d05)) p4d05 = 0
  287. if (PRESENT(p4d06)) p4d06 = 0
  288. if (PRESENT(p4d07)) p4d07 = 0
  289. if (PRESENT(p4d08)) p4d08 = 0
  290. if (PRESENT(p4d09)) p4d09 = 0
  291. if (PRESENT(p4d10)) p4d10 = 0
  292. #elif defined key_init_alloc_huge
  293. p4d01 = HUGE(p4d01)
  294. if (PRESENT(p4d02)) p4d02 = HUGE(p4d02)
  295. if (PRESENT(p4d03)) p4d03 = HUGE(p4d03)
  296. if (PRESENT(p4d04)) p4d04 = HUGE(p4d04)
  297. if (PRESENT(p4d05)) p4d05 = HUGE(p4d05)
  298. if (PRESENT(p4d06)) p4d06 = HUGE(p4d06)
  299. if (PRESENT(p4d07)) p4d07 = HUGE(p4d07)
  300. if (PRESENT(p4d08)) p4d08 = HUGE(p4d08)
  301. if (PRESENT(p4d09)) p4d09 = HUGE(p4d09)
  302. if (PRESENT(p4d10)) p4d10 = HUGE(p4d10)
  303. #endif
  304. !
  305. END SUBROUTINE wrk_alloc_4dr
  306. SUBROUTINE wrk_alloc_4di( kidim, kjdim, kkdim, kldim, k4d01, k4d02, k4d03, k4d04, k4d05, k4d06, k4d07, k4d08, k4d09, k4d10, &
  307. & kistart, kjstart, kkstart, klstart )
  308. INTEGER , INTENT(in ) :: kidim, kjdim, kkdim, kldim ! dimensions size
  309. INTEGER , POINTER, DIMENSION(:,:,:,:), INTENT(inout) :: k4d01
  310. INTEGER , POINTER, DIMENSION(:,:,:,:), INTENT(inout), OPTIONAL :: k4d02,k4d03,k4d04,k4d05,k4d06,k4d07,k4d08,k4d09,k4d10
  311. INTEGER , INTENT(in ), OPTIONAL :: kistart, kjstart, kkstart, klstart
  312. !
  313. CALL wrk_alloc_xd( kidim, kjdim, kkdim, kldim, kistart, kjstart, kkstart, klstart, &
  314. & k4d01 = k4d01, k4d02 = k4d02, k4d03 = k4d03, k4d04 = k4d04, k4d05 = k4d05, &
  315. & k4d06 = k4d06, k4d07 = k4d07, k4d08 = k4d08, k4d09 = k4d09, k4d10 = k4d10 )
  316. !
  317. END SUBROUTINE wrk_alloc_4di
  318. SUBROUTINE wrk_dealloc_1dr( kidim, p1d01, p1d02, p1d03, p1d04, p1d05, p1d06, p1d07, p1d08, p1d09, p1d10, kistart )
  319. INTEGER , INTENT(in ) :: kidim ! dimensions size
  320. REAL(wp), POINTER, DIMENSION(:), INTENT(inout) :: p1d01
  321. REAL(wp), POINTER, DIMENSION(:), INTENT(inout), OPTIONAL :: p1d02,p1d03,p1d04,p1d05,p1d06,p1d07,p1d08,p1d09,p1d10
  322. INTEGER , INTENT(in ), OPTIONAL :: kistart
  323. !
  324. INTEGER :: icnt, jn
  325. icnt = 1 + COUNT( (/ PRESENT(p1d02),PRESENT(p1d03),PRESENT(p1d04),PRESENT(p1d05), &
  326. & PRESENT(p1d06),PRESENT(p1d07),PRESENT(p1d08),PRESENT(p1d09),PRESENT(p1d10) /) )
  327. DO jn = 1, icnt ; CALL wrk_deallocbase( jpreal, kidim, 0, 0, 0, kistart, 1, 1, 1) ; END DO
  328. !
  329. END SUBROUTINE wrk_dealloc_1dr
  330. SUBROUTINE wrk_dealloc_1di( kidim, k1d01, k1d02, k1d03, k1d04, k1d05, k1d06, k1d07, k1d08, k1d09, k1d10, kistart )
  331. INTEGER , INTENT(in ) :: kidim ! dimensions size
  332. INTEGER , POINTER, DIMENSION(:), INTENT(inout) :: k1d01
  333. INTEGER , POINTER, DIMENSION(:), INTENT(inout), OPTIONAL :: k1d02,k1d03,k1d04,k1d05,k1d06,k1d07,k1d08,k1d09,k1d10
  334. INTEGER , INTENT(in ), OPTIONAL :: kistart
  335. !
  336. INTEGER :: icnt, jn
  337. icnt = 1 + COUNT( (/ PRESENT(k1d02),PRESENT(k1d03),PRESENT(k1d04),PRESENT(k1d05), &
  338. & PRESENT(k1d06),PRESENT(k1d07),PRESENT(k1d08),PRESENT(k1d09),PRESENT(k1d10) /) )
  339. DO jn = 1, icnt ; CALL wrk_deallocbase( jpinteger, kidim, 0, 0, 0, kistart, 1, 1, 1 ) ; END DO
  340. !
  341. END SUBROUTINE wrk_dealloc_1di
  342. SUBROUTINE wrk_dealloc_2dr( kidim, kjdim, p2d01, p2d02, p2d03, p2d04, p2d05, p2d06, p2d07, p2d08, p2d09, p2d10, kistart,kjstart )
  343. INTEGER , INTENT(in ) :: kidim, kjdim ! dimensions size
  344. REAL(wp), POINTER, DIMENSION(:,:), INTENT(inout) :: p2d01
  345. REAL(wp), POINTER, DIMENSION(:,:), INTENT(inout), OPTIONAL :: p2d02,p2d03,p2d04,p2d05,p2d06,p2d07,p2d08,p2d09,p2d10
  346. INTEGER , INTENT(in ), OPTIONAL :: kistart, kjstart
  347. !
  348. INTEGER :: icnt, jn
  349. icnt = 1 + COUNT( (/ PRESENT(p2d02),PRESENT(p2d03),PRESENT(p2d04),PRESENT(p2d05), &
  350. & PRESENT(p2d06),PRESENT(p2d07),PRESENT(p2d08),PRESENT(p2d09),PRESENT(p2d10) /) )
  351. DO jn = 1, icnt ; CALL wrk_deallocbase( jpreal, kidim, kjdim, 0, 0, kistart, kjstart, 1, 1 ) ; END DO
  352. !
  353. END SUBROUTINE wrk_dealloc_2dr
  354. SUBROUTINE wrk_dealloc_2di( kidim, kjdim, k2d01, k2d02, k2d03, k2d04, k2d05, k2d06, k2d07, k2d08, k2d09, k2d10, kistart,kjstart )
  355. INTEGER , INTENT(in ) :: kidim, kjdim ! dimensions size
  356. INTEGER , POINTER, DIMENSION(:,:), INTENT(inout) :: k2d01
  357. INTEGER , POINTER, DIMENSION(:,:), INTENT(inout), OPTIONAL :: k2d02,k2d03,k2d04,k2d05,k2d06,k2d07,k2d08,k2d09,k2d10
  358. INTEGER , INTENT(in ), OPTIONAL :: kistart, kjstart
  359. !
  360. INTEGER :: icnt, jn
  361. icnt = 1 + COUNT( (/ PRESENT(k2d02),PRESENT(k2d03),PRESENT(k2d04),PRESENT(k2d05), &
  362. & PRESENT(k2d06),PRESENT(k2d07),PRESENT(k2d08),PRESENT(k2d09),PRESENT(k2d10) /) )
  363. DO jn = 1, icnt ; CALL wrk_deallocbase( jpinteger, kidim, kjdim, 0, 0, kistart, kjstart, 1, 1 ) ; END DO
  364. !
  365. END SUBROUTINE wrk_dealloc_2di
  366. SUBROUTINE wrk_dealloc_3dr( kidim, kjdim, kkdim, p3d01, p3d02, p3d03, p3d04, p3d05, p3d06, p3d07, p3d08, p3d09, p3d10, &
  367. & kistart, kjstart, kkstart )
  368. INTEGER , INTENT(in ) :: kidim, kjdim, kkdim ! dimensions size
  369. REAL(wp), POINTER, DIMENSION(:,:,:), INTENT(inout) :: p3d01
  370. REAL(wp), POINTER, DIMENSION(:,:,:), INTENT(inout), OPTIONAL :: p3d02,p3d03,p3d04,p3d05,p3d06,p3d07,p3d08,p3d09,p3d10
  371. INTEGER , INTENT(in ), OPTIONAL :: kistart, kjstart, kkstart
  372. !
  373. INTEGER :: icnt, jn
  374. icnt = 1 + COUNT( (/ PRESENT(p3d02),PRESENT(p3d03),PRESENT(p3d04),PRESENT(p3d05), &
  375. & PRESENT(p3d06),PRESENT(p3d07),PRESENT(p3d08),PRESENT(p3d09),PRESENT(p3d10) /) )
  376. DO jn = 1, icnt ; CALL wrk_deallocbase( jpreal, kidim, kjdim, kkdim, 0, kistart, kjstart, kkstart, 1 ) ; END DO
  377. !
  378. END SUBROUTINE wrk_dealloc_3dr
  379. SUBROUTINE wrk_dealloc_3di( kidim, kjdim, kkdim, k3d01, k3d02, k3d03, k3d04, k3d05, k3d06, k3d07, k3d08, k3d09, k3d10, &
  380. & kistart, kjstart, kkstart )
  381. INTEGER , INTENT(in ) :: kidim, kjdim, kkdim ! dimensions size
  382. INTEGER , POINTER, DIMENSION(:,:,:), INTENT(inout) :: k3d01
  383. INTEGER , POINTER, DIMENSION(:,:,:), INTENT(inout), OPTIONAL :: k3d02,k3d03,k3d04,k3d05,k3d06,k3d07,k3d08,k3d09,k3d10
  384. INTEGER , INTENT(in ), OPTIONAL :: kistart, kjstart, kkstart
  385. !
  386. INTEGER :: icnt, jn
  387. icnt = 1 + COUNT( (/ PRESENT(k3d02),PRESENT(k3d03),PRESENT(k3d04),PRESENT(k3d05), &
  388. & PRESENT(k3d06),PRESENT(k3d07),PRESENT(k3d08),PRESENT(k3d09),PRESENT(k3d10) /) )
  389. DO jn = 1, icnt ; CALL wrk_deallocbase( jpinteger, kidim, kjdim, kkdim, 0, kistart, kjstart, kkstart, 1 ) ; END DO
  390. !
  391. END SUBROUTINE wrk_dealloc_3di
  392. SUBROUTINE wrk_dealloc_4dr( kidim, kjdim, kkdim, kldim, p4d01, p4d02, p4d03, p4d04, p4d05, p4d06, p4d07, p4d08, p4d09, p4d10, &
  393. & kistart, kjstart, kkstart, klstart )
  394. INTEGER , INTENT(in ) :: kidim, kjdim, kkdim, kldim ! dimensions size
  395. REAL(wp), POINTER, DIMENSION(:,:,:,:), INTENT(inout) :: p4d01
  396. REAL(wp), POINTER, DIMENSION(:,:,:,:), INTENT(inout), OPTIONAL :: p4d02,p4d03,p4d04,p4d05,p4d06,p4d07,p4d08,p4d09,p4d10
  397. INTEGER , INTENT(in ), OPTIONAL :: kistart, kjstart, kkstart, klstart
  398. !
  399. INTEGER :: icnt, jn
  400. icnt = 1 + COUNT( (/ PRESENT(p4d02),PRESENT(p4d03),PRESENT(p4d04),PRESENT(p4d05), &
  401. & PRESENT(p4d06),PRESENT(p4d07),PRESENT(p4d08),PRESENT(p4d09),PRESENT(p4d10) /) )
  402. DO jn = 1, icnt ; CALL wrk_deallocbase( jpreal, kidim, kjdim, kkdim, kldim, kistart, kjstart, kkstart, klstart ) ; END DO
  403. !
  404. END SUBROUTINE wrk_dealloc_4dr
  405. SUBROUTINE wrk_dealloc_4di( kidim, kjdim, kkdim, kldim, k4d01, k4d02, k4d03, k4d04, k4d05, k4d06, k4d07, k4d08, k4d09, k4d10, &
  406. & kistart, kjstart, kkstart, klstart )
  407. INTEGER , INTENT(in ) :: kidim, kjdim, kkdim, kldim ! dimensions size
  408. INTEGER , POINTER, DIMENSION(:,:,:,:), INTENT(inout) :: k4d01
  409. INTEGER , POINTER, DIMENSION(:,:,:,:), INTENT(inout), OPTIONAL :: k4d02,k4d03,k4d04,k4d05,k4d06,k4d07,k4d08,k4d09,k4d10
  410. INTEGER , INTENT(in ), OPTIONAL :: kistart, kjstart, kkstart, klstart
  411. !
  412. INTEGER :: icnt, jn
  413. icnt = 1 + COUNT( (/ PRESENT(k4d02),PRESENT(k4d03),PRESENT(k4d04),PRESENT(k4d05), &
  414. & PRESENT(k4d06),PRESENT(k4d07),PRESENT(k4d08),PRESENT(k4d09),PRESENT(k4d10) /) )
  415. DO jn = 1, icnt ; CALL wrk_deallocbase( jpinteger, kidim, kjdim, kkdim, kldim, kistart, kjstart, kkstart, klstart ) ; END DO
  416. !
  417. END SUBROUTINE wrk_dealloc_4di
  418. SUBROUTINE wrk_alloc_xd( kidim, kjdim, kkdim, kldim, &
  419. & kisrt, kjsrt, kksrt, klsrt, &
  420. & k1d01, k1d02, k1d03, k1d04, k1d05, k1d06, k1d07, k1d08, k1d09, k1d10, &
  421. & k2d01, k2d02, k2d03, k2d04, k2d05, k2d06, k2d07, k2d08, k2d09, k2d10, &
  422. & k3d01, k3d02, k3d03, k3d04, k3d05, k3d06, k3d07, k3d08, k3d09, k3d10, &
  423. & k4d01, k4d02, k4d03, k4d04, k4d05, k4d06, k4d07, k4d08, k4d09, k4d10, &
  424. & p1d01, p1d02, p1d03, p1d04, p1d05, p1d06, p1d07, p1d08, p1d09, p1d10, &
  425. & p2d01, p2d02, p2d03, p2d04, p2d05, p2d06, p2d07, p2d08, p2d09, p2d10, &
  426. & p3d01, p3d02, p3d03, p3d04, p3d05, p3d06, p3d07, p3d08, p3d09, p3d10, &
  427. & p4d01, p4d02, p4d03, p4d04, p4d05, p4d06, p4d07, p4d08, p4d09, p4d10 )
  428. INTEGER ,INTENT(in ) :: kidim, kjdim, kkdim, kldim ! dimensions size
  429. INTEGER ,INTENT(in ),OPTIONAL:: kisrt, kjsrt, kksrt, klsrt
  430. INTEGER , POINTER, DIMENSION(: ),INTENT(inout),OPTIONAL:: k1d01,k1d02,k1d03,k1d04,k1d05,k1d06,k1d07,k1d08,k1d09,k1d10
  431. INTEGER , POINTER, DIMENSION(:,: ),INTENT(inout),OPTIONAL:: k2d01,k2d02,k2d03,k2d04,k2d05,k2d06,k2d07,k2d08,k2d09,k2d10
  432. INTEGER , POINTER, DIMENSION(:,:,: ),INTENT(inout),OPTIONAL:: k3d01,k3d02,k3d03,k3d04,k3d05,k3d06,k3d07,k3d08,k3d09,k3d10
  433. INTEGER , POINTER, DIMENSION(:,:,:,:),INTENT(inout),OPTIONAL:: k4d01,k4d02,k4d03,k4d04,k4d05,k4d06,k4d07,k4d08,k4d09,k4d10
  434. REAL(wp), POINTER, DIMENSION(: ),INTENT(inout),OPTIONAL:: p1d01,p1d02,p1d03,p1d04,p1d05,p1d06,p1d07,p1d08,p1d09,p1d10
  435. REAL(wp), POINTER, DIMENSION(:,: ),INTENT(inout),OPTIONAL:: p2d01,p2d02,p2d03,p2d04,p2d05,p2d06,p2d07,p2d08,p2d09,p2d10
  436. REAL(wp), POINTER, DIMENSION(:,:,: ),INTENT(inout),OPTIONAL:: p3d01,p3d02,p3d03,p3d04,p3d05,p3d06,p3d07,p3d08,p3d09,p3d10
  437. REAL(wp), POINTER, DIMENSION(:,:,:,:),INTENT(inout),OPTIONAL:: p4d01,p4d02,p4d03,p4d04,p4d05,p4d06,p4d07,p4d08,p4d09,p4d10
  438. !
  439. LOGICAL :: llpres
  440. INTEGER :: jn, iisrt, ijsrt, iksrt, ilsrt
  441. !
  442. IF( .NOT. linit ) THEN
  443. tree(:)%itype = jpnotdefined
  444. DO jn = 1, jparray ; tree(jn)%ishape(:) = 0 ; tree(jn)%istart(:) = 0 ; END DO
  445. linit = .TRUE.
  446. ENDIF
  447. IF( PRESENT(kisrt) ) THEN ; iisrt = kisrt ; ELSE ; iisrt = 1 ; ENDIF
  448. IF( PRESENT(kjsrt) ) THEN ; ijsrt = kjsrt ; ELSE ; ijsrt = 1 ; ENDIF
  449. IF( PRESENT(kksrt) ) THEN ; iksrt = kksrt ; ELSE ; iksrt = 1 ; ENDIF
  450. IF( PRESENT(klsrt) ) THEN ; ilsrt = klsrt ; ELSE ; ilsrt = 1 ; ENDIF
  451. llpres = PRESENT(k1d01) .OR. PRESENT(k2d01) .OR. PRESENT(k3d01) .OR. PRESENT(k4d01) &
  452. & .OR. PRESENT(p1d01) .OR. PRESENT(p2d01) .OR. PRESENT(p3d01) .OR. PRESENT(p4d01)
  453. IF( llpres ) CALL wrk_allocbase( kidim, kjdim, kkdim, kldim, iisrt, ijsrt, iksrt, ilsrt, &
  454. & k1d01, k2d01, k3d01, k4d01, p1d01, p2d01, p3d01, p4d01 )
  455. llpres = PRESENT(k1d02) .OR. PRESENT(k2d02) .OR. PRESENT(k3d02) .OR. PRESENT(k4d02) &
  456. & .OR. PRESENT(p1d02) .OR. PRESENT(p2d02) .OR. PRESENT(p3d02) .OR. PRESENT(p4d02)
  457. IF( llpres ) CALL wrk_allocbase( kidim, kjdim, kkdim, kldim, iisrt, ijsrt, iksrt, ilsrt, &
  458. & k1d02, k2d02, k3d02, k4d02, p1d02, p2d02, p3d02, p4d02 )
  459. llpres = PRESENT(k1d03) .OR. PRESENT(k2d03) .OR. PRESENT(k3d03) .OR. PRESENT(k4d03) &
  460. & .OR. PRESENT(p1d03) .OR. PRESENT(p2d03) .OR. PRESENT(p3d03) .OR. PRESENT(p4d03)
  461. IF( llpres ) CALL wrk_allocbase( kidim, kjdim, kkdim, kldim, iisrt, ijsrt, iksrt, ilsrt, &
  462. & k1d03, k2d03, k3d03, k4d03, p1d03, p2d03, p3d03, p4d03 )
  463. llpres = PRESENT(k1d04) .OR. PRESENT(k2d04) .OR. PRESENT(k3d04) .OR. PRESENT(k4d04) &
  464. & .OR. PRESENT(p1d04) .OR. PRESENT(p2d04) .OR. PRESENT(p3d04) .OR. PRESENT(p4d04)
  465. IF( llpres ) CALL wrk_allocbase( kidim, kjdim, kkdim, kldim, iisrt, ijsrt, iksrt, ilsrt, &
  466. & k1d04, k2d04, k3d04, k4d04, p1d04, p2d04, p3d04, p4d04 )
  467. llpres = PRESENT(k1d05) .OR. PRESENT(k2d05) .OR. PRESENT(k3d05) .OR. PRESENT(k4d05) &
  468. & .OR. PRESENT(p1d05) .OR. PRESENT(p2d05) .OR. PRESENT(p3d05) .OR. PRESENT(p4d05)
  469. IF( llpres ) CALL wrk_allocbase( kidim, kjdim, kkdim, kldim, iisrt, ijsrt, iksrt, ilsrt, &
  470. & k1d05, k2d05, k3d05, k4d05, p1d05, p2d05, p3d05, p4d05 )
  471. llpres = PRESENT(k1d06) .OR. PRESENT(k2d06) .OR. PRESENT(k3d06) .OR. PRESENT(k4d06) &
  472. & .OR. PRESENT(p1d06) .OR. PRESENT(p2d06) .OR. PRESENT(p3d06) .OR. PRESENT(p4d06)
  473. IF( llpres ) CALL wrk_allocbase( kidim, kjdim, kkdim, kldim, iisrt, ijsrt, iksrt, ilsrt, &
  474. & k1d06, k2d06, k3d06, k4d06, p1d06, p2d06, p3d06, p4d06 )
  475. llpres = PRESENT(k1d07) .OR. PRESENT(k2d07) .OR. PRESENT(k3d07) .OR. PRESENT(k4d07) &
  476. & .OR. PRESENT(p1d07) .OR. PRESENT(p2d07) .OR. PRESENT(p3d07) .OR. PRESENT(p4d07)
  477. IF( llpres ) CALL wrk_allocbase( kidim, kjdim, kkdim, kldim, iisrt, ijsrt, iksrt, ilsrt, &
  478. & k1d07, k2d07, k3d07, k4d07, p1d07, p2d07, p3d07, p4d07 )
  479. llpres = PRESENT(k1d08) .OR. PRESENT(k2d08) .OR. PRESENT(k3d08) .OR. PRESENT(k4d08) &
  480. & .OR. PRESENT(p1d08) .OR. PRESENT(p2d08) .OR. PRESENT(p3d08) .OR. PRESENT(p4d08)
  481. IF( llpres ) CALL wrk_allocbase( kidim, kjdim, kkdim, kldim, iisrt, ijsrt, iksrt, ilsrt, &
  482. & k1d08, k2d08, k3d08, k4d08, p1d08, p2d08, p3d08, p4d08 )
  483. llpres = PRESENT(k1d09) .OR. PRESENT(k2d09) .OR. PRESENT(k3d09) .OR. PRESENT(k4d09) &
  484. & .OR. PRESENT(p1d09) .OR. PRESENT(p2d09) .OR. PRESENT(p3d09) .OR. PRESENT(p4d09)
  485. IF( llpres ) CALL wrk_allocbase( kidim, kjdim, kkdim, kldim, iisrt, ijsrt, iksrt, ilsrt, &
  486. & k1d09, k2d09, k3d09, k4d09, p1d09, p2d09, p3d09, p4d09 )
  487. llpres = PRESENT(k1d10) .OR. PRESENT(k2d10) .OR. PRESENT(k3d10) .OR. PRESENT(k4d10) &
  488. & .OR. PRESENT(p1d10) .OR. PRESENT(p2d10) .OR. PRESENT(p3d10) .OR. PRESENT(p4d10)
  489. IF( llpres ) CALL wrk_allocbase( kidim, kjdim, kkdim, kldim, iisrt, ijsrt, iksrt, ilsrt, &
  490. & k1d10, k2d10, k3d10, k4d10, p1d10, p2d10, p3d10, p4d10 )
  491. END SUBROUTINE wrk_alloc_xd
  492. SUBROUTINE wrk_allocbase( kidim , kjdim , kkdim , kldim , kisrt , kjsrt , kksrt , klsrt , &
  493. & kwrk1d, kwrk2d, kwrk3d, kwrk4d, pwrk1d, pwrk2d, pwrk3d, pwrk4d )
  494. INTEGER , INTENT(in ) :: kidim, kjdim, kkdim, kldim
  495. INTEGER , INTENT(in ) :: kisrt, kjsrt, kksrt, klsrt
  496. INTEGER , POINTER, DIMENSION(:) , INTENT(inout), OPTIONAL :: kwrk1d
  497. INTEGER , POINTER, DIMENSION(:,:) , INTENT(inout), OPTIONAL :: kwrk2d
  498. INTEGER , POINTER, DIMENSION(:,:,:) , INTENT(inout), OPTIONAL :: kwrk3d
  499. INTEGER , POINTER, DIMENSION(:,:,:,:), INTENT(inout), OPTIONAL :: kwrk4d
  500. REAL(wp), POINTER, DIMENSION(:) , INTENT(inout), OPTIONAL :: pwrk1d
  501. REAL(wp), POINTER, DIMENSION(:,:) , INTENT(inout), OPTIONAL :: pwrk2d
  502. REAL(wp), POINTER, DIMENSION(:,:,:) , INTENT(inout), OPTIONAL :: pwrk3d
  503. REAL(wp), POINTER, DIMENSION(:,:,:,:), INTENT(inout), OPTIONAL :: pwrk4d
  504. !
  505. INTEGER, DIMENSION(jpmaxdim) :: ishape, isrt, iend
  506. INTEGER :: itype
  507. INTEGER :: ii
  508. ! define the shape to be given to the work array
  509. ishape(:) = (/ kidim, kjdim, kkdim, kldim /)
  510. ! define the starting index of the dimension shape to be given to the work array
  511. isrt (:) = (/ kisrt, kjsrt, kksrt, klsrt /)
  512. iend (:) = ishape(:) + isrt(:) - 1
  513. ! is it integer or real array?
  514. IF( PRESENT(kwrk1d) .OR. PRESENT(kwrk2d) .OR. PRESENT(kwrk3d) .OR. PRESENT(kwrk4d) ) itype = jpinteger
  515. IF( PRESENT(pwrk1d) .OR. PRESENT(pwrk2d) .OR. PRESENT(pwrk3d) .OR. PRESENT(pwrk4d) ) itype = jpreal
  516. ! find the branch with the matching shape, staring index and type or get the first "free" branch
  517. ii = 1
  518. DO WHILE( ( ANY( tree(ii)%ishape /= ishape ) .OR. ANY( tree(ii)%istart /= isrt ) .OR. tree(ii)%itype /= itype ) &
  519. & .AND. SUM( tree(ii)%ishape ) /= 0 )
  520. ii = ii + 1
  521. IF (ii > jparray) STOP ! increase the value of jparray (should not be needed as already very big!)
  522. END DO
  523. IF( SUM( tree(ii)%ishape ) == 0 ) THEN ! create a new branch
  524. IF(ldebug) PRINT *, 'create new branch ', ii,ishape, isrt, itype
  525. tree(ii)%itype = itype ! define the type of this branch
  526. tree(ii)%ishape(:) = ishape(:) ! define the shape of this branch
  527. tree(ii)%istart(:) = isrt(:) ! define the lower bounds of this branch
  528. ALLOCATE( tree(ii)%start ) ! allocate its start
  529. ALLOCATE( tree(ii)%current) ! allocate the current leaf (the first leaf)
  530. tree(ii)%start%in_use = .FALSE. ! Never use the start as work array
  531. tree(ii)%start%indic = 0
  532. tree(ii)%start%prev => NULL() ! nothing before the start
  533. tree(ii)%start%next => tree(ii)%current ! first leaf link to the start
  534. tree(ii)%current%in_use = .FALSE. ! first leaf is not yet used
  535. tree(ii)%current%indic = 1 ! first leaf
  536. tree(ii)%current%prev => tree(ii)%start ! previous leaf is the start
  537. tree(ii)%current%next => NULL() ! next leaf is not yet defined
  538. ! allocate the array of the first leaf
  539. IF( PRESENT(kwrk1d) ) ALLOCATE( tree(ii)%current%iwrk1d(isrt(1):iend(1) ) )
  540. IF( PRESENT(kwrk2d) ) ALLOCATE( tree(ii)%current%iwrk2d(isrt(1):iend(1),isrt(2):iend(2) ) )
  541. IF( PRESENT(kwrk3d) ) ALLOCATE( tree(ii)%current%iwrk3d(isrt(1):iend(1),isrt(2):iend(2),isrt(3):iend(3) ) )
  542. IF( PRESENT(kwrk4d) ) ALLOCATE( tree(ii)%current%iwrk4d(isrt(1):iend(1),isrt(2):iend(2),isrt(3):iend(3),isrt(4):iend(4)) )
  543. IF( PRESENT(pwrk1d) ) ALLOCATE( tree(ii)%current%zwrk1d(isrt(1):iend(1) ) )
  544. IF( PRESENT(pwrk2d) ) ALLOCATE( tree(ii)%current%zwrk2d(isrt(1):iend(1),isrt(2):iend(2) ) )
  545. IF( PRESENT(pwrk3d) ) ALLOCATE( tree(ii)%current%zwrk3d(isrt(1):iend(1),isrt(2):iend(2),isrt(3):iend(3) ) )
  546. IF( PRESENT(pwrk4d) ) ALLOCATE( tree(ii)%current%zwrk4d(isrt(1):iend(1),isrt(2):iend(2),isrt(3):iend(3),isrt(4):iend(4)) )
  547. ELSE IF( .NOT. ASSOCIATED(tree(ii)%current%next) ) THEN ! all leafs used -> define a new one
  548. ALLOCATE( tree(ii)%current%next ) ! allocate the new leaf
  549. tree(ii)%current%next%in_use = .FALSE. ! this leaf is not yet used
  550. tree(ii)%current%next%indic = tree(ii)%current%indic + 1 ! number of this leaf
  551. IF(ldebug) PRINT *, 'add a leaf ', ii, tree(ii)%current%indic
  552. tree(ii)%current%next%prev => tree(ii)%current ! previous leaf of the new leaf is the current leaf
  553. tree(ii)%current%next%next => NULL() ! next leaf is not yet defined
  554. tree(ii)%current => tree(ii)%current%next ! the current leaf becomes the new one
  555. ! allocate the array of the new leaf
  556. IF( PRESENT(kwrk1d) ) ALLOCATE( tree(ii)%current%iwrk1d(isrt(1):iend(1) ) )
  557. IF( PRESENT(kwrk2d) ) ALLOCATE( tree(ii)%current%iwrk2d(isrt(1):iend(1),isrt(2):iend(2) ) )
  558. IF( PRESENT(kwrk3d) ) ALLOCATE( tree(ii)%current%iwrk3d(isrt(1):iend(1),isrt(2):iend(2),isrt(3):iend(3) ) )
  559. IF( PRESENT(kwrk4d) ) ALLOCATE( tree(ii)%current%iwrk4d(isrt(1):iend(1),isrt(2):iend(2),isrt(3):iend(3),isrt(4):iend(4)) )
  560. IF( PRESENT(pwrk1d) ) ALLOCATE( tree(ii)%current%zwrk1d(isrt(1):iend(1) ) )
  561. IF( PRESENT(pwrk2d) ) ALLOCATE( tree(ii)%current%zwrk2d(isrt(1):iend(1),isrt(2):iend(2) ) )
  562. IF( PRESENT(pwrk3d) ) ALLOCATE( tree(ii)%current%zwrk3d(isrt(1):iend(1),isrt(2):iend(2),isrt(3):iend(3) ) )
  563. IF( PRESENT(pwrk4d) ) ALLOCATE( tree(ii)%current%zwrk4d(isrt(1):iend(1),isrt(2):iend(2),isrt(3):iend(3),isrt(4):iend(4)) )
  564. ELSE
  565. tree(ii)%current => tree(ii)%current%next ! the current leaf becomes the next one
  566. ENDIF
  567. !
  568. ! use the array of the current leaf as a work array
  569. IF( PRESENT(kwrk1d) ) kwrk1d => tree(ii)%current%iwrk1d
  570. IF( PRESENT(kwrk2d) ) kwrk2d => tree(ii)%current%iwrk2d
  571. IF( PRESENT(kwrk3d) ) kwrk3d => tree(ii)%current%iwrk3d
  572. IF( PRESENT(kwrk4d) ) kwrk4d => tree(ii)%current%iwrk4d
  573. IF( PRESENT(pwrk1d) ) pwrk1d => tree(ii)%current%zwrk1d
  574. IF( PRESENT(pwrk2d) ) pwrk2d => tree(ii)%current%zwrk2d
  575. IF( PRESENT(pwrk3d) ) pwrk3d => tree(ii)%current%zwrk3d
  576. IF( PRESENT(pwrk4d) ) pwrk4d => tree(ii)%current%zwrk4d
  577. tree(ii)%current%in_use = .TRUE. ! this leaf is now used
  578. !
  579. END SUBROUTINE wrk_allocbase
  580. SUBROUTINE wrk_deallocbase( ktype, kidim, kjdim, kkdim, kldim, kisrt, kjsrt, kksrt, klsrt )
  581. INTEGER, INTENT(in ) :: ktype
  582. INTEGER, INTENT(in ) :: kidim, kjdim, kkdim, kldim
  583. INTEGER, INTENT(in ), OPTIONAL :: kisrt, kjsrt, kksrt, klsrt
  584. !
  585. INTEGER, DIMENSION(jpmaxdim) :: ishape, istart
  586. INTEGER :: ii
  587. ishape(:) = (/ kidim, kjdim, kkdim, kldim /)
  588. IF( PRESENT(kisrt) ) THEN ; istart(1) = kisrt ; ELSE ; istart(1) = 1 ; ENDIF
  589. IF( PRESENT(kjsrt) ) THEN ; istart(2) = kjsrt ; ELSE ; istart(2) = 1 ; ENDIF
  590. IF( PRESENT(kksrt) ) THEN ; istart(3) = kksrt ; ELSE ; istart(3) = 1 ; ENDIF
  591. IF( PRESENT(klsrt) ) THEN ; istart(4) = klsrt ; ELSE ; istart(4) = 1 ; ENDIF
  592. ! find the branch with the matcing shape and type or get the first "free" branch
  593. ii = 1
  594. DO WHILE( ANY( tree(ii)%ishape /= ishape ) .OR. ANY( tree(ii)%istart /= istart ) .OR. tree(ii)%itype /= ktype )
  595. ii = ii + 1
  596. END DO
  597. !
  598. tree(ii)%current%in_use = .FALSE. ! current leaf is no more used
  599. tree(ii)%current => tree(ii)%current%prev ! move back toward previous leaf
  600. !
  601. END SUBROUTINE wrk_deallocbase
  602. SUBROUTINE wrk_stop(cmsg)
  603. !!----------------------------------------------------------------------
  604. !! *** ROUTINE wrk_stop ***
  605. !! ** Purpose : to act as local alternative to ctl_stop.
  606. !! Avoids dependency on in_out_manager module.
  607. !!----------------------------------------------------------------------
  608. CHARACTER(LEN=*), INTENT(in) :: cmsg
  609. !!----------------------------------------------------------------------
  610. !
  611. ! WRITE(kumout, cform_err2)
  612. WRITE(*,*) TRIM(cmsg)
  613. ! ARPDBG - would like to CALL mppstop here to force a stop but that
  614. ! introduces a dependency on lib_mpp. Could CALL mpi_abort() directly
  615. ! but that's fairly brutal. Better to rely on CALLing routine to
  616. ! deal with the error passed back from the wrk_X routine?
  617. !CALL mppstop
  618. !
  619. END SUBROUTINE wrk_stop
  620. !!=====================================================================
  621. END MODULE wrk_nemo