modmask.F90 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. !
  2. ! $Id: modmask.F90 4779 2014-09-19 14:21:37Z rblod $
  3. !
  4. ! AGRIF (Adaptive Grid Refinement In Fortran)
  5. !
  6. ! Copyright (C) 2003 Laurent Debreu (Laurent.Debreu@imag.fr)
  7. ! Christophe Vouland (Christophe.Vouland@imag.fr)
  8. !
  9. ! This program is free software; you can redistribute it and/or modify
  10. ! it under the terms of the GNU General Public License as published by
  11. ! the Free Software Foundation; either version 2 of the License, or
  12. ! (at your option) any later version.
  13. !
  14. ! This program is distributed in the hope that it will be useful,
  15. ! but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. ! GNU General Public License for more details.
  18. !
  19. ! You should have received a copy of the GNU General Public License
  20. ! along with this program; if not, write to the Free Software
  21. ! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  22. !
  23. !
  24. !> Module Agrif_Mask.
  25. !>
  26. !> Module for masks.
  27. !
  28. module Agrif_Mask
  29. !
  30. use Agrif_Types
  31. !
  32. implicit none
  33. !
  34. contains
  35. !
  36. !===================================================================================================
  37. ! subroutine Agrif_CheckMasknD
  38. !
  39. !> Called in the procedure #Agrif_InterpnD to recalculate the value of the parent grid variable
  40. !! when this one is equal to Agrif_SpecialValue.
  41. !---------------------------------------------------------------------------------------------------
  42. subroutine Agrif_CheckMasknD ( tempP, parent, pbtab, petab, ppbtab, ppetab, noraftab, nbdim )
  43. !---------------------------------------------------------------------------------------------------
  44. type(Agrif_Variable), pointer :: tempP !< Part of the parent grid used for the interpolation of the child grid
  45. type(Agrif_Variable), pointer :: parent !< The parent grid
  46. integer, dimension(nbdim) :: pbtab !< limits of the parent grid used
  47. integer, dimension(nbdim) :: petab !< interpolation of the child grid
  48. integer, dimension(nbdim) :: ppbtab, ppetab
  49. logical, dimension(nbdim) :: noraftab
  50. integer :: nbdim
  51. !
  52. integer :: i0,j0,k0,l0,m0,n0
  53. !
  54. select case (nbdim)
  55. case (1)
  56. do i0 = pbtab(1),petab(1)
  57. if (tempP%array1(i0) == Agrif_SpecialValue) then
  58. call CalculNewValTempP((/i0/),tempP,parent,ppbtab,ppetab,noraftab,nbdim)
  59. endif
  60. enddo
  61. case (2)
  62. do j0 = pbtab(2),petab(2)
  63. do i0 = pbtab(1),petab(1)
  64. if (tempP%array2(i0,j0) == Agrif_SpecialValue) then
  65. call CalculNewValTempP((/i0,j0/),tempP,parent,ppbtab,ppetab, noraftab,nbdim)
  66. endif
  67. enddo
  68. enddo
  69. case (3)
  70. do k0 = pbtab(3),petab(3)
  71. do j0 = pbtab(2),petab(2)
  72. do i0 = pbtab(1),petab(1)
  73. if (tempP%array3(i0,j0,k0) == Agrif_SpecialValue) then
  74. !------CDIR NEXPAND
  75. call CalculNewValTempP3D((/i0,j0,k0/), &
  76. tempP%array3(ppbtab(1),ppbtab(2),ppbtab(3)), &
  77. parent%array3(ppbtab(1),ppbtab(2),ppbtab(3)), &
  78. ppbtab,ppetab,noraftab,MaxSearch,Agrif_SpecialValue)
  79. ! Call CalculNewValTempP((/i0,j0,k0/),
  80. ! & tempP,parent,
  81. ! & ppbtab,ppetab,
  82. ! & noraftab,nbdim)
  83. endif
  84. enddo
  85. enddo
  86. enddo
  87. case (4)
  88. do l0 = pbtab(4),petab(4)
  89. do k0 = pbtab(3),petab(3)
  90. do j0 = pbtab(2),petab(2)
  91. do i0 = pbtab(1),petab(1)
  92. if (tempP%array4(i0,j0,k0,l0) == Agrif_SpecialValue) then
  93. call CalculNewValTempP4D((/i0,j0,k0,l0/), &
  94. tempP%array4(ppbtab(1),ppbtab(2),ppbtab(3),ppbtab(4)), &
  95. parent%array4(ppbtab(1),ppbtab(2),ppbtab(3),ppbtab(4)), &
  96. ppbtab,ppetab,noraftab,MaxSearch,Agrif_SpecialValue)
  97. endif
  98. enddo
  99. enddo
  100. enddo
  101. enddo
  102. case (5)
  103. do m0 = pbtab(5),petab(5)
  104. do l0 = pbtab(4),petab(4)
  105. do k0 = pbtab(3),petab(3)
  106. do j0 = pbtab(2),petab(2)
  107. do i0 = pbtab(1),petab(1)
  108. if (tempP%array5(i0,j0,k0,l0,m0) == Agrif_SpecialValue) then
  109. call CalculNewValTempP((/i0,j0,k0,l0,m0/), &
  110. tempP,parent,ppbtab,ppetab,noraftab,nbdim)
  111. endif
  112. enddo
  113. enddo
  114. enddo
  115. enddo
  116. enddo
  117. case (6)
  118. do n0 = pbtab(6),petab(6)
  119. do m0 = pbtab(5),petab(5)
  120. do l0 = pbtab(4),petab(4)
  121. do k0 = pbtab(3),petab(3)
  122. do j0 = pbtab(2),petab(2)
  123. do i0 = pbtab(1),petab(1)
  124. if (tempP%array6(i0,j0,k0,l0,m0,n0) == Agrif_SpecialValue) then
  125. call CalculNewValTempP((/i0,j0,k0,l0,m0,n0/), &
  126. tempP,parent,ppbtab,ppetab,noraftab,nbdim)
  127. endif
  128. enddo
  129. enddo
  130. enddo
  131. enddo
  132. enddo
  133. enddo
  134. end select
  135. !---------------------------------------------------------------------------------------------------
  136. end subroutine Agrif_CheckMasknD
  137. !===================================================================================================
  138. !
  139. !===================================================================================================
  140. ! subroutine CalculNewValTempP
  141. !
  142. !> Called in the procedure #Agrif_InterpnD to recalculate the value of the parent grid variable
  143. !! when this one is equal to Agrif_SpecialValue.
  144. !---------------------------------------------------------------------------------------------------
  145. subroutine CalculNewValTempP ( indic, tempP, parent, ppbtab, ppetab, noraftab, nbdim )
  146. !---------------------------------------------------------------------------------------------------
  147. integer, dimension(nbdim) :: indic
  148. type(Agrif_Variable), pointer :: tempP !< Part of the parent grid used for the interpolation of the child grid
  149. type(Agrif_Variable), pointer :: parent !< The parent grid
  150. integer, dimension(nbdim) :: ppbtab, ppetab
  151. logical, dimension(nbdim) :: noraftab
  152. integer :: nbdim
  153. !
  154. integer :: i,ii,iii,jj,kk,ll,mm,nn
  155. integer, dimension(nbdim) :: imin,imax,idecal
  156. integer :: nbvals
  157. real :: res
  158. real :: valparent
  159. integer :: ValMax
  160. logical :: firsttest
  161. !
  162. ValMax = 1
  163. do iii = 1,nbdim
  164. if (.NOT.noraftab(iii)) then
  165. ValMax = max(ValMax,ppetab(iii)-indic(iii))
  166. ValMax = max(ValMax,indic(iii)-ppbtab(iii))
  167. endif
  168. enddo
  169. !
  170. Valmax = min(Valmax,MaxSearch)
  171. !
  172. !CDIR NOVECTOR
  173. imin = indic
  174. !CDIR NOVECTOR
  175. imax = indic
  176. !
  177. i = 1
  178. firsttest = .TRUE.
  179. !
  180. do while (i <= ValMax)
  181. !
  182. if ( (i == 1).AND.(firsttest) ) i = Valmax
  183. !
  184. do iii = 1,nbdim
  185. if (.NOT.noraftab(iii)) then
  186. imin(iii) = max(indic(iii) - i,ppbtab(iii))
  187. imax(iii) = min(indic(iii) + i,ppetab(iii))
  188. if (firsttest) then
  189. if (indic(iii) > ppbtab(iii)) then
  190. !CDIR NOVECTOR
  191. idecal = indic
  192. idecal(iii) = idecal(iii)-1
  193. SELECT CASE(nbdim)
  194. CASE (1)
  195. if (tempP%array1(idecal(1) &
  196. ) == Agrif_SpecialValue) imin(iii) = imax(iii)
  197. CASE (2)
  198. if (tempP%array2(idecal(1), idecal(2) &
  199. ) == Agrif_SpecialValue) imin(iii) = imax(iii)
  200. CASE (3)
  201. if (tempP%array3(idecal(1), &
  202. idecal(2), idecal(3) &
  203. ) == Agrif_SpecialValue) imin(iii) = imax(iii)
  204. CASE (4)
  205. if (tempP%array4(idecal(1), idecal(2), &
  206. idecal(3), idecal(4) &
  207. ) == Agrif_SpecialValue) imin(iii) = imax(iii)
  208. CASE (5)
  209. if (tempP%array5(idecal(1), idecal(2), &
  210. idecal(3), idecal(4), &
  211. idecal(5) &
  212. ) == Agrif_SpecialValue) imin(iii) = imax(iii)
  213. CASE (6)
  214. if (tempP%array6(idecal(1), idecal(2), &
  215. idecal(3), idecal(4), &
  216. idecal(5), idecal(6) &
  217. ) == Agrif_SpecialValue) imin(iii) = imax(iii)
  218. END SELECT
  219. endif
  220. endif
  221. endif
  222. enddo
  223. !
  224. Res = 0.
  225. Nbvals = 0
  226. !
  227. SELECT CASE(nbdim)
  228. CASE (1)
  229. !CDIR ALTCODE
  230. !CDIR SHORTLOOP
  231. do ii = imin(1),imax(1)
  232. ValParent = parent%array1(ii)
  233. if ( ValParent /= Agrif_SpecialValue) then
  234. Res = Res + ValParent
  235. Nbvals = Nbvals + 1
  236. endif
  237. enddo
  238. !
  239. CASE (2)
  240. do jj = imin(2),imax(2)
  241. !CDIR ALTCODE
  242. !CDIR SHORTLOOP
  243. do ii = imin(1),imax(1)
  244. ValParent = parent%array2(ii,jj)
  245. if ( ValParent /= Agrif_SpecialValue) then
  246. Res = Res + ValParent
  247. Nbvals = Nbvals + 1
  248. endif
  249. enddo
  250. enddo
  251. CASE (3)
  252. do kk = imin(3),imax(3)
  253. do jj = imin(2),imax(2)
  254. !CDIR ALTCODE
  255. !CDIR SHORTLOOP
  256. do ii = imin(1),imax(1)
  257. ValParent = parent%array3(ii,jj,kk)
  258. if ( ValParent /= Agrif_SpecialValue) then
  259. Res = Res + ValParent
  260. Nbvals = Nbvals + 1
  261. endif
  262. enddo
  263. enddo
  264. enddo
  265. CASE (4)
  266. do ll = imin(4),imax(4)
  267. do kk = imin(3),imax(3)
  268. do jj = imin(2),imax(2)
  269. !CDIR ALTCODE
  270. !CDIR SHORTLOOP
  271. do ii = imin(1),imax(1)
  272. ValParent = parent%array4(ii,jj,kk,ll)
  273. if ( ValParent /= Agrif_SpecialValue) then
  274. Res = Res + ValParent
  275. Nbvals = Nbvals + 1
  276. endif
  277. enddo
  278. enddo
  279. enddo
  280. enddo
  281. CASE (5)
  282. do mm = imin(5),imax(5)
  283. do ll = imin(4),imax(4)
  284. do kk = imin(3),imax(3)
  285. do jj = imin(2),imax(2)
  286. !CDIR ALTCODE
  287. !CDIR SHORTLOOP
  288. do ii = imin(1),imax(1)
  289. ValParent = parent%array5(ii,jj,kk,ll,mm)
  290. if ( ValParent /= Agrif_SpecialValue) then
  291. Res = Res + ValParent
  292. Nbvals = Nbvals + 1
  293. endif
  294. enddo
  295. enddo
  296. enddo
  297. enddo
  298. enddo
  299. CASE (6)
  300. do nn = imin(6),imax(6)
  301. do mm = imin(5),imax(5)
  302. do ll = imin(4),imax(4)
  303. do kk = imin(3),imax(3)
  304. do jj = imin(2),imax(2)
  305. !CDIR ALTCODE
  306. !CDIR SHORTLOOP
  307. do ii = imin(1),imax(1)
  308. ValParent = parent%array6(ii,jj,kk,ll,mm,nn)
  309. if ( ValParent /= Agrif_SpecialValue) then
  310. Res = Res + ValParent
  311. Nbvals = Nbvals + 1
  312. endif
  313. enddo
  314. enddo
  315. enddo
  316. enddo
  317. enddo
  318. enddo
  319. END SELECT
  320. !
  321. if (Nbvals > 0) then
  322. if (firsttest) then
  323. firsttest = .FALSE.
  324. i=1
  325. cycle
  326. endif
  327. SELECT CASE(nbdim)
  328. CASE (1)
  329. tempP%array1(indic(1)) = Res/Nbvals
  330. CASE (2)
  331. tempP%array2(indic(1), indic(2)) = Res/Nbvals
  332. CASE (3)
  333. tempP%array3(indic(1), indic(2), &
  334. indic(3)) = Res/Nbvals
  335. CASE (4)
  336. tempP%array4(indic(1), indic(2), &
  337. indic(3), indic(4)) = Res/Nbvals
  338. CASE (5)
  339. tempP%array5(indic(1), indic(2), &
  340. indic(3), indic(4), &
  341. indic(5)) = Res/Nbvals
  342. CASE (6)
  343. tempP%array6(indic(1), indic(2), &
  344. indic(3), indic(4), &
  345. indic(5), indic(6)) = Res/Nbvals
  346. END SELECT
  347. exit
  348. else
  349. if (firsttest) exit
  350. i = i + 1
  351. endif
  352. !
  353. enddo
  354. !---------------------------------------------------------------------------------------------------
  355. end subroutine CalculNewValTempP
  356. !===================================================================================================
  357. !
  358. !===================================================================================================
  359. ! subroutine CalculNewValTempP3D
  360. !
  361. !> Called in the procedure #Agrif_InterpnD to recalculate the value of the parent grid variable
  362. !! when this one is equal to Agrif_SpecialValue.
  363. !---------------------------------------------------------------------------------------------------
  364. subroutine CalculNewValTempP3D ( indic, tempP, parent, ppbtab, ppetab, noraftab, &
  365. MaxSearch, Agrif_SpecialValue )
  366. !---------------------------------------------------------------------------------------------------
  367. integer, parameter :: nbdim = 3
  368. integer, dimension(nbdim) :: indic
  369. integer, dimension(nbdim) :: ppbtab, ppetab
  370. logical, dimension(nbdim) :: noraftab
  371. integer :: MaxSearch
  372. real :: Agrif_SpecialValue
  373. real, dimension(ppbtab(1):ppetab(1), &
  374. ppbtab(2):ppetab(2), &
  375. ppbtab(3):ppetab(3)) &
  376. :: tempP, parent !< Part of the parent grid used for
  377. !< the interpolation of the child grid
  378. !
  379. integer :: i,ii,iii,jj,kk
  380. integer, dimension(nbdim) :: imin,imax,idecal
  381. integer :: Nbvals
  382. real :: Res
  383. real :: ValParent
  384. integer :: ValMax
  385. logical :: Existunmasked
  386. !
  387. ValMax = 1
  388. !CDIR NOVECTOR
  389. do iii = 1,nbdim
  390. if (.NOT.noraftab(iii)) then
  391. ValMax = max(ValMax,ppetab(iii)-indic(iii))
  392. ValMax = max(ValMax,indic(iii)-ppbtab(iii))
  393. endif
  394. enddo
  395. !
  396. Valmax = min(Valmax,MaxSearch)
  397. !
  398. !CDIR NOVECTOR
  399. imin = indic
  400. !CDIR NOVECTOR
  401. imax = indic
  402. !CDIR NOVECTOR
  403. idecal = indic
  404. i = Valmax
  405. !
  406. do iii = 1,nbdim
  407. if (.NOT.noraftab(iii)) then
  408. imin(iii) = max(indic(iii) - i,ppbtab(iii))
  409. imax(iii) = min(indic(iii) + i,ppetab(iii))
  410. if (indic(iii) > ppbtab(iii)) then
  411. idecal(iii) = idecal(iii)-1
  412. if (tempP(idecal(1),idecal(2),idecal(3)) == Agrif_SpecialValue) then
  413. imin(iii) = imax(iii)
  414. endif
  415. idecal(iii) = idecal(iii)+1
  416. endif
  417. endif
  418. enddo
  419. !
  420. Existunmasked = .FALSE.
  421. !
  422. do kk = imin(3),imax(3)
  423. do jj = imin(2),imax(2)
  424. !CDIR NOVECTOR
  425. do ii = imin(1),imax(1)
  426. if ( parent(ii,jj,kk) /= Agrif_SpecialValue) then
  427. Existunmasked = .TRUE.
  428. exit
  429. endif
  430. enddo
  431. enddo
  432. enddo
  433. !
  434. if (.Not.Existunmasked) return
  435. !
  436. i = 1
  437. !
  438. do while(i <= ValMax)
  439. !
  440. do iii = 1 , nbdim
  441. if (.NOT.noraftab(iii)) then
  442. imin(iii) = max(indic(iii) - i,ppbtab(iii))
  443. imax(iii) = min(indic(iii) + i,ppetab(iii))
  444. endif
  445. enddo
  446. !
  447. Res = 0.
  448. Nbvals = 0
  449. !
  450. do kk = imin(3),imax(3)
  451. do jj = imin(2),imax(2)
  452. !CDIR NOVECTOR
  453. do ii = imin(1),imax(1)
  454. ValParent = parent(ii,jj,kk)
  455. if ( ValParent /= Agrif_SpecialValue) then
  456. Res = Res + ValParent
  457. Nbvals = Nbvals + 1
  458. endif
  459. enddo
  460. enddo
  461. enddo
  462. !
  463. if (Nbvals > 0) then
  464. tempP(indic(1),indic(2),indic(3)) = Res/Nbvals
  465. exit
  466. else
  467. i = i + 1
  468. endif
  469. enddo
  470. !---------------------------------------------------------------------------------------------------
  471. end subroutine CalculNewValTempP3D
  472. !===================================================================================================
  473. !
  474. !===================================================================================================
  475. ! subroutine CalculNewValTempP4D
  476. !
  477. !> Called in the procedure #Agrif_InterpnD to recalculate the value of the parent grid variable
  478. !! when this one is equal to Agrif_SpecialValue.
  479. !---------------------------------------------------------------------------------------------------
  480. subroutine CalculNewValTempP4D ( indic, tempP, parent, ppbtab, ppetab, noraftab, &
  481. MaxSearch, Agrif_SpecialValue )
  482. !---------------------------------------------------------------------------------------------------
  483. integer, parameter :: nbdim = 4
  484. integer, dimension(nbdim) :: indic
  485. integer, dimension(nbdim) :: ppbtab, ppetab
  486. logical, dimension(nbdim) :: noraftab
  487. integer :: MaxSearch
  488. real :: Agrif_SpecialValue
  489. real, dimension(ppbtab(1):ppetab(1), &
  490. ppbtab(2):ppetab(2), &
  491. ppbtab(3):ppetab(3), &
  492. ppbtab(4):ppetab(4)) &
  493. :: tempP, parent !< Part of the parent grid used for
  494. !< the interpolation of the child grid
  495. !
  496. integer :: i,ii,iii,jj,kk,ll
  497. integer, dimension(nbdim) :: imin,imax,idecal
  498. integer :: Nbvals
  499. real :: Res
  500. real :: ValParent
  501. integer :: ValMax
  502. !
  503. logical :: firsttest
  504. !
  505. ValMax = 1
  506. do iii = 1,nbdim
  507. if (.NOT.noraftab(iii)) then
  508. ValMax = max(ValMax,ppetab(iii)-indic(iii))
  509. ValMax = max(ValMax,indic(iii)-ppbtab(iii))
  510. endif
  511. enddo
  512. !
  513. Valmax = min(Valmax,MaxSearch)
  514. !
  515. imin = indic
  516. imax = indic
  517. !
  518. i = 1
  519. firsttest = .TRUE.
  520. idecal = indic
  521. !
  522. do while (i <= ValMax)
  523. !
  524. if ((i == 1).AND.(firsttest)) i = Valmax
  525. do iii = 1,nbdim
  526. if (.NOT.noraftab(iii)) then
  527. imin(iii) = max(indic(iii) - i,ppbtab(iii))
  528. imax(iii) = min(indic(iii) + i,ppetab(iii))
  529. if (firsttest) then
  530. if (indic(iii) > ppbtab(iii)) then
  531. idecal(iii) = idecal(iii)-1
  532. if (tempP(idecal(1),idecal(2),idecal(3),idecal(4)) == Agrif_SpecialValue) then
  533. imin(iii) = imax(iii)
  534. endif
  535. idecal(iii) = idecal(iii)+1
  536. endif
  537. endif
  538. endif
  539. enddo
  540. !
  541. Res = 0.
  542. Nbvals = 0
  543. !
  544. do ll = imin(4),imax(4)
  545. do kk = imin(3),imax(3)
  546. do jj = imin(2),imax(2)
  547. do ii = imin(1),imax(1)
  548. ValParent = parent(ii,jj,kk,ll)
  549. if ( ValParent /= Agrif_SpecialValue) then
  550. Res = Res + ValParent
  551. Nbvals = Nbvals + 1
  552. endif
  553. enddo
  554. enddo
  555. enddo
  556. enddo
  557. !
  558. if (Nbvals > 0) then
  559. if (firsttest) then
  560. firsttest = .FALSE.
  561. i=1
  562. cycle
  563. endif
  564. tempP(indic(1),indic(2),indic(3),indic(4)) = Res/Nbvals
  565. exit
  566. else
  567. if (firsttest) exit
  568. i = i + 1
  569. endif
  570. enddo
  571. !---------------------------------------------------------------------------------------------------
  572. end subroutine CalculNewValTempP4D
  573. !===================================================================================================
  574. !
  575. end module Agrif_Mask