m_GeneralGridComms.F90 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536
  1. !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2. ! Math and Computer Science Division, Argonne National Laboratory !
  3. !-----------------------------------------------------------------------
  4. ! CVS m_GeneralGridComms.F90,v 1.23 2004-04-21 22:16:33 jacob Exp
  5. ! CVS MCT_2_8_0
  6. !BOP -------------------------------------------------------------------
  7. !
  8. ! !MODULE: m_GeneralGridComms - Communications for the GeneralGrid type.
  9. !
  10. ! !DESCRIPTION:
  11. !
  12. ! In this module, we define communications methods specific to the
  13. ! {\tt GeneralGrid} class (see the module {\tt m\_GeneralGrid} for more
  14. ! information about this class and its methods).
  15. !
  16. ! !INTERFACE:
  17. module m_GeneralGridComms
  18. !
  19. ! !USES:
  20. !
  21. use m_GeneralGrid ! GeneralGrid class and its methods
  22. implicit none
  23. private ! except
  24. public :: gather ! gather all local vectors to the root
  25. public :: scatter ! scatter from the root to all PEs
  26. public :: bcast ! bcast from root to all PEs
  27. public :: send ! Blocking SEND
  28. public :: recv ! Blocking RECEIVE
  29. interface gather ; module procedure &
  30. GM_gather_, &
  31. GSM_gather_
  32. end interface
  33. interface scatter ; module procedure &
  34. GM_scatter_, &
  35. GSM_scatter_
  36. end interface
  37. interface bcast ; module procedure bcast_ ; end interface
  38. interface send ; module procedure send_ ; end interface
  39. interface recv ; module procedure recv_ ; end interface
  40. ! !REVISION HISTORY:
  41. ! 27Apr01 - J.W. Larson <larson@mcs.anl.gov> - Initial module/APIs
  42. ! 07Jun01 - J.W. Larson <larson@mcs.anl.gov> - Added point-to-point
  43. ! 27Mar02 - J.W. Larson <larson@mcs.anl.gov> - Overhaul of error
  44. ! handling calls throughout this module.
  45. ! 05Aug02 - E. Ong <eong@mcs.anl.gov> - Added buffer association
  46. ! error checks to avoid making bad MPI calls
  47. !EOP ___________________________________________________________________
  48. character(len=*),parameter :: myname='MCT::m_GeneralGridComms'
  49. contains
  50. !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  51. ! Math and Computer Science Division, Argonne National Laboratory !
  52. !BOP -------------------------------------------------------------------
  53. !
  54. ! !IROUTINE: send_ - Point-to-point blocking send for the GeneralGrid.
  55. !
  56. ! !DESCRIPTION: The point-to-point send routine {\tt send\_()} sends
  57. ! the input {\tt GeneralGrid} argument {\tt iGGrid} to component
  58. ! {\tt comp\_id}.
  59. ! The message is identified by the tag defined by the {\tt INTEGER}
  60. ! argument {\tt TagBase}. The value of {\tt TagBase} must match the
  61. ! value used in the call to {\tt recv\_()} on process {\tt dest}. The
  62. ! success (failure) of this operation corresponds to a zero (nonzero)
  63. ! value for the output {\tt INTEGER} flag {\tt status}.
  64. ! The argument will be sent to the local root of the component.
  65. !
  66. ! {\bf N.B.}: One must avoid assigning elsewhere the MPI tag values
  67. ! between {\tt TagBase} and {\tt TagBase+20}, inclusive. This is
  68. ! because {\tt send\_()} performs one send operation set up the header
  69. ! transfer, up to five {\tt List\_send} operations (two {\tt MPI\_SEND}
  70. ! calls in each), two send operations to transfer {\tt iGGrid\%descend(:)},
  71. ! and finally the send of the {\tt AttrVect} component {\tt iGGrid\%data}
  72. ! (which comprises eight {\tt MPI\_SEND} operations).
  73. !
  74. ! !INTERFACE:
  75. subroutine send_(iGGrid, comp_id, TagBase, status)
  76. !
  77. ! !USES:
  78. !
  79. use m_stdio
  80. use m_die
  81. use m_mpif90
  82. use m_GeneralGrid, only : GeneralGrid
  83. use m_GeneralGrid, only : GeneralGrid_init => init
  84. use m_GeneralGrid, only : GeneralGrid_lsize => lsize
  85. use m_MCTWorld, only : ComponentToWorldRank
  86. use m_MCTWorld, only : ThisMCTWorld
  87. use m_AttrVectComms,only : AttrVect_send => send
  88. use m_List, only : List_send => send
  89. use m_List, only : List_allocated => allocated
  90. implicit none
  91. ! !INPUT PARAMETERS:
  92. !
  93. type(GeneralGrid), intent(in) :: iGGrid
  94. integer, intent(in) :: comp_id
  95. integer, intent(in) :: TagBase
  96. ! !OUTPUT PARAMETERS:
  97. !
  98. integer, optional, intent(out) :: status
  99. ! !REVISION HISTORY:
  100. ! 04Jun01 - J.W. Larson <larson@mcs.anl.gov> - API Specification.
  101. ! 07Jun01 - J.W. Larson <larson@mcs.anl.gov> - Initial version.
  102. ! 10Jun01 - J.W. Larson <larson@mcs.anl.gov> - Bug fixes--now works.
  103. ! 11Jun01 - R. Jacob <jacob@mcs.anl.gov> use component id as input
  104. ! argument.
  105. ! 13Jun01 - J.W. Larson <larson@mcs.anl.gov> - Initialize status
  106. ! (if present).
  107. ! 15Feb02 - J.W. Larson <larson@mcs.anl.gov> - Made input argument
  108. ! comm optional.
  109. ! 13Jun02 - J.W. Larson <larson@mcs.anl.gov> - Removed the argument
  110. ! comm. This routine is now explicitly for intercomponent
  111. ! communications only.
  112. !EOP ___________________________________________________________________
  113. character(len=*),parameter :: myname_=myname//'::send_'
  114. integer :: ierr
  115. integer :: dest
  116. logical :: HeaderAssoc(6)
  117. ! Initialize status (if present)
  118. if(present(status)) status = 0
  119. dest = ComponentToWorldRank(0, comp_id, ThisMCTWorld)
  120. ! Step 1. Check elements of the GeneralGrid header to see
  121. ! which components of it are allocated. Load the results
  122. ! into HeaderAssoc(:), and send it to process dest.
  123. HeaderAssoc(1) = List_allocated(iGGrid%coordinate_list)
  124. HeaderAssoc(2) = List_allocated(iGGrid%coordinate_sort_order)
  125. HeaderAssoc(3) = associated(iGGrid%descend)
  126. HeaderAssoc(4) = List_allocated(iGGrid%weight_list)
  127. HeaderAssoc(5) = List_allocated(iGGrid%other_list)
  128. HeaderAssoc(6) = List_allocated(iGGrid%index_list)
  129. call MPI_SEND(HeaderAssoc, 6, MP_LOGICAL, dest, TagBase, ThisMCTWorld%MCT_comm, ierr)
  130. if(ierr /= 0) then
  131. call MP_perr_die(myname_,':: MPI_SEND(HeaderAssoc...',ierr)
  132. endif
  133. ! Step 2. If iGGrid%coordinate_list is defined, send it.
  134. if(HeaderAssoc(1)) then
  135. call List_send(iGGrid%coordinate_list, dest, TagBase+1, ThisMCTWorld%MCT_comm, ierr)
  136. if(ierr /= 0) then
  137. write(stderr,*) myname_,':: call List_send(iGGrid%coordinate_list...', &
  138. 'Error flag ierr = ',ierr
  139. if(present(status)) then
  140. status = ierr
  141. return
  142. else
  143. call die(myname_,':: call List_send(iGGrid%coordinate_list...',ierr)
  144. endif
  145. endif
  146. else ! This constitutes an error, as a GeneralGrid must have coordinates
  147. if(present(status)) then
  148. write(stderr,*) myname_,':: Error. GeneralGrid%coordinate_list undefined.'
  149. status = -1
  150. return
  151. else
  152. call die(myname_,':: Error. GeneralGrid%coordinate_list undefined.',-1)
  153. endif
  154. endif ! if(HeaderAssoc(1))...
  155. ! Step 3. If iGGrid%coordinate_sort_order is defined, send it.
  156. if(HeaderAssoc(2)) then
  157. call List_send(iGGrid%coordinate_sort_order, dest, TagBase+3, ThisMCTWorld%MCT_comm, ierr)
  158. if(ierr /= 0) then
  159. if(present(status)) then
  160. write(stderr,*) myname_,':: call List_send(iGGrid%coordinate_sort_order...'
  161. status = ierr
  162. return
  163. else
  164. call die(myname_,':: call List_send(iGGrid%coordinate_sort_order...',ierr)
  165. endif
  166. endif
  167. endif ! if(HeaderAssoc(2))...
  168. ! Step 4. If iGGrid%descend is allocated, determine its size,
  169. ! send this size, and then send the elements of iGGrid%descend.
  170. if(HeaderAssoc(3)) then
  171. if(size(iGGrid%descend)<=0) call die(myname_,'size(iGGrid%descend)<=0')
  172. call MPI_SEND(size(iGGrid%descend), 1, MP_type(size(iGGrid%descend)), &
  173. dest, TagBase+5, ThisMCTWorld%MCT_comm, ierr)
  174. if(ierr /= 0) then
  175. call MP_perr_die(myname_,':: call MPI_SEND(size(iGGrid%descend)...',ierr)
  176. endif
  177. call MPI_SEND(iGGrid%descend, size(iGGrid%descend), MP_type(iGGrid%descend(1)), &
  178. dest, TagBase+6, ThisMCTWorld%MCT_comm, ierr)
  179. if(ierr /= 0) then
  180. call MP_perr_die(myname_,':: call MPI_SEND(iGGrid%descend...',ierr)
  181. endif
  182. endif ! if(HeaderAssoc(3))...
  183. ! Step 5. If iGGrid%weight_list is defined, send it.
  184. if(HeaderAssoc(4)) then
  185. call List_send(iGGrid%weight_list, dest, TagBase+7, ThisMCTWorld%MCT_comm, ierr)
  186. if(ierr /= 0) then
  187. if(present(status)) then
  188. write(stderr,*) myname_,':: call List_send(iGGrid%weight_list...'
  189. status = ierr
  190. return
  191. else
  192. call die(myname_,':: call List_send(iGGrid%weight_list...',ierr)
  193. endif
  194. endif
  195. endif ! if(HeaderAssoc(4))...
  196. ! Step 6. If iGGrid%other_list is defined, send it.
  197. if(HeaderAssoc(5)) then
  198. call List_send(iGGrid%other_list, dest, TagBase+9, ThisMCTWorld%MCT_comm, ierr)
  199. if(ierr /= 0) then
  200. if(present(status)) then
  201. write(stderr,*) myname_,':: call List_send(iGGrid%other_list...'
  202. status = ierr
  203. return
  204. else
  205. call die(myname_,':: call List_send(iGGrid%other_list...',ierr)
  206. endif
  207. endif
  208. endif ! if(HeaderAssoc(5))...
  209. ! Step 7. If iGGrid%index_list is defined, send it.
  210. if(HeaderAssoc(6)) then
  211. call List_send(iGGrid%index_list, dest, TagBase+11, ThisMCTWorld%MCT_comm, ierr)
  212. if(ierr /= 0) then
  213. if(present(status)) then
  214. write(stderr,*) myname_,':: call List_send(iGGrid%index_list...'
  215. status = ierr
  216. return
  217. else
  218. call die(myname_,':: call List_send(iGGrid%index_list...',ierr)
  219. endif
  220. endif
  221. else ! This constitutes an error, as a GeneralGrid must at a minimum
  222. ! contain the index GlobGridNum
  223. if(present(status)) then
  224. write(stderr,*) myname_,':: Error. GeneralGrid%index_list undefined.'
  225. status = -2
  226. return
  227. else
  228. call die(myname_,':: Error. GeneralGrid%index_list undefined.',-2)
  229. endif
  230. endif ! if(HeaderAssoc(6))...
  231. ! Step 8. Finally, send the AttrVect iGGrid%data.
  232. call AttrVect_send(iGGrid%data, dest, TagBase+13, ThisMCTWorld%MCT_comm, ierr)
  233. if(ierr /= 0) then
  234. if(present(status)) then
  235. write(stderr,*) myname_,':: call AttrVect_send(iGGrid%data...'
  236. status = ierr
  237. return
  238. else
  239. call die(myname_,':: call AttrVect_send(iGGrid%data...',ierr)
  240. endif
  241. endif
  242. ! The GeneralGrid send is now complete.
  243. end subroutine send_
  244. !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  245. ! Math and Computer Science Division, Argonne National Laboratory !
  246. !BOP -------------------------------------------------------------------
  247. !
  248. ! !IROUTINE: recv_ - Point-to-point blocking recv for the GeneralGrid.
  249. !
  250. ! !DESCRIPTION: The point-to-point receive routine {\tt recv\_()}
  251. ! receives the output {\tt GeneralGrid} argument {\tt oGGrid} from component
  252. ! {\tt comp\_id}. The message is identified by the tag defined by the
  253. ! {\tt INTEGER} argument {\tt TagBase}. The value of {\tt TagBase} must
  254. ! match the value used in the call to {\tt send\_()} on the other component.
  255. ! The success (failure) of this operation corresponds to a zero (nonzero)
  256. ! value for the output {\tt INTEGER} flag {\tt status}.
  257. !
  258. ! {\bf N.B.}: This routine assumes that the {\tt GeneralGrid} argument
  259. ! {\tt oGGrid} is uninitialized on input; that is, all the {\tt List}
  260. ! components are blank, the {\tt LOGICAL} array {\tt oGGrid\%descend} is
  261. ! unallocated, and the {\tt AttrVect} component {\tt oGGrid\%data} is
  262. ! uninitialized. The {\tt GeneralGrid} {\tt oGGrid} represents allocated
  263. ! memory. When the user no longer needs {\tt oGGrid}, it should be
  264. ! deallocated by invoking {\tt GeneralGrid\_clean()} (see
  265. ! {\tt m\_GeneralGrid} for further details).
  266. !
  267. ! {\bf N.B.}: One must avoid assigning elsewhere the MPI tag values
  268. ! between {\tt TagBase} and {\tt TagBase+20}, inclusive. This is
  269. ! because {\tt recv\_()} performs one receive operation set up the header
  270. ! transfer, up to five {\tt List\_recv} operations (two {\tt MPI\_RECV}
  271. ! calls in each), two receive operations to transfer {\tt iGGrid\%descend(:)},
  272. ! and finally the receive of the {\tt AttrVect} component {\tt iGGrid\%data}
  273. ! (which comprises eight {\tt MPI\_RECV} operations).
  274. !
  275. ! !INTERFACE:
  276. subroutine recv_(oGGrid, comp_id, TagBase, status)
  277. !
  278. ! !USES:
  279. !
  280. use m_stdio
  281. use m_die
  282. use m_mpif90
  283. use m_GeneralGrid, only : GeneralGrid
  284. use m_GeneralGrid, only : GeneralGrid_init => init
  285. use m_GeneralGrid, only : GeneralGrid_lsize => lsize
  286. use m_MCTWorld, only : ComponentToWorldRank
  287. use m_MCTWorld, only : ThisMCTWorld
  288. use m_AttrVectComms,only : AttrVect_recv => recv
  289. use m_List,only : List_recv => recv
  290. use m_List,only : List_nullify => nullify
  291. implicit none
  292. ! !INPUT PARAMETERS:
  293. !
  294. integer, intent(in) :: comp_id
  295. integer, intent(in) :: TagBase
  296. ! !OUTPUT PARAMETERS:
  297. !
  298. type(GeneralGrid), intent(out) :: oGGrid
  299. integer, optional, intent(out) :: status
  300. ! !REVISION HISTORY:
  301. ! 04Jun01 - J.W. Larson <larson@mcs.anl.gov> - API Specification.
  302. ! 07Jun01 - J.W. Larson <larson@mcs.anl.gov> - Initial version.
  303. ! 10Jun01 - J.W. Larson <larson@mcs.anl.gov> - Bug fixes--now works.
  304. ! 11Jun01 - R. Jacob <jacob@mcs.anl.gov> use component id as input
  305. ! argument.
  306. ! 13Jun01 - J.W. Larson <larson@mcs.anl.gov> - Initialize status
  307. ! (if present).
  308. ! 13Jun02 - J.W. Larson <larson@mcs.anl.gov> - Removed the argument
  309. ! comm. This routine is now explicitly for intercomponent
  310. ! communications only.
  311. !EOP ___________________________________________________________________
  312. character(len=*),parameter :: myname_=myname//'::recv_'
  313. integer :: ierr
  314. integer :: source
  315. integer :: MPstatus(MP_STATUS_SIZE), DescendSize
  316. logical :: HeaderAssoc(6)
  317. ! for now, assume the components root is the source.
  318. source = ComponentToWorldRank(0, comp_id, ThisMCTWorld)
  319. ! Step 1. Receive the elements of the LOGICAL flag array
  320. ! HeaderAssoc. TRUE entries in this array correspond to
  321. ! Check elements of the GeneralGrid header that are not
  322. ! blank, and are being sent by process source.
  323. !
  324. ! The significance of the entries of HeaderAssoc has been
  325. ! defined in send_(). Here are the definitions of these
  326. ! values:
  327. !
  328. ! HeaderAssoc(1) = List_allocated(oGGrid%coordinate_list)
  329. ! HeaderAssoc(2) = List_allocated(oGGrid%coordinate_sort_order)
  330. ! HeaderAssoc(3) = associated(oGGrid%descend)
  331. ! HeaderAssoc(4) = List_allocated(oGGrid%weight_list)
  332. ! HeaderAssoc(5) = List_allocated(oGGrid%other_list)
  333. ! HeaderAssoc(6) = List_allocated(oGGrid%index_list)
  334. ! Initialize status (if present)
  335. if(present(status)) status = 0
  336. ! Step 1. Nullify oGGrid components, set HeaderAssoc(:) to .FALSE.,
  337. ! then receive incoming HeaderAssoc(:) data
  338. call List_nullify(oGGrid%coordinate_list)
  339. call List_nullify(oGGrid%coordinate_sort_order)
  340. call List_nullify(oGGrid%weight_list)
  341. call List_nullify(oGGrid%other_list)
  342. call List_nullify(oGGrid%index_list)
  343. nullify(oGGrid%descend)
  344. HeaderAssoc = .FALSE.
  345. call MPI_RECV(HeaderAssoc, 6, MP_LOGICAL, source, TagBase, ThisMCTWorld%MCT_comm, MPstatus, ierr)
  346. if(ierr /= 0) then
  347. call MP_perr_die(myname_,':: MPI_RECV(HeaderAssoc...',ierr)
  348. endif
  349. ! Step 2. If oGGrid%coordinate_list is defined, receive it.
  350. if(HeaderAssoc(1)) then
  351. call List_recv(oGGrid%coordinate_list, source, TagBase+1, ThisMCTWorld%MCT_comm, ierr)
  352. if(ierr /= 0) then
  353. if(present(status)) then
  354. write(stderr,*) myname_,':: call List_recv(oGGrid%coordinate_list...'
  355. status = ierr
  356. return
  357. else
  358. call die(myname_,':: call List_recv(oGGrid%coordinate_list...',ierr)
  359. endif
  360. endif
  361. else ! This constitutes an error, as a GeneralGrid must have coordinates
  362. if(present(status)) then
  363. write(stderr,*) myname_,':: Error. GeneralGrid%coordinate_list undefined.'
  364. status = -1
  365. return
  366. else
  367. call die(myname_,':: Error. GeneralGrid%coordinate_list undefined.',-1)
  368. endif
  369. endif ! if(HeaderAssoc(1))...
  370. ! Step 3. If oGGrid%coordinate_sort_order is defined, receive it.
  371. if(HeaderAssoc(2)) then
  372. call List_recv(oGGrid%coordinate_sort_order, source, TagBase+3, ThisMCTWorld%MCT_comm, ierr)
  373. if(ierr /= 0) then
  374. if(present(status)) then
  375. write(stderr,*) myname_,':: Error calling ',&
  376. 'List_recv(oGGrid%coordinate_sort_order...'
  377. status = ierr
  378. return
  379. else
  380. call die(myname_,':: call List_recv(oGGrid%coordinate_sort_order...', ierr)
  381. endif
  382. endif
  383. endif ! if(HeaderAssoc(2))...
  384. ! Step 4. If oGGrid%descend is allocated, determine its size,
  385. ! receive this size, allocate oGGrid%descend, and then receive
  386. ! the elements of oGGrid%descend.
  387. if(HeaderAssoc(3)) then
  388. call MPI_RECV(DescendSize, 1, MP_type(DescendSize), &
  389. source, TagBase+5, ThisMCTWorld%MCT_comm, MPstatus, ierr)
  390. if(ierr /= 0) then
  391. call MP_perr_die(myname_,':: call MPI_RECV(size(oGGrid%descend)...',ierr)
  392. endif
  393. allocate(oGGrid%descend(DescendSize), stat=ierr)
  394. if(ierr /= 0) then
  395. if(present(status)) then
  396. write(stderr,*) myname_,':: allocate(oGGrid%descend...'
  397. status = ierr
  398. return
  399. else
  400. call die(myname_,':: allocate(oGGrid%descend... failed.',ierr)
  401. endif
  402. endif
  403. call MPI_RECV(oGGrid%descend, DescendSize, MP_type(oGGrid%descend(1)), &
  404. source, TagBase+6, ThisMCTWorld%MCT_comm, MPstatus, ierr)
  405. if(ierr /= 0) then
  406. call MP_perr_die(myname_,':: call MPI_RECV(oGGrid%descend...',ierr)
  407. endif
  408. endif ! if(HeaderAssoc(3))...
  409. ! Step 5. If oGGrid%weight_list is defined, receive it.
  410. if(HeaderAssoc(4)) then
  411. call List_recv(oGGrid%weight_list, source, TagBase+7, ThisMCTWorld%MCT_comm, ierr)
  412. if(ierr /= 0) then
  413. if(present(status)) then
  414. write(stderr,*) myname_,':: call List_recv(oGGrid%weight_list...'
  415. status = ierr
  416. return
  417. else
  418. call die(myname_,':: call List_recv(oGGrid%weight_list...',ierr)
  419. endif
  420. endif
  421. endif ! if(HeaderAssoc(4))...
  422. ! Step 6. If oGGrid%other_list is defined, receive it.
  423. if(HeaderAssoc(5)) then
  424. call List_recv(oGGrid%other_list, source, TagBase+9, ThisMCTWorld%MCT_comm, ierr)
  425. if(ierr /= 0) then
  426. if(present(status)) then
  427. write(stderr,*) myname_,':: call List_recv(oGGrid%other_list...'
  428. status = ierr
  429. return
  430. else
  431. call die(myname_,':: call List_recv(oGGrid%other_list...',ierr)
  432. endif
  433. endif
  434. endif ! if(HeaderAssoc(5))...
  435. ! Step 7. If oGGrid%index_list is defined, receive it.
  436. if(HeaderAssoc(6)) then
  437. call List_recv(oGGrid%index_list, source, TagBase+11, ThisMCTWorld%MCT_comm, ierr)
  438. if(ierr /= 0) then
  439. if(present(status)) then
  440. write(stderr,*) myname_,':: call List_recv(oGGrid%index_list...'
  441. status = ierr
  442. return
  443. else
  444. call die(myname_,':: call List_recv(oGGrid%index_list...',ierr)
  445. endif
  446. endif
  447. else ! This constitutes an error, as a GeneralGrid must at a minimum
  448. ! contain the index GlobGridNum
  449. if(present(status)) then
  450. write(stderr,*) myname_,':: Error. GeneralGrid%index_list undefined.'
  451. status = -2
  452. return
  453. else
  454. call die(myname_,':: Error. GeneralGrid%index_list undefined.',-2)
  455. endif
  456. endif ! if(HeaderAssoc(6))...
  457. ! Step 8. Finally, receive the AttrVect oGGrid%data.
  458. call AttrVect_recv(oGGrid%data, source, TagBase+13, ThisMCTWorld%MCT_comm, ierr)
  459. if(ierr /= 0) then
  460. if(present(status)) then
  461. write(stderr,*) myname_,':: call AttrVect_recv(oGGrid%data...'
  462. status = ierr
  463. return
  464. else
  465. call die(myname_,':: call AttrVect_recv(oGGrid%data...',ierr)
  466. endif
  467. endif
  468. ! The GeneralGrid receive is now complete.
  469. end subroutine recv_
  470. !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  471. ! Math and Computer Science Division, Argonne National Laboratory !
  472. !BOP -------------------------------------------------------------------
  473. !
  474. ! !IROUTINE: GM_gather_ - gather a GeneralGrid using input GlobalMap.
  475. !
  476. ! !DESCRIPTION: {\tt GM\_gather\_()} takes an input {\tt GeneralGrid}
  477. ! argument {\tt iG} whose decomposition on the communicator associated
  478. ! with the F90 handle {\tt comm} is described by the {\tt GlobalMap}
  479. ! argument {\tt GMap}, and gathers it to the {\tt GeneralGrid} output
  480. ! argument {\tt oG} on the {\tt root}. The success (failure) of this
  481. ! operation is reported as a zero (nonzero) value in the optional
  482. ! {\tt INTEGER} output argument {\tt stat}.
  483. ! {\bf N.B.}: An important assumption made here is that the distributed
  484. ! {\tt GeneralGrid} {\tt iG} has been initialized with the same
  485. ! coordinate system, sort order, other real attributes, and the same
  486. ! indexing attributes for all processes on {\tt comm}.
  487. !
  488. ! {\bf N.B.}: Once the gridpoint data of the {\tt GeneralGrid} are assembled
  489. ! on the {\tt root}, they are stored in the order determined by the input
  490. ! {\tt GlobalMap} {\tt GMap}. The user may need to sorted these gathered
  491. ! data to order them in accordance with the {\tt coordinate\_sort\_order}
  492. ! attribute of {\tt iG}.
  493. !
  494. ! {\bf N.B.}: The output {\tt GeneralGrid} {\tt oG} represents allocated
  495. ! memory on the {\tt root}. When the user no longer needs {\tt oG} it
  496. ! should be deallocated using {\tt GeneralGrid\_clean()} to avoid a memory
  497. ! leak
  498. !
  499. ! !INTERFACE:
  500. !
  501. subroutine GM_gather_(iG, oG, GMap, root, comm, stat)
  502. !
  503. ! !USES:
  504. !
  505. use m_stdio
  506. use m_die
  507. use m_mpif90
  508. use m_GlobalMap, only : GlobalMap
  509. use m_GlobalMap, only : GlobalMap_gsize => gsize
  510. use m_GeneralGrid, only : GeneralGrid
  511. use m_GeneralGrid, only : GeneralGrid_init => init
  512. use m_AttrVectComms,only : AttrVect_Gather => gather
  513. implicit none
  514. ! !INPUT PARAMETERS:
  515. !
  516. type(GeneralGrid), intent(in) :: iG
  517. type(GlobalMap), intent(in) :: GMap
  518. integer, intent(in) :: root
  519. integer, intent(in) :: comm
  520. ! !OUTPUT PARAMETERS:
  521. !
  522. type(GeneralGrid), intent(out) :: oG
  523. integer, optional, intent(out) :: stat
  524. ! !REVISION HISTORY:
  525. ! 27Apr01 - J.W. Larson <larson@mcs.anl.gov> - API Specification.
  526. ! 02May01 - J.W. Larson <larson@mcs.anl.gov> - Initial code.
  527. ! 13Jun01 - J.W. Larson <larson@mcs.anl.gov> - Initialize stat
  528. ! (if present).
  529. !EOP ___________________________________________________________________
  530. character(len=*),parameter :: myname_=myname//'::GM_gather_'
  531. !Process ID
  532. integer :: myID
  533. !Error flag
  534. integer :: ierr
  535. !Number of points on the _Gathered_ grid:
  536. integer :: length
  537. ! Initialize stat (if present)
  538. if(present(stat)) stat = 0
  539. ! Which process am I?
  540. call MPI_COMM_RANK(comm, myID, ierr)
  541. if(ierr /= 0) then
  542. call MP_perr_die(myname_,'call MPI_COMM_RANK()',ierr)
  543. endif
  544. if(myID == root) then ! prepare oG:
  545. ! The length of the _gathered_ GeneralGrid oG is determined by
  546. ! the GlobalMap function GlobalMap_gsize()
  547. length = GlobalMap_gsize(GMap)
  548. ! Initialize attributes of oG from iG
  549. call copyGeneralGridHeader_(iG,oG)
  550. endif
  551. ! Gather gridpoint data in iG%data to oG%data
  552. call AttrVect_Gather(iG%data, oG%data, GMap, root, comm, ierr)
  553. if(ierr /= 0) then
  554. write(stderr,*) myname_,':: Error--call AttrVect_Gather() failed.', &
  555. ' ierr = ',ierr
  556. if(present(stat)) then
  557. stat=ierr
  558. return
  559. else
  560. call die(myname_,'call AttrVect_Gather(ig%data...',ierr)
  561. endif
  562. endif
  563. end subroutine GM_gather_
  564. !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  565. ! Math and Computer Science Division, Argonne National Laboratory !
  566. !BOP -------------------------------------------------------------------
  567. !
  568. ! !IROUTINE: GSM_gather_ - gather a GeneralGrid using input GlobalSegMap.
  569. !
  570. ! !DESCRIPTION: {\tt GMS\_gather\_()} takes an input {\tt GeneralGrid}
  571. ! argument {\tt iG} whose decomposition on the communicator associated
  572. ! with the F90 handle {\tt comm} is described by the {\tt GlobalSegMap}
  573. ! argument {\tt GSMap}, and gathers it to the {\tt GeneralGrid} output
  574. ! argument {\tt oG} on the {\tt root}. The success (failure) of this
  575. ! operation is reported as a zero (nonzero) value in the optional
  576. ! {\tt INTEGER} output argument {\tt stat}.
  577. !
  578. ! {\bf N.B.}: An important assumption made here is that the distributed
  579. ! {\tt GeneralGrid} {\tt iG} has been initialized with the same
  580. ! coordinate system, sort order, other real attributes, and the same
  581. ! indexing attributes for all processes on {\tt comm}.
  582. !
  583. ! {\bf N.B.}: Once the gridpoint data of the {\tt GeneralGrid} are assembled
  584. ! on the {\tt root}, they are stored in the order determined by the input
  585. ! {\tt GlobalSegMap} {\tt GSMap}. The user may need to sorted these gathered
  586. ! data to order them in accordance with the {\tt coordinate\_sort\_order}
  587. ! attribute of {\tt iG}.
  588. !
  589. ! {\bf N.B.}: The output {\tt GeneralGrid} {\tt oG} represents allocated
  590. ! memory on the {\tt root}. When the user no longer needs {\tt oG} it
  591. ! should be deallocated using {\tt GeneralGrid\_clean()} to avoid a memory
  592. ! leak
  593. !
  594. ! !INTERFACE:
  595. subroutine GSM_gather_(iG, oG, GSMap, root, comm, stat)
  596. !
  597. ! !USES:
  598. !
  599. use m_stdio
  600. use m_die
  601. use m_mpif90
  602. use m_GlobalSegMap, only : GlobalSegMap
  603. use m_GlobalSegMap, only : GlobalSegMap_lsize => lsize
  604. use m_GlobalSegMap, only : GlobalSegMap_gsize => gsize
  605. use m_GeneralGrid, only : GeneralGrid
  606. use m_GeneralGrid, only : GeneralGrid_init => init
  607. use m_GeneralGrid, only : GeneralGrid_lsize => lsize
  608. use m_AttrVectComms,only : AttrVect_Gather => gather
  609. implicit none
  610. ! !INPUT PARAMETERS:
  611. !
  612. type(GeneralGrid), intent(in) :: iG
  613. type(GlobalSegMap), intent(in) :: GSMap
  614. integer, intent(in) :: root
  615. integer, intent(in) :: comm
  616. ! !OUTPUT PARAMETERS:
  617. !
  618. type(GeneralGrid), intent(out) :: oG
  619. integer, optional, intent(out) :: stat
  620. ! !REVISION HISTORY:
  621. ! 27Apr01 - J.W. Larson <larson@mcs.anl.gov> - API Specification.
  622. ! 01May01 - J.W. Larson <larson@mcs.anl.gov> - Working Version.
  623. ! 13Jun01 - J.W. Larson <larson@mcs.anl.gov> - Initialize stat
  624. ! (if present).
  625. !EOP ___________________________________________________________________
  626. character(len=*),parameter :: myname_=myname//'::GSM_gather_'
  627. !Process ID
  628. integer :: myID
  629. !Error flag
  630. integer :: ierr
  631. !Number of points on the _Gathered_ grid:
  632. integer :: length
  633. ! Initialize stat (if present)
  634. if(present(stat)) stat = 0
  635. ! Which process am I?
  636. call MPI_COMM_RANK(comm, myID, ierr)
  637. if(ierr /= 0) then
  638. call MP_perr_die(myname_,'MPI_COMM_RANK()',ierr)
  639. endif
  640. if(myID == root) then ! prepare oG:
  641. ! The length of the _gathered_ GeneralGrid oG is determined by
  642. ! the GlobalMap function GlobalSegMap_gsize()
  643. length = GlobalSegMap_gsize(GSMap)
  644. ! Initialize attributes of oG from iG
  645. call copyGeneralGridHeader_(iG,oG)
  646. endif
  647. ! Gather gridpoint data in iG%data to oG%data
  648. call AttrVect_Gather(iG%data, oG%data, GSMap, root, comm, ierr)
  649. if(ierr /= 0) then
  650. write(stderr,*) myname_,':: ERROR--call AttrVect_Gather() failed.', &
  651. ' ierr = ',ierr
  652. if(present(stat)) then
  653. stat=ierr
  654. return
  655. else
  656. call die(myname_)
  657. endif
  658. endif
  659. end subroutine GSM_gather_
  660. !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  661. ! Math and Computer Science Division, Argonne National Laboratory !
  662. !BOP -------------------------------------------------------------------
  663. !
  664. ! !IROUTINE: GM_scatter_ - scatter a GeneralGrid using input GlobalMap.
  665. !
  666. ! !DESCRIPTION: {\tt GM\_scatter\_()} takes an input {\tt GeneralGrid}
  667. ! argument {\tt iG} (valid only on the {\tt root} process), and scatters
  668. ! it to the distributed {\tt GeneralGrid} variable {\tt oG}. The
  669. ! {\tt GeneralGrid} {\tt oG} is distributed on the communicator
  670. ! associated with the F90 handle {\tt comm} using the domain
  671. ! decomposition described by the {\tt GlobalMap} argument {\tt GMap}.
  672. ! The success (failure) of this operation is reported as a zero (nonzero)
  673. ! value in the optional {\tt INTEGER} output argument {\tt stat}.
  674. !
  675. ! {\bf N.B.}: The output {\tt GeneralGrid} {\tt oG} represents allocated
  676. ! memory on the {\tt root}. When the user no longer needs {\tt oG} it
  677. ! should be deallocated using {\tt GeneralGrid\_clean()} to avoid a memory
  678. ! leak.
  679. !
  680. ! !INTERFACE:
  681. subroutine GM_scatter_(iG, oG, GMap, root, comm, stat)
  682. !
  683. ! !USES:
  684. !
  685. use m_stdio
  686. use m_die
  687. use m_mpif90
  688. use m_GlobalMap, only : GlobalMap
  689. use m_GlobalMap, only : GlobalMap_lsize => lsize
  690. use m_GlobalMap, only : GlobalMap_gsize => gsize
  691. use m_AttrVectComms, only : AttrVect_scatter => scatter
  692. use m_GeneralGrid, only : GeneralGrid
  693. use m_GeneralGrid, only : GeneralGrid_init => init
  694. use m_GeneralGrid, only : GeneralGrid_lsize => lsize
  695. implicit none
  696. ! !INPUT PARAMETERS:
  697. !
  698. type(GeneralGrid), intent(in) :: iG
  699. type(GlobalMap), intent(in) :: GMap
  700. integer, intent(in) :: root
  701. integer, intent(in) :: comm
  702. ! !OUTPUT PARAMETERS:
  703. !
  704. type(GeneralGrid), intent(out) :: oG
  705. integer, optional, intent(out) :: stat
  706. ! !REVISION HISTORY:
  707. ! 27Apr01 - J.W. Larson <larson@mcs.anl.gov> - API Specification.
  708. ! 04Jun01 - J.W. Larson <larson@mcs.anl.gov> - Changed comms model
  709. ! to MPI-style (i.e. iG valid on root only).
  710. ! 13Jun01 - J.W. Larson <larson@mcs.anl.gov> - Initialize stat
  711. ! (if present).
  712. !EOP ___________________________________________________________________
  713. character(len=*),parameter :: myname_=myname//'::GM_scatter_'
  714. logical :: DescendAssoc
  715. integer :: DescendSize
  716. integer :: ierr, myID
  717. ! Initialize status (if present)
  718. if(present(stat)) stat = 0
  719. ! Step 1. Determine process ID number myID
  720. call MPI_COMM_RANK(comm, myID, ierr)
  721. if(ierr /= 0) then
  722. call MP_perr_die(myname_,'MPI_COMM_RANK(comm...',ierr)
  723. endif
  724. ! Step 2. On the root, initialize the List and LOGICAL
  725. ! attributes of the GeneralGrid variable iG to oG.
  726. if(myID == root) then
  727. call copyGeneralGridHeader_(iG, oG)
  728. endif
  729. ! Step 3. Broadcast from the root the List and LOGICAL
  730. ! attributes of the GeneralGrid variable oG.
  731. call bcastGeneralGridHeader_(oG, root, comm, ierr)
  732. if(ierr /= 0) then
  733. write(stderr,*) myname_,':: Error calling bcastGeneralGridHeader_().',&
  734. ' ierr = ',ierr
  735. if(present(stat)) then
  736. stat = ierr
  737. return
  738. else
  739. call die(myname_,'call bcastGeneralGridHeader_(oG...',ierr)
  740. endif
  741. endif
  742. ! Step 4. Using the GeneralMap GMap, scatter the AttrVect
  743. ! portion of the input GeneralGrid iG to the GeneralGrid oG.
  744. call AttrVect_scatter(iG%data, oG%data, GMap, root, comm, ierr)
  745. if(ierr /= 0) then
  746. write(stderr,*) myname_,':: Error calling AttrVect_scatter(iG%data...',&
  747. ' ierr = ',ierr
  748. if(present(stat)) then
  749. stat = ierr
  750. return
  751. else
  752. call die(myname_,'call AttrVect_scatter(iG%data...',ierr)
  753. endif
  754. endif
  755. ! The GeneralGrid scatter is now complete.
  756. end subroutine GM_scatter_
  757. !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  758. ! Math and Computer Science Division, Argonne National Laboratory !
  759. !BOP -------------------------------------------------------------------
  760. !
  761. ! !IROUTINE: GSM_scatter_ - scatter a GeneralGrid using input GlobalSegMap.
  762. !
  763. ! !DESCRIPTION: {\tt GM\_scatter\_()} takes an input {\tt GeneralGrid}
  764. ! argument {\tt iG} (valid only on the {\tt root} process), and scatters
  765. ! it to the distributed {\tt GeneralGrid} variable {\tt oG}. The
  766. ! {\tt GeneralGrid} {\tt oG} is distributed on the communicator
  767. ! associated with the F90 handle {\tt comm} using the domain
  768. ! decomposition described by the {\tt GlobalSegMap} argument {\tt GSMap}.
  769. ! The success (failure) of this operation is reported as a zero (nonzero)
  770. ! value in the optional {\tt INTEGER} output argument {\tt stat}.
  771. !
  772. ! {\bf N.B.}: The output {\tt GeneralGrid} {\tt oG} represents allocated
  773. ! memory on the {\tt root}. When the user no longer needs {\tt oG} it
  774. ! should be deallocated using {\tt GeneralGrid\_clean()} to avoid a memory
  775. ! leak.
  776. !
  777. ! !INTERFACE:
  778. subroutine GSM_scatter_(iG, oG, GSMap, root, comm, stat)
  779. !
  780. ! !USES:
  781. !
  782. use m_stdio
  783. use m_die
  784. use m_mpif90
  785. use m_GlobalSegMap, only : GlobalSegMap
  786. use m_GlobalSegMap, only : GlobalSegMap_lsize => lsize
  787. use m_GlobalSegMap, only : GlobalSegMap_gsize => gsize
  788. use m_AttrVectComms, only : AttrVect_scatter => scatter
  789. use m_GeneralGrid, only : GeneralGrid
  790. use m_GeneralGrid, only : GeneralGrid_init => init
  791. use m_GeneralGrid, only : GeneralGrid_lsize => lsize
  792. implicit none
  793. ! !INPUT PARAMETERS:
  794. !
  795. type(GeneralGrid), intent(in) :: iG
  796. type(GlobalSegMap), intent(in) :: GSMap
  797. integer, intent(in) :: root
  798. integer, intent(in) :: comm
  799. ! !OUTPUT PARAMETERS:
  800. !
  801. type(GeneralGrid), intent(out) :: oG
  802. integer, optional, intent(out) :: stat
  803. ! !REVISION HISTORY:
  804. ! 27Apr01 - J.W. Larson <larson@mcs.anl.gov> - API Specification.
  805. ! 04Jun01 - J.W. Larson <larson@mcs.anl.gov> - Initial code.
  806. ! 13Jun01 - J.W. Larson <larson@mcs.anl.gov> - Initialize stat
  807. ! (if present).
  808. !EOP ___________________________________________________________________
  809. character(len=*),parameter :: myname_=myname//'::GSM_scatter_'
  810. integer :: ierr, myID
  811. ! Initialize stat (if present)
  812. if(present(stat)) stat = 0
  813. ! Step 1. Determine process ID number myID
  814. call MPI_COMM_RANK(comm, myID, ierr)
  815. if(ierr /= 0) then
  816. call MP_perr_die(myname_,'MPI_COMM_RANK(comm...',ierr)
  817. endif
  818. ! Step 2. On the root, initialize the List and LOGICAL
  819. ! attributes of the GeneralGrid variable iG to oG.
  820. if(myID == root) then
  821. call copyGeneralGridHeader_(iG, oG)
  822. endif
  823. ! Step 3. Broadcast from the root the List and LOGICAL
  824. ! attributes of the GeneralGrid variable oG.
  825. call bcastGeneralGridHeader_(oG, root, comm, ierr)
  826. if(ierr /= 0) then
  827. write(stderr,*) myname_,':: Error calling bcastGeneralGridHeader_(...',&
  828. ' ierr = ',ierr
  829. if(present(stat)) then
  830. stat = ierr
  831. return
  832. else
  833. call die(myname_,'bcastGeneralGridHeader_(oG...',ierr)
  834. endif
  835. endif
  836. ! Step 4. Using the GeneralSegMap GSMap, scatter the AttrVect
  837. ! portion of the input GeneralGrid iG to the GeneralGrid oG.
  838. call AttrVect_scatter(iG%data, oG%data, GSMap, root, comm, ierr)
  839. if(ierr /= 0) then
  840. write(stderr,*) myname_,':: Error calling AttrVect_scatter(iG%data...',&
  841. ' ierr = ',ierr
  842. if(present(stat)) then
  843. stat = ierr
  844. return
  845. else
  846. call die(myname_,'call AttrVect_scatter(iG%data...',ierr)
  847. endif
  848. endif
  849. ! The GeneralGrid scatter is now complete.
  850. end subroutine GSM_scatter_
  851. !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  852. ! Math and Computer Science Division, Argonne National Laboratory !
  853. !BOP -------------------------------------------------------------------
  854. !
  855. ! !IROUTINE: bcast_ - Broadcast a GeneralGrid.
  856. !
  857. ! !DESCRIPTION: {\tt bcast\_()} takes an input {\tt GeneralGrid}
  858. ! argument {\tt ioG} (valid only on the {\tt root} process), and
  859. ! broadcasts it to all processes on the communicator associated with the
  860. ! F90 handle {\tt comm}. The success (failure) of this operation is
  861. ! reported as a zero (nonzero) value in the optional {\tt INTEGER}
  862. ! output argument {\tt stat}.
  863. !
  864. ! {\bf N.B.}: On the non-root processes, the output {\tt GeneralGrid}
  865. ! {\tt ioG} represents allocated memory. When the user no longer needs
  866. ! {\tt ioG} it should be deallocated by invoking {\tt GeneralGrid\_clean()}.
  867. ! Failure to do so risks a memory leak.
  868. !
  869. ! !INTERFACE:
  870. subroutine bcast_(ioG, root, comm, stat)
  871. !
  872. ! !USES:
  873. !
  874. use m_stdio
  875. use m_die
  876. use m_mpif90
  877. use m_GlobalSegMap, only : GlobalSegMap
  878. use m_GlobalSegMap, only : GlobalSegMap_lsize => lsize
  879. use m_GlobalSegMap, only : GlobalSegMap_gsize => gsize
  880. use m_GeneralGrid, only : GeneralGrid
  881. use m_GeneralGrid, only : GeneralGrid_init => init
  882. use m_GeneralGrid, only : GeneralGrid_lsize => lsize
  883. use m_AttrVectComms,only : AttrVect_bcast => bcast
  884. implicit none
  885. ! !INPUT PARAMETERS:
  886. !
  887. integer, intent(in) :: root
  888. integer, intent(in) :: comm
  889. ! !INPUT/OUTPUT PARAMETERS:
  890. !
  891. type(GeneralGrid), intent(inout) :: ioG
  892. ! !OUTPUT PARAMETERS:
  893. !
  894. integer, optional, intent(out) :: stat
  895. ! !REVISION HISTORY:
  896. ! 27Apr01 - J.W. Larson <larson@mcs.anl.gov> - API Specification.
  897. ! 02May01 - J.W. Larson <larson@mcs.anl.gov> - Initial version.
  898. ! 13Jun01 - J.W. Larson <larson@mcs.anl.gov> - Initialize stat
  899. ! (if present).
  900. !EOP ___________________________________________________________________
  901. character(len=*),parameter :: myname_=myname//'::bcast_'
  902. integer :: ierr, myID
  903. ! Initialize status (if present)
  904. if(present(stat)) stat = 0
  905. ! Step 1. Determine process ID number myID
  906. call MPI_COMM_RANK(comm, myID, ierr)
  907. if(ierr /= 0) then
  908. call MP_perr_die(myname_,'MPI_COMM_RANK(comm...',ierr)
  909. endif
  910. ! Step 2. Broadcast from the root the List and LOGICAL
  911. ! attributes of the GeneralGrid variable ioG.
  912. call bcastGeneralGridHeader_(ioG, root, comm, ierr)
  913. if(ierr /= 0) then
  914. write(stderr,*) myname_,':: Error calling bcastGeneralGridHeader_(...',&
  915. ' ierr = ',ierr
  916. if(present(stat)) then
  917. stat = ierr
  918. return
  919. else
  920. call die(myname_)
  921. endif
  922. endif
  923. ! Step 3. Broadcast ioG%data from the root.
  924. call AttrVect_bcast(ioG%data, root, comm, ierr)
  925. if(ierr /= 0) then
  926. write(stderr,*) myname_,':: Error calling AttrVect_scatter(iG%data...',&
  927. ' ierr = ',ierr
  928. if(present(stat)) then
  929. stat = ierr
  930. return
  931. else
  932. call die(myname_)
  933. endif
  934. endif
  935. ! The GeneralGrid broadcast is now complete.
  936. end subroutine bcast_
  937. !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  938. ! Math and Computer Science Division, Argonne National Laboratory !
  939. !BOP -------------------------------------------------------------------
  940. !
  941. ! !IROUTINE: bcastGeneralGridHeader_ - Broadcast the GeneralGrid Header.
  942. !
  943. ! !DESCRIPTION: This routine broadcasts the header information from
  944. ! the input {\tt GeneralGrid} argument {\tt ioGGrid} (on input valid
  945. ! on the {\tt root} only). This broadcast is from the {\tt root} to
  946. ! all processes on the communicator associated with the fortran 90
  947. ! {\tt INTEGER} handle {\tt comm}. The success (failure) of this operation
  948. ! corresponds to a zero (nonzero) value for the output {\tt INTEGER} flag
  949. ! {\tt stat}.
  950. !
  951. ! The {\em header information} in a {\tt GeneralGrid} variable comprises
  952. ! all the non-{\tt AttrVect} components of the {\tt GeneralGrid}; that
  953. ! is, everything except the gridpoint coordinate, geometry, and index
  954. ! data stored in {\tt iGGrid\%data}. This information includes:
  955. ! \begin{enumerate}
  956. ! \item The coordinates in {\tt iGGrid\%coordinate\_list}
  957. ! \item The coordinate sort order in {\tt iGGrid\%coordinate\_sort\_order}
  958. ! \item The area/volume weights in {\tt iGGrid\%weight\_list}
  959. ! \item Other {\tt REAL} geometric information in {\tt iGGrid\%other\_list}
  960. ! \item Indexing information in {\tt iGGrid\%index\_list}
  961. ! \item The {\tt LOGICAL} descending/ascending order sort flags in
  962. ! {\tt iGGrid\%descend(:)}.
  963. ! \end{enumerate}
  964. !
  965. ! !INTERFACE:
  966. subroutine bcastGeneralGridHeader_(ioGGrid, root, comm, stat)
  967. !
  968. ! !USES:
  969. !
  970. use m_stdio
  971. use m_die
  972. use m_mpif90
  973. use m_GlobalSegMap, only : GlobalSegMap
  974. use m_GlobalSegMap, only : GlobalSegMap_lsize => lsize
  975. use m_GlobalSegMap, only : GlobalSegMap_gsize => gsize
  976. use m_GeneralGrid, only : GeneralGrid
  977. use m_GeneralGrid, only : GeneralGrid_init => init
  978. use m_GeneralGrid, only : GeneralGrid_lsize => lsize
  979. use m_List, only : List
  980. use m_List, only : List_allocated => allocated
  981. use m_List, only : List_nullify => nullify
  982. use m_List, only : List_bcast => bcast
  983. implicit none
  984. ! !INPUT PARAMETERS:
  985. !
  986. integer, intent(in) :: root
  987. integer, intent(in) :: comm
  988. ! !INPUT/OUTPUT PARAMETERS:
  989. !
  990. type(GeneralGrid), intent(inout) :: ioGGrid
  991. ! !OUTPUT PARAMETERS:
  992. !
  993. integer, optional, intent(out) :: stat
  994. ! !REVISION HISTORY:
  995. ! 05Jun01 - J.W. Larson <larson@mcs.anl.gov> - Initial code.
  996. ! 13Jun01 - J.W. Larson <larson@mcs.anl.gov> - Initialize stat
  997. ! (if present).
  998. ! 05Aug02 - E. Ong <eong@mcs.anl.gov> - added association checking
  999. !EOP ___________________________________________________________________
  1000. character(len=*),parameter :: myname_=myname//'::bcastGeneralGridHeader_'
  1001. ! Process ID
  1002. integer :: myID
  1003. ! Error flag
  1004. integer :: ierr
  1005. ! Size of array ioGGrid%descend(:)
  1006. integer :: DescendSize
  1007. ! Header-Assocation array
  1008. logical :: HeaderAssoc(6)
  1009. ! Initialize stat (if present)
  1010. if(present(stat)) stat = 0
  1011. ! Determine process ID number myID
  1012. call MPI_COMM_RANK(comm, myID, ierr)
  1013. if(ierr /= 0) then
  1014. call MP_perr_die(myname_,'MPI_COMM_RANK(comm...',ierr)
  1015. endif
  1016. ! Step 0.5. Check elements of the GeneralGrid header to see
  1017. ! which components of it are allocated. Load the results
  1018. ! into HeaderAssoc(:), and broadcast it.
  1019. if(myID == root) then
  1020. HeaderAssoc(1) = List_allocated(ioGGrid%coordinate_list)
  1021. HeaderAssoc(2) = List_allocated(ioGGrid%coordinate_sort_order)
  1022. HeaderAssoc(3) = List_allocated(ioGGrid%weight_list)
  1023. HeaderAssoc(4) = List_allocated(ioGGrid%other_list)
  1024. HeaderAssoc(5) = List_allocated(ioGGrid%index_list)
  1025. HeaderAssoc(6) = associated(ioGGrid%descend)
  1026. else
  1027. call List_nullify(ioGGrid%coordinate_list)
  1028. call List_nullify(ioGGrid%coordinate_sort_order)
  1029. call List_nullify(ioGGrid%weight_list)
  1030. call List_nullify(ioGGrid%other_list)
  1031. call List_nullify(ioGGrid%index_list)
  1032. nullify(ioGGrid%descend)
  1033. endif
  1034. call MPI_BCAST(HeaderAssoc,6,MP_LOGICAL,root,comm,ierr)
  1035. ! Step 1. Broadcast List attributes of the GeneralGrid.
  1036. if(HeaderAssoc(1)) then
  1037. call List_bcast(ioGGrid%coordinate_list, root, comm, ierr)
  1038. if(ierr /= 0) then
  1039. write(stderr,*) myname_,'List_bcast(ioGGrid%coordinate_list... failed.',&
  1040. ' ierr = ',ierr
  1041. if(present(stat)) then
  1042. stat = ierr
  1043. return
  1044. else
  1045. call die(myname_)
  1046. endif
  1047. endif
  1048. endif
  1049. if(HeaderAssoc(2)) then
  1050. call List_bcast(ioGGrid%coordinate_sort_order, root, comm, ierr)
  1051. if(ierr /= 0) then
  1052. write(stderr,*) myname_,'List_bcast(ioGGrid%coordinate_sort_order... failed', &
  1053. ' ierr = ',ierr
  1054. if(present(stat)) then
  1055. stat = ierr
  1056. return
  1057. else
  1058. call die(myname_)
  1059. endif
  1060. endif
  1061. endif
  1062. if(HeaderAssoc(3)) then
  1063. call List_bcast(ioGGrid%weight_list, root, comm, ierr)
  1064. if(ierr /= 0) then
  1065. write(stderr,*) myname_,'List_bcast(ioGGrid%weight_list... failed',&
  1066. ' ierr = ',ierr
  1067. if(present(stat)) then
  1068. stat = ierr
  1069. return
  1070. else
  1071. call die(myname_)
  1072. endif
  1073. endif
  1074. endif
  1075. if(HeaderAssoc(4)) then
  1076. call List_bcast(ioGGrid%other_list, root, comm, ierr)
  1077. if(ierr /= 0) then
  1078. write(stderr,*) myname_,'List_bcast(ioGGrid%other_list... failed',&
  1079. ' ierr = ',ierr
  1080. if(present(stat)) then
  1081. stat = ierr
  1082. return
  1083. else
  1084. call die(myname_)
  1085. endif
  1086. endif
  1087. endif
  1088. if(HeaderAssoc(5)) then
  1089. call List_bcast(ioGGrid%index_list, root, comm, ierr)
  1090. if(ierr /= 0) then
  1091. write(stderr,*) myname_,'List_bcast(ioGGrid%index_list... failed',&
  1092. ' ierr = ',ierr
  1093. if(present(stat)) then
  1094. stat = ierr
  1095. return
  1096. else
  1097. call die(myname_)
  1098. endif
  1099. endif
  1100. endif
  1101. ! If ioGGrid%descend is associated on the root, prepare and
  1102. ! execute its broadcast
  1103. if(HeaderAssoc(6)) then
  1104. ! On the root, get the size of ioGGrid%descend(:)
  1105. if(myID == root) then
  1106. DescendSize = size(ioGGrid%descend)
  1107. if(DescendSize<=0) call die(myname_,'size(ioGGrid%descend)<=0')
  1108. endif
  1109. ! Broadcast the size of ioGGrid%descend(:) from the root.
  1110. call MPI_BCAST(DescendSize, 1, MP_INTEGER, root, comm, ierr)
  1111. if(ierr /= 0) then
  1112. call MP_perr_die(myname_,'MPI_BCAST(DescendSize...',ierr)
  1113. endif
  1114. ! Off the root, allocate ioGGrid%descend(:)
  1115. if(myID /= root) then
  1116. allocate(ioGGrid%descend(DescendSize), stat=ierr)
  1117. if(ierr /= 0) then
  1118. write(stderr,*) myname_,':: ERROR in allocate(ioGGrid%descend...',&
  1119. ' ierr = ',ierr
  1120. call die(myname_)
  1121. endif
  1122. endif
  1123. ! Finally, broadcast ioGGrid%descend(:) from the root
  1124. call MPI_BCAST(ioGGrid%descend, DescendSize, MP_LOGICAL, root, &
  1125. comm, ierr)
  1126. if(ierr /= 0) then
  1127. call MP_perr_die(myname_,'MPI_BCAST(ioGGrid%descend...',ierr)
  1128. endif
  1129. endif
  1130. ! The broadcast of the GeneralGrid Header from the &
  1131. ! root is complete.
  1132. end subroutine bcastGeneralGridHeader_
  1133. !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1134. ! Math and Computer Science Division, Argonne National Laboratory !
  1135. !BOP -------------------------------------------------------------------
  1136. !
  1137. ! !IROUTINE: copyGeneralGridHeader_ - Copy the GeneralGrid Header.
  1138. !
  1139. ! !DESCRIPTION: This routine copies the header information from the
  1140. ! input {\tt GeneralGrid} argument {\tt iGGrid} to the output
  1141. ! {\tt GeneralGrid} argument {\tt oGGrid}. The {\em header information}
  1142. ! in a {\tt GeneralGrid} variable comprises all the non-{\tt AttrVect}
  1143. ! components of the {\tt GeneralGrid}; that is, everything except the
  1144. ! gridpoint coordinate, geometry, and index data stored in
  1145. ! {\tt iGGrid\%data}. This information includes:
  1146. ! \begin{enumerate}
  1147. ! \item The coordinates in {\tt iGGrid\%coordinate\_list}
  1148. ! \item The coordinate sort order in {\tt iGGrid\%coordinate\_sort\_order}
  1149. ! \item The area/volume weights in {\tt iGGrid\%weight\_list}
  1150. ! \item Other {\tt REAL} geometric information in {\tt iGGrid\%other\_list}
  1151. ! \item Indexing information in {\tt iGGrid\%index\_list}
  1152. ! \item The {\tt LOGICAL} descending/ascending order sort flags in
  1153. ! {\tt iGGrid\%descend(:)}.
  1154. ! \end{enumerate}
  1155. !
  1156. ! !INTERFACE:
  1157. subroutine copyGeneralGridHeader_(iGGrid, oGGrid)
  1158. !
  1159. ! !USES:
  1160. !
  1161. use m_stdio
  1162. use m_die
  1163. use m_List, only : List
  1164. use m_List, only : List_copy => copy
  1165. use m_List, only : List_allocated => allocated
  1166. use m_List, only : List_nullify => nullify
  1167. use m_GeneralGrid, only : GeneralGrid
  1168. implicit none
  1169. ! !INPUT PARAMETERS:
  1170. !
  1171. type(GeneralGrid), intent(in) :: iGGrid
  1172. ! !OUTPUT PARAMETERS:
  1173. !
  1174. type(GeneralGrid), intent(out) :: oGGrid
  1175. ! !REVISION HISTORY:
  1176. ! 05Jun01 - J.W. Larson <larson@mcs.anl.gov> - Initial code.
  1177. ! 08Aug01 - E.T. Ong <eong@mcs.anl.gov> - changed list assignments(=)
  1178. ! to list copy.
  1179. ! 05Aug02 - E. Ong <eong@mcs.anl.gov> - added association checking
  1180. !EOP ___________________________________________________________________
  1181. character(len=*),parameter :: myname_=myname//'::copyGeneralGridHeader_'
  1182. logical :: DescendAssoc
  1183. integer :: DescendSize, i, ierr
  1184. ! Step 1. Copy GeneralGrid List attributes from iGGrid
  1185. ! to oGGrid.
  1186. call List_nullify(oGGrid%coordinate_list)
  1187. call List_nullify(oGGrid%coordinate_sort_order)
  1188. call List_nullify(oGGrid%weight_list)
  1189. call List_nullify(oGGrid%other_list)
  1190. call List_nullify(oGGrid%index_list)
  1191. nullify(oGGrid%descend)
  1192. if(List_allocated(iGGrid%coordinate_list)) then
  1193. call List_copy(oGGrid%coordinate_list,iGGrid%coordinate_list)
  1194. endif
  1195. if(List_allocated(iGGrid%coordinate_sort_order)) then
  1196. call List_copy(oGGrid%coordinate_sort_order,iGGrid%coordinate_sort_order)
  1197. endif
  1198. if(List_allocated(iGGrid%weight_list)) then
  1199. call List_copy(oGGrid%weight_list,iGGrid%weight_list)
  1200. endif
  1201. if(List_allocated(iGGrid%other_list)) then
  1202. call List_copy(oGGrid%other_list,iGGrid%other_list)
  1203. endif
  1204. if(List_allocated(iGGrid%index_list)) then
  1205. call List_copy(oGGrid%index_list,iGGrid%index_list)
  1206. endif
  1207. DescendAssoc = associated(iGGrid%descend)
  1208. if(DescendAssoc) then
  1209. DescendSize = size(iGGrid%descend)
  1210. allocate(oGGrid%descend(DescendSize), stat=ierr)
  1211. if(ierr /= 0) then
  1212. write(stderr,*) myname_,':: ERROR--allocate(iGGrid%descend(... failed.',&
  1213. ' ierr = ', ierr, 'DescendSize = ', DescendSize
  1214. call die(myname_)
  1215. endif
  1216. do i=1,DescendSize
  1217. oGGrid%descend(i) = iGGrid%descend(i)
  1218. end do
  1219. endif
  1220. ! The GeneralGrid header copy is now complete.
  1221. end subroutine copyGeneralGridHeader_
  1222. end module m_GeneralGridComms