modinterpbasic.F90 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464
  1. !
  2. ! $Id: modinterpbasic.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_InterpBasic
  25. !>
  26. !> Contains different procedures of interpolation (linear,lagrange, spline,...) used in
  27. !! the Agrif_Interpolation module.
  28. !
  29. module Agrif_InterpBasic
  30. !
  31. use Agrif_Types
  32. !
  33. implicit none
  34. !
  35. real, dimension(5,Agrif_MaxRaff,3) :: tabppm
  36. real, dimension(Agrif_MaxRaff) :: tabdiff2, tabdiff3
  37. real, dimension(:), allocatable :: tabtest4
  38. real, dimension(:,:), allocatable :: coeffparent
  39. integer, dimension(:,:), allocatable :: indparent
  40. integer, dimension(:,:), allocatable :: indparentppm, indchildppm
  41. integer, dimension(:), allocatable :: indparentppm_1d, indchildppm_1d
  42. !
  43. private :: Agrif_limiter_vanleer
  44. !
  45. contains
  46. !
  47. !===================================================================================================
  48. ! subroutine Agrif_basicinterp_linear1D
  49. !
  50. !> Linear 1D interpolation on a child grid (vector y) from its parent grid (vector x).
  51. !---------------------------------------------------------------------------------------------------
  52. subroutine Agrif_basicinterp_linear1D ( x, y, np, nc, s_parent, s_child, ds_parent, ds_child )
  53. !---------------------------------------------------------------------------------------------------
  54. real, dimension(np), intent(in) :: x !< Coarse input data from parent
  55. real, dimension(nc), intent(out) :: y !< Fine output data to child
  56. integer, intent(in) :: np !< Length of input array
  57. integer, intent(in) :: nc !< Length of output array
  58. real, intent(in) :: s_parent !< Parent grid position (s_root = 0)
  59. real, intent(in) :: s_child !< Child grid position (s_root = 0)
  60. real, intent(in) :: ds_parent !< Parent grid dx (ds_root = 1)
  61. real, intent(in) :: ds_child !< Child grid dx (ds_root = 1)
  62. !
  63. integer :: i, coeffraf, locind_parent_left
  64. real :: globind_parent_left, globind_parent_right
  65. real :: invds, invds2, ypos, ypos2, diff
  66. !
  67. coeffraf = nint(ds_parent/ds_child)
  68. !
  69. if ( coeffraf == 1 ) then
  70. locind_parent_left = 1 + nint((s_child - s_parent)/ds_parent)
  71. y(1:nc) = x(locind_parent_left:locind_parent_left+nc-1)
  72. return
  73. endif
  74. !
  75. ypos = s_child
  76. locind_parent_left = 1 + agrif_int((ypos - s_parent)/ds_parent)
  77. globind_parent_left = s_parent + (locind_parent_left - 1)*ds_parent
  78. globind_parent_right = globind_parent_left + ds_parent
  79. !
  80. invds = 1./ds_parent
  81. invds2 = ds_child/ds_parent
  82. ypos2 = ypos*invds
  83. globind_parent_right = globind_parent_right*invds
  84. !
  85. do i = 1,nc-1
  86. !
  87. if (ypos2 > globind_parent_right) then
  88. locind_parent_left = locind_parent_left + 1
  89. globind_parent_right = globind_parent_right + 1.
  90. ypos2 = ypos*invds+(i-1)*invds2
  91. endif
  92. !
  93. diff = globind_parent_right - ypos2
  94. y(i) = (diff*x(locind_parent_left) + (1.-diff)*x(locind_parent_left+1))
  95. ypos2 = ypos2 + invds2
  96. !
  97. enddo
  98. !
  99. ypos = s_child + (nc-1)*ds_child
  100. locind_parent_left = 1 + agrif_int((ypos - s_parent)/ds_parent)
  101. !
  102. if (locind_parent_left == np) then
  103. y(nc) = x(np)
  104. else
  105. globind_parent_left = s_parent + (locind_parent_left - 1)*ds_parent
  106. y(nc) = ((globind_parent_left + ds_parent - ypos)*x(locind_parent_left) &
  107. + (ypos - globind_parent_left)*x(locind_parent_left+1))*invds
  108. endif
  109. !---------------------------------------------------------------------------------------------------
  110. end subroutine Agrif_basicinterp_linear1D
  111. !===================================================================================================
  112. !
  113. !===================================================================================================
  114. ! subroutine Linear1dPrecompute2d
  115. !
  116. !> Computes 2D coefficients and index for a linear 1D interpolation on a child grid (vector y)
  117. !! from its parent grid (vector x).
  118. !---------------------------------------------------------------------------------------------------
  119. subroutine Linear1dPrecompute2d ( np2, np, nc, s_parent, s_child, ds_parent, ds_child, dir )
  120. !---------------------------------------------------------------------------------------------------
  121. integer, intent(in) :: np,nc,np2
  122. real, intent(in) :: s_parent, s_child
  123. real, intent(in) :: ds_parent, ds_child
  124. integer, intent(in) :: dir
  125. !
  126. integer :: i,coeffraf,locind_parent_left,inc,inc1,inc2
  127. integer, dimension(:,:), allocatable :: indparent_tmp
  128. real, dimension(:,:), allocatable :: coeffparent_tmp
  129. real :: ypos,globind_parent_left,globind_parent_right
  130. real :: invds, invds2, invds3
  131. real :: ypos2,diff
  132. !
  133. coeffraf = nint(ds_parent/ds_child)
  134. !
  135. ypos = s_child
  136. locind_parent_left = 1 + agrif_int((ypos - s_parent)/ds_parent)
  137. globind_parent_left = s_parent + (locind_parent_left - 1)*ds_parent
  138. globind_parent_right = globind_parent_left + ds_parent
  139. !
  140. invds = 1./ds_parent
  141. invds2 = ds_child/ds_parent
  142. invds3 = 0.5/real(coeffraf)
  143. ypos2 = ypos*invds
  144. globind_parent_right=globind_parent_right*invds
  145. !
  146. if (.not.allocated(indparent)) then
  147. allocate(indparent(nc*np2,3),coeffparent(nc*np2,3))
  148. else
  149. if ( size(indparent,1) < nc*np2 ) then
  150. allocate(coeffparent_tmp(size(indparent,1),size(indparent,2)))
  151. allocate( indparent_tmp(size(indparent,1),size(indparent,2)))
  152. coeffparent_tmp = coeffparent
  153. indparent_tmp = indparent
  154. deallocate(indparent,coeffparent)
  155. allocate(indparent(nc*np2,3),coeffparent(nc*np2,3))
  156. coeffparent(1:size(coeffparent_tmp,1),1:size(coeffparent_tmp,2)) = coeffparent_tmp
  157. indparent( 1:size(indparent_tmp, 1),1:size(indparent_tmp, 2)) = indparent_tmp
  158. deallocate(indparent_tmp,coeffparent_tmp)
  159. endif
  160. endif
  161. !
  162. do i = 1,nc-1
  163. !
  164. if (ypos2 > globind_parent_right) then
  165. locind_parent_left = locind_parent_left + 1
  166. globind_parent_right = globind_parent_right + 1.
  167. ypos2 = ypos*invds+(i-1)*invds2
  168. endif
  169. !
  170. diff = globind_parent_right - ypos2
  171. diff = invds3*nint(2*coeffraf*diff)
  172. indparent(i,dir) = locind_parent_left
  173. coeffparent(i,dir) = diff
  174. ypos2 = ypos2 + invds2
  175. !
  176. enddo
  177. !
  178. ypos = s_child + (nc-1)*ds_child
  179. locind_parent_left = 1 + agrif_int((ypos - s_parent)/ds_parent)
  180. if (locind_parent_left == np) then
  181. indparent(nc,dir) = locind_parent_left-1
  182. coeffparent(nc,dir) = 0.
  183. else
  184. globind_parent_left = s_parent + (locind_parent_left - 1)*ds_parent
  185. indparent(nc,dir) = locind_parent_left
  186. diff = (globind_parent_left + ds_parent - ypos) * invds
  187. diff = invds3*nint(2*coeffraf*diff)
  188. coeffparent(nc,dir) = diff
  189. endif
  190. do i=2, np2
  191. inc = i*nc
  192. inc1 = (i-1)*nc
  193. inc2 = (i-2)*nc
  194. !CDIR ALTCODE
  195. indparent(1+inc1:inc,dir) = indparent(1+inc2:inc1,dir)+np
  196. !CDIR ALTCODE
  197. coeffparent(1+inc1:inc,dir) =coeffparent(1:nc,dir)
  198. enddo
  199. !---------------------------------------------------------------------------------------------------
  200. end subroutine Linear1dPrecompute2d
  201. !===================================================================================================
  202. !
  203. !===================================================================================================
  204. ! subroutine Linear1dAfterCompute
  205. !
  206. !> Carries out a linear 1D interpolation on a child grid (vector y) from its parent grid (vector x)
  207. !! using precomputed coefficient and index.
  208. !---------------------------------------------------------------------------------------------------
  209. subroutine Linear1dAfterCompute ( x, y, np, nc, dir )
  210. !---------------------------------------------------------------------------------------------------
  211. integer, intent(in) :: np, nc
  212. real, dimension(np), intent(in) :: x
  213. real, dimension(nc), intent(out) :: y
  214. integer, intent(in) :: dir
  215. !
  216. integer :: i
  217. !
  218. !CDIR ALTCODE
  219. !CDIR NODEP
  220. do i = 1,nc
  221. y(i) = coeffparent(i,dir) * x(MAX(indparent(i,dir),1)) + &
  222. (1.-coeffparent(i,dir)) * x(indparent(i,dir)+1)
  223. enddo
  224. !---------------------------------------------------------------------------------------------------
  225. end subroutine Linear1dAfterCompute
  226. !===================================================================================================
  227. !
  228. !===================================================================================================
  229. ! subroutine Lagrange1d
  230. !
  231. !> Carries out a lagrange 1D interpolation on a child grid (vector y) from its parent grid
  232. !! (vector x).
  233. !---------------------------------------------------------------------------------------------------
  234. subroutine Lagrange1d ( x, y, np, nc, s_parent, s_child, ds_parent, ds_child )
  235. !---------------------------------------------------------------------------------------------------
  236. integer, intent(in) :: np, nc
  237. real, dimension(np), intent(in) :: x
  238. real, dimension(nc), intent(out) :: y
  239. real, intent(in) :: s_parent, s_child
  240. real, intent(in) :: ds_parent, ds_child
  241. !
  242. integer :: i, coeffraf, locind_parent_left
  243. real :: ypos,globind_parent_left
  244. real :: deltax, invdsparent
  245. real :: t2,t3,t4,t5,t6,t7,t8
  246. !
  247. if (np <= 2) then
  248. call Agrif_basicinterp_linear1D(x,y,np,nc,s_parent,s_child,ds_parent,ds_child)
  249. return
  250. endif
  251. !
  252. coeffraf = nint(ds_parent/ds_child)
  253. !
  254. if (coeffraf == 1) then
  255. locind_parent_left = 1 + nint((s_child - s_parent)/ds_parent)
  256. y(1:nc) = x(locind_parent_left:locind_parent_left+nc-1)
  257. return
  258. endif
  259. !
  260. invdsparent = 1./ds_parent
  261. ypos = s_child
  262. !
  263. do i = 1,nc
  264. !
  265. locind_parent_left = 1 + agrif_int((ypos - s_parent)/ds_parent)
  266. globind_parent_left = s_parent + (locind_parent_left - 1)*ds_parent
  267. deltax = invdsparent*(ypos-globind_parent_left)
  268. deltax = nint(coeffraf*deltax)/real(coeffraf)
  269. ypos = ypos + ds_child
  270. if (abs(deltax) <= 0.0001) then
  271. y(i)=x(locind_parent_left)
  272. cycle
  273. endif
  274. !
  275. t2 = deltax - 2.
  276. t3 = deltax - 1.
  277. t4 = deltax + 1.
  278. t5 = -(1./6.)*deltax*t2*t3
  279. t6 = 0.5*t2*t3*t4
  280. t7 = -0.5*deltax*t2*t4
  281. t8 = (1./6.)*deltax*t3*t4
  282. y(i) = t5*x(locind_parent_left-1) + t6*x(locind_parent_left) &
  283. +t7*x(locind_parent_left+1) + t8*x(locind_parent_left+2)
  284. !
  285. enddo
  286. !---------------------------------------------------------------------------------------------------
  287. end subroutine Lagrange1d
  288. !===================================================================================================
  289. !
  290. !===================================================================================================
  291. ! subroutine Constant1d
  292. !
  293. !> Carries out a constant 1D interpolation on a child grid (vector y) from its parent grid (vector x).
  294. !---------------------------------------------------------------------------------------------------
  295. subroutine Constant1d ( x, y, np, nc, s_parent, s_child, ds_parent, ds_child )
  296. !---------------------------------------------------------------------------------------------------
  297. integer, intent(in) :: np, nc
  298. real, dimension(np), intent(in) :: x
  299. real, dimension(nc), intent(out) :: y
  300. real, intent(in) :: s_parent, s_child
  301. real, intent(in) :: ds_parent, ds_child
  302. !
  303. integer :: i, coeffraf, locind_parent
  304. real :: ypos
  305. !
  306. coeffraf = nint(ds_parent/ds_child)
  307. !
  308. if (coeffraf == 1) then
  309. locind_parent = 1 + nint((s_child - s_parent)/ds_parent)
  310. y(1:nc) = x(locind_parent:locind_parent+nc-1)
  311. return
  312. endif
  313. !
  314. ypos = s_child
  315. !
  316. do i = 1,nc
  317. !
  318. locind_parent = 1 + nint((ypos - s_parent)/ds_parent)
  319. y(i) = x(locind_parent)
  320. ypos = ypos + ds_child
  321. !
  322. enddo
  323. !---------------------------------------------------------------------------------------------------
  324. end subroutine Constant1d
  325. !===================================================================================================
  326. !
  327. !===================================================================================================
  328. ! subroutine Linear1dConserv
  329. !
  330. !> Carries out a conservative linear 1D interpolation on a child grid (vector y) from its parent
  331. !! grid (vector x).
  332. !---------------------------------------------------------------------------------------------------
  333. subroutine Linear1dConserv ( x, y, np, nc, s_parent, s_child, ds_parent, ds_child )
  334. !---------------------------------------------------------------------------------------------------
  335. integer, intent(in) :: np, nc
  336. real, dimension(np), intent(in) :: x
  337. real, dimension(nc), intent(out) :: y
  338. real, intent(in) :: s_parent, s_child
  339. real, intent(in) :: ds_parent, ds_child
  340. !
  341. real, dimension(:), allocatable :: ytemp
  342. integer :: i,coeffraf,locind_parent_left,locind_parent_last
  343. real :: ypos,xdiffmod,xpmin,xpmax,slope
  344. integer :: i1,i2,ii
  345. integer :: diffmod
  346. !
  347. coeffraf = nint(ds_parent/ds_child)
  348. !
  349. if (coeffraf == 1) then
  350. locind_parent_left = 1 + nint((s_child - s_parent)/ds_parent)
  351. y(1:nc) = x(locind_parent_left:locind_parent_left+nc-1)
  352. return
  353. endif
  354. !
  355. diffmod = 0
  356. if (mod(coeffraf,2) == 0) diffmod = 1
  357. xdiffmod = real(diffmod)/2.
  358. allocate(ytemp(-2*coeffraf:nc+2*coeffraf))
  359. !
  360. ypos = s_child
  361. !
  362. locind_parent_left = 1 + agrif_int((ypos - s_parent)/ds_parent)
  363. locind_parent_last = 1 + agrif_ceiling((ypos +(nc - 1) *ds_child - s_parent)/ds_parent)
  364. xpmin = s_parent + (locind_parent_left-1)*ds_parent
  365. xpmax = s_parent + (locind_parent_last-1)*ds_parent
  366. i1 = 1+agrif_int((xpmin-s_child)/ds_child)
  367. i2 = 1+agrif_int((xpmax-s_child)/ds_child)
  368. i = i1
  369. if (locind_parent_left == 1) then
  370. slope = (x(locind_parent_left+1)-x(locind_parent_left))/(coeffraf)
  371. else
  372. slope = (x(locind_parent_left+1)-x(locind_parent_left-1))/(2.*coeffraf)
  373. endif
  374. do ii = i-coeffraf/2+diffmod,i+coeffraf/2
  375. ytemp(ii) = x(locind_parent_left)+(ii-i-xdiffmod/2.)*slope
  376. enddo
  377. locind_parent_left = locind_parent_left + 1
  378. do i = i1+coeffraf, i2-coeffraf,coeffraf
  379. slope = (x(locind_parent_left+1)-x(locind_parent_left-1))/(2.*coeffraf)
  380. do ii = i-coeffraf/2+diffmod,i+coeffraf/2
  381. ytemp(ii) = x(locind_parent_left)+(ii-i-xdiffmod/2.)*slope
  382. enddo
  383. locind_parent_left = locind_parent_left + 1
  384. enddo
  385. i = i2
  386. if (locind_parent_left == np) then
  387. slope = (x(locind_parent_left)-x(locind_parent_left-1))/(coeffraf)
  388. else
  389. slope = (x(locind_parent_left+1)-x(locind_parent_left-1))/(2.*coeffraf)
  390. endif
  391. do ii = i-coeffraf/2+diffmod,nc
  392. ytemp(ii) = x(locind_parent_left)+(ii-i-xdiffmod/2.)*slope
  393. enddo
  394. !
  395. y(1:nc)=ytemp(1:nc)
  396. !
  397. deallocate(ytemp)
  398. !---------------------------------------------------------------------------------------------------
  399. end subroutine Linear1dConserv
  400. !===================================================================================================
  401. !
  402. !===================================================================================================
  403. ! subroutine Linear1dConservLim
  404. !
  405. !> Carries out a limited conservative linear 1D interpolation on a child grid (vector y) from
  406. !! its parent grid (vector x).
  407. !---------------------------------------------------------------------------------------------------
  408. subroutine Linear1dConservLim ( x, y, np, nc, s_parent, s_child, ds_parent, ds_child )
  409. !---------------------------------------------------------------------------------------------------
  410. integer, intent(in) :: np, nc
  411. real, dimension(np), intent(in) :: x
  412. real, dimension(nc), intent(out) :: y
  413. real, intent(in) :: s_parent, s_child
  414. real, intent(in) :: ds_parent, ds_child
  415. !
  416. real, dimension(:), allocatable :: ytemp
  417. integer :: i,coeffraf,locind_parent_left,locind_parent_last
  418. real :: ypos,xdiffmod,xpmin,xpmax,slope
  419. integer :: i1,i2,ii
  420. integer :: diffmod
  421. !
  422. coeffraf = nint(ds_parent/ds_child)
  423. !
  424. if (coeffraf == 1) then
  425. locind_parent_left = 1 + nint((s_child - s_parent)/ds_parent)
  426. y(1:nc) = x(locind_parent_left:locind_parent_left+nc-1)
  427. return
  428. endif
  429. !
  430. if (coeffraf /= 3) then
  431. print *,'Linear1dConservLim not ready for refinement ratio = ', coeffraf
  432. stop
  433. endif
  434. !
  435. diffmod = 0
  436. if (mod(coeffraf,2) == 0) diffmod = 1
  437. xdiffmod = real(diffmod)/2.
  438. allocate(ytemp(-2*coeffraf:nc+2*coeffraf))
  439. !
  440. ypos = s_child
  441. !
  442. locind_parent_left = 1 + agrif_int((ypos - s_parent)/ds_parent)
  443. locind_parent_last = 1 + agrif_ceiling((ypos +(nc - 1) *ds_child - s_parent)/ds_parent)
  444. xpmin = s_parent + (locind_parent_left-1)*ds_parent
  445. xpmax = s_parent + (locind_parent_last-1)*ds_parent
  446. i1 = 1+agrif_int((xpmin-s_child)/ds_child)
  447. i2 = 1+agrif_int((xpmax-s_child)/ds_child)
  448. i = i1
  449. if (locind_parent_left == 1) then
  450. slope=0.
  451. else
  452. slope = Agrif_limiter_vanleer(x(locind_parent_left-1:locind_parent_left+1))
  453. slope = slope / coeffraf
  454. endif
  455. do ii = i-coeffraf/2+diffmod,i+coeffraf/2
  456. ytemp(ii) = x(locind_parent_left)+(ii-i-xdiffmod/2.)*slope
  457. enddo
  458. locind_parent_left = locind_parent_left + 1
  459. do i = i1+coeffraf, i2-coeffraf,coeffraf
  460. slope = Agrif_limiter_vanleer(x(locind_parent_left-1:locind_parent_left+1))
  461. slope = slope / coeffraf
  462. do ii=i-coeffraf/2+diffmod,i+coeffraf/2
  463. ytemp(ii) = x(locind_parent_left)+(ii-i-xdiffmod/2.)*slope
  464. enddo
  465. locind_parent_left = locind_parent_left + 1
  466. enddo
  467. i = i2
  468. if (locind_parent_left == np) then
  469. slope=0.
  470. else
  471. slope = Agrif_limiter_vanleer(x(locind_parent_left-1:locind_parent_left+1))
  472. slope = slope / coeffraf
  473. endif
  474. do ii=i-coeffraf/2+diffmod,nc
  475. ytemp(ii) = x(locind_parent_left)+(ii-i-xdiffmod/2.)*slope
  476. enddo
  477. !
  478. y(1:nc) = ytemp(1:nc)
  479. !
  480. deallocate(ytemp)
  481. !---------------------------------------------------------------------------------------------------
  482. end subroutine Linear1dConservLim
  483. !===================================================================================================
  484. !
  485. !===================================================================================================
  486. ! subroutine PPM1d
  487. !
  488. !> Carries out a 1D interpolation and apply monotonicity constraints using piecewise parabolic
  489. !! method (PPM) on a child grid (vector y) from its parent grid (vector x).
  490. !---------------------------------------------------------------------------------------------------
  491. subroutine PPM1d ( x, y, np, nc, s_parent, s_child, ds_parent, ds_child )
  492. !---------------------------------------------------------------------------------------------------
  493. integer, intent(in) :: np, nc
  494. real, dimension(np), intent(in) :: x
  495. real, dimension(nc), intent(out) :: y
  496. real, intent(in) :: s_parent, s_child
  497. real, intent(in) :: ds_parent, ds_child
  498. !
  499. integer :: i,coeffraf,locind_parent_left,locind_parent_last
  500. integer :: iparent,ipos,pos,nmin,nmax
  501. real :: ypos
  502. integer :: i1,jj
  503. real :: xpmin,a
  504. !
  505. real, dimension(np) :: xl,delta,a6,slope
  506. integer :: diffmod
  507. real :: invcoeffraf
  508. !
  509. coeffraf = nint(ds_parent/ds_child)
  510. !
  511. if (coeffraf == 1) then
  512. locind_parent_left = 1 + nint((s_child - s_parent)/ds_parent)
  513. !CDIR ALTCODE
  514. !CDIR SHORTLOOP
  515. y(1:nc) = x(locind_parent_left:locind_parent_left+nc-1)
  516. return
  517. endif
  518. !
  519. invcoeffraf = ds_child/ds_parent
  520. !
  521. if( .not. allocated(tabtest4) ) then
  522. allocate(tabtest4(-2*coeffraf:nc+2*coeffraf))
  523. else
  524. if (size(tabtest4) < nc+4*coeffraf+1) then
  525. deallocate( tabtest4 )
  526. allocate(tabtest4(-2*coeffraf:nc+2*coeffraf))
  527. endif
  528. endif
  529. !
  530. ypos = s_child
  531. !
  532. locind_parent_left = 1 + agrif_int((ypos - s_parent)/ds_parent)
  533. locind_parent_last = 1 + agrif_ceiling((ypos +(nc - 1)*ds_child - s_parent)/ds_parent)
  534. !
  535. xpmin = s_parent + (locind_parent_left-1)*ds_parent
  536. i1 = 1+agrif_int((xpmin-s_child)/ds_child)
  537. !
  538. !CDIR NOVECTOR
  539. do i=1,coeffraf
  540. tabdiff2(i) = (real(i)-0.5)*invcoeffraf
  541. enddo
  542. !
  543. a = invcoeffraf**2
  544. tabdiff3(1) = (1./3.)*a
  545. a = 2.*a
  546. !CDIR NOVECTOR
  547. do i=2,coeffraf
  548. tabdiff3(i) = tabdiff3(i-1)+(real(i)-1)*a
  549. enddo
  550. !
  551. if ( locind_parent_last+2 <= np ) then
  552. nmax = locind_parent_last+2
  553. else if ( locind_parent_last+1 <= np ) then
  554. nmax = locind_parent_last+1
  555. else
  556. nmax = locind_parent_last
  557. endif
  558. !
  559. if (locind_parent_left-1 >= 1) then
  560. nmin = locind_parent_left-1
  561. else
  562. nmin = locind_parent_left
  563. endif
  564. !
  565. !CDIR ALTCODE
  566. !CDIR SHORTLOOP
  567. do i = nmin,nmax
  568. slope(i) = x(i) - x(i-1)
  569. enddo
  570. !
  571. !CDIR ALTCODE
  572. !CDIR SHORTLOOP
  573. do i = nmin+1,nmax-1
  574. xl(i)= 0.5*(x(i-1)+x(i))-0.08333333333333*(slope(i+1)-slope(i-1))
  575. enddo
  576. !
  577. ! apply parabolic monotonicity
  578. !CDIR ALTCODE
  579. !CDIR SHORTLOOP
  580. do i = locind_parent_left,locind_parent_last
  581. delta(i) = xl(i+1) - xl(i)
  582. a6(i) = 6.*x(i)-3.*(xl(i) +xl(i+1))
  583. enddo
  584. !
  585. diffmod = 0
  586. if (mod(coeffraf,2) == 0) diffmod = 1
  587. !
  588. ipos = i1
  589. !
  590. do iparent = locind_parent_left,locind_parent_last
  591. pos=1
  592. !CDIR ALTCODE
  593. !CDIR SHORTLOOP
  594. do jj = ipos-coeffraf/2+diffmod,ipos+coeffraf/2
  595. !
  596. tabtest4(jj) = xl(iparent) + tabdiff2(pos) * (delta(iparent)+a6(iparent)) &
  597. - tabdiff3(pos) * a6(iparent)
  598. pos = pos+1
  599. enddo
  600. ipos = ipos + coeffraf
  601. enddo
  602. !
  603. !CDIR ALTCODE
  604. !CDIR SHORTLOOP
  605. y(1:nc) = tabtest4(1:nc)
  606. !---------------------------------------------------------------------------------------------------
  607. end subroutine PPM1d
  608. !===================================================================================================
  609. !
  610. !===================================================================================================
  611. ! subroutine PPM1dPrecompute2d
  612. !
  613. !> Computes 2D coefficients and index for a 1D interpolation using piecewise parabolic method
  614. !---------------------------------------------------------------------------------------------------
  615. subroutine PPM1dPrecompute2d ( np2, np, nc, s_parent, s_child, ds_parent, ds_child, dir )
  616. !---------------------------------------------------------------------------------------------------
  617. integer, intent(in) :: np2, np, nc
  618. real, intent(in) :: s_parent, s_child
  619. real, intent(in) :: ds_parent, ds_child
  620. integer, intent(in) :: dir
  621. !
  622. integer, dimension(:,:), allocatable :: indparent_tmp
  623. integer, dimension(:,:), allocatable :: indchild_tmp
  624. integer :: i,coeffraf,locind_parent_left,locind_parent_last
  625. integer :: iparent,ipos,pos
  626. real :: ypos
  627. integer :: i1,jj
  628. real :: xpmin,a
  629. !
  630. integer :: diffmod
  631. real :: invcoeffraf
  632. !
  633. coeffraf = nint(ds_parent/ds_child)
  634. !
  635. invcoeffraf = ds_child/ds_parent
  636. !
  637. if (.not.allocated(indparentppm)) then
  638. allocate(indparentppm(np2*nc,3),indchildppm(np2*nc,3))
  639. else
  640. if (size(indparentppm,1) < np2*nc) then
  641. allocate( &
  642. indparent_tmp(size(indparentppm,1),size(indparentppm,2)), &
  643. indchild_tmp( size(indparentppm,1),size(indparentppm,2)))
  644. indparent_tmp = indparentppm
  645. indchild_tmp = indchildppm
  646. deallocate(indparentppm,indchildppm)
  647. allocate(indparentppm(np2*nc,3),indchildppm(np2*nc,3))
  648. indparentppm(1:size(indparent_tmp,1),1:size(indparent_tmp,2)) = indparent_tmp
  649. indchildppm( 1:size(indparent_tmp,1),1:size(indparent_tmp,2)) = indchild_tmp
  650. deallocate(indparent_tmp,indchild_tmp)
  651. endif
  652. endif
  653. if (.not.allocated(indparentppm_1d)) then
  654. allocate(indparentppm_1d(-2*coeffraf:nc+2*coeffraf), &
  655. indchildppm_1d( -2*coeffraf:nc+2*coeffraf))
  656. else
  657. if (size(indparentppm_1d) < nc+4*coeffraf+1) then
  658. deallocate(indparentppm_1d,indchildppm_1d)
  659. allocate(indparentppm_1d(-2*coeffraf:nc+2*coeffraf),&
  660. indchildppm_1d( -2*coeffraf:nc+2*coeffraf))
  661. endif
  662. endif
  663. !
  664. ypos = s_child
  665. !
  666. locind_parent_left = 1 + agrif_int((ypos - s_parent)/ds_parent)
  667. locind_parent_last = 1 + agrif_ceiling((ypos +(nc - 1)*ds_child - s_parent)/ds_parent)
  668. !
  669. xpmin = s_parent + (locind_parent_left-1)*ds_parent
  670. i1 = 1+agrif_int((xpmin-s_child)/ds_child)
  671. !
  672. do i = 1,coeffraf
  673. tabdiff2(i)=(real(i)-0.5)*invcoeffraf
  674. enddo
  675. !
  676. a = invcoeffraf**2
  677. tabdiff3(1) = (1./3.)*a
  678. a = 2.*a
  679. !CDIR ALTCODE
  680. do i = 2,coeffraf
  681. tabdiff3(i) = tabdiff3(i-1)+(real(i)-1)*a
  682. enddo
  683. !CDIR ALTCODE
  684. do i = 1,coeffraf
  685. tabppm(1,i,dir) = 0.08333333333333*(-1.+4*tabdiff2(i)-3*tabdiff3(i))
  686. tabppm(2,i,dir) = 0.08333333333333*(7.-26.*tabdiff2(i)+18.*tabdiff3(i))
  687. tabppm(3,i,dir) = 0.08333333333333*(7.+30*tabdiff2(i)-30*tabdiff3(i))
  688. tabppm(4,i,dir) = 0.08333333333333*(-1.-10.*tabdiff2(i)+18.*tabdiff3(i))
  689. tabppm(5,i,dir) = 0.08333333333333*(2*tabdiff2(i)-3*tabdiff3(i))
  690. enddo
  691. !
  692. diffmod = 0
  693. if (mod(coeffraf,2) == 0) diffmod = 1
  694. !
  695. ipos = i1
  696. !
  697. do iparent = locind_parent_left,locind_parent_last
  698. pos=1
  699. !CDIR ALTCODE
  700. do jj = ipos - coeffraf/2+diffmod,ipos + coeffraf/2
  701. indparentppm_1d(jj) = iparent-2
  702. indchildppm_1d(jj) = pos
  703. pos = pos+1
  704. enddo
  705. ipos = ipos + coeffraf
  706. enddo
  707. !
  708. do i = 1,np2
  709. indparentppm(1+(i-1)*nc:i*nc,dir) = indparentppm_1d(1:nc) + (i-1)*np
  710. indchildppm (1+(i-1)*nc:i*nc,dir) = indchildppm_1d (1:nc)
  711. enddo
  712. !---------------------------------------------------------------------------------------------------
  713. end subroutine PPM1dPrecompute2d
  714. !===================================================================================================
  715. !
  716. !===================================================================================================
  717. !subroutine PPM1dPrecompute(np,nc,&
  718. ! s_parent,s_child,ds_parent,ds_child)
  719. !!
  720. !!CC Description:
  721. !!CC subroutine to compute coefficient and index for a 1D interpolation
  722. !!CC using piecewise parabolic method
  723. !!C Method:
  724. !!
  725. !! Declarations:
  726. !!
  727. ! Implicit none
  728. !!
  729. !! Arguments
  730. ! Integer :: np,nc
  731. !! Real, Dimension(:),Allocatable :: ytemp
  732. ! Real :: s_parent,s_child,ds_parent,ds_child
  733. !!
  734. !! Local scalars
  735. ! Integer :: i,coeffraf,locind_parent_left,locind_parent_last
  736. ! Integer :: iparent,ipos,pos,nmin,nmax
  737. ! Real :: ypos
  738. ! integer :: i1,jj
  739. ! Real :: xpmin,a
  740. !!
  741. ! Real :: xrmin,xrmax,am3,s2,s1
  742. ! Real, Dimension(np) :: xl,delta,a6,slope
  743. !! Real, Dimension(:),Allocatable :: diff,diff2,diff3
  744. ! INTEGER :: diffmod
  745. ! REAL :: invcoeffraf
  746. !!
  747. ! coeffraf = nint(ds_parent/ds_child)
  748. !!
  749. ! If (coeffraf == 1) Then
  750. ! return
  751. ! End If
  752. ! invcoeffraf = ds_child/ds_parent
  753. !!
  754. !
  755. ! if (.not.allocated(indparentppm)) then
  756. ! allocate(indparentppm(-2*coeffraf:nc+2*coeffraf,1),&
  757. ! indchildppm(-2*coeffraf:nc+2*coeffraf,1))
  758. ! else
  759. ! if (size(indparentppm,1)<nc+4*coeffraf+1) then
  760. ! deallocate(indparentppm,indchildppm)
  761. ! allocate(indparentppm(-2*coeffraf:nc+2*coeffraf,1),&
  762. ! indchildppm(-2*coeffraf:nc+2*coeffraf,1))
  763. ! endif
  764. ! endif
  765. !
  766. ! ypos = s_child
  767. !!
  768. ! locind_parent_left = 1 + agrif_int((ypos - s_parent)/ds_parent)
  769. ! locind_parent_last = 1 +&
  770. ! agrif_ceiling((ypos +(nc - 1)&
  771. ! *ds_child - s_parent)/ds_parent)
  772. !!
  773. ! xpmin = s_parent + (locind_parent_left-1)*ds_parent
  774. ! i1 = 1+agrif_int((xpmin-s_child)/ds_child)
  775. !!
  776. !!
  777. !
  778. ! Do i=1,coeffraf
  779. ! tabdiff2(i)=(real(i)-0.5)*invcoeffraf
  780. ! EndDo
  781. !
  782. ! a = invcoeffraf**2
  783. ! tabdiff3(1) = (1./3.)*a
  784. ! a=2.*a
  785. !!CDIR ALTCODE
  786. !!!!CDIR SHORTLOOP
  787. ! Do i=2,coeffraf
  788. ! tabdiff3(i) = tabdiff3(i-1)+(real(i)-1)*a
  789. ! EndDo
  790. !
  791. !!CDIR ALTCODE
  792. !!!!CDIR SHORTLOOP
  793. ! Do i=1,coeffraf
  794. ! tabppm(1,i,1) = 0.08333333333333*(-1.+4*tabdiff2(i)-3*tabdiff3(i))
  795. ! tabppm(2,i,1) = 0.08333333333333*&
  796. ! (7.-26.*tabdiff2(i)+18.*tabdiff3(i))
  797. ! tabppm(3,i,1) =0.08333333333333*(7.+30*tabdiff2(i)-30*tabdiff3(i))
  798. ! tabppm(4,i,1) = 0.08333333333333*&
  799. ! (-1.-10.*tabdiff2(i)+18.*tabdiff3(i))
  800. ! tabppm(5,i,1) = 0.08333333333333*(2*tabdiff2(i)-3*tabdiff3(i))
  801. ! End Do
  802. !!
  803. !!
  804. ! diffmod = 0
  805. ! IF (mod(coeffraf,2) == 0) diffmod = 1
  806. !!
  807. ! ipos = i1
  808. !!
  809. ! Do iparent = locind_parent_left,locind_parent_last
  810. ! pos=1
  811. !!CDIR ALTCODE
  812. !!CDIR SHORTLOOP
  813. ! Do jj = ipos - coeffraf/2+diffmod,ipos + coeffraf/2
  814. ! indparentppm(jj,1) = iparent-2
  815. ! indchildppm(jj,1) = pos
  816. ! pos = pos+1
  817. ! End do
  818. ! ipos = ipos + coeffraf
  819. !!
  820. ! End do
  821. !
  822. ! Return
  823. ! End subroutine ppm1dprecompute
  824. !===================================================================================================
  825. !
  826. !===================================================================================================
  827. ! subroutine PPM1dAfterCompute
  828. !
  829. ! Carries out a 1D interpolation and apply monotonicity constraints using piecewise parabolic
  830. ! method (PPM) on a child grid (vector y) from its parent grid (vector x).
  831. ! Use precomputed coefficient and index.
  832. !---------------------------------------------------------------------------------------------------
  833. subroutine PPM1dAfterCompute ( x, y, np, nc, dir )
  834. !---------------------------------------------------------------------------------------------------
  835. real, dimension(np), intent(in) :: x
  836. real, dimension(nc), intent(out) :: y
  837. integer, intent(in) :: np, nc
  838. integer, intent(in) :: dir
  839. !
  840. integer :: i
  841. !
  842. do i = 1,nc
  843. y(i) = tabppm(1,indchildppm(i,dir),dir) * x(indparentppm(i,dir) ) + &
  844. tabppm(2,indchildppm(i,dir),dir) * x(indparentppm(i,dir)+1) + &
  845. tabppm(3,indchildppm(i,dir),dir) * x(indparentppm(i,dir)+2) + &
  846. tabppm(4,indchildppm(i,dir),dir) * x(indparentppm(i,dir)+3) + &
  847. tabppm(5,indchildppm(i,dir),dir) * x(indparentppm(i,dir)+4)
  848. enddo
  849. !---------------------------------------------------------------------------------------------------
  850. end subroutine PPM1dAfterCompute
  851. !===================================================================================================
  852. !
  853. !===================================================================================================
  854. ! subroutine weno1d
  855. !
  856. ! Carries out a 1D interpolation and apply monotonicity constraints
  857. ! using WENO method on a child grid (vector y) from its parent grid (vector x).
  858. !---------------------------------------------------------------------------------------------------
  859. !subroutine weno1dnew ( x, y, np, nc, s_parent, s_child, ds_parent, ds_child )
  860. !---------------------------------------------------------------------------------------------------
  861. !
  862. !CC Description:
  863. !CC subroutine to do a 1D interpolation and apply monotonicity constraints
  864. !CC using piecewise parabolic method
  865. !CC on a child grid (vector y) from its parent grid (vector x).
  866. !C Method:
  867. !
  868. ! Declarations:
  869. !
  870. ! Implicit none
  871. !
  872. ! Arguments
  873. ! Integer :: np,nc
  874. ! Real, Dimension(np) :: x
  875. ! Real, Dimension(nc) :: y
  876. ! Real, Dimension(:),Allocatable :: ytemp
  877. ! Real :: s_parent,s_child,ds_parent,ds_child
  878. !
  879. ! Local scalars
  880. ! Integer :: i,coeffraf,locind_parent_left,locind_parent_last
  881. ! Integer :: iparent,ipos,pos,nmin,nmax
  882. ! Real :: ypos
  883. ! integer :: i1,jj
  884. ! Real :: xpmin,cavg,a,b
  885. !
  886. ! Real :: xrmin,xrmax,am3,s2,s1
  887. ! Real, Dimension(np) :: xr,xl,delta,a6,slope,slope2,smooth
  888. ! Real, Dimension(:),Allocatable :: diff,diff2,diff3
  889. ! INTEGER :: diffmod
  890. ! REAL :: invcoeffraf
  891. ! integer :: s,l,k
  892. ! integer :: etan, etap
  893. ! real :: delta0, delta1, delta2
  894. ! real :: epsilon
  895. ! parameter (epsilon = 1.D-8)
  896. ! real, dimension(:,:), allocatable :: ak, ck
  897. !
  898. ! coeffraf = nint(ds_parent/ds_child)
  899. !
  900. ! If (coeffraf == 1) Then
  901. ! locind_parent_left = 1 + nint((s_child - s_parent)/ds_parent)
  902. ! y(1:nc) = x(locind_parent_left:locind_parent_left+nc-1)
  903. ! return
  904. ! End If
  905. ! invcoeffraf = ds_child/ds_parent
  906. ! Allocate(ak(0:1,coeffraf))
  907. ! Allocate(ck(0:1,coeffraf))
  908. !
  909. !
  910. ! Allocate(ytemp(-2*coeffraf:nc+2*coeffraf))
  911. ! ypos = s_child
  912. !
  913. ! locind_parent_left = 1 + agrif_int((ypos - s_parent)/ds_parent)
  914. ! locind_parent_last = 1 +&
  915. ! agrif_ceiling((ypos +(nc - 1)&
  916. ! *ds_child - s_parent)/ds_parent)
  917. !
  918. ! xpmin = s_parent + (locind_parent_left-1)*ds_parent
  919. ! i1 = 1+agrif_int((xpmin-s_child)/ds_child)
  920. !
  921. ! Allocate( diff(coeffraf),diff2(coeffraf),diff3(coeffraf) )
  922. !
  923. ! diff(1)=0.5*invcoeffraf
  924. ! do i=2,coeffraf
  925. ! diff(i) = diff(i-1)+invcoeffraf
  926. ! enddo
  927. !
  928. ! ak = 0.
  929. ! ck = 0.
  930. !
  931. ! do i=1,coeffraf
  932. ! do k=0,1
  933. ! do s=0,2
  934. ! do l=0,2
  935. ! if (l /= s) then
  936. ! ak(k,i) = ak(k,i)+(diff(i)-(k-l+1.))
  937. ! endif
  938. ! enddo
  939. ! enddo
  940. ! enddo
  941. !
  942. ! etap = 0
  943. ! etan = 0
  944. ! do k=0,1
  945. ! if (ak(k,i) > 0) then
  946. ! etap = etap+1
  947. ! else if (ak(k,i) < 0) then
  948. ! etan = etan + 1
  949. ! endif
  950. ! enddo
  951. !
  952. ! do k=0,1
  953. ! if (ak(k,i) == 0) then
  954. ! Ck(k,i) = 1.
  955. ! else if (ak(k,i) > 0) then
  956. ! Ck(k,i) = 1./(etap * ak(k,i))
  957. ! else
  958. ! Ck(k,i) = -1./(etan * ak(k,i))
  959. ! endif
  960. ! enddo
  961. ! enddo
  962. !
  963. !
  964. ! a = 0.
  965. ! b = invcoeffraf
  966. ! Do i=1,coeffraf
  967. ! diff2(i) = 0.5*(b*b - a*a)
  968. ! diff3(i) = (1./3.)*(b*b*b - a*a*a)
  969. ! a = a + invcoeffraf
  970. ! b = b + invcoeffraf
  971. ! End do
  972. !
  973. ! if( locind_parent_last+2 <= np ) then
  974. ! nmax = locind_parent_last+2
  975. ! elseif( locind_parent_last+1 <= np ) then
  976. ! nmax = locind_parent_last+1
  977. ! else
  978. ! nmax = locind_parent_last
  979. ! endif
  980. !
  981. ! if(locind_parent_left-2 >= 1) then
  982. ! nmin = locind_parent_left-2
  983. ! elseif(locind_parent_left-1 >= 1) then
  984. ! nmin = locind_parent_left-1
  985. ! else
  986. ! nmin = locind_parent_left
  987. ! endif
  988. !
  989. ! Do i = nmin+1,nmax
  990. ! slope(i) = (x(i) - x(i-1))
  991. ! Enddo
  992. ! DO i=nmin+2,nmax
  993. ! smooth(i) = 0.5*(slope(i)**2+slope(i-1)**2)&
  994. ! +(slope(i)-slope(i-1))**2
  995. ! enddo
  996. !
  997. ! diffmod = 0
  998. ! IF (mod(coeffraf,2) == 0) diffmod = 1
  999. !
  1000. ! ipos = i1
  1001. !
  1002. ! Do iparent = locind_parent_left,locind_parent_last
  1003. ! pos=1
  1004. !
  1005. ! delta0=1./(epsilon+smooth(iparent ))**3
  1006. ! delta1=1./(epsilon+smooth(iparent+1))**3
  1007. ! delta2=1./(epsilon+smooth(iparent+2))**3
  1008. !
  1009. ! Do jj = ipos - coeffraf/2+diffmod,ipos + coeffraf/2
  1010. !
  1011. ! pos = pos+1
  1012. ! End do
  1013. ! ipos = ipos + coeffraf
  1014. !
  1015. ! End do
  1016. !
  1017. !
  1018. ! y(1:nc)=ytemp(1:nc)
  1019. ! deallocate(ytemp)
  1020. ! deallocate(diff, diff2, diff3)
  1021. !
  1022. ! deallocate(ak,ck)
  1023. !
  1024. ! Return
  1025. ! End subroutine weno1dnew
  1026. !===================================================================================================
  1027. !
  1028. !===================================================================================================
  1029. ! subroutine WENO1d
  1030. !
  1031. !> Carries out a a 1D interpolation using WENO method on a child grid (vector y) from its parent
  1032. !! grid (vector x).
  1033. !---------------------------------------------------------------------------------------------------
  1034. subroutine WENO1d ( x, y, np, nc, s_parent, s_child, ds_parent, ds_child )
  1035. !---------------------------------------------------------------------------------------------------
  1036. integer, intent(in) :: np, nc
  1037. real, dimension(np), intent(in) :: x
  1038. real, dimension(nc), intent(out) :: y
  1039. real, intent(in) :: s_parent, s_child
  1040. real, intent(in) :: ds_parent, ds_child
  1041. !
  1042. real, dimension(:), allocatable :: ytemp
  1043. integer :: i,coeffraf,locind_parent_left,locind_parent_last
  1044. integer :: iparent,ipos,pos,nmin,nmax
  1045. real :: ypos
  1046. integer :: i1,jj
  1047. real :: xpmin
  1048. !
  1049. real, dimension(np) :: slope
  1050. real, dimension(:), allocatable :: diff
  1051. integer :: diffmod
  1052. real :: invcoeffraf
  1053. real :: delta0, delta1, sumdelta
  1054. real, parameter :: epsilon = 1.d-8
  1055. !
  1056. coeffraf = nint(ds_parent/ds_child)
  1057. !
  1058. if (coeffraf == 1) then
  1059. locind_parent_left = 1 + nint((s_child - s_parent)/ds_parent)
  1060. y(1:nc) = x(locind_parent_left:locind_parent_left+nc-1)
  1061. return
  1062. endif
  1063. !
  1064. invcoeffraf = ds_child/ds_parent
  1065. !
  1066. allocate(ytemp(-2*coeffraf:nc+2*coeffraf))
  1067. ypos = s_child
  1068. !
  1069. locind_parent_left = 1 + agrif_int((ypos - s_parent)/ds_parent)
  1070. locind_parent_last = 1 + agrif_ceiling((ypos +(nc - 1) *ds_child - s_parent)/ds_parent)
  1071. !
  1072. xpmin = s_parent + (locind_parent_left-1)*ds_parent
  1073. i1 = 1+agrif_int((xpmin-s_child)/ds_child)
  1074. !
  1075. allocate(diff(coeffraf))
  1076. diff(1) = 0.5*invcoeffraf
  1077. do i = 2,coeffraf
  1078. diff(i) = diff(i-1)+invcoeffraf
  1079. enddo
  1080. !
  1081. if ( locind_parent_last+2 <= np ) then
  1082. nmax = locind_parent_last+2
  1083. else if ( locind_parent_last+1 <= np ) then
  1084. nmax = locind_parent_last+1
  1085. else
  1086. nmax = locind_parent_last
  1087. endif
  1088. !
  1089. if(locind_parent_left-1 >= 1) then
  1090. nmin = locind_parent_left-1
  1091. else
  1092. nmin = locind_parent_left
  1093. endif
  1094. !
  1095. do i = nmin+1,nmax
  1096. slope(i) = x(i) - x(i-1)
  1097. enddo
  1098. !
  1099. diffmod = 0
  1100. if (mod(coeffraf,2) == 0) diffmod = 1
  1101. !
  1102. ipos = i1
  1103. !
  1104. do iparent = locind_parent_left,locind_parent_last
  1105. pos=1
  1106. delta0 = 1./(epsilon+slope(iparent )**2)**2
  1107. delta1 = 1./(epsilon+slope(iparent+1)**2)**2
  1108. sumdelta = 1./(delta0+delta1)
  1109. do jj = ipos - coeffraf/2+diffmod,ipos + coeffraf/2
  1110. ytemp(jj) = x(iparent)+(diff(pos)-0.5)*( delta0*slope(iparent) + &
  1111. delta1*slope(iparent+1))*sumdelta
  1112. pos = pos+1
  1113. enddo
  1114. ipos = ipos + coeffraf
  1115. enddo
  1116. !
  1117. y(1:nc) = ytemp(1:nc)
  1118. deallocate(ytemp)
  1119. deallocate(diff)
  1120. !---------------------------------------------------------------------------------------------------
  1121. end subroutine WENO1d
  1122. !===================================================================================================
  1123. !
  1124. !===================================================================================================
  1125. ! subroutine ENO1d
  1126. !
  1127. !> Carries out a 1D interpolation using piecewise polynomial ENO reconstruction technique
  1128. !! on a child grid (vector y) from its parent grid (vector x).
  1129. !! \see ---- p 163-164 Computational gasdynamics ----
  1130. !---------------------------------------------------------------------------------------------------
  1131. subroutine ENO1d ( x, y, np, nc, s_parent, s_child, ds_parent, ds_child )
  1132. !---------------------------------------------------------------------------------------------------
  1133. integer, intent(in) :: np, nc
  1134. real, dimension(np), intent(in) :: x
  1135. real, dimension(nc), intent(out) :: y
  1136. real, intent(in) :: s_parent, s_child
  1137. real, intent(in) :: ds_parent, ds_child
  1138. !
  1139. integer :: i,coeffraf,locind_parent_left,locind_parent_last
  1140. integer :: ipos, pos
  1141. real :: ypos,xi
  1142. integer :: i1,jj
  1143. real :: xpmin
  1144. !
  1145. real, dimension(:), allocatable :: ytemp
  1146. real, dimension(:,:), allocatable :: xbar
  1147. real, dimension(1:np+1) :: xhalf
  1148. real, dimension(3,np) :: dd, c
  1149. integer :: diffmod, left
  1150. !
  1151. coeffraf = nint(ds_parent/ds_child)
  1152. !
  1153. if (coeffraf == 1) then
  1154. locind_parent_left = 1 + nint((s_child - s_parent)/ds_parent)
  1155. y(1:nc) = x(locind_parent_left:locind_parent_left+nc-1)
  1156. return
  1157. end if
  1158. diffmod = 0
  1159. if (mod(coeffraf,2) == 0) diffmod = 1
  1160. !
  1161. allocate(ytemp(-2*coeffraf:nc+2*coeffraf))
  1162. ypos = s_child
  1163. !
  1164. locind_parent_left = 1 + agrif_int((ypos - s_parent)/ds_parent)
  1165. locind_parent_last = 1 + agrif_ceiling((ypos +(nc - 1) *ds_child - s_parent)/ds_parent)
  1166. !
  1167. xpmin = s_parent + (locind_parent_left-1)*ds_parent
  1168. i1 = 1+agrif_int((xpmin-s_child)/ds_child)
  1169. !
  1170. do i = 1,np+1
  1171. xhalf(i) = i - 0.5
  1172. enddo
  1173. !
  1174. ! Compute divided differences
  1175. !
  1176. dd(1,1:np) = x(1:np)
  1177. dd(2,1:np-1) = 0.5*( dd(1,2:np) - dd(1,1:np-1) )
  1178. dd(3,1:np-2) = (1./3.)*( dd(2,2:np-1) - dd(2,1:np-2) )
  1179. !
  1180. allocate( xbar( coeffraf,2 ) )
  1181. xi = 0.5
  1182. do i = 1,coeffraf
  1183. xbar(i,1) = (i-1)*ds_child/ds_parent - xi
  1184. xbar(i,2) = i *ds_child/ds_parent - xi
  1185. enddo
  1186. !
  1187. ipos = i1
  1188. !
  1189. do i = locind_parent_left,locind_parent_last
  1190. left = i
  1191. do jj = 2,3
  1192. if(abs(dd(jj,left)) > abs(dd(jj,left-1))) left = left-1
  1193. enddo
  1194. !
  1195. ! convert to Taylor series form
  1196. call taylor(i,xhalf(left:left+2),dd(1:3,left),c(1:3,i))
  1197. enddo
  1198. !
  1199. ! Evaluate the reconstruction on each cell
  1200. !
  1201. do i = locind_parent_left,locind_parent_last
  1202. !
  1203. pos = 1
  1204. !
  1205. do jj = ipos - coeffraf/2+diffmod,ipos + coeffraf/2
  1206. ytemp(jj) = ( c(1,i)*(xbar(pos,2)-xbar(pos,1)) &
  1207. + c(2,i)*(xbar(pos,2)*xbar(pos,2) - &
  1208. xbar(pos,1)*xbar(pos,1)) &
  1209. + c(3,i)*(xbar(pos,2)*xbar(pos,2)*xbar(pos,2) - &
  1210. xbar(pos,1)*xbar(pos,1)*xbar(pos,1)) &
  1211. ) * coeffraf
  1212. pos = pos+1
  1213. enddo
  1214. ipos = ipos + coeffraf
  1215. !
  1216. enddo
  1217. !
  1218. y(1:nc) = ytemp(1:nc)
  1219. deallocate(ytemp,xbar)
  1220. !---------------------------------------------------------------------------------------------------
  1221. end subroutine ENO1d
  1222. !===================================================================================================
  1223. !
  1224. ! **************************************************************************
  1225. !CC Subroutine ppm1d_lim
  1226. ! **************************************************************************
  1227. !
  1228. Subroutine ppm1d_lim(x,y,np,nc,s_parent,s_child,ds_parent,ds_child)
  1229. !
  1230. !CC Description:
  1231. !CC Subroutine to do a 1D interpolation and apply monotonicity constraints
  1232. !CC using piecewise parabolic method
  1233. !CC on a child grid (vector y) from its parent grid (vector x).
  1234. !C Method:
  1235. !
  1236. ! Declarations:
  1237. !
  1238. Implicit none
  1239. !
  1240. ! Arguments
  1241. Integer :: np,nc
  1242. Real, Dimension(np) :: x
  1243. Real, Dimension(nc) :: y
  1244. Real, Dimension(:),Allocatable :: ytemp
  1245. Real :: s_parent,s_child,ds_parent,ds_child
  1246. !
  1247. ! Local scalars
  1248. Integer :: i,coeffraf,locind_parent_left,locind_parent_last
  1249. Integer :: iparent,ipos,pos,nmin,nmax
  1250. Real :: ypos
  1251. integer :: i1,jj
  1252. Real :: xpmin,cavg,a,b
  1253. !
  1254. Real :: xrmin,xrmax,am3,s2,s1
  1255. Real, Dimension(np) :: dela,xr,xl,delta,a6,slope,slope2
  1256. Real, Dimension(:),Allocatable :: diff,diff2,diff3
  1257. INTEGER :: diffmod
  1258. !
  1259. coeffraf = nint(ds_parent/ds_child)
  1260. !
  1261. If (coeffraf == 1) Then
  1262. locind_parent_left = 1 + nint((s_child - s_parent)/ds_parent)
  1263. y(1:nc) = x(locind_parent_left:locind_parent_left+nc-1)
  1264. return
  1265. End If
  1266. !
  1267. Allocate(ytemp(-2*coeffraf:nc+2*coeffraf))
  1268. ypos = s_child
  1269. !
  1270. locind_parent_left = 1 + agrif_int((ypos - s_parent)/ds_parent)
  1271. locind_parent_last = 1 + &
  1272. agrif_ceiling((ypos +(nc - 1) &
  1273. *ds_child - s_parent)/ds_parent)
  1274. !
  1275. xpmin = s_parent + (locind_parent_left-1)*ds_parent
  1276. i1 = 1+agrif_int((xpmin-s_child)/ds_child)
  1277. !
  1278. Allocate( diff(coeffraf),diff2(coeffraf),diff3(coeffraf) )
  1279. !
  1280. diff(:) = ds_child/ds_parent
  1281. !
  1282. Do i=1,coeffraf
  1283. a = real(i-1)*ds_child/ds_parent
  1284. b = real(i)*ds_child/ds_parent
  1285. diff2(i) = 0.5*(b*b - a*a)
  1286. diff3(i) = (1./3.)*(b*b*b - a*a*a)
  1287. End do
  1288. !
  1289. if( locind_parent_last+2 <= np ) then
  1290. nmax = locind_parent_last+2
  1291. else if( locind_parent_last+1 <= np ) then
  1292. nmax = locind_parent_last+1
  1293. else
  1294. nmax = locind_parent_last
  1295. endif
  1296. !
  1297. if(locind_parent_left-1 >= 1) then
  1298. nmin = locind_parent_left-1
  1299. else
  1300. nmin = locind_parent_left
  1301. endif
  1302. !
  1303. Do i = nmin,nmax
  1304. slope(i) = x(i) - x(i-1)
  1305. slope2(i) = 2.*abs(slope(i))
  1306. Enddo
  1307. !
  1308. Do i = nmin,nmax-1
  1309. dela(i) = 0.5 * ( slope(i) + slope(i+1) )
  1310. ! Van Leer slope limiter
  1311. dela(i) = min( abs(dela(i)),slope2(i), &
  1312. slope2(i+1) )*sign(1.,dela(i))
  1313. IF( slope(i)*slope(i+1) <= 0. ) dela(i) = 0.
  1314. Enddo
  1315. !
  1316. Do i = nmin,nmax-2
  1317. xr(i) = x(i) + (1./2.)*slope(i+1) + (-1./6.)*dela(i+1) &
  1318. + ( 1./6. )*dela(i)
  1319. Enddo
  1320. !
  1321. Do i = nmin,nmax-2
  1322. xrmin = min(x(i),x(i+1))
  1323. xrmax = max(x(i),x(i+1))
  1324. xr(i) = min(xr(i),xrmax)
  1325. xr(i) = max(xr(i),xrmin)
  1326. xl(i+1) = xr(i)
  1327. Enddo
  1328. ! apply parabolic monotonicity
  1329. Do i = locind_parent_left,locind_parent_last
  1330. If( ( (xr(i)-x(i))* (x(i)-xl(i)) ) .le. 0. ) then
  1331. xl(i) = x(i)
  1332. xr(i) = x(i)
  1333. Endif
  1334. delta(i) = xr(i) - xl(i)
  1335. am3 = 3. * x(i)
  1336. s1 = am3 - 2. * xr(i)
  1337. s2 = am3 - 2. * xl(i)
  1338. IF( delta(i) * (xl(i) - s1) .le. 0. ) xl(i) = s1
  1339. IF( delta(i) * (s2 - xr(i)) .le. 0. ) xr(i) = s2
  1340. delta(i) = xr(i) - xl(i)
  1341. a6(i) = 6.*x(i)-3.*(xl(i) +xr(i))
  1342. !
  1343. End do
  1344. !
  1345. diffmod = 0
  1346. IF (mod(coeffraf,2) == 0) diffmod = 1
  1347. !
  1348. ipos = i1
  1349. !
  1350. Do iparent = locind_parent_left,locind_parent_last
  1351. pos=1
  1352. cavg = 0.
  1353. Do jj = ipos - coeffraf/2+diffmod,ipos + coeffraf/2
  1354. !
  1355. ytemp(jj) = (diff(pos)*xl(iparent) &
  1356. + diff2(pos) &
  1357. * (delta(iparent)+a6(iparent)) &
  1358. - diff3(pos)*a6(iparent))*coeffraf
  1359. cavg = cavg + ytemp(jj)
  1360. pos = pos+1
  1361. End do
  1362. ipos = ipos + coeffraf
  1363. !
  1364. End do
  1365. !
  1366. !
  1367. y(1:nc)=ytemp(1:nc)
  1368. deallocate(ytemp)
  1369. deallocate(diff, diff2, diff3)
  1370. Return
  1371. End Subroutine ppm1d_lim
  1372. !===================================================================================================
  1373. ! subroutine taylor
  1374. !---------------------------------------------------------------------------------------------------
  1375. subroutine taylor ( ind, xhalf, dd, c )
  1376. !---------------------------------------------------------------------------------------------------
  1377. integer, intent(in) :: ind
  1378. real, dimension(3), intent(in) :: xhalf
  1379. real, dimension(3), intent(in) :: dd
  1380. real, dimension(3), intent(out) :: c
  1381. !
  1382. real, dimension(0:3,0:3) :: d
  1383. integer :: i, j
  1384. !
  1385. d(0,0:3) = 1.0
  1386. do i = 1,3
  1387. d(i,0) = (ind-xhalf(i))*d(i-1,0)
  1388. enddo
  1389. !
  1390. do i = 1,3
  1391. do j = 1,3-i
  1392. d(i,j) = d(i,j-1) + (ind-xhalf(i+j))*d(i-1,j)
  1393. enddo
  1394. enddo
  1395. !
  1396. do j = 1,3
  1397. c(j) = 0.
  1398. do i=0,3-j
  1399. c(j) = c(j) + d(i,j)*dd(i+j)
  1400. enddo
  1401. enddo
  1402. !---------------------------------------------------------------------------------------------------
  1403. end subroutine taylor
  1404. !===================================================================================================
  1405. !
  1406. !===================================================================================================
  1407. ! function Agrif_limiter_vanleer
  1408. !---------------------------------------------------------------------------------------------------
  1409. real function Agrif_limiter_vanleer ( tab ) result(res)
  1410. !---------------------------------------------------------------------------------------------------
  1411. real, dimension(3), intent(in) :: tab
  1412. !
  1413. real :: p1, p2, p3
  1414. p1 = (tab(3)-tab(1))/2.
  1415. p2 = 2.*(tab(2)-tab(1))
  1416. p3 = 2.*(tab(3)-tab(2))
  1417. if ((p1>0.).AND.(p2>0.).AND.(p3>0)) then
  1418. res = minval((/p1,p2,p3/))
  1419. elseif ((p1<0.).AND.(p2<0.).AND.(p3<0)) then
  1420. res = maxval((/p1,p2,p3/))
  1421. else
  1422. res=0.
  1423. endif
  1424. !---------------------------------------------------------------------------------------------------
  1425. end function Agrif_limiter_vanleer
  1426. !===================================================================================================
  1427. !
  1428. end module Agrif_InterpBasic