modcluster.F90 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277
  1. !
  2. ! $Id: modcluster.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_Clustering
  25. !>
  26. !> Contains subroutines to create and initialize the grid hierarchy from the
  27. !> AGRIF_FixedGrids.in file.
  28. !
  29. module Agrif_Clustering
  30. !
  31. use Agrif_CurgridFunctions
  32. use Agrif_Init_Vars
  33. use Agrif_Save
  34. !
  35. implicit none
  36. !
  37. abstract interface
  38. subroutine init_proc()
  39. end subroutine init_proc
  40. end interface
  41. !
  42. contains
  43. !
  44. !===================================================================================================
  45. ! subroutine Agrif_Cluster_All
  46. !
  47. !> Subroutine for the clustering. A temporary grid hierarchy, pointed by parent_rect, is created.
  48. !---------------------------------------------------------------------------------------------------
  49. recursive subroutine Agrif_Cluster_All ( g, parent_rect )
  50. !---------------------------------------------------------------------------------------------------
  51. TYPE(Agrif_Grid) , pointer :: g !< Pointer on the current grid
  52. TYPE(Agrif_Rectangle), pointer :: parent_rect
  53. !
  54. TYPE(Agrif_LRectangle), pointer :: parcours
  55. TYPE(Agrif_Grid) , pointer :: newgrid
  56. REAL :: g_eps
  57. INTEGER :: i
  58. !
  59. g_eps = huge(1.)
  60. do i = 1,Agrif_Probdim
  61. g_eps = min(g_eps, g % Agrif_dx(i))
  62. enddo
  63. !
  64. g_eps = g_eps / 100.
  65. !
  66. ! Necessary condition for clustering
  67. do i = 1,Agrif_Probdim
  68. if ( g%Agrif_dx(i)/Agrif_coeffref(i) < (Agrif_mind(i)-g_eps)) return
  69. enddo
  70. !
  71. nullify(parent_rect%childgrids)
  72. !
  73. call Agrif_ClusterGridnD(g,parent_rect)
  74. !
  75. parcours => parent_rect % childgrids
  76. !
  77. do while ( associated(parcours) )
  78. !
  79. ! Newgrid is created. It is a copy of a fine grid created previously by clustering.
  80. allocate(newgrid)
  81. !
  82. do i = 1,Agrif_Probdim
  83. newgrid % nb(i) = (parcours % r % imax(i) - parcours % r % imin(i)) * Agrif_Coeffref(i)
  84. newgrid % Agrif_x(i) = g % Agrif_x(i) + (parcours % r % imin(i) -1) * g%Agrif_dx(i)
  85. newgrid % Agrif_dx(i) = g % Agrif_dx(i) / Agrif_Coeffref(i)
  86. enddo
  87. !
  88. if ( Agrif_Probdim == 1 ) then
  89. allocate(newgrid%tabpoint1D(newgrid%nb(1)+1))
  90. newgrid%tabpoint1D = 0
  91. endif
  92. !
  93. if ( Agrif_Probdim == 2 ) then
  94. allocate(newgrid%tabpoint2D(newgrid%nb(1)+1, newgrid%nb(2)+1))
  95. newgrid%tabpoint2D = 0
  96. endif
  97. !
  98. if ( Agrif_Probdim == 3 ) then
  99. allocate(newgrid%tabpoint3D(newgrid%nb(1)+1, newgrid%nb(2)+1, newgrid%nb(3)+1))
  100. newgrid%tabpoint3D = 0
  101. endif
  102. !
  103. ! Points detection on newgrid
  104. call Agrif_TabpointsnD(Agrif_mygrid,newgrid)
  105. !
  106. ! recursive call to Agrif_Cluster_All
  107. call Agrif_Cluster_All(newgrid, parcours % r)
  108. !
  109. parcours => parcours % next
  110. !
  111. if ( Agrif_Probdim == 1 ) deallocate(newgrid%tabpoint1D)
  112. if ( Agrif_Probdim == 2 ) deallocate(newgrid%tabpoint2D)
  113. if ( Agrif_Probdim == 3 ) deallocate(newgrid%tabpoint3D)
  114. !
  115. deallocate(newgrid)
  116. !
  117. enddo
  118. !---------------------------------------------------------------------------------------------------
  119. end subroutine Agrif_Cluster_All
  120. !===================================================================================================
  121. !
  122. !===================================================================================================
  123. ! subroutine Agrif_TabpointsnD
  124. !
  125. !> Copy on newgrid of points detected on the grid hierarchy pointed by g.
  126. !---------------------------------------------------------------------------------------------------
  127. recursive subroutine Agrif_TabpointsnD ( g, newgrid )
  128. !---------------------------------------------------------------------------------------------------
  129. TYPE(Agrif_Grid), pointer :: g, newgrid
  130. !
  131. TYPE(Agrif_PGrid), pointer :: parcours
  132. !
  133. REAL :: g_eps, newgrid_eps, eps
  134. REAL , DIMENSION(3) :: newmin, newmax
  135. REAL , DIMENSION(3) :: gmin, gmax
  136. REAL , DIMENSION(3) :: xmin
  137. INTEGER, DIMENSION(3) :: igmin, inewmin
  138. INTEGER, DIMENSION(3) :: inewmax
  139. INTEGER :: i, j, k
  140. INTEGER :: i0, j0, k0
  141. !
  142. parcours => g % child_list % first
  143. !
  144. do while( associated(parcours) )
  145. call Agrif_TabpointsnD(parcours%gr,newgrid)
  146. parcours => parcours % next
  147. enddo
  148. !
  149. g_eps = 10.
  150. newgrid_eps = 10.
  151. !
  152. do i = 1,Agrif_probdim
  153. g_eps = min( g_eps , g % Agrif_dx(i) )
  154. newgrid_eps = min(newgrid_eps,newgrid%Agrif_dx(i))
  155. enddo
  156. !
  157. eps = min(g_eps,newgrid_eps)/100.
  158. !
  159. do i = 1,Agrif_probdim
  160. !
  161. if ( newgrid%Agrif_dx(i) < (g%Agrif_dx(i)-eps) ) return
  162. !
  163. gmin(i) = g%Agrif_x(i)
  164. gmax(i) = g%Agrif_x(i) + g%nb(i) * g%Agrif_dx(i)
  165. !
  166. newmin(i) = newgrid%Agrif_x(i)
  167. newmax(i) = newgrid%Agrif_x(i) + newgrid%nb(i) * newgrid%Agrif_dx(i)
  168. !
  169. if (gmax(i) < newmin(i)) return
  170. if (gmin(i) > newmax(i)) return
  171. !
  172. inewmin(i) = 1 - floor(-(max(gmin(i),newmin(i))-newmin(i)) / newgrid%Agrif_dx(i))
  173. !
  174. xmin(i) = newgrid%Agrif_x(i) + (inewmin(i)-1)*newgrid%Agrif_dx(i)
  175. !
  176. igmin(i) = 1 + nint((xmin(i)-gmin(i))/g%Agrif_dx(i))
  177. !
  178. inewmax(i) = 1 + int( (min(gmax(i),newmax(i))-newmin(i)) / newgrid%Agrif_dx(i))
  179. !
  180. enddo
  181. !
  182. if ( Agrif_probdim == 1 ) then
  183. i0 = igmin(1)
  184. do i = inewmin(1),inewmax(1)
  185. newgrid%tabpoint1D(i) = max( newgrid%tabpoint1D(i), g%tabpoint1D(i0) )
  186. enddo
  187. i0 = i0 + int(newgrid%Agrif_dx(1)/g%Agrif_dx(1))
  188. endif
  189. !
  190. if ( Agrif_probdim == 2 ) then
  191. i0 = igmin(1)
  192. do i = inewmin(1),inewmax(1)
  193. j0 = igmin(2)
  194. do j = inewmin(2),inewmax(2)
  195. newgrid%tabpoint2D(i,j) = max( newgrid%tabpoint2D(i,j), g%tabpoint2D(i0,j0) )
  196. j0 = j0 + int(newgrid%Agrif_dx(2)/g%Agrif_dx(2))
  197. enddo
  198. i0 = i0 + int(newgrid%Agrif_dx(1)/g%Agrif_dx(1))
  199. enddo
  200. endif
  201. !
  202. if ( Agrif_probdim == 3 ) then
  203. i0 = igmin(1)
  204. do i = inewmin(1),inewmax(1)
  205. j0 = igmin(2)
  206. do j = inewmin(2),inewmax(2)
  207. k0 = igmin(3)
  208. do k = inewmin(3),inewmax(3)
  209. newgrid%tabpoint3D(i,j,k) = max( newgrid%tabpoint3D(i,j,k), g%tabpoint3D(i0,j0,k0))
  210. k0 = k0 + int(newgrid%Agrif_dx(3)/g%Agrif_dx(3))
  211. enddo
  212. j0 = j0 + int(newgrid%Agrif_dx(2)/g%Agrif_dx(2))
  213. enddo
  214. i0 = i0 + int(newgrid%Agrif_dx(1)/g%Agrif_dx(1))
  215. enddo
  216. endif
  217. !---------------------------------------------------------------------------------------------------
  218. end subroutine Agrif_TabpointsnD
  219. !===================================================================================================
  220. !
  221. !===================================================================================================
  222. ! subroutine Agrif_ClusterGridnD
  223. !
  224. !> Clustering on the grid pointed by g.
  225. !---------------------------------------------------------------------------------------------------
  226. subroutine Agrif_ClusterGridnD ( g, parent_rect )
  227. !---------------------------------------------------------------------------------------------------
  228. TYPE(Agrif_Grid) , pointer :: g !< Pointer on the current grid
  229. TYPE(Agrif_Rectangle), pointer :: parent_rect
  230. !
  231. TYPE(Agrif_Rectangle) :: newrect
  232. TYPE(Agrif_Variable_i) :: newflag
  233. !
  234. INTEGER :: i,j,k
  235. INTEGER, DIMENSION(3) :: sx
  236. INTEGER :: bufferwidth,flagpoints
  237. INTEGER :: n1,n2,m1,m2,o1,o2
  238. !
  239. bufferwidth = int(Agrif_Minwidth/5.)
  240. !
  241. do i = 1,Agrif_probdim
  242. sx(i) = g % nb(i) + 1
  243. enddo
  244. !
  245. if ( Agrif_probdim == 1 ) then
  246. allocate(newflag%iarray1(sx(1)))
  247. newflag%iarray1 = 0
  248. endif
  249. if ( Agrif_probdim == 2 ) then
  250. allocate(newflag%iarray2(sx(1),sx(2)))
  251. newflag%iarray2 = 0
  252. endif
  253. if ( Agrif_probdim == 3 ) then
  254. allocate(newflag%iarray3(sx(1),sx(2),sx(3)))
  255. newflag%iarray3 = 0
  256. endif
  257. !
  258. flagpoints = 0
  259. !
  260. if ( bufferwidth>0 ) then
  261. !
  262. if ( Agrif_probdim == 1 ) then
  263. do i = bufferwidth,sx(1)-bufferwidth+1
  264. if (g % tabpoint1D(i) == 1) then
  265. m1 = i - bufferwidth + 1
  266. m2 = i + bufferwidth - 1
  267. flagpoints = flagpoints + 1
  268. newflag%iarray1(m1:m2) = 1
  269. endif
  270. enddo
  271. endif
  272. !
  273. if ( Agrif_probdim == 2 ) then
  274. do i = bufferwidth,sx(1)-bufferwidth+1
  275. do j = bufferwidth,sx(2)-bufferwidth+1
  276. if (g % tabpoint2D(i,j) == 1) then
  277. n1 = j - bufferwidth + 1
  278. n2 = j + bufferwidth - 1
  279. m1 = i - bufferwidth + 1
  280. m2 = i + bufferwidth - 1
  281. flagpoints = flagpoints + 1
  282. newflag%iarray2(m1:m2,n1:n2) = 1
  283. endif
  284. enddo
  285. enddo
  286. endif
  287. !
  288. if ( Agrif_probdim == 3 ) then
  289. do i = bufferwidth,sx(1)-bufferwidth+1
  290. do j = bufferwidth,sx(2)-bufferwidth+1
  291. do k = bufferwidth,sx(3)-bufferwidth+1
  292. if (g % tabpoint3D(i,j,k) == 1) then
  293. o1 = k - bufferwidth + 1
  294. o2 = k + bufferwidth - 1
  295. n1 = j - bufferwidth + 1
  296. n2 = j + bufferwidth - 1
  297. m1 = i - bufferwidth + 1
  298. m2 = i + bufferwidth - 1
  299. flagpoints = flagpoints + 1
  300. newflag%iarray3(m1:m2,n1:n2,o1:o2) = 1
  301. endif
  302. enddo
  303. enddo
  304. enddo
  305. endif
  306. !
  307. else
  308. !
  309. flagpoints = 1
  310. if ( Agrif_probdim == 1 ) newflag%iarray1 = g % tabpoint1D
  311. if ( Agrif_probdim == 2 ) newflag%iarray2 = g % tabpoint2D
  312. if ( Agrif_probdim == 3 ) newflag%iarray3 = g % tabpoint3D
  313. !
  314. endif
  315. !
  316. if (flagpoints == 0) then
  317. if ( Agrif_probdim == 1 ) deallocate(newflag%iarray1)
  318. if ( Agrif_probdim == 2 ) deallocate(newflag%iarray2)
  319. if ( Agrif_probdim == 3 ) deallocate(newflag%iarray3)
  320. return
  321. endif
  322. !
  323. do i = 1 , Agrif_probdim
  324. newrect % imin(i) = 1
  325. newrect % imax(i) = sx(i)
  326. enddo
  327. !
  328. call Agrif_Clusternd(newflag,parent_rect%childgrids,newrect)
  329. !
  330. if ( Agrif_probdim == 1 ) deallocate(newflag%iarray1)
  331. if ( Agrif_probdim == 2 ) deallocate(newflag%iarray2)
  332. if ( Agrif_probdim == 3 ) deallocate(newflag%iarray3)
  333. !---------------------------------------------------------------------------------------------------
  334. end subroutine Agrif_ClusterGridnD
  335. !===================================================================================================
  336. !
  337. !===================================================================================================
  338. ! subroutine Agrif_ClusternD
  339. !
  340. !> Clustering on the grid pointed by oldB.
  341. !---------------------------------------------------------------------------------------------------
  342. recursive subroutine Agrif_Clusternd ( flag, boxlib, oldB )
  343. !---------------------------------------------------------------------------------------------------
  344. TYPE(Agrif_Variable_i) :: flag
  345. TYPE(Agrif_LRectangle), pointer :: boxlib
  346. TYPE(Agrif_Rectangle) :: oldB
  347. !
  348. TYPE(Agrif_LRectangle),pointer :: tempbox,parcbox,parcbox2
  349. TYPE(Agrif_Rectangle) :: newB,newB2
  350. INTEGER :: i,j,k
  351. INTEGER, DIMENSION(:), allocatable :: i_sig, j_sig, k_sig
  352. INTEGER, DIMENSION(3) :: ipu,ipl
  353. INTEGER, DIMENSION(3) :: istr,islice
  354. REAL :: cureff, neweff
  355. INTEGER :: ValMax,ValSum,TailleTab
  356. INTEGER :: nbpoints,nbpointsflag
  357. LOGICAL :: test
  358. !
  359. allocate( i_sig(oldB%imin(1):oldB%imax(1)) )
  360. if ( Agrif_probdim >= 2 ) allocate( j_sig(oldB%imin(2):oldB%imax(2)) )
  361. if ( Agrif_probdim == 3 ) allocate( k_sig(oldB%imin(3):oldB%imax(3)) )
  362. !
  363. test = .FALSE.
  364. do i = 1,Agrif_probdim
  365. test = test .OR. ( (oldB%imax(i)-oldB%imin(i)+1) < Agrif_Minwidth)
  366. enddo
  367. if ( test ) return
  368. !
  369. if ( Agrif_probdim == 1 ) i_sig = flag%iarray1
  370. if ( Agrif_probdim == 2 ) then
  371. do i = oldB%imin(1),oldB%imax(1)
  372. i_sig(i) = SUM(flag%iarray2(i, oldB%imin(2):oldB%imax(2)))
  373. enddo
  374. do j = oldB%imin(2),oldB%imax(2)
  375. j_sig(j) = SUM(flag%iarray2(oldB%imin(1):oldB%imax(1),j))
  376. enddo
  377. endif
  378. if ( Agrif_probdim == 3 ) then
  379. do i = oldB%imin(1),oldB%imax(1)
  380. i_sig(i) = SUM(flag%iarray3(i,oldB%imin(2):oldB%imax(2), &
  381. oldB%imin(3):oldB%imax(3)))
  382. enddo
  383. do j = oldB%imin(2),oldB%imax(2)
  384. j_sig(j) = SUM(flag%iarray3( oldB%imin(1):oldB%imax(1), j, &
  385. oldB%imin(3):oldB%imax(3)))
  386. enddo
  387. do k = oldB%imin(3),oldB%imax(3)
  388. k_sig(k) = SUM(flag%iarray3( oldB%imin(1):oldB%imax(1), &
  389. oldB%imin(2):oldB%imax(2), k) )
  390. enddo
  391. endif
  392. !
  393. do i = 1,Agrif_probdim
  394. ipl(i) = oldB%imin(i)
  395. ipu(i) = oldB%imax(i)
  396. enddo
  397. !
  398. call Agrif_Clusterprune(i_sig,ipl(1),ipu(1))
  399. if ( Agrif_probdim >= 2 ) call Agrif_Clusterprune(j_sig,ipl(2),ipu(2))
  400. if ( Agrif_probdim == 3 ) call Agrif_Clusterprune(k_sig,ipl(3),ipu(3))
  401. !
  402. test = .TRUE.
  403. do i = 1,Agrif_probdim
  404. test = test .AND. (ipl(i) == oldB%imin(i))
  405. test = test .AND. (ipu(i) == oldB%imax(i))
  406. enddo
  407. if (.NOT. test) then
  408. do i = 1 , Agrif_probdim
  409. newB%imin(i) = ipl(i)
  410. newB%imax(i) = ipu(i)
  411. enddo
  412. !
  413. if ( Agrif_probdim == 1 ) nbpoints = SUM(flag%iarray1(newB%imin(1):newB%imax(1)))
  414. if ( Agrif_probdim == 2 ) nbpoints = SUM(flag%iarray2(newB%imin(1):newB%imax(1), &
  415. newB%imin(2):newB%imax(2)))
  416. if ( Agrif_probdim == 3 ) nbpoints = SUM(flag%iarray3(newB%imin(1):newB%imax(1), &
  417. newB%imin(2):newB%imax(2), &
  418. newB%imin(3):newB%imax(3)))
  419. !
  420. if ( Agrif_probdim == 1 ) TailleTab = (newB%imax(1)-newB%imin(1)+1)
  421. if ( Agrif_probdim == 2 ) TailleTab = (newB%imax(1)-newB%imin(1)+1) * &
  422. (newB%imax(2)-newB%imin(2)+1)
  423. if ( Agrif_probdim == 3 ) TailleTab = (newB%imax(1)-newB%imin(1)+1) * &
  424. (newB%imax(2)-newB%imin(2)+1) * &
  425. (newB%imax(3)-newB%imin(3)+1)
  426. neweff = REAL(nbpoints) / TailleTab
  427. !
  428. if (nbpoints > 0) then
  429. !
  430. if ((neweff > Agrif_efficiency)) then
  431. call Agrif_Add_Rectangle(newB,boxlib)
  432. return
  433. else
  434. !
  435. tempbox => boxlib
  436. newB2 = newB
  437. call Agrif_Clusternd(flag,boxlib,newB)
  438. !
  439. ! Compute new efficiency
  440. cureff = neweff
  441. parcbox2 => boxlib
  442. nbpoints = 0
  443. nbpointsflag = 0
  444. !
  445. do while (associated(parcbox2))
  446. if (associated(parcbox2,tempbox)) exit
  447. newB = parcbox2%r
  448. !
  449. if ( Agrif_probdim == 1 ) Valsum = SUM(flag%iarray1(newB%imin(1):newB%imax(1)))
  450. if ( Agrif_probdim == 2 ) Valsum = SUM(flag%iarray2(newB%imin(1):newB%imax(1), &
  451. newB%imin(2):newB%imax(2)))
  452. if ( Agrif_probdim == 3 ) Valsum = SUM(flag%iarray3(newB%imin(1):newB%imax(1), &
  453. newB%imin(2):newB%imax(2), &
  454. newB%imin(3):newB%imax(3)))
  455. nbpointsflag = nbpointsflag + ValSum
  456. !
  457. if ( Agrif_probdim == 1 ) TailleTab = (newB%imax(1)-newB%imin(1)+1)
  458. if ( Agrif_probdim == 2 ) TailleTab = (newB%imax(1)-newB%imin(1)+1) * &
  459. (newB%imax(2)-newB%imin(2)+1)
  460. if ( Agrif_probdim == 3 ) TailleTab = (newB%imax(1)-newB%imin(1)+1) * &
  461. (newB%imax(2)-newB%imin(2)+1) * &
  462. (newB%imax(3)-newB%imin(3)+1)
  463. nbpoints = nbpoints + TailleTab
  464. parcbox2 => parcbox2%next
  465. enddo
  466. !
  467. ! coefficient 1.05 avant 1.15 possibilite de laisser choix a l utilisateur
  468. if ( REAL(nbpointsflag)/REAL(nbpoints) < (1.0001*cureff)) then
  469. parcbox2 => boxlib
  470. do while (associated(parcbox2))
  471. if (associated(parcbox2,tempbox)) exit
  472. deallocate(parcbox2%r)
  473. parcbox2 => parcbox2%next
  474. enddo
  475. boxlib => tempbox
  476. call Agrif_Add_Rectangle(newB2,boxlib)
  477. return
  478. endif
  479. endif
  480. endif
  481. return
  482. endif
  483. !
  484. do i = 1,Agrif_Probdim
  485. istr(i) = oldB%imax(i)
  486. islice(i) = oldB%imin(i)
  487. enddo
  488. !
  489. call Agrif_Clusterslice(i_sig,islice(1),istr(1))
  490. if ( Agrif_probdim >= 2 ) call Agrif_Clusterslice(j_sig,islice(2),istr(2))
  491. if ( Agrif_probdim == 3 ) call Agrif_Clusterslice(k_sig,islice(3),istr(3))
  492. !
  493. ValSum = 0
  494. do i = 1,Agrif_Probdim
  495. Valsum = valSum + islice(i)
  496. enddo
  497. !
  498. if ( Valsum == -Agrif_Probdim ) then
  499. call Agrif_Add_Rectangle(oldB,boxlib)
  500. return
  501. endif
  502. !
  503. nullify(tempbox)
  504. tempbox => boxlib
  505. if ( Agrif_probdim == 1 ) cureff = (oldB%imax(1)-oldB%imin(1)+1)
  506. if ( Agrif_probdim == 2 ) cureff = (oldB%imax(1)-oldB%imin(1)+1) * &
  507. (oldB%imax(2)-oldB%imin(2)+1)
  508. if ( Agrif_probdim == 3 ) cureff = (oldB%imax(1)-oldB%imin(1)+1) * &
  509. (oldB%imax(2)-oldB%imin(2)+1) * &
  510. (oldB%imax(3)-oldB%imin(3)+1)
  511. nullify(parcbox)
  512. !
  513. do i = 1,Agrif_Probdim
  514. newB%imax(i) = oldB%imax(i)
  515. newB%imin(i) = oldB%imin(i)
  516. enddo
  517. !
  518. ValMax = 0
  519. do i = 1 , Agrif_Probdim
  520. ValMax = Max(ValMax,istr(i))
  521. enddo
  522. !
  523. if (istr(1) == ValMax ) then
  524. newB%imax(1) = islice(1)
  525. call Agrif_Add_Rectangle(newB,parcbox)
  526. newB%imin(1) = islice(1)+1
  527. newB%imax(1) = oldB%imax(1)
  528. call Agrif_Add_Rectangle(newB,parcbox)
  529. else if ( Agrif_probdim >= 2 ) then
  530. if (istr(2) == ValMax ) then
  531. newB%imax(2) = islice(2)
  532. call Agrif_Add_Rectangle(newB,parcbox)
  533. newB%imin(2) = islice(2)+1
  534. newB%imax(2) = oldB%imax(2)
  535. call Agrif_Add_Rectangle(newB,parcbox)
  536. else if ( Agrif_probdim == 3 ) then
  537. newB%imax(3) = islice(3)
  538. call Agrif_Add_Rectangle(newB,parcbox)
  539. newB%imin(3) = islice(3)+1
  540. newB%imax(3) = oldB%imax(3)
  541. call Agrif_Add_Rectangle(newB,parcbox)
  542. endif
  543. endif
  544. !
  545. do while ( associated(parcbox) )
  546. newB = parcbox%r
  547. !
  548. if ( Agrif_probdim == 1 ) nbpoints = SUM(flag%iarray1(newB%imin(1):newB%imax(1)))
  549. if ( Agrif_probdim == 2 ) nbpoints = SUM(flag%iarray2(newB%imin(1):newB%imax(1), &
  550. newB%imin(2):newB%imax(2)))
  551. if ( Agrif_probdim == 3 ) nbpoints = SUM(flag%iarray3(newB%imin(1):newB%imax(1), &
  552. newB%imin(2):newB%imax(2), &
  553. newB%imin(3):newB%imax(3)))
  554. !
  555. if ( Agrif_probdim == 1 ) TailleTab = (newB%imax(1)-newB%imin(1)+1)
  556. if ( Agrif_probdim == 2 ) TailleTab = (newB%imax(1)-newB%imin(1)+1) * &
  557. (newB%imax(2)-newB%imin(2)+1)
  558. if ( Agrif_probdim == 3 ) TailleTab = (newB%imax(1)-newB%imin(1)+1) * &
  559. (newB%imax(2)-newB%imin(2)+1) * &
  560. (newB%imax(3)-newB%imin(3)+1)
  561. neweff = REAL(nbpoints) / TailleTab
  562. !
  563. if ( nbpoints > 0 ) then
  564. !
  565. if ( (neweff > Agrif_efficiency)) then
  566. call Agrif_Add_Rectangle(newB,boxlib)
  567. else
  568. tempbox => boxlib
  569. newB2 = newB
  570. call Agrif_Clusternd(flag,boxlib,newB)
  571. !
  572. ! Compute new efficiency
  573. cureff = neweff
  574. parcbox2 => boxlib
  575. nbpoints = 0
  576. nbpointsflag = 0
  577. !
  578. do while (associated(parcbox2))
  579. if (associated(parcbox2,tempbox)) exit
  580. newB = parcbox2%r
  581. !
  582. if ( Agrif_probdim == 1 ) ValSum = SUM(flag%iarray1(newB%imin(1):newB%imax(1)))
  583. if ( Agrif_probdim == 2 ) ValSum = SUM(flag%iarray2(newB%imin(1):newB%imax(1), &
  584. newB%imin(2):newB%imax(2)))
  585. if ( Agrif_probdim == 3 ) ValSum = SUM(flag%iarray3(newB%imin(1):newB%imax(1), &
  586. newB%imin(2):newB%imax(2), &
  587. newB%imin(3):newB%imax(3)))
  588. nbpointsflag = nbpointsflag + ValSum
  589. !
  590. if ( Agrif_probdim == 1 ) TailleTab = (newB%imax(1)-newB%imin(1)+1)
  591. if ( Agrif_probdim == 2 ) TailleTab = (newB%imax(1)-newB%imin(1)+1) * &
  592. (newB%imax(2)-newB%imin(2)+1)
  593. if ( Agrif_probdim == 3 ) TailleTab = (newB%imax(1)-newB%imin(1)+1) * &
  594. (newB%imax(2)-newB%imin(2)+1) * &
  595. (newB%imax(3)-newB%imin(3)+1)
  596. nbpoints = nbpoints + TailleTab
  597. parcbox2 => parcbox2%next
  598. enddo
  599. !
  600. if ( REAL(nbpointsflag)/REAL(nbpoints) < (1.15*cureff)) then
  601. parcbox2 => boxlib
  602. do while (associated(parcbox2))
  603. if (associated(parcbox2,tempbox)) exit
  604. deallocate(parcbox2%r)
  605. parcbox2 => parcbox2%next
  606. enddo
  607. boxlib => tempbox
  608. call Agrif_Add_Rectangle(newB2,boxlib)
  609. endif
  610. endif
  611. endif
  612. parcbox => parcbox%next
  613. enddo
  614. !---------------------------------------------------------------------------------------------------
  615. end subroutine Agrif_Clusternd
  616. !===================================================================================================
  617. !
  618. !===================================================================================================
  619. ! subroutine Agrif_Clusterslice
  620. !---------------------------------------------------------------------------------------------------
  621. subroutine Agrif_Clusterslice ( sig, slice, str )
  622. !---------------------------------------------------------------------------------------------------
  623. INTEGER, intent(inout) :: slice
  624. INTEGER, intent(inout) :: str
  625. INTEGER, DIMENSION(slice:str), intent(in) :: sig
  626. !
  627. INTEGER :: ideb, ifin
  628. INTEGER :: i, t, a, di, ts
  629. INTEGER, DIMENSION(slice:str) :: lap
  630. !
  631. ideb = slice
  632. ifin = str
  633. !
  634. if (SIZE(sig) <= 2*Agrif_Minwidth) then
  635. str = -1
  636. slice = -1
  637. return
  638. endif
  639. !
  640. t = -1
  641. a = -1
  642. !
  643. do i = ideb+Agrif_Minwidth-1,ifin-Agrif_Minwidth
  644. if (sig(i) == 0) then
  645. if ((i-ideb) < (ifin-i)) then
  646. di = i - ideb
  647. else
  648. di = ifin - i
  649. endif
  650. !
  651. if (di > t) then
  652. a = i
  653. t = di
  654. endif
  655. endif
  656. enddo
  657. !
  658. if (a /= -1) then
  659. slice = a
  660. str = t
  661. return
  662. endif
  663. !
  664. t = -1
  665. a = -1
  666. !
  667. do i = ideb+1,ifin-1
  668. lap(i) = sig(i+1) + sig(i-1) - 2*sig(i)
  669. enddo
  670. !
  671. do i = ideb + Agrif_Minwidth-1,ifin-Agrif_Minwidth
  672. if ((lap(i+1)*lap(i)) <= 0) then
  673. ts = ABS(lap(i+1) - lap(i))
  674. if (ts > t) then
  675. t = ts
  676. a = i
  677. endif
  678. endif
  679. enddo
  680. !
  681. if (a == (ideb + Agrif_Minwidth - 1)) then
  682. a = -1
  683. t = -1
  684. endif
  685. !
  686. slice = a
  687. str = t
  688. !---------------------------------------------------------------------------------------------------
  689. end subroutine Agrif_Clusterslice
  690. !===================================================================================================
  691. !
  692. !===================================================================================================
  693. ! subroutine Agrif_Clusterprune
  694. !---------------------------------------------------------------------------------------------------
  695. subroutine Agrif_Clusterprune ( sig, pl, pu )
  696. !---------------------------------------------------------------------------------------------------
  697. INTEGER, intent(inout) :: pl, pu
  698. INTEGER, DIMENSION(pl:pu), intent(in) :: sig
  699. !
  700. INTEGER :: ideb, ifin
  701. INTEGER :: diff, addl, addu, udist, ldist
  702. !
  703. ideb = pl
  704. ifin = pu
  705. !
  706. if (SIZE(sig) <= Agrif_Minwidth) return
  707. !
  708. do while ((sig(pl) == 0) .AND. (pl < ifin))
  709. pl = pl + 1
  710. enddo
  711. !
  712. do while ((sig(pu) == 0) .AND. (pu > ideb))
  713. pu = pu - 1
  714. enddo
  715. !
  716. if ( (pu-pl) < Agrif_Minwidth ) then
  717. diff = Agrif_Minwidth - (pu - pl + 1)
  718. udist = ifin - pu
  719. ldist = pl - ideb
  720. addl = diff / 2
  721. addu = diff - addl
  722. if (addu > udist) then
  723. addu = udist
  724. addl = diff - addu
  725. endif
  726. !
  727. if (addl > ldist) then
  728. addl = ldist
  729. addu = diff - addl
  730. endif
  731. !
  732. pu = pu + addu
  733. pl = pl - addl
  734. endif
  735. !---------------------------------------------------------------------------------------------------
  736. end subroutine Agrif_Clusterprune
  737. !===================================================================================================
  738. !
  739. !===================================================================================================
  740. ! subroutine Agrif_Add_Rectangle
  741. !
  742. !> Adds the Agrif_Rectangle R in a list managed by LR.
  743. !---------------------------------------------------------------------------------------------------
  744. subroutine Agrif_Add_Rectangle ( R, LR )
  745. !---------------------------------------------------------------------------------------------------
  746. TYPE(Agrif_Rectangle) :: R
  747. TYPE(Agrif_LRectangle), pointer :: LR
  748. !
  749. TYPE(Agrif_LRectangle), pointer :: newrect
  750. !
  751. integer :: i
  752. !
  753. allocate(newrect)
  754. allocate(newrect % r)
  755. !
  756. newrect % r = R
  757. !
  758. do i = 1,Agrif_Probdim
  759. newrect % r % spaceref(i) = Agrif_Coeffref(i)
  760. newrect % r % timeref(i) = Agrif_Coeffreft(i)
  761. enddo
  762. !
  763. newrect % r % number = -1
  764. newrect % next => LR
  765. LR => newrect
  766. !---------------------------------------------------------------------------------------------------
  767. end subroutine Agrif_Add_Rectangle
  768. !===================================================================================================
  769. !
  770. !===================================================================================================
  771. ! subroutine Agrif_Copy_Rectangle
  772. !
  773. !> Creates and returns a copy of Agrif_Rectangle R.
  774. !---------------------------------------------------------------------------------------------------
  775. function Agrif_Copy_Rectangle ( R, expand ) result( copy )
  776. !---------------------------------------------------------------------------------------------------
  777. TYPE(Agrif_Rectangle), pointer, intent(in) :: R
  778. integer, optional, intent(in) :: expand
  779. !
  780. TYPE(Agrif_Rectangle), pointer :: copy
  781. !
  782. allocate(copy)
  783. !
  784. copy = R
  785. if ( present(expand) ) then
  786. copy % imin = copy % imin - expand
  787. copy % imax = copy % imax + expand
  788. endif
  789. copy % childgrids => R % childgrids
  790. !---------------------------------------------------------------------------------------------------
  791. end function Agrif_Copy_Rectangle
  792. !===================================================================================================
  793. !
  794. !===================================================================================================
  795. ! subroutine Agrif_Read_Fix_Grd
  796. !
  797. !> Creates the grid hierarchy from the reading of the AGRIF_FixedGrids.in file.
  798. !---------------------------------------------------------------------------------------------------
  799. recursive subroutine Agrif_Read_Fix_Grd ( parent_rect, j, nunit )
  800. !---------------------------------------------------------------------------------------------------
  801. TYPE(Agrif_Rectangle), pointer :: parent_rect !< Pointer on the first grid of the grid hierarchy
  802. INTEGER :: j !< Number of the new grid
  803. INTEGER :: nunit !< unit associated with file
  804. !
  805. TYPE(Agrif_Rectangle) :: newrect ! Pointer on a new grid
  806. TYPE(Agrif_LRectangle), pointer :: parcours ! Pointer for the recursive procedure
  807. TYPE(Agrif_LRectangle), pointer :: newlrect
  808. TYPE(Agrif_LRectangle), pointer :: end_list
  809. INTEGER :: i,n ! for each child grid
  810. INTEGER :: nb_grids ! Number of child grids
  811. !
  812. ! Reading of the number of child grids
  813. read(nunit,*,end=99) nb_grids
  814. !
  815. allocate(end_list)
  816. !
  817. parent_rect % childgrids => end_list
  818. !
  819. ! Reading of imin(1),imax(1),imin(2),imax(2),imin(3),imax(3), and space and
  820. ! time refinement factors for each child grid.
  821. ! Creation and addition of the new grid to the grid hierarchy.
  822. !
  823. do n = 1,nb_grids
  824. !
  825. allocate(newlrect)
  826. newrect % number = j ! Number of the grid
  827. !
  828. if ( Agrif_USE_ONLY_FIXED_GRIDS == 0 ) then
  829. if (Agrif_Probdim == 3) then
  830. read(nunit,*) newrect % imin(1), newrect % imax(1), &
  831. newrect % imin(2), newrect % imax(2), &
  832. newrect % imin(3), newrect % imax(3), &
  833. newrect % spaceref(1), newrect % spaceref(2), newrect % spaceref(3), &
  834. newrect % timeref(1), newrect % timeref(2), newrect % timeref(3)
  835. elseif (Agrif_Probdim == 2) then
  836. read(nunit,*) newrect % imin(1), newrect % imax(1), &
  837. newrect % imin(2), newrect % imax(2), &
  838. newrect % spaceref(1), newrect % spaceref(2), &
  839. newrect % timeref(1), newrect % timeref(2)
  840. elseif (Agrif_Probdim == 1) then
  841. read(nunit,*) newrect % imin(1), newrect % imax(1), &
  842. newrect % spaceref(1), &
  843. newrect % timeref(1)
  844. endif
  845. else
  846. if (Agrif_Probdim == 3) then
  847. read(nunit,*) newrect % imin(1), newrect % imax(1), &
  848. newrect % imin(2), newrect % imax(2), &
  849. newrect % imin(3), newrect % imax(3), &
  850. newrect % spaceref(1), newrect % spaceref(2), newrect % spaceref(3), &
  851. newrect % timeref(1)
  852. elseif (Agrif_Probdim == 2) then
  853. read(nunit,*) newrect % imin(1), newrect % imax(1), &
  854. newrect % imin(2), newrect % imax(2), &
  855. newrect % spaceref(1), newrect % spaceref(2), &
  856. newrect % timeref(1)
  857. elseif (Agrif_Probdim == 1) then
  858. read(nunit,*) newrect % imin(1), newrect % imax(1), &
  859. newrect % spaceref(1), &
  860. newrect % timeref(1)
  861. endif
  862. !
  863. if ( Agrif_probdim >= 2 ) then
  864. do i = 2,Agrif_probdim
  865. newrect % timeref(i) = newrect % timeref(1)
  866. enddo
  867. endif
  868. !
  869. endif
  870. !
  871. ! Addition to the grid hierarchy
  872. !
  873. j = j + 1
  874. allocate(newlrect%r)
  875. newlrect % r = newrect
  876. end_list % next => newlrect
  877. end_list => end_list % next
  878. !
  879. enddo
  880. !
  881. parent_rect % childgrids => parent_rect % childgrids % next
  882. parcours => parent_rect % childgrids
  883. !
  884. ! recursive operation to create the grid hierarchy branch by branch
  885. !
  886. do while ( associated(parcours) )
  887. call Agrif_Read_Fix_Grd(parcours % r, j, nunit)
  888. parcours => parcours % next
  889. enddo
  890. 99 continue
  891. !---------------------------------------------------------------------------------------------------
  892. end subroutine Agrif_Read_Fix_Grd
  893. !===================================================================================================
  894. !
  895. !===================================================================================================
  896. ! subroutine Agrif_Create_Grids
  897. !
  898. !> Creates the grid hierarchy (g) from the one created with the #Agrif_Read_Fix_Grd or
  899. !! #Agrif_Cluster_All procedures (parent_rect).
  900. !---------------------------------------------------------------------------------------------------
  901. recursive subroutine Agrif_Create_Grids ( parent_grid, parent_rect )
  902. !---------------------------------------------------------------------------------------------------
  903. TYPE(Agrif_Grid) , pointer :: parent_grid !< Pointer on the root coarse grid
  904. TYPE(Agrif_Rectangle), pointer :: parent_rect !< Pointer on the root coarse grid of the grid hierarchy
  905. !! created with the #Agrif_Read_Fix_Grd subroutine
  906. !
  907. TYPE(Agrif_Grid) , pointer :: child_grid ! Newly created child grid
  908. TYPE(Agrif_PGrid) , pointer :: child_grid_p
  909. TYPE(Agrif_LRectangle), pointer :: child_rect_p
  910. type(Agrif_Rectangle), pointer :: child_rect
  911. !
  912. INTEGER :: i
  913. INTEGER, save :: moving_grid_id = 0
  914. !
  915. child_rect_p => parent_rect % childgrids
  916. !
  917. ! Creation of the grid hierarchy from the one created by using the Agrif_Read_Fix_Grd subroutine
  918. !
  919. do while ( associated(child_rect_p) )
  920. !
  921. child_rect => child_rect_p % r
  922. !
  923. allocate(child_grid)
  924. !
  925. ! Pointer on the parent grid
  926. child_grid % parent => parent_grid
  927. child_grid % rect_in_parent => Agrif_Copy_Rectangle(child_rect_p % r, expand=Agrif_Extra_Boundary_Cells)
  928. !
  929. moving_grid_id = moving_grid_id+1
  930. child_grid % grid_id = moving_grid_id
  931. !
  932. do i = 1,Agrif_Probdim
  933. child_grid % spaceref(i) = child_rect % spaceref(i)
  934. child_grid % timeref(i) = child_rect % timeref(i)
  935. child_grid % nb(i) = (child_rect % imax(i) - child_rect % imin(i)) * child_rect % spaceref(i)
  936. child_grid % ix(i) = child_rect % imin(i)
  937. child_grid % Agrif_dt(i) = parent_grid % Agrif_dt(i) / REAL(child_grid % timeref(i))
  938. child_grid % Agrif_dx(i) = parent_grid % Agrif_dx(i) / REAL(child_grid % spaceref(i))
  939. child_grid % Agrif_x(i) = parent_grid % Agrif_x(i) + &
  940. (child_rect % imin(i) - 1) * parent_grid % Agrif_dx(i)
  941. enddo
  942. !
  943. ! Size of the grid in terms of cpu cost (nx*ny*timeref)
  944. child_grid % size = product( child_grid % nb(1:Agrif_Probdim) ) * child_grid % timeref(1)
  945. !
  946. ! Level of the current grid
  947. child_grid % level = child_grid % parent % level + 1
  948. if (child_grid % level > Agrif_MaxLevelLoc) then
  949. Agrif_MaxLevelLoc = child_grid%level
  950. endif
  951. !
  952. ! Number of the grid pointed by child_grid
  953. child_grid % fixedrank = child_rect % number
  954. !
  955. ! Grid pointed by child_grid is a fixed grid
  956. child_grid % fixed = ( child_grid % fixedrank > 0 )
  957. !
  958. ! Update the total number of fixed grids
  959. if (child_grid % fixed) then
  960. Agrif_nbfixedgrids = Agrif_nbfixedgrids + 1
  961. endif
  962. !
  963. ! Initialize integration counter
  964. child_grid % ngridstep = 0
  965. !
  966. ! Test indicating if the current grid has a common border with the root
  967. ! coarse grid in the x direction
  968. do i = 1 , Agrif_Probdim
  969. !
  970. child_grid % NearRootBorder(i) = ( &
  971. (child_grid % parent % NearRootBorder(i)) .AND. &
  972. (child_grid % ix(i) == 1) )
  973. !
  974. child_grid % DistantRootBorder(i) = ( &
  975. (child_grid % parent % DistantRootBorder(i)) .AND. &
  976. (child_grid % ix(i) + (child_grid%nb(i)/child_grid%spaceref(i))-1 == child_grid % parent % nb(i)) )
  977. enddo
  978. !
  979. ! Writing in output files
  980. child_grid % oldgrid = .FALSE.
  981. !
  982. #if defined AGRIF_MPI
  983. child_grid % communicator = parent_grid % communicator
  984. #endif
  985. !
  986. ! Definition of the characteristics of the variable of the grid pointed by child_grid
  987. call Agrif_Create_Var(child_grid)
  988. !
  989. ! Addition of this grid to the grid hierarchy
  990. call Agrif_gl_append( parent_grid % child_list, child_grid )
  991. !
  992. child_rect_p => child_rect_p % next
  993. !
  994. enddo
  995. !
  996. ! Recursive call to the subroutine Agrif_Create_Fixed_Grids to create the grid hierarchy
  997. !
  998. child_grid_p => parent_grid % child_list % first
  999. child_rect_p => parent_rect % childgrids
  1000. !
  1001. do while ( associated(child_rect_p) )
  1002. call Agrif_Create_Grids( child_grid_p % gr, child_rect_p % r )
  1003. child_grid_p => child_grid_p % next
  1004. child_rect_p => child_rect_p % next
  1005. enddo
  1006. !---------------------------------------------------------------------------------------------------
  1007. end subroutine Agrif_Create_Grids
  1008. !===================================================================================================
  1009. !
  1010. !===================================================================================================
  1011. ! subroutine Agrif_Init_Hierarchy
  1012. !
  1013. !> Initializes all the grids except the root coarse grid (this one, pointed by Agrif_Types::Agrif_Mygrid, is
  1014. !! initialized by the subroutine Agrif_Util#Agrif_Init_Grids defined in the module Agrif_Util and
  1015. !! called in the main program).
  1016. !---------------------------------------------------------------------------------------------------
  1017. recursive subroutine Agrif_Init_Hierarchy ( g, procname )
  1018. !---------------------------------------------------------------------------------------------------
  1019. use Agrif_seq
  1020. !
  1021. type(Agrif_Grid), pointer :: g !< Pointer on the current grid
  1022. procedure(init_proc), optional :: procname !< Initialisation subroutine (Default: Agrif_InitValues)
  1023. !
  1024. TYPE(Agrif_PGrid), pointer :: parcours ! Pointer for the recursive call
  1025. LOGICAL :: Init_Hierarchy
  1026. !
  1027. ! Initialise the grand mother grid (if any)
  1028. !
  1029. if ( associated(g, Agrif_Mygrid) .and. agrif_coarse ) then
  1030. call Agrif_Instance(Agrif_Coarsegrid)
  1031. call Agrif_Allocation(Agrif_Coarsegrid)
  1032. call Agrif_initialisations(Agrif_Coarsegrid)
  1033. call Agrif_InitWorkspace()
  1034. !
  1035. ! Initialization by interpolation (this routine is written by the user)
  1036. if (present(procname)) Then
  1037. call procname()
  1038. else
  1039. call Agrif_InitValues()
  1040. endif
  1041. call Agrif_Instance(Agrif_Mygrid)
  1042. endif
  1043. parcours => g % child_list % first
  1044. !
  1045. do while ( associated(parcours) )
  1046. !
  1047. Init_Hierarchy = .false.
  1048. if ( Agrif_USE_FIXED_GRIDS == 1 .OR. Agrif_USE_ONLY_FIXED_GRIDS == 1 ) then
  1049. if ( (parcours%gr%fixed) .AND. (Agrif_Mygrid%ngridstep == 0) ) then
  1050. Init_Hierarchy = .true.
  1051. endif
  1052. endif
  1053. !
  1054. if (.NOT. parcours % gr % fixed) Init_Hierarchy = .true.
  1055. if (parcours % gr % oldgrid) Init_Hierarchy = .false.
  1056. !
  1057. if (Init_Hierarchy) then
  1058. !
  1059. ! Instanciation of the grid pointed by parcours%gr and its variables
  1060. call Agrif_Instance(parcours % gr)
  1061. !
  1062. ! Allocation of the arrays containing values of the variables of the
  1063. ! grid pointed by parcours%gr
  1064. !
  1065. call Agrif_Allocation(parcours % gr)
  1066. call Agrif_initialisations(parcours % gr)
  1067. !
  1068. if ( Agrif_USE_ONLY_FIXED_GRIDS == 0 ) then
  1069. ! Initialization by copy of the grids created by clustering
  1070. call Agrif_Allocate_Restore(parcours % gr)
  1071. call Agrif_CopyFromOld_All(parcours % gr, Agrif_oldmygrid)
  1072. endif
  1073. !
  1074. ! Initialization by interpolation (this routine is written by the user)
  1075. call Agrif_InitWorkSpace()
  1076. if (present(procname)) Then
  1077. call procname()
  1078. else
  1079. call Agrif_InitValues()
  1080. endif
  1081. !
  1082. if ( Agrif_USE_ONLY_FIXED_GRIDS == 0 ) then
  1083. call Agrif_Free_Restore(parcours % gr)
  1084. endif
  1085. !
  1086. endif
  1087. !
  1088. parcours => parcours % next
  1089. !
  1090. enddo
  1091. !
  1092. parcours => g % child_list % first
  1093. !
  1094. ! recursive operation to initialize all the grids
  1095. do while ( associated(parcours) )
  1096. call Agrif_Init_Hierarchy(parcours%gr,procname)
  1097. parcours => parcours%next
  1098. enddo
  1099. !---------------------------------------------------------------------------------------------------
  1100. end subroutine Agrif_Init_Hierarchy
  1101. !===================================================================================================
  1102. !
  1103. #if defined AGRIF_MPI
  1104. !===================================================================================================
  1105. ! subroutine Agrif_Init_Hierarchy_Parallel_1
  1106. !---------------------------------------------------------------------------------------------------
  1107. recursive subroutine Agrif_Init_Hierarchy_Parallel_1 ( g )
  1108. !---------------------------------------------------------------------------------------------------
  1109. use Agrif_seq
  1110. !
  1111. type(Agrif_Grid), pointer :: g !< Pointer on the current grid
  1112. !
  1113. TYPE(Agrif_PGrid), pointer :: parcours ! Pointer for the recursive call
  1114. LOGICAL :: Init_Hierarchy
  1115. !
  1116. parcours => g % child_list % first
  1117. !
  1118. do while ( associated(parcours) )
  1119. !
  1120. Init_Hierarchy = .false.
  1121. if ( Agrif_USE_FIXED_GRIDS == 1 .OR. Agrif_USE_ONLY_FIXED_GRIDS == 1 ) then
  1122. if ( (parcours%gr%fixed) .AND. (Agrif_Mygrid%ngridstep == 0) ) then
  1123. Init_Hierarchy = .true.
  1124. endif
  1125. endif
  1126. !
  1127. if (.NOT. parcours % gr % fixed) Init_Hierarchy = .true.
  1128. if (parcours % gr % oldgrid) Init_Hierarchy = .false.
  1129. !
  1130. if (Init_Hierarchy) then
  1131. !
  1132. ! Instanciation of the grid pointed by parcours%gr and its variables
  1133. call Agrif_Instance(parcours % gr)
  1134. !
  1135. ! Allocation of the arrays containing values of the variables of the
  1136. ! grid pointed by parcours%gr
  1137. !
  1138. call Agrif_Allocation(parcours % gr)
  1139. call Agrif_initialisations(parcours % gr)
  1140. !
  1141. endif
  1142. !
  1143. parcours => parcours % next
  1144. !
  1145. enddo
  1146. !
  1147. parcours => g % child_list % first
  1148. !
  1149. ! recursive operation to initialize all the grids
  1150. do while ( associated(parcours) )
  1151. call Agrif_Init_Hierarchy_Parallel_1(parcours%gr)
  1152. parcours => parcours%next
  1153. enddo
  1154. !
  1155. !---------------------------------------------------------------------------------------------------
  1156. end subroutine Agrif_Init_Hierarchy_Parallel_1
  1157. !===================================================================================================
  1158. !
  1159. !===================================================================================================
  1160. ! subroutine Agrif_Init_Hierarchy_Parallel_2
  1161. !---------------------------------------------------------------------------------------------------
  1162. recursive subroutine Agrif_Init_Hierarchy_Parallel_2 ( g, procname )
  1163. !---------------------------------------------------------------------------------------------------
  1164. use Agrif_seq
  1165. !
  1166. type(Agrif_Grid), pointer :: g !< Pointer on the current grid
  1167. procedure(init_proc), optional :: procname !< Initialisation subroutine (Default: Agrif_InitValues)
  1168. !
  1169. type(Agrif_PGrid), pointer :: parcours ! Pointer for the recursive call
  1170. integer :: is
  1171. !
  1172. call Agrif_Instance(g)
  1173. call Agrif_seq_init_sequences( g )
  1174. !
  1175. if ( .not. associated(g % child_seq) ) return
  1176. !
  1177. do is = 1, g % child_seq % nb_seqs
  1178. !
  1179. parcours => Agrif_seq_select_child(g,is)
  1180. !
  1181. ! Instanciation of the variables of the current grid
  1182. call Agrif_Instance(parcours % gr)
  1183. !
  1184. ! Initialization by interpolation (this routine is written by the user)
  1185. if (present(procname)) Then
  1186. call procname()
  1187. else
  1188. call Agrif_InitValues()
  1189. endif
  1190. !
  1191. call Agrif_Init_ProcList(parcours % gr % proc_def_list, &
  1192. parcours % gr % proc_def_in_parent_list % nitems)
  1193. !
  1194. call Agrif_Init_Hierarchy_Parallel_2(parcours%gr,procname)
  1195. !
  1196. enddo
  1197. !---------------------------------------------------------------------------------------------------
  1198. end subroutine Agrif_Init_Hierarchy_Parallel_2
  1199. !===================================================================================================
  1200. #endif
  1201. !
  1202. !===================================================================================================
  1203. ! subroutine Agrif_Allocate_Restore
  1204. !---------------------------------------------------------------------------------------------------
  1205. subroutine Agrif_Allocate_Restore ( Agrif_Gr )
  1206. !---------------------------------------------------------------------------------------------------
  1207. TYPE(Agrif_Grid), pointer :: Agrif_Gr !< Pointer on the root coarse grid
  1208. !
  1209. integer :: i
  1210. !
  1211. do i = 1,Agrif_NbVariables(0)
  1212. !
  1213. if ( Agrif_Mygrid%tabvars(i) % restore ) then
  1214. if ( Agrif_Gr%tabvars(i) % nbdim == 1 ) then
  1215. allocate( Agrif_Gr%tabvars(i)%Restore1D( &
  1216. lbound(Agrif_Gr%tabvars(i)%array1,1):&
  1217. ubound(Agrif_Gr%tabvars(i)%array1,1)))
  1218. Agrif_Gr%tabvars(i)%Restore1D = 0
  1219. endif
  1220. if ( Agrif_Gr%tabvars(i) % nbdim == 2 ) then
  1221. allocate( Agrif_Gr%tabvars(i)%Restore2D( &
  1222. lbound(Agrif_Gr%tabvars(i)%array2,1):&
  1223. ubound(Agrif_Gr%tabvars(i)%array2,1),&
  1224. lbound(Agrif_Gr%tabvars(i)%array2,2):&
  1225. ubound(Agrif_Gr%tabvars(i)%array2,2)))
  1226. Agrif_Gr%tabvars(i)%Restore2D = 0
  1227. endif
  1228. if ( Agrif_Mygrid%tabvars(i) % nbdim == 3 ) then
  1229. allocate( Agrif_Gr%tabvars(i)%Restore3D( &
  1230. lbound(Agrif_Gr%tabvars(i)%array3,1):&
  1231. ubound(Agrif_Gr%tabvars(i)%array3,1),&
  1232. lbound(Agrif_Gr%tabvars(i)%array3,2):&
  1233. ubound(Agrif_Gr%tabvars(i)%array3,2),&
  1234. lbound(Agrif_Gr%tabvars(i)%array3,3):&
  1235. ubound(Agrif_Gr%tabvars(i)%array3,3)))
  1236. Agrif_Gr%tabvars(i)%Restore3D = 0
  1237. endif
  1238. endif
  1239. !
  1240. enddo
  1241. !---------------------------------------------------------------------------------------------------
  1242. end subroutine Agrif_Allocate_Restore
  1243. !===================================================================================================
  1244. !
  1245. !===================================================================================================
  1246. ! subroutine Agrif_Free_Restore
  1247. !---------------------------------------------------------------------------------------------------
  1248. subroutine Agrif_Free_Restore ( Agrif_Gr )
  1249. !---------------------------------------------------------------------------------------------------
  1250. TYPE(Agrif_Grid), pointer :: Agrif_Gr !< Pointer on the root coarse grid
  1251. !
  1252. TYPE(Agrif_Variable), pointer :: var
  1253. integer :: i
  1254. !
  1255. do i = 1,Agrif_NbVariables(0)
  1256. !
  1257. if ( Agrif_Mygrid % tabvars(i) % restore ) then
  1258. !
  1259. var = Agrif_Gr % tabvars(i)
  1260. !
  1261. if (associated(var%Restore1D)) deallocate(var%Restore1D)
  1262. if (associated(var%Restore2D)) deallocate(var%Restore2D)
  1263. if (associated(var%Restore3D)) deallocate(var%Restore3D)
  1264. if (associated(var%Restore4D)) deallocate(var%Restore4D)
  1265. if (associated(var%Restore5D)) deallocate(var%Restore5D)
  1266. if (associated(var%Restore6D)) deallocate(var%Restore6D)
  1267. !
  1268. endif
  1269. !
  1270. enddo
  1271. !---------------------------------------------------------------------------------------------------
  1272. end subroutine Agrif_Free_Restore
  1273. !===================================================================================================
  1274. !
  1275. end module Agrif_Clustering