PageRenderTime 50ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 1ms

/wrfv2_fire/dyn_nmm/NMM_NEST_UTILS1.F

http://github.com/jbeezley/wrf-fire
FORTRAN Legacy | 3802 lines | 2481 code | 422 blank | 899 comment | 16 complexity | 9b1eb832c545956ed2b6043efc59e2ba MD5 | raw file
Possible License(s): AGPL-1.0

Large files files are truncated, but you can click here to view the full file

  1. #if (NMM_NEST == 1)
  2. !===========================================================================
  3. !
  4. ! E-GRID NESTING UTILITIES: This is gopal's doing
  5. !
  6. !===========================================================================
  7. SUBROUTINE med_nest_egrid_configure ( parent , nest )
  8. USE module_domain
  9. USE module_configure
  10. USE module_timing
  11. IMPLICIT NONE
  12. TYPE(domain) , POINTER :: parent , nest
  13. REAL, PARAMETER :: ERAD=6371200.
  14. REAL, PARAMETER :: DTR=0.01745329
  15. REAL, PARAMETER :: DTAD=1.0
  16. REAL, PARAMETER :: CP=1004.6
  17. INTEGER :: IDS,IDE,JDS,JDE,KDS,KDE
  18. INTEGER :: IMS,IME,JMS,JME,KMS,KME
  19. INTEGER :: ITS,ITE,JTS,JTE,KTS,KTE
  20. CHARACTER(LEN=255) :: message
  21. !----------------------------------------------------------------------------
  22. ! PURPOSE:
  23. ! - Initialize nested domain configurations including setting up
  24. ! wbd,sbd and some other variables and 1D arrays.
  25. ! - Note that in order to obtain coincident grid points, which
  26. ! is a basic requirement for RSL, WRF infrastructure, we use
  27. ! western and southern boundaries of nested domain (nest%wbd0
  28. ! and nest%sbd0 derived from the parent domain. In this case
  29. ! the nested domain may be considered as a part of the parent
  30. ! domain with a higher resolution (telescoping ?).
  31. ! - Also note that in this case, the central lat/lons for nested
  32. ! domain should coincide with the central lat/lons of the parent,
  33. ! although the nested domain NEED NOT be located at the center of
  34. ! the domain.
  35. !----------------------------------------------------------------------------
  36. !
  37. ! BASIC TEST FOR PARENT DOMAIN: CHECK IF JMAX IS ODD. SINCE JDE IN THE NAMELIST
  38. ! IS JMAX + 1, WE NEED TO CHECK IF JDE IS EVEN IN WRF CONTEXT
  39. IF(MOD(parent%ed32,2) .NE. 0)THEN
  40. CALL wrf_error_fatal("PARENT DOMAIN: JMAX IS EVEN, INCREASE e_sn IN THE namelist.input BY 1")
  41. ENDIF
  42. ! BASIC TEST FOR NESTED DOMAIN: CHECK IF JMAX IS ODD. SINCE JDE IN THE NAMELIST
  43. ! IS JMAX + 1, WE NEED TO CHECK IF JDE IS EVEN IN WRF CONTEXT
  44. IF(MOD(nest%ed32,2) .NE. 0)THEN
  45. CALL wrf_error_fatal("NESTED DOMAIN: JMAX IS EVEN, INCREASE e_sn IN THE namelist.input BY 1")
  46. ENDIF
  47. ! Parent grid configuration, including, western and southern boundary
  48. IDS = parent%sd31
  49. IDE = parent%ed31
  50. JDS = parent%sd32
  51. JDE = parent%ed32
  52. KDS = parent%sd33
  53. KDE = parent%ed33
  54. IMS = parent%sm31
  55. IME = parent%em31
  56. JMS = parent%sm32
  57. JME = parent%em32
  58. KMS = parent%sm33
  59. KME = parent%em33
  60. ITS = parent%sp31
  61. ITE = parent%ep31
  62. JTS = parent%sp32
  63. JTE = parent%ep32
  64. KTS = parent%sp33
  65. KTE = parent%ep33
  66. ! grid configuration
  67. ! calculate wbd0 and sbd0 only for MOAD i.e. grid with parent_id == 0
  68. if (parent%parent_id == 0 ) then ! Dusan's doing
  69. parent%wbd0 = -(IDE-2)*parent%dx ! WBD0: in degrees;factor 2 takes care of dummy last column
  70. parent%sbd0 = -((JDE-1)/2)*parent%dy ! SBD0: in degrees; note that JDE-1 should be odd
  71. end if
  72. nest%wbd0 = parent%wbd0 + (nest%i_parent_start-1)*2.*parent%dx + mod(nest%j_parent_start+1,2)*parent%dx
  73. nest%sbd0 = parent%sbd0 + (nest%j_parent_start-1)*parent%dy
  74. nest%dx = parent%dx/nest%parent_grid_ratio
  75. nest%dy = parent%dy/nest%parent_grid_ratio
  76. write(message,*)" - i_parent_start = ",nest%i_parent_start
  77. CALL wrf_message(trim(message))
  78. write(message,*)" - j_parent_start = ",nest%j_parent_start
  79. CALL wrf_message(trim(message))
  80. write(message,*)" - parent%wbd0 = ",parent%wbd0
  81. CALL wrf_message(trim(message))
  82. write(message,*)" - parent%sbd0 = ",parent%sbd0
  83. CALL wrf_message(trim(message))
  84. write(message,*)" - nest%wbd0 = ",nest%wbd0
  85. CALL wrf_message(trim(message))
  86. write(message,*)" - nest%sbd0 = ",nest%sbd0
  87. CALL wrf_message(trim(message))
  88. write(message,*)" - nest%dx = ",nest%dx
  89. CALL wrf_message(trim(message))
  90. write(message,*)" - nest%dy = ",nest%dy
  91. CALL wrf_message(trim(message))
  92. !
  93. CALL nl_set_dx (nest%id , nest%dx) ! for output purpose
  94. CALL nl_set_dy (nest%id , nest%dy) ! for output purpose
  95. ! set lat-lons; parent set to nested domain
  96. CALL nl_get_cen_lat (parent%id, parent%cen_lat) ! cen_lat of parent set to nested domain
  97. CALL nl_get_cen_lon (parent%id, parent%cen_lon) ! cen_lon of parent set to nested domain
  98. nest%cen_lat=parent%cen_lat
  99. nest%cen_lon=parent%cen_lon
  100. !
  101. CALL nl_set_cen_lat ( nest%id , nest%cen_lat) ! for output purpose
  102. CALL nl_set_cen_lon ( nest%id , nest%cen_lon) ! for output purpose
  103. write(message,*)" - nest%cen_lat = ",nest%cen_lat
  104. CALL wrf_message(trim(message))
  105. write(message,*)" - nest%cen_lon = ",nest%cen_lon
  106. CALL wrf_message(trim(message))
  107. ! soil configuration
  108. #ifdef HWRF
  109. !zhang
  110. if ( .not.nest%analysis ) then
  111. #endif
  112. nest%sldpth = parent%sldpth
  113. nest%dzsoil = parent%dzsoil
  114. nest%rtdpth = parent%rtdpth
  115. #ifdef HWRF
  116. endif
  117. #endif
  118. ! numerical set up
  119. nest%deta = parent%deta
  120. nest%aeta = parent%aeta
  121. nest%etax = parent%etax
  122. nest%dfl = parent%dfl
  123. nest%deta1 = parent%deta1
  124. nest%aeta1 = parent%aeta1
  125. nest%eta1 = parent%eta1
  126. nest%deta2 = parent%deta2
  127. nest%aeta2 = parent%aeta2
  128. nest%eta2 = parent%eta2
  129. nest%pdtop = parent%pdtop
  130. nest%pt = parent%pt
  131. nest%dfrlg = parent%dfrlg
  132. nest%num_soil_layers = parent%num_soil_layers
  133. nest%num_moves = parent%num_moves
  134. ! Unfortunately, some of the single value constants in used in module_initialize have
  135. ! to be defiend here instead of the usual spot in med_initialize_nest_nmm. There
  136. ! appears to be a problem in Registry and related code in this area.
  137. !
  138. ! state logical upstrm - dyn_nmm - - -
  139. nest%dlmd = nest%dx
  140. nest%dphd = nest%dy
  141. nest%dy_nmm = erad*(nest%dphd*dtr)
  142. nest%cpgfv = -nest%dt/(48.*nest%dy_nmm)
  143. nest%en = nest%dt/( 4.*nest%dy_nmm)*dtad
  144. nest%ent = nest%dt/(16.*nest%dy_nmm)*dtad
  145. nest%f4d = -.5*nest%dt*dtad
  146. nest%f4q = -nest%dt*dtad
  147. nest%ef4t = .5*nest%dt/cp
  148. ! Other output configurations that will make grads happy
  149. CALL nl_get_truelat1 (parent%id, parent%truelat1 )
  150. CALL nl_get_truelat2 (parent%id, parent%truelat2 )
  151. #ifdef HWRF
  152. ! bao : to make the restart output identical at the restart initial time for stand_lon
  153. CALL nl_get_stand_lon (parent%id, parent%stand_lon )
  154. #endif
  155. CALL nl_get_map_proj (parent%id, parent%map_proj )
  156. CALL nl_get_iswater (parent%id, parent%iswater )
  157. nest%truelat1=parent%truelat1
  158. nest%truelat2=parent%truelat2
  159. !bao
  160. nest%stand_lon=parent%stand_lon
  161. !bao
  162. nest%map_proj=parent%map_proj
  163. nest%iswater=parent%iswater
  164. CALL nl_set_truelat1(nest%id, nest%truelat1)
  165. CALL nl_set_truelat2(nest%id, nest%truelat2)
  166. !bao
  167. CALL nl_set_stand_lon(nest%id, nest%stand_lon)
  168. !bao
  169. CALL nl_set_map_proj(nest%id, nest%map_proj)
  170. CALL nl_set_iswater(nest%id, nest%iswater)
  171. ! physics and other configurations
  172. ! CALL nl_get_iswater (parent%id, nest%iswater) ! iswater is just based on parents
  173. ! CALL nl_get_bl_surface_physics (nest%id, nest%bl_surface_physics )
  174. ! CALL nl_get_num_soil_layers( parent%num_soil_layers )
  175. ! CALL nl_get_real_data_init_type (parent%real_data_init_type)
  176. END SUBROUTINE med_nest_egrid_configure
  177. SUBROUTINE med_construct_egrid_weights ( parent , nest )
  178. USE module_domain
  179. USE module_configure
  180. USE module_timing
  181. IMPLICIT NONE
  182. TYPE(domain) , POINTER :: parent , nest
  183. LOGICAL, EXTERNAL :: wrf_dm_on_monitor
  184. INTEGER :: IDS,IDE,JDS,JDE,KDS,KDE
  185. INTEGER :: IMS,IME,JMS,JME,KMS,KME
  186. INTEGER :: ITS,ITE,JTS,JTE,KTS,KTE
  187. INTEGER :: I,J,II,JJ,NII,NJJ
  188. REAL :: parent_CLAT,parent_CLON,parent_WBD,parent_SBD,parent_DLMD,parent_DPHD
  189. REAL :: nest_WBD,nest_SBD,nest_DLMD,nest_DPHD
  190. REAL :: SW_LATD,SW_LOND
  191. REAL :: ADDSUM1,ADDSUM2
  192. REAL :: xr,zr,xc
  193. !-----------------------------------------------------------------------------------------------------------
  194. ! PURPOSE:
  195. ! - Initialize lat-lons and determine weights
  196. !
  197. !----------------------------------------------------------------------------------------------------------
  198. ! First obtain central latitude and longitude for the parent domain
  199. CALL nl_get_cen_lat (parent%ID, parent_CLAT)
  200. CALL nl_get_cen_lon (parent%ID, parent_CLON)
  201. ! Parent grid configuration, including, western and southern boundary
  202. IDS = parent%sd31
  203. IDE = parent%ed31
  204. JDS = parent%sd32
  205. JDE = parent%ed32
  206. KDS = parent%sd33
  207. KDE = parent%ed33
  208. IMS = parent%sm31
  209. IME = parent%em31
  210. JMS = parent%sm32
  211. JME = parent%em32
  212. KMS = parent%sm33
  213. KME = parent%em33
  214. ITS = parent%sp31
  215. ITE = parent%ep31
  216. JTS = parent%sp32
  217. JTE = parent%ep32
  218. KTS = parent%sp33
  219. KTE = parent%ep33
  220. !
  221. parent_DLMD = parent%dx ! DLMD: dlamda in degrees
  222. parent_DPHD = parent%dy ! DPHD: dphi in degrees
  223. parent_WBD = parent%wbd0
  224. parent_SBD = parent%sbd0
  225. ! Now compute Geodetic lat/lon (Positive East) of parent grid in degrees
  226. CALL EARTH_LATLON ( parent%HLAT,parent%HLON,parent%VLAT,parent%VLON, & !output
  227. parent_DLMD,parent_DPHD,parent_WBD,parent_SBD, & !inputs
  228. parent_CLAT,parent_CLON, &
  229. IDS,IDE,JDS,JDE,KDS,KDE, &
  230. IMS,IME,JMS,JME,KMS,KME, &
  231. ITS,ITE,JTS,JTE,KTS,KTE )
  232. ! Nested grid configuration, including, western and southern boundary
  233. IDS = nest%sd31
  234. IDE = nest%ed31
  235. JDS = nest%sd32
  236. JDE = nest%ed32
  237. KDS = nest%sd33
  238. KDE = nest%ed33
  239. IMS = nest%sm31
  240. IME = nest%em31
  241. JMS = nest%sm32
  242. JME = nest%em32
  243. KMS = nest%sm33
  244. KME = nest%em33
  245. ITS = nest%sp31
  246. ITE = nest%ep31
  247. JTS = nest%sp32
  248. JTE = nest%ep32
  249. KTS = nest%sp33
  250. KTE = nest%ep33
  251. !
  252. nest_DLMD = nest%dx
  253. nest_DPHD = nest%dy
  254. nest_WBD = nest%wbd0
  255. nest_SBD = nest%sbd0
  256. !
  257. ! Now compute Geodetic lat/lon (Positive East) of nest in degrees, with the same central lat-lon
  258. ! as the parent grid
  259. !
  260. CALL EARTH_LATLON ( nest%HLAT,nest%HLON,nest%VLAT,nest%VLON, & ! output
  261. nest_DLMD,nest_DPHD,nest_WBD,nest_SBD, & ! nest inputs
  262. parent_CLAT,parent_CLON, & ! parent central lat/lon
  263. IDS,IDE,JDS,JDE,KDS,KDE, & ! nested domain dimension
  264. IMS,IME,JMS,JME,KMS,KME, &
  265. ITS,ITE,JTS,JTE,KTS,KTE )
  266. ! Determine the weights of nested grid h points nearest to H points of parent domain
  267. if(nest%vortex_tracker /= 1) then
  268. CALL G2T2H_new( nest%IIH,nest%JJH, & ! output grid index in parent grid
  269. nest%HBWGT1,nest%HBWGT2, & ! output weights in terms of parent grid
  270. nest%HBWGT3,nest%HBWGT4, &
  271. nest%I_PARENT_START,nest%J_PARENT_START, & ! nest start I, J in parent domain
  272. 3, & ! Ratio of parent and child grid ( always = 3 for NMM)
  273. IDS,IDE,JDS,JDE,KDS,KDE, & ! target (nest) dimensions
  274. IMS,IME,JMS,JME,KMS,KME, &
  275. ITS,ITE,JTS,JTE,KTS,KTE )
  276. else
  277. CALL G2T2H( nest%IIH,nest%JJH, & ! output grid index on nested grid
  278. nest%HBWGT1,nest%HBWGT2, & ! output weights on the nested grid
  279. nest%HBWGT3,nest%HBWGT4, &
  280. nest%HLAT,nest%HLON, & ! target (nest) input lat lon in degrees
  281. parent_DLMD,parent_DPHD,parent_WBD,parent_SBD, & ! parent res, western and south boundaries
  282. parent_CLAT,parent_CLON, & ! parent central lat,lon, all in degrees
  283. parent%ed31,parent%ed32, & ! parent imax and jmax
  284. IDS,IDE,JDS,JDE,KDS,KDE, & !
  285. IMS,IME,JMS,JME,KMS,KME, & ! nested grid configuration
  286. ITS,ITE,JTS,JTE,KTS,KTE ) !
  287. endif
  288. ! Determine the weights of nested grid v points nearest to V points of parent domain
  289. if(nest%vortex_tracker /= 1) then
  290. CALL G2T2V_new( nest%IIV,nest%JJV, & ! output grid index in parent grid
  291. nest%VBWGT1,nest%VBWGT2, & ! output weights in terms of parent grid
  292. nest%VBWGT3,nest%VBWGT4, &
  293. nest%I_PARENT_START,nest%J_PARENT_START, & ! nest start I, J in parent domain
  294. 3, & ! Ratio of parent and child grid ( always = 3 for NMM)
  295. IDS,IDE,JDS,JDE,KDS,KDE, & ! target (nest) dimensions
  296. IMS,IME,JMS,JME,KMS,KME, &
  297. ITS,ITE,JTS,JTE,KTS,KTE )
  298. else
  299. CALL G2T2V( nest%IIV,nest%JJV, & ! output grid index on nested grid
  300. nest%VBWGT1,nest%VBWGT2, & ! output weights on the nested grid
  301. nest%VBWGT3,nest%VBWGT4, &
  302. nest%VLAT,nest%VLON, & ! target (nest) input lat lon in degrees
  303. parent_DLMD,parent_DPHD,parent_WBD,parent_SBD, & ! parent res, western and south boundaries
  304. parent_CLAT,parent_CLON, & ! parent central lat,lon, all in degrees
  305. parent%ed31,parent%ed32, & ! parent imax and jmax
  306. IDS,IDE,JDS,JDE,KDS,KDE, & !
  307. IMS,IME,JMS,JME,KMS,KME, & ! nested grid configuration
  308. ITS,ITE,JTS,JTE,KTS,KTE ) !
  309. endif
  310. !*** CHECK WEIGHTS AT MASS AND VELOCITY POINTS
  311. CALL WEIGTS_CHECK(nest%HBWGT1,nest%HBWGT2, & ! output weights on the nested grid
  312. nest%HBWGT3,nest%HBWGT4, &
  313. nest%VBWGT1,nest%VBWGT2, & ! output weights on the nested grid
  314. nest%VBWGT3,nest%VBWGT4, &
  315. IDS,IDE,JDS,JDE,KDS,KDE, & !
  316. IMS,IME,JMS,JME,KMS,KME, & ! nested grid configuration
  317. ITS,ITE,JTS,JTE,KTS,KTE )
  318. !*** CHECK DOMAIN BOUNDS BEFORE PROCEEDING TO INTERPOLATION
  319. !
  320. CALL BOUNDS_CHECK( nest%IIH,nest%JJH,nest%IIV,nest%JJV, &
  321. nest%i_parent_start,nest%j_parent_start,nest%shw, &
  322. IDS,IDE,JDS,JDE,KDS,KDE, & !
  323. IMS,IME,JMS,JME,KMS,KME, & ! nested grid configuration
  324. ITS,ITE,JTS,JTE,KTS,KTE )
  325. !------------------------------------------------------------------------------------------
  326. END SUBROUTINE med_construct_egrid_weights
  327. !======================================================================================
  328. !
  329. ! compute earth lat-lons for parent and the nest before interpolations
  330. !------------------------------------------------------------------------------
  331. SUBROUTINE EARTH_LATLON ( HLAT,HLON,VLAT,VLON, & !Earth lat,lon at H and V points
  332. DLMD1,DPHD1,WBD1,SBD1, & !input res,west & south boundaries,
  333. CENTRAL_LAT,CENTRAL_LON, & ! central lat,lon, all in degrees
  334. IDS,IDE,JDS,JDE,KDS,KDE, &
  335. IMS,IME,JMS,JME,KMS,KME, &
  336. ITS,ITE,JTS,JTE,KTS,KTE )
  337. !============================================================================
  338. !
  339. IMPLICIT NONE
  340. INTEGER, INTENT(IN ) :: IDS,IDE,JDS,JDE,KDS,KDE
  341. INTEGER, INTENT(IN ) :: IMS,IME,JMS,JME,KMS,KME
  342. INTEGER, INTENT(IN ) :: ITS,ITE,JTS,JTE,KTS,KTE
  343. REAL, INTENT(IN ) :: DLMD1,DPHD1,WBD1,SBD1
  344. REAL, INTENT(IN ) :: CENTRAL_LAT,CENTRAL_LON
  345. REAL, DIMENSION(IMS:IME,JMS:JME), INTENT(OUT) :: HLAT,HLON,VLAT,VLON
  346. ! local
  347. INTEGER,PARAMETER :: KNUM=SELECTED_REAL_KIND(13)
  348. INTEGER :: I,J
  349. REAL(KIND=KNUM) :: WB,SB,DLM,DPH,TPH0,STPH0,CTPH0
  350. REAL(KIND=KNUM) :: TDLM,TDPH,TLMH,TLMV,TLMH0,TLMV0,TPHH,TPHV,DTR
  351. REAL(KIND=KNUM) :: STPH,CTPH,STPV,CTPV,PI_2
  352. REAL(KIND=KNUM) :: SPHH,CLMH,FACTH,SPHV,CLMV,FACTV
  353. REAL(KIND=KNUM), DIMENSION(IMS:IME,JMS:JME) :: GLATH,GLONH,GLATV,GLONV
  354. !-------------------------------------------------------------------------
  355. !
  356. PI_2 = ACOS(0.)
  357. DTR = PI_2/90.
  358. WB = WBD1 * DTR ! WB: western boundary in radians
  359. SB = SBD1 * DTR ! SB: southern boundary in radians
  360. DLM = DLMD1 * DTR ! DLM: dlamda in radians
  361. DPH = DPHD1 * DTR ! DPH: dphi in radians
  362. TDLM = DLM + DLM ! TDLM: 2.0*dlamda
  363. TDPH = DPH + DPH ! TDPH: 2.0*DPH
  364. ! For earth lat lon only
  365. TPH0 = CENTRAL_LAT*DTR ! TPH0: central lat in radians
  366. STPH0 = SIN(TPH0)
  367. CTPH0 = COS(TPH0)
  368. ! .H
  369. DO J = JTS,MIN(JTE,JDE-1) ! H./ This loop takes care of zig-zag
  370. ! ! \.H starting points along j
  371. TLMH0 = WB - TDLM + MOD(J+1,2) * DLM ! ./ TLMH (rotated lats at H points)
  372. TLMV0 = WB - TDLM + MOD(J,2) * DLM ! H (//ly for V points)
  373. TPHH = SB + (J-1)*DPH ! TPHH (rotated lons at H points) are simple trans.
  374. TPHV = TPHH ! TPHV (rotated lons at V points) are simple trans.
  375. STPH = SIN(TPHH)
  376. CTPH = COS(TPHH)
  377. STPV = SIN(TPHV)
  378. CTPV = COS(TPHV)
  379. ! .H
  380. DO I = ITS,MIN(ITE,IDE-1) ! /
  381. TLMH = TLMH0 + I*TDLM ! \.H .U .H
  382. ! !H./ ----><----
  383. SPHH = CTPH0 * STPH + STPH0 * CTPH * COS(TLMH) ! DLM + DLM
  384. GLATH(I,J)=ASIN(SPHH) ! GLATH: Earth Lat in radians
  385. CLMH = CTPH*COS(TLMH)/(COS(GLATH(I,J))*CTPH0) &
  386. - TAN(GLATH(I,J))*TAN(TPH0)
  387. IF(CLMH .GT. 1.) CLMH = 1.0
  388. IF(CLMH .LT. -1.) CLMH = -1.0
  389. FACTH = 1.
  390. IF(TLMH .GT. 0.) FACTH = -1.
  391. GLONH(I,J) = -CENTRAL_LON*DTR + FACTH*ACOS(CLMH)
  392. ENDDO
  393. DO I = ITS,MIN(ITE,IDE-1)
  394. TLMV = TLMV0 + I*TDLM
  395. SPHV = CTPH0 * STPV + STPH0 * CTPV * COS(TLMV)
  396. GLATV(I,J) = ASIN(SPHV)
  397. CLMV = CTPV*COS(TLMV)/(COS(GLATV(I,J))*CTPH0) &
  398. - TAN(GLATV(I,J))*TAN(TPH0)
  399. IF(CLMV .GT. 1.) CLMV = 1.
  400. IF(CLMV .LT. -1.) CLMV = -1.
  401. FACTV = 1.
  402. IF(TLMV .GT. 0.) FACTV = -1.
  403. GLONV(I,J) = -CENTRAL_LON*DTR + FACTV*ACOS(CLMV)
  404. ENDDO
  405. ENDDO
  406. ! Conversion to degrees (may not be required, eventually)
  407. DO J = JTS, MIN(JTE,JDE-1)
  408. DO I = ITS, MIN(ITE,IDE-1)
  409. HLAT(I,J) = GLATH(I,J) / DTR
  410. HLON(I,J)= -GLONH(I,J)/DTR
  411. IF(HLON(I,J) .GT. 180.) HLON(I,J) = HLON(I,J) - 360.
  412. IF(HLON(I,J) .LT. -180.) HLON(I,J) = HLON(I,J) + 360.
  413. !
  414. VLAT(I,J) = GLATV(I,J) / DTR
  415. VLON(I,J) = -GLONV(I,J) / DTR
  416. IF(VLON(I,J) .GT. 180.) VLON(I,J) = VLON(I,J) - 360.
  417. IF(VLON(I,J) .LT. -180.) VLON(I,J) = VLON(I,J) + 360.
  418. ENDDO
  419. ENDDO
  420. END SUBROUTINE EARTH_LATLON
  421. !-----------------------------------------------------------------------------
  422. SUBROUTINE G2T2H( IIH,JJH, & ! output grid index and weights
  423. HBWGT1,HBWGT2, & ! output weights in terms of parent grid
  424. HBWGT3,HBWGT4, &
  425. HLAT,HLON, & ! target (nest) input lat lon in degrees
  426. DLMD1,DPHD1,WBD1,SBD1, & ! parent res, west and south boundaries
  427. CENTRAL_LAT,CENTRAL_LON, & ! parent central lat,lon, all in degrees
  428. P_IDE,P_JDE, & ! parent imax and jmax
  429. IDS,IDE,JDS,JDE,KDS,KDE, & ! target (nest) dIMEnsions
  430. IMS,IME,JMS,JME,KMS,KME, &
  431. ITS,ITE,JTS,JTE,KTS,KTE )
  432. !
  433. !*** Tom Black - Initial Version
  434. !*** Gopal - Revised Version for WRF (includes coincident grid points)
  435. !***
  436. !*** GIVEN PARENT CENTRAL LAT-LONS, RESOLUTION AND WESTERN AND SOUTHERN BOUNDARY,
  437. !*** AND THE NESTED GRID LAT-LONS AT H POINTS, THIS ROUTINE FIRST LOCATES THE
  438. !*** INDICES,IIH,JJH, OF THE PARENT DOMAIN'S H POINTS THAT LIES CLOSEST TO THE
  439. !*** h POINTS OF THE NESTED DOMAIN
  440. !
  441. !============================================================================
  442. !
  443. IMPLICIT NONE
  444. INTEGER, INTENT(IN ) :: IDS,IDE,JDS,JDE,KDS,KDE
  445. INTEGER, INTENT(IN ) :: IMS,IME,JMS,JME,KMS,KME
  446. INTEGER, INTENT(IN ) :: ITS,ITE,JTS,JTE,KTS,KTE
  447. INTEGER, INTENT(IN ) :: P_IDE,P_JDE
  448. REAL, INTENT(IN ) :: DLMD1,DPHD1,WBD1,SBD1
  449. REAL, INTENT(IN ) :: CENTRAL_LAT,CENTRAL_LON
  450. REAL, DIMENSION(IMS:IME,JMS:JME), INTENT(IN) :: HLAT,HLON
  451. REAL, DIMENSION(IMS:IME,JMS:JME), INTENT(OUT) :: HBWGT1,HBWGT2,HBWGT3,HBWGT4
  452. INTEGER, DIMENSION(IMS:IME,JMS:JME), INTENT(OUT) :: IIH,JJH
  453. ! local
  454. INTEGER,PARAMETER :: KNUM=SELECTED_REAL_KIND(13)
  455. INTEGER :: IMT,JMT,N2R,MK,K,I,J,DSLP0,DSLOPE
  456. INTEGER :: NROW,NCOL,KROWS
  457. REAL(KIND=KNUM) :: X,Y,Z,TLAT,TLON
  458. REAL(KIND=KNUM) :: PI_2,D2R,R2D,GLAT,GLON,DPH,DLM,TPH0,TLM0,WB,SB
  459. REAL(KIND=KNUM) :: ROW,COL,SLP0,TLATHC,TLONHC,DENOM,SLOPE
  460. REAL(KIND=KNUM) :: TLAT1,TLAT2,TLON1,TLON2,DLM1,DLM2,DLM3,DLM4,D1,D2
  461. REAL(KIND=KNUM) :: DLA1,DLA2,DLA3,DLA4,S1,R1,DS1,AN1,AN2,AN3 ! Q
  462. REAL(KIND=KNUM) :: DL1,DL2,DL3,DL4,DL1I,DL2I,DL3I,DL4I,SUMDL,TLONO,TLATO
  463. REAL(KIND=KNUM) :: DTEMP
  464. REAL , DIMENSION(IMS:IME,JMS:JME) :: TLATHX,TLONHX
  465. INTEGER, DIMENSION(IMS:IME,JMS:JME) :: KOUTB
  466. !-------------------------------------------------------------------------------
  467. IMT=2*P_IDE-2 ! parent i dIMEnsions
  468. JMT=P_JDE/2 ! parent j dIMEnsions
  469. PI_2=ACOS(0.)
  470. D2R=PI_2/90.
  471. R2D=1./D2R
  472. DPH=DPHD1*D2R
  473. DLM=DLMD1*D2R
  474. TPH0= CENTRAL_LAT*D2R
  475. TLM0=-CENTRAL_LON*D2R ! NOTE THE MINUS HERE
  476. WB=WBD1*D2R ! CONVERT NESTED GRID H POINTS FROM GEODETIC
  477. SB=SBD1*D2R
  478. SLP0=DPHD1/DLMD1
  479. DSLP0=NINT(R2D*ATAN(SLP0))
  480. DS1=SQRT(DPH*DPH+DLM*DLM) ! Q
  481. AN1=ASIN(DLM/DS1)
  482. AN2=ASIN(DPH/DS1)
  483. DO J = JTS,MIN(JTE,JDE-1)
  484. DO I = ITS,MIN(ITE,IDE-1)
  485. !***
  486. !*** LOCATE TARGET h POINTS (HLAT AND HLON) ON THE PARENT DOMAIN AND
  487. !*** DETERMINE THE INDICES IN TERMS OF THE PARENT DOMAIN. FIRST
  488. !*** CONVERT NESTED GRID h POINTS FROM GEODETIC TO TRANSFORMED
  489. !*** COORDINATE ON THE PARENT GRID
  490. !
  491. GLAT=HLAT(I,J)*D2R
  492. GLON= (360. - HLON(I,J))*D2R
  493. X=COS(TPH0)*COS(GLAT)*COS(GLON-TLM0)+SIN(TPH0)*SIN(GLAT)
  494. Y=-COS(GLAT)*SIN(GLON-TLM0)
  495. Z=COS(TPH0)*SIN(GLAT)-SIN(TPH0)*COS(GLAT)*COS(GLON-TLM0)
  496. TLAT=R2D*ATAN(Z/SQRT(X*X+Y*Y))
  497. TLON=R2D*ATAN(Y/X)
  498. ! ROW=TLAT/DPHD1+JMT ! JMT IS THE CENTRAL ROW OF THE PARENT DOMAIN
  499. ! COL=TLON/DLMD1+P_IDE-1 ! (P_IDE-1) IS THE CENTRAL COLUMN OF THE PARENT DOMAIN
  500. ROW=(TLAT-SBD1)/DPHD1+1 ! Dusan's doing
  501. COL=(TLON-WBD1)/DLMD1+1 ! Dusan's doing
  502. NROW=INT(ROW + 0.001) ! ROUND-OFF IS AVOIDED WITHOUT USING NINT ON PURPOSE
  503. NCOL=INT(COL + 0.001)
  504. TLAT=TLAT*D2R
  505. TLON=TLON*D2R
  506. !***
  507. !***
  508. !*** FIRST CONSIDER THE SITUATION WHERE THE POINT h IS AT
  509. !***
  510. !*** V H
  511. !***
  512. !***
  513. !*** H
  514. !*** H V
  515. !***
  516. !*** THEN LOCATE THE NEAREST H POINT ON THE PARENT GRID
  517. !***
  518. IF(MOD(NROW,2).EQ.1.AND.MOD(NCOL,2).EQ.1.OR. &
  519. MOD(NROW,2).EQ.0.AND.MOD(NCOL,2).EQ.0)THEN
  520. TLAT1=(NROW-JMT)*DPH
  521. TLAT2=TLAT1+DPH
  522. TLON1=(NCOL-(P_IDE-1))*DLM
  523. TLON2=TLON1+DLM
  524. DLM1=TLON-TLON1
  525. DLM2=TLON-TLON2
  526. ! D1=ACOS(COS(TLAT)*COS(TLAT1)*COS(DLM1)+SIN(TLAT)*SIN(TLAT1))
  527. ! D2=ACOS(COS(TLAT)*COS(TLAT2)*COS(DLM2)+SIN(TLAT)*SIN(TLAT2))
  528. DTEMP=MIN(1.0_KNUM,COS(TLAT)*COS(TLAT1)*COS(DLM1)+SIN(TLAT)*SIN(TLAT1))
  529. D1=ACOS(DTEMP)
  530. DTEMP=MIN(1.0_KNUM,COS(TLAT)*COS(TLAT2)*COS(DLM2)+SIN(TLAT)*SIN(TLAT2))
  531. D2=ACOS(DTEMP)
  532. IF(D1.GT.D2)THEN
  533. NROW=NROW+1 ! FIND THE NEAREST H ROW
  534. NCOL=NCOL+1 ! FIND THE NEAREST H COLUMN
  535. ENDIF
  536. ELSE
  537. !***
  538. !*** NOW CONSIDER THE SITUATION WHERE THE POINT h IS AT
  539. !***
  540. !*** H V
  541. !***
  542. !***
  543. !*** H
  544. !*** V H
  545. !***
  546. !*** THEN LOCATE THE NEAREST H POINT ON THE PARENT GRID
  547. !***
  548. !***
  549. TLAT1=(NROW+1-JMT)*DPH
  550. TLAT2=TLAT1-DPH
  551. TLON1=(NCOL-(P_IDE-1))*DLM
  552. TLON2=TLON1+DLM
  553. DLM1=TLON-TLON1
  554. DLM2=TLON-TLON2
  555. ! D1=ACOS(COS(TLAT)*COS(TLAT1)*COS(DLM1)+SIN(TLAT)*SIN(TLAT1))
  556. ! D2=ACOS(COS(TLAT)*COS(TLAT2)*COS(DLM2)+SIN(TLAT)*SIN(TLAT2))
  557. DTEMP=MIN(1.0_KNUM,COS(TLAT)*COS(TLAT1)*COS(DLM1)+SIN(TLAT)*SIN(TLAT1))
  558. D1=ACOS(DTEMP)
  559. DTEMP=MIN(1.0_KNUM,COS(TLAT)*COS(TLAT2)*COS(DLM2)+SIN(TLAT)*SIN(TLAT2))
  560. D2=ACOS(DTEMP)
  561. IF(D1.LT.D2)THEN
  562. NROW=NROW+1 ! FIND THE NEAREST H ROW
  563. ELSE
  564. NCOL=NCOL+1 ! FIND THE NEAREST H COLUMN
  565. ENDIF
  566. ENDIF
  567. KROWS=((NROW-1)/2)*IMT
  568. IF(MOD(NROW,2).EQ.1)THEN
  569. K=KROWS+(NCOL+1)/2
  570. ELSE
  571. K=KROWS+P_IDE-1+NCOL/2
  572. ENDIF
  573. !***
  574. !*** WE NOW KNOW THAT THE INNER GRID POINT IN QUESTION IS
  575. !*** NEAREST TO THE CENTER K AS SEEN BELOW. WE MUST FIND
  576. !*** WHICH OF THE FOUR H-BOXES (OF WHICH THIS H POINT IS
  577. !*** A VERTEX) SURROUNDS THE INNER GRID h POINT IN QUESTION.
  578. !***
  579. !**
  580. !*** H
  581. !***
  582. !***
  583. !***
  584. !*** H V H
  585. !***
  586. !***
  587. !*** H
  588. !*** H V H V H
  589. !***
  590. !***
  591. !***
  592. !*** H V H
  593. !***
  594. !***
  595. !***
  596. !*** H
  597. !***
  598. !***
  599. !*** FIND THE SLOPE OF THE LINE CONNECTING h AND THE CENTER H.
  600. !***
  601. N2R=K/IMT
  602. MK=MOD(K,IMT)
  603. !
  604. IF(MK.EQ.0)THEN
  605. TLATHC=SB+(2*N2R-1)*DPH
  606. ELSE
  607. TLATHC=SB+(2*N2R+(MK-1)/(P_IDE-1))*DPH
  608. ENDIF
  609. !
  610. IF(MK.LE.(P_IDE-1))THEN
  611. TLONHC=WB+2*(MK-1)*DLM
  612. ELSE
  613. TLONHC=WB+(2*(MK-(P_IDE-1))-1)*DLM
  614. ENDIF
  615. !
  616. !*** EXECUTE CAUTION IF YOU NEED TO CHANGE THESE CONDITIONS. SINCE WE ARE
  617. !*** DEALING WITH SLOPES TO GENERATE DIAMOND SHAPE H BOXES, WE NEED TO BE
  618. !*** CAREFUL HERE
  619. !
  620. IF(ABS(TLON-TLONHC) .LE. 1.E-4)TLONHC=TLON
  621. IF(ABS(TLAT-TLATHC) .LE. 1.E-4)TLATHC=TLAT
  622. DENOM=(TLON-TLONHC)
  623. !
  624. !***
  625. !***STORE THE LOCATION OF THE WESTERNMOST VERTEX OF THE H-BOX ON
  626. !***THE OUTER GRID THAT SURROUNDS THE h POINT ON THE INNER GRID.
  627. !***
  628. !*** COINCIDENT CONDITIONS
  629. IF(DENOM.EQ.0.0)THEN
  630. IF(TLATHC.EQ.TLAT)THEN
  631. KOUTB(I,J)=K
  632. IIH(I,J) = NCOL
  633. JJH(I,J) = NROW
  634. TLATHX(I,J)=TLATHC
  635. TLONHX(I,J)=TLONHC
  636. HBWGT1(I,J)=1.0
  637. HBWGT2(I,J)=0.0
  638. HBWGT3(I,J)=0.0
  639. HBWGT4(I,J)=0.0
  640. ELSE ! SAME LONGITUDE BUT DIFFERENT LATS
  641. !
  642. IF(TLATHC .GT. TLAT)THEN ! NESTED POINT SOUTH OF PARENT
  643. KOUTB(I,J)=K-(P_IDE-1)
  644. IIH(I,J) = NCOL-1
  645. JJH(I,J) = NROW-1
  646. TLATHX(I,J)=TLATHC-DPH
  647. TLONHX(I,J)=TLONHC-DLM
  648. ELSE ! NESTED POINT NORTH OF PARENT
  649. KOUTB(I,J)=K+(P_IDE-1)-1
  650. IIH(I,J) = NCOL-1
  651. JJH(I,J) = NROW+1
  652. TLATHX(I,J)=TLATHC+DPH
  653. TLONHX(I,J)=TLONHC-DLM
  654. ENDIF
  655. !***
  656. !***
  657. !*** 4
  658. !***
  659. !*** H
  660. !*** 1 2
  661. !***
  662. !*** 3
  663. !*** DL 1-4 ARE THE ANGULAR DISTANCES FROM h TO EACH VERTEX
  664. TLATO=TLATHX(I,J)
  665. TLONO=TLONHX(I,J)
  666. DLM1=TLON-TLONO
  667. DLA1=TLAT-TLATO ! Q
  668. ! DL1=ACOS(COS(TLAT)*COS(TLATO)*COS(DLM1)+SIN(TLAT)*SIN(TLATO)) ! Q
  669. DL1=SQRT(DLM1*DLM1+DLA1*DLA1) ! Q
  670. !
  671. TLATO=TLATHX(I,J)
  672. TLONO=TLONHX(I,J)+2.*DLM
  673. DLM2=TLON-TLONO
  674. DLA2=TLAT-TLATO ! Q
  675. ! DL2=ACOS(COS(TLAT)*COS(TLATO)*COS(DLM2)+SIN(TLAT)*SIN(TLATO)) ! Q
  676. DL2=SQRT(DLM2*DLM2+DLA2*DLA2) ! Q
  677. !
  678. TLATO=TLATHX(I,J)-DPH
  679. TLONO=TLONHX(I,J)+DLM
  680. DLM3=TLON-TLONO
  681. DLA3=TLAT-TLATO ! Q
  682. ! DL3=ACOS(COS(TLAT)*COS(TLATO)*COS(DLM3)+SIN(TLAT)*SIN(TLATO)) ! Q
  683. DL3=SQRT(DLM3*DLM3+DLA3*DLA3) ! Q
  684. TLATO=TLATHX(I,J)+DPH
  685. TLONO=TLONHX(I,J)+DLM
  686. DLM4=TLON-TLONO
  687. DLA4=TLAT-TLATO ! Q
  688. ! DL4=ACOS(COS(TLAT)*COS(TLATO)*COS(DLM4)+SIN(TLAT)*SIN(TLATO)) ! Q
  689. DL4=SQRT(DLM4*DLM4+DLA4*DLA4) ! Q
  690. ! THE BILINEAR WEIGHTS
  691. !***
  692. !***
  693. AN3=ATAN2(DLA1,DLM1) ! Q
  694. R1=DL1*SIN(AN2-AN3)/SIN(2.*AN1)
  695. S1=DL1*SIN(2.*PI_2-2*AN1-AN2+AN3)/SIN(2.*AN1)
  696. R1=R1/DS1
  697. S1=S1/DS1
  698. DL1I=(1.-R1)*(1.-S1)
  699. DL2I=R1*S1
  700. DL3I=R1*(1.-S1)
  701. DL4I=(1.-R1)*S1
  702. !
  703. HBWGT1(I,J)=DL1I
  704. HBWGT2(I,J)=DL2I
  705. HBWGT3(I,J)=DL3I
  706. HBWGT4(I,J)=DL4I
  707. !
  708. ENDIF
  709. ELSE
  710. !
  711. !*** NON-COINCIDENT POINTS
  712. !
  713. SLOPE=(TLAT-TLATHC)/DENOM
  714. DSLOPE=NINT(R2D*ATAN(SLOPE))
  715. IF(DSLOPE.LE.DSLP0.AND.DSLOPE.GE.-DSLP0)THEN
  716. IF(TLON.GT.TLONHC)THEN
  717. IF(TLONHC.GE.-WB-DLM)CALL wrf_error_fatal("1H:NESTED DOMAIN TOO CLOSE TO THE BOUNDARY OF PARENT")
  718. KOUTB(I,J)=K
  719. IIH(I,J) = NCOL
  720. JJH(I,J) = NROW
  721. TLATHX(I,J)=TLATHC
  722. TLONHX(I,J)=TLONHC
  723. ELSE
  724. IF(TLONHC.LE.WB+DLM)CALL wrf_error_fatal("2H:NESTED DOMAIN TOO CLOSE TO THE BOUNDARY OF PARENT")
  725. KOUTB(I,J)=K-1
  726. IIH(I,J) = NCOL-2
  727. JJH(I,J) = NROW
  728. TLATHX(I,J)=TLATHC
  729. TLONHX(I,J)=TLONHC -2.*DLM
  730. ENDIF
  731. !
  732. ELSEIF(DSLOPE.GT.DSLP0)THEN
  733. IF(TLON.GT.TLONHC)THEN
  734. IF(TLATHC.GE.-SB-DPH)CALL wrf_error_fatal("3H:NESTED DOMAIN TOO CLOSE TO THE BOUNDARY OF PARENT")
  735. KOUTB(I,J)=K+(P_IDE-1)-1
  736. IIH(I,J) = NCOL-1
  737. JJH(I,J) = NROW+1
  738. TLATHX(I,J)=TLATHC+DPH
  739. TLONHX(I,J)=TLONHC-DLM
  740. ELSE
  741. IF(TLATHC.LE.SB+DPH)CALL wrf_error_fatal("4H:NESTED DOMAIN TOO CLOSE TO THE BOUNDARY OF PARENT")
  742. KOUTB(I,J)=K-(P_IDE-1)
  743. IIH(I,J) = NCOL-1
  744. JJH(I,J) = NROW-1
  745. TLATHX(I,J)=TLATHC-DPH
  746. TLONHX(I,J)=TLONHC-DLM
  747. ENDIF
  748. !
  749. ELSEIF(DSLOPE.LT.-DSLP0)THEN
  750. IF(TLON.GT.TLONHC)THEN
  751. IF(TLATHC.LE.SB+DPH)CALL wrf_error_fatal("5H:NESTED DOMAIN TOO CLOSE TO THE BOUNDARY OF PARENT")
  752. KOUTB(I,J)=K-(P_IDE-1)
  753. IIH(I,J) = NCOL-1
  754. JJH(I,J) = NROW-1
  755. TLATHX(I,J)=TLATHC-DPH
  756. TLONHX(I,J)=TLONHC-DLM
  757. ELSE
  758. IF(TLATHC.GE.-SB-DPH)CALL wrf_error_fatal("6H:NESTED DOMAIN TOO CLOSE TO THE BOUNDARY OF PARENT")
  759. KOUTB(I,J)=K+(P_IDE-1)-1
  760. IIH(I,J) = NCOL-1
  761. JJH(I,J) = NROW+1
  762. TLATHX(I,J)=TLATHC+DPH
  763. TLONHX(I,J)=TLONHC-DLM
  764. ENDIF
  765. ENDIF
  766. !
  767. !*** NOW WE WILL MOVE AS FOLLOWS:
  768. !***
  769. !***
  770. !*** 4
  771. !***
  772. !***
  773. !***
  774. !*** H
  775. !*** 1 2
  776. !***
  777. !***
  778. !***
  779. !***
  780. !*** 3
  781. !***
  782. !***
  783. !***
  784. !*** DL 1-4 ARE THE ANGULAR DISTANCES FROM h TO EACH VERTEX
  785. TLATO=TLATHX(I,J)
  786. TLONO=TLONHX(I,J)
  787. DLM1=TLON-TLONO
  788. DLA1=TLAT-TLATO ! Q
  789. ! DL1=ACOS(COS(TLAT)*COS(TLATO)*COS(DLM1)+SIN(TLAT)*SIN(TLATO)) ! Q
  790. DL1=SQRT(DLM1*DLM1+DLA1*DLA1) ! Q
  791. !
  792. TLATO=TLATHX(I,J) ! redundant computations
  793. TLONO=TLONHX(I,J)+2.*DLM
  794. DLM2=TLON-TLONO
  795. DLA2=TLAT-TLATO ! Q
  796. ! DL2=ACOS(COS(TLAT)*COS(TLATO)*COS(DLM2)+SIN(TLAT)*SIN(TLATO)) ! Q
  797. DL2=SQRT(DLM2*DLM2+DLA2*DLA2) ! Q
  798. !
  799. TLATO=TLATHX(I,J)-DPH
  800. TLONO=TLONHX(I,J)+DLM
  801. DLM3=TLON-TLONO
  802. DLA3=TLAT-TLATO ! Q
  803. ! DL3=ACOS(COS(TLAT)*COS(TLATO)*COS(DLM3)+SIN(TLAT)*SIN(TLATO)) ! Q
  804. DL3=SQRT(DLM3*DLM3+DLA3*DLA3) ! Q
  805. !
  806. TLATO=TLATHX(I,J)+DPH
  807. TLONO=TLONHX(I,J)+DLM
  808. DLM4=TLON-TLONO
  809. DLA4=TLAT-TLATO ! Q
  810. ! DL4=ACOS(COS(TLAT)*COS(TLATO)*COS(DLM4)+SIN(TLAT)*SIN(TLATO)) ! Q
  811. DL4=SQRT(DLM4*DLM4+DLA4*DLA4) ! Q
  812. ! THE BILINEAR WEIGHTS
  813. !***
  814. AN3=ATAN2(DLA1,DLM1) ! Q
  815. R1=DL1*SIN(AN2-AN3)/SIN(2.*AN1)
  816. S1=DL1*SIN(2.*PI_2-2*AN1-AN2+AN3)/SIN(2.*AN1)
  817. R1=R1/DS1
  818. S1=S1/DS1
  819. DL1I=(1.-R1)*(1.-S1)
  820. DL2I=R1*S1
  821. DL3I=R1*(1.-S1)
  822. DL4I=(1.-R1)*S1
  823. !
  824. HBWGT1(I,J)=DL1I
  825. HBWGT2(I,J)=DL2I
  826. HBWGT3(I,J)=DL3I
  827. HBWGT4(I,J)=DL4I
  828. !
  829. ENDIF
  830. !
  831. !*** FINALLY STORE IIH IN TERMS OF E-GRID INDEX
  832. !
  833. IIH(I,J)=NINT(0.5*IIH(I,J))
  834. HBWGT1(I,J)=MAX(HBWGT1(I,J),0.0) ! all weights must be GE zero (postive def)
  835. HBWGT2(I,J)=MAX(HBWGT2(I,J),0.0) ! all weights must be GE zero (postive def)
  836. HBWGT3(I,J)=MAX(HBWGT3(I,J),0.0) ! all weights must be GE zero (postive def)
  837. HBWGT4(I,J)=MAX(HBWGT4(I,J),0.0) ! all weights must be GE zero (postive def)
  838. ! write(message,105)"H WEIGHTS:",I,J,HBWGT1(I,J),HBWGT2(I,J),HBWGT3(I,J),HBWGT4(I,J), &
  839. ! HBWGT1(I,J)+HBWGT2(I,J)+HBWGT3(I,J)+HBWGT4(I,J),IIH(i,j),JJH(i,j)
  840. ! CALL wrf_message(trim(message))
  841. ! 105 format(a,2i4,5f7.3,2i4)
  842. ENDDO
  843. ENDDO
  844. RETURN
  845. END SUBROUTINE G2T2H
  846. !========================================================================================
  847. SUBROUTINE G2T2V( IIV,JJV, & ! output grid index and weights
  848. VBWGT1,VBWGT2, & ! output weights in terms of parent grid
  849. VBWGT3,VBWGT4, &
  850. VLAT,VLON, & ! target (nest) input lat lon in degrees
  851. DLMD1,DPHD1,WBD1,SBD1, & ! parent res, west and south boundaries
  852. CENTRAL_LAT,CENTRAL_LON, & ! parent central lat,lon, all in degrees
  853. P_IDE,P_JDE, & ! parent imax and jmax
  854. IDS,IDE,JDS,JDE,KDS,KDE, & ! target (nest) dIMEnsions
  855. IMS,IME,JMS,JME,KMS,KME, &
  856. ITS,ITE,JTS,JTE,KTS,KTE )
  857. !
  858. !*** Tom Black - Initial Version
  859. !*** Gopal - Revised Version for WRF (includes coincIDEnt grid points)
  860. !***
  861. !*** GIVEN PARENT CENTRAL LAT-LONS, RESOLUTION AND WESTERN AND SOUTHERN BOUNDARY,
  862. !*** AND THE NESTED GRID LAT-LONS AT V POINTS, THIS ROUTINE FIRST LOCATES THE
  863. !*** INDICES,IIV,JJV, OF THE PARENT DOMAIN'S V POINTS THAT LIES CLOSEST TO THE
  864. !*** V POINTS OF THE NESTED DOMAIN
  865. !
  866. !============================================================================
  867. IMPLICIT NONE
  868. INTEGER, INTENT(IN ) :: IDS,IDE,JDS,JDE,KDS,KDE
  869. INTEGER, INTENT(IN ) :: IMS,IME,JMS,JME,KMS,KME
  870. INTEGER, INTENT(IN ) :: ITS,ITE,JTS,JTE,KTS,KTE
  871. INTEGER, INTENT(IN ) :: P_IDE,P_JDE
  872. REAL, INTENT(IN ) :: DLMD1,DPHD1,WBD1,SBD1
  873. REAL, INTENT(IN ) :: CENTRAL_LAT,CENTRAL_LON
  874. REAL, DIMENSION(IMS:IME,JMS:JME), INTENT(IN) :: VLAT,VLON
  875. REAL, DIMENSION(IMS:IME,JMS:JME), INTENT(OUT) :: VBWGT1,VBWGT2,VBWGT3,VBWGT4
  876. INTEGER, DIMENSION(IMS:IME,JMS:JME), INTENT(OUT) :: IIV,JJV
  877. ! local
  878. INTEGER,PARAMETER :: KNUM=SELECTED_REAL_KIND(13) ! (6) single precision
  879. INTEGER :: IMT,JMT,N2R,MK,K,I,J,DSLP0,DSLOPE
  880. INTEGER :: NROW,NCOL,KROWS
  881. REAL(KIND=KNUM) :: X,Y,Z,TLAT,TLON
  882. REAL(KIND=KNUM) :: PI_2,D2R,R2D,GLAT,GLON,DPH,DLM,TPH0,TLM0,WB,SB
  883. REAL(KIND=KNUM) :: ROW,COL,SLP0,TLATVC,TLONVC,DENOM,SLOPE
  884. REAL(KIND=KNUM) :: TLAT1,TLAT2,TLON1,TLON2,DLM1,DLM2,DLM3,DLM4,D1,D2
  885. REAL(KIND=KNUM) :: DLA1,DLA2,DLA3,DLA4,S1,R1,DS1,AN1,AN2,AN3 ! Q
  886. REAL(KIND=KNUM) :: DL1,DL2,DL3,DL4,DL1I,DL2I,DL3I,DL4I,SUMDL,TLONO,TLATO
  887. REAL(KIND=KNUM) :: DTEMP
  888. REAL , DIMENSION(IMS:IME,JMS:JME) :: TLATVX,TLONVX
  889. INTEGER, DIMENSION(IMS:IME,JMS:JME) :: KOUTB
  890. !-------------------------------------------------------------------------------------
  891. IMT=2*P_IDE-2 ! parent i dIMEnsions
  892. JMT=P_JDE/2 ! parent j dIMEnsions
  893. PI_2=ACOS(0.)
  894. D2R=PI_2/90.
  895. R2D=1./D2R
  896. DPH=DPHD1*D2R
  897. DLM=DLMD1*D2R
  898. TPH0= CENTRAL_LAT*D2R
  899. TLM0=-CENTRAL_LON*D2R ! NOTE THE MINUS HERE
  900. WB=WBD1*D2R ! DEGREES TO RADIANS
  901. SB=SBD1*D2R
  902. SLP0=DPHD1/DLMD1
  903. DSLP0=NINT(R2D*ATAN(SLP0))
  904. DS1=SQRT(DPH*DPH+DLM*DLM) ! Q
  905. AN1=ASIN(DLM/DS1)
  906. AN2=ASIN(DPH/DS1)
  907. DO J = JTS,MIN(JTE,JDE-1)
  908. DO I = ITS,MIN(ITE,IDE-1)
  909. !***
  910. !*** LOCATE TARGET V POINTS (VLAT AND VLON) ON THE PARENT DOMAIN AND
  911. !*** DETERMINE THE INDICES IN TERMS OF THE PARENT DOMAIN. FIRST
  912. !*** CONVERT NESTED GRID V POINTS FROM GEODETIC TO TRANSFORMED
  913. !*** COORDINATE ON THE PARENT GRID
  914. !
  915. GLAT=VLAT(I,J)*D2R
  916. GLON=(360. - VLON(I,J))*D2R
  917. X=COS(TPH0)*COS(GLAT)*COS(GLON-TLM0)+SIN(TPH0)*SIN(GLAT)
  918. Y=-COS(GLAT)*SIN(GLON-TLM0)
  919. Z=COS(TPH0)*SIN(GLAT)-SIN(TPH0)*COS(GLAT)*COS(GLON-TLM0)
  920. TLAT=R2D*ATAN(Z/SQRT(X*X+Y*Y))
  921. TLON=R2D*ATAN(Y/X)
  922. ! ROW=TLAT/DPHD1+JMT ! JMT IS THE CENTRAL ROW OF THE PARENT DOMAIN
  923. ! COL=TLON/DLMD1+P_IDE-1 ! (P_IDE-1) IS THE CENTRAL COLUMN OF THE PARENT DOMAIN
  924. ROW=(TLAT-SBD1)/DPHD1+1 ! Dusan's doing
  925. COL=(TLON-WBD1)/DLMD1+1 ! Dusan's doing
  926. NROW=INT(ROW + 0.001) ! ROUND-OFF IS AVOIDED WITHOUT USING NINT ON PURPOSE
  927. NCOL=INT(COL + 0.001)
  928. TLAT=TLAT*D2R
  929. TLON=TLON*D2R
  930. !***
  931. !***
  932. !*** FIRST CONSIDER THE SITUATION WHERE THE POINT V IS AT
  933. !***
  934. !*** H V
  935. !***
  936. !***
  937. !*** V
  938. !*** V H
  939. !***
  940. !*** THEN LOCATE THE NEAREST V POINT ON THE PARENT GRID
  941. !***
  942. IF(MOD(NROW,2).EQ.0.AND.MOD(NCOL,2).EQ.1.OR. &
  943. MOD(NROW,2).EQ.1.AND.MOD(NCOL,2).EQ.0)THEN
  944. TLAT1=(NROW-JMT)*DPH
  945. TLAT2=TLAT1+DPH
  946. TLON1=(NCOL-(P_IDE-1))*DLM
  947. TLON2=TLON1+DLM
  948. DLM1=TLON-TLON1
  949. DLM2=TLON-TLON2
  950. ! D1=ACOS(COS(TLAT)*COS(TLAT1)*COS(DLM1)+SIN(TLAT)*SIN(TLAT1))
  951. ! D2=ACOS(COS(TLAT)*COS(TLAT2)*COS(DLM2)+SIN(TLAT)*SIN(TLAT2))
  952. DTEMP=MIN(1.0_KNUM,COS(TLAT)*COS(TLAT1)*COS(DLM1)+SIN(TLAT)*SIN(TLAT1))
  953. D1=ACOS(DTEMP)
  954. DTEMP=MIN(1.0_KNUM,COS(TLAT)*COS(TLAT2)*COS(DLM2)+SIN(TLAT)*SIN(TLAT2))
  955. D2=ACOS(DTEMP)
  956. IF(D1.GT.D2)THEN
  957. NROW=NROW+1 ! FIND THE NEAREST V ROW
  958. NCOL=NCOL+1 ! FIND THE NEAREST V COLUMN
  959. ENDIF
  960. ELSE
  961. !***
  962. !*** NOW CONSIDER THE SITUATION WHERE THE POINT V IS AT
  963. !***
  964. !*** V H
  965. !***
  966. !***
  967. !*** V
  968. !*** H V
  969. !***
  970. !*** THEN LOCATE THE NEAREST V POINT ON THE PARENT GRID
  971. !***
  972. TLAT1=(NROW+1-JMT)*DPH
  973. TLAT2=TLAT1-DPH
  974. TLON1=(NCOL-(P_IDE-1))*DLM
  975. TLON2=TLON1+DLM
  976. DLM1=TLON-TLON1
  977. DLM2=TLON-TLON2
  978. ! D1=ACOS(COS(TLAT)*COS(TLAT1)*COS(DLM1)+SIN(TLAT)*SIN(TLAT1))
  979. ! D2=ACOS(COS(TLAT)*COS(TLAT2)*COS(DLM2)+SIN(TLAT)*SIN(TLAT2))
  980. DTEMP=MIN(1.0_KNUM,COS(TLAT)*COS(TLAT1)*COS(DLM1)+SIN(TLAT)*SIN(TLAT1))
  981. D1=ACOS(DTEMP)
  982. DTEMP=MIN(1.0_KNUM,COS(TLAT)*COS(TLAT2)*COS(DLM2)+SIN(TLAT)*SIN(TLAT2))
  983. D2=ACOS(DTEMP)
  984. IF(D1.LT.D2)THEN
  985. NROW=NROW+1 ! FIND THE NEAREST H ROW
  986. ELSE
  987. NCOL=NCOL+1 ! FIND THE NEAREST H COLUMN
  988. ENDIF
  989. ENDIF
  990. KROWS=((NROW-1)/2)*IMT
  991. IF(MOD(NROW,2).EQ.1)THEN
  992. K=KROWS+NCOL/2
  993. ELSE
  994. K=KROWS+P_IDE-2+(NCOL+1)/2 ! check this one should this not be P_IDE-2 ????
  995. ENDIF
  996. !***
  997. !*** WE NOW KNOW THAT THE INNER GRID POINT IN QUESTION IS
  998. !*** NEAREST TO THE CENTER K AS SEEN BELOW. WE MUST FIND
  999. !*** WHICH OF THE FOUR v-BOXES (OF WHICH THIS V POINT IS
  1000. !*** A VERTEX) SURROUNDS THE INNER GRID V POINT IN QUESTION.
  1001. !***
  1002. !***
  1003. !*** V
  1004. !***
  1005. !***
  1006. !***
  1007. !*** V H V
  1008. !***
  1009. !***
  1010. !*** V
  1011. !*** V H V H V
  1012. !***
  1013. !***
  1014. !***
  1015. !*** V H V
  1016. !***
  1017. !***
  1018. !***
  1019. !*** V
  1020. !***
  1021. !***
  1022. !*** FIND THE SLOPE OF THE LINE CONNECTING V AND THE CENTER v.
  1023. !***
  1024. N2R=K/IMT
  1025. MK=MOD(K,IMT)
  1026. !
  1027. IF(MK.EQ.0)THEN
  1028. TLATVC=SB+(2*N2R-1)*DPH
  1029. ELSE
  1030. TLATVC=SB+(2*N2R+MK/(P_IDE-1))*DPH
  1031. ENDIF
  1032. !
  1033. IF(MK.LE.(P_IDE-1)-1)THEN
  1034. TLONVC=WB+(2*MK-1)*DLM
  1035. ELSE
  1036. TLONVC=WB+2*(MK-(P_IDE-1))*DLM
  1037. ENDIF
  1038. !
  1039. !*** EXECUTE CAUTION IF YOU NEED TO CHANGE THESE CONDITIONS. SINCE WE ARE
  1040. !*** DEALING WITH SLOPES TO GENERATE DIAMOND SHAPE V BOXES, WE NEED TO BE
  1041. !*** CAREFUL HERE
  1042. !
  1043. IF(ABS(TLON-TLONVC) .LE. 1.E-4)TLONVC=TLON
  1044. IF(ABS(TLAT-TLATVC) .LE. 1.E-4)TLATVC=TLAT
  1045. DENOM=(TLON-TLONVC)
  1046. !
  1047. !***
  1048. !***STORE THE LOCATION OF THE WESTERNMOST VERTEX OF THE H-BOX ON
  1049. !***THE OUTER GRID THAT SURROUNDS THE h POINT ON THE INNER GRID.
  1050. !***
  1051. !*** COINCIDENT CONDITIONS
  1052. IF(DENOM.EQ.0.0)THEN
  1053. IF(TLATVC.EQ.TLAT)THEN
  1054. KOUTB(I,J)=K
  1055. IIV(I,J) = NCOL
  1056. JJV(I,J) = NROW
  1057. TLATVX(I,J)=TLATVC
  1058. TLONVX(I,J)=TLONVC
  1059. VBWGT1(I,J)=1.0
  1060. VBWGT2(I,J)=0.0
  1061. VBWGT3(I,J)=0.0
  1062. VBWGT4(I,J)=0.0
  1063. ELSE ! SAME LONGITUDE BUT DIFFERENT LATS
  1064. IF(TLATVC .GT. TLAT)THEN ! NESTED POINT SOUTH OF PARENT
  1065. KOUTB(I,J)=K-(P_IDE-1)
  1066. IIV(I,J) = NCOL-1
  1067. JJV(I,J) = NROW-1
  1068. TLATVX(I,J)=TLATVC-DPH
  1069. TLONVX(I,J)=TLONVC-DLM
  1070. ELSE ! NESTED POINT NORTH OF PARENT
  1071. KOUTB(I,J)=K+(P_IDE-1)-1
  1072. IIV(I,J) = NCOL-1
  1073. JJV(I,J) = NROW+1
  1074. TLATVX(I,J)=TLATVC+DPH
  1075. TLONVX(I,J)=TLONVC-DLM
  1076. ENDIF
  1077. !***
  1078. !***
  1079. !*** 4
  1080. !***
  1081. !*** V
  1082. !*** 1 2
  1083. !***
  1084. !*** 3
  1085. !*** DL 1-4 ARE THE ANGULAR DISTANCES FROM h TO EACH VERTEX
  1086. TLATO=TLATVX(I,J)
  1087. TLONO=TLONVX(I,J)
  1088. DLM1=TLON-TLONO
  1089. DLA1=TLAT-TLATO ! Q
  1090. ! DL1=ACOS(COS(TLAT)*COS(TLATO)*COS(DLM1)+SIN(TLAT)*SIN(TLATO)) ! Q
  1091. DL1=SQRT(DLM1*DLM1+DLA1*DLA1) ! Q
  1092. !
  1093. TLATO=TLATVX(I,J)
  1094. TLONO=TLONVX(I,J)+2.*DLM
  1095. DLM2=TLON-TLONO
  1096. DLA2=TLAT-TLATO ! Q
  1097. ! DL2=ACOS(COS(TLAT)*COS(TLATO)*COS(DLM2)+SIN(TLAT)*SIN(TLATO)) ! Q
  1098. DL2=SQRT(DLM2*DLM2+DLA2*DLA2) ! Q
  1099. TLATO=TLATVX(I,J)-DPH
  1100. TLONO=TLONVX(I,J)+DLM
  1101. DLM3=TLON-TLONO
  1102. DLA3=TLAT-TLATO ! Q
  1103. ! DL3=ACOS(COS(TLAT)*COS(TLATO)*COS(DLM3)+SIN(TLAT)*SIN(TLATO)) ! Q
  1104. DL3=SQRT(DLM3*DLM3+DLA3*DLA3) ! Q
  1105. TLATO=TLATVX(I,J)+DPH
  1106. TLONO=TLONVX(I,J)+DLM
  1107. DLM4=TLON-TLONO
  1108. DLA4=TLAT-TLATO ! Q
  1109. ! DL4=ACOS(COS(TLAT)*COS(TLATO)*COS(DLM4)+SIN(TLAT)*SIN(TLATO)) ! Q
  1110. DL4=SQRT(DLM4*DLM4+DLA4*DLA4) ! Q
  1111. ! THE BILINEAR WEIGHTS
  1112. !***
  1113. AN3=ATAN2(DLA1,DLM1) ! Q
  1114. R1=DL1*SIN(AN2-AN3)/SIN(2.*AN1)
  1115. S1=DL1*SIN(2.*PI_2-2*AN1-AN2+AN3)/SIN(2.*AN1)
  1116. R1=R1/DS1
  1117. S1=S1/DS1
  1118. DL1I=(1.-R1)*(1.-S1)
  1119. DL2I=R1*S1
  1120. DL3I=R1*(1.-S1)
  1121. DL4I=(1.-R1)*S1
  1122. !
  1123. VBWGT1(I,J)=DL1I
  1124. VBWGT2(I,J)=DL2I
  1125. VBWGT3(I,J)=DL3I
  1126. VBWGT4(I,J)=DL4I
  1127. ENDIF
  1128. ELSE
  1129. !
  1130. !*** NON-COINCIDENT POINTS
  1131. !
  1132. SLOPE=(TLAT-TLATVC)/DENOM
  1133. DSLOPE=NINT(R2D*ATAN(SLOPE))
  1134. IF(DSLOPE.LE.DSLP0.AND.DSLOPE.GE.-DSLP0)THEN
  1135. IF(TLON.GT.TLONVC)THEN
  1136. IF(TLONVC.GE.-WB-DLM)CALL wrf_error_fatal("1V:NESTED DOMAIN TOO CLOSE TO THE BOUNDARY OF PARENT")
  1137. KOUTB(I,J)=K
  1138. IIV(I,J)=NCOL
  1139. JJV(I,J)=NROW
  1140. TLATVX(I,J)=TLATVC
  1141. TLONVX(I,J)=TLONVC
  1142. ELSE
  1143. IF(TLONVC.LE.WB+DLM)CALL wrf_error_fatal("2V:NESTED DOMAIN TOO CLOSE TO THE BOUNDARY OF PARENT")
  1144. KOUTB(I,J)=K-1
  1145. IIV(I,J) = NCOL-2
  1146. JJV(I,J) = NROW
  1147. TLATVX(I,J)=TLATVC
  1148. TLONVX(I,J)=TLONVC-2.*DLM
  1149. ENDIF
  1150. ELSEIF(DSLOPE.GT.DSLP0)THEN
  1151. IF(TLON.GT.TLONVC)THEN
  1152. IF(TLATVC.GE.-SB-DPH)CALL wrf_error_fatal("3V:NESTED DOMAIN TOO CLOSE TO THE BOUNDARY OF PARENT")
  1153. KOUTB(I,J)=K+(P_IDE-1)-1
  1154. IIV(I,J) = NCOL-1
  1155. JJV(I,J) = NROW+1
  1156. TLATVX(I,J)=TLATVC+DPH
  1157. TLONVX(I,J)=TLONVC-DLM
  1158. ELSE
  1159. IF(TLATVC.LE.SB+DPH)CALL wrf_error_fatal("4V:NESTED DOMAIN TOO CLOSE TO THE BOUNDARY OF PARENT")
  1160. KOUTB(I,J)=K-(P_IDE-1)
  1161. IIV(I,J) = NCOL-1
  1162. JJV(I,J) = NROW-1
  1163. TLATVX(I,J)=TLATVC-DPH
  1164. TLONVX(I,J)=TLONVC-DLM
  1165. ENDIF
  1166. ELSEIF(DSLOPE.LT.-DSLP0)THEN
  1167. IF(TLON.GT.TLONVC)THEN
  1168. IF(TLATVC.LE.SB+DPH)CALL wrf_error_fatal("5V:NESTED DOMAIN TOO CLOSE TO THE BOUNDARY OF PARENT")
  1169. KOUTB(I,J)=K-(P_IDE-1)
  1170. IIV(I,J) = NCOL-1
  1171. JJV(I,J) = NROW-1
  1172. TLATVX(I,J)=TLATVC-DPH
  1173. TLONVX(I,J)=TLONVC-DLM
  1174. ELSE
  1175. IF(TLATVC.GE.-SB-DPH)CALL wrf_error_fatal("6V:NESTED DOMAIN TOO CLOSE TO THE BOUNDARY OF PARENT")
  1176. KOUTB(I,J)=K+(P_IDE-1)-1
  1177. IIV(I,J) = NCOL-1
  1178. JJV(I,J) = NROW+1
  1179. TLATVX(I,J)=TLATVC+DPH
  1180. TLONVX(I,J)=TLONVC-DLM
  1181. ENDIF
  1182. ENDIF
  1183. !
  1184. !*** NOW WE WILL MOVE AS FOLLOWS:
  1185. !***
  1186. !***
  1187. !*** 4
  1188. !***
  1189. !***
  1190. !***
  1191. !*** V
  1192. !*** 1 2
  1193. !***
  1194. !***
  1195. !***
  1196. !***
  1197. !*** 3
  1198. !***
  1199. !***
  1200. !***
  1201. !*** DL 1-4 ARE THE ANGULAR DISTANCES FROM V TO EACH VERTEX
  1202. TLATO=TLATVX(I,J)
  1203. TLONO=TLONVX(I,J)
  1204. DLM1=TLON-TLONO
  1205. DLA1=TLAT-TLATO ! Q
  1206. ! DL1=ACOS(COS(TLAT)*COS(TLATO)*COS(DLM1)+SIN(TLAT)*SIN(TLATO)) ! Q
  1207. DL1=SQRT(DLM1*DLM1+DLA1*DLA1) ! Q
  1208. !
  1209. TLATO=TLATVX(I,J)
  1210. TLONO=TLONVX(I,J)+2.*DLM
  1211. DLM2=TLON-TLONO
  1212. DLA2=TLAT-TLATO ! Q
  1213. ! DL2=ACOS(COS(TLAT)*COS(TLATO)*COS(DLM2)+SIN(TLAT)*SIN(TLATO)) ! Q
  1214. DL2=SQRT(DLM2*DLM2+DLA2*DLA2) ! Q
  1215. !
  1216. TLATO

Large files files are truncated, but you can click here to view the full file