PageRenderTime 92ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/wrfv2_fire/share/interp_fcn.F

http://github.com/jbeezley/wrf-fire
FORTRAN Legacy | 4745 lines | 2932 code | 628 blank | 1185 comment | 18 complexity | dc16ac86532aa48d91fa387825e5a956 MD5 | raw file
Possible License(s): AGPL-1.0
  1. !WRF:MEDIATION_LAYER:INTERPOLATIONFUNCTION
  2. !
  3. #if (DA_CORE != 1)
  4. #define MM5_SINT
  5. #endif
  6. !#define DUMBCOPY
  7. ! Note, NMM-specific routines moved to end. 20080612. JM
  8. SUBROUTINE interp_fcn ( cfld, & ! CD field
  9. cids, cide, ckds, ckde, cjds, cjde, &
  10. cims, cime, ckms, ckme, cjms, cjme, &
  11. cits, cite, ckts, ckte, cjts, cjte, &
  12. nfld, & ! ND field
  13. nids, nide, nkds, nkde, njds, njde, &
  14. nims, nime, nkms, nkme, njms, njme, &
  15. nits, nite, nkts, nkte, njts, njte, &
  16. shw, & ! stencil half width for interp
  17. imask, & ! interpolation mask
  18. xstag, ystag, & ! staggering of field
  19. ipos, jpos, & ! Position of lower left of nest in CD
  20. nri, nrj ) ! nest ratios
  21. USE module_timing
  22. USE module_configure
  23. IMPLICIT NONE
  24. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  25. cims, cime, ckms, ckme, cjms, cjme, &
  26. cits, cite, ckts, ckte, cjts, cjte, &
  27. nids, nide, nkds, nkde, njds, njde, &
  28. nims, nime, nkms, nkme, njms, njme, &
  29. nits, nite, nkts, nkte, njts, njte, &
  30. shw, &
  31. ipos, jpos, &
  32. nri, nrj
  33. LOGICAL, INTENT(IN) :: xstag, ystag
  34. REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
  35. REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
  36. INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
  37. ! Local
  38. !logical first
  39. INTEGER ci, cj, ck, ni, nj, nk, ip, jp, ioff, joff, nioff, njoff
  40. #ifdef MM5_SINT
  41. INTEGER nfx, ior
  42. PARAMETER (ior=2)
  43. INTEGER nf
  44. REAL psca(cims:cime,cjms:cjme,nri*nrj)
  45. LOGICAL icmask( cims:cime, cjms:cjme )
  46. INTEGER i,j,k
  47. INTEGER nrio2, nrjo2
  48. #endif
  49. ! Iterate over the ND tile and compute the values
  50. ! from the CD tile.
  51. #ifdef MM5_SINT
  52. ioff = 0 ; joff = 0
  53. nioff = 0 ; njoff = 0
  54. IF ( xstag ) THEN
  55. ioff = (nri-1)/2
  56. nioff = nri
  57. ENDIF
  58. IF ( ystag ) THEN
  59. joff = (nrj-1)/2
  60. njoff = nrj
  61. ENDIF
  62. nrio2 = nri/2
  63. nrjo2 = nrj/2
  64. nfx = nri * nrj
  65. !$OMP PARALLEL DO &
  66. !$OMP PRIVATE ( i,j,k,ni,nj,ci,cj,ip,jp,nk,ck,nf,icmask,psca )
  67. DO k = ckts, ckte
  68. icmask = .FALSE.
  69. DO nf = 1,nfx
  70. DO j = cjms,cjme
  71. nj = (j-jpos) * nrj + ( nrjo2 + 1 ) ! j point on nest
  72. DO i = cims,cime
  73. ni = (i-ipos) * nri + ( nrio2 + 1 ) ! i point on nest
  74. if ( ni .ge. nits-nioff-nrio2 .and. &
  75. ni .le. nite+nioff+nrio2 .and. &
  76. nj .ge. njts-njoff-nrjo2 .and. &
  77. nj .le. njte+njoff+nrjo2 ) then
  78. ! if ( imask(ni,nj) .eq. 1 .or. imask(ni-nioff,nj-njoff) .eq. 1 ) then
  79. ! icmask( i, j ) = .TRUE.
  80. ! endif
  81. if ( ni.ge.nims.and.ni.le.nime.and.nj.ge.njms.and.nj.le.njme) then
  82. if ( imask(ni,nj) .eq. 1 ) then
  83. icmask( i, j ) = .TRUE.
  84. endif
  85. endif
  86. if ( ni-nioff.ge.nims.and.ni.le.nime.and.nj-njoff.ge.njms.and.nj.le.njme) then
  87. if (ni .ge. nits-nioff .and. nj .ge. njts-njoff ) then
  88. if ( imask(ni-nioff,nj-njoff) .eq. 1) then
  89. icmask( i, j ) = .TRUE.
  90. endif
  91. endif
  92. endif
  93. endif
  94. psca(i,j,nf) = cfld(i,k,j)
  95. ENDDO
  96. ENDDO
  97. ENDDO
  98. ! tile dims in this call to sint are 1-over to account for the fact
  99. ! that the number of cells on the nest local subdomain is not
  100. ! necessarily a multiple of the nest ratio in a given dim.
  101. ! this could be a little less ham-handed.
  102. !call start_timing
  103. CALL sint( psca, &
  104. cims, cime, cjms, cjme, icmask, &
  105. cits-1, cite+1, cjts-1, cjte+1, nrj*nri, xstag, ystag )
  106. !call end_timing( ' sint ' )
  107. DO nj = njts, njte+joff
  108. cj = jpos + (nj-1) / nrj ! j coord of CD point
  109. jp = mod ( nj-1 , nrj ) ! coord of ND w/i CD point
  110. nk = k
  111. ck = nk
  112. DO ni = nits, nite+ioff
  113. ci = ipos + (ni-1) / nri ! i coord of CD point
  114. ip = mod ( ni-1 , nri ) ! coord of ND w/i CD point
  115. if ( imask ( ni, nj ) .eq. 1 .or. imask ( ni-ioff, nj-joff ) .eq. 1 ) then
  116. nfld( ni-ioff, nk, nj-joff ) = psca( ci , cj, ip+1 + (jp)*nri )
  117. endif
  118. ENDDO
  119. ENDDO
  120. ENDDO
  121. !$OMP END PARALLEL DO
  122. #endif
  123. #ifdef DUMBCOPY
  124. !write(0,'(") cims:cime, ckms:ckme, cjms:cjme ",6i4)')cims,cime, ckms,ckme, cjms,cjme
  125. !write(0,'(") nims:nime, nkms:nkme, njms:njme ",6i4)')nims,nime, nkms,nkme, njms,njme
  126. !write(0,'(") cits:cite, ckts:ckte, cjts:cjte ",6i4)')cits,cite, ckts,ckte, cjts,cjte
  127. !write(0,'(") nits:nite, nkts:nkte, njts:njte ",6i4)')nits,nite, nkts,nkte, njts,njte
  128. DO nj = njts, njte
  129. cj = jpos + (nj-1) / nrj ! j coord of CD point
  130. jp = mod ( nj , nrj ) ! coord of ND w/i CD point
  131. DO nk = nkts, nkte
  132. ck = nk
  133. DO ni = nits, nite
  134. ci = ipos + (ni-1) / nri ! j coord of CD point
  135. ip = mod ( ni , nri ) ! coord of ND w/i CD point
  136. ! This is a trivial implementation of the interp_fcn; just copies
  137. ! the values from the CD into the ND
  138. if ( imask ( ni, nj ) .eq. 1 ) then
  139. nfld( ni, nk, nj ) = cfld( ci , ck , cj )
  140. endif
  141. ENDDO
  142. ENDDO
  143. ENDDO
  144. #endif
  145. RETURN
  146. END SUBROUTINE interp_fcn
  147. !==================================
  148. ! this is the default function used in feedback.
  149. SUBROUTINE copy_fcn ( cfld, & ! CD field
  150. cids, cide, ckds, ckde, cjds, cjde, &
  151. cims, cime, ckms, ckme, cjms, cjme, &
  152. cits, cite, ckts, ckte, cjts, cjte, &
  153. nfld, & ! ND field
  154. nids, nide, nkds, nkde, njds, njde, &
  155. nims, nime, nkms, nkme, njms, njme, &
  156. nits, nite, nkts, nkte, njts, njte, &
  157. shw, & ! stencil half width for interp
  158. imask, & ! interpolation mask
  159. xstag, ystag, & ! staggering of field
  160. ipos, jpos, & ! Position of lower left of nest in CD
  161. nri, nrj ) ! nest ratios
  162. USE module_configure
  163. IMPLICIT NONE
  164. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  165. cims, cime, ckms, ckme, cjms, cjme, &
  166. cits, cite, ckts, ckte, cjts, cjte, &
  167. nids, nide, nkds, nkde, njds, njde, &
  168. nims, nime, nkms, nkme, njms, njme, &
  169. nits, nite, nkts, nkte, njts, njte, &
  170. shw, &
  171. ipos, jpos, &
  172. nri, nrj
  173. LOGICAL, INTENT(IN) :: xstag, ystag
  174. REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ), INTENT(OUT) :: cfld
  175. REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ),INTENT(IN) :: nfld
  176. INTEGER, DIMENSION ( nims:nime, njms:njme ),INTENT(IN) :: imask
  177. ! Local
  178. INTEGER ci, cj, ck, ni, nj, nk, ip, jp, ioff, joff, ioffa, joffa
  179. INTEGER :: icmin,icmax,jcmin,jcmax
  180. INTEGER :: istag,jstag, ipoints,jpoints,ijpoints
  181. INTEGER , PARAMETER :: passes = 2
  182. INTEGER spec_zone
  183. ! Loop over the coarse grid in the area of the fine mesh. Do not
  184. ! process the coarse grid values that are along the lateral BC
  185. ! provided to the fine grid. Since that is in the specified zone
  186. ! for the fine grid, it should not be used in any feedback to the
  187. ! coarse grid as it should not have changed.
  188. ! Due to peculiarities of staggering, it is simpler to handle the feedback
  189. ! for the staggerings based upon whether it is a even ratio (2::1, 4::1, etc.) or
  190. ! an odd staggering ratio (3::1, 5::1, etc.).
  191. ! Though there are separate grid ratios for the i and j directions, this code
  192. ! is not general enough to handle aspect ratios .NE. 1 for the fine grid cell.
  193. ! These are local integer increments in the looping. Basically, istag=1 means
  194. ! that we will assume one less point in the i direction. Note that ci and cj
  195. ! have a maximum value that is decreased by istag and jstag, respectively.
  196. ! Horizontal momentum feedback is along the face, not within the cell. For a
  197. ! 3::1 ratio, temperature would use 9 pts for feedback, while u and v use
  198. ! only 3 points for feedback from the nest to the parent.
  199. CALL nl_get_spec_zone( 1 , spec_zone )
  200. istag = 1 ; jstag = 1
  201. IF ( xstag ) istag = 0
  202. IF ( ystag ) jstag = 0
  203. IF( MOD(nrj,2) .NE. 0) THEN ! odd refinement ratio
  204. IF ( ( .NOT. xstag ) .AND. ( .NOT. ystag ) ) THEN
  205. DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
  206. nj = (cj-jpos)*nrj + jstag + 1
  207. DO ck = ckts, ckte
  208. nk = ck
  209. DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
  210. ni = (ci-ipos)*nri + istag + 1
  211. cfld( ci, ck, cj ) = 0.
  212. DO ijpoints = 1 , nri * nrj
  213. ipoints = MOD((ijpoints-1),nri) + 1 - nri/2 - 1
  214. jpoints = (ijpoints-1)/nri + 1 - nrj/2 - 1
  215. cfld( ci, ck, cj ) = cfld( ci, ck, cj ) + &
  216. 1./REAL(nri*nrj) * nfld( ni+ipoints , nk , nj+jpoints )
  217. END DO
  218. ! cfld( ci, ck, cj ) = 1./9. * &
  219. ! ( nfld( ni-1, nk , nj-1) + &
  220. ! nfld( ni , nk , nj-1) + &
  221. ! nfld( ni+1, nk , nj-1) + &
  222. ! nfld( ni-1, nk , nj ) + &
  223. ! nfld( ni , nk , nj ) + &
  224. ! nfld( ni+1, nk , nj ) + &
  225. ! nfld( ni-1, nk , nj+1) + &
  226. ! nfld( ni , nk , nj+1) + &
  227. ! nfld( ni+1, nk , nj+1) )
  228. ENDDO
  229. ENDDO
  230. ENDDO
  231. ELSE IF ( ( xstag ) .AND. ( .NOT. ystag ) ) THEN
  232. DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
  233. nj = (cj-jpos)*nrj + jstag + 1
  234. DO ck = ckts, ckte
  235. nk = ck
  236. DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
  237. ni = (ci-ipos)*nri + istag + 1
  238. cfld( ci, ck, cj ) = 0.
  239. DO ijpoints = (nri+1)/2 , (nri+1)/2 + nri*(nri-1) , nri
  240. ipoints = MOD((ijpoints-1),nri) + 1 - nri/2 - 1
  241. jpoints = (ijpoints-1)/nri + 1 - nrj/2 - 1
  242. cfld( ci, ck, cj ) = cfld( ci, ck, cj ) + &
  243. 1./REAL(nri ) * nfld( ni+ipoints , nk , nj+jpoints )
  244. END DO
  245. ! cfld( ci, ck, cj ) = 1./3. * &
  246. ! ( nfld( ni , nk , nj-1) + &
  247. ! nfld( ni , nk , nj ) + &
  248. ! nfld( ni , nk , nj+1) )
  249. ENDDO
  250. ENDDO
  251. ENDDO
  252. ELSE IF ( ( .NOT. xstag ) .AND. ( ystag ) ) THEN
  253. DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
  254. nj = (cj-jpos)*nrj + jstag + 1
  255. DO ck = ckts, ckte
  256. nk = ck
  257. DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
  258. ni = (ci-ipos)*nri + istag + 1
  259. cfld( ci, ck, cj ) = 0.
  260. DO ijpoints = ( nrj*nrj +1 )/2 - nrj/2 , ( nrj*nrj +1 )/2 - nrj/2 + nrj-1
  261. ipoints = MOD((ijpoints-1),nri) + 1 - nri/2 - 1
  262. jpoints = (ijpoints-1)/nri + 1 - nrj/2 - 1
  263. cfld( ci, ck, cj ) = cfld( ci, ck, cj ) + &
  264. 1./REAL( nrj) * nfld( ni+ipoints , nk , nj+jpoints )
  265. END DO
  266. ! cfld( ci, ck, cj ) = 1./3. * &
  267. ! ( nfld( ni-1, nk , nj ) + &
  268. ! nfld( ni , nk , nj ) + &
  269. ! nfld( ni+1, nk , nj ) )
  270. ENDDO
  271. ENDDO
  272. ENDDO
  273. END IF
  274. ! Even refinement ratio
  275. ELSE IF ( MOD(nrj,2) .EQ. 0) THEN
  276. IF ( ( .NOT. xstag ) .AND. ( .NOT. ystag ) ) THEN
  277. ! This is a simple schematic of the feedback indexing used in the even
  278. ! ratio nests. For simplicity, a 2::1 ratio is depicted. Only the
  279. ! mass variable staggering is shown.
  280. ! Each of
  281. ! the boxes with a "T" and four small "t" represents a coarse grid (CG)
  282. ! cell, that is composed of four (2::1 ratio) fine grid (FG) cells.
  283. ! Shown below is the area of the CG that is in the area of the FG. The
  284. ! first grid point of the depicted CG is the starting location of the nest
  285. ! in the parent domain (ipos,jpos - i_parent_start and j_parent_start from
  286. ! the namelist).
  287. ! For each of the CG points, the feedback loop is over each of the FG points
  288. ! within the CG cell. For a 2::1 ratio, there are four total points (this is
  289. ! the ijpoints loop). The feedback value to the CG is the arithmetic mean of
  290. ! all of the FG values within each CG cell.
  291. ! |-------------||-------------| |-------------||-------------|
  292. ! | t t || t t | | t t || t t |
  293. ! jpos+ | || | | || |
  294. ! (njde-njds)- | T || T | | T || T |
  295. ! jstag | || | | || |
  296. ! | t t || t t | | t t || t t |
  297. ! |-------------||-------------| |-------------||-------------|
  298. ! |-------------||-------------| |-------------||-------------|
  299. ! | t t || t t | | t t || t t |
  300. ! | || | | || |
  301. ! | T || T | | T || T |
  302. ! | || | | || |
  303. ! | t t || t t | | t t || t t |
  304. ! |-------------||-------------| |-------------||-------------|
  305. !
  306. ! ...
  307. ! ...
  308. ! ...
  309. ! ...
  310. ! ...
  311. ! |-------------||-------------| |-------------||-------------|
  312. ! jpoints = 1 | t t || t t | | t t || t t |
  313. ! | || | | || |
  314. ! | T || T | | T || T |
  315. ! | || | | || |
  316. ! jpoints = 0, | t t || t t | | t t || t t |
  317. ! nj=3 |-------------||-------------| |-------------||-------------|
  318. ! |-------------||-------------| |-------------||-------------|
  319. ! jpoints = 1 | t t || t t | | t t || t t |
  320. ! | || | | || |
  321. ! jpos | T || T | ... | T || T |
  322. ! | || | ... | || |
  323. ! jpoints = 0, | t t || t t | ... | t t || t t |
  324. ! nj=1 |-------------||-------------| |-------------||-------------|
  325. ! ^ ^
  326. ! | |
  327. ! | |
  328. ! ipos ipos+
  329. ! ni = 1 3 (nide-nids)/nri
  330. ! ipoints= 0 1 0 1 -istag
  331. !
  332. ! For performance benefits, users can comment out the inner most loop (and cfld=0) and
  333. ! hardcode the loop feedback. For example, it is set up to run a 2::1 ratio
  334. ! if uncommented. This lacks generality, but is likely to gain timing benefits
  335. ! with compilers unable to unroll inner loops that do not have parameterized sizes.
  336. ! The extra +1 ---------/ and the extra -1 ----\ (both for ci and cj)
  337. ! / \ keeps the feedback out of the
  338. ! / \ outer row/col, since that CG data
  339. ! / \ specified the nest boundary originally
  340. ! / \ This
  341. ! / \ is just
  342. ! / \ a sentence to not end a line
  343. ! / \ with a stupid backslash
  344. DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
  345. nj = (cj-jpos)*nrj + jstag
  346. DO ck = ckts, ckte
  347. nk = ck
  348. DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
  349. ni = (ci-ipos)*nri + istag
  350. cfld( ci, ck, cj ) = 0.
  351. DO ijpoints = 1 , nri * nrj
  352. ipoints = MOD((ijpoints-1),nri)
  353. jpoints = (ijpoints-1)/nri
  354. cfld( ci, ck, cj ) = cfld( ci, ck, cj ) + &
  355. 1./REAL(nri*nrj) * nfld( ni+ipoints , nk , nj+jpoints )
  356. END DO
  357. ! cfld( ci, ck, cj ) = 1./4. * &
  358. ! ( nfld( ni , nk , nj ) + &
  359. ! nfld( ni+1, nk , nj ) + &
  360. ! nfld( ni , nk , nj+1) + &
  361. ! nfld( ni+1, nk , nj+1) )
  362. END DO
  363. END DO
  364. END DO
  365. ! U
  366. ELSE IF ( ( xstag ) .AND. ( .NOT. ystag ) ) THEN
  367. ! |---------------|
  368. ! | |
  369. ! jpoints = 1 u u |
  370. ! | |
  371. ! U |
  372. ! | |
  373. ! jpoints = 0, u u |
  374. ! nj=3 | |
  375. ! |---------------|
  376. ! |---------------|
  377. ! | |
  378. ! jpoints = 1 u u |
  379. ! | |
  380. ! jpos U |
  381. ! | |
  382. ! jpoints = 0, u u |
  383. ! nj=1 | |
  384. ! |---------------|
  385. !
  386. ! ^
  387. ! |
  388. ! |
  389. ! ipos
  390. ! ni = 1 3
  391. ! ipoints= 0 1 0
  392. !
  393. DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
  394. nj = (cj-jpos)*nrj + 1
  395. DO ck = ckts, ckte
  396. nk = ck
  397. DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
  398. ni = (ci-ipos)*nri + 1
  399. cfld( ci, ck, cj ) = 0.
  400. DO ijpoints = 1 , nri*nrj , nri
  401. ipoints = MOD((ijpoints-1),nri)
  402. jpoints = (ijpoints-1)/nri
  403. cfld( ci, ck, cj ) = cfld( ci, ck, cj ) + &
  404. 1./REAL(nri ) * nfld( ni+ipoints , nk , nj+jpoints )
  405. END DO
  406. ! cfld( ci, ck, cj ) = 1./2. * &
  407. ! ( nfld( ni , nk , nj ) + &
  408. ! nfld( ni , nk , nj+1) )
  409. ENDDO
  410. ENDDO
  411. ENDDO
  412. ! V
  413. ELSE IF ( ( .NOT. xstag ) .AND. ( ystag ) ) THEN
  414. DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
  415. nj = (cj-jpos)*nrj + 1
  416. DO ck = ckts, ckte
  417. nk = ck
  418. DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
  419. ni = (ci-ipos)*nri + 1
  420. cfld( ci, ck, cj ) = 0.
  421. DO ijpoints = 1 , nri
  422. ipoints = MOD((ijpoints-1),nri)
  423. jpoints = (ijpoints-1)/nri
  424. cfld( ci, ck, cj ) = cfld( ci, ck, cj ) + &
  425. 1./REAL(nri ) * nfld( ni+ipoints , nk , nj+jpoints )
  426. END DO
  427. ! cfld( ci, ck, cj ) = 1./2. * &
  428. ! ( nfld( ni , nk , nj ) + &
  429. ! nfld( ni+1, nk , nj ) )
  430. ENDDO
  431. ENDDO
  432. ENDDO
  433. END IF
  434. END IF
  435. RETURN
  436. END SUBROUTINE copy_fcn
  437. !==================================
  438. ! this is the 1pt function used in feedback.
  439. SUBROUTINE copy_fcnm ( cfld, & ! CD field
  440. cids, cide, ckds, ckde, cjds, cjde, &
  441. cims, cime, ckms, ckme, cjms, cjme, &
  442. cits, cite, ckts, ckte, cjts, cjte, &
  443. nfld, & ! ND field
  444. nids, nide, nkds, nkde, njds, njde, &
  445. nims, nime, nkms, nkme, njms, njme, &
  446. nits, nite, nkts, nkte, njts, njte, &
  447. shw, & ! stencil half width for interp
  448. imask, & ! interpolation mask
  449. xstag, ystag, & ! staggering of field
  450. ipos, jpos, & ! Position of lower left of nest in CD
  451. nri, nrj ) ! nest ratios
  452. USE module_configure
  453. USE module_wrf_error
  454. IMPLICIT NONE
  455. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  456. cims, cime, ckms, ckme, cjms, cjme, &
  457. cits, cite, ckts, ckte, cjts, cjte, &
  458. nids, nide, nkds, nkde, njds, njde, &
  459. nims, nime, nkms, nkme, njms, njme, &
  460. nits, nite, nkts, nkte, njts, njte, &
  461. shw, &
  462. ipos, jpos, &
  463. nri, nrj
  464. LOGICAL, INTENT(IN) :: xstag, ystag
  465. REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ), INTENT(OUT) :: cfld
  466. REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ), INTENT(IN) :: nfld
  467. INTEGER, DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: imask
  468. ! Local
  469. INTEGER ci, cj, ck, ni, nj, nk, ip, jp, ioff, joff, ioffa, joffa
  470. INTEGER :: icmin,icmax,jcmin,jcmax
  471. INTEGER :: istag,jstag, ipoints,jpoints,ijpoints
  472. INTEGER , PARAMETER :: passes = 2
  473. INTEGER spec_zone
  474. CALL nl_get_spec_zone( 1, spec_zone )
  475. istag = 1 ; jstag = 1
  476. IF ( xstag ) istag = 0
  477. IF ( ystag ) jstag = 0
  478. IF( MOD(nrj,2) .NE. 0) THEN ! odd refinement ratio
  479. DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
  480. nj = (cj-jpos)*nrj + jstag + 1
  481. DO ck = ckts, ckte
  482. nk = ck
  483. DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
  484. ni = (ci-ipos)*nri + istag + 1
  485. cfld( ci, ck, cj ) = nfld( ni , nk , nj )
  486. ENDDO
  487. ENDDO
  488. ENDDO
  489. ELSE ! even refinement ratio, pick nearest neighbor on SW corner
  490. DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
  491. nj = (cj-jpos)*nrj + 1
  492. DO ck = ckts, ckte
  493. nk = ck
  494. DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
  495. ni = (ci-ipos)*nri + 1
  496. ipoints = nri/2 -1
  497. jpoints = nrj/2 -1
  498. cfld( ci, ck, cj ) = nfld( ni+ipoints , nk , nj+jpoints )
  499. END DO
  500. END DO
  501. END DO
  502. END IF
  503. RETURN
  504. END SUBROUTINE copy_fcnm
  505. !==================================
  506. ! this is the 1pt function used in feedback for integers
  507. SUBROUTINE copy_fcni ( cfld, & ! CD field
  508. cids, cide, ckds, ckde, cjds, cjde, &
  509. cims, cime, ckms, ckme, cjms, cjme, &
  510. cits, cite, ckts, ckte, cjts, cjte, &
  511. nfld, & ! ND field
  512. nids, nide, nkds, nkde, njds, njde, &
  513. nims, nime, nkms, nkme, njms, njme, &
  514. nits, nite, nkts, nkte, njts, njte, &
  515. shw, & ! stencil half width for interp
  516. imask, & ! interpolation mask
  517. xstag, ystag, & ! staggering of field
  518. ipos, jpos, & ! Position of lower left of nest in CD
  519. nri, nrj ) ! nest ratios
  520. USE module_configure
  521. USE module_wrf_error
  522. IMPLICIT NONE
  523. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  524. cims, cime, ckms, ckme, cjms, cjme, &
  525. cits, cite, ckts, ckte, cjts, cjte, &
  526. nids, nide, nkds, nkde, njds, njde, &
  527. nims, nime, nkms, nkme, njms, njme, &
  528. nits, nite, nkts, nkte, njts, njte, &
  529. shw, &
  530. ipos, jpos, &
  531. nri, nrj
  532. LOGICAL, INTENT(IN) :: xstag, ystag
  533. INTEGER, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ), INTENT(OUT) :: cfld
  534. INTEGER, DIMENSION ( nims:nime, nkms:nkme, njms:njme ), INTENT(IN) :: nfld
  535. INTEGER, DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: imask
  536. ! Local
  537. INTEGER ci, cj, ck, ni, nj, nk, ip, jp, ioff, joff, ioffa, joffa
  538. INTEGER :: icmin,icmax,jcmin,jcmax
  539. INTEGER :: istag,jstag, ipoints,jpoints,ijpoints
  540. INTEGER , PARAMETER :: passes = 2
  541. INTEGER spec_zone
  542. CALL nl_get_spec_zone( 1, spec_zone )
  543. istag = 1 ; jstag = 1
  544. IF ( xstag ) istag = 0
  545. IF ( ystag ) jstag = 0
  546. IF( MOD(nrj,2) .NE. 0) THEN ! odd refinement ratio
  547. DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
  548. nj = (cj-jpos)*nrj + jstag + 1
  549. DO ck = ckts, ckte
  550. nk = ck
  551. DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
  552. ni = (ci-ipos)*nri + istag + 1
  553. cfld( ci, ck, cj ) = nfld( ni , nk , nj )
  554. ENDDO
  555. ENDDO
  556. ENDDO
  557. ELSE ! even refinement ratio
  558. DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
  559. nj = (cj-jpos)*nrj + 1
  560. DO ck = ckts, ckte
  561. nk = ck
  562. DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
  563. ni = (ci-ipos)*nri + 1
  564. ipoints = nri/2 -1
  565. jpoints = nrj/2 -1
  566. cfld( ci, ck, cj ) = nfld( ni+ipoints , nk , nj+jpoints )
  567. END DO
  568. END DO
  569. END DO
  570. END IF
  571. RETURN
  572. END SUBROUTINE copy_fcni
  573. !==================================
  574. SUBROUTINE p2c ( cfld, & ! CD field
  575. cids, cide, ckds, ckde, cjds, cjde, &
  576. cims, cime, ckms, ckme, cjms, cjme, &
  577. cits, cite, ckts, ckte, cjts, cjte, &
  578. nfld, & ! ND field
  579. nids, nide, nkds, nkde, njds, njde, &
  580. nims, nime, nkms, nkme, njms, njme, &
  581. nits, nite, nkts, nkte, njts, njte, &
  582. shw, & ! stencil half width
  583. imask, & ! interpolation mask
  584. xstag, ystag, & ! staggering of field
  585. ipos, jpos, & ! Position of lower left of nest in CD
  586. nri, nrj & ! nest ratios
  587. )
  588. USE module_configure
  589. IMPLICIT NONE
  590. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  591. cims, cime, ckms, ckme, cjms, cjme, &
  592. cits, cite, ckts, ckte, cjts, cjte, &
  593. nids, nide, nkds, nkde, njds, njde, &
  594. nims, nime, nkms, nkme, njms, njme, &
  595. nits, nite, nkts, nkte, njts, njte, &
  596. shw, &
  597. ipos, jpos, &
  598. nri, nrj
  599. LOGICAL, INTENT(IN) :: xstag, ystag
  600. REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
  601. REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
  602. INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
  603. CALL interp_fcn (cfld, & ! CD field
  604. cids, cide, ckds, ckde, cjds, cjde, &
  605. cims, cime, ckms, ckme, cjms, cjme, &
  606. cits, cite, ckts, ckte, cjts, cjte, &
  607. nfld, & ! ND field
  608. nids, nide, nkds, nkde, njds, njde, &
  609. nims, nime, nkms, nkme, njms, njme, &
  610. nits, nite, nkts, nkte, njts, njte, &
  611. shw, & ! stencil half width for interp
  612. imask, & ! interpolation mask
  613. xstag, ystag, & ! staggering of field
  614. ipos, jpos, & ! Position of lower left of nest in CD
  615. nri, nrj ) ! nest ratios
  616. END SUBROUTINE p2c
  617. !==================================
  618. SUBROUTINE bdy_interp ( cfld, & ! CD field
  619. cids, cide, ckds, ckde, cjds, cjde, &
  620. cims, cime, ckms, ckme, cjms, cjme, &
  621. cits, cite, ckts, ckte, cjts, cjte, &
  622. nfld, & ! ND field
  623. nids, nide, nkds, nkde, njds, njde, &
  624. nims, nime, nkms, nkme, njms, njme, &
  625. nits, nite, nkts, nkte, njts, njte, &
  626. shw, & ! stencil half width
  627. imask, & ! interpolation mask
  628. xstag, ystag, & ! staggering of field
  629. ipos, jpos, & ! Position of lower left of nest in CD
  630. nri, nrj, & ! nest ratios
  631. cbdy_xs, nbdy_xs, &
  632. cbdy_xe, nbdy_xe, &
  633. cbdy_ys, nbdy_ys, &
  634. cbdy_ye, nbdy_ye, &
  635. cbdy_txs, nbdy_txs, &
  636. cbdy_txe, nbdy_txe, &
  637. cbdy_tys, nbdy_tys, &
  638. cbdy_tye, nbdy_tye, &
  639. cdt, ndt &
  640. ) ! boundary arrays
  641. USE module_configure
  642. IMPLICIT NONE
  643. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  644. cims, cime, ckms, ckme, cjms, cjme, &
  645. cits, cite, ckts, ckte, cjts, cjte, &
  646. nids, nide, nkds, nkde, njds, njde, &
  647. nims, nime, nkms, nkme, njms, njme, &
  648. nits, nite, nkts, nkte, njts, njte, &
  649. shw, &
  650. ipos, jpos, &
  651. nri, nrj
  652. LOGICAL, INTENT(IN) :: xstag, ystag
  653. REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
  654. REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
  655. INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
  656. REAL, DIMENSION( * ), INTENT(INOUT) :: cbdy_xs, cbdy_txs, nbdy_xs, nbdy_txs
  657. REAL, DIMENSION( * ), INTENT(INOUT) :: cbdy_xe, cbdy_txe, nbdy_xe, nbdy_txe
  658. REAL, DIMENSION( * ), INTENT(INOUT) :: cbdy_ys, cbdy_tys, nbdy_ys, nbdy_tys
  659. REAL, DIMENSION( * ), INTENT(INOUT) :: cbdy_ye, cbdy_tye, nbdy_ye, nbdy_tye
  660. REAL cdt, ndt
  661. ! Local
  662. INTEGER nijds, nijde, spec_bdy_width
  663. nijds = min(nids, njds)
  664. nijde = max(nide, njde)
  665. CALL nl_get_spec_bdy_width( 1, spec_bdy_width )
  666. CALL bdy_interp1( cfld, & ! CD field
  667. cids, cide, ckds, ckde, cjds, cjde, &
  668. cims, cime, ckms, ckme, cjms, cjme, &
  669. cits, cite, ckts, ckte, cjts, cjte, &
  670. nfld, & ! ND field
  671. nijds, nijde , spec_bdy_width , &
  672. nids, nide, nkds, nkde, njds, njde, &
  673. nims, nime, nkms, nkme, njms, njme, &
  674. nits, nite, nkts, nkte, njts, njte, &
  675. shw, imask, &
  676. xstag, ystag, & ! staggering of field
  677. ipos, jpos, & ! Position of lower left of nest in CD
  678. nri, nrj, &
  679. cbdy_xs, nbdy_xs, &
  680. cbdy_xe, nbdy_xe, &
  681. cbdy_ys, nbdy_ys, &
  682. cbdy_ye, nbdy_ye, &
  683. cbdy_txs, nbdy_txs, &
  684. cbdy_txe, nbdy_txe, &
  685. cbdy_tys, nbdy_tys, &
  686. cbdy_tye, nbdy_tye, &
  687. cdt, ndt &
  688. )
  689. RETURN
  690. END SUBROUTINE bdy_interp
  691. SUBROUTINE bdy_interp1( cfld, & ! CD field
  692. cids, cide, ckds, ckde, cjds, cjde, &
  693. cims, cime, ckms, ckme, cjms, cjme, &
  694. cits, cite, ckts, ckte, cjts, cjte, &
  695. nfld, & ! ND field
  696. nijds, nijde, spec_bdy_width , &
  697. nids, nide, nkds, nkde, njds, njde, &
  698. nims, nime, nkms, nkme, njms, njme, &
  699. nits, nite, nkts, nkte, njts, njte, &
  700. shw1, &
  701. imask, & ! interpolation mask
  702. xstag, ystag, & ! staggering of field
  703. ipos, jpos, & ! Position of lower left of nest in CD
  704. nri, nrj, &
  705. cbdy_xs, bdy_xs, &
  706. cbdy_xe, bdy_xe, &
  707. cbdy_ys, bdy_ys, &
  708. cbdy_ye, bdy_ye, &
  709. cbdy_txs, bdy_txs, &
  710. cbdy_txe, bdy_txe, &
  711. cbdy_tys, bdy_tys, &
  712. cbdy_tye, bdy_tye, &
  713. cdt, ndt &
  714. )
  715. USE module_configure
  716. use module_state_description
  717. IMPLICIT NONE
  718. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  719. cims, cime, ckms, ckme, cjms, cjme, &
  720. cits, cite, ckts, ckte, cjts, cjte, &
  721. nids, nide, nkds, nkde, njds, njde, &
  722. nims, nime, nkms, nkme, njms, njme, &
  723. nits, nite, nkts, nkte, njts, njte, &
  724. shw1, & ! ignore
  725. ipos, jpos, &
  726. nri, nrj
  727. INTEGER, INTENT(IN) :: nijds, nijde, spec_bdy_width
  728. LOGICAL, INTENT(IN) :: xstag, ystag
  729. REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ), INTENT(INOUT) :: cfld
  730. REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ), INTENT(INOUT) :: nfld
  731. INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
  732. REAL, DIMENSION ( * ), INTENT(INOUT) :: cbdy_xs, cbdy_txs ! not used
  733. REAL, DIMENSION ( * ), INTENT(INOUT) :: cbdy_xe, cbdy_txe ! not used
  734. REAL, DIMENSION ( * ), INTENT(INOUT) :: cbdy_ys, cbdy_tys ! not used
  735. REAL, DIMENSION ( * ), INTENT(INOUT) :: cbdy_ye, cbdy_tye ! not used
  736. REAL :: cdt, ndt
  737. REAL, DIMENSION ( njms:njme, nkms:nkme, spec_bdy_width ), INTENT(INOUT) :: bdy_xs, bdy_txs
  738. REAL, DIMENSION ( njms:njme, nkms:nkme, spec_bdy_width ), INTENT(INOUT) :: bdy_xe, bdy_txe
  739. REAL, DIMENSION ( nims:nime, nkms:nkme, spec_bdy_width ), INTENT(INOUT) :: bdy_ys, bdy_tys
  740. REAL, DIMENSION ( nims:nime, nkms:nkme, spec_bdy_width ), INTENT(INOUT) :: bdy_ye, bdy_tye
  741. ! Local
  742. REAL*8 rdt
  743. INTEGER ci, cj, ck, ni, nj, nk, ni1, nj1, nk1, ip, jp, ioff, joff
  744. #ifdef MM5_SINT
  745. INTEGER nfx, ior
  746. PARAMETER (ior=2)
  747. INTEGER nf
  748. REAL psca1(cims:cime,cjms:cjme,nri*nrj)
  749. REAL psca(cims:cime,cjms:cjme,nri*nrj)
  750. LOGICAL icmask( cims:cime, cjms:cjme )
  751. INTEGER i,j,k
  752. #endif
  753. INTEGER shw
  754. INTEGER spec_zone
  755. INTEGER relax_zone
  756. INTEGER sz
  757. INTEGER n2ci,n
  758. INTEGER n2cj
  759. ! statement functions for converting a nest index to coarse
  760. n2ci(n) = (n+ipos*nri-1)/nri
  761. n2cj(n) = (n+jpos*nrj-1)/nrj
  762. rdt = 1.D0/cdt
  763. shw = 0
  764. ioff = 0 ; joff = 0
  765. IF ( xstag ) THEN
  766. ioff = (nri-1)/2
  767. ENDIF
  768. IF ( ystag ) THEN
  769. joff = (nrj-1)/2
  770. ENDIF
  771. ! Iterate over the ND tile and compute the values
  772. ! from the CD tile.
  773. #ifdef MM5_SINT
  774. CALL nl_get_spec_zone( 1, spec_zone )
  775. CALL nl_get_relax_zone( 1, relax_zone )
  776. sz = MIN(MAX( spec_zone, relax_zone + 1 ),spec_bdy_width)
  777. nfx = nri * nrj
  778. !$OMP PARALLEL DO &
  779. !$OMP PRIVATE ( i,j,k,ni,nj,ni1,nj1,ci,cj,ip,jp,nk,ck,nf,icmask,psca,psca1 )
  780. DO k = ckts, ckte
  781. DO nf = 1,nfx
  782. DO j = cjms,cjme
  783. nj = (j-jpos) * nrj + ( nrj / 2 + 1 ) ! j point on nest
  784. DO i = cims,cime
  785. ni = (i-ipos) * nri + ( nri / 2 + 1 ) ! i point on nest
  786. psca1(i,j,nf) = cfld(i,k,j)
  787. ENDDO
  788. ENDDO
  789. ENDDO
  790. ! hopefully less ham handed but still correct and more efficient
  791. ! sintb ignores icmask so it does not matter that icmask is not set
  792. !
  793. ! SOUTH BDY
  794. IF ( njts .ge. njds .and. njts .le. njds + sz + joff ) THEN
  795. CALL sintb( psca1, psca, &
  796. cims, cime, cjms, cjme, icmask, &
  797. n2ci(nits)-1, n2ci(nite)+1, n2cj(MAX(njts,njds)), n2cj(MIN(njte,njds+sz+joff)), nrj*nri, xstag, ystag )
  798. ENDIF
  799. ! NORTH BDY
  800. IF ( njte .le. njde .and. njte .ge. njde - sz - joff ) THEN
  801. CALL sintb( psca1, psca, &
  802. cims, cime, cjms, cjme, icmask, &
  803. n2ci(nits)-1, n2ci(nite)+1, n2cj(MAX(njts,njde-sz-joff)), n2cj(MIN(njte,njde-1+joff)), nrj*nri, xstag, ystag )
  804. ENDIF
  805. ! WEST BDY
  806. IF ( nits .ge. nids .and. nits .le. nids + sz + ioff ) THEN
  807. CALL sintb( psca1, psca, &
  808. cims, cime, cjms, cjme, icmask, &
  809. n2ci(MAX(nits,nids)), n2ci(MIN(nite,nids+sz+ioff)), n2cj(njts)-1, n2cj(njte)+1, nrj*nri, xstag, ystag )
  810. ENDIF
  811. ! EAST BDY
  812. IF ( nite .le. nide .and. nite .ge. nide - sz - ioff ) THEN
  813. CALL sintb( psca1, psca, &
  814. cims, cime, cjms, cjme, icmask, &
  815. n2ci(MAX(nits,nide-sz-ioff)), n2ci(MIN(nite,nide-1+ioff)), n2cj(njts)-1, n2cj(njte)+1, nrj*nri, xstag, ystag )
  816. ENDIF
  817. DO nj1 = MAX(njds,njts-1), MIN(njde+joff,njte+joff+1)
  818. cj = jpos + (nj1-1) / nrj ! j coord of CD point
  819. jp = mod ( nj1-1 , nrj ) ! coord of ND w/i CD point
  820. nk = k
  821. ck = nk
  822. DO ni1 = MAX(nids,nits-1), MIN(nide+ioff,nite+ioff+1)
  823. ci = ipos + (ni1-1) / nri ! j coord of CD point
  824. ip = mod ( ni1-1 , nri ) ! coord of ND w/i CD point
  825. ni = ni1-ioff
  826. nj = nj1-joff
  827. IF ( ( ni.LT.nids) .OR. (nj.LT.njds) ) THEN
  828. CYCLE
  829. END IF
  830. !bdy contains the value at t-dt. psca contains the value at t
  831. !compute dv/dt and store in bdy_t
  832. !afterwards store the new value of v at t into bdy
  833. ! WEST
  834. IF ( ni .ge. nids .and. ni .lt. nids + sz ) THEN
  835. bdy_txs( nj,k,ni ) = rdt*(psca(ci+shw,cj+shw,ip+1+(jp)*nri)-nfld(ni,k,nj))
  836. bdy_xs( nj,k,ni ) = psca(ci+shw,cj+shw,ip+1+(jp)*nri )
  837. ENDIF
  838. ! SOUTH
  839. IF ( nj .ge. njds .and. nj .lt. njds + sz ) THEN
  840. bdy_tys( ni,k,nj ) = rdt*(psca(ci+shw,cj+shw,ip+1+(jp)*nri)-nfld(ni,k,nj))
  841. bdy_ys( ni,k,nj ) = psca(ci+shw,cj+shw,ip+1+(jp)*nri )
  842. ENDIF
  843. ! EAST
  844. IF ( xstag ) THEN
  845. IF ( ni .ge. nide - sz + 1 .AND. ni .le. nide ) THEN
  846. bdy_txe( nj,k,nide-ni+1 ) = rdt*(psca(ci+shw,cj+shw,ip+1+(jp)*nri)-nfld(ni,k,nj))
  847. bdy_xe( nj,k,nide-ni+1 ) = psca(ci+shw,cj+shw,ip+1+(jp)*nri )
  848. ENDIF
  849. ELSE
  850. IF ( ni .ge. nide - sz .AND. ni .le. nide-1 ) THEN
  851. bdy_txe( nj,k,nide-ni ) = rdt*(psca(ci+shw,cj+shw,ip+1+(jp)*nri)-nfld(ni,k,nj))
  852. bdy_xe( nj,k,nide-ni ) = psca(ci+shw,cj+shw,ip+1+(jp)*nri )
  853. ENDIF
  854. ENDIF
  855. ! NORTH
  856. IF ( ystag ) THEN
  857. IF ( nj .ge. njde - sz + 1 .AND. nj .le. njde ) THEN
  858. bdy_tye( ni,k,njde-nj+1 ) = rdt*(psca(ci+shw,cj+shw,ip+1+(jp)*nri)-nfld(ni,k,nj))
  859. bdy_ye( ni,k,njde-nj+1 ) = psca(ci+shw,cj+shw,ip+1+(jp)*nri )
  860. ENDIF
  861. ELSE
  862. IF ( nj .ge. njde - sz .AND. nj .le. njde-1 ) THEN
  863. bdy_tye(ni,k,njde-nj ) = rdt*(psca(ci+shw,cj+shw,ip+1+(jp)*nri)-nfld(ni,k,nj))
  864. bdy_ye( ni,k,njde-nj ) = psca(ci+shw,cj+shw,ip+1+(jp)*nri )
  865. ENDIF
  866. ENDIF
  867. ENDDO
  868. ENDDO
  869. ENDDO
  870. !$OMP END PARALLEL DO
  871. #endif
  872. RETURN
  873. END SUBROUTINE bdy_interp1
  874. SUBROUTINE interp_fcni( cfld, & ! CD field
  875. cids, cide, ckds, ckde, cjds, cjde, &
  876. cims, cime, ckms, ckme, cjms, cjme, &
  877. cits, cite, ckts, ckte, cjts, cjte, &
  878. nfld, & ! ND field
  879. nids, nide, nkds, nkde, njds, njde, &
  880. nims, nime, nkms, nkme, njms, njme, &
  881. nits, nite, nkts, nkte, njts, njte, &
  882. shw, & ! stencil half width
  883. imask, & ! interpolation mask
  884. xstag, ystag, & ! staggering of field
  885. ipos, jpos, & ! Position of lower left of nest in CD
  886. nri, nrj ) ! nest ratios
  887. USE module_configure
  888. IMPLICIT NONE
  889. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  890. cims, cime, ckms, ckme, cjms, cjme, &
  891. cits, cite, ckts, ckte, cjts, cjte, &
  892. nids, nide, nkds, nkde, njds, njde, &
  893. nims, nime, nkms, nkme, njms, njme, &
  894. nits, nite, nkts, nkte, njts, njte, &
  895. shw, &
  896. ipos, jpos, &
  897. nri, nrj
  898. LOGICAL, INTENT(IN) :: xstag, ystag
  899. INTEGER, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
  900. INTEGER, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
  901. INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
  902. ! Local
  903. INTEGER ci, cj, ck, ni, nj, nk, ip, jp
  904. ! Iterate over the ND tile and compute the values
  905. ! from the CD tile.
  906. !write(0,'("cits:cite, ckts:ckte, cjts:cjte ",6i4)')cits,cite, ckts,ckte, cjts,cjte
  907. !write(0,'("nits:nite, nkts:nkte, njts:njte ",6i4)')nits,nite, nkts,nkte, njts,njte
  908. DO nj = njts, njte
  909. cj = jpos + (nj-1) / nrj ! j coord of CD point
  910. jp = mod ( nj , nrj ) ! coord of ND w/i CD point
  911. DO nk = nkts, nkte
  912. ck = nk
  913. DO ni = nits, nite
  914. ci = ipos + (ni-1) / nri ! j coord of CD point
  915. ip = mod ( ni , nri ) ! coord of ND w/i CD point
  916. ! This is a trivial implementation of the interp_fcn; just copies
  917. ! the values from the CD into the ND
  918. nfld( ni, nk, nj ) = cfld( ci , ck , cj )
  919. ENDDO
  920. ENDDO
  921. ENDDO
  922. RETURN
  923. END SUBROUTINE interp_fcni
  924. SUBROUTINE interp_fcnm( cfld, & ! CD field
  925. cids, cide, ckds, ckde, cjds, cjde, &
  926. cims, cime, ckms, ckme, cjms, cjme, &
  927. cits, cite, ckts, ckte, cjts, cjte, &
  928. nfld, & ! ND field
  929. nids, nide, nkds, nkde, njds, njde, &
  930. nims, nime, nkms, nkme, njms, njme, &
  931. nits, nite, nkts, nkte, njts, njte, &
  932. shw, & ! stencil half width
  933. imask, & ! interpolation mask
  934. xstag, ystag, & ! staggering of field
  935. ipos, jpos, & ! Position of lower left of nest in CD
  936. nri, nrj ) ! nest ratios
  937. USE module_configure
  938. IMPLICIT NONE
  939. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  940. cims, cime, ckms, ckme, cjms, cjme, &
  941. cits, cite, ckts, ckte, cjts, cjte, &
  942. nids, nide, nkds, nkde, njds, njde, &
  943. nims, nime, nkms, nkme, njms, njme, &
  944. nits, nite, nkts, nkte, njts, njte, &
  945. shw, &
  946. ipos, jpos, &
  947. nri, nrj
  948. LOGICAL, INTENT(IN) :: xstag, ystag
  949. REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
  950. REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
  951. INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
  952. ! Local
  953. INTEGER ci, cj, ck, ni, nj, nk, ip, jp
  954. ! Iterate over the ND tile and compute the values
  955. ! from the CD tile.
  956. !write(0,'("mask cits:cite, ckts:ckte, cjts:cjte ",6i4)')cits,cite, ckts,ckte, cjts,cjte
  957. !write(0,'("mask nits:nite, nkts:nkte, njts:njte ",6i4)')nits,nite, nkts,nkte, njts,njte
  958. DO nj = njts, njte
  959. cj = jpos + (nj-1) / nrj ! j coord of CD point
  960. jp = mod ( nj , nrj ) ! coord of ND w/i CD point
  961. DO nk = nkts, nkte
  962. ck = nk
  963. DO ni = nits, nite
  964. ci = ipos + (ni-1) / nri ! j coord of CD point
  965. ip = mod ( ni , nri ) ! coord of ND w/i CD point
  966. ! This is a trivial implementation of the interp_fcn; just copies
  967. ! the values from the CD into the ND
  968. nfld( ni, nk, nj ) = cfld( ci , ck , cj )
  969. ENDDO
  970. ENDDO
  971. ENDDO
  972. RETURN
  973. END SUBROUTINE interp_fcnm
  974. SUBROUTINE interp_mask_land_field ( enable, & ! says whether to allow interpolation or just the bcasts
  975. cfld, & ! CD field
  976. cids, cide, ckds, ckde, cjds, cjde, &
  977. cims, cime, ckms, ckme, cjms, cjme, &
  978. cits, cite, ckts, ckte, cjts, cjte, &
  979. nfld, & ! ND field
  980. nids, nide, nkds, nkde, njds, njde, &
  981. nims, nime, nkms, nkme, njms, njme, &
  982. nits, nite, nkts, nkte, njts, njte, &
  983. shw, & ! stencil half width
  984. imask, & ! interpolation mask
  985. xstag, ystag, & ! staggering of field
  986. ipos, jpos, & ! Position of lower left of nest in CD
  987. nri, nrj, & ! nest ratios
  988. clu, nlu )
  989. USE module_configure
  990. USE module_wrf_error
  991. IMPLICIT NONE
  992. LOGICAL, INTENT(IN) :: enable
  993. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  994. cims, cime, ckms, ckme, cjms, cjme, &
  995. cits, cite, ckts, ckte, cjts, cjte, &
  996. nids, nide, nkds, nkde, njds, njde, &
  997. nims, nime, nkms, nkme, njms, njme, &
  998. nits, nite, nkts, nkte, njts, njte, &
  999. shw, &
  1000. ipos, jpos, &
  1001. nri, nrj
  1002. LOGICAL, INTENT(IN) :: xstag, ystag
  1003. REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
  1004. REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
  1005. INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
  1006. REAL, DIMENSION ( cims:cime, cjms:cjme ) :: clu
  1007. REAL, DIMENSION ( nims:nime, njms:njme ) :: nlu
  1008. ! Local
  1009. INTEGER ci, cj, ck, ni, nj, nk, ip, jp
  1010. INTEGER :: icount , ii , jj , ist , ien , jst , jen , iswater
  1011. REAL :: avg , sum , dx , dy
  1012. INTEGER , PARAMETER :: max_search = 5
  1013. CHARACTER*120 message
  1014. ! Find out what the water value is.
  1015. CALL nl_get_iswater(1,iswater)
  1016. ! Right now, only mass point locations permitted.
  1017. IF ( ( .NOT. xstag) .AND. ( .NOT. ystag ) ) THEN
  1018. ! Loop over each i,k,j in the nested domain.
  1019. IF ( enable ) THEN
  1020. DO nj = njts, njte
  1021. IF ( MOD ( nrj , 2 ) .EQ. 0 ) THEN
  1022. cj = ( nj + (nrj/2)-1 ) / nrj + jpos -1 ! first coarse position equal to or below nest point
  1023. ELSE
  1024. cj = ( nj + (nrj-1)/2 ) / nrj + jpos -1 ! first coarse position equal to or below nest point
  1025. END IF
  1026. DO nk = nkts, nkte
  1027. ck = nk
  1028. DO ni = nits, nite
  1029. IF ( MOD ( nri , 2 ) .EQ. 0 ) THEN
  1030. ci = ( ni + (nri/2)-1 ) / nri + ipos -1 ! first coarse position equal to or to the left of nest point
  1031. ELSE
  1032. ci = ( ni + (nri-1)/2 ) / nri + ipos -1 ! first coarse position equal to or to the left of nest point
  1033. END IF
  1034. !
  1035. ! (ci,cj+1) (ci+1,cj+1)
  1036. ! - -------------
  1037. ! 1-dy | | |
  1038. ! | | |
  1039. ! - | * |
  1040. ! dy | | (ni,nj) |
  1041. ! | | |
  1042. ! - -------------
  1043. ! (ci,cj) (ci+1,cj)
  1044. !
  1045. ! |--|--------|
  1046. ! dx 1-dx
  1047. ! For odd ratios, at (nri+1)/2, we are on the coarse grid point, so dx = 0
  1048. IF ( MOD ( nri , 2 ) .EQ. 0 ) THEN
  1049. dx = ( REAL ( MOD ( ni+(nri-1)/2 , nri ) ) + 0.5 ) / REAL ( nri )
  1050. ELSE
  1051. dx = REAL ( MOD ( ni+(nri-1)/2 , nri ) ) / REAL ( nri )
  1052. END IF
  1053. IF ( MOD ( nrj , 2 ) .EQ. 0 ) THEN
  1054. dy = ( REAL ( MOD ( nj+(nrj-1)/2 , nrj ) ) + 0.5 ) / REAL ( nrj )
  1055. ELSE
  1056. dy = REAL ( MOD ( nj+(nrj-1)/2 , nrj ) ) / REAL ( nrj )
  1057. END IF
  1058. ! This is a "land only" field. If this is a water point, no operations required.
  1059. IF ( ( NINT(nlu(ni ,nj )) .EQ. iswater ) ) THEN
  1060. nfld(ni,nk,nj) = cfld(ci ,ck,cj )
  1061. ! If this is a nested land point, and the surrounding coarse values are all land points,
  1062. ! then this is a simple 4-pt interpolation.
  1063. ELSE IF ( ( NINT(nlu(ni ,nj )) .NE. iswater ) .AND. &
  1064. ( NINT(clu(ci ,cj )) .NE. iswater ) .AND. &
  1065. ( NINT(clu(ci+1,cj )) .NE. iswater ) .AND. &
  1066. ( NINT(clu(ci ,cj+1)) .NE. iswater ) .AND. &
  1067. ( NINT(clu(ci+1,cj+1)) .NE. iswater ) ) THEN
  1068. nfld(ni,nk,nj) = ( 1. - dx ) * ( ( 1. - dy ) * cfld(ci ,ck,cj ) + &
  1069. dy * cfld(ci ,ck,cj+1) ) + &
  1070. dx * ( ( 1. - dy ) * cfld(ci+1,ck,cj ) + &
  1071. dy * cfld(ci+1,ck,cj+1) )
  1072. ! If this is a nested land point and there are NO coarse land values surrounding,
  1073. ! we temporarily punt.
  1074. ELSE IF ( ( NINT(nlu(ni ,nj )) .NE. iswater ) .AND. &
  1075. ( NINT(clu(ci ,cj )) .EQ. iswater ) .AND. &
  1076. ( NINT(clu(ci+1,cj )) .EQ. iswater ) .AND. &
  1077. ( NINT(clu(ci ,cj+1)) .EQ. iswater ) .AND. &
  1078. ( NINT(clu(ci+1,cj+1)) .EQ. iswater ) ) THEN
  1079. nfld(ni,nk,nj) = -1
  1080. ! If there are some water points and some land points, take an average.
  1081. ELSE IF ( NINT(nlu(ni ,nj )) .NE. iswater ) THEN
  1082. icount = 0
  1083. sum = 0
  1084. IF ( NINT(clu(ci ,cj )) .NE. iswater ) THEN
  1085. icount = icount + 1
  1086. sum = sum + cfld(ci ,ck,cj )
  1087. END IF
  1088. IF ( NINT(clu(ci+1,cj )) .NE. iswater ) THEN
  1089. icount = icount + 1
  1090. sum = sum + cfld(ci+1,ck,cj )
  1091. END IF
  1092. IF ( NINT(clu(ci ,cj+1)) .NE. iswater ) THEN
  1093. icount = icount + 1
  1094. sum = sum + cfld(ci ,ck,cj+1)
  1095. END IF
  1096. IF ( NINT(clu(ci+1,cj+1)) .NE. iswater ) THEN
  1097. icount = icount + 1
  1098. sum = sum + cfld(ci+1,ck,cj+1)
  1099. END IF
  1100. nfld(ni,nk,nj) = sum / REAL ( icount )
  1101. END IF
  1102. END DO
  1103. END DO
  1104. END DO
  1105. ! Get an average of the whole domain for problem locations.
  1106. sum = 0
  1107. icount = 0
  1108. DO nj = njts, njte
  1109. DO nk = nkts, nkte
  1110. DO ni = nits, nite
  1111. IF ( nfld(ni,nk,nj) .NE. -1 ) THEN
  1112. icount = icount + 1
  1113. sum = sum + nfld(ni,nk,nj)
  1114. END IF
  1115. END DO
  1116. END DO
  1117. END DO
  1118. ELSE
  1119. sum = 0.
  1120. icount = 0
  1121. ENDIF
  1122. CALL wrf_dm_bcast_real( sum, 1 )
  1123. CALL wrf_dm_bcast_integer( icount, 1 )
  1124. IF ( enable ) THEN
  1125. IF ( icount .GT. 0 ) THEN
  1126. avg = sum / REAL ( icount )
  1127. ! OK, if there were any of those island situations, we try to search a bit broader
  1128. ! of an area in the coarse grid.
  1129. DO nj = njts, njte
  1130. DO nk = nkts, nkte
  1131. DO ni = nits, nite
  1132. IF ( nfld(ni,nk,nj) .EQ. -1 ) THEN
  1133. IF ( MOD ( nrj , 2 ) .EQ. 0 ) THEN
  1134. cj = ( nj + (nrj/2)-1 ) / nrj + jpos -1 ! first coarse position equal to or below nest point
  1135. ELSE
  1136. cj = ( nj + (nrj-1)/2 ) / nrj + jpos -1 ! first coarse position equal to or below nest point
  1137. END IF
  1138. IF ( MOD ( nri , 2 ) .EQ. 0 ) THEN
  1139. ci = ( ni + (nri/2)-1 ) / nri + ipos -1 ! first coarse position equal to or to the left of nest point
  1140. ELSE
  1141. ci = ( ni + (nri-1)/2 ) / nri + ipos -1 ! first coarse position equal to or to the left of nest point
  1142. END IF
  1143. ist = MAX (ci-max_search,cits)
  1144. ien = MIN (ci+max_search,cite,cide-1)
  1145. jst = MAX (cj-max_search,cjts)
  1146. jen = MIN (cj+max_search,cjte,cjde-1)
  1147. icount = 0
  1148. sum = 0
  1149. DO jj = jst,jen
  1150. DO ii = ist,ien
  1151. IF ( NINT(clu(ii,jj)) .NE. iswater ) THEN
  1152. icount = icount + 1
  1153. sum = sum + cfld(ii,nk,jj)
  1154. END IF
  1155. END DO
  1156. END DO
  1157. IF ( icount .GT. 0 ) THEN
  1158. nfld(ni,nk,nj) = sum / REAL ( icount )
  1159. ELSE
  1160. ! CALL wrf_error_fatal ( "horizontal interp error - island" )
  1161. write(message,*) 'horizontal interp error - island, using average ', avg
  1162. CALL wrf_message ( message )
  1163. nfld(ni,nk,nj) = avg
  1164. END IF
  1165. END IF
  1166. END DO
  1167. END DO
  1168. END DO
  1169. ENDIF
  1170. ENDIF
  1171. ELSE
  1172. CALL wrf_error_fatal ( "only unstaggered fields right now" )
  1173. END IF
  1174. END SUBROUTINE interp_mask_land_field
  1175. SUBROUTINE interp_mask_water_field ( enable, & ! says whether to allow interpolation or just the bcasts
  1176. cfld, & ! CD field
  1177. cids, cide, ckds, ckde, cjds, cjde, &
  1178. cims, cime, ckms, ckme, cjms, cjme, &
  1179. cits, cite, ckts, ckte, cjts, cjte, &
  1180. nfld, & ! ND field
  1181. nids, nide, nkds, nkde, njds, njde, &
  1182. nims, nime, nkms, nkme, njms, njme, &
  1183. nits, nite, nkts, nkte, njts, njte, &
  1184. shw, & ! stencil half width
  1185. imask, & ! interpolation mask
  1186. xstag, ystag, & ! staggering of field
  1187. ipos, jpos, & ! Position of lower left of nest in CD
  1188. nri, nrj, & ! nest ratios
  1189. clu, nlu, cflag, nflag )
  1190. USE module_configure
  1191. USE module_wrf_error
  1192. IMPLICIT NONE
  1193. LOGICAL, INTENT(IN) :: enable
  1194. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  1195. cims, cime, ckms, ckme, cjms, cjme, &
  1196. cits, cite, ckts, ckte, cjts, cjte, &
  1197. nids, nide, nkds, nkde, njds, njde, &
  1198. nims, nime, nkms, nkme, njms, njme, &
  1199. nits, nite, nkts, nkte, njts, njte, &
  1200. shw, &
  1201. ipos, jpos, &
  1202. nri, nrj, cflag, nflag
  1203. LOGICAL, INTENT(IN) :: xstag, ystag
  1204. REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
  1205. REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
  1206. INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
  1207. REAL, DIMENSION ( cims:cime, cjms:cjme ) :: clu
  1208. REAL, DIMENSION ( nims:nime, njms:njme ) :: nlu
  1209. ! Local
  1210. INTEGER ci, cj, ck, ni, nj, nk, ip, jp
  1211. INTEGER :: icount , ii , jj , ist , ien , jst , jen
  1212. REAL :: avg , sum , dx , dy
  1213. INTEGER , PARAMETER :: max_search = 5
  1214. ! Right now, only mass point locations permitted.
  1215. IF ( ( .NOT. xstag) .AND. ( .NOT. ystag ) ) THEN
  1216. IF ( enable ) THEN
  1217. ! Loop over each i,k,j in the nested domain.
  1218. DO nj = njts, njte
  1219. IF ( MOD ( nrj , 2 ) .EQ. 0 ) THEN
  1220. cj = ( nj + (nrj/2)-1 ) / nrj + jpos -1 ! first coarse position equal to or below nest point
  1221. ELSE
  1222. cj = ( nj + (nrj-1)/2 ) / nrj + jpos -1 ! first coarse position equal to or below nest point
  1223. END IF
  1224. DO nk = nkts, nkte
  1225. ck = nk
  1226. DO ni = nits, nite
  1227. IF ( MOD ( nri , 2 ) .EQ. 0 ) THEN
  1228. ci = ( ni + (nri/2)-1 ) / nri + ipos -1 ! first coarse position equal to or to the left of nest point
  1229. ELSE
  1230. ci = ( ni + (nri-1)/2 ) / nri + ipos -1 ! first coarse position equal to or to the left of nest point
  1231. END IF
  1232. !
  1233. ! (ci,cj+1) (ci+1,cj+1)
  1234. ! - -------------
  1235. ! 1-dy | | |
  1236. ! | | |
  1237. ! - | * |
  1238. ! dy | | (ni,nj) |
  1239. ! | | |
  1240. ! - -------------
  1241. ! (ci,cj) (ci+1,cj)
  1242. !
  1243. ! |--|--------|
  1244. ! dx 1-dx
  1245. ! At ni=2, we are on the coarse grid point, so dx = 0
  1246. IF ( MOD ( nri , 2 ) .EQ. 0 ) THEN
  1247. dx = ( REAL ( MOD ( ni+(nri-1)/2 , nri ) ) + 0.5 ) / REAL ( nri )
  1248. ELSE
  1249. dx = REAL ( MOD ( ni+(nri-1)/2 , nri ) ) / REAL ( nri )
  1250. END IF
  1251. IF ( MOD ( nrj , 2 ) .EQ. 0 ) THEN
  1252. dy = ( REAL ( MOD ( nj+(nrj-1)/2 , nrj ) ) + 0.5 ) / REAL ( nrj )
  1253. ELSE
  1254. dy = REAL ( MOD ( nj+(nrj-1)/2 , nrj ) ) / REAL ( nrj )
  1255. END IF
  1256. ! This is a "water only" field. If this is a land point, no operations required.
  1257. IF ( ( NINT(nlu(ni ,nj )) .NE. nflag ) ) THEN
  1258. nfld(ni,nk,nj) = cfld(ci ,ck,cj )
  1259. ! If this is a nested water point, and the surrounding coarse values are all water points,
  1260. ! then this is a simple 4-pt interpolation.
  1261. ELSE IF ( ( NINT(nlu(ni ,nj )) .EQ. nflag ) .AND. &
  1262. ( NINT(clu(ci ,cj )) .EQ. nflag ) .AND. &
  1263. ( NINT(clu(ci+1,cj )) .EQ. nflag ) .AND. &
  1264. ( NINT(clu(ci ,cj+1)) .EQ. nflag ) .AND. &
  1265. ( NINT(clu(ci+1,cj+1)) .EQ. nflag ) ) THEN
  1266. nfld(ni,nk,nj) = ( 1. - dx ) * ( ( 1. - dy ) * cfld(ci ,ck,cj ) + &
  1267. dy * cfld(ci ,ck,cj+1) ) + &
  1268. dx * ( ( 1. - dy ) * cfld(ci+1,ck,cj ) + &
  1269. dy * cfld(ci+1,ck,cj+1) )
  1270. ! If this is a nested water point and there are NO coarse water values surrounding,
  1271. ! we temporarily punt.
  1272. ELSE IF ( ( NINT(nlu(ni ,nj )) .EQ. nflag ) .AND. &
  1273. ( NINT(clu(ci ,cj )) .NE. nflag ) .AND. &
  1274. ( NINT(clu(ci+1,cj )) .NE. nflag ) .AND. &
  1275. ( NINT(clu(ci ,cj+1)) .NE. nflag ) .AND. &
  1276. ( NINT(clu(ci+1,cj+1)) .NE. nflag ) ) THEN
  1277. nfld(ni,nk,nj) = -1
  1278. ! If there are some land points and some water points, take an average.
  1279. ELSE IF ( NINT(nlu(ni ,nj )) .EQ. nflag ) THEN
  1280. icount = 0
  1281. sum = 0
  1282. IF ( NINT(clu(ci ,cj )) .EQ. nflag ) THEN
  1283. icount = icount + 1
  1284. sum = sum + cfld(ci ,ck,cj )
  1285. END IF
  1286. IF ( NINT(clu(ci+1,cj )) .EQ. nflag ) THEN
  1287. icount = icount + 1
  1288. sum = sum + cfld(ci+1,ck,cj )
  1289. END IF
  1290. IF ( NINT(clu(ci ,cj+1)) .EQ. nflag ) THEN
  1291. icount = icount + 1
  1292. sum = sum + cfld(ci ,ck,cj+1)
  1293. END IF
  1294. IF ( NINT(clu(ci+1,cj+1)) .EQ. nflag ) THEN
  1295. icount = icount + 1
  1296. sum = sum + cfld(ci+1,ck,cj+1)
  1297. END IF
  1298. nfld(ni,nk,nj) = sum / REAL ( icount )
  1299. END IF
  1300. END DO
  1301. END DO
  1302. END DO
  1303. ! Get an average of the whole domain for problem locations.
  1304. sum = 0
  1305. icount = 0
  1306. DO nj = njts, njte
  1307. DO nk = nkts, nkte
  1308. DO ni = nits, nite
  1309. IF ( nfld(ni,nk,nj) .NE. -1 ) THEN
  1310. icount = icount + 1
  1311. sum = sum + nfld(ni,nk,nj)
  1312. END IF
  1313. END DO
  1314. END DO
  1315. END DO
  1316. ELSE
  1317. sum = 0.
  1318. icount = 0
  1319. ENDIF
  1320. CALL wrf_dm_bcast_real( sum, 1 )
  1321. CALL wrf_dm_bcast_integer( icount, 1 )
  1322. IF ( enable ) THEN
  1323. IF ( icount .NE. 0 ) THEN
  1324. avg = sum / REAL ( icount )
  1325. ! OK, if there were any of those lake situations, we try to search a bit broader
  1326. ! of an area in the coarse grid.
  1327. DO nj = njts, njte
  1328. DO nk = nkts, nkte
  1329. DO ni = nits, nite
  1330. IF ( nfld(ni,nk,nj) .EQ. -1 ) THEN
  1331. IF ( MOD ( nrj , 2 ) .EQ. 0 ) THEN
  1332. cj = ( nj + (nrj/2)-1 ) / nrj + jpos -1 ! first coarse position equal to or below nest point
  1333. ELSE
  1334. cj = ( nj + (nrj-1)/2 ) / nrj + jpos -1 ! first coarse position equal to or below nest point
  1335. END IF
  1336. IF ( MOD ( nri , 2 ) .EQ. 0 ) THEN
  1337. ci = ( ni + (nri/2)-1 ) / nri + ipos -1 ! first coarse position equal to or to the left of nest point
  1338. ELSE
  1339. ci = ( ni + (nri-1)/2 ) / nri + ipos -1 ! first coarse position equal to or to the left of nest point
  1340. END IF
  1341. ist = MAX (ci-max_search,cits)
  1342. ien = MIN (ci+max_search,cite,cide-1)
  1343. jst = MAX (cj-max_search,cjts)
  1344. jen = MIN (cj+max_search,cjte,cjde-1)
  1345. icount = 0
  1346. sum = 0
  1347. DO jj = jst,jen
  1348. DO ii = ist,ien
  1349. IF ( NINT(clu(ii,jj)) .EQ. nflag ) THEN
  1350. icount = icount + 1
  1351. sum = sum + cfld(ii,nk,jj)
  1352. END IF
  1353. END DO
  1354. END DO
  1355. IF ( icount .GT. 0 ) THEN
  1356. nfld(ni,nk,nj) = sum / REAL ( icount )
  1357. ELSE
  1358. ! CALL wrf_error_fatal ( "horizontal interp error - lake" )
  1359. print *,'horizontal interp error - lake, using average ',avg
  1360. nfld(ni,nk,nj) = avg
  1361. END IF
  1362. END IF
  1363. END DO
  1364. END DO
  1365. END DO
  1366. ENDIF
  1367. ENDIF
  1368. ELSE
  1369. CALL wrf_error_fatal ( "only unstaggered fields right now" )
  1370. END IF
  1371. END SUBROUTINE interp_mask_water_field
  1372. SUBROUTINE p2c_mask ( cfld, & ! CD field
  1373. cids, cide, ckds, ckde, cjds, cjde, &
  1374. cims, cime, ckms, ckme, cjms, cjme, &
  1375. cits, cite, ckts, ckte, cjts, cjte, &
  1376. nfld, & ! ND field
  1377. nids, nide, nkds, nkde, njds, njde, &
  1378. nims, nime, nkms, nkme, njms, njme, &
  1379. nits, nite, nkts, nkte, njts, njte, &
  1380. shw, & ! stencil half width
  1381. imask, & ! interpolation mask
  1382. xstag, ystag, & ! staggering of field
  1383. ipos, jpos, & ! Position of lower left of nest in CD
  1384. nri, nrj, & ! nest ratios
  1385. clu, nlu, & ! land use categories
  1386. ctslb,ntslb, & ! soil temps
  1387. cnum_soil_layers,nnum_soil_layers, & ! number of soil layers for tslb
  1388. ciswater, niswater ) ! iswater category
  1389. USE module_configure
  1390. USE module_wrf_error
  1391. IMPLICIT NONE
  1392. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  1393. cims, cime, ckms, ckme, cjms, cjme, &
  1394. cits, cite, ckts, ckte, cjts, cjte, &
  1395. nids, nide, nkds, nkde, njds, njde, &
  1396. nims, nime, nkms, nkme, njms, njme, &
  1397. nits, nite, nkts, nkte, njts, njte, &
  1398. shw, &
  1399. ipos, jpos, &
  1400. nri, nrj, &
  1401. cnum_soil_layers, nnum_soil_layers, &
  1402. ciswater, niswater
  1403. LOGICAL, INTENT(IN) :: xstag, ystag
  1404. REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
  1405. REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
  1406. INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
  1407. REAL, DIMENSION ( cims:cime, cjms:cjme ) :: clu
  1408. REAL, DIMENSION ( nims:nime, njms:njme ) :: nlu
  1409. REAL, DIMENSION ( cims:cime, 1:cnum_soil_layers, cjms:cjme ) :: ctslb
  1410. REAL, DIMENSION ( nims:nime, 1:nnum_soil_layers, njms:njme ) :: ntslb
  1411. ! Local
  1412. INTEGER ci, cj, ck, ni, nj, nk
  1413. INTEGER :: icount
  1414. REAL :: sum , dx , dy
  1415. ! Right now, only mass point locations permitted.
  1416. IF ( ( .NOT. xstag) .AND. ( .NOT. ystag ) ) THEN
  1417. ! Loop over each i,k,j in the nested domain.
  1418. DO nj = njts, MIN(njde-1,njte)
  1419. IF ( MOD ( nrj , 2 ) .EQ. 0 ) THEN
  1420. cj = ( nj + (nrj/2)-1 ) / nrj + jpos -1 ! first coarse position equal to or below nest point
  1421. ELSE
  1422. cj = ( nj + (nrj-1)/2 ) / nrj + jpos -1 ! first coarse position equal to or below nest point
  1423. END IF
  1424. DO nk = nkts, nkte
  1425. ck = nk
  1426. DO ni = nits, MIN(nide-1,nite)
  1427. IF ( MOD ( nri , 2 ) .EQ. 0 ) THEN
  1428. ci = ( ni + (nri/2)-1 ) / nri + ipos -1 ! first coarse position equal to or to the left of nest point
  1429. ELSE
  1430. ci = ( ni + (nri-1)/2 ) / nri + ipos -1 ! first coarse position equal to or to the left of nest point
  1431. END IF
  1432. !
  1433. ! (ci,cj+1) (ci+1,cj+1)
  1434. ! - -------------
  1435. ! 1-dy | | |
  1436. ! | | |
  1437. ! - | * |
  1438. ! dy | | (ni,nj) |
  1439. ! | | |
  1440. ! - -------------
  1441. ! (ci,cj) (ci+1,cj)
  1442. !
  1443. ! |--|--------|
  1444. ! dx 1-dx
  1445. ! At ni=2, we are on the coarse grid point, so dx = 0
  1446. IF ( MOD ( nri , 2 ) .EQ. 0 ) THEN
  1447. dx = ( REAL ( MOD ( ni+(nri-1)/2 , nri ) ) + 0.5 ) / REAL ( nri )
  1448. ELSE
  1449. dx = REAL ( MOD ( ni+(nri-1)/2 , nri ) ) / REAL ( nri )
  1450. END IF
  1451. IF ( MOD ( nrj , 2 ) .EQ. 0 ) THEN
  1452. dy = ( REAL ( MOD ( nj+(nrj-1)/2 , nrj ) ) + 0.5 ) / REAL ( nrj )
  1453. ELSE
  1454. dy = REAL ( MOD ( nj+(nrj-1)/2 , nrj ) ) / REAL ( nrj )
  1455. END IF
  1456. ! This is a "water only" field. If this is a land point, no operations required.
  1457. IF ( ( NINT(nlu(ni ,nj )) .NE. niswater ) ) THEN
  1458. nfld(ni,nk,nj) = 273.18
  1459. ! If this is a nested water point, and the surrounding coarse values are all water points,
  1460. ! then this is a simple 4-pt interpolation.
  1461. ELSE IF ( ( NINT(nlu(ni ,nj )) .EQ. niswater ) .AND. &
  1462. ( NINT(clu(ci ,cj )) .EQ. niswater ) .AND. &
  1463. ( NINT(clu(ci+1,cj )) .EQ. niswater ) .AND. &
  1464. ( NINT(clu(ci ,cj+1)) .EQ. niswater ) .AND. &
  1465. ( NINT(clu(ci+1,cj+1)) .EQ. niswater ) ) THEN
  1466. nfld(ni,nk,nj) = ( 1. - dx ) * ( ( 1. - dy ) * cfld(ci ,ck,cj ) + &
  1467. dy * cfld(ci ,ck,cj+1) ) + &
  1468. dx * ( ( 1. - dy ) * cfld(ci+1,ck,cj ) + &
  1469. dy * cfld(ci+1,ck,cj+1) )
  1470. ! If this is a nested water point and there are NO coarse water values surrounding,
  1471. ! we manufacture something from the deepest CG soil temp.
  1472. ELSE IF ( ( NINT(nlu(ni ,nj )) .EQ. niswater ) .AND. &
  1473. ( NINT(clu(ci ,cj )) .NE. niswater ) .AND. &
  1474. ( NINT(clu(ci+1,cj )) .NE. niswater ) .AND. &
  1475. ( NINT(clu(ci ,cj+1)) .NE. niswater ) .AND. &
  1476. ( NINT(clu(ci+1,cj+1)) .NE. niswater ) ) THEN
  1477. nfld(ni,nk,nj) = ( 1. - dx ) * ( ( 1. - dy ) * ctslb(ci ,cnum_soil_layers,cj ) + &
  1478. dy * ctslb(ci ,cnum_soil_layers,cj+1) ) + &
  1479. dx * ( ( 1. - dy ) * ctslb(ci+1,cnum_soil_layers,cj ) + &
  1480. dy * ctslb(ci+1,cnum_soil_layers,cj+1) )
  1481. ! If there are some land points and some water points, take an average of the water points.
  1482. ELSE IF ( NINT(nlu(ni ,nj )) .EQ. niswater ) THEN
  1483. icount = 0
  1484. sum = 0
  1485. IF ( NINT(clu(ci ,cj )) .EQ. niswater ) THEN
  1486. icount = icount + 1
  1487. sum = sum + cfld(ci ,ck,cj )
  1488. END IF
  1489. IF ( NINT(clu(ci+1,cj )) .EQ. niswater ) THEN
  1490. icount = icount + 1
  1491. sum = sum + cfld(ci+1,ck,cj )
  1492. END IF
  1493. IF ( NINT(clu(ci ,cj+1)) .EQ. niswater ) THEN
  1494. icount = icount + 1
  1495. sum = sum + cfld(ci ,ck,cj+1)
  1496. END IF
  1497. IF ( NINT(clu(ci+1,cj+1)) .EQ. niswater ) THEN
  1498. icount = icount + 1
  1499. sum = sum + cfld(ci+1,ck,cj+1)
  1500. END IF
  1501. nfld(ni,nk,nj) = sum / REAL ( icount )
  1502. END IF
  1503. END DO
  1504. END DO
  1505. END DO
  1506. ELSE
  1507. CALL wrf_error_fatal ( "only unstaggered fields right now" )
  1508. END IF
  1509. END SUBROUTINE p2c_mask
  1510. SUBROUTINE none
  1511. END SUBROUTINE none
  1512. SUBROUTINE smoother ( cfld , &
  1513. cids, cide, ckds, ckde, cjds, cjde, &
  1514. cims, cime, ckms, ckme, cjms, cjme, &
  1515. cits, cite, ckts, ckte, cjts, cjte, &
  1516. nids, nide, nkds, nkde, njds, njde, &
  1517. nims, nime, nkms, nkme, njms, njme, &
  1518. nits, nite, nkts, nkte, njts, njte, &
  1519. xstag, ystag, & ! staggering of field
  1520. ipos, jpos, & ! Position of lower left of nest in
  1521. nri, nrj &
  1522. )
  1523. USE module_configure
  1524. IMPLICIT NONE
  1525. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  1526. cims, cime, ckms, ckme, cjms, cjme, &
  1527. cits, cite, ckts, ckte, cjts, cjte, &
  1528. nids, nide, nkds, nkde, njds, njde, &
  1529. nims, nime, nkms, nkme, njms, njme, &
  1530. nits, nite, nkts, nkte, njts, njte, &
  1531. nri, nrj, &
  1532. ipos, jpos
  1533. LOGICAL, INTENT(IN) :: xstag, ystag
  1534. INTEGER :: smooth_option, feedback , spec_zone
  1535. REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
  1536. ! If there is no feedback, there can be no smoothing.
  1537. CALL nl_get_feedback ( 1, feedback )
  1538. IF ( feedback == 0 ) RETURN
  1539. CALL nl_get_spec_zone ( 1, spec_zone )
  1540. ! These are the 2d smoothers used on the fedback data. These filters
  1541. ! are run on the coarse grid data (after the nested info has been
  1542. ! fedback). Only the area of the nest in the coarse grid is filtered.
  1543. CALL nl_get_smooth_option ( 1, smooth_option )
  1544. IF ( smooth_option == 0 ) THEN
  1545. ! no op
  1546. ELSE IF ( smooth_option == 1 ) THEN
  1547. CALL sm121 ( cfld , &
  1548. cids, cide, ckds, ckde, cjds, cjde, &
  1549. cims, cime, ckms, ckme, cjms, cjme, &
  1550. cits, cite, ckts, ckte, cjts, cjte, &
  1551. xstag, ystag, & ! staggering of field
  1552. nids, nide, nkds, nkde, njds, njde, &
  1553. nims, nime, nkms, nkme, njms, njme, &
  1554. nits, nite, nkts, nkte, njts, njte, &
  1555. nri, nrj, &
  1556. ipos, jpos & ! Position of lower left of nest in
  1557. )
  1558. ELSE IF ( smooth_option == 2 ) THEN
  1559. CALL smdsm ( cfld , &
  1560. cids, cide, ckds, ckde, cjds, cjde, &
  1561. cims, cime, ckms, ckme, cjms, cjme, &
  1562. cits, cite, ckts, ckte, cjts, cjte, &
  1563. xstag, ystag, & ! staggering of field
  1564. nids, nide, nkds, nkde, njds, njde, &
  1565. nims, nime, nkms, nkme, njms, njme, &
  1566. nits, nite, nkts, nkte, njts, njte, &
  1567. nri, nrj, &
  1568. ipos, jpos & ! Position of lower left of nest in
  1569. )
  1570. END IF
  1571. END SUBROUTINE smoother
  1572. SUBROUTINE sm121 ( cfld , &
  1573. cids, cide, ckds, ckde, cjds, cjde, &
  1574. cims, cime, ckms, ckme, cjms, cjme, &
  1575. cits, cite, ckts, ckte, cjts, cjte, &
  1576. xstag, ystag, & ! staggering of field
  1577. nids, nide, nkds, nkde, njds, njde, &
  1578. nims, nime, nkms, nkme, njms, njme, &
  1579. nits, nite, nkts, nkte, njts, njte, &
  1580. nri, nrj, &
  1581. ipos, jpos & ! Position of lower left of nest in
  1582. )
  1583. USE module_configure
  1584. IMPLICIT NONE
  1585. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  1586. cims, cime, ckms, ckme, cjms, cjme, &
  1587. cits, cite, ckts, ckte, cjts, cjte, &
  1588. nids, nide, nkds, nkde, njds, njde, &
  1589. nims, nime, nkms, nkme, njms, njme, &
  1590. nits, nite, nkts, nkte, njts, njte, &
  1591. nri, nrj, &
  1592. ipos, jpos
  1593. LOGICAL, INTENT(IN) :: xstag, ystag
  1594. REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
  1595. REAL, DIMENSION ( cims:cime, cjms:cjme ) :: cfldnew
  1596. INTEGER :: i , j , k , loop
  1597. INTEGER :: istag,jstag
  1598. INTEGER, PARAMETER :: smooth_passes = 1 ! More passes requires a larger stencil (currently 48 pt)
  1599. istag = 1 ; jstag = 1
  1600. IF ( xstag ) istag = 0
  1601. IF ( ystag ) jstag = 0
  1602. ! Simple 1-2-1 smoother.
  1603. smoothing_passes : DO loop = 1 , smooth_passes
  1604. DO k = ckts , ckte
  1605. ! Initialize dummy cfldnew
  1606. DO i = MAX(ipos,cits-3) , MIN(ipos+(nide-nids)/nri,cite+3)
  1607. DO j = MAX(jpos,cjts-3) , MIN(jpos+(njde-njds)/nrj,cjte+3)
  1608. cfldnew(i,j) = cfld(i,k,j)
  1609. END DO
  1610. END DO
  1611. ! 1-2-1 smoothing in the j direction first,
  1612. DO i = MAX(ipos+2,cits-2) , MIN(ipos+(nide-nids)/nri-2-istag,cite+2)
  1613. DO j = MAX(jpos+2,cjts-2) , MIN(jpos+(njde-njds)/nrj-2-jstag,cjte+2)
  1614. cfldnew(i,j) = 0.25 * ( cfld(i,k,j+1) + 2.*cfld(i,k,j) + cfld(i,k,j-1) )
  1615. END DO
  1616. END DO
  1617. ! then 1-2-1 smoothing in the i direction last
  1618. DO j = MAX(jpos+2,cjts-2) , MIN(jpos+(njde-njds)/nrj-2-jstag,cjte+2)
  1619. DO i = MAX(ipos+2,cits-2) , MIN(ipos+(nide-nids)/nri-2-istag,cite+2)
  1620. cfld(i,k,j) = 0.25 * ( cfldnew(i+1,j) + 2.*cfldnew(i,j) + cfldnew(i-1,j) )
  1621. END DO
  1622. END DO
  1623. END DO
  1624. END DO smoothing_passes
  1625. END SUBROUTINE sm121
  1626. SUBROUTINE smdsm ( cfld , &
  1627. cids, cide, ckds, ckde, cjds, cjde, &
  1628. cims, cime, ckms, ckme, cjms, cjme, &
  1629. cits, cite, ckts, ckte, cjts, cjte, &
  1630. xstag, ystag, & ! staggering of field
  1631. nids, nide, nkds, nkde, njds, njde, &
  1632. nims, nime, nkms, nkme, njms, njme, &
  1633. nits, nite, nkts, nkte, njts, njte, &
  1634. nri, nrj, &
  1635. ipos, jpos & ! Position of lower left of nest in
  1636. )
  1637. USE module_configure
  1638. IMPLICIT NONE
  1639. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  1640. cims, cime, ckms, ckme, cjms, cjme, &
  1641. cits, cite, ckts, ckte, cjts, cjte, &
  1642. nids, nide, nkds, nkde, njds, njde, &
  1643. nims, nime, nkms, nkme, njms, njme, &
  1644. nits, nite, nkts, nkte, njts, njte, &
  1645. nri, nrj, &
  1646. ipos, jpos
  1647. LOGICAL, INTENT(IN) :: xstag, ystag
  1648. REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
  1649. REAL, DIMENSION ( cims:cime, cjms:cjme ) :: cfldnew
  1650. REAL , DIMENSION ( 2 ) :: xnu
  1651. INTEGER :: i , j , k , loop , n
  1652. INTEGER :: istag,jstag
  1653. INTEGER, PARAMETER :: smooth_passes = 1 ! More passes requires a larger stencil (currently 48 pt)
  1654. xnu = (/ 0.50 , -0.52 /)
  1655. istag = 1 ; jstag = 1
  1656. IF ( xstag ) istag = 0
  1657. IF ( ystag ) jstag = 0
  1658. ! The odd number passes of this are the "smoother", the even
  1659. ! number passes are the "de-smoother" (note the different signs on xnu).
  1660. smoothing_passes : DO loop = 1 , smooth_passes * 2
  1661. n = 2 - MOD ( loop , 2 )
  1662. DO k = ckts , ckte
  1663. DO i = MAX(ipos+2,cits-2) , MIN(ipos+(nide-nids)/nri-2-istag,cite+2)
  1664. DO j = MAX(jpos+2,cjts-2) , MIN(jpos+(njde-njds)/nrj-2-jstag,cjte+2)
  1665. cfldnew(i,j) = cfld(i,k,j) + xnu(n) * ((cfld(i,k,j+1) + cfld(i,k,j-1)) * 0.5-cfld(i,k,j))
  1666. END DO
  1667. END DO
  1668. DO i = MAX(ipos+2,cits-2) , MIN(ipos+(nide-nids)/nri-2-istag,cite+2)
  1669. DO j = MAX(jpos+2,cjts-2) , MIN(jpos+(njde-njds)/nrj-2-jstag,cjte+2)
  1670. cfld(i,k,j) = cfldnew(i,j)
  1671. END DO
  1672. END DO
  1673. DO j = MAX(jpos+2,cjts-2) , MIN(jpos+(njde-njds)/nrj-2-jstag,cjte+2)
  1674. DO i = MAX(ipos+2,cits-2) , MIN(ipos+(nide-nids)/nri-2-istag,cite+2)
  1675. cfldnew(i,j) = cfld(i,k,j) + xnu(n) * ((cfld(i+1,k,j) + cfld(i-1,k,j)) * 0.5-cfld(i,k,j))
  1676. END DO
  1677. END DO
  1678. DO j = MAX(jpos+2,cjts-2) , MIN(jpos+(njde-njds)/nrj-2-jstag,cjte+2)
  1679. DO i = MAX(ipos+2,cits-2) , MIN(ipos+(nide-nids)/nri-2-istag,cite+2)
  1680. cfld(i,k,j) = cfldnew(i,j)
  1681. END DO
  1682. END DO
  1683. END DO
  1684. END DO smoothing_passes
  1685. END SUBROUTINE smdsm
  1686. !==================================
  1687. ! this is used to modify a field over the nest so we can see where the nest is
  1688. SUBROUTINE mark_domain ( cfld, & ! CD field
  1689. cids, cide, ckds, ckde, cjds, cjde, &
  1690. cims, cime, ckms, ckme, cjms, cjme, &
  1691. cits, cite, ckts, ckte, cjts, cjte, &
  1692. nfld, & ! ND field
  1693. nids, nide, nkds, nkde, njds, njde, &
  1694. nims, nime, nkms, nkme, njms, njme, &
  1695. nits, nite, nkts, nkte, njts, njte, &
  1696. shw, & ! stencil half width for interp
  1697. imask, & ! interpolation mask
  1698. xstag, ystag, & ! staggering of field
  1699. ipos, jpos, & ! Position of lower left of nest in CD
  1700. nri, nrj ) ! nest ratios
  1701. USE module_configure
  1702. USE module_wrf_error
  1703. IMPLICIT NONE
  1704. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  1705. cims, cime, ckms, ckme, cjms, cjme, &
  1706. cits, cite, ckts, ckte, cjts, cjte, &
  1707. nids, nide, nkds, nkde, njds, njde, &
  1708. nims, nime, nkms, nkme, njms, njme, &
  1709. nits, nite, nkts, nkte, njts, njte, &
  1710. shw, &
  1711. ipos, jpos, &
  1712. nri, nrj
  1713. LOGICAL, INTENT(IN) :: xstag, ystag
  1714. REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ), INTENT(OUT) :: cfld
  1715. REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ), INTENT(IN) :: nfld
  1716. INTEGER, DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: imask
  1717. ! Local
  1718. INTEGER ci, cj, ck, ni, nj, nk, ip, jp, ioff, joff, ioffa, joffa
  1719. INTEGER :: icmin,icmax,jcmin,jcmax
  1720. INTEGER :: istag,jstag, ipoints,jpoints,ijpoints
  1721. istag = 1 ; jstag = 1
  1722. IF ( xstag ) istag = 0
  1723. IF ( ystag ) jstag = 0
  1724. DO cj = MAX(jpos+1,cjts),MIN(jpos+(njde-njds)/nrj-jstag-1,cjte)
  1725. nj = (cj-jpos)*nrj + jstag + 1
  1726. DO ck = ckts, ckte
  1727. nk = ck
  1728. DO ci = MAX(ipos+1,cits),MIN(ipos+(nide-nids)/nri-istag-1,cite)
  1729. ni = (ci-ipos)*nri + istag + 1
  1730. cfld( ci, ck, cj ) = 9021000. !magic number: Beverly Hills * 100.
  1731. ENDDO
  1732. ENDDO
  1733. ENDDO
  1734. END SUBROUTINE mark_domain
  1735. #if ( NMM_CORE == 1 )
  1736. !=======================================================================================
  1737. ! E grid interpolation for mass with addition of terrain adjustments. First routine
  1738. ! pertains to initial conditions and the next one corresponds to boundary conditions
  1739. ! This is gopal's doing
  1740. !=======================================================================================
  1741. SUBROUTINE interp_mass_nmm (cfld, & ! CD field
  1742. cids, cide, ckds, ckde, cjds, cjde, &
  1743. cims, cime, ckms, ckme, cjms, cjme, &
  1744. cits, cite, ckts, ckte, cjts, cjte, &
  1745. nfld, & ! ND field
  1746. nids, nide, nkds, nkde, njds, njde, &
  1747. nims, nime, nkms, nkme, njms, njme, &
  1748. nits, nite, nkts, nkte, njts, njte, &
  1749. shw, & ! stencil half width for interp
  1750. imask, & ! interpolation mask
  1751. xstag, ystag, & ! staggering of field
  1752. ipos, jpos, & ! Position of lower left of nest in CD
  1753. nri, nrj, & ! nest ratios
  1754. CII, IIH, CJJ, JJH, CBWGT1, HBWGT1, & ! south-western grid locs and weights
  1755. CBWGT2, HBWGT2, CBWGT3, HBWGT3, & ! note that "C"ourse grid ones are
  1756. CBWGT4, HBWGT4, & ! dummys for weights
  1757. CZ3d, Z3d, & ! Z3d interpolated from CZ3d
  1758. CFIS,FIS, & ! CFIS dummy on fine domain
  1759. CSM,SM, & ! CSM is dummy
  1760. CPDTOP,PDTOP, &
  1761. CPTOP,PTOP, &
  1762. CPSTD,PSTD, &
  1763. CKZMAX,KZMAX )
  1764. USE MODULE_MODEL_CONSTANTS
  1765. USE module_timing
  1766. IMPLICIT NONE
  1767. LOGICAL,INTENT(IN) :: xstag, ystag
  1768. INTEGER,INTENT(IN) :: ckzmax,kzmax
  1769. INTEGER,INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  1770. cims, cime, ckms, ckme, cjms, cjme, &
  1771. cits, cite, ckts, ckte, cjts, cjte, &
  1772. nids, nide, nkds, nkde, njds, njde, &
  1773. nims, nime, nkms, nkme, njms, njme, &
  1774. nits, nite, nkts, nkte, njts, njte, &
  1775. shw,ipos,jpos,nri,nrj
  1776. INTEGER,DIMENSION(nims:nime,njms:njme), INTENT(IN) :: IMASK
  1777. ! parent domain
  1778. INTEGER,DIMENSION(cims:cime,cjms:cjme), INTENT(IN) :: CII,CJJ ! dummy
  1779. REAL,DIMENSION(cims:cime,cjms:cjme), INTENT(IN) :: CBWGT1,CBWGT2,CBWGT3
  1780. REAL,DIMENSION(cims:cime,cjms:cjme), INTENT(IN) :: CBWGT4,CFIS,CSM
  1781. REAL,DIMENSION(cims:cime,cjms:cjme,ckms:ckme), INTENT(IN) :: CFLD
  1782. REAL,DIMENSION(cims:cime,cjms:cjme,1:KZMAX), INTENT(IN) :: CZ3d
  1783. REAL,DIMENSION(1:KZMAX), INTENT(IN) :: CPSTD
  1784. REAL,INTENT(IN) :: CPDTOP,CPTOP
  1785. ! nested domain
  1786. INTEGER,DIMENSION(nims:nime,njms:njme), INTENT(IN) :: IIH,JJH
  1787. REAL,DIMENSION(nims:nime,njms:njme), INTENT(IN) :: HBWGT1,HBWGT2,HBWGT3
  1788. REAL,DIMENSION(nims:nime,njms:njme), INTENT(IN) :: HBWGT4
  1789. REAL,DIMENSION(nims:nime,njms:njme), INTENT(IN) :: FIS,SM
  1790. REAL,DIMENSION(nims:nime,njms:njme,nkms:nkme), INTENT(INOUT) :: NFLD
  1791. REAL,DIMENSION(1:KZMAX), INTENT(IN) :: PSTD
  1792. REAL,DIMENSION(nims:nime,njms:njme,1:KZMAX), INTENT(OUT) :: Z3d
  1793. REAL,INTENT(IN) :: PDTOP,PTOP
  1794. ! local
  1795. INTEGER,PARAMETER :: JTB=134
  1796. REAL, PARAMETER :: LAPSR=6.5E-3,GI=1./G, D608=0.608
  1797. REAL, PARAMETER :: COEF3=R_D*GI*LAPSR
  1798. INTEGER :: I,J,K,IDUM
  1799. REAL :: dlnpdz,tvout,pmo
  1800. REAL,DIMENSION(nims:nime,njms:njme) :: ZS,DUM2d
  1801. REAL,DIMENSION(JTB) :: PIN,ZIN,Y2,PIO,ZOUT,DUM1,DUM2
  1802. !-----------------------------------------------------------------------------------------------------
  1803. !
  1804. !*** CHECK DOMAIN BOUNDS BEFORE INTERPOLATION
  1805. !
  1806. DO J=NJTS,MIN(NJTE,NJDE-1)
  1807. DO I=NITS,MIN(NITE,NIDE-1)
  1808. IF(IIH(i,j).LT.(CIDS-shw) .OR. IIH(i,j).GT.(CIDE+shw)) &
  1809. CALL wrf_error_fatal ('mass points:check domain bounds along x' )
  1810. IF(JJH(i,j).LT.(CJDS-shw) .OR. JJH(i,j).GT.(CJDE+shw)) &
  1811. CALL wrf_error_fatal ('mass points:check domain bounds along y' )
  1812. ENDDO
  1813. ENDDO
  1814. IF(KZMAX .GT. (JTB-10)) &
  1815. CALL wrf_error_fatal ('mass points: increase JTB in interp_mass_nmm')
  1816. ! WRITE(21,*)'------------- MED NEST INITIAL 1 ----------------'
  1817. ! DO J=NJTS,MIN(NJTE,NJDE-1)
  1818. ! DO I=NITS,MIN(NITE,NIDE-1)
  1819. ! WRITE(21,*)I,J,IMASK(I,J),NFLD(I,1,J)
  1820. ! ENDDO
  1821. ! ENDDO
  1822. ! WRITE(21,*)
  1823. !
  1824. !*** DEFINE LOCAL TOPOGRAPHY ON THE BASIS OF FIS. ALSO CHECK IF SM IS LAND (SM=0) OVER TOPO
  1825. !*** YOU DON'T WANT MOUNTAINS INSIDE WATER BODIES!
  1826. !
  1827. DO J=NJTS,MIN(NJTE,NJDE-1)
  1828. DO I=NITS,MIN(NITE,NIDE-1)
  1829. ZS(I,J)=FIS(I,J)/G
  1830. ENDDO
  1831. ENDDO
  1832. !
  1833. !*** Interpolate GPMs DERIVED FROM STANDARD ATMOSPHERIC LAPSE RATE FROM THE PARENT TO
  1834. !*** THE NESTED DOMAIN
  1835. !
  1836. !*** INDEX CONVENTIONS
  1837. !*** HBWGT4
  1838. !*** 4
  1839. !***
  1840. !***
  1841. !***
  1842. !*** h
  1843. !*** 1 2
  1844. !*** HBWGT1 HBWGT2
  1845. !***
  1846. !***
  1847. !*** 3
  1848. !*** HBWGT3
  1849. Z3d=0.0
  1850. DO K=NKTS,KZMAX ! Please note that we are still in isobaric surfaces
  1851. DO J=NJTS,MIN(NJTE,NJDE-1)
  1852. DO I=NITS,MIN(NITE,NIDE-1)
  1853. !
  1854. IF(MOD(JJH(I,J),2) .NE. 0)THEN ! 1,3,5,7
  1855. Z3d(I,J,K) = HBWGT1(I,J)*CZ3d(IIH(I,J), JJH(I,J) ,K) &
  1856. + HBWGT2(I,J)*CZ3d(IIH(I,J)+1,JJH(I,J) ,K) &
  1857. + HBWGT3(I,J)*CZ3d(IIH(I,J), JJH(I,J)-1,K) &
  1858. + HBWGT4(I,J)*CZ3d(IIH(I,J), JJH(I,J)+1,K)
  1859. ELSE
  1860. Z3d(I,J,K) = HBWGT1(I,J)*CZ3d(IIH(I,J), JJH(I,J) ,K) &
  1861. + HBWGT2(I,J)*CZ3d(IIH(I,J)+1,JJH(I,J) ,K) &
  1862. + HBWGT3(I,J)*CZ3d(IIH(I,J)+1,JJH(I,J)-1,K) &
  1863. + HBWGT4(I,J)*CZ3d(IIH(I,J)+1,JJH(I,J)+1,K)
  1864. ENDIF
  1865. !
  1866. ENDDO
  1867. ENDDO
  1868. ENDDO
  1869. ! RECONSTRUCT PDs ON THE BASIS OF TOPOGRAPHY AND THE INTERPOLATED HEIGHTS
  1870. DO J=NJTS,MIN(NJTE,NJDE-1)
  1871. DO I=NITS,MIN(NITE,NIDE-1)
  1872. !
  1873. IF (ZS(I,J) .LT. Z3d(I,J,1)) THEN
  1874. dlnpdz = (log(PSTD(1))-log(PSTD(2)) )/(Z3d(i,j,1)-Z3d(i,j,2))
  1875. dum2d(i,j) = exp(log(PSTD(1)) + dlnpdz*(ZS(I,J) - Z3d(i,j,1)))
  1876. dum2d(i,j) = dum2d(i,j) - PDTOP -PTOP
  1877. ELSE ! target level bounded by input levels
  1878. DO K =NKTS,KZMAX-1 ! still in the isobaric surfaces
  1879. IF(ZS(I,J) .GE. Z3d(I,J,K) .AND. ZS(I,J) .LT. Z3d(I,J,K+1))THEN
  1880. dlnpdz = (log(PSTD(K))-log(PSTD(K+1)) ) /(Z3d(I,J,K)-Z3d(I,J,K+1))
  1881. dum2d(i,j) = exp(log(PSTD(K)) + dlnpdz*(ZS(I,J)- Z3d(I,J,K)))
  1882. dum2d(i,j) = dum2d(i,j) - PDTOP -PTOP
  1883. ENDIF
  1884. ENDDO
  1885. ENDIF
  1886. IF(ZS(I,J) .GE. Z3d(I,J,KZMAX))THEN
  1887. WRITE(0,*)'I=',I,'J=',J,'K=',KZMAX,'TERRAIN HEIGHT',ZS(I,J),'Z3d',Z3d(I,J,KZMAX)
  1888. CALL wrf_error_fatal3 ( "interp_fcn.b" , 176 , "MOUNTAIN TOO HIGH TO FIT THE MODEL DEPTH")
  1889. ENDIF
  1890. !
  1891. ENDDO
  1892. ENDDO
  1893. DO K=NKDS,NKDE ! NKTE is 1, nevertheless let us pretend religious
  1894. DO J=NJTS,MIN(NJTE,NJDE-1)
  1895. DO I=NITS,MIN(NITE,NIDE-1)
  1896. IF(IMASK(I,J) .NE. 1)THEN
  1897. NFLD(I,J,K)= dum2d(i,j) ! PD defined in the nested domain
  1898. ENDIF
  1899. ENDDO
  1900. ENDDO
  1901. ENDDO
  1902. !
  1903. END SUBROUTINE interp_mass_nmm
  1904. !
  1905. !--------------------------------------------------------------------------------------
  1906. SUBROUTINE nmm_bdymass_hinterp ( cfld, & ! CD field
  1907. cids, cide, ckds, ckde, cjds, cjde, &
  1908. cims, cime, ckms, ckme, cjms, cjme, &
  1909. cits, cite, ckts, ckte, cjts, cjte, &
  1910. nfld, & ! ND field
  1911. nids, nide, nkds, nkde, njds, njde, &
  1912. nims, nime, nkms, nkme, njms, njme, &
  1913. nits, nite, nkts, nkte, njts, njte, &
  1914. shw, & ! stencil half width
  1915. imask, & ! interpolation mask
  1916. xstag, ystag, & ! staggering of field
  1917. ipos, jpos, & ! Position of lower left of nest in CD
  1918. nri, nrj, & ! nest ratios
  1919. c_bxs,n_bxs, &
  1920. c_bxe,n_bxe, &
  1921. c_bys,n_bys, &
  1922. c_bye,n_bye, &
  1923. c_btxs,n_btxs, &
  1924. c_btxe,n_btxe, &
  1925. c_btys,n_btys, &
  1926. c_btye,n_btye, &
  1927. CTEMP_B,NTEMP_B, & ! These temp arrays should be removed
  1928. CTEMP_BT,NTEMP_BT, & ! later on
  1929. CII, IIH, CJJ, JJH, CBWGT1, HBWGT1, & ! south-western grid locs and weights
  1930. CBWGT2, HBWGT2, CBWGT3, HBWGT3, & ! note that "C"ourse grid ones are
  1931. CBWGT4, HBWGT4, & ! dummys
  1932. CZ3d, Z3d, & ! Z3d dummy on nested domain
  1933. CFIS,FIS, & ! CFIS dummy on fine domain
  1934. CSM,SM, & ! CSM is dummy
  1935. CPDTOP,PDTOP, &
  1936. CPTOP,PTOP, &
  1937. CPSTD,PSTD, &
  1938. CKZMAX,KZMAX )
  1939. USE MODULE_MODEL_CONSTANTS
  1940. USE module_configure
  1941. USE module_wrf_error
  1942. IMPLICIT NONE
  1943. INTEGER, INTENT(IN) :: ckzmax,kzmax
  1944. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  1945. cims, cime, ckms, ckme, cjms, cjme, &
  1946. cits, cite, ckts, ckte, cjts, cjte, &
  1947. nids, nide, nkds, nkde, njds, njde, &
  1948. nims, nime, nkms, nkme, njms, njme, &
  1949. nits, nite, nkts, nkte, njts, njte, &
  1950. shw, &
  1951. ipos, jpos, &
  1952. nri, nrj
  1953. REAL, DIMENSION ( cims:cime, cjms:cjme, ckms:ckme ), INTENT(OUT) :: ctemp_b,ctemp_bt
  1954. REAL, DIMENSION ( nims:nime, njms:njme, nkms:nkme ), INTENT(OUT) :: ntemp_b,ntemp_bt
  1955. LOGICAL, INTENT(IN) :: xstag, ystag
  1956. REAL, DIMENSION( * ), INTENT(INOUT) :: c_bxs,n_bxs,c_bxe,n_bxe,c_bys,n_bys,c_bye,n_bye
  1957. REAL, DIMENSION( * ), INTENT(INOUT) :: c_btxs,n_btxs,c_btxe,n_btxe,c_btys,n_btys,c_btye,n_btye
  1958. ! parent domain
  1959. INTEGER,DIMENSION(nims:nime,njms:njme), INTENT(IN) :: IMASK
  1960. INTEGER,DIMENSION(cims:cime,cjms:cjme), INTENT(IN) :: CII,CJJ ! dummy
  1961. REAL,DIMENSION(cims:cime,cjms:cjme), INTENT(IN) :: CBWGT1,CBWGT2,CBWGT3
  1962. REAL,DIMENSION(cims:cime,cjms:cjme), INTENT(IN) :: CBWGT4,CFIS,CSM
  1963. REAL,DIMENSION(cims:cime,cjms:cjme,ckms:ckme), INTENT(IN) :: CFLD
  1964. REAL,DIMENSION(cims:cime,cjms:cjme,1:KZMAX), INTENT(IN) :: CZ3d
  1965. REAL,DIMENSION(1:KZMAX), INTENT(IN) :: CPSTD
  1966. REAL,INTENT(IN) :: CPDTOP,CPTOP
  1967. ! nested domain
  1968. INTEGER,DIMENSION(nims:nime,njms:njme), INTENT(IN) :: IIH,JJH
  1969. REAL,DIMENSION(nims:nime,njms:njme), INTENT(IN) :: HBWGT1,HBWGT2,HBWGT3
  1970. REAL,DIMENSION(nims:nime,njms:njme), INTENT(IN) :: HBWGT4
  1971. REAL,DIMENSION(nims:nime,njms:njme), INTENT(IN) :: FIS,SM
  1972. REAL,DIMENSION(nims:nime,njms:njme,nkms:nkme), INTENT(INOUT) :: NFLD
  1973. REAL,DIMENSION(1:KZMAX), INTENT(IN) :: PSTD
  1974. REAL,DIMENSION(nims:nime,njms:njme,1:KZMAX), INTENT(OUT) :: Z3d
  1975. REAL,INTENT(IN) :: PDTOP,PTOP
  1976. ! Local
  1977. INTEGER :: nijds, nijde, spec_bdy_width,i,j,k
  1978. REAL :: dlnpdz,dum2d
  1979. REAL,DIMENSION(nims:nime,njms:njme) :: zs
  1980. INTEGER,PARAMETER :: JTB=134
  1981. INTEGER :: ii,jj
  1982. REAL, DIMENSION (nims:nime,njms:njme) :: CWK1,CWK2,CWK3,CWK4
  1983. nijds = min(nids, njds)
  1984. nijde = max(nide, njde)
  1985. CALL nl_get_spec_bdy_width( 1, spec_bdy_width )
  1986. !
  1987. !*** DEFINE LOCAL TOPOGRAPHY ON THE BASIS OF FIS. ASLO CHECK IF SM IS LAND (SM=0) OVER TOPO
  1988. !*** YOU DON'T WANT MOUNTAINS INSIDE WATER BODIES!
  1989. !
  1990. DO J=NJTS,MIN(NJTE,NJDE-1)
  1991. DO I=NITS,MIN(NITE,NIDE-1)
  1992. ZS(I,J)=FIS(I,J)/G
  1993. ENDDO
  1994. ENDDO
  1995. ! X start boundary
  1996. NMM_XS: IF(NITS .EQ. NIDS)THEN
  1997. ! WRITE(0,*)'ENTERING X1 START BOUNDARY AT MASS POINTS',NJTS,MIN(NJTE,NJDE-1)
  1998. I = NIDS
  1999. DO K=NKTS,KZMAX
  2000. DO J = NJTS,MIN(NJTE,NJDE-1)
  2001. IF(MOD(JJH(I,J),2) .NE. 0)THEN ! 1,3,5,7 of the parent domain
  2002. Z3d(I,J,K) = HBWGT1(I,J)*CZ3d(IIH(I,J), JJH(I,J) ,K) &
  2003. + HBWGT2(I,J)*CZ3d(IIH(I,J)+1,JJH(I,J) ,K) &
  2004. + HBWGT3(I,J)*CZ3d(IIH(I,J), JJH(I,J)-1,K) &
  2005. + HBWGT4(I,J)*CZ3d(IIH(I,J), JJH(I,J)+1,K)
  2006. ELSE
  2007. Z3d(I,J,K) = HBWGT1(I,J)*CZ3d(IIH(I,J), JJH(I,J) ,K) &
  2008. + HBWGT2(I,J)*CZ3d(IIH(I,J)+1,JJH(I,J) ,K) &
  2009. + HBWGT3(I,J)*CZ3d(IIH(I,J)+1,JJH(I,J)-1,K) &
  2010. + HBWGT4(I,J)*CZ3d(IIH(I,J)+1,JJH(I,J)+1,K)
  2011. ENDIF
  2012. END DO
  2013. END DO
  2014. DO J = NJTS,MIN(NJTE,NJDE-1)
  2015. IF(MOD(J,2) .NE. 0)THEN
  2016. IF (ZS(I,J) .LT. Z3d(I,J,2)) THEN ! level 2 has to be changed
  2017. dlnpdz = (log(PSTD(1))-log(PSTD(2)) )/(Z3d(I,J,1)-Z3d(I,J,2))
  2018. dum2d = exp(log(PSTD(1)) + dlnpdz*(ZS(I,J) - Z3d(I,J,1)))
  2019. CWK1(I,J) = dum2d -PDTOP -PTOP
  2020. ELSE ! target level bounded by input levels
  2021. DO K =NKTS,KZMAX-1
  2022. IF(ZS(I,J) .GE. Z3d(I,J,K) .AND. ZS(I,J) .LT. Z3d(I,J,K+1))THEN
  2023. dlnpdz = (log(PSTD(K))-log(PSTD(K+1)) ) /(Z3d(I,J,K)-Z3d(I,J,K+1))
  2024. dum2d = exp(log(PSTD(K)) + dlnpdz*(ZS(I,J)- Z3d(I,J,K)))
  2025. CWK1(I,J) = dum2d -PDTOP -PTOP
  2026. ENDIF
  2027. ENDDO
  2028. ENDIF
  2029. IF(ZS(I,J) .GE. Z3d(I,J,KZMAX))THEN
  2030. WRITE(0,*)'I=',I,'J=',J,'K=',K,'TERRAIN HEIGHT',ZS(I,J),'Z3d',Z3d(I,J,KZMAX)
  2031. CALL wrf_error_fatal("BC:MOUNTAIN TOO HIGH TO FIT THE MODEL DEPTH")
  2032. ENDIF
  2033. ELSE
  2034. CWK1(I,J)=0.
  2035. ENDIF
  2036. ENDDO
  2037. DO J = NJTS,MIN(NJTE,NJDE-1)
  2038. DO K = NKDS,NKDE
  2039. ntemp_b(i,j,k) = CWK1(I,J)
  2040. ntemp_bt(i,j,k) = 0.0
  2041. END DO
  2042. END DO
  2043. ENDIF NMM_XS
  2044. ! X end boundary
  2045. NMM_XE: IF(NITE-1 .EQ. NIDE-1)THEN
  2046. ! WRITE(0,*)'ENTERING X END BOUNDARY AT MASS POINTS',NJTS,MIN(NJTE,NJDE-1)
  2047. I = NIDE-1
  2048. II = NIDE - I
  2049. DO K=NKTS,KZMAX
  2050. DO J=NJTS,MIN(NJTE,NJDE-1)
  2051. IF(MOD(JJH(I,J),2) .NE. 0)THEN ! 1,3,5,7
  2052. Z3d(I,J,K) = HBWGT1(I,J)*CZ3d(IIH(I,J), JJH(I,J) ,K) &
  2053. + HBWGT2(I,J)*CZ3d(IIH(I,J)+1,JJH(I,J) ,K) &
  2054. + HBWGT3(I,J)*CZ3d(IIH(I,J), JJH(I,J)-1,K) &
  2055. + HBWGT4(I,J)*CZ3d(IIH(I,J), JJH(I,J)+1,K)
  2056. ELSE
  2057. Z3d(I,J,K) = HBWGT1(I,J)*CZ3d(IIH(I,J), JJH(I,J) ,K) &
  2058. + HBWGT2(I,J)*CZ3d(IIH(I,J)+1,JJH(I,J) ,K) &
  2059. + HBWGT3(I,J)*CZ3d(IIH(I,J)+1,JJH(I,J)-1,K) &
  2060. + HBWGT4(I,J)*CZ3d(IIH(I,J)+1,JJH(I,J)+1,K)
  2061. ENDIF
  2062. ENDDO
  2063. ENDDO
  2064. DO J = NJTS,MIN(NJTE,NJDE-1)
  2065. IF(MOD(J,2) .NE.0)THEN ! 1,3,5,7 of nested domain
  2066. IF (ZS(I,J) .LT. Z3d(I,J,2)) THEN ! level 2 has to be changed
  2067. dlnpdz = (log(PSTD(1))-log(PSTD(2)) )/(Z3d(I,J,1)-Z3d(I,J,2))
  2068. dum2d = exp(log(PSTD(1)) + dlnpdz*(ZS(I,J) - Z3d(I,J,1)))
  2069. CWK2(I,J) = dum2d -PDTOP -PTOP
  2070. ELSE ! target level bounded by input levels
  2071. DO K =NKTS,KZMAX-1
  2072. IF(ZS(I,J) .GE. Z3d(I,J,K) .AND. ZS(I,J) .LT. Z3d(I,J,K+1))THEN
  2073. dlnpdz = (log(PSTD(K))-log(PSTD(K+1)) ) /(Z3d(I,J,K)-Z3d(I,J,K+1))
  2074. dum2d = exp(log(PSTD(K)) + dlnpdz*(ZS(I,J)- Z3d(I,J,K)))
  2075. CWK2(I,J) = dum2d -PDTOP -PTOP
  2076. ENDIF
  2077. ENDDO
  2078. ENDIF
  2079. IF(ZS(I,J) .GE. Z3d(I,J,KZMAX))THEN
  2080. WRITE(0,*)'I=',I,'J=',J,'K=',K,'TERRAIN HEIGHT',ZS(I,J),'Z3d',Z3d(I,J,KZMAX)
  2081. CALL wrf_error_fatal("BC:MOUNTAIN TOO HIGH TO FIT THE MODEL DEPTH")
  2082. ENDIF
  2083. ELSE
  2084. CWK2(I,J) = 0.0
  2085. ENDIF
  2086. ENDDO
  2087. DO J = NJTS,MIN(NJTE,NJDE-1)
  2088. DO K = NKDS,NKDE
  2089. ntemp_b(i,j,k) = CWK2(I,J)
  2090. ntemp_bt(i,j,k) = 0.0
  2091. END DO
  2092. END DO
  2093. ENDIF NMM_XE
  2094. ! Y start boundary
  2095. NMM_YS: IF(NJTS .EQ. NJDS)THEN
  2096. ! WRITE(20,*)'ENTERING Y START BOUNDARY AT MASS POINTS',NITS,MIN(NITE,NIDE-1)
  2097. J = NJDS
  2098. DO K=NKTS,KZMAX
  2099. DO I = NITS,MIN(NITE,NIDE-1)
  2100. IF(MOD(JJH(I,J),2) .NE. 0)THEN ! 1,3,5,7
  2101. Z3d(I,J,K) = HBWGT1(I,J)*CZ3d(IIH(I,J), JJH(I,J) ,K) &
  2102. + HBWGT2(I,J)*CZ3d(IIH(I,J)+1,JJH(I,J) ,K) &
  2103. + HBWGT3(I,J)*CZ3d(IIH(I,J), JJH(I,J)-1,K) &
  2104. + HBWGT4(I,J)*CZ3d(IIH(I,J), JJH(I,J)+1,K)
  2105. ELSE
  2106. Z3d(I,J,K) = HBWGT1(I,J)*CZ3d(IIH(I,J), JJH(I,J) ,K) &
  2107. + HBWGT2(I,J)*CZ3d(IIH(I,J)+1,JJH(I,J) ,K) &
  2108. + HBWGT3(I,J)*CZ3d(IIH(I,J)+1,JJH(I,J)-1,K) &
  2109. + HBWGT4(I,J)*CZ3d(IIH(I,J)+1,JJH(I,J)+1,K)
  2110. ENDIF
  2111. END DO
  2112. END DO
  2113. DO I = NITS,MIN(NITE,NIDE-1)
  2114. IF (ZS(I,J) .LT. Z3d(I,J,2)) THEN ! level 2 has to be changed
  2115. dlnpdz = (log(PSTD(1))-log(PSTD(2)) )/(Z3d(I,J,1)-Z3d(I,J,2))
  2116. dum2d = exp(log(PSTD(1)) + dlnpdz*(ZS(I,J) - Z3d(I,J,1)))
  2117. CWK3(I,J) = dum2d -PDTOP -PTOP
  2118. ELSE ! target level bounded by input levels
  2119. DO K =NKTS,KZMAX-1
  2120. IF(ZS(I,J) .GE. Z3d(I,J,K) .AND. ZS(I,J) .LT. Z3d(I,J,K+1))THEN
  2121. dlnpdz = (log(PSTD(K))-log(PSTD(K+1)) ) /(Z3d(I,J,K)-Z3d(I,J,K+1))
  2122. dum2d = exp(log(PSTD(K)) + dlnpdz*(ZS(I,J)- Z3d(I,J,K)))
  2123. CWK3(I,J) = dum2d -PDTOP -PTOP
  2124. ENDIF
  2125. ENDDO
  2126. ENDIF
  2127. IF(ZS(I,J) .GE. Z3d(I,J,KZMAX))THEN
  2128. WRITE(0,*)'I=',I,'J=',J,'K=',K,'TERRAIN HEIGHT',ZS(I,J),'Z3d',Z3d(I,J,KZMAX)
  2129. CALL wrf_error_fatal("BC:MOUNTAIN TOO HIGH TO FIT THE MODEL DEPTH")
  2130. ENDIF
  2131. ENDDO
  2132. DO K = NKDS, NKDE
  2133. DO I = NITS,MIN(NITE,NIDE-1)
  2134. ntemp_b(i,j,k) = CWK3(I,J)
  2135. ntemp_bt(i,j,k) = 0.0
  2136. END DO
  2137. END DO
  2138. END IF NMM_YS
  2139. ! Y end boundary
  2140. NMM_YE: IF(NJTE-1 .EQ. NJDE-1)THEN
  2141. ! WRITE(20,*)'ENTERING Y END BOUNDARY AT MASS POINTS',NITS,MIN(NITE,NIDE-1)
  2142. J = NJDE-1
  2143. JJ = NJDE - J
  2144. DO K=NKTS,KZMAX
  2145. DO I = NITS,MIN(NITE,NIDE-1)
  2146. IF(MOD(JJH(I,J),2) .NE. 0)THEN ! 1,3,5,7
  2147. Z3d(I,J,K) = HBWGT1(I,J)*CZ3d(IIH(I,J), JJH(I,J) ,K) &
  2148. + HBWGT2(I,J)*CZ3d(IIH(I,J)+1,JJH(I,J) ,K) &
  2149. + HBWGT3(I,J)*CZ3d(IIH(I,J), JJH(I,J)-1,K) &
  2150. + HBWGT4(I,J)*CZ3d(IIH(I,J), JJH(I,J)+1,K)
  2151. ELSE
  2152. Z3d(I,J,K) = HBWGT1(I,J)*CZ3d(IIH(I,J), JJH(I,J) ,K) &
  2153. + HBWGT2(I,J)*CZ3d(IIH(I,J)+1,JJH(I,J) ,K) &
  2154. + HBWGT3(I,J)*CZ3d(IIH(I,J)+1,JJH(I,J)-1,K) &
  2155. + HBWGT4(I,J)*CZ3d(IIH(I,J)+1,JJH(I,J)+1,K)
  2156. ENDIF
  2157. END DO
  2158. END DO
  2159. DO I = NITS,MIN(NITE,NIDE-1)
  2160. IF (ZS(I,J) .LT. Z3d(I,J,2)) THEN ! level 2 has to be changed
  2161. dlnpdz = (log(PSTD(1))-log(PSTD(2)) )/(Z3d(I,J,1)-Z3d(I,J,2))
  2162. dum2d = exp(log(PSTD(1)) + dlnpdz*(ZS(I,J) - Z3d(I,J,1)))
  2163. CWK4(I,J) = dum2d -PDTOP -PTOP
  2164. ELSE ! target level bounded by input levels
  2165. DO K =NKTS,KZMAX-1
  2166. IF(ZS(I,J) .GE. Z3d(I,J,K) .AND. ZS(I,J) .LT. Z3d(I,J,K+1))THEN
  2167. dlnpdz = (log(PSTD(K))-log(PSTD(K+1)) ) /(Z3d(I,J,K)-Z3d(I,J,K+1))
  2168. dum2d = exp(log(PSTD(K)) + dlnpdz*(ZS(I,J)- Z3d(I,J,K)))
  2169. CWK4(I,J) = dum2d -PDTOP -PTOP
  2170. ENDIF
  2171. ENDDO
  2172. ENDIF
  2173. IF(ZS(I,J) .GE. Z3d(I,J,KZMAX))THEN
  2174. WRITE(0,*)'I=',I,'J=',J,'K=',K,'TERRAIN HEIGHT',ZS(I,J),'Z3d',Z3d(I,J,KZMAX)
  2175. CALL wrf_error_fatal("BC:MOUNTAIN TOO HIGH TO FIT THE MODEL DEPTH")
  2176. ENDIF
  2177. ENDDO
  2178. DO K = NKDS,NKDE
  2179. DO I = NITS,MIN(NITE,NIDE-1)
  2180. ntemp_b(i,j,k) = CWK4(I,J)
  2181. ntemp_bt(i,j,k) = 0.0
  2182. END DO
  2183. END DO
  2184. END IF NMM_YE
  2185. RETURN
  2186. END SUBROUTINE nmm_bdymass_hinterp
  2187. !
  2188. !=======================================================================================
  2189. !
  2190. ! ADDED FOR INCLUDING MOISTURE AND THERMODYNAMIC ENERGY BALANCE
  2191. !
  2192. !=======================================================================================
  2193. SUBROUTINE interp_scalar_nmm (cfld, & ! CD field
  2194. cids,cide,ckds,ckde,cjds,cjde, &
  2195. cims,cime,ckms,ckme,cjms,cjme, &
  2196. cits,cite,ckts,ckte,cjts,cjte, &
  2197. nfld, & ! ND field
  2198. nids,nide,nkds,nkde,njds,njde, &
  2199. nims,nime,nkms,nkme,njms,njme, &
  2200. nits,nite,nkts,nkte,njts,njte, &
  2201. shw, & ! stencil half width for interp
  2202. imask, & ! interpolation mask
  2203. xstag,ystag, & ! staggering of field
  2204. ipos,jpos, & ! Position of lower left of nest in CD
  2205. nri,nrj, & ! nest ratios
  2206. CII, IIH, CJJ, JJH, CBWGT1, HBWGT1, & ! south-western grid locs and weights
  2207. CBWGT2, HBWGT2, CBWGT3, HBWGT3, & ! note that "C"ourse grid ones are
  2208. CBWGT4, HBWGT4, & ! dummys for weights
  2209. CC3d,C3d, &
  2210. CPD,PD, &
  2211. CPSTD,PSTD, &
  2212. CPDTOP,PDTOP, &
  2213. CPTOP,PTOP, &
  2214. CETA1,ETA1,CETA2,ETA2 )
  2215. USE MODULE_MODEL_CONSTANTS
  2216. USE module_timing
  2217. IMPLICIT NONE
  2218. LOGICAL,INTENT(IN) :: xstag, ystag
  2219. INTEGER,INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  2220. cims, cime, ckms, ckme, cjms, cjme, &
  2221. cits, cite, ckts, ckte, cjts, cjte, &
  2222. nids, nide, nkds, nkde, njds, njde, &
  2223. nims, nime, nkms, nkme, njms, njme, &
  2224. nits, nite, nkts, nkte, njts, njte, &
  2225. shw,ipos,jpos,nri,nrj
  2226. INTEGER,DIMENSION(nims:nime,njms:njme), INTENT(IN) :: IMASK
  2227. ! parent domain
  2228. INTEGER,DIMENSION(cims:cime,cjms:cjme), INTENT(IN) :: CII,CJJ ! dummy
  2229. REAL,DIMENSION(cims:cime,cjms:cjme), INTENT(IN) :: CBWGT1,CBWGT2
  2230. REAL,DIMENSION(cims:cime,cjms:cjme), INTENT(IN) :: CBWGT3,CBWGT4
  2231. REAL,DIMENSION(cims:cime,cjms:cjme,ckms:ckme), INTENT(IN) :: CFLD
  2232. REAL,DIMENSION(cims:cime,cjms:cjme,ckms:ckme), INTENT(IN) :: CC3d ! scalar input on constant pressure levels
  2233. REAL,DIMENSION(ckms:ckme), INTENT(IN) :: CPSTD
  2234. REAL,DIMENSION(cims:cime,cjms:cjme), INTENT(IN) :: CPD
  2235. REAL,DIMENSION(ckms:ckme), INTENT(IN) :: CETA1,CETA2
  2236. REAL, INTENT(IN) :: CPDTOP,CPTOP
  2237. ! nested domain
  2238. INTEGER,DIMENSION(nims:nime,njms:njme), INTENT(IN) :: IIH,JJH
  2239. REAL,DIMENSION(nims:nime,njms:njme), INTENT(IN) :: HBWGT1,HBWGT2
  2240. REAL,DIMENSION(nims:nime,njms:njme), INTENT(IN) :: HBWGT3,HBWGT4
  2241. REAL,DIMENSION(nims:nime,njms:njme,nkms:nkme), INTENT(OUT):: NFLD ! This is scalar on hybrid levels
  2242. REAL,DIMENSION(nims:nime,njms:njme,nkms:nkme), INTENT(OUT):: C3d ! Scalar on constant pressure levels
  2243. REAL,DIMENSION(nkms:nkme), INTENT(IN) :: PSTD
  2244. REAL,DIMENSION(nims:nime,njms:njme), INTENT(IN) :: PD
  2245. REAL,DIMENSION(nkms:nkme), INTENT(IN) :: ETA1,ETA2
  2246. REAL,INTENT(IN) :: PDTOP,PTOP
  2247. ! local
  2248. INTEGER,PARAMETER :: JTB=134
  2249. INTEGER :: I,J,K
  2250. REAL,DIMENSION(JTB) :: PIN,CIN,Y2,PIO,PTMP,COUT,DUM1,DUM2
  2251. !-----------------------------------------------------------------------------------------------------
  2252. !
  2253. !
  2254. ! *** CHECK VERTICAL BOUNDS BEFORE USING SPLINE OR LINEAR INTERPOLATION
  2255. !
  2256. IF(nkme .GT. (JTB-10) .OR. NKDE .GT. (JTB-10)) &
  2257. CALL wrf_error_fatal ('mass points: increase JTB in interp_mass_nmm')
  2258. !
  2259. ! FIRST, HORIZONTALLY INTERPOLATE MOISTURE NOW AVAILABLE ON CONSTANT PRESSURE SURFACE (LEVELS) FROM THE
  2260. ! PARENT TO THE NESTED DOMAIN
  2261. !
  2262. !*** INDEX CONVENTIONS
  2263. !*** HBWGT4
  2264. !*** 4
  2265. !***
  2266. !***
  2267. !***
  2268. !*** h
  2269. !*** 1 2
  2270. !*** HBWGT1 HBWGT2
  2271. !***
  2272. !***
  2273. !*** 3
  2274. !*** HBWGT3
  2275. C3d=0.0
  2276. DO K=NKDS,NKDE-1 ! Please note that we are still in isobaric surfaces
  2277. DO J=NJTS,MIN(NJTE,NJDE-1)
  2278. DO I=NITS,MIN(NITE,NIDE-1)
  2279. IF(IMASK(I,J) .NE. 1)THEN
  2280. IF(MOD(JJH(I,J),2) .NE. 0)THEN ! 1,3,5,7
  2281. C3d(I,J,K) = HBWGT1(I,J)*CC3d(IIH(I,J), JJH(I,J) ,K) &
  2282. + HBWGT2(I,J)*CC3d(IIH(I,J)+1,JJH(I,J) ,K) &
  2283. + HBWGT3(I,J)*CC3d(IIH(I,J), JJH(I,J)-1,K) &
  2284. + HBWGT4(I,J)*CC3d(IIH(I,J), JJH(I,J)+1,K)
  2285. ELSE
  2286. C3d(I,J,K) = HBWGT1(I,J)*CC3d(IIH(I,J), JJH(I,J) ,K) &
  2287. + HBWGT2(I,J)*CC3d(IIH(I,J)+1,JJH(I,J) ,K) &
  2288. + HBWGT3(I,J)*CC3d(IIH(I,J)+1,JJH(I,J)-1,K) &
  2289. + HBWGT4(I,J)*CC3d(IIH(I,J)+1,JJH(I,J)+1,K)
  2290. ENDIF
  2291. ENDIF
  2292. ENDDO
  2293. ENDDO
  2294. ENDDO
  2295. !
  2296. ! RECOVER THE SCALARS FROM CONSTANT PRESSURE SURFACES (LEVELS) ON TO HYBRID SURFACES
  2297. !
  2298. DO J=NJTS,MIN(NJTE,NJDE-1)
  2299. DO I=NITS,MIN(NITE,NIDE-1)
  2300. IF(IMASK(I,J) .NE. 1)THEN
  2301. ! clean local array before use of spline or linear interpolation
  2302. CIN=0.;PIN=0.;Y2=0;PIO=0.;PTMP=0.;COUT=0.;DUM1=0.;DUM2=0.
  2303. DO K=NKDS+1,NKDE ! inputs at standard levels
  2304. PIN(K-1) = EXP((ALOG(PSTD(NKDE-K+1))+ALOG(PSTD(NKDE-K+2)))*0.5)
  2305. CIN(K-1) = C3d(I,J,NKDE-K+1)
  2306. ENDDO
  2307. Y2(1 )=0.
  2308. Y2(NKDE-1)=0.
  2309. DO K=NKDS,NKDE ! target points in model interface levels (pint)
  2310. PTMP(K) = ETA1(K)*PDTOP + ETA2(K)*PD(I,J) + PTOP
  2311. ENDDO
  2312. DO K=NKDS,NKDE-1 ! target points in model levels
  2313. PIO(K) = EXP((ALOG(PTMP(K))+ALOG(PTMP(K+1)))*0.5)
  2314. ENDDO
  2315. IF(PTMP(1) .GE. PSTD(1))THEN ! if lower boundary is higher than PMSL(1) re-set lower boundary
  2316. PIN(NKDE-1) = PIO(1) ! be consistent with target. This may not happen at all
  2317. WRITE(0,*)'WARNING: NESTED DOMAIN PRESSURE AT LOWEST LEVEL HIGHER THAN PSTD'
  2318. WRITE(0,*)'I,J,PIO(1),PSTD(1)',I,J,PIO(1),PSTD(1)
  2319. ENDIF
  2320. CALL SPLINE2(I,J,JTB,NKDE-1,PIN,CIN,Y2,NKDE-1,PIO,COUT,DUM1,DUM2) ! interpolate
  2321. DO K=1,NKDE-1
  2322. NFLD(I,J,K)= COUT(K) ! scalar in the nested domain
  2323. ENDDO
  2324. ENDIF
  2325. ENDDO
  2326. ENDDO
  2327. END SUBROUTINE interp_scalar_nmm
  2328. !
  2329. !===========================================================================================
  2330. !
  2331. SUBROUTINE nmm_bdy_scalar (cfld, & ! CD field
  2332. cids,cide,ckds,ckde,cjds,cjde, &
  2333. cims,cime,ckms,ckme,cjms,cjme, &
  2334. cits,cite,ckts,ckte,cjts,cjte, &
  2335. nfld, & ! ND field
  2336. nids,nide,nkds,nkde,njds,njde, &
  2337. nims,nime,nkms,nkme,njms,njme, &
  2338. nits,nite,nkts,nkte,njts,njte, &
  2339. shw, & ! stencil half width for interp
  2340. imask, & ! interpolation mask
  2341. xstag,ystag, & ! staggering of field
  2342. ipos,jpos, & ! Position of lower left of nest in CD
  2343. nri,nrj, & ! nest ratios
  2344. c_bxs,n_bxs, &
  2345. c_bxe,n_bxe, &
  2346. c_bys,n_bys, &
  2347. c_bye,n_bye, &
  2348. c_btxs,n_btxs, &
  2349. c_btxe,n_btxe, &
  2350. c_btys,n_btys, &
  2351. c_btye,n_btye, &
  2352. cdt, ndt, &
  2353. CTEMP_B,NTEMP_B, & ! to be removed
  2354. CTEMP_BT,NTEMP_BT, &
  2355. CII, IIH, CJJ, JJH, CBWGT1, HBWGT1, & ! south-western grid locs and weights
  2356. CBWGT2, HBWGT2, CBWGT3, HBWGT3, & ! note that "C"ourse grid ones are
  2357. CBWGT4, HBWGT4, & ! dummys for weights
  2358. CC3d,C3d, &
  2359. CPD,PD, &
  2360. CPSTD,PSTD, &
  2361. CPDTOP,PDTOP, &
  2362. CPTOP,PTOP, &
  2363. CETA1,ETA1,CETA2,ETA2 )
  2364. USE MODULE_MODEL_CONSTANTS
  2365. USE module_timing
  2366. IMPLICIT NONE
  2367. LOGICAL,INTENT(IN) :: xstag, ystag
  2368. REAL, INTENT(INOUT) :: cdt, ndt
  2369. INTEGER,INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  2370. cims, cime, ckms, ckme, cjms, cjme, &
  2371. cits, cite, ckts, ckte, cjts, cjte, &
  2372. nids, nide, nkds, nkde, njds, njde, &
  2373. nims, nime, nkms, nkme, njms, njme, &
  2374. nits, nite, nkts, nkte, njts, njte, &
  2375. shw,ipos,jpos,nri,nrj
  2376. REAL, DIMENSION ( cims:cime, cjms:cjme, ckms:ckme ), INTENT(OUT) :: ctemp_b,ctemp_bt
  2377. REAL, DIMENSION ( nims:nime, njms:njme, nkms:nkme ), INTENT(OUT) :: ntemp_b,ntemp_bt
  2378. REAL, DIMENSION( * ), INTENT(INOUT) :: c_bxs,n_bxs,c_bxe,n_bxe,c_bys,n_bys,c_bye,n_bye
  2379. REAL, DIMENSION( * ), INTENT(INOUT) :: c_btxs,n_btxs,c_btxe,n_btxe,c_btys,n_btys,c_btye,n_btye
  2380. INTEGER,DIMENSION(nims:nime,njms:njme), INTENT(IN) :: IMASK
  2381. ! parent domain
  2382. INTEGER,DIMENSION(cims:cime,cjms:cjme), INTENT(IN) :: CII,CJJ ! dummy
  2383. REAL,DIMENSION(cims:cime,cjms:cjme), INTENT(IN) :: CBWGT1,CBWGT2
  2384. REAL,DIMENSION(cims:cime,cjms:cjme), INTENT(IN) :: CBWGT3,CBWGT4
  2385. REAL,DIMENSION(cims:cime,cjms:cjme,ckms:ckme), INTENT(IN) :: CFLD
  2386. REAL,DIMENSION(cims:cime,cjms:cjme,ckms:ckme), INTENT(IN) :: CC3d ! scalar input on constant pressure levels
  2387. REAL,DIMENSION(ckms:ckme), INTENT(IN) :: CPSTD
  2388. REAL,DIMENSION(cims:cime,cjms:cjme), INTENT(IN) :: CPD
  2389. REAL,DIMENSION(ckms:ckme), INTENT(IN) :: CETA1,CETA2
  2390. REAL, INTENT(IN) :: CPDTOP,CPTOP
  2391. ! nested domain
  2392. INTEGER,DIMENSION(nims:nime,njms:njme), INTENT(IN) :: IIH,JJH
  2393. REAL,DIMENSION(nims:nime,njms:njme), INTENT(IN) :: HBWGT1,HBWGT2
  2394. REAL,DIMENSION(nims:nime,njms:njme), INTENT(IN) :: HBWGT3,HBWGT4
  2395. REAL,DIMENSION(nims:nime,njms:njme,nkms:nkme), INTENT(OUT):: NFLD
  2396. REAL,DIMENSION(nims:nime,njms:njme,nkms:nkme), INTENT(OUT):: C3d !Scalar on constant pressure levels
  2397. REAL,DIMENSION(nkms:nkme), INTENT(IN) :: PSTD
  2398. REAL,DIMENSION(nims:nime,njms:njme), INTENT(IN) :: PD
  2399. REAL,DIMENSION(nkms:nkme), INTENT(IN) :: ETA1,ETA2
  2400. REAL,INTENT(IN) :: PDTOP,PTOP
  2401. ! local
  2402. INTEGER,PARAMETER :: JTB=134
  2403. INTEGER :: I,J,K,II,JJ
  2404. REAL,DIMENSION(JTB) :: PIN,CIN,Y2,PIO,PTMP,COUT,DUM1,DUM2
  2405. REAL, DIMENSION (nims:nime,njms:njme,nkms:nkme) :: CWK1,CWK2,CWK3,CWK4
  2406. !-----------------------------------------------------------------------------------------------------
  2407. !
  2408. !
  2409. ! *** CHECK VERTICAL BOUNDS BEFORE USING SPLINE INTERPOLATION
  2410. !
  2411. IF(nkme .GT. (JTB-10) .OR. NKDE .GT. (JTB-10)) &
  2412. CALL wrf_error_fatal ('mass points: increase JTB in interp_mass_nmm')
  2413. ! X start boundary
  2414. NMM_XS: IF(NITS .EQ. NIDS)THEN
  2415. ! WRITE(0,*)'ENTERING X1 START BOUNDARY AT T POINTS',NJTS,MIN(NJTE,NJDE-1)
  2416. I = NIDS
  2417. DO K=NKDS,NKDE-1 ! Please note that we are still in isobaric surfaces
  2418. DO J = NJTS,MIN(NJTE,NJDE-1)
  2419. IF(MOD(JJH(I,J),2) .NE. 0)THEN ! 1,3,5,7 of the parent domain
  2420. C3d(I,J,K) = HBWGT1(I,J)*CC3d(IIH(I,J), JJH(I,J) ,K) &
  2421. + HBWGT2(I,J)*CC3d(IIH(I,J)+1,JJH(I,J) ,K) &
  2422. + HBWGT3(I,J)*CC3d(IIH(I,J), JJH(I,J)-1,K) &
  2423. + HBWGT4(I,J)*CC3d(IIH(I,J), JJH(I,J)+1,K)
  2424. ELSE
  2425. C3d(I,J,K) = HBWGT1(I,J)*CC3d(IIH(I,J), JJH(I,J) ,K) &
  2426. + HBWGT2(I,J)*CC3d(IIH(I,J)+1,JJH(I,J) ,K) &
  2427. + HBWGT3(I,J)*CC3d(IIH(I,J)+1,JJH(I,J)-1,K) &
  2428. + HBWGT4(I,J)*CC3d(IIH(I,J)+1,JJH(I,J)+1,K)
  2429. ENDIF
  2430. ENDDO
  2431. ENDDO
  2432. !
  2433. DO J=NJTS,MIN(NJTE,NJDE-1)
  2434. IF(MOD(J,2) .NE. 0)THEN
  2435. CIN=0.;PIN=0.;Y2=0;PIO=0.;PTMP=0.;COUT=0.;DUM1=0.;DUM2=0. ! clean up local array
  2436. DO K=NKDS+1,NKDE ! inputs at standard levels
  2437. PIN(K-1) = EXP((ALOG(PSTD(NKDE-K+1))+ALOG(PSTD(NKDE-K+2)))*0.5)
  2438. CIN(K-1) = C3d(I,J,NKDE-K+1)
  2439. ENDDO
  2440. Y2(1 )=0.
  2441. Y2(NKDE-1)=0.
  2442. DO K=NKDS,NKDE ! target points in model interface levels (pint)
  2443. PTMP(K) = ETA1(K)*PDTOP + ETA2(K)*PD(I,J) + PTOP
  2444. ENDDO
  2445. DO K=NKDS,NKDE-1 ! target points in model levels
  2446. PIO(K) = EXP((ALOG(PTMP(K))+ALOG(PTMP(K+1)))*0.5)
  2447. ENDDO
  2448. IF(PTMP(1) .GE. PSTD(1))THEN ! if lower boundary is higher than PMSL(1) re-set lower boundary
  2449. PIN(NKDE-1) = PIO(1) ! be consistent with target. This may not happen at all
  2450. WRITE(0,*)'WARNING: NESTED DOMAIN PRESSURE AT LOWEST LEVEL HIGHER THAN PSTD'
  2451. WRITE(0,*)'I,J,PIO(1),PSTD(1)',I,J,PIO(1),PSTD(1)
  2452. ENDIF
  2453. CALL SPLINE2(I,J,JTB,NKDE-1,PIN,CIN,Y2,NKDE-1,PIO,COUT,DUM1,DUM2) ! interpolate
  2454. DO K=1,NKDE-1
  2455. CWK1(I,J,K)= COUT(K) ! scalar in the nested domain
  2456. ENDDO
  2457. ELSE
  2458. DO K=NKDS,NKDE-1
  2459. CWK1(I,J,K)=0.0
  2460. ENDDO
  2461. ENDIF
  2462. ENDDO
  2463. DO J = NJTS,MIN(NJTE,NJDE-1)
  2464. DO K = NKDS,NKDE-1
  2465. ntemp_b(i,j,k) = CWK1(I,J,K)
  2466. ntemp_bt(i,j,k) = 0.0
  2467. END DO
  2468. END DO
  2469. ENDIF NMM_XS
  2470. ! X end boundary
  2471. NMM_XE: IF(NITE-1 .EQ. NIDE-1)THEN
  2472. ! WRITE(0,*)'ENTERING X END BOUNDARY AT T POINTS',NJTS,MIN(NJTE,NJDE-1)
  2473. I = NIDE-1
  2474. DO K=NKDS,NKDE-1 ! Please note that we are still in isobaric surfaces
  2475. DO J = NJTS,MIN(NJTE,NJDE-1)
  2476. IF(MOD(JJH(I,J),2) .NE. 0)THEN ! 1,3,5,7 of the parent domain
  2477. C3d(I,J,K) = HBWGT1(I,J)*CC3d(IIH(I,J), JJH(I,J) ,K) &
  2478. + HBWGT2(I,J)*CC3d(IIH(I,J)+1,JJH(I,J) ,K) &
  2479. + HBWGT3(I,J)*CC3d(IIH(I,J), JJH(I,J)-1,K) &
  2480. + HBWGT4(I,J)*CC3d(IIH(I,J), JJH(I,J)+1,K)
  2481. ELSE
  2482. C3d(I,J,K) = HBWGT1(I,J)*CC3d(IIH(I,J), JJH(I,J) ,K) &
  2483. + HBWGT2(I,J)*CC3d(IIH(I,J)+1,JJH(I,J) ,K) &
  2484. + HBWGT3(I,J)*CC3d(IIH(I,J)+1,JJH(I,J)-1,K) &
  2485. + HBWGT4(I,J)*CC3d(IIH(I,J)+1,JJH(I,J)+1,K)
  2486. ENDIF
  2487. ENDDO
  2488. ENDDO
  2489. DO J=NJTS,MIN(NJTE,NJDE-1)
  2490. IF(MOD(J,2) .NE. 0)THEN
  2491. CIN=0.;PIN=0.;Y2=0;PIO=0.;PTMP=0.;COUT=0.;DUM1=0.;DUM2=0. ! clean up local array
  2492. DO K=NKDS+1,NKDE ! inputs at standard levels
  2493. PIN(K-1) = EXP((ALOG(PSTD(NKDE-K+1))+ALOG(PSTD(NKDE-K+2)))*0.5)
  2494. CIN(K-1) = C3d(I,J,NKDE-K+1)
  2495. ENDDO
  2496. Y2(1 )=0.
  2497. Y2(NKDE-1)=0.
  2498. DO K=NKDS,NKDE ! target points in model interface levels (pint)
  2499. PTMP(K) = ETA1(K)*PDTOP + ETA2(K)*PD(I,J) + PTOP
  2500. ENDDO
  2501. DO K=NKDS,NKDE-1 ! target points in model levels
  2502. PIO(K) = EXP((ALOG(PTMP(K))+ALOG(PTMP(K+1)))*0.5)
  2503. ENDDO
  2504. IF(PTMP(1) .GE. PSTD(1))THEN ! if lower boundary is higher than PMSL(1) re-set lower boundary
  2505. PIN(NKDE-1) = PIO(1) ! be consistent with target. This may not happen at all
  2506. WRITE(0,*)'WARNING: NESTED DOMAIN PRESSURE AT LOWEST LEVEL HIGHER THAN PSTD'
  2507. WRITE(0,*)'I,J,PIO(1),PSTD(1)',I,J,PIO(1),PSTD(1)
  2508. ENDIF
  2509. CALL SPLINE2(I,J,JTB,NKDE-1,PIN,CIN,Y2,NKDE-1,PIO,COUT,DUM1,DUM2) ! interpolate
  2510. DO K=1,NKDE-1
  2511. CWK2(I,J,K)= COUT(K) ! scalar in the nested domain
  2512. ENDDO
  2513. ELSE
  2514. DO K=NKDS,NKDE-1
  2515. CWK2(I,J,K)=0.0
  2516. ENDDO
  2517. ENDIF
  2518. ENDDO
  2519. DO J = NJTS,MIN(NJTE,NJDE-1)
  2520. DO K = NKDS,MIN(NKTE,NKDE-1)
  2521. ntemp_b(i,j,k) = CWK2(I,J,K)
  2522. ntemp_bt(i,j,k) = 0.0
  2523. END DO
  2524. END DO
  2525. ENDIF NMM_XE
  2526. ! Y start boundary
  2527. NMM_YS: IF(NJTS .EQ. NJDS)THEN
  2528. ! WRITE(0,*)'ENTERING Y START BOUNDARY AT T POINTS',NITS,MIN(NITE,NIDE-1)
  2529. J = NJDS
  2530. DO K=NKDS,NKDE-1
  2531. DO I = NITS,MIN(NITE,NIDE-1)
  2532. IF(MOD(JJH(I,J),2) .NE. 0)THEN ! 1,3,5,7 of the parent domain
  2533. C3d(I,J,K) = HBWGT1(I,J)*CC3d(IIH(I,J), JJH(I,J) ,K) &
  2534. + HBWGT2(I,J)*CC3d(IIH(I,J)+1,JJH(I,J) ,K) &
  2535. + HBWGT3(I,J)*CC3d(IIH(I,J), JJH(I,J)-1,K) &
  2536. + HBWGT4(I,J)*CC3d(IIH(I,J), JJH(I,J)+1,K)
  2537. ELSE
  2538. C3d(I,J,K) = HBWGT1(I,J)*CC3d(IIH(I,J), JJH(I,J) ,K) &
  2539. + HBWGT2(I,J)*CC3d(IIH(I,J)+1,JJH(I,J) ,K) &
  2540. + HBWGT3(I,J)*CC3d(IIH(I,J)+1,JJH(I,J)-1,K) &
  2541. + HBWGT4(I,J)*CC3d(IIH(I,J)+1,JJH(I,J)+1,K)
  2542. ENDIF
  2543. ENDDO
  2544. ENDDO
  2545. !
  2546. DO I=NITS,MIN(NITE,NIDE-1)
  2547. CIN=0.;PIN=0.;Y2=0;PIO=0.;PTMP=0.;COUT=0.;DUM1=0.;DUM2=0. ! clean up local array
  2548. DO K=NKDS+1,NKDE ! inputs at standard levels
  2549. PIN(K-1) = EXP((ALOG(PSTD(NKDE-K+1))+ALOG(PSTD(NKDE-K+2)))*0.5)
  2550. CIN(K-1) = C3d(I,J,NKDE-K+1)
  2551. ENDDO
  2552. Y2(1 )=0.
  2553. Y2(NKDE-1)=0.
  2554. DO K=NKDS,NKDE ! target points in model interface levels (pint)
  2555. PTMP(K) = ETA1(K)*PDTOP + ETA2(K)*PD(I,J) + PTOP
  2556. ENDDO
  2557. DO K=NKDS,NKDE-1 ! target points in model levels
  2558. PIO(K) = EXP((ALOG(PTMP(K))+ALOG(PTMP(K+1)))*0.5)
  2559. ENDDO
  2560. IF(PTMP(1) .GE. PSTD(1))THEN ! if lower boundary is higher than PMSL(1) re-set lower boundary
  2561. PIN(NKDE-1) = PIO(1) ! be consistent with target. This may not happen at all
  2562. WRITE(0,*)'WARNING: NESTED DOMAIN PRESSURE AT LOWEST LEVEL HIGHER THAN PSTD'
  2563. WRITE(0,*)'I,J,PIO(1),PSTD(1)',I,J,PIO(1),PSTD(1)
  2564. ENDIF
  2565. CALL SPLINE2(I,J,JTB,NKDE-1,PIN,CIN,Y2,NKDE-1,PIO,COUT,DUM1,DUM2) ! interpolate
  2566. DO K=1,NKDE-1
  2567. CWK3(I,J,K)= COUT(K) ! scalar in the nested domain
  2568. ENDDO
  2569. ENDDO
  2570. DO K = NKDS,NKDE-1
  2571. DO I = NITS,MIN(NITE,NIDE-1)
  2572. ntemp_b(i,J,K) = CWK3(I,J,K)
  2573. ntemp_bt(i,J,K) = 0.0
  2574. ENDDO
  2575. ENDDO
  2576. ENDIF NMM_YS
  2577. ! Y end boundary
  2578. NMM_YE: IF(NJTE-1 .EQ. NJDE-1)THEN
  2579. ! WRITE(0,*)'ENTERING Y END BOUNDARY AT T POINTS',NITS,MIN(NITE,NIDE-1)
  2580. J = NJDE-1
  2581. DO K=NKDS,NKDE-1
  2582. DO I = NITS,MIN(NITE,NIDE-1)
  2583. IF(MOD(JJH(I,J),2) .NE. 0)THEN ! 1,3,5,7 of the parent domain
  2584. C3d(I,J,K) = HBWGT1(I,J)*CC3d(IIH(I,J), JJH(I,J) ,K) &
  2585. + HBWGT2(I,J)*CC3d(IIH(I,J)+1,JJH(I,J) ,K) &
  2586. + HBWGT3(I,J)*CC3d(IIH(I,J), JJH(I,J)-1,K) &
  2587. + HBWGT4(I,J)*CC3d(IIH(I,J), JJH(I,J)+1,K)
  2588. ELSE
  2589. C3d(I,J,K) = HBWGT1(I,J)*CC3d(IIH(I,J), JJH(I,J) ,K) &
  2590. + HBWGT2(I,J)*CC3d(IIH(I,J)+1,JJH(I,J) ,K) &
  2591. + HBWGT3(I,J)*CC3d(IIH(I,J)+1,JJH(I,J)-1,K) &
  2592. + HBWGT4(I,J)*CC3d(IIH(I,J)+1,JJH(I,J)+1,K)
  2593. ENDIF
  2594. ENDDO
  2595. ENDDO
  2596. DO I=NITS,MIN(NITE,NIDE-1)
  2597. CIN=0.;PIN=0.;Y2=0;PIO=0.;PTMP=0.;COUT=0.;DUM1=0.;DUM2=0. ! clean up local array
  2598. DO K=NKDS+1,NKDE ! inputs at standard levels
  2599. PIN(K-1) = EXP((ALOG(PSTD(NKDE-K+1))+ALOG(PSTD(NKDE-K+2)))*0.5)
  2600. CIN(K-1) = C3d(I,J,NKDE-K+1)
  2601. ENDDO
  2602. Y2(1 )=0.
  2603. Y2(NKDE-1)=0.
  2604. DO K=NKDS,NKDE ! target points in model interface levels (pint)
  2605. PTMP(K) = ETA1(K)*PDTOP + ETA2(K)*PD(I,J) + PTOP
  2606. ENDDO
  2607. DO K=NKDS,NKDE-1 ! target points in model levels
  2608. PIO(K) = EXP((ALOG(PTMP(K))+ALOG(PTMP(K+1)))*0.5)
  2609. ENDDO
  2610. IF(PTMP(1) .GE. PSTD(1))THEN ! if lower boundary is higher than PMSL(1) re-set lower boundary
  2611. PIN(NKDE-1) = PIO(1) ! be consistent with target. This may not happen at all
  2612. WRITE(0,*)'WARNING: NESTED DOMAIN PRESSURE AT LOWEST LEVEL HIGHER THAN PSTD'
  2613. WRITE(0,*)'I,J,PIO(1),PSTD(1)',I,J,PIO(1),PSTD(1)
  2614. ENDIF
  2615. CALL SPLINE2(I,J,JTB,NKDE-1,PIN,CIN,Y2,NKDE-1,PIO,COUT,DUM1,DUM2) ! interpolate
  2616. DO K=1,NKDE-1
  2617. CWK4(I,J,K)= COUT(K) ! scalar in the nested domain
  2618. ENDDO
  2619. ENDDO
  2620. DO K = NKDS,NKDE-1
  2621. DO I = NITS,MIN(NITE,NIDE-1)
  2622. ntemp_b(i,J,K) = CWK4(I,J,K)
  2623. ntemp_bt(i,J,K) = 0.0
  2624. END DO
  2625. END DO
  2626. ENDIF NMM_YE
  2627. END SUBROUTINE nmm_bdy_scalar
  2628. !
  2629. !
  2630. !=======================================================================================
  2631. SUBROUTINE SPLINE2(I,J,JTBX,NOLD,XOLD,YOLD,Y2,NNEW,XNEW,YNEW,P,Q)
  2632. !
  2633. ! ******************************************************************
  2634. ! * *
  2635. ! * THIS IS A ONE-DIMENSIONAL CUBIC SPLINE FITTING ROUTINE *
  2636. ! * PROGRAMED FOR A SMALL SCALAR MACHINE. *
  2637. ! * *
  2638. ! * PROGRAMER Z. JANJIC *
  2639. ! * *
  2640. ! * NOLD - NUMBER OF GIVEN VALUES OF THE FUNCTION. MUST BE GE 3. *
  2641. ! * XOLD - LOCATIONS OF THE POINTS AT WHICH THE VALUES OF THE *
  2642. ! * FUNCTION ARE GIVEN. MUST BE IN ASCENDING ORDER. *
  2643. ! * YOLD - THE GIVEN VALUES OF THE FUNCTION AT THE POINTS XOLD. *
  2644. ! * Y2 - THE SECOND DERIVATIVES AT THE POINTS XOLD. IF NATURAL *
  2645. ! * SPLINE IS FITTED Y2(1)=0. AND Y2(NOLD)=0. MUST BE *
  2646. ! * SPECIFIED. *
  2647. ! * NNEW - NUMBER OF VALUES OF THE FUNCTION TO BE CALCULATED. *
  2648. ! * XNEW - LOCATIONS OF THE POINTS AT WHICH THE VALUES OF THE *
  2649. ! * FUNCTION ARE CALCULATED. XNEW(K) MUST BE GE XOLD(1) *
  2650. ! * AND LE XOLD(NOLD). *
  2651. ! * YNEW - THE VALUES OF THE FUNCTION TO BE CALCULATED. *
  2652. ! * P, Q - AUXILIARY VECTORS OF THE LENGTH NOLD-2. *
  2653. ! * *
  2654. ! ******************************************************************
  2655. !---------------------------------------------------------------------
  2656. IMPLICIT NONE
  2657. !---------------------------------------------------------------------
  2658. INTEGER,INTENT(IN) :: I,J,JTBX,NNEW,NOLD
  2659. REAL,DIMENSION(JTBX),INTENT(IN) :: XNEW,XOLD,YOLD
  2660. REAL,DIMENSION(JTBX),INTENT(INOUT) :: P,Q,Y2
  2661. REAL,DIMENSION(JTBX),INTENT(OUT) :: YNEW
  2662. !
  2663. INTEGER :: II,JJ,K,K1,K2,KOLD,NOLDM1
  2664. REAL :: AK,BK,CK,DEN,DX,DXC,DXL,DXR,DYDXL,DYDXR &
  2665. ,RDX,RTDXC,X,XK,XSQ,Y2K,Y2KP1
  2666. !---------------------------------------------------------------------
  2667. ! debug
  2668. II=9999
  2669. JJ=9999
  2670. IF(I.eq.II.and.J.eq.JJ)THEN
  2671. WRITE(0,*)'DEBUG in SPLINE2: I,J',I,J
  2672. WRITE(0,*)'DEBUG in SPLINE2:HSO= ',xnew(1:nold)
  2673. DO K=1,NOLD
  2674. WRITE(0,*)'DEBUG in SPLINE2:L,ZETAI,PINTI= ' &
  2675. ,K,YOLD(K),XOLD(K)
  2676. ENDDO
  2677. ENDIF
  2678. !
  2679. NOLDM1=NOLD-1
  2680. !
  2681. DXL=XOLD(2)-XOLD(1)
  2682. DXR=XOLD(3)-XOLD(2)
  2683. DYDXL=(YOLD(2)-YOLD(1))/DXL
  2684. DYDXR=(YOLD(3)-YOLD(2))/DXR
  2685. RTDXC=0.5/(DXL+DXR)
  2686. !
  2687. P(1)= RTDXC*(6.*(DYDXR-DYDXL)-DXL*Y2(1))
  2688. Q(1)=-RTDXC*DXR
  2689. !
  2690. IF(NOLD.EQ.3)GO TO 150
  2691. !---------------------------------------------------------------------
  2692. K=3
  2693. !
  2694. 100 DXL=DXR
  2695. DYDXL=DYDXR
  2696. DXR=XOLD(K+1)-XOLD(K)
  2697. DYDXR=(YOLD(K+1)-YOLD(K))/DXR
  2698. DXC=DXL+DXR
  2699. DEN=1./(DXL*Q(K-2)+DXC+DXC)
  2700. !
  2701. P(K-1)= DEN*(6.*(DYDXR-DYDXL)-DXL*P(K-2))
  2702. Q(K-1)=-DEN*DXR
  2703. !
  2704. K=K+1
  2705. IF(K.LT.NOLD)GO TO 100
  2706. !-----------------------------------------------------------------------
  2707. 150 K=NOLDM1
  2708. !
  2709. 200 Y2(K)=P(K-1)+Q(K-1)*Y2(K+1)
  2710. !
  2711. K=K-1
  2712. IF(K.GT.1)GO TO 200
  2713. !-----------------------------------------------------------------------
  2714. K1=1
  2715. !
  2716. 300 XK=XNEW(K1)
  2717. !
  2718. DO 400 K2=2,NOLD
  2719. !
  2720. IF(XOLD(K2).GT.XK)THEN
  2721. KOLD=K2-1
  2722. GO TO 450
  2723. ENDIF
  2724. !
  2725. 400 CONTINUE
  2726. !
  2727. YNEW(K1)=YOLD(NOLD)
  2728. GO TO 600
  2729. !
  2730. 450 IF(K1.EQ.1)GO TO 500
  2731. IF(K.EQ.KOLD)GO TO 550
  2732. !
  2733. 500 K=KOLD
  2734. !
  2735. Y2K=Y2(K)
  2736. Y2KP1=Y2(K+1)
  2737. DX=XOLD(K+1)-XOLD(K)
  2738. RDX=1./DX
  2739. !
  2740. AK=.1666667*RDX*(Y2KP1-Y2K)
  2741. BK=0.5*Y2K
  2742. CK=RDX*(YOLD(K+1)-YOLD(K))-.1666667*DX*(Y2KP1+Y2K+Y2K)
  2743. !
  2744. 550 X=XK-XOLD(K)
  2745. XSQ=X*X
  2746. !
  2747. YNEW(K1)=AK*XSQ*X+BK*XSQ+CK*X+YOLD(K)
  2748. ! debug
  2749. IF(I.eq.II.and.J.eq.JJ)THEN
  2750. WRITE(0,*) 'DEBUG:: k1,xnew(k1),ynew(k1): ', K1,XNEW(k1),YNEW(k1)
  2751. ENDIF
  2752. !
  2753. 600 K1=K1+1
  2754. IF(K1.LE.NNEW)GO TO 300
  2755. RETURN
  2756. END SUBROUTINE SPLINE2
  2757. !=======================================================================================
  2758. ! E grid interpolation for H and V points
  2759. !=======================================================================================
  2760. SUBROUTINE interp_h_nmm (cfld, & ! CD field
  2761. cids, cide, ckds, ckde, cjds, cjde, &
  2762. cims, cime, ckms, ckme, cjms, cjme, &
  2763. cits, cite, ckts, ckte, cjts, cjte, &
  2764. nfld, & ! ND field
  2765. nids, nide, nkds, nkde, njds, njde, &
  2766. nims, nime, nkms, nkme, njms, njme, &
  2767. nits, nite, nkts, nkte, njts, njte, &
  2768. shw, & ! stencil half width for interp
  2769. imask, & ! interpolation mask
  2770. xstag, ystag, & ! staggering of field
  2771. ipos, jpos, & ! Position of lower left of nest in CD
  2772. nri, nrj, & ! nest ratios
  2773. CII, IIH, CJJ, JJH, CBWGT1, HBWGT1, & ! south-western grid locs and weights
  2774. CBWGT2, HBWGT2, CBWGT3, HBWGT3, & ! note that "C"ourse grid ones are
  2775. CBWGT4, HBWGT4 ) ! dummys for weights
  2776. USE module_timing
  2777. IMPLICIT NONE
  2778. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  2779. cims, cime, ckms, ckme, cjms, cjme, &
  2780. cits, cite, ckts, ckte, cjts, cjte, &
  2781. nids, nide, nkds, nkde, njds, njde, &
  2782. nims, nime, nkms, nkme, njms, njme, &
  2783. nits, nite, nkts, nkte, njts, njte, &
  2784. shw, &
  2785. ipos, jpos, &
  2786. nri, nrj
  2787. LOGICAL, INTENT(IN) :: xstag, ystag
  2788. REAL, DIMENSION ( cims:cime, cjms:cjme, ckms:ckme ) :: cfld
  2789. REAL, DIMENSION ( nims:nime, njms:njme, nkms:nkme ) :: nfld
  2790. REAL, DIMENSION ( cims:cime, cjms:cjme ), INTENT(IN) :: CBWGT1,CBWGT2,CBWGT3,CBWGT4 ! dummy
  2791. REAL, DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: HBWGT1,HBWGT2,HBWGT3,HBWGT4
  2792. INTEGER, DIMENSION ( cims:cime, cjms:cjme ), INTENT(IN) :: CII,CJJ ! dummy
  2793. INTEGER, DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: IIH,JJH
  2794. INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
  2795. ! local
  2796. INTEGER i,j,k
  2797. !
  2798. !*** CHECK DOMAIN BOUNDS BEFORE INTERPOLATION
  2799. !
  2800. DO J=NJTS,MIN(NJTE,NJDE-1)
  2801. DO I=NITS,MIN(NITE,NIDE-1)
  2802. IF(IIH(i,j).LT.(CIDS-shw) .OR. IIH(i,j).GT.(CIDE+shw)) &
  2803. CALL wrf_error_fatal ('hpoints:check domain bounds along x' )
  2804. IF(JJH(i,j).LT.(CJDS-shw) .OR. JJH(i,j).GT.(CJDE+shw)) &
  2805. CALL wrf_error_fatal ('hpoints:check domain bounds along y' )
  2806. ENDDO
  2807. ENDDO
  2808. !
  2809. !*** INDEX CONVENTIONS
  2810. !*** HBWGT4
  2811. !*** 4
  2812. !***
  2813. !***
  2814. !***
  2815. !*** h
  2816. !*** 1 2
  2817. !*** HBWGT1 HBWGT2
  2818. !***
  2819. !***
  2820. !*** 3
  2821. !*** HBWGT3
  2822. DO K=NKDS,NKDE
  2823. DO J=NJTS,MIN(NJTE,NJDE-1)
  2824. DO I=NITS,MIN(NITE,NIDE-1)
  2825. IF(IMASK(I,J) .NE. 1)THEN
  2826. !
  2827. IF(MOD(JJH(I,J),2) .NE. 0)THEN ! 1,3,5,7
  2828. NFLD(I,J,K) = HBWGT1(I,J)*CFLD(IIH(I,J), JJH(I,J) ,K) &
  2829. + HBWGT2(I,J)*CFLD(IIH(I,J)+1,JJH(I,J) ,K) &
  2830. + HBWGT3(I,J)*CFLD(IIH(I,J), JJH(I,J)-1,K) &
  2831. + HBWGT4(I,J)*CFLD(IIH(I,J), JJH(I,J)+1,K)
  2832. ELSE
  2833. NFLD(I,J,K) = HBWGT1(I,J)*CFLD(IIH(I,J), JJH(I,J) ,K) &
  2834. + HBWGT2(I,J)*CFLD(IIH(I,J)+1,JJH(I,J) ,K) &
  2835. + HBWGT3(I,J)*CFLD(IIH(I,J)+1,JJH(I,J)-1,K) &
  2836. + HBWGT4(I,J)*CFLD(IIH(I,J)+1,JJH(I,J)+1,K)
  2837. ENDIF
  2838. !
  2839. ENDIF
  2840. ENDDO
  2841. ENDDO
  2842. ENDDO
  2843. END SUBROUTINE interp_h_nmm
  2844. !
  2845. SUBROUTINE interp_v_nmm (cfld, & ! CD field
  2846. cids, cide, ckds, ckde, cjds, cjde, &
  2847. cims, cime, ckms, ckme, cjms, cjme, &
  2848. cits, cite, ckts, ckte, cjts, cjte, &
  2849. nfld, & ! ND field
  2850. nids, nide, nkds, nkde, njds, njde, &
  2851. nims, nime, nkms, nkme, njms, njme, &
  2852. nits, nite, nkts, nkte, njts, njte, &
  2853. shw, & ! stencil half width for interp
  2854. imask, & ! interpolation mask
  2855. xstag, ystag, & ! staggering of field
  2856. ipos, jpos, & ! Position of lower left of nest in CD
  2857. nri, nrj, & ! nest ratios
  2858. CII, IIV, CJJ, JJV, CBWGT1, VBWGT1, & ! south-western grid locs and weights
  2859. CBWGT2, VBWGT2, CBWGT3, VBWGT3, & ! note that "C"ourse grid ones are
  2860. CBWGT4, VBWGT4 ) ! dummys
  2861. USE module_timing
  2862. IMPLICIT NONE
  2863. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  2864. cims, cime, ckms, ckme, cjms, cjme, &
  2865. cits, cite, ckts, ckte, cjts, cjte, &
  2866. nids, nide, nkds, nkde, njds, njde, &
  2867. nims, nime, nkms, nkme, njms, njme, &
  2868. nits, nite, nkts, nkte, njts, njte, &
  2869. shw, &
  2870. ipos, jpos, &
  2871. nri, nrj
  2872. LOGICAL, INTENT(IN) :: xstag, ystag
  2873. REAL, DIMENSION ( cims:cime, cjms:cjme, ckms:ckme ) :: cfld
  2874. REAL, DIMENSION ( nims:nime, njms:njme, nkms:nkme ) :: nfld
  2875. REAL, DIMENSION ( cims:cime, cjms:cjme ), INTENT(IN) :: CBWGT1,CBWGT2,CBWGT3,CBWGT4 ! dummy
  2876. REAL, DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: VBWGT1,VBWGT2,VBWGT3,VBWGT4
  2877. INTEGER, DIMENSION ( cims:cime, cjms:cjme ), INTENT(IN) :: CII,CJJ ! dummy
  2878. INTEGER, DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: IIV,JJV
  2879. INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
  2880. ! local
  2881. INTEGER i,j,k
  2882. !
  2883. !*** CHECK DOMAIN BOUNDS BEFORE INTERPOLATION
  2884. !
  2885. DO J=NJTS,MIN(NJTE,NJDE-1)
  2886. DO I=NITS,MIN(NITE,NIDE-1)
  2887. IF(IIV(i,j).LT.(CIDS-shw) .OR. IIV(i,j).GT.(CIDE+shw)) &
  2888. CALL wrf_error_fatal ('vpoints:check domain bounds along x' )
  2889. IF(JJV(i,j).LT.(CJDS-shw) .OR. JJV(i,j).GT.(CJDE+shw)) &
  2890. CALL wrf_error_fatal ('vpoints:check domain bounds along y' )
  2891. ENDDO
  2892. ENDDO
  2893. !
  2894. !*** INDEX CONVENTIONS
  2895. !*** VBWGT4
  2896. !*** 4
  2897. !***
  2898. !***
  2899. !***
  2900. !*** h
  2901. !*** 1 2
  2902. !*** VBWGT1 VBWGT2
  2903. !***
  2904. !***
  2905. !*** 3
  2906. !*** VBWGT3
  2907. DO K=NKDS,NKDE
  2908. DO J=NJTS,MIN(NJTE,NJDE-1)
  2909. DO I=NITS,MIN(NITE,NIDE-1)
  2910. IF(IMASK(I,J) .NE. 1)THEN
  2911. IF(MOD(JJV(I,J),2) .NE. 0)THEN ! 1,3,5,7
  2912. NFLD(I,J,K) = VBWGT1(I,J)*CFLD(IIV(I,J), JJV(I,J) ,K) &
  2913. + VBWGT2(I,J)*CFLD(IIV(I,J)+1,JJV(I,J) ,K) &
  2914. + VBWGT3(I,J)*CFLD(IIV(I,J)+1,JJV(I,J)-1,K) &
  2915. + VBWGT4(I,J)*CFLD(IIV(I,J)+1,JJV(I,J)+1,K)
  2916. ELSE
  2917. NFLD(I,J,K) = VBWGT1(I,J)*CFLD(IIV(I,J), JJV(I,J) ,K) &
  2918. + VBWGT2(I,J)*CFLD(IIV(I,J)+1,JJV(I,J) ,K) &
  2919. + VBWGT3(I,J)*CFLD(IIV(I,J), JJV(I,J)-1,K) &
  2920. + VBWGT4(I,J)*CFLD(IIV(I,J), JJV(I,J)+1,K)
  2921. ENDIF
  2922. ENDIF
  2923. ENDDO
  2924. ENDDO
  2925. ENDDO
  2926. END SUBROUTINE interp_v_nmm
  2927. !
  2928. !=======================================================================================
  2929. ! E grid nearest neighbour interpolation for H points.
  2930. ! This routine assumes cfld and nfld are in IJK
  2931. !=======================================================================================
  2932. !
  2933. SUBROUTINE interp_hnear_nmm (cfld, & ! CD field
  2934. cids, cide, ckds, ckde, cjds, cjde, &
  2935. cims, cime, ckms, ckme, cjms, cjme, &
  2936. cits, cite, ckts, ckte, cjts, cjte, &
  2937. nfld, & ! ND field
  2938. nids, nide, nkds, nkde, njds, njde, &
  2939. nims, nime, nkms, nkme, njms, njme, &
  2940. nits, nite, nkts, nkte, njts, njte, &
  2941. shw, & ! stencil half width for interp
  2942. imask, & ! interpolation mask
  2943. xstag, ystag, & ! staggering of field
  2944. ipos, jpos, & ! Position of lower left of nest in CD
  2945. nri, nrj, & ! nest ratios
  2946. CII, IIH, CJJ, JJH, CBWGT1, HBWGT1, & ! south-western grid locs and weights
  2947. CBWGT2, HBWGT2, CBWGT3, HBWGT3, & ! note that "C"ourse grid ones are
  2948. CBWGT4, HBWGT4 ) ! just dummys
  2949. USE module_timing
  2950. IMPLICIT NONE
  2951. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  2952. cims, cime, ckms, ckme, cjms, cjme, &
  2953. cits, cite, ckts, ckte, cjts, cjte, &
  2954. nids, nide, nkds, nkde, njds, njde, &
  2955. nims, nime, nkms, nkme, njms, njme, &
  2956. nits, nite, nkts, nkte, njts, njte, &
  2957. shw, &
  2958. ipos, jpos, &
  2959. nri, nrj
  2960. LOGICAL, INTENT(IN) :: xstag, ystag
  2961. REAL, DIMENSION ( cims:cime, cjms:cjme, ckms:ckme ) :: cfld
  2962. REAL, DIMENSION ( nims:nime, njms:njme, nkms:nkme ) :: nfld
  2963. REAL, DIMENSION ( cims:cime, cjms:cjme ), INTENT(IN) :: CBWGT1,CBWGT2,CBWGT3,CBWGT4 ! dummy
  2964. REAL, DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: HBWGT1,HBWGT2,HBWGT3,HBWGT4
  2965. INTEGER, DIMENSION ( cims:cime, cjms:cjme ), INTENT(IN) :: CII,CJJ ! dummy
  2966. INTEGER, DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: IIH,JJH
  2967. INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
  2968. ! local
  2969. LOGICAL FLIP
  2970. INTEGER i,j,k,n
  2971. REAL SUM,AMAXVAL
  2972. REAL, DIMENSION (4, nims:nime, njms:njme ) :: NBWGT
  2973. !
  2974. !*** INDEX CONVENTIONS
  2975. !*** NBWGT4=0
  2976. !*** 4
  2977. !***
  2978. !***
  2979. !***
  2980. !*** h
  2981. !*** 1 2
  2982. !*** NBWGT1=1 NBWGT2=0
  2983. !***
  2984. !***
  2985. !*** 3
  2986. !*** NBWGT3=0
  2987. DO J=NJTS,MIN(NJTE,NJDE-1)
  2988. DO I=NITS,MIN(NITE,NIDE-1)
  2989. IF(IMASK(I,J) .NE. 1)THEN
  2990. NBWGT(1,I,J)=HBWGT1(I,J)
  2991. NBWGT(2,I,J)=HBWGT2(I,J)
  2992. NBWGT(3,I,J)=HBWGT3(I,J)
  2993. NBWGT(4,I,J)=HBWGT4(I,J)
  2994. ENDIF
  2995. ENDDO
  2996. ENDDO
  2997. DO J=NJTS,MIN(NJTE,NJDE-1)
  2998. DO I=NITS,MIN(NITE,NIDE-1)
  2999. IF(IMASK(I,J) .NE. 1)THEN
  3000. AMAXVAL=0.
  3001. DO N=1,4
  3002. AMAXVAL=amax1(NBWGT(N,I,J),AMAXVAL)
  3003. ENDDO
  3004. FLIP=.TRUE.
  3005. SUM=0.0
  3006. DO N=1,4
  3007. IF(AMAXVAL .EQ. NBWGT(N,I,J) .AND. FLIP)THEN
  3008. NBWGT(N,I,J)=1.0
  3009. FLIP=.FALSE.
  3010. ELSE
  3011. NBWGT(N,I,J)=0.0
  3012. ENDIF
  3013. SUM=SUM+NBWGT(N,I,J)
  3014. IF(SUM .GT. 1.0)CALL wrf_error_fatal ( "horizontal interp error - interp_hnear_nmm" )
  3015. ENDDO
  3016. ENDIF
  3017. ENDDO
  3018. ENDDO
  3019. DO K=NKDS,NKDE
  3020. DO J=NJTS,MIN(NJTE,NJDE-1)
  3021. DO I=NITS,MIN(NITE,NIDE-1)
  3022. IF(IMASK(I,J) .NE. 1)THEN
  3023. IF(MOD(JJH(I,J),2) .NE. 0)THEN ! 1,3,5,7
  3024. NFLD(I,J,K) = NBWGT(1,I,J)*CFLD(IIH(I,J), JJH(I,J) ,K) &
  3025. + NBWGT(2,I,J)*CFLD(IIH(I,J)+1,JJH(I,J) ,K) &
  3026. + NBWGT(3,I,J)*CFLD(IIH(I,J), JJH(I,J)-1,K) &
  3027. + NBWGT(4,I,J)*CFLD(IIH(I,J), JJH(I,J)+1,K)
  3028. ELSE
  3029. NFLD(I,J,K) = NBWGT(1,I,J)*CFLD(IIH(I,J), JJH(I,J) ,K) &
  3030. + NBWGT(2,I,J)*CFLD(IIH(I,J)+1,JJH(I,J) ,K) &
  3031. + NBWGT(3,I,J)*CFLD(IIH(I,J)+1,JJH(I,J)-1,K) &
  3032. + NBWGT(4,I,J)*CFLD(IIH(I,J)+1,JJH(I,J)+1,K)
  3033. ENDIF
  3034. ENDIF
  3035. ENDDO
  3036. ENDDO
  3037. ENDDO
  3038. END SUBROUTINE interp_hnear_nmm
  3039. SUBROUTINE force_sst_nmm (cfld, & ! CD field
  3040. cids, cide, ckds, ckde, cjds, cjde, &
  3041. cims, cime, ckms, ckme, cjms, cjme, &
  3042. cits, cite, ckts, ckte, cjts, cjte, &
  3043. nfld, & ! ND field
  3044. nids, nide, nkds, nkde, njds, njde, &
  3045. nims, nime, nkms, nkme, njms, njme, &
  3046. nits, nite, nkts, nkte, njts, njte, &
  3047. shw, & ! stencil half width for interp
  3048. imask, & ! interpolation mask
  3049. xstag, ystag, & ! staggering of field
  3050. ipos, jpos, & ! Position of lower left of nest in CD
  3051. nri, nrj, & ! nest ratios
  3052. CII, IIH, CJJ, JJH, CBWGT1, HBWGT1, & ! south-western grid locs and weights
  3053. CBWGT2, HBWGT2, CBWGT3, HBWGT3, & ! note that "C"ourse grid ones are
  3054. CBWGT4, HBWGT4, CCSST, CSST ) ! just dummys
  3055. USE module_timing
  3056. IMPLICIT NONE
  3057. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  3058. cims, cime, ckms, ckme, cjms, cjme, &
  3059. cits, cite, ckts, ckte, cjts, cjte, &
  3060. nids, nide, nkds, nkde, njds, njde, &
  3061. nims, nime, nkms, nkme, njms, njme, &
  3062. nits, nite, nkts, nkte, njts, njte, &
  3063. shw, &
  3064. ipos, jpos, &
  3065. nri, nrj
  3066. LOGICAL, INTENT(IN) :: xstag, ystag
  3067. REAL, DIMENSION ( cims:cime, cjms:cjme ) :: cfld
  3068. REAL, DIMENSION ( nims:nime, njms:njme ) :: nfld
  3069. REAL, DIMENSION ( cims:cime, cjms:cjme ), INTENT(IN) :: CBWGT1,CBWGT2,CBWGT3,CBWGT4 ! dummy
  3070. REAL, DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: HBWGT1,HBWGT2,HBWGT3,HBWGT4
  3071. INTEGER, DIMENSION ( cims:cime, cjms:cjme ), INTENT(IN) :: CII,CJJ ! dummy
  3072. INTEGER, DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: IIH,JJH
  3073. INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
  3074. INTEGER , INTENT(IN) :: csst(*), ccsst(*)
  3075. ! local
  3076. LOGICAL FLIP
  3077. INTEGER i,j,k,n
  3078. REAL SUM,AMAXVAL
  3079. REAL, DIMENSION (4, nims:nime, njms:njme ) :: NBWGT
  3080. if(csst(1) /= 1) return
  3081. !
  3082. !*** INDEX CONVENTIONS
  3083. !*** NBWGT4=0
  3084. !*** 4
  3085. !***
  3086. !***
  3087. !***
  3088. !*** h
  3089. !*** 1 2
  3090. !*** NBWGT1=1 NBWGT2=0
  3091. !***
  3092. !***
  3093. !*** 3
  3094. !*** NBWGT3=0
  3095. DO J=NJTS,MIN(NJTE,NJDE-1)
  3096. DO I=NITS,MIN(NITE,NIDE-1)
  3097. NBWGT(1,I,J)=HBWGT1(I,J)
  3098. NBWGT(2,I,J)=HBWGT2(I,J)
  3099. NBWGT(3,I,J)=HBWGT3(I,J)
  3100. NBWGT(4,I,J)=HBWGT4(I,J)
  3101. ENDDO
  3102. ENDDO
  3103. DO J=NJTS,MIN(NJTE,NJDE-1)
  3104. DO I=NITS,MIN(NITE,NIDE-1)
  3105. AMAXVAL=0.
  3106. DO N=1,4
  3107. AMAXVAL=amax1(NBWGT(N,I,J),AMAXVAL)
  3108. ENDDO
  3109. FLIP=.TRUE.
  3110. SUM=0.0
  3111. DO N=1,4
  3112. IF(AMAXVAL .EQ. NBWGT(N,I,J) .AND. FLIP)THEN
  3113. NBWGT(N,I,J)=1.0
  3114. FLIP=.FALSE.
  3115. ELSE
  3116. NBWGT(N,I,J)=0.0
  3117. ENDIF
  3118. SUM=SUM+NBWGT(N,I,J)
  3119. IF(SUM .GT. 1.0)CALL wrf_error_fatal ( "horizontal interp error - interp_hnear_nmm" )
  3120. ENDDO
  3121. ENDDO
  3122. ENDDO
  3123. DO J=NJTS,MIN(NJTE,NJDE-1)
  3124. DO I=NITS,MIN(NITE,NIDE-1)
  3125. IF(MOD(JJH(I,J),2) .NE. 0)THEN ! 1,3,5,7
  3126. NFLD(I,J) = NBWGT(1,I,J)*CFLD(IIH(I,J), JJH(I,J) ) &
  3127. + NBWGT(2,I,J)*CFLD(IIH(I,J)+1,JJH(I,J) ) &
  3128. + NBWGT(3,I,J)*CFLD(IIH(I,J), JJH(I,J)-1) &
  3129. + NBWGT(4,I,J)*CFLD(IIH(I,J), JJH(I,J)+1)
  3130. ELSE
  3131. NFLD(I,J) = NBWGT(1,I,J)*CFLD(IIH(I,J), JJH(I,J) ) &
  3132. + NBWGT(2,I,J)*CFLD(IIH(I,J)+1,JJH(I,J) ) &
  3133. + NBWGT(3,I,J)*CFLD(IIH(I,J)+1,JJH(I,J)-1) &
  3134. + NBWGT(4,I,J)*CFLD(IIH(I,J)+1,JJH(I,J)+1)
  3135. ENDIF
  3136. ENDDO
  3137. ENDDO
  3138. END SUBROUTINE force_sst_nmm
  3139. !=======================================================================================
  3140. ! E grid nearest neighbour interpolation for H points.
  3141. ! This routine assumes cfld and nfld are in IKJ or ILJ
  3142. !=======================================================================================
  3143. !
  3144. SUBROUTINE interp_hnear_ikj_nmm (cfld, & ! CD field
  3145. cids, cide, ckds, ckde, cjds, cjde, &
  3146. cims, cime, ckms, ckme, cjms, cjme, &
  3147. cits, cite, ckts, ckte, cjts, cjte, &
  3148. nfld, & ! ND field
  3149. nids, nide, nkds, nkde, njds, njde, &
  3150. nims, nime, nkms, nkme, njms, njme, &
  3151. nits, nite, nkts, nkte, njts, njte, &
  3152. shw, & ! stencil half width for interp
  3153. imask, & ! interpolation mask
  3154. xstag, ystag, & ! staggering of field
  3155. ipos, jpos, & ! Position of lower left of nest in CD
  3156. nri, nrj, & ! nest ratios
  3157. CII, IIH, CJJ, JJH, CBWGT1, HBWGT1, & ! south-western grid locs and weights
  3158. CBWGT2, HBWGT2, CBWGT3, HBWGT3, & ! note that "C"ourse grid ones are
  3159. CBWGT4, HBWGT4 ) ! just dummys
  3160. USE module_timing
  3161. IMPLICIT NONE
  3162. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  3163. cims, cime, ckms, ckme, cjms, cjme, &
  3164. cits, cite, ckts, ckte, cjts, cjte, &
  3165. nids, nide, nkds, nkde, njds, njde, &
  3166. nims, nime, nkms, nkme, njms, njme, &
  3167. nits, nite, nkts, nkte, njts, njte, &
  3168. shw, &
  3169. ipos, jpos, &
  3170. nri, nrj
  3171. LOGICAL, INTENT(IN) :: xstag, ystag
  3172. REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
  3173. REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
  3174. REAL, DIMENSION ( cims:cime, cjms:cjme ), INTENT(IN) :: CBWGT1,CBWGT2,CBWGT3,CBWGT4 ! dummy
  3175. REAL, DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: HBWGT1,HBWGT2,HBWGT3,HBWGT4
  3176. INTEGER, DIMENSION ( cims:cime, cjms:cjme ), INTENT(IN) :: CII,CJJ ! dummy
  3177. INTEGER, DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: IIH,JJH
  3178. INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
  3179. ! local
  3180. LOGICAL FLIP
  3181. INTEGER i,j,k,n
  3182. REAL SUM,AMAXVAL
  3183. REAL, DIMENSION (4, nims:nime, njms:njme ) :: NBWGT
  3184. !
  3185. !*** INDEX CONVENTIONS
  3186. !*** NBWGT4=0
  3187. !*** 4
  3188. !***
  3189. !***
  3190. !***
  3191. !*** h
  3192. !*** 1 2
  3193. !*** NBWGT1=1 NBWGT2=0
  3194. !***
  3195. !***
  3196. !*** 3
  3197. !*** NBWGT3=0
  3198. DO J=NJTS,MIN(NJTE,NJDE-1)
  3199. DO I=NITS,MIN(NITE,NIDE-1)
  3200. IF(IMASK(I,J) .NE. 1)THEN
  3201. NBWGT(1,I,J)=HBWGT1(I,J)
  3202. NBWGT(2,I,J)=HBWGT2(I,J)
  3203. NBWGT(3,I,J)=HBWGT3(I,J)
  3204. NBWGT(4,I,J)=HBWGT4(I,J)
  3205. ENDIF
  3206. ENDDO
  3207. ENDDO
  3208. DO J=NJTS,MIN(NJTE,NJDE-1)
  3209. DO I=NITS,MIN(NITE,NIDE-1)
  3210. IF(IMASK(I,J) .NE. 1)THEN
  3211. AMAXVAL=0.
  3212. DO N=1,4
  3213. AMAXVAL=amax1(NBWGT(N,I,J),AMAXVAL)
  3214. ENDDO
  3215. FLIP=.TRUE.
  3216. SUM=0.0
  3217. DO N=1,4
  3218. IF(AMAXVAL .EQ. NBWGT(N,I,J) .AND. FLIP)THEN
  3219. NBWGT(N,I,J)=1.0
  3220. FLIP=.FALSE.
  3221. ELSE
  3222. NBWGT(N,I,J)=0.0
  3223. ENDIF
  3224. SUM=SUM+NBWGT(N,I,J)
  3225. IF(SUM .GT. 1.0)CALL wrf_error_fatal ( "horizontal interp error - interp_hnear_nmm" )
  3226. ENDDO
  3227. ENDIF
  3228. ENDDO
  3229. ENDDO
  3230. DO J=NJTS,MIN(NJTE,NJDE-1)
  3231. DO K=NKDS,NKDE
  3232. DO I=NITS,MIN(NITE,NIDE-1)
  3233. IF(IMASK(I,J) .NE. 1)THEN
  3234. IF(MOD(JJH(I,J),2) .NE. 0)THEN ! 1,3,5,7
  3235. NFLD(I,K,J) = NBWGT(1,I,J)*CFLD(IIH(I,J), K,JJH(I,J) ) &
  3236. + NBWGT(2,I,J)*CFLD(IIH(I,J)+1,K,JJH(I,J) ) &
  3237. + NBWGT(3,I,J)*CFLD(IIH(I,J), K,JJH(I,J)-1) &
  3238. + NBWGT(4,I,J)*CFLD(IIH(I,J), K,JJH(I,J)+1)
  3239. ELSE
  3240. NFLD(I,K,J) = NBWGT(1,I,J)*CFLD(IIH(I,J), K,JJH(I,J) ) &
  3241. + NBWGT(2,I,J)*CFLD(IIH(I,J)+1,K,JJH(I,J) ) &
  3242. + NBWGT(3,I,J)*CFLD(IIH(I,J)+1,K,JJH(I,J)-1) &
  3243. + NBWGT(4,I,J)*CFLD(IIH(I,J)+1,K,JJH(I,J)+1)
  3244. ENDIF
  3245. ENDIF
  3246. ENDDO
  3247. ENDDO
  3248. ENDDO
  3249. END SUBROUTINE interp_hnear_ikj_nmm
  3250. !
  3251. !=======================================================================================
  3252. ! E grid nearest neighbour interpolation for integer H points
  3253. !=======================================================================================
  3254. !
  3255. SUBROUTINE interp_int_hnear_nmm (cfld, & ! CD field; integers
  3256. cids, cide, ckds, ckde, cjds, cjde, &
  3257. cims, cime, ckms, ckme, cjms, cjme, &
  3258. cits, cite, ckts, ckte, cjts, cjte, &
  3259. nfld, & ! ND field; integers
  3260. nids, nide, nkds, nkde, njds, njde, &
  3261. nims, nime, nkms, nkme, njms, njme, &
  3262. nits, nite, nkts, nkte, njts, njte, &
  3263. shw, & ! stencil half width for interp
  3264. imask, & ! interpolation mask
  3265. xstag, ystag, & ! staggering of field
  3266. ipos, jpos, & ! lower left of nest in CD
  3267. nri, nrj, & ! nest ratios
  3268. CII, IIH, CJJ, JJH, CBWGT1, HBWGT1, & ! s-w grid locs and weights
  3269. CBWGT2, HBWGT2, CBWGT3, HBWGT3, & ! note that "C"ourse grid ones are
  3270. CBWGT4, HBWGT4 ) ! just dummys
  3271. USE module_timing
  3272. IMPLICIT NONE
  3273. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  3274. cims, cime, ckms, ckme, cjms, cjme, &
  3275. cits, cite, ckts, ckte, cjts, cjte, &
  3276. nids, nide, nkds, nkde, njds, njde, &
  3277. nims, nime, nkms, nkme, njms, njme, &
  3278. nits, nite, nkts, nkte, njts, njte, &
  3279. shw, &
  3280. ipos, jpos, &
  3281. nri, nrj
  3282. LOGICAL, INTENT(IN) :: xstag, ystag
  3283. INTEGER, DIMENSION ( cims:cime, cjms:cjme, ckms:ckme ) :: cfld
  3284. INTEGER, DIMENSION ( nims:nime, njms:njme, nkms:nkme ) :: nfld
  3285. REAL, DIMENSION ( cims:cime, cjms:cjme ), INTENT(IN) :: CBWGT1,CBWGT2,CBWGT3,CBWGT4 ! dummy
  3286. REAL, DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: HBWGT1,HBWGT2,HBWGT3,HBWGT4
  3287. INTEGER, DIMENSION ( cims:cime, cjms:cjme ), INTENT(IN) :: CII,CJJ ! dummy
  3288. INTEGER, DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: IIH,JJH
  3289. INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
  3290. ! local
  3291. LOGICAL FLIP
  3292. INTEGER i,j,k,n
  3293. REAL SUM,AMAXVAL
  3294. REAL, DIMENSION (4, nims:nime, njms:njme ) :: NBWGT
  3295. !
  3296. !*** INDEX CONVENTIONS
  3297. !*** NBWGT4=0
  3298. !*** 4
  3299. !***
  3300. !***
  3301. !***
  3302. !*** h
  3303. !*** 1 2
  3304. !*** NBWGT1=1 NBWGT2=0
  3305. !***
  3306. !***
  3307. !*** 3
  3308. !*** NBWGT3=0
  3309. DO J=NJTS,MIN(NJTE,NJDE-1)
  3310. DO I=NITS,MIN(NITE,NIDE-1)
  3311. IF(IMASK(I,J) .NE. 1)THEN
  3312. NBWGT(1,I,J)=HBWGT1(I,J)
  3313. NBWGT(2,I,J)=HBWGT2(I,J)
  3314. NBWGT(3,I,J)=HBWGT3(I,J)
  3315. NBWGT(4,I,J)=HBWGT4(I,J)
  3316. ENDIF
  3317. ENDDO
  3318. ENDDO
  3319. DO J=NJTS,MIN(NJTE,NJDE-1)
  3320. DO I=NITS,MIN(NITE,NIDE-1)
  3321. IF(IMASK(I,J) .NE. 1)THEN
  3322. AMAXVAL=0.
  3323. DO N=1,4
  3324. AMAXVAL=amax1(NBWGT(N,I,J),AMAXVAL)
  3325. ENDDO
  3326. FLIP=.TRUE.
  3327. SUM=0.0
  3328. DO N=1,4
  3329. IF(AMAXVAL .EQ. NBWGT(N,I,J) .AND. FLIP)THEN
  3330. NBWGT(N,I,J)=1.0
  3331. FLIP=.FALSE.
  3332. ELSE
  3333. NBWGT(N,I,J)=0.0
  3334. ENDIF
  3335. SUM=SUM+NBWGT(N,I,J)
  3336. IF(SUM .GT. 1.0)CALL wrf_error_fatal ( "horizontal interp error - interp_hnear_nmm" )
  3337. ENDDO
  3338. !
  3339. ENDIF
  3340. ENDDO
  3341. ENDDO
  3342. DO J=NJTS,MIN(NJTE,NJDE-1)
  3343. DO K=NKTS,NKTS
  3344. DO I=NITS,MIN(NITE,NIDE-1)
  3345. IF(IMASK(I,J) .NE. 1)THEN
  3346. IF(MOD(JJH(I,J),2) .NE. 0)THEN ! 1,3,5,7
  3347. NFLD(I,J,K) = NBWGT(1,I,J)*CFLD(IIH(I,J), JJH(I,J) ,K) &
  3348. + NBWGT(2,I,J)*CFLD(IIH(I,J)+1,JJH(I,J) ,K) &
  3349. + NBWGT(3,I,J)*CFLD(IIH(I,J), JJH(I,J)-1,K) &
  3350. + NBWGT(4,I,J)*CFLD(IIH(I,J), JJH(I,J)+1,K)
  3351. ELSE
  3352. NFLD(I,J,K) = NBWGT(1,I,J)*CFLD(IIH(I,J), JJH(I,J) ,K) &
  3353. + NBWGT(2,I,J)*CFLD(IIH(I,J)+1,JJH(I,J) ,K) &
  3354. + NBWGT(3,I,J)*CFLD(IIH(I,J)+1,JJH(I,J)-1,K) &
  3355. + NBWGT(4,I,J)*CFLD(IIH(I,J)+1,JJH(I,J)+1,K)
  3356. ENDIF
  3357. ENDIF
  3358. ENDDO
  3359. ENDDO
  3360. ENDDO
  3361. END SUBROUTINE interp_int_hnear_nmm
  3362. !
  3363. !--------------------------------------------------------------------------------------
  3364. !
  3365. SUBROUTINE nmm_bdy_hinterp (cfld, & ! CD field
  3366. cids, cide, ckds, ckde, cjds, cjde, &
  3367. cims, cime, ckms, ckme, cjms, cjme, &
  3368. cits, cite, ckts, ckte, cjts, cjte, &
  3369. nfld, & ! ND field
  3370. nids, nide, nkds, nkde, njds, njde, &
  3371. nims, nime, nkms, nkme, njms, njme, &
  3372. nits, nite, nkts, nkte, njts, njte, &
  3373. shw, & ! stencil half width
  3374. imask, & ! interpolation mask
  3375. xstag, ystag, & ! staggering of field
  3376. ipos, jpos, & ! Position of lower left of nest in CD
  3377. nri, nrj, & ! nest ratios
  3378. c_bxs,n_bxs, &
  3379. c_bxe,n_bxe, &
  3380. c_bys,n_bys, &
  3381. c_bye,n_bye, &
  3382. c_btxs,n_btxs, &
  3383. c_btxe,n_btxe, &
  3384. c_btys,n_btys, &
  3385. c_btye,n_btye, &
  3386. CTEMP_B,NTEMP_B, & ! These temp arrays should be removed
  3387. CTEMP_BT,NTEMP_BT, & ! later on
  3388. CII, IIH, CJJ, JJH, CBWGT1, HBWGT1, & ! south-western grid locs and weights
  3389. CBWGT2, HBWGT2, CBWGT3, HBWGT3, & ! note that "C"ourse grid ones are
  3390. CBWGT4, HBWGT4 ) ! dummys
  3391. ! use module_state_description
  3392. USE module_configure
  3393. USE module_wrf_error
  3394. IMPLICIT NONE
  3395. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  3396. cims, cime, ckms, ckme, cjms, cjme, &
  3397. cits, cite, ckts, ckte, cjts, cjte, &
  3398. nids, nide, nkds, nkde, njds, njde, &
  3399. nims, nime, nkms, nkme, njms, njme, &
  3400. nits, nite, nkts, nkte, njts, njte, &
  3401. shw, &
  3402. ipos, jpos, &
  3403. nri, nrj
  3404. LOGICAL, INTENT(IN) :: xstag, ystag
  3405. REAL, DIMENSION ( cims:cime, cjms:cjme, ckms:ckme ) :: cfld
  3406. REAL, DIMENSION ( nims:nime, njms:njme, nkms:nkme ) :: nfld
  3407. !
  3408. REAL, DIMENSION ( cims:cime, cjms:cjme, ckms:ckme ) :: ctemp_b,ctemp_bt
  3409. REAL, DIMENSION ( nims:nime, njms:njme, nkms:nkme ) :: ntemp_b,ntemp_bt
  3410. !
  3411. INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
  3412. REAL, DIMENSION( * ), INTENT(INOUT) :: c_bxs,n_bxs,c_bxe,n_bxe,c_bys,n_bys,c_bye,n_bye
  3413. REAL, DIMENSION( * ), INTENT(INOUT) :: c_btxs,n_btxs,c_btxe,n_btxe,c_btys,n_btys,c_btye,n_btye
  3414. REAL, DIMENSION ( cims:cime, cjms:cjme ), INTENT(IN) :: CBWGT1,CBWGT2,CBWGT3,CBWGT4 ! dummy
  3415. REAL, DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: HBWGT1,HBWGT2,HBWGT3,HBWGT4
  3416. INTEGER, DIMENSION ( cims:cime, cjms:cjme ), INTENT(IN) :: CII,CJJ ! dummy
  3417. INTEGER, DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: IIH,JJH
  3418. ! Local
  3419. INTEGER :: i,j,k
  3420. REAL, DIMENSION ( nims:nime, njms:njme, nkms:nkme ) :: cwk1,cwk2,cwk3,cwk4
  3421. ! X start boundary
  3422. NMM_XS: IF(NITS .EQ. NIDS)THEN
  3423. ! WRITE(0,*)'ENTERING X1 START BOUNDARY AT MASS POINTS',NJTS,MIN(NJTE,NJDE-1)
  3424. I = NIDS
  3425. DO K = NKDS,NKDE
  3426. DO J = NJTS,MIN(NJTE,NJDE-1)
  3427. IF(MOD(J,2) .NE.0)THEN ! 1,3,5,7 of nested domain
  3428. IF(MOD(JJH(I,J),2) .NE. 0)THEN ! 1,3,5,7 of the parent domain
  3429. CWK1(I,J,K) = HBWGT1(I,J)*CFLD(IIH(I,J), JJH(I,J) ,K) &
  3430. + HBWGT2(I,J)*CFLD(IIH(I,J)+1,JJH(I,J) ,K) &
  3431. + HBWGT3(I,J)*CFLD(IIH(I,J), JJH(I,J)-1,K) &
  3432. + HBWGT4(I,J)*CFLD(IIH(I,J), JJH(I,J)+1,K)
  3433. ELSE
  3434. CWK1(I,J,K) = HBWGT1(I,J)*CFLD(IIH(I,J), JJH(I,J) ,K) &
  3435. + HBWGT2(I,J)*CFLD(IIH(I,J)+1,JJH(I,J) ,K) &
  3436. + HBWGT3(I,J)*CFLD(IIH(I,J)+1,JJH(I,J)-1,K) &
  3437. + HBWGT4(I,J)*CFLD(IIH(I,J)+1,JJH(I,J)+1,K)
  3438. ENDIF
  3439. ELSE
  3440. CWK1(I,J,K) = 0.0 ! even rows at mass points of the nested domain
  3441. ENDIF
  3442. ntemp_b(i,J,K) = CWK1(I,J,K)
  3443. ntemp_bt(i,J,K) = 0.0
  3444. END DO
  3445. END DO
  3446. ENDIF NMM_XS
  3447. ! X end boundary
  3448. NMM_XE: IF(NITE-1 .EQ. NIDE-1)THEN
  3449. ! WRITE(0,*)'ENTERING X END BOUNDARY AT MASS POINTS',NJTS,MIN(NJTE,NJDE-1)
  3450. I = NIDE-1
  3451. DO K = NKDS,NKDE
  3452. DO J = NJTS,MIN(NJTE,NJDE-1)
  3453. IF(MOD(J,2) .NE.0)THEN ! 1,3,5,7 of the nested domain
  3454. IF(MOD(JJH(I,J),2) .NE. 0)THEN ! 1,3,5,7 of the parent domain
  3455. CWK2(I,J,K) = HBWGT1(I,J)*CFLD(IIH(I,J), JJH(I,J) ,K) &
  3456. + HBWGT2(I,J)*CFLD(IIH(I,J)+1,JJH(I,J) ,K) &
  3457. + HBWGT3(I,J)*CFLD(IIH(I,J), JJH(I,J)-1,K) &
  3458. + HBWGT4(I,J)*CFLD(IIH(I,J), JJH(I,J)+1,K)
  3459. ELSE
  3460. CWK2(I,J,K) = HBWGT1(I,J)*CFLD(IIH(I,J), JJH(I,J) ,K) &
  3461. + HBWGT2(I,J)*CFLD(IIH(I,J)+1,JJH(I,J) ,K) &
  3462. + HBWGT3(I,J)*CFLD(IIH(I,J)+1,JJH(I,J)-1,K) &
  3463. + HBWGT4(I,J)*CFLD(IIH(I,J)+1,JJH(I,J)+1,K)
  3464. ENDIF
  3465. ELSE
  3466. CWK2(I,J,K) = 0.0 ! even rows at mass points
  3467. ENDIF
  3468. ntemp_b(i,J,K) = CWK2(I,J,K)
  3469. ntemp_bt(i,J,K) = 0.0
  3470. END DO
  3471. END DO
  3472. ENDIF NMM_XE
  3473. ! Y start boundary
  3474. NMM_YS: IF(NJTS .EQ. NJDS)THEN
  3475. ! WRITE(0,*)'ENTERING Y START BOUNDARY AT MASS POINTS',NITS,MIN(NITE,NIDE-1)
  3476. J = NJDS
  3477. DO K = NKDS, NKDE
  3478. DO I = NITS,MIN(NITE,NIDE-1)
  3479. IF(MOD(JJH(I,J),2) .NE. 0)THEN ! 1,3,5,7
  3480. CWK3(I,J,K) = HBWGT1(I,J)*CFLD(IIH(I,J), JJH(I,J) ,K) &
  3481. + HBWGT2(I,J)*CFLD(IIH(I,J)+1,JJH(I,J) ,K) &
  3482. + HBWGT3(I,J)*CFLD(IIH(I,J), JJH(I,J)-1,K) &
  3483. + HBWGT4(I,J)*CFLD(IIH(I,J), JJH(I,J)+1,K)
  3484. ELSE
  3485. CWK3(I,J,K) = HBWGT1(I,J)*CFLD(IIH(I,J), JJH(I,J) ,K) &
  3486. + HBWGT2(I,J)*CFLD(IIH(I,J)+1,JJH(I,J) ,K) &
  3487. + HBWGT3(I,J)*CFLD(IIH(I,J)+1,JJH(I,J)-1,K) &
  3488. + HBWGT4(I,J)*CFLD(IIH(I,J)+1,JJH(I,J)+1,K)
  3489. ENDIF
  3490. ntemp_b(i,J,K) = CWK3(I,J,K)
  3491. ntemp_bt(i,J,K) = 0.0
  3492. END DO
  3493. END DO
  3494. END IF NMM_YS
  3495. ! Y end boundary
  3496. NMM_YE: IF(NJTE-1 .EQ. NJDE-1)THEN
  3497. ! WRITE(0,*)'ENTERING Y END BOUNDARY AT MASS POINTS',NITS,MIN(NITE,NIDE-1)
  3498. J = NJDE-1
  3499. DO K = NKDS,NKDE
  3500. DO I = NITS,MIN(NITE,NIDE-1)
  3501. IF(MOD(JJH(I,J),2) .NE. 0)THEN ! 1,3,5,7
  3502. CWK4(I,J,K) = HBWGT1(I,J)*CFLD(IIH(I,J), JJH(I,J) ,K) &
  3503. + HBWGT2(I,J)*CFLD(IIH(I,J)+1,JJH(I,J) ,K) &
  3504. + HBWGT3(I,J)*CFLD(IIH(I,J), JJH(I,J)-1,K) &
  3505. + HBWGT4(I,J)*CFLD(IIH(I,J), JJH(I,J)+1,K)
  3506. ELSE
  3507. CWK4(I,J,K) = HBWGT1(I,J)*CFLD(IIH(I,J), JJH(I,J) ,K) &
  3508. + HBWGT2(I,J)*CFLD(IIH(I,J)+1,JJH(I,J) ,K) &
  3509. + HBWGT3(I,J)*CFLD(IIH(I,J)+1,JJH(I,J)-1,K) &
  3510. + HBWGT4(I,J)*CFLD(IIH(I,J)+1,JJH(I,J)+1,K)
  3511. ENDIF
  3512. ntemp_b(i,J,K) = CWK4(I,J,K)
  3513. ntemp_bt(i,J,K) = 0.0
  3514. END DO
  3515. END DO
  3516. END IF NMM_YE
  3517. RETURN
  3518. END SUBROUTINE nmm_bdy_hinterp
  3519. !--------------------------------------------------------------------------------------
  3520. SUBROUTINE nmm_bdy_vinterp ( cfld, & ! CD field
  3521. cids, cide, ckds, ckde, cjds, cjde, &
  3522. cims, cime, ckms, ckme, cjms, cjme, &
  3523. cits, cite, ckts, ckte, cjts, cjte, &
  3524. nfld, & ! ND field
  3525. nids, nide, nkds, nkde, njds, njde, &
  3526. nims, nime, nkms, nkme, njms, njme, &
  3527. nits, nite, nkts, nkte, njts, njte, &
  3528. shw, & ! stencil half width
  3529. imask, & ! interpolation mask
  3530. xstag, ystag, & ! staggering of field
  3531. ipos, jpos, & ! Position of lower left of nest in CD
  3532. nri, nrj, & ! nest ratios
  3533. c_bxs,n_bxs, &
  3534. c_bxe,n_bxe, &
  3535. c_bys,n_bys, &
  3536. c_bye,n_bye, &
  3537. c_btxs,n_btxs, &
  3538. c_btxe,n_btxe, &
  3539. c_btys,n_btys, &
  3540. c_btye,n_btye, &
  3541. CTEMP_B,NTEMP_B, & ! These temp arrays should be removed
  3542. CTEMP_BT,NTEMP_BT, & ! later on
  3543. CII, IIV, CJJ, JJV, CBWGT1, VBWGT1, & ! south-western grid locs and weights
  3544. CBWGT2, VBWGT2, CBWGT3, VBWGT3, & ! note that "C"ourse grid ones are
  3545. CBWGT4, VBWGT4 ) ! dummys
  3546. ! use module_state_description
  3547. USE module_configure
  3548. USE module_wrf_error
  3549. IMPLICIT NONE
  3550. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  3551. cims, cime, ckms, ckme, cjms, cjme, &
  3552. cits, cite, ckts, ckte, cjts, cjte, &
  3553. nids, nide, nkds, nkde, njds, njde, &
  3554. nims, nime, nkms, nkme, njms, njme, &
  3555. nits, nite, nkts, nkte, njts, njte, &
  3556. shw, &
  3557. ipos, jpos, &
  3558. nri, nrj
  3559. LOGICAL, INTENT(IN) :: xstag, ystag
  3560. REAL, DIMENSION ( cims:cime, cjms:cjme, ckms:ckme ) :: cfld
  3561. REAL, DIMENSION ( nims:nime, njms:njme, nkms:nkme ) :: nfld
  3562. !
  3563. REAL, DIMENSION ( cims:cime, cjms:cjme, ckms:ckme ) :: ctemp_b,ctemp_bt
  3564. REAL, DIMENSION ( nims:nime, njms:njme, nkms:nkme ) :: ntemp_b,ntemp_bt
  3565. !
  3566. INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
  3567. REAL, DIMENSION( * ), INTENT(INOUT) :: c_bxs,n_bxs,c_bxe,n_bxe,c_bys,n_bys,c_bye,n_bye
  3568. REAL, DIMENSION( * ), INTENT(INOUT) :: c_btxs,n_btxs,c_btxe,n_btxe,c_btys,n_btys,c_btye,n_btye
  3569. REAL, DIMENSION ( cims:cime, cjms:cjme ), INTENT(IN) :: CBWGT1,CBWGT2,CBWGT3,CBWGT4 ! dummy
  3570. REAL, DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: VBWGT1,VBWGT2,VBWGT3,VBWGT4
  3571. INTEGER, DIMENSION ( cims:cime, cjms:cjme ), INTENT(IN) :: CII,CJJ ! dummy
  3572. INTEGER, DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: IIV,JJV
  3573. ! Local
  3574. INTEGER :: i,j,k
  3575. REAL, DIMENSION ( nims:nime, njms:njme, nkms:nkme ) :: cwk1,cwk2,cwk3,cwk4
  3576. ! X start boundary
  3577. NMM_XS: IF(NITS .EQ. NIDS)THEN
  3578. ! WRITE(0,*)'ENTERING X START BOUNDARY AT VELOCITY POINTS',NITS,NIDS,NJTS,MIN(NJTE,NJDE-1)
  3579. I = NIDS
  3580. DO K = NKDS,NKDE
  3581. DO J = NJTS,MIN(NJTE,NJDE-1)
  3582. IF(MOD(J,2) .EQ.0)THEN ! 1,3,5,7 of nested domain
  3583. IF(MOD(JJV(I,J),2) .NE. 0)THEN ! 1,3,5,7 of the parent domain
  3584. CWK1(I,J,K) = VBWGT1(I,J)*CFLD(IIV(I,J), JJV(I,J) ,K) &
  3585. + VBWGT2(I,J)*CFLD(IIV(I,J)+1,JJV(I,J) ,K) &
  3586. + VBWGT3(I,J)*CFLD(IIV(I,J)+1,JJV(I,J)-1,K) &
  3587. + VBWGT4(I,J)*CFLD(IIV(I,J)+1,JJV(I,J)+1,K)
  3588. ELSE
  3589. CWK1(I,J,K) = VBWGT1(I,J)*CFLD(IIV(I,J), JJV(I,J) ,K) &
  3590. + VBWGT2(I,J)*CFLD(IIV(I,J)+1,JJV(I,J) ,K) &
  3591. + VBWGT3(I,J)*CFLD(IIV(I,J), JJV(I,J)-1,K) &
  3592. + VBWGT4(I,J)*CFLD(IIV(I,J), JJV(I,J)+1,K)
  3593. ENDIF
  3594. ELSE
  3595. CWK1(I,J,K) = 0.0 ! odd rows along J, at mass points have zero velocity
  3596. ENDIF
  3597. ntemp_b(i,J,K) = CWK1(I,J,K)
  3598. ntemp_bt(i,J,K) = 0.0
  3599. END DO
  3600. END DO
  3601. ENDIF NMM_XS
  3602. ! X end boundary
  3603. NMM_XE: IF(NITE-1 .EQ. NIDE-1)THEN
  3604. ! WRITE(0,*)'ENTERING X END BOUNDARY AT VELOCITY POINTS',NITE-1,NIDE-1,NJTS,MIN(NJTE,NJDE-1)
  3605. I = NIDE-1
  3606. DO K = NKDS,NKDE
  3607. DO J = NJTS,MIN(NJTE,NJDE-1)
  3608. IF(MOD(J,2) .EQ.0)THEN ! 1,3,5,7 of the nested domain
  3609. IF(MOD(JJV(I,J),2) .NE. 0)THEN ! 1,3,5,7 of the parent domain
  3610. CWK2(I,J,K) = VBWGT1(I,J)*CFLD(IIV(I,J), JJV(I,J) ,K) &
  3611. + VBWGT2(I,J)*CFLD(IIV(I,J)+1,JJV(I,J) ,K) &
  3612. + VBWGT3(I,J)*CFLD(IIV(I,J)+1,JJV(I,J)-1,K) &
  3613. + VBWGT4(I,J)*CFLD(IIV(I,J)+1,JJV(I,J)+1,K)
  3614. ELSE
  3615. CWK2(I,J,K) = VBWGT1(I,J)*CFLD(IIV(I,J), JJV(I,J) ,K) &
  3616. + VBWGT2(I,J)*CFLD(IIV(I,J)+1,JJV(I,J) ,K) &
  3617. + VBWGT3(I,J)*CFLD(IIV(I,J), JJV(I,J)-1,K) &
  3618. + VBWGT4(I,J)*CFLD(IIV(I,J), JJV(I,J)+1,K)
  3619. ENDIF
  3620. ELSE
  3621. CWK2(I,J,K) = 0.0 ! odd rows at mass points
  3622. ENDIF
  3623. ntemp_b(i,J,K) = CWK2(I,J,K)
  3624. ntemp_bt(i,J,K) = 0.0
  3625. END DO
  3626. END DO
  3627. ENDIF NMM_XE
  3628. ! Y start boundary
  3629. NMM_YS: IF(NJTS .EQ. NJDS)THEN
  3630. ! WRITE(0,*)'ENTERING Y START BOUNDARY AT VELOCITY POINTS',NJTS,NJDS,NITS,MIN(NITE,NIDE-1)
  3631. J = NJDS
  3632. DO K = NKDS, NKDE
  3633. DO I = NITS,MIN(NITE,NIDE-2) ! NIDE-1 SHOULD NOT MATTER IF WE FILL UP PHANTOM CELL
  3634. IF(MOD(JJV(I,J),2) .NE. 0)THEN ! 1,3,5,7
  3635. CWK3(I,J,K) = VBWGT1(I,J)*CFLD(IIV(I,J), JJV(I,J) ,K) &
  3636. + VBWGT2(I,J)*CFLD(IIV(I,J)+1,JJV(I,J) ,K) &
  3637. + VBWGT3(I,J)*CFLD(IIV(I,J)+1,JJV(I,J)-1,K) &
  3638. + VBWGT4(I,J)*CFLD(IIV(I,J)+1,JJV(I,J)+1,K)
  3639. ELSE
  3640. CWK3(I,J,K) = VBWGT1(I,J)*CFLD(IIV(I,J), JJV(I,J) ,K) &
  3641. + VBWGT2(I,J)*CFLD(IIV(I,J)+1,JJV(I,J) ,K) &
  3642. + VBWGT3(I,J)*CFLD(IIV(I,J), JJV(I,J)-1,K) &
  3643. + VBWGT4(I,J)*CFLD(IIV(I,J), JJV(I,J)+1,K)
  3644. ENDIF
  3645. ntemp_b(i,J,K) = CWK3(I,J,K)
  3646. ntemp_bt(i,J,K) = 0.0
  3647. END DO
  3648. END DO
  3649. END IF NMM_YS
  3650. ! Y end boundary
  3651. NMM_YE: IF(NJTE-1 .EQ. NJDE-1)THEN
  3652. ! WRITE(0,*)'ENTERING Y END BOUNDARY AT VELOCITY POINTS',NJTE-1,NJDE-1,NITS,MIN(NITE,NIDE-1)
  3653. J = NJDE-1
  3654. DO K = NKDS,NKDE
  3655. DO I = NITS,MIN(NITE,NIDE-2) ! NIDE-1 SHOULD NOT MATTER IF WE FILL UP PHANTOM CELL
  3656. IF(MOD(JJV(I,J),2) .NE. 0)THEN ! 1,3,5,7
  3657. CWK4(I,J,K) = VBWGT1(I,J)*CFLD(IIV(I,J), JJV(I,J) ,K) &
  3658. + VBWGT2(I,J)*CFLD(IIV(I,J)+1,JJV(I,J) ,K) &
  3659. + VBWGT3(I,J)*CFLD(IIV(I,J)+1,JJV(I,J)-1,K) &
  3660. + VBWGT4(I,J)*CFLD(IIV(I,J)+1,JJV(I,J)+1,K)
  3661. ELSE
  3662. CWK4(I,J,K) = VBWGT1(I,J)*CFLD(IIV(I,J), JJV(I,J) ,K) &
  3663. + VBWGT2(I,J)*CFLD(IIV(I,J)+1,JJV(I,J) ,K) &
  3664. + VBWGT3(I,J)*CFLD(IIV(I,J), JJV(I,J)-1,K) &
  3665. + VBWGT4(I,J)*CFLD(IIV(I,J), JJV(I,J)+1,K)
  3666. ENDIF
  3667. ntemp_b(i,J,K) = CWK4(I,J,K)
  3668. ntemp_bt(i,J,K) = 0.0
  3669. END DO
  3670. END DO
  3671. END IF NMM_YE
  3672. RETURN
  3673. END SUBROUTINE nmm_bdy_vinterp
  3674. !
  3675. !=======================================================================================
  3676. ! E grid interpolation: simple copy from parent to mother domain
  3677. !=======================================================================================
  3678. !
  3679. SUBROUTINE nmm_copy ( cfld, & ! CD field
  3680. cids, cide, ckds, ckde, cjds, cjde, &
  3681. cims, cime, ckms, ckme, cjms, cjme, &
  3682. cits, cite, ckts, ckte, cjts, cjte, &
  3683. nfld, & ! ND field
  3684. nids, nide, nkds, nkde, njds, njde, &
  3685. nims, nime, nkms, nkme, njms, njme, &
  3686. nits, nite, nkts, nkte, njts, njte, &
  3687. shw, & ! stencil half width
  3688. imask, & ! interpolation mask
  3689. xstag, ystag, & ! staggering of field
  3690. ipos, jpos, & ! Position of lower left of nest in CD
  3691. nri, nrj, & ! nest ratios
  3692. CII, IIH, CJJ, JJH )
  3693. USE module_timing
  3694. IMPLICIT NONE
  3695. LOGICAL, INTENT(IN) :: xstag, ystag
  3696. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  3697. cims, cime, ckms, ckme, cjms, cjme, &
  3698. cits, cite, ckts, ckte, cjts, cjte, &
  3699. nids, nide, nkds, nkde, njds, njde, &
  3700. nims, nime, nkms, nkme, njms, njme, &
  3701. nits, nite, nkts, nkte, njts, njte, &
  3702. shw, &
  3703. ipos, jpos, &
  3704. nri, nrj
  3705. REAL, DIMENSION ( cims:cime, cjms:cjme, ckms:ckme ), INTENT(IN) :: cfld
  3706. REAL, DIMENSION ( nims:nime, njms:njme, nkms:nkme ), INTENT(INOUT) :: nfld
  3707. INTEGER, DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: imask
  3708. INTEGER, DIMENSION ( cims:cime, cjms:cjme ), INTENT(IN) :: CII,CJJ ! dummy
  3709. INTEGER, DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: IIH,JJH
  3710. ! local
  3711. INTEGER i,j,k
  3712. DO J=NJTS,MIN(NJTE,NJDE-1)
  3713. DO K=NKTS,NKTE
  3714. DO I=NITS,MIN(NITE,NIDE-1)
  3715. NFLD(I,J,K) = CFLD(IIH(I,J),JJH(I,J),K)
  3716. ENDDO
  3717. ENDDO
  3718. ENDDO
  3719. RETURN
  3720. END SUBROUTINE nmm_copy
  3721. !
  3722. !=======================================================================================
  3723. ! E grid test for mass point coincidence
  3724. !=======================================================================================
  3725. !
  3726. SUBROUTINE test_nmm (cfld, & ! CD field
  3727. cids, cide, ckds, ckde, cjds, cjde, &
  3728. cims, cime, ckms, ckme, cjms, cjme, &
  3729. cits, cite, ckts, ckte, cjts, cjte, &
  3730. nfld, & ! ND field
  3731. nids, nide, nkds, nkde, njds, njde, &
  3732. nims, nime, nkms, nkme, njms, njme, &
  3733. nits, nite, nkts, nkte, njts, njte, &
  3734. shw, & ! stencil half width for interp
  3735. imask, & ! interpolation mask
  3736. xstag, ystag, & ! staggering of field
  3737. ipos, jpos, & ! Position of lower left of nest in CD
  3738. nri, nrj, & ! nest ratios
  3739. CII, IIH, CJJ, JJH, CBWGT1, HBWGT1, & ! south-western grid locs and weights
  3740. CBWGT2, HBWGT2, CBWGT3, HBWGT3, & ! note that "C"ourse grid ones are
  3741. CBWGT4, HBWGT4 ) ! dummys for weights
  3742. USE module_timing
  3743. IMPLICIT NONE
  3744. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  3745. cims, cime, ckms, ckme, cjms, cjme, &
  3746. cits, cite, ckts, ckte, cjts, cjte, &
  3747. nids, nide, nkds, nkde, njds, njde, &
  3748. nims, nime, nkms, nkme, njms, njme, &
  3749. nits, nite, nkts, nkte, njts, njte, &
  3750. shw, &
  3751. ipos, jpos, &
  3752. nri, nrj
  3753. LOGICAL, INTENT(IN) :: xstag, ystag
  3754. REAL, DIMENSION ( cims:cime, cjms:cjme, ckms:ckme ) :: cfld
  3755. REAL, DIMENSION ( nims:nime, njms:njme, nkms:nkme ) :: nfld
  3756. REAL, DIMENSION ( cims:cime, cjms:cjme ), INTENT(IN) :: CBWGT1,CBWGT2,CBWGT3,CBWGT4 ! dummy
  3757. REAL, DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: HBWGT1,HBWGT2,HBWGT3,HBWGT4
  3758. INTEGER, DIMENSION ( cims:cime, cjms:cjme ), INTENT(IN) :: CII,CJJ ! dummy
  3759. INTEGER, DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: IIH,JJH
  3760. INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
  3761. ! local
  3762. INTEGER i,j,k
  3763. REAL,PARAMETER :: error=0.0001,error1=1.0
  3764. REAL :: diff
  3765. !
  3766. !*** CHECK DOMAIN BOUNDS BEFORE INTERPOLATION
  3767. !
  3768. DO J=NJTS,MIN(NJTE,NJDE-1)
  3769. DO I=NITS,MIN(NITE,NIDE-1)
  3770. IF(IIH(i,j).LT.(CIDS-shw) .OR. IIH(i,j).GT.(CIDE+shw)) &
  3771. CALL wrf_error_fatal ('hpoints:check domain bounds along x' )
  3772. IF(JJH(i,j).LT.(CJDS-shw) .OR. JJH(i,j).GT.(CJDE+shw)) &
  3773. CALL wrf_error_fatal ('hpoints:check domain bounds along y' )
  3774. ENDDO
  3775. ENDDO
  3776. !
  3777. !*** INDEX CONVENTIONS
  3778. !*** HBWGT4
  3779. !*** 4
  3780. !***
  3781. !***
  3782. !***
  3783. !*** h
  3784. !*** 1 2
  3785. !*** HBWGT1 HBWGT2
  3786. !***
  3787. !***
  3788. !*** 3
  3789. !*** HBWGT3
  3790. ! WRITE(0,*)NITS,MIN(NITE,NIDE-1),CITS,CITE
  3791. DO J=NJTS,MIN(NJTE,NJDE-1)
  3792. DO K=NKDS,NKDE
  3793. DO I=NITS,MIN(NITE,NIDE-1)
  3794. IF(ABS(1.0-HBWGT1(I,J)) .LE. ERROR)THEN
  3795. DIFF=ABS(NFLD(I,J,K)-CFLD(IIH(I,J),JJH(I,J),K))
  3796. IF(DIFF .GT. ERROR)THEN
  3797. CALL wrf_debug(1,"dyn_nmm: NON-COINCIDENT, NESTED MASS POINT")
  3798. WRITE(0,*)I,IIH(I,J),J,JJH(I,J),HBWGT1(I,J),NFLD(I,J,K),CFLD(IIH(I,J),JJH(I,J),K),DIFF
  3799. ENDIF
  3800. IF(DIFF .GT. ERROR1)THEN
  3801. WRITE(0,*)I,IIH(I,J),J,JJH(I,J),HBWGT1(I,J),NFLD(I,J,K),CFLD(IIH(I,J),JJH(I,J),K),DIFF
  3802. CALL wrf_error_fatal ('dyn_nmm: NON-COINCIDENT, NESTED MASS POINT')
  3803. ENDIF
  3804. ENDIF
  3805. ENDDO
  3806. ENDDO
  3807. ENDDO
  3808. END SUBROUTINE test_nmm
  3809. !==================================
  3810. ! this is the default function used in nmm feedback at mass points.
  3811. SUBROUTINE nmm_feedback ( cfld, & ! CD field
  3812. cids, cide, ckds, ckde, cjds, cjde, &
  3813. cims, cime, ckms, ckme, cjms, cjme, &
  3814. cits, cite, ckts, ckte, cjts, cjte, &
  3815. nfld, & ! ND field
  3816. nids, nide, nkds, nkde, njds, njde, &
  3817. nims, nime, nkms, nkme, njms, njme, &
  3818. nits, nite, nkts, nkte, njts, njte, &
  3819. shw, & ! stencil half width for interp
  3820. imask, & ! interpolation mask
  3821. xstag, ystag, & ! staggering of field
  3822. ipos, jpos, & ! Position of lower left of nest in CD
  3823. nri, nrj, & ! nest ratios
  3824. CII, IIH, CJJ, JJH, &
  3825. CBWGT1, HBWGT1, CBWGT2, HBWGT2, &
  3826. CBWGT3, HBWGT3, CBWGT4, HBWGT4 )
  3827. USE module_configure
  3828. IMPLICIT NONE
  3829. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  3830. cims, cime, ckms, ckme, cjms, cjme, &
  3831. cits, cite, ckts, ckte, cjts, cjte, &
  3832. nids, nide, nkds, nkde, njds, njde, &
  3833. nims, nime, nkms, nkme, njms, njme, &
  3834. nits, nite, nkts, nkte, njts, njte, &
  3835. shw, &
  3836. ipos, jpos, &
  3837. nri, nrj
  3838. INTEGER,DIMENSION(cims:cime,cjms:cjme), INTENT(IN) :: CII,CJJ ! dummy
  3839. INTEGER,DIMENSION(nims:nime,njms:njme), INTENT(IN) :: IIH,JJH
  3840. REAL,DIMENSION(cims:cime,cjms:cjme), INTENT(IN) :: CBWGT1,CBWGT2,CBWGT3,CBWGT4
  3841. REAL,DIMENSION(nims:nime,njms:njme), INTENT(IN) :: HBWGT1,HBWGT2,HBWGT3,HBWGT4
  3842. LOGICAL, INTENT(IN) :: xstag, ystag
  3843. REAL, DIMENSION ( cims:cime, cjms:cjme, ckms:ckme ), INTENT(OUT) :: cfld
  3844. REAL, DIMENSION ( nims:nime, njms:njme, nkms:nkme ), INTENT(IN) :: nfld
  3845. INTEGER, DIMENSION ( nims:nime, njms:njme ),INTENT(IN) :: imask
  3846. ! Local
  3847. INTEGER ci, cj, ck, ni, nj, nk, ip, jp, ioff, joff, ioffa, joffa
  3848. INTEGER :: icmin,icmax,jcmin,jcmax
  3849. INTEGER :: is, ipoints,jpoints,ijpoints
  3850. INTEGER , PARAMETER :: passes = 2
  3851. REAL :: AVGH
  3852. !=====================================================================================
  3853. !
  3854. IF(nri .ne. 3 .OR. nrj .ne. 3) &
  3855. CALL wrf_error_fatal ('Feedback works for only 1:3 ratios, currently. Modify the namelist' )
  3856. ! WRITE(0,*)'SIMPLE FEED BACK IS SWITCHED ON FOR MASS'
  3857. CFLD = 9999.0
  3858. DO ck = ckts, ckte
  3859. nk = ck
  3860. DO cj = MAX(jpos+1,cjts),MIN(jpos+(njde-njds)/nrj-1,cjte) ! exclude top and bottom BCs
  3861. nj = (cj-jpos)*nrj + 1
  3862. if(mod(cj,2) .eq. 0)THEN
  3863. is=0 ! even rows for mass points (2,4,6,8)
  3864. else
  3865. is=1 ! odd rows for mass points (1,3,5,7)
  3866. endif
  3867. DO ci = MAX(ipos+is,cits),MIN(ipos+(nide-nids)/nri-1,cite) ! excludes LBCs
  3868. ni = (ci-ipos)*nri + 2 -is
  3869. IF(IS==0)THEN ! (2,4,6,8)
  3870. ! AVGH = NFLD(NI,NJ+1,NK) + NFLD(NI,NJ-1,NK) + NFLD(NI+1,NJ+1,NK)+ NFLD(NI+1,NJ-1,NK) &
  3871. ! + NFLD(NI+1,NJ,NK) + NFLD(NI-1,NJ,NK) + NFLD(NI,NJ+2,NK) + NFLD(NI,NJ-2,NK) &
  3872. ! + NFLD(NI+1,NJ+2,NK)+ NFLD(NI-1,NJ+2,NK)+ NFLD(NI+1,NJ-2,NK)+ NFLD(NI-1,NJ-2,NK)
  3873. AVGH = NFLD(NI,NJ+2,NK) &
  3874. + NFLD(NI ,NJ+1,NK) + NFLD(NI+1,NJ+1,NK) &
  3875. + NFLD(NI-1,NJ ,NK) + NFLD(NI,NJ ,NK) + NFLD(NI+1,NJ ,NK) &
  3876. + NFLD(NI ,NJ-1,NK) + NFLD(NI+1,NJ-1,NK) &
  3877. + NFLD(NI,NJ-2,NK)
  3878. ELSE
  3879. ! AVGH = NFLD(NI,NJ+1,NK) + NFLD(NI,NJ-1,NK) + NFLD(NI-1,NJ+1,NK)+ NFLD(NI-1,NJ-1,NK) &
  3880. ! + NFLD(NI+1,NJ,NK) + NFLD(NI-1,NJ,NK) + NFLD(NI,NJ+2,NK) + NFLD(NI,NJ-2,NK) &
  3881. ! + NFLD(NI+1,NJ+2,NK)+ NFLD(NI-1,NJ+2,NK)+ NFLD(NI+1,NJ-2,NK)+ NFLD(NI-1,NJ-2,NK)
  3882. AVGH = NFLD(NI,NJ+2,NK) &
  3883. + NFLD(NI-1,NJ+1,NK) + NFLD(NI,NJ+1,NK) &
  3884. + NFLD(NI-1,NJ ,NK) + NFLD(NI,NJ ,NK) + NFLD(NI+1,NJ ,NK) &
  3885. + NFLD(NI-1,NJ-1,NK) + NFLD(NI,NJ-1,NK) &
  3886. + NFLD(NI,NJ-2,NK)
  3887. ENDIF
  3888. !dusan CFLD(CI,CK,CJ) = 0.5*CFLD(CI,CK,CJ) + 0.5*(NFLD(NI,NK,NJ)+AVGH)/13.0
  3889. ! CFLD(CI,CJ,CK) = (NFLD(NI,NJ,NK)+AVGH)/13.0
  3890. CFLD(CI,CJ,CK) = AVGH/9.0
  3891. ENDDO
  3892. ENDDO
  3893. ENDDO
  3894. END SUBROUTINE nmm_feedback
  3895. !===========================================================================================
  3896. SUBROUTINE nmm_vfeedback ( cfld, & ! CD field
  3897. cids, cide, ckds, ckde, cjds, cjde, &
  3898. cims, cime, ckms, ckme, cjms, cjme, &
  3899. cits, cite, ckts, ckte, cjts, cjte, &
  3900. nfld, & ! ND field
  3901. nids, nide, nkds, nkde, njds, njde, &
  3902. nims, nime, nkms, nkme, njms, njme, &
  3903. nits, nite, nkts, nkte, njts, njte, &
  3904. shw, & ! stencil half width for interp
  3905. imask, & ! interpolation mask
  3906. xstag, ystag, & ! staggering of field
  3907. ipos, jpos, & ! Position of lower left of nest in CD
  3908. nri, nrj, & ! nest ratios
  3909. CII, IIV, CJJ, JJV, &
  3910. CBWGT1, VBWGT1, CBWGT2, VBWGT2, &
  3911. CBWGT3, VBWGT3, CBWGT4, VBWGT4 )
  3912. USE module_configure
  3913. IMPLICIT NONE
  3914. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  3915. cims, cime, ckms, ckme, cjms, cjme, &
  3916. cits, cite, ckts, ckte, cjts, cjte, &
  3917. nids, nide, nkds, nkde, njds, njde, &
  3918. nims, nime, nkms, nkme, njms, njme, &
  3919. nits, nite, nkts, nkte, njts, njte, &
  3920. shw, &
  3921. ipos, jpos, &
  3922. nri, nrj
  3923. INTEGER,DIMENSION(cims:cime,cjms:cjme), INTENT(IN) :: CII,CJJ ! dummy
  3924. INTEGER,DIMENSION(nims:nime,njms:njme), INTENT(IN) :: IIV,JJV
  3925. REAL,DIMENSION(cims:cime,cjms:cjme), INTENT(IN) :: CBWGT1,CBWGT2,CBWGT3,CBWGT4
  3926. REAL,DIMENSION(nims:nime,njms:njme), INTENT(IN) :: VBWGT1,VBWGT2,VBWGT3,VBWGT4
  3927. LOGICAL, INTENT(IN) :: xstag, ystag
  3928. REAL, DIMENSION ( cims:cime, cjms:cjme, ckms:ckme ), INTENT(OUT) :: cfld
  3929. REAL, DIMENSION ( nims:nime, njms:njme, nkms:nkme ), INTENT(IN) :: nfld
  3930. INTEGER, DIMENSION ( nims:nime, njms:njme ),INTENT(IN) :: imask
  3931. ! Local
  3932. INTEGER ci, cj, ck, ni, nj, nk, ip, jp, ioff, joff, ioffa, joffa
  3933. INTEGER :: icmin,icmax,jcmin,jcmax
  3934. INTEGER :: is, ipoints,jpoints,ijpoints
  3935. INTEGER , PARAMETER :: passes = 2
  3936. REAL :: AVGV
  3937. !=====================================================================================
  3938. !
  3939. IF(nri .ne. 3 .OR. nrj .ne. 3) &
  3940. CALL wrf_error_fatal ('Feedback works for only 1:3 ratios, currently. Modify the namelist')
  3941. ! WRITE(0,*)'SIMPLE FEED BACK IS SWITCHED ON FOR VELOCITY'
  3942. CFLD = 9999.0
  3943. DO ck = ckts, ckte
  3944. nk = ck
  3945. DO cj = MAX(jpos+1,cjts),MIN(jpos+(njde-njds)/nrj-1,cjte) ! exclude top and bottom BCs
  3946. nj = (cj-jpos)*nrj + 1
  3947. if(mod(cj,2) .eq. 0)THEN
  3948. is=1 ! even rows for velocity points (2,4,6,8)
  3949. else
  3950. is=0 ! odd rows for velocity points (1,3,5,7)
  3951. endif
  3952. DO ci = MAX(ipos+is,cits),MIN(ipos+(nide-nids)/nri-1,cite) ! excludes LBCs
  3953. ni = (ci-ipos)*nri + 2 -is
  3954. IF(IS==0)THEN ! (1,3,5,7)
  3955. ! AVGV = NFLD(NI,NK,NJ+1) + NFLD(NI,NK,NJ-1) + NFLD(NI+1,NK,NJ+1)+ NFLD(NI+1,NK,NJ-1) &
  3956. ! + NFLD(NI+1,NK,NJ) + NFLD(NI-1,NK,NJ) + NFLD(NI,NK,NJ+2) + NFLD(NI,NK,NJ-2) &
  3957. ! + NFLD(NI+1,NK,NJ+2)+ NFLD(NI-1,NK,NJ+2)+ NFLD(NI+1,NK,NJ-2)+ NFLD(NI-1,NK,NJ-2)
  3958. AVGV = NFLD(NI,NJ+2,NK) &
  3959. + NFLD(NI ,NJ+1,NK) + NFLD(NI+1,NJ+1,NK) &
  3960. + NFLD(NI-1,NJ ,NK) + NFLD(NI,NJ ,NK) + NFLD(NI+1,NJ ,NK) &
  3961. + NFLD(NI ,NJ-1,NK) + NFLD(NI+1,NJ-1,NK) &
  3962. + NFLD(NI,NJ-2,NK)
  3963. ELSE
  3964. ! AVGV = NFLD(NI,NK,NJ+1) + NFLD(NI,NK,NJ-1) + NFLD(NI-1,NK,NJ+1)+ NFLD(NI-1,NK,NJ-1) &
  3965. ! + NFLD(NI+1,NK,NJ) + NFLD(NI-1,NK,NJ) + NFLD(NI,NK,NJ+2) + NFLD(NI,NK,NJ-2) &
  3966. ! + NFLD(NI+1,NK,NJ+2)+ NFLD(NI-1,NK,NJ+2)+ NFLD(NI+1,NK,NJ-2)+ NFLD(NI-1,NK,NJ-2)
  3967. AVGV = NFLD(NI,NJ+2,NK) &
  3968. + NFLD(NI-1,NJ+1,NK) + NFLD(NI,NJ+1,NK) &
  3969. + NFLD(NI-1,NJ ,NK) + NFLD(NI,NJ ,NK) + NFLD(NI+1,NJ ,NK) &
  3970. + NFLD(NI-1,NJ-1,NK) + NFLD(NI,NJ-1,NK) &
  3971. + NFLD(NI,NJ-2,NK)
  3972. ENDIF
  3973. !dusan CFLD(CI,CK,CJ) = 0.5*CFLD(CI,CK,CJ) + 0.5*(NFLD(NI,NK,NJ)+AVGV)/13.0
  3974. ! CFLD(CI,CK,CJ) = (NFLD(NI,NK,NJ)+AVGV)/13.0
  3975. CFLD(CI,CJ,CK) = AVGV/9.0
  3976. ENDDO
  3977. ENDDO
  3978. ENDDO
  3979. END SUBROUTINE nmm_vfeedback
  3980. SUBROUTINE nmm_smoother ( cfld , &
  3981. cids, cide, ckds, ckde, cjds, cjde, &
  3982. cims, cime, ckms, ckme, cjms, cjme, &
  3983. cits, cite, ckts, ckte, cjts, cjte, &
  3984. nids, nide, nkds, nkde, njds, njde, &
  3985. nims, nime, nkms, nkme, njms, njme, &
  3986. nits, nite, nkts, nkte, njts, njte, &
  3987. xstag, ystag, &
  3988. ipos, jpos, &
  3989. nri, nrj &
  3990. )
  3991. USE module_configure
  3992. IMPLICIT NONE
  3993. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  3994. cims, cime, ckms, ckme, cjms, cjme, &
  3995. cits, cite, ckts, ckte, cjts, cjte, &
  3996. nids, nide, nkds, nkde, njds, njde, &
  3997. nims, nime, nkms, nkme, njms, njme, &
  3998. nits, nite, nkts, nkte, njts, njte, &
  3999. nri, nrj, &
  4000. ipos, jpos
  4001. REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ), INTENT(INOUT) :: cfld
  4002. LOGICAL, INTENT(IN) :: xstag, ystag
  4003. ! Local
  4004. INTEGER :: feedback
  4005. INTEGER, PARAMETER :: smooth_passes = 5
  4006. REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfldnew
  4007. INTEGER :: ci, cj, ck
  4008. INTEGER :: is, npass
  4009. REAL :: AVGH
  4010. RETURN
  4011. ! If there is no feedback, there can be no smoothing.
  4012. CALL nl_get_feedback ( 1, feedback )
  4013. IF ( feedback == 0 ) RETURN
  4014. WRITE(0,*)'SIMPLE SMOOTHER IS SWITCHED ON FOR HEIGHT'
  4015. DO npass = 1, smooth_passes
  4016. DO cj = MAX(jpos+1,cjts),MIN(jpos+(njde-njds)/nrj-1,cjte) ! exclude top and bottom BCs
  4017. if(mod(cj,2) .eq. 0)THEN
  4018. is=0 ! even rows for mass points (2,4,6,8)
  4019. else
  4020. is=1 ! odd rows for mass points (1,3,5,7)
  4021. endif
  4022. DO ck = ckts, ckte
  4023. DO ci = MAX(ipos+is,cits),MIN(ipos+(nide-nids)/nri-1,cite) ! excludes LBCs
  4024. IF(IS==0)THEN ! (2,4,6,8)
  4025. AVGH = CFLD(CI,CK,CJ+1) + CFLD(CI,CK,CJ-1) + CFLD(CI+1,CK,CJ+1) + CFLD(CI+1,CK,CJ-1)
  4026. ELSE
  4027. AVGH = CFLD(CI,CK,CJ+1) + CFLD(CI,CK,CJ-1) + CFLD(CI-1,CK,CJ+1) + CFLD(CI-1,CK,CJ-1)
  4028. ENDIF
  4029. CFLDNEW(CI,CK,CJ) = (AVGH + 4*CFLD(CI,CK,CJ)) / 8.0
  4030. ENDDO
  4031. ENDDO
  4032. ENDDO
  4033. DO cj = MAX(jpos+1,cjts),MIN(jpos+(njde-njds)/nrj-1,cjte) ! exclude top and bottom BCs
  4034. if(mod(cj,2) .eq. 0)THEN
  4035. is=0 ! even rows for mass points (2,4,6,8)
  4036. else
  4037. is=1 ! odd rows for mass points (1,3,5,7)
  4038. endif
  4039. DO ck = ckts, ckte
  4040. DO ci = MAX(ipos+is,cits),MIN(ipos+(nide-nids)/nri-1,cite) ! excludes LBCs
  4041. CFLD(CI,CK,CJ) = CFLDNEW(CI,CK,CJ)
  4042. ENDDO
  4043. ENDDO
  4044. ENDDO
  4045. ENDDO ! do npass
  4046. END SUBROUTINE nmm_smoother
  4047. SUBROUTINE nmm_vsmoother ( cfld , &
  4048. cids, cide, ckds, ckde, cjds, cjde, &
  4049. cims, cime, ckms, ckme, cjms, cjme, &
  4050. cits, cite, ckts, ckte, cjts, cjte, &
  4051. nids, nide, nkds, nkde, njds, njde, &
  4052. nims, nime, nkms, nkme, njms, njme, &
  4053. nits, nite, nkts, nkte, njts, njte, &
  4054. xstag, ystag, &
  4055. ipos, jpos, &
  4056. nri, nrj &
  4057. )
  4058. USE module_configure
  4059. IMPLICIT NONE
  4060. INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
  4061. cims, cime, ckms, ckme, cjms, cjme, &
  4062. cits, cite, ckts, ckte, cjts, cjte, &
  4063. nids, nide, nkds, nkde, njds, njde, &
  4064. nims, nime, nkms, nkme, njms, njme, &
  4065. nits, nite, nkts, nkte, njts, njte, &
  4066. nri, nrj, &
  4067. ipos, jpos
  4068. REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ), INTENT(INOUT) :: cfld
  4069. LOGICAL, INTENT(IN) :: xstag, ystag
  4070. ! Local
  4071. INTEGER :: feedback
  4072. INTEGER, PARAMETER :: smooth_passes = 5
  4073. REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfldnew
  4074. INTEGER :: ci, cj, ck
  4075. INTEGER :: is, npass
  4076. REAL :: AVGV
  4077. RETURN
  4078. ! If there is no feedback, there can be no smoothing.
  4079. CALL nl_get_feedback ( 1, feedback )
  4080. IF ( feedback == 0 ) RETURN
  4081. WRITE(0,*)'SIMPLE SMOOTHER IS SWITCHED ON FOR VELOCITY'
  4082. DO npass = 1, smooth_passes
  4083. DO cj = MAX(jpos+1,cjts),MIN(jpos+(njde-njds)/nrj-1,cjte) ! exclude top and bottom BCs
  4084. if(mod(cj,2) .eq. 0)THEN
  4085. is=1 ! even rows for mass points (2,4,6,8)
  4086. else
  4087. is=0 ! odd rows for mass points (1,3,5,7)
  4088. endif
  4089. DO ck = ckts, ckte
  4090. DO ci = MAX(ipos+is,cits),MIN(ipos+(nide-nids)/nri-1,cite) ! excludes LBCs
  4091. IF(IS==0)THEN ! (2,4,6,8)
  4092. AVGV = CFLD(CI,CK,CJ+1) + CFLD(CI,CK,CJ-1) + CFLD(CI+1,CK,CJ+1) + CFLD(CI+1,CK,CJ-1)
  4093. ELSE
  4094. AVGV = CFLD(CI,CK,CJ+1) + CFLD(CI,CK,CJ-1) + CFLD(CI-1,CK,CJ+1) + CFLD(CI-1,CK,CJ-1)
  4095. ENDIF
  4096. CFLDNEW(CI,CK,CJ) = (AVGV + 4*CFLD(CI,CK,CJ)) / 8.0
  4097. ENDDO
  4098. ENDDO
  4099. ENDDO
  4100. DO cj = MAX(jpos+1,cjts),MIN(jpos+(njde-njds)/nrj-1,cjte) ! exclude top and bottom BCs
  4101. if(mod(cj,2) .eq. 0)THEN
  4102. is=1 ! even rows for mass points (2,4,6,8)
  4103. else
  4104. is=0 ! odd rows for mass points (1,3,5,7)
  4105. endif
  4106. DO ck = ckts, ckte
  4107. DO ci = MAX(ipos+is,cits),MIN(ipos+(nide-nids)/nri-1,cite) ! excludes LBCs
  4108. CFLD(CI,CK,CJ) = CFLDNEW(CI,CK,CJ)
  4109. ENDDO
  4110. ENDDO
  4111. ENDDO
  4112. ENDDO
  4113. END SUBROUTINE nmm_vsmoother
  4114. !======================================================================================
  4115. ! End of gopal's doing
  4116. !======================================================================================
  4117. #endif