obs_surf_def.F90 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. MODULE obs_surf_def
  2. !!=====================================================================
  3. !! *** MODULE obs_surf_def ***
  4. !! Observation diagnostics: Storage handling for surface observation
  5. !! arrays and additional flags etc.
  6. !! This module only defines the data type and
  7. !! operations on the data type. There is no
  8. !! actual data in the module.
  9. !!=====================================================================
  10. !!----------------------------------------------------------------------
  11. !! obs_surf : F90 type containing the surface information
  12. !! obs_surf_alloc : Allocates surface data arrays
  13. !! obs_surf_dealloc : Deallocates surface data arrays
  14. !! obs_surf_compress : Extract sub-information from a obs_surf type
  15. !! to a new obs_surf type
  16. !! obs_surf_decompress : Reinsert sub-information from a obs_surf type
  17. !! into the original obs_surf type
  18. !!----------------------------------------------------------------------
  19. !! * Modules used
  20. USE par_kind, ONLY : & ! Precision variables
  21. & wp
  22. USE obs_mpp, ONLY : & ! MPP tools
  23. obs_mpp_sum_integer
  24. IMPLICIT NONE
  25. !! * Routine/type accessibility
  26. PRIVATE
  27. PUBLIC &
  28. & obs_surf, &
  29. & obs_surf_alloc, &
  30. & obs_surf_dealloc, &
  31. & obs_surf_compress, &
  32. & obs_surf_decompress
  33. !! * Type definition for surface observation type
  34. TYPE obs_surf
  35. ! Bookkeeping
  36. INTEGER :: nsurf !: Local number of surface data within window
  37. INTEGER :: nsurfmpp !: Global number of surface data within window
  38. INTEGER :: nvar !: Number of variables at observation points
  39. INTEGER :: nextra !: Number of extra fields at observation points
  40. INTEGER :: nstp !: Number of time steps
  41. INTEGER :: npi !: Number of 3D grid points
  42. INTEGER :: npj
  43. INTEGER :: nsurfup !: Observation counter used in obs_oper
  44. ! Arrays with size equal to the number of surface observations
  45. INTEGER, POINTER, DIMENSION(:) :: &
  46. & mi, & !: i-th grid coord. for interpolating to surface observation
  47. & mj, & !: j-th grid coord. for interpolating to surface observation
  48. & nsidx,& !: Surface observation number
  49. & nsfil,& !: Surface observation number in file
  50. & nyea, & !: Year of surface observation
  51. & nmon, & !: Month of surface observation
  52. & nday, & !: Day of surface observation
  53. & nhou, & !: Hour of surface observation
  54. & nmin, & !: Minute of surface observation
  55. & mstp, & !: Time step nearest to surface observation
  56. & nqc, & !: Surface observation qc flag
  57. & ntyp !: Type of surface observation product
  58. CHARACTER(LEN=8), POINTER, DIMENSION(:) :: &
  59. & cwmo !: WMO indentifier
  60. REAL(KIND=wp), POINTER, DIMENSION(:) :: &
  61. & rlam, & !: Longitude coordinate of surface observation
  62. & rphi !: Latitude coordinate of surface observation
  63. REAL(KIND=wp), POINTER, DIMENSION(:,:) :: &
  64. & robs, & !: Surface observation
  65. & rmod !: Model counterpart of the surface observation vector
  66. REAL(KIND=wp), POINTER, DIMENSION(:,:) :: &
  67. & rext !: Extra fields interpolated to observation points
  68. REAL(KIND=wp), POINTER, DIMENSION(:,:) :: &
  69. & vdmean !: Time averaged of model field
  70. ! Arrays with size equal to the number of time steps in the window
  71. INTEGER, POINTER, DIMENSION(:) :: &
  72. & nsstp, & !: Local number of surface observations per time step
  73. & nsstpmpp !: Global number of surface observations per time step
  74. ! Arrays used to store source indices when
  75. ! compressing obs_surf derived types
  76. ! Array with size nsurf
  77. INTEGER, POINTER, DIMENSION(:) :: &
  78. & nsind !: Source indices of surface data in compressed data
  79. END TYPE obs_surf
  80. !!----------------------------------------------------------------------
  81. !! NEMO/OPA 3.3 , NEMO Consortium (2010)
  82. !! $Id: obs_surf_def.F90 3651 2012-11-26 10:46:39Z cbricaud $
  83. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  84. !!----------------------------------------------------------------------
  85. CONTAINS
  86. SUBROUTINE obs_surf_alloc( surf, ksurf, kvar, kextra, kstp, kpi, kpj )
  87. !!----------------------------------------------------------------------
  88. !! *** ROUTINE obs_surf_alloc ***
  89. !!
  90. !! ** Purpose : - Allocate data for surface data arrays
  91. !!
  92. !! ** Method : - Fortran-90 dynamic arrays
  93. !!
  94. !! History :
  95. !! ! 07-03 (K. Mogensen, A. Weaver, E. Remy, S. Ricci) original
  96. !!----------------------------------------------------------------------
  97. !! * Arguments
  98. TYPE(obs_surf), INTENT(INOUT) :: surf ! Surface data to be allocated
  99. INTEGER, INTENT(IN) :: ksurf ! Number of surface observations
  100. INTEGER, INTENT(IN) :: kvar ! Number of surface variables
  101. INTEGER, INTENT(IN) :: kextra ! Number of extra fields at observation points
  102. INTEGER, INTENT(IN) :: kstp ! Number of time steps
  103. INTEGER, INTENT(IN) :: kpi ! Number of 3D grid points
  104. INTEGER, INTENT(IN) :: kpj
  105. !!* Local variables
  106. INTEGER :: ji
  107. ! Set bookkeeping variables
  108. surf%nsurf = ksurf
  109. surf%nsurfmpp = 0
  110. surf%nextra = kextra
  111. surf%nvar = kvar
  112. surf%nstp = kstp
  113. surf%npi = kpi
  114. surf%npj = kpj
  115. ! Allocate arrays of number of surface data size
  116. ALLOCATE( &
  117. & surf%mi(ksurf), &
  118. & surf%mj(ksurf), &
  119. & surf%nsidx(ksurf), &
  120. & surf%nsfil(ksurf), &
  121. & surf%nyea(ksurf), &
  122. & surf%nmon(ksurf), &
  123. & surf%nday(ksurf), &
  124. & surf%nhou(ksurf), &
  125. & surf%nmin(ksurf), &
  126. & surf%mstp(ksurf), &
  127. & surf%nqc(ksurf), &
  128. & surf%ntyp(ksurf), &
  129. & surf%cwmo(ksurf), &
  130. & surf%rlam(ksurf), &
  131. & surf%rphi(ksurf), &
  132. & surf%nsind(ksurf) &
  133. & )
  134. ! Allocate arrays of number of surface data size * number of variables
  135. ALLOCATE( &
  136. & surf%robs(ksurf,kvar), &
  137. & surf%rmod(ksurf,kvar) &
  138. & )
  139. ! Allocate arrays of number of extra fields at observation points
  140. ALLOCATE( &
  141. & surf%rext(ksurf,kextra) &
  142. & )
  143. ! Allocate arrays of number of time step size
  144. ALLOCATE( &
  145. & surf%nsstp(kstp), &
  146. & surf%nsstpmpp(kstp) &
  147. & )
  148. ! Allocate arrays of size number of grid points
  149. ALLOCATE( &
  150. & surf%vdmean(kpi,kpj) &
  151. & )
  152. ! Set defaults for compression indices
  153. DO ji = 1, ksurf
  154. surf%nsind(ji) = ji
  155. END DO
  156. ! Set defaults for number of observations per time step
  157. surf%nsstp(:) = 0
  158. surf%nsstpmpp(:) = 0
  159. ! Set the observation counter used in obs_oper
  160. surf%nsurfup = 0
  161. END SUBROUTINE obs_surf_alloc
  162. SUBROUTINE obs_surf_dealloc( surf )
  163. !!----------------------------------------------------------------------
  164. !! *** ROUTINE obs_surf_dealloc ***
  165. !!
  166. !! ** Purpose : - Deallocate data for surface data arrays
  167. !!
  168. !! ** Method : - Fortran-90 dynamic arrays
  169. !!
  170. !! History :
  171. !! ! 07-03 (K. Mogensen, A. Weaver, E. Remy, S. Ricci) original
  172. !!----------------------------------------------------------------------
  173. !! * Arguments
  174. TYPE(obs_surf), INTENT(INOUT) :: &
  175. & surf ! Surface data to be allocated
  176. !!* Local variables
  177. ! Deallocate arrays of number of surface data size
  178. DEALLOCATE( &
  179. & surf%mi, &
  180. & surf%mj, &
  181. & surf%nsidx, &
  182. & surf%nsfil, &
  183. & surf%nyea, &
  184. & surf%nmon, &
  185. & surf%nday, &
  186. & surf%nhou, &
  187. & surf%nmin, &
  188. & surf%mstp, &
  189. & surf%nqc, &
  190. & surf%ntyp, &
  191. & surf%cwmo, &
  192. & surf%rlam, &
  193. & surf%rphi, &
  194. & surf%nsind &
  195. & )
  196. ! Allocate arrays of number of surface data size * number of variables
  197. DEALLOCATE( &
  198. & surf%robs, &
  199. & surf%rmod &
  200. & )
  201. ! Deallocate arrays of number of extra fields at observation points
  202. DEALLOCATE( &
  203. & surf%rext &
  204. & )
  205. ! Deallocate arrays of size number of grid points size times
  206. ! number of variables
  207. DEALLOCATE( &
  208. & surf%vdmean &
  209. & )
  210. ! Deallocate arrays of number of time step size
  211. DEALLOCATE( &
  212. & surf%nsstp, &
  213. & surf%nsstpmpp &
  214. & )
  215. END SUBROUTINE obs_surf_dealloc
  216. SUBROUTINE obs_surf_compress( surf, newsurf, lallocate, kumout, lvalid )
  217. !!----------------------------------------------------------------------
  218. !! *** ROUTINE obs_surf_compress ***
  219. !!
  220. !! ** Purpose : - Extract sub-information from a obs_surf type
  221. !! into a new obs_surf type
  222. !!
  223. !! ** Method : - The data is copied from surf to new surf.
  224. !! In the case of lvalid being present only the
  225. !! selected data will be copied.
  226. !! If lallocate is true the data in the newsurf is
  227. !! allocated either with the same number of elements
  228. !! as surf or with only the subset of elements defined
  229. !! by the optional selection.
  230. !!
  231. !! History :
  232. !! ! 07-03 (K. Mogensen, A. Weaver, E. Remy, S. Ricci) original
  233. !!----------------------------------------------------------------------
  234. !! * Arguments
  235. TYPE(obs_surf), INTENT(IN) :: surf ! Original surface data
  236. TYPE(obs_surf), INTENT(INOUT) :: newsurf ! New surface data with a subset of the original data
  237. LOGICAL :: lallocate ! Allocate newsurf data
  238. INTEGER,INTENT(IN) :: kumout ! Fortran unit for messages
  239. LOGICAL, OPTIONAL, INTENT(in), DIMENSION(:) :: &
  240. & lvalid ! Valid of surface observations
  241. !!* Local variables
  242. INTEGER :: insurf
  243. INTEGER :: ji
  244. INTEGER :: jk
  245. LOGICAL, DIMENSION(:), ALLOCATABLE :: llvalid
  246. ! Count how many elements there should be in the new data structure
  247. IF ( PRESENT(lvalid) ) THEN
  248. insurf = 0
  249. DO ji = 1, surf%nsurf
  250. IF ( lvalid(ji) ) THEN
  251. insurf = insurf + 1
  252. ENDIF
  253. END DO
  254. ELSE
  255. insurf = surf%nsurf
  256. ENDIF
  257. ! Optionally allocate data in the new data structure
  258. IF ( lallocate ) THEN
  259. CALL obs_surf_alloc( newsurf, insurf, surf%nvar, &
  260. & surf%nextra, surf%nstp, surf%npi, surf%npj )
  261. ENDIF
  262. ! Allocate temporary valid array to unify the code for both cases
  263. ALLOCATE( llvalid(surf%nsurf) )
  264. IF ( PRESENT(lvalid) ) THEN
  265. llvalid(:) = lvalid(:)
  266. ELSE
  267. llvalid(:) = .TRUE.
  268. ENDIF
  269. ! Setup bookkeeping variables
  270. insurf = 0
  271. ! Loop over source surface data
  272. DO ji = 1, surf%nsurf
  273. IF ( llvalid(ji) ) THEN
  274. ! Copy the header information
  275. insurf = insurf + 1
  276. newsurf%mi(insurf) = surf%mi(ji)
  277. newsurf%mj(insurf) = surf%mj(ji)
  278. newsurf%nsidx(insurf) = surf%nsidx(ji)
  279. newsurf%nsfil(insurf) = surf%nsfil(ji)
  280. newsurf%nyea(insurf) = surf%nyea(ji)
  281. newsurf%nmon(insurf) = surf%nmon(ji)
  282. newsurf%nday(insurf) = surf%nday(ji)
  283. newsurf%nhou(insurf) = surf%nhou(ji)
  284. newsurf%nmin(insurf) = surf%nmin(ji)
  285. newsurf%mstp(insurf) = surf%mstp(ji)
  286. newsurf%nqc(insurf) = surf%nqc(ji)
  287. newsurf%ntyp(insurf) = surf%ntyp(ji)
  288. newsurf%cwmo(insurf) = surf%cwmo(ji)
  289. newsurf%rlam(insurf) = surf%rlam(ji)
  290. newsurf%rphi(insurf) = surf%rphi(ji)
  291. DO jk = 1, surf%nvar
  292. newsurf%robs(insurf,jk) = surf%robs(ji,jk)
  293. newsurf%rmod(insurf,jk) = surf%rmod(ji,jk)
  294. END DO
  295. DO jk = 1, surf%nextra
  296. newsurf%rext(insurf,jk) = surf%rext(ji,jk)
  297. END DO
  298. ! nsind is the index of the original surface data
  299. newsurf%nsind(insurf) = ji
  300. ENDIF
  301. END DO
  302. ! Update MPP counters
  303. newsurf%nsurf = insurf
  304. CALL obs_mpp_sum_integer ( newsurf%nsurf, newsurf%nsurfmpp )
  305. ! Set book keeping variables which do not depend on number of obs.
  306. newsurf%nstp = surf%nstp
  307. ! Deallocate temporary data
  308. DEALLOCATE( llvalid )
  309. END SUBROUTINE obs_surf_compress
  310. SUBROUTINE obs_surf_decompress( surf, oldsurf, ldeallocate, kumout )
  311. !!----------------------------------------------------------------------
  312. !! *** ROUTINE obs_surf_decompress ***
  313. !!
  314. !! ** Purpose : - Copy back information to original surface data type
  315. !!
  316. !! ** Method : - Reinsert updated information from a previous
  317. !! copied/compressed surface data type into the original
  318. !! surface data and optionally deallocate the surface
  319. !! data input
  320. !!
  321. !! History :
  322. !! ! 07-03 (K. Mogensen, A. Weaver, E. Remy, S. Ricci) original
  323. !!----------------------------------------------------------------------
  324. !! * Arguments
  325. TYPE(obs_surf),INTENT(INOUT) :: surf ! Updated surface data
  326. TYPE(obs_surf),INTENT(INOUT) :: oldsurf ! Original surface data
  327. LOGICAL :: ldeallocate ! Deallocate the updated data of insertion
  328. INTEGER,INTENT(in) :: kumout ! Output unit
  329. !!* Local variables
  330. INTEGER :: ji
  331. INTEGER :: jj
  332. INTEGER :: jk
  333. ! Copy data from surf to old surf
  334. DO ji = 1, surf%nsurf
  335. jj=surf%nsind(ji)
  336. oldsurf%mi(jj) = surf%mi(ji)
  337. oldsurf%mj(jj) = surf%mj(ji)
  338. oldsurf%nsidx(jj) = surf%nsidx(ji)
  339. oldsurf%nsfil(jj) = surf%nsfil(ji)
  340. oldsurf%nyea(jj) = surf%nyea(ji)
  341. oldsurf%nmon(jj) = surf%nmon(ji)
  342. oldsurf%nday(jj) = surf%nday(ji)
  343. oldsurf%nhou(jj) = surf%nhou(ji)
  344. oldsurf%nmin(jj) = surf%nmin(ji)
  345. oldsurf%mstp(jj) = surf%mstp(ji)
  346. oldsurf%nqc(jj) = surf%nqc(ji)
  347. oldsurf%ntyp(jj) = surf%ntyp(ji)
  348. oldsurf%cwmo(jj) = surf%cwmo(ji)
  349. oldsurf%rlam(jj) = surf%rlam(ji)
  350. oldsurf%rphi(jj) = surf%rphi(ji)
  351. END DO
  352. DO jk = 1, surf%nvar
  353. DO ji = 1, surf%nsurf
  354. jj=surf%nsind(ji)
  355. oldsurf%robs(jj,jk) = surf%robs(ji,jk)
  356. oldsurf%rmod(jj,jk) = surf%rmod(ji,jk)
  357. END DO
  358. END DO
  359. DO jk = 1, surf%nextra
  360. DO ji = 1, surf%nsurf
  361. jj=surf%nsind(ji)
  362. oldsurf%rext(jj,jk) = surf%rext(ji,jk)
  363. END DO
  364. END DO
  365. ! Optionally deallocate the updated surface data
  366. IF ( ldeallocate ) CALL obs_surf_dealloc( surf )
  367. END SUBROUTINE obs_surf_decompress
  368. END MODULE obs_surf_def