modmpp.F90 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. !
  2. ! $Id: modmpp.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_Mpp
  25. !
  26. use Agrif_Arrays
  27. use Agrif_Grids
  28. !
  29. implicit none
  30. !
  31. interface
  32. subroutine Agrif_get_proc_info ( imin, imax, jmin, jmax )
  33. integer, intent(out) :: imin, imax
  34. integer, intent(out) :: jmin, jmax
  35. end subroutine Agrif_get_proc_info
  36. end interface
  37. !
  38. integer, private :: Agrif_MPI_prec
  39. !
  40. private :: Agrif_get_proc_info
  41. !
  42. contains
  43. !
  44. #if defined AGRIF_MPI
  45. !===================================================================================================
  46. ! subroutine Agrif_MPI_Init
  47. !---------------------------------------------------------------------------------------------------
  48. subroutine Agrif_MPI_Init ( comm )
  49. !---------------------------------------------------------------------------------------------------
  50. integer, optional, intent(in) :: comm !< MPI communicator to be attached to the root grid.
  51. !
  52. include 'mpif.h'
  53. integer :: code, ierr
  54. logical :: mpi_was_called
  55. integer :: current_mpi_prec
  56. !
  57. call MPI_INITIALIZED( mpi_was_called, code )
  58. if( code /= MPI_SUCCESS ) then
  59. write(*,*) ': Error in routine mpi_initialized'
  60. call MPI_ABORT( MPI_COMM_WORLD, code, ierr )
  61. endif
  62. if( .not. mpi_was_called ) then
  63. write(*,*) '### AGRIF Error : you should call Agrif_MPI_Init *after* MPI_Init.'
  64. stop
  65. endif
  66. current_mpi_prec = KIND(1.0)
  67. if (current_mpi_prec == 4) then
  68. Agrif_MPI_prec = MPI_REAL4
  69. else
  70. Agrif_MPI_prec = MPI_REAL8
  71. endif
  72. !
  73. if ( present(comm) ) then
  74. call Agrif_MPI_switch_comm(comm)
  75. else
  76. call Agrif_MPI_switch_comm(MPI_COMM_WORLD)
  77. endif
  78. !
  79. Agrif_Mygrid % communicator = Agrif_mpi_comm
  80. !
  81. if ( Agrif_Parallel_sisters ) then
  82. call Agrif_Init_ProcList( Agrif_Mygrid % proc_def_list, Agrif_Nbprocs )
  83. call Agrif_pl_copy( Agrif_Mygrid % proc_def_list, Agrif_Mygrid % required_proc_list )
  84. endif
  85. !---------------------------------------------------------------------------------------------------
  86. end subroutine Agrif_MPI_Init
  87. !===================================================================================================
  88. !
  89. !===================================================================================================
  90. subroutine Agrif_MPI_switch_comm ( comm )
  91. !---------------------------------------------------------------------------------------------------
  92. integer, intent(in) :: comm !< MPI communicator you want to switch to.
  93. !
  94. include 'mpif.h'
  95. integer :: code
  96. logical :: mpi_was_called
  97. !
  98. call MPI_INITIALIZED( mpi_was_called, code )
  99. if ( .not. mpi_was_called ) return
  100. !
  101. call MPI_COMM_SIZE(comm, Agrif_Nbprocs, code)
  102. call MPI_COMM_RANK(comm, Agrif_ProcRank, code)
  103. Agrif_mpi_comm = comm
  104. !---------------------------------------------------------------------------------------------------
  105. end subroutine Agrif_MPI_switch_comm
  106. !===================================================================================================
  107. !
  108. !===================================================================================================
  109. function Agrif_MPI_get_grid_comm ( ) result ( comm )
  110. !---------------------------------------------------------------------------------------------------
  111. integer :: comm
  112. comm = Agrif_Curgrid % communicator
  113. !---------------------------------------------------------------------------------------------------
  114. end function Agrif_MPI_get_grid_comm
  115. !===================================================================================================
  116. !
  117. !===================================================================================================
  118. subroutine Agrif_MPI_set_grid_comm ( comm )
  119. !---------------------------------------------------------------------------------------------------
  120. integer, intent(in) :: comm
  121. Agrif_Curgrid % communicator = comm
  122. !---------------------------------------------------------------------------------------------------
  123. end subroutine Agrif_MPI_set_grid_comm
  124. !===================================================================================================
  125. !
  126. !===================================================================================================
  127. subroutine Agrif_Init_ProcList ( proclist, nbprocs )
  128. !---------------------------------------------------------------------------------------------------
  129. type(Agrif_Proc_List), intent(inout) :: proclist
  130. integer, intent(in) :: nbprocs
  131. !
  132. include 'mpif.h'
  133. type(Agrif_Proc), pointer :: new_proc
  134. integer :: p, ierr
  135. integer :: imin, imax, jmin, jmax
  136. integer, dimension(5) :: local_proc_grid_info
  137. integer, dimension(5,nbprocs) :: all_procs_grid_info
  138. !
  139. call Agrif_get_proc_info(imin, imax, jmin, jmax)
  140. !
  141. local_proc_grid_info(:) = (/Agrif_Procrank, imin, jmin, imax, jmax/)
  142. !
  143. call MPI_ALLGATHER(local_proc_grid_info, 5, MPI_INTEGER, &
  144. all_procs_grid_info, 5, MPI_INTEGER, Agrif_mpi_comm, ierr)
  145. !
  146. do p = 1,nbprocs
  147. !
  148. allocate(new_proc)
  149. new_proc % pn = all_procs_grid_info(1,p)
  150. new_proc % imin(1) = all_procs_grid_info(2,p)
  151. new_proc % imin(2) = all_procs_grid_info(3,p)
  152. new_proc % imax(1) = all_procs_grid_info(4,p)
  153. new_proc % imax(2) = all_procs_grid_info(5,p)
  154. call Agrif_pl_append( proclist, new_proc )
  155. !
  156. enddo
  157. !
  158. !---------------------------------------------------------------------------------------------------
  159. end subroutine Agrif_Init_ProcList
  160. !===================================================================================================
  161. !
  162. !===================================================================================================
  163. ! subroutine Get_External_Data_first
  164. !---------------------------------------------------------------------------------------------------
  165. subroutine Get_External_Data_first ( pttruetab, cetruetab, pttruetabwhole, cetruetabwhole, &
  166. nbdim, memberoutall, coords, sendtoproc, recvfromproc, &
  167. imin, imax, imin_recv, imax_recv )
  168. !---------------------------------------------------------------------------------------------------
  169. include 'mpif.h'
  170. !
  171. integer, intent(in) :: nbdim
  172. integer, dimension(nbdim,0:Agrif_NbProcs-1), intent(in) :: pttruetab, cetruetab
  173. integer, dimension(nbdim,0:Agrif_NbProcs-1), intent(in) :: pttruetabwhole,cetruetabwhole
  174. logical, dimension(0:Agrif_Nbprocs-1), intent(in) :: memberoutall
  175. integer, dimension(nbdim), intent(in) :: coords
  176. logical, dimension(0:Agrif_Nbprocs-1), intent(out) :: sendtoproc
  177. logical, dimension(0:Agrif_Nbprocs-1), intent(out) :: recvfromproc
  178. integer, dimension(nbdim,0:Agrif_NbProcs-1), intent(out) :: imin,imax
  179. integer, dimension(nbdim,0:Agrif_NbProcs-1), intent(out) :: imin_recv,imax_recv
  180. !
  181. integer :: imintmp, imaxtmp, i, j, k, i1
  182. integer :: imin1,imax1
  183. logical :: tochange,tochangebis
  184. integer, dimension(nbdim,0:Agrif_NbProcs-1) :: pttruetab2,cetruetab2
  185. !
  186. ! pttruetab2 and cetruetab2 are modified arrays in order to always
  187. ! send the most inner points
  188. !
  189. pttruetab2(:,Agrif_Procrank) = pttruetab(:,Agrif_Procrank)
  190. cetruetab2(:,Agrif_Procrank) = cetruetab(:,Agrif_Procrank)
  191. !
  192. do k = 0,Agrif_Nbprocs-1
  193. do i = 1,nbdim
  194. tochangebis = .TRUE.
  195. DO i1 = 1,nbdim
  196. IF (i /= i1) THEN
  197. IF ( (pttruetab(i1,Agrif_Procrank) /= pttruetab(i1,k)) .OR. &
  198. (cetruetab(i1,Agrif_Procrank) /= cetruetab(i1,k))) THEN
  199. tochangebis = .FALSE.
  200. EXIT
  201. ENDIF
  202. ENDIF
  203. ENDDO
  204. IF (tochangebis) THEN
  205. imin1 = max(pttruetab(i,Agrif_Procrank), pttruetab(i,k))
  206. imax1 = min(cetruetab(i,Agrif_Procrank), cetruetab(i,k))
  207. ! Always send the most interior points
  208. tochange = .false.
  209. IF (cetruetab(i,Agrif_Procrank) > cetruetab(i,k)) THEN
  210. DO j=imin1,imax1
  211. IF ((cetruetab(i,k)-j) > (j-pttruetab(i,Agrif_Procrank))) THEN
  212. imintmp = j+1
  213. tochange = .TRUE.
  214. ELSE
  215. EXIT
  216. ENDIF
  217. ENDDO
  218. ENDIF
  219. if (tochange) then
  220. pttruetab2(i,Agrif_Procrank) = imintmp
  221. endif
  222. tochange = .FALSE.
  223. imaxtmp=0
  224. IF (pttruetab(i,Agrif_Procrank) < pttruetab(i,k)) THEN
  225. DO j=imax1,imin1,-1
  226. IF ((j-pttruetab(i,k)) > (cetruetab(i,Agrif_Procrank)-j)) THEN
  227. imaxtmp = j-1
  228. tochange = .TRUE.
  229. ELSE
  230. EXIT
  231. ENDIF
  232. ENDDO
  233. ENDIF
  234. if (tochange) then
  235. cetruetab2(i,Agrif_Procrank) = imaxtmp
  236. endif
  237. ENDIF
  238. enddo
  239. enddo
  240. do k = 0,Agrif_NbProcs-1
  241. !
  242. sendtoproc(k) = .true.
  243. !
  244. !CDIR SHORTLOOP
  245. do i = 1,nbdim
  246. imin(i,k) = max(pttruetab2(i,Agrif_Procrank), pttruetabwhole(i,k))
  247. imax(i,k) = min(cetruetab2(i,Agrif_Procrank), cetruetabwhole(i,k))
  248. !
  249. if ( (imin(i,k) > imax(i,k)) .and. (coords(i) /= 0) ) then
  250. sendtoproc(k) = .false.
  251. endif
  252. enddo
  253. IF ( .not. memberoutall(k) ) THEN
  254. sendtoproc(k) = .false.
  255. ENDIF
  256. enddo
  257. !
  258. call Exchangesamelevel_first(sendtoproc,nbdim,imin,imax,recvfromproc,imin_recv,imax_recv)
  259. !---------------------------------------------------------------------------------------------------
  260. end subroutine Get_External_Data_first
  261. !===================================================================================================
  262. !
  263. !===================================================================================================
  264. ! subroutine ExchangeSameLevel_first
  265. !---------------------------------------------------------------------------------------------------
  266. subroutine ExchangeSameLevel_first ( sendtoproc, nbdim, imin, imax, recvfromproc, &
  267. imin_recv, imax_recv )
  268. !---------------------------------------------------------------------------------------------------
  269. LOGICAL, DIMENSION(0:Agrif_Nbprocs-1), intent(in) :: sendtoproc
  270. INTEGER, intent(in) :: nbdim
  271. INTEGER, DIMENSION(nbdim,0:Agrif_Nbprocs-1), intent(in) :: imin
  272. INTEGER, DIMENSION(nbdim,0:Agrif_Nbprocs-1), intent(in) :: imax
  273. LOGICAL, DIMENSION(0:Agrif_Nbprocs-1), intent(out) :: recvfromproc
  274. INTEGER, DIMENSION(nbdim,0:Agrif_Nbprocs-1), intent(out) :: imin_recv
  275. INTEGER, DIMENSION(nbdim,0:Agrif_Nbprocs-1), intent(out) :: imax_recv
  276. !
  277. include 'mpif.h'
  278. INTEGER :: k
  279. INTEGER :: etiquette = 100
  280. INTEGER :: code
  281. LOGICAL :: res
  282. INTEGER, DIMENSION(MPI_STATUS_SIZE) :: statut
  283. INTEGER, DIMENSION(nbdim,2,0:Agrif_Nbprocs-1) :: iminmax_temp
  284. do k = 0,Agrif_ProcRank-1
  285. !
  286. call MPI_SEND(sendtoproc(k),1,MPI_LOGICAL,k,etiquette,Agrif_mpi_comm,code)
  287. !
  288. if (sendtoproc(k)) then
  289. iminmax_temp(:,1,k) = imin(:,k)
  290. iminmax_temp(:,2,k) = imax(:,k)
  291. call MPI_SEND(iminmax_temp(:,:,k),2*nbdim,MPI_INTEGER,k,etiquette,Agrif_mpi_comm,code)
  292. endif
  293. !
  294. enddo
  295. !
  296. ! Reception from others processors of the necessary part of the parent grid
  297. do k = Agrif_ProcRank+1,Agrif_Nbprocs-1
  298. !
  299. call MPI_RECV(res,1,MPI_LOGICAL,k,etiquette,Agrif_mpi_comm,statut,code)
  300. recvfromproc(k) = res
  301. !
  302. if (recvfromproc(k)) then
  303. call MPI_RECV(iminmax_temp(:,:,k),2*nbdim,MPI_INTEGER,k,etiquette, &
  304. Agrif_mpi_comm,statut,code)
  305. imin_recv(:,k) = iminmax_temp(:,1,k)
  306. imax_recv(:,k) = iminmax_temp(:,2,k)
  307. endif
  308. !
  309. enddo
  310. ! Reception from others processors of the necessary part of the parent grid
  311. do k = Agrif_ProcRank+1,Agrif_Nbprocs-1
  312. !
  313. call MPI_SEND(sendtoproc(k),1,MPI_LOGICAL,k,etiquette,Agrif_mpi_comm,code)
  314. !
  315. if (sendtoproc(k)) then
  316. !
  317. iminmax_temp(:,1,k) = imin(:,k)
  318. iminmax_temp(:,2,k) = imax(:,k)
  319. call MPI_SEND(iminmax_temp(:,:,k),2*nbdim,MPI_INTEGER,k,etiquette, &
  320. Agrif_mpi_comm,code)
  321. endif
  322. !
  323. enddo
  324. !
  325. !
  326. ! Reception from others processors of the necessary part of the parent grid
  327. do k = Agrif_ProcRank-1,0,-1
  328. !
  329. call MPI_RECV(res,1,MPI_LOGICAL,k,etiquette,Agrif_mpi_comm,statut,code)
  330. recvfromproc(k) = res
  331. !
  332. if (recvfromproc(k)) then
  333. !
  334. call MPI_RECV(iminmax_temp(:,:,k),2*nbdim,MPI_INTEGER,k,etiquette, &
  335. Agrif_mpi_comm,statut,code)
  336. imin_recv(:,k) = iminmax_temp(:,1,k)
  337. imax_recv(:,k) = iminmax_temp(:,2,k)
  338. endif
  339. !
  340. enddo
  341. !---------------------------------------------------------------------------------------------------
  342. end subroutine ExchangeSamelevel_first
  343. !===================================================================================================
  344. !
  345. !===================================================================================================
  346. ! subroutine ExchangeSameLevel
  347. !---------------------------------------------------------------------------------------------------
  348. subroutine ExchangeSameLevel ( sendtoproc, recvfromproc, nbdim, &
  349. pttruetabwhole, cetruetabwhole, &
  350. imin, imax, imin_recv, imax_recv, &
  351. memberout, tempC, tempCextend )
  352. !---------------------------------------------------------------------------------------------------
  353. LOGICAL, DIMENSION(0:Agrif_Nbprocs-1), intent(in) :: sendtoproc
  354. LOGICAL, DIMENSION(0:Agrif_Nbprocs-1), intent(in) :: recvfromproc
  355. INTEGER, intent(in) :: nbdim
  356. INTEGER, DIMENSION(nbdim,0:Agrif_Nbprocs-1), intent(in) :: pttruetabwhole
  357. INTEGER, DIMENSION(nbdim,0:Agrif_Nbprocs-1), intent(in) :: cetruetabwhole
  358. INTEGER, DIMENSION(nbdim,0:Agrif_Nbprocs-1), intent(in) :: imin, imax
  359. INTEGER, DIMENSION(nbdim,0:Agrif_Nbprocs-1), intent(in) :: imin_recv, imax_recv
  360. LOGICAL, intent(in) :: memberout
  361. TYPE(Agrif_Variable), pointer, intent(inout) :: tempC, tempCextend
  362. !
  363. include 'mpif.h'
  364. INTEGER :: i,k
  365. INTEGER :: etiquette = 100
  366. INTEGER :: code, datasize
  367. INTEGER, DIMENSION(MPI_STATUS_SIZE) :: statut
  368. TYPE(Agrif_Variable), pointer, SAVE :: temprecv
  369. !
  370. IF (memberout) THEN
  371. call Agrif_array_allocate(tempCextend, pttruetabwhole(:,Agrif_ProcRank), &
  372. cetruetabwhole(:,Agrif_ProcRank),nbdim)
  373. call Agrif_var_set_array_tozero(tempCextend,nbdim)
  374. ENDIF
  375. !
  376. IF (sendtoproc(Agrif_ProcRank)) THEN
  377. call Agrif_var_copy_array(tempCextend,imin(:,Agrif_Procrank),imax(:,Agrif_Procrank), &
  378. tempC, imin(:,Agrif_Procrank),imax(:,Agrif_Procrank), &
  379. nbdim)
  380. ENDIF
  381. !
  382. do k = 0,Agrif_ProcRank-1
  383. !
  384. if (sendtoproc(k)) then
  385. !
  386. datasize = 1
  387. !
  388. !CDIR SHORTLOOP
  389. do i = 1,nbdim
  390. datasize = datasize * (imax(i,k)-imin(i,k)+1)
  391. enddo
  392. !
  393. SELECT CASE(nbdim)
  394. CASE(1)
  395. call MPI_SEND(tempC%array1(imin(1,k):imax(1,k)), &
  396. datasize,Agrif_MPI_prec,k,etiquette, &
  397. Agrif_mpi_comm,code)
  398. CASE(2)
  399. call MPI_SEND(tempC%array2(imin(1,k):imax(1,k), &
  400. imin(2,k):imax(2,k)), &
  401. datasize,Agrif_MPI_prec,k,etiquette, &
  402. Agrif_mpi_comm,code)
  403. CASE(3)
  404. call Agrif_Send_3Darray(tempC%array3,lbound(tempC%array3),imin(:,k),imax(:,k),k)
  405. CASE(4)
  406. call MPI_SEND(tempC%array4(imin(1,k):imax(1,k), &
  407. imin(2,k):imax(2,k), &
  408. imin(3,k):imax(3,k), &
  409. imin(4,k):imax(4,k)), &
  410. datasize,Agrif_MPI_prec,k,etiquette, &
  411. Agrif_mpi_comm,code)
  412. CASE(5)
  413. call MPI_SEND(tempC%array5(imin(1,k):imax(1,k), &
  414. imin(2,k):imax(2,k), &
  415. imin(3,k):imax(3,k), &
  416. imin(4,k):imax(4,k), &
  417. imin(5,k):imax(5,k)), &
  418. datasize,Agrif_MPI_prec,k,etiquette, &
  419. Agrif_mpi_comm,code)
  420. CASE(6)
  421. call MPI_SEND(tempC%array6(imin(1,k):imax(1,k), &
  422. imin(2,k):imax(2,k), &
  423. imin(3,k):imax(3,k), &
  424. imin(4,k):imax(4,k), &
  425. imin(5,k):imax(5,k), &
  426. imin(6,k):imax(6,k)), &
  427. datasize,Agrif_MPI_prec,k,etiquette, &
  428. Agrif_mpi_comm,code)
  429. END SELECT
  430. !
  431. endif
  432. enddo
  433. !
  434. ! Reception from others processors of the necessary part of the parent grid
  435. do k = Agrif_ProcRank+1,Agrif_Nbprocs-1
  436. !
  437. if (recvfromproc(k)) then
  438. !
  439. datasize = 1
  440. !
  441. !CDIR SHORTLOOP
  442. do i = 1,nbdim
  443. datasize = datasize * (imax_recv(i,k)-imin_recv(i,k)+1)
  444. enddo
  445. if (.not.associated(temprecv)) allocate(temprecv)
  446. call Agrif_array_allocate(temprecv,imin_recv(:,k),imax_recv(:,k),nbdim)
  447. SELECT CASE(nbdim)
  448. CASE(1)
  449. call MPI_RECV(temprecv%array1,datasize,Agrif_MPI_prec,k,etiquette, &
  450. Agrif_mpi_comm,statut,code)
  451. CASE(2)
  452. call MPI_RECV(temprecv%array2,datasize,Agrif_MPI_prec,k,etiquette, &
  453. Agrif_mpi_comm,statut,code)
  454. CASE(3)
  455. call MPI_RECV(temprecv%array3,datasize,Agrif_MPI_prec,k,etiquette, &
  456. Agrif_mpi_comm,statut,code)
  457. CASE(4)
  458. call MPI_RECV(temprecv%array4,datasize,Agrif_MPI_prec,k,etiquette, &
  459. Agrif_mpi_comm,statut,code)
  460. CASE(5)
  461. call MPI_RECV(temprecv%array5,datasize,Agrif_MPI_prec,k,etiquette, &
  462. Agrif_mpi_comm,statut,code)
  463. CASE(6)
  464. call MPI_RECV(temprecv%array6,datasize,Agrif_MPI_prec,k,etiquette, &
  465. Agrif_mpi_comm,statut,code)
  466. END SELECT
  467. call Agrif_var_replace_value(tempCextend,temprecv,imin_recv(:,k),imax_recv(:,k),0.,nbdim)
  468. call Agrif_array_deallocate(temprecv,nbdim)
  469. !
  470. endif
  471. enddo
  472. ! Reception from others processors of the necessary part of the parent grid
  473. do k = Agrif_ProcRank+1,Agrif_Nbprocs-1
  474. !
  475. if (sendtoproc(k)) then
  476. !
  477. SELECT CASE(nbdim)
  478. CASE(1)
  479. datasize=SIZE(tempC%array1(imin(1,k):imax(1,k)))
  480. call MPI_SEND(tempC%array1(imin(1,k):imax(1,k)), &
  481. datasize,Agrif_MPI_prec,k,etiquette, &
  482. Agrif_mpi_comm,code)
  483. CASE(2)
  484. datasize=SIZE(tempC%array2(imin(1,k):imax(1,k), &
  485. imin(2,k):imax(2,k)))
  486. call MPI_SEND(tempC%array2(imin(1,k):imax(1,k), &
  487. imin(2,k):imax(2,k)), &
  488. datasize,Agrif_MPI_prec,k,etiquette, &
  489. Agrif_mpi_comm,code)
  490. CASE(3)
  491. datasize=SIZE(tempC%array3(imin(1,k):imax(1,k), &
  492. imin(2,k):imax(2,k), &
  493. imin(3,k):imax(3,k)))
  494. call MPI_SEND(tempC%array3(imin(1,k):imax(1,k), &
  495. imin(2,k):imax(2,k), &
  496. imin(3,k):imax(3,k)), &
  497. datasize,Agrif_MPI_prec,k,etiquette, &
  498. Agrif_mpi_comm,code)
  499. CASE(4)
  500. datasize=SIZE(tempC%array4(imin(1,k):imax(1,k), &
  501. imin(2,k):imax(2,k), &
  502. imin(3,k):imax(3,k), &
  503. imin(4,k):imax(4,k)))
  504. call MPI_SEND(tempC%array4(imin(1,k):imax(1,k), &
  505. imin(2,k):imax(2,k), &
  506. imin(3,k):imax(3,k), &
  507. imin(4,k):imax(4,k)), &
  508. datasize,Agrif_MPI_prec,k,etiquette, &
  509. Agrif_mpi_comm,code)
  510. CASE(5)
  511. datasize=SIZE(tempC%array5(imin(1,k):imax(1,k), &
  512. imin(2,k):imax(2,k), &
  513. imin(3,k):imax(3,k), &
  514. imin(4,k):imax(4,k), &
  515. imin(5,k):imax(5,k)))
  516. call MPI_SEND(tempC%array5(imin(1,k):imax(1,k), &
  517. imin(2,k):imax(2,k), &
  518. imin(3,k):imax(3,k), &
  519. imin(4,k):imax(4,k), &
  520. imin(5,k):imax(5,k)), &
  521. datasize,Agrif_MPI_prec,k,etiquette, &
  522. Agrif_mpi_comm,code)
  523. CASE(6)
  524. datasize=SIZE(tempC%array6(imin(1,k):imax(1,k), &
  525. imin(2,k):imax(2,k), &
  526. imin(3,k):imax(3,k), &
  527. imin(4,k):imax(4,k), &
  528. imin(5,k):imax(5,k), &
  529. imin(6,k):imax(6,k)))
  530. call MPI_SEND(tempC%array6(imin(1,k):imax(1,k), &
  531. imin(2,k):imax(2,k), &
  532. imin(3,k):imax(3,k), &
  533. imin(4,k):imax(4,k), &
  534. imin(5,k):imax(5,k), &
  535. imin(6,k):imax(6,k)), &
  536. datasize,Agrif_MPI_prec,k,etiquette, &
  537. Agrif_mpi_comm,code)
  538. END SELECT
  539. !
  540. endif
  541. !
  542. enddo
  543. !
  544. ! Reception from others processors of the necessary part of the parent grid
  545. do k = Agrif_ProcRank-1,0,-1
  546. !
  547. if (recvfromproc(k)) then
  548. !
  549. if (.not.associated(temprecv)) allocate(temprecv)
  550. call Agrif_array_allocate(temprecv,imin_recv(:,k),imax_recv(:,k),nbdim)
  551. SELECT CASE(nbdim)
  552. CASE(1)
  553. datasize=SIZE(temprecv%array1)
  554. call MPI_RECV(temprecv%array1,datasize,Agrif_MPI_prec,k,etiquette,&
  555. Agrif_mpi_comm,statut,code)
  556. CASE(2)
  557. datasize=SIZE(temprecv%array2)
  558. call MPI_RECV(temprecv%array2,datasize,Agrif_MPI_prec,k,etiquette,&
  559. Agrif_mpi_comm,statut,code)
  560. CASE(3)
  561. datasize=SIZE(temprecv%array3)
  562. call MPI_RECV(temprecv%array3,datasize,Agrif_MPI_prec,k,etiquette,&
  563. Agrif_mpi_comm,statut,code)
  564. CASE(4)
  565. datasize=SIZE(temprecv%array4)
  566. call MPI_RECV(temprecv%array4,datasize,Agrif_MPI_prec,k,etiquette,&
  567. Agrif_mpi_comm,statut,code)
  568. CASE(5)
  569. datasize=SIZE(temprecv%array5)
  570. call MPI_RECV(temprecv%array5,datasize,Agrif_MPI_prec,k,etiquette,&
  571. Agrif_mpi_comm,statut,code)
  572. CASE(6)
  573. datasize=SIZE(temprecv%array6)
  574. call MPI_RECV(temprecv%array6,datasize,Agrif_MPI_prec,k,etiquette,&
  575. Agrif_mpi_comm,statut,code)
  576. END SELECT
  577. call Agrif_var_replace_value(tempCextend,temprecv,imin_recv(:,k),imax_recv(:,k),0.,nbdim)
  578. call Agrif_array_deallocate(temprecv,nbdim)
  579. !
  580. endif
  581. !
  582. enddo
  583. !---------------------------------------------------------------------------------------------------
  584. end subroutine ExchangeSamelevel
  585. !===================================================================================================
  586. !
  587. !===================================================================================================
  588. ! subroutine Agrif_Send_3Darray
  589. !---------------------------------------------------------------------------------------------------
  590. subroutine Agrif_Send_3Darray ( tab3D, bounds, imin, imax, k )
  591. !---------------------------------------------------------------------------------------------------
  592. integer, dimension(3), intent(in) :: bounds
  593. real, dimension(bounds(1):,bounds(2):,bounds(3):), target, intent(in) :: tab3D
  594. integer, dimension(3), intent(in) :: imin, imax
  595. integer, intent(in) :: k
  596. !
  597. integer :: etiquette = 100
  598. integer :: datasize, code
  599. include 'mpif.h'
  600. datasize = SIZE(tab3D(imin(1):imax(1), &
  601. imin(2):imax(2), &
  602. imin(3):imax(3)))
  603. call MPI_SEND( tab3D( imin(1):imax(1), &
  604. imin(2):imax(2), &
  605. imin(3):imax(3)), &
  606. datasize,Agrif_MPI_prec,k,etiquette,Agrif_mpi_comm,code)
  607. !---------------------------------------------------------------------------------------------------
  608. end subroutine Agrif_Send_3Darray
  609. !===================================================================================================
  610. !
  611. #else
  612. subroutine dummy_Agrif_Mpp ()
  613. end subroutine dummy_Agrif_Mpp
  614. #endif
  615. !
  616. end Module Agrif_Mpp