fracnnei.f 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. subroutine fracnnei (src_size, dst_size,
  2. $ ld_srcmask, ld_dstmask,
  3. $ src_lon, src_lat, dst_lon, dst_lat,
  4. $ num_links, num_wgts, num_neigh, lnnei,
  5. $ weights_temp, src_addr_temp, dst_addr_temp,
  6. $ weights, src_addr, dst_addr)
  7. C****
  8. C *****************************
  9. C * OASIS ROUTINE - LEVEL 4 *
  10. C * ------------- ------- *
  11. C *****************************
  12. C
  13. C**** *fracnnei* - SCRIP remapping
  14. C
  15. C Purpose:
  16. C -------
  17. C Treatment of the tricky points in an interpolation
  18. C
  19. C Interface:
  20. C ---------
  21. C *CALL* *
  22. C
  23. C Called from:
  24. C -----------
  25. C scriprmp
  26. C
  27. C Input:
  28. C -----
  29. C src_size : source grid size (integer)
  30. C dst_size : target grid size (integer)
  31. C ld_srcmask : mask of the source grid
  32. C ld_dstmask : mask of the target grid
  33. C src_lon : longitudes of the source grid
  34. C src_lat : latitudes of the source grid
  35. C dst_lon : longitudes of the target grid
  36. C dst_lat : latitudes of the target grid
  37. C num_links : total number of links
  38. C num_wgts : number of weights for each link
  39. C InOut
  40. C -----
  41. C weights : remapping weights
  42. C src_addr : remapping source addresses
  43. C dst_addr : remapping target addresses
  44. C
  45. C History:
  46. C -------
  47. C Version Programmer Date Description
  48. C ------- ---------- ---- -----------
  49. C 2.5 D.Declat 2002/08/20 adapted from S. Valcke ptmsq
  50. C 3.0 S. Valcke 2002/10/30 test and corrections
  51. C
  52. C %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  53. C* ---------------------------- Modules used ----------------------------
  54. C
  55. use kinds_mod ! defines common data types
  56. use constants ! defines common constants
  57. use grids ! module containing grid information
  58. use remap_vars ! module containing remap information
  59. USE mod_oasis_flush
  60. C
  61. C* ---------------------------- Implicit --------------------------------
  62. C
  63. implicit none
  64. C
  65. C* ---------------------------- Include files ---------------------------
  66. C
  67. C INCLUDE 'netcdf.inc'
  68. C
  69. C* ---------------------------- Intent In -------------------------------
  70. C
  71. INTEGER (kind=int_kind) ::
  72. $ src_size, ! size of the source grid
  73. $ dst_size ! size of the destination grid
  74. C
  75. REAL (kind=dbl_kind) ::
  76. $ src_lat(src_size), src_lon(src_size),
  77. $ dst_lat(dst_size), dst_lon(dst_size)
  78. C
  79. LOGICAL ::
  80. $ ld_srcmask(src_size), ! source grid mask
  81. $ ld_dstmask(dst_size) ! target grid mask
  82. C
  83. INTEGER (kind=int_kind) ::
  84. $ num_links, ! number of links between src and tgt
  85. $ num_wgts, ! number of weights
  86. $ num_neigh ! number of Vmm points
  87. logical (kind=log_kind) ::
  88. $ lnnei(dst_size) ! flag for tricky points
  89. REAL (kind=dbl_kind) ::
  90. $ weights_temp(num_wgts, num_links) ! oldsize remapping weights
  91. C
  92. INTEGER (kind=int_kind) ::
  93. $ src_addr_temp(num_links), ! oldsize remapping source addresses
  94. $ dst_addr_temp(num_links) ! oldsize remapping target addresses
  95. C
  96. C* ---------------------------- Intent Out ------------------------------
  97. C
  98. REAL (kind=dbl_kind) ::
  99. $ weights(num_wgts, num_links+num_neigh ) ! remapping weights
  100. C
  101. INTEGER (kind=int_kind) ::
  102. $ src_addr(num_links+num_neigh), ! remapping source addresses
  103. $ dst_addr(num_links+num_neigh) ! remapping target addresses
  104. C
  105. C* ---------------------------- Local declarations ----------------------
  106. C
  107. C
  108. C
  109. INTEGER (kind=int_kind) ::
  110. $ ila_nneiadd ! Nearest-neighbor address
  111. C
  112. INTEGER (kind=int_kind) ::
  113. $ ib_dst, ! INDEX loop for the distance grid
  114. $ ib_src, ! INDEX loop for the source grid
  115. $ ib_links ! INDEX loop for the links
  116. C
  117. REAL (kind=dbl_kind) ::
  118. $ coslat, ! cosinus of the latitude
  119. $ sinlat, ! sinus of the latitude
  120. $ coslon, ! cosinus of the longitude
  121. $ sinlon, ! sinus of the longitude
  122. $ distance,
  123. $ dist_min,
  124. $ arg
  125. C
  126. INTEGER (kind=int_kind) :: n, il
  127. C
  128. INTEGER (kind=int_kind) :: counter_Vmm
  129. C
  130. C* ---------------------------- Poema verses ----------------------------
  131. C
  132. C %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  133. C
  134. C* 1. Initialization
  135. C --------------
  136. C
  137. IF (nlogprt .GE. 2) THEN
  138. WRITE (UNIT = nulou,FMT = *) ' '
  139. WRITE (UNIT = nulou,FMT = *) ' '
  140. WRITE (UNIT = nulou,FMT = *)
  141. $ ' Entering ROUTINE fracnnei - Level 4'
  142. WRITE (UNIT = nulou,FMT = *)
  143. $ ' **************** *******'
  144. WRITE (UNIT = nulou,FMT = *) ' '
  145. WRITE (UNIT = nulou,FMT = *)
  146. $ ' Treating the tricky points of the remapping'
  147. WRITE (UNIT = nulou,FMT = *) ' '
  148. CALL FLUSH(nulou)
  149. ENDIF
  150. C
  151. C *----------------------------------------------------------------------
  152. C
  153. C* 2. Treating Vmm points V
  154. C ------------------- m m
  155. C The target point is a non-masked Valid point while the source points
  156. C are all masked points. Use of the non-masked nearest neighbours.
  157. C
  158. C -- store the weights, src_addr, dst_addr from temporary array
  159. weights(1:num_wgts,1:num_links) =
  160. $ weights_temp(1:num_wgts,1:num_links)
  161. src_addr(1:num_links) = src_addr_temp(1:num_links)
  162. dst_addr(1:num_links) = dst_addr_temp(1:num_links)
  163. C* -- Find the nearest neighbours and store weights and address
  164. counter_Vmm = 0
  165. DO ib_dst = 1, dst_size
  166. IF ( lnnei(ib_dst) .eqv. .true. ) THEN
  167. counter_Vmm = counter_Vmm+1
  168. dst_addr(num_links+counter_Vmm) = ib_dst
  169. IF (nlogprt .GE. 2) THEN
  170. write(nulou,*) 'ib_dst for true=',ib_dst
  171. write(nulou,*) 'counter_Vmm =',counter_Vmm
  172. write(nulou,*) 'num_links+counter_Vmm =',
  173. $ num_links+counter_Vmm
  174. write(nulou,*) 'dst_addr =',dst_addr(num_links+counter_Vmm)
  175. ENDIF
  176. coslat = cos(dst_lat(ib_dst))
  177. sinlat = sin(dst_lat(ib_dst))
  178. coslon = cos(dst_lon(ib_dst))
  179. sinlon = sin(dst_lon(ib_dst))
  180. dist_min = bignum
  181. ila_nneiadd = 0
  182. DO ib_src = 1, src_size
  183. IF (ld_srcmask(ib_src)) THEN
  184. arg =
  185. & coslat*cos(src_lat(ib_src))*
  186. & (coslon*cos(src_lon(ib_src)) +
  187. & sinlon*sin(src_lon(ib_src)))+
  188. & sinlat*sin(src_lat(ib_src))
  189. IF (arg < -1.0d0) THEN
  190. arg = -1.0d0
  191. ELSE IF (arg > 1.0d0) THEN
  192. arg = 1.0d0
  193. END IF
  194. distance = acos(arg)
  195. IF (distance < dist_min) THEN
  196. ila_nneiadd = ib_src
  197. dist_min = distance
  198. ENDIF
  199. ENDIF
  200. END DO
  201. src_addr(num_links+counter_Vmm) = ila_nneiadd
  202. weights(1,num_links+counter_Vmm) = 1.0
  203. IF (nlogprt .GE. 2) THEN
  204. write(nulou,*) 'src_addr =',src_addr(num_links+counter_Vmm)
  205. WRITE(nulou,*)
  206. $ '*************** Nearest source neighbour is ',
  207. $ ila_nneiadd
  208. ENDIF
  209. ENDIF
  210. END DO
  211. C
  212. C
  213. C *----------------------------------------------------------------------
  214. C
  215. IF (nlogprt .GE. 2) THEN
  216. WRITE (UNIT = nulou,FMT = *) ' '
  217. WRITE (UNIT = nulou,FMT = *)
  218. $ ' Leaving ROUTINE fracnnei - Level 4'
  219. WRITE (UNIT = nulou,FMT = *) ' '
  220. CALL FLUSH(nulou)
  221. ENDIF
  222. END SUBROUTINE fracnnei
  223. !***********************************************************************