12362add9SBarry Smith 2b45d2f2cSJed Brown #include <petsc-private/isimpl.h> /*I "petscis.h" I*/ 30c312b8eSJed Brown #include <petscsf.h> 4665c2dedSJed Brown #include <petscviewer.h> 52362add9SBarry Smith 67087cfbeSBarry Smith PetscClassId IS_LTOGM_CLASSID; 78e58c17dSMatthew Knepley 804a59952SBarry Smith 94a2ae208SSatish Balay #undef __FUNCT__ 10743c9b42SStefano Zampini #define __FUNCT__ "ISG2LMapApply" 11186d4ecdSBarry Smith PetscErrorCode ISG2LMapApply(ISLocalToGlobalMapping mapping,PetscInt n,const PetscInt in[],PetscInt out[]) 12186d4ecdSBarry Smith { 13186d4ecdSBarry Smith PetscErrorCode ierr; 14743c9b42SStefano Zampini PetscInt i,start,end; 15186d4ecdSBarry Smith 16186d4ecdSBarry Smith PetscFunctionBegin; 17186d4ecdSBarry Smith if (!mapping->globals) { 18186d4ecdSBarry Smith ierr = ISGlobalToLocalMappingApply(mapping,IS_GTOLM_MASK,0,0,0,0);CHKERRQ(ierr); 19186d4ecdSBarry Smith } 20743c9b42SStefano Zampini start = mapping->globalstart; 21743c9b42SStefano Zampini end = mapping->globalend; 22186d4ecdSBarry Smith for (i=0; i<n; i++) { 23186d4ecdSBarry Smith if (in[i] < 0) out[i] = in[i]; 24186d4ecdSBarry Smith else if (in[i] < start) out[i] = -1; 25186d4ecdSBarry Smith else if (in[i] > end) out[i] = -1; 26743c9b42SStefano Zampini else out[i] = mapping->globals[in[i] - start]; 27186d4ecdSBarry Smith } 28186d4ecdSBarry Smith PetscFunctionReturn(0); 29186d4ecdSBarry Smith } 30186d4ecdSBarry Smith 31186d4ecdSBarry Smith 32186d4ecdSBarry Smith #undef __FUNCT__ 334a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingGetSize" 343b9aefa3SBarry Smith /*@C 353b9aefa3SBarry Smith ISLocalToGlobalMappingGetSize - Gets the local size of a local to global mapping. 363b9aefa3SBarry Smith 373b9aefa3SBarry Smith Not Collective 383b9aefa3SBarry Smith 393b9aefa3SBarry Smith Input Parameter: 403b9aefa3SBarry Smith . ltog - local to global mapping 413b9aefa3SBarry Smith 423b9aefa3SBarry Smith Output Parameter: 433b9aefa3SBarry Smith . n - the number of entries in the local mapping 443b9aefa3SBarry Smith 453b9aefa3SBarry Smith Level: advanced 463b9aefa3SBarry Smith 47273d9f13SBarry Smith Concepts: mapping^local to global 483b9aefa3SBarry Smith 493b9aefa3SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 503b9aefa3SBarry Smith @*/ 517087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingGetSize(ISLocalToGlobalMapping mapping,PetscInt *n) 523b9aefa3SBarry Smith { 533b9aefa3SBarry Smith PetscFunctionBegin; 540700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 554482741eSBarry Smith PetscValidIntPointer(n,2); 563b9aefa3SBarry Smith *n = mapping->n; 573b9aefa3SBarry Smith PetscFunctionReturn(0); 583b9aefa3SBarry Smith } 593b9aefa3SBarry Smith 604a2ae208SSatish Balay #undef __FUNCT__ 614a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingView" 625a5d4f66SBarry Smith /*@C 635a5d4f66SBarry Smith ISLocalToGlobalMappingView - View a local to global mapping 645a5d4f66SBarry Smith 65b9cd556bSLois Curfman McInnes Not Collective 66b9cd556bSLois Curfman McInnes 675a5d4f66SBarry Smith Input Parameters: 683b9aefa3SBarry Smith + ltog - local to global mapping 693b9aefa3SBarry Smith - viewer - viewer 705a5d4f66SBarry Smith 71a997ad1aSLois Curfman McInnes Level: advanced 72a997ad1aSLois Curfman McInnes 73273d9f13SBarry Smith Concepts: mapping^local to global 745a5d4f66SBarry Smith 755a5d4f66SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 765a5d4f66SBarry Smith @*/ 777087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingView(ISLocalToGlobalMapping mapping,PetscViewer viewer) 785a5d4f66SBarry Smith { 7932dcc486SBarry Smith PetscInt i; 8032dcc486SBarry Smith PetscMPIInt rank; 81ace3abfcSBarry Smith PetscBool iascii; 826849ba73SBarry Smith PetscErrorCode ierr; 835a5d4f66SBarry Smith 845a5d4f66SBarry Smith PetscFunctionBegin; 850700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 863050cee2SBarry Smith if (!viewer) { 87ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mapping),&viewer);CHKERRQ(ierr); 883050cee2SBarry Smith } 890700a824SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 905a5d4f66SBarry Smith 91ce94432eSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mapping),&rank);CHKERRQ(ierr); 92251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 9332077d6dSBarry Smith if (iascii) { 94*98c3331eSBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mapping,viewer);CHKERRQ(ierr); 957b23a99aSBarry Smith ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);CHKERRQ(ierr); 965a5d4f66SBarry Smith for (i=0; i<mapping->n; i++) { 977904a332SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] %D %D\n",rank,i,mapping->indices[i]);CHKERRQ(ierr); 986831982aSBarry Smith } 99b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1007b23a99aSBarry Smith ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_FALSE);CHKERRQ(ierr); 1017b23a99aSBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported for ISLocalToGlobalMapping",((PetscObject)viewer)->type_name); 1025a5d4f66SBarry Smith PetscFunctionReturn(0); 1035a5d4f66SBarry Smith } 1045a5d4f66SBarry Smith 1054a2ae208SSatish Balay #undef __FUNCT__ 1064a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreateIS" 1071f428162SBarry Smith /*@ 1082bdab257SBarry Smith ISLocalToGlobalMappingCreateIS - Creates a mapping between a local (0 to n) 1092bdab257SBarry Smith ordering and a global parallel ordering. 1102bdab257SBarry Smith 1110f5bd95cSBarry Smith Not collective 112b9cd556bSLois Curfman McInnes 113a997ad1aSLois Curfman McInnes Input Parameter: 1148c03b21aSDmitry Karpeev . is - index set containing the global numbers for each local number 1152bdab257SBarry Smith 116a997ad1aSLois Curfman McInnes Output Parameter: 1172bdab257SBarry Smith . mapping - new mapping data structure 1182bdab257SBarry Smith 119a997ad1aSLois Curfman McInnes Level: advanced 120a997ad1aSLois Curfman McInnes 121273d9f13SBarry Smith Concepts: mapping^local to global 1222bdab257SBarry Smith 1232bdab257SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 1242bdab257SBarry Smith @*/ 1257087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingCreateIS(IS is,ISLocalToGlobalMapping *mapping) 1262bdab257SBarry Smith { 1276849ba73SBarry Smith PetscErrorCode ierr; 1283bbf0e92SBarry Smith PetscInt n,bs; 1295d0c19d7SBarry Smith const PetscInt *indices; 1302bdab257SBarry Smith MPI_Comm comm; 1313bbf0e92SBarry Smith PetscBool isblock; 1323a40ed3dSBarry Smith 1333a40ed3dSBarry Smith PetscFunctionBegin; 1340700a824SBarry Smith PetscValidHeaderSpecific(is,IS_CLASSID,1); 1354482741eSBarry Smith PetscValidPointer(mapping,2); 1362bdab257SBarry Smith 1372bdab257SBarry Smith ierr = PetscObjectGetComm((PetscObject)is,&comm);CHKERRQ(ierr); 1383b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 1392bdab257SBarry Smith ierr = ISGetIndices(is,&indices);CHKERRQ(ierr); 1403bbf0e92SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)is,ISBLOCK,&isblock);CHKERRQ(ierr); 1413bbf0e92SBarry Smith ierr = ISGetBlockSize(is,&bs);CHKERRQ(ierr); 1423bbf0e92SBarry Smith if (!isblock || bs == 1) { 143d5ad8652SBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,n,indices,PETSC_COPY_VALUES,mapping);CHKERRQ(ierr); 1442bdab257SBarry Smith ierr = ISRestoreIndices(is,&indices);CHKERRQ(ierr); 1453bbf0e92SBarry Smith } else { 1463bbf0e92SBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,n,indices,PETSC_OWN_POINTER,mapping);CHKERRQ(ierr); 1473bbf0e92SBarry Smith } 1483a40ed3dSBarry Smith PetscFunctionReturn(0); 1492bdab257SBarry Smith } 1505a5d4f66SBarry Smith 151a4d96a55SJed Brown #undef __FUNCT__ 152a4d96a55SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingCreateSF" 153a4d96a55SJed Brown /*@C 154a4d96a55SJed Brown ISLocalToGlobalMappingCreateSF - Creates a mapping between a local (0 to n) 155a4d96a55SJed Brown ordering and a global parallel ordering. 156a4d96a55SJed Brown 157a4d96a55SJed Brown Collective 158a4d96a55SJed Brown 159a4d96a55SJed Brown Input Parameter: 160a4d96a55SJed Brown + sf - star forest mapping contiguous local indices to (rank, offset) 161a4d96a55SJed Brown - start - first global index on this process 162a4d96a55SJed Brown 163a4d96a55SJed Brown Output Parameter: 164a4d96a55SJed Brown . mapping - new mapping data structure 165a4d96a55SJed Brown 166a4d96a55SJed Brown Level: advanced 167a4d96a55SJed Brown 168a4d96a55SJed Brown Concepts: mapping^local to global 169a4d96a55SJed Brown 170a4d96a55SJed Brown .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingCreateIS() 171a4d96a55SJed Brown @*/ 172a4d96a55SJed Brown PetscErrorCode ISLocalToGlobalMappingCreateSF(PetscSF sf,PetscInt start,ISLocalToGlobalMapping *mapping) 173a4d96a55SJed Brown { 174a4d96a55SJed Brown PetscErrorCode ierr; 175a4d96a55SJed Brown PetscInt i,maxlocal,nroots,nleaves,*globals,*ltog; 176a4d96a55SJed Brown const PetscInt *ilocal; 177a4d96a55SJed Brown MPI_Comm comm; 178a4d96a55SJed Brown 179a4d96a55SJed Brown PetscFunctionBegin; 180a4d96a55SJed Brown PetscValidHeaderSpecific(sf,PETSCSF_CLASSID,1); 181a4d96a55SJed Brown PetscValidPointer(mapping,3); 182a4d96a55SJed Brown 183a4d96a55SJed Brown ierr = PetscObjectGetComm((PetscObject)sf,&comm);CHKERRQ(ierr); 1840298fd71SBarry Smith ierr = PetscSFGetGraph(sf,&nroots,&nleaves,&ilocal,NULL);CHKERRQ(ierr); 185f6e5521dSKarl Rupp if (ilocal) { 186f6e5521dSKarl Rupp for (i=0,maxlocal=0; i<nleaves; i++) maxlocal = PetscMax(maxlocal,ilocal[i]+1); 187f6e5521dSKarl Rupp } 188a4d96a55SJed Brown else maxlocal = nleaves; 189785e854fSJed Brown ierr = PetscMalloc1(nroots,&globals);CHKERRQ(ierr); 190785e854fSJed Brown ierr = PetscMalloc1(maxlocal,<og);CHKERRQ(ierr); 191a4d96a55SJed Brown for (i=0; i<nroots; i++) globals[i] = start + i; 192a4d96a55SJed Brown for (i=0; i<maxlocal; i++) ltog[i] = -1; 193a4d96a55SJed Brown ierr = PetscSFBcastBegin(sf,MPIU_INT,globals,ltog);CHKERRQ(ierr); 194a4d96a55SJed Brown ierr = PetscSFBcastEnd(sf,MPIU_INT,globals,ltog);CHKERRQ(ierr); 195a4d96a55SJed Brown ierr = ISLocalToGlobalMappingCreate(comm,maxlocal,ltog,PETSC_OWN_POINTER,mapping);CHKERRQ(ierr); 196a4d96a55SJed Brown ierr = PetscFree(globals);CHKERRQ(ierr); 197a4d96a55SJed Brown PetscFunctionReturn(0); 198a4d96a55SJed Brown } 199b46b645bSBarry Smith 2004a2ae208SSatish Balay #undef __FUNCT__ 2014a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreate" 202ba5bb76aSSatish Balay /*@ 20390f02eecSBarry Smith ISLocalToGlobalMappingCreate - Creates a mapping between a local (0 to n) 20490f02eecSBarry Smith ordering and a global parallel ordering. 2052362add9SBarry Smith 20689d82c54SBarry Smith Not Collective, but communicator may have more than one process 207b9cd556bSLois Curfman McInnes 2082362add9SBarry Smith Input Parameters: 20989d82c54SBarry Smith + comm - MPI communicator 21090f02eecSBarry Smith . n - the number of local elements 2119669e4d8SBarry Smith . indices - the global index for each local element, these do not need to be in increasing order (sorted) 212d5ad8652SBarry Smith - mode - see PetscCopyMode 2132362add9SBarry Smith 214a997ad1aSLois Curfman McInnes Output Parameter: 21590f02eecSBarry Smith . mapping - new mapping data structure 2162362add9SBarry Smith 217a997ad1aSLois Curfman McInnes Level: advanced 218a997ad1aSLois Curfman McInnes 219273d9f13SBarry Smith Concepts: mapping^local to global 2202362add9SBarry Smith 221d5ad8652SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 2222362add9SBarry Smith @*/ 2237087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingCreate(MPI_Comm cm,PetscInt n,const PetscInt indices[],PetscCopyMode mode,ISLocalToGlobalMapping *mapping) 2242362add9SBarry Smith { 2256849ba73SBarry Smith PetscErrorCode ierr; 22632dcc486SBarry Smith PetscInt *in; 227b46b645bSBarry Smith 228b46b645bSBarry Smith PetscFunctionBegin; 22973911063SBarry Smith if (n) PetscValidIntPointer(indices,3); 2304482741eSBarry Smith PetscValidPointer(mapping,4); 231b46b645bSBarry Smith 2320298fd71SBarry Smith *mapping = NULL; 233607a6623SBarry Smith ierr = ISInitializePackage();CHKERRQ(ierr); 2342362add9SBarry Smith 23567c2884eSBarry Smith ierr = PetscHeaderCreate(*mapping,_p_ISLocalToGlobalMapping,int,IS_LTOGM_CLASSID,"ISLocalToGlobalMapping","Local to global mapping","IS", 23652e6d16bSBarry Smith cm,ISLocalToGlobalMappingDestroy,ISLocalToGlobalMappingView);CHKERRQ(ierr); 237d4bb536fSBarry Smith (*mapping)->n = n; 238d4bb536fSBarry Smith /* 239d4bb536fSBarry Smith Do not create the global to local mapping. This is only created if 240d4bb536fSBarry Smith ISGlobalToLocalMapping() is called 241d4bb536fSBarry Smith */ 242d4bb536fSBarry Smith (*mapping)->globals = 0; 243d5ad8652SBarry Smith if (mode == PETSC_COPY_VALUES) { 244785e854fSJed Brown ierr = PetscMalloc1(n,&in);CHKERRQ(ierr); 245d5ad8652SBarry Smith ierr = PetscMemcpy(in,indices,n*sizeof(PetscInt));CHKERRQ(ierr); 2463bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)*mapping,n*sizeof(PetscInt));CHKERRQ(ierr); 247d5ad8652SBarry Smith (*mapping)->indices = in; 248f6e5521dSKarl Rupp } else if (mode == PETSC_OWN_POINTER) (*mapping)->indices = (PetscInt*)indices; 249f6e5521dSKarl Rupp else SETERRQ(cm,PETSC_ERR_SUP,"Cannot currently use PETSC_USE_POINTER"); 2503a40ed3dSBarry Smith PetscFunctionReturn(0); 2512362add9SBarry Smith } 2522362add9SBarry Smith 2534a2ae208SSatish Balay #undef __FUNCT__ 2544a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingBlock" 255bce096a4SSatish Balay /*@ 256323b833fSBarry Smith ISLocalToGlobalMappingBlock - Creates a blocked index version of an 257323b833fSBarry Smith ISLocalToGlobalMapping that is appropriate for MatSetLocalToGlobalMappingBlock() 258323b833fSBarry Smith and VecSetLocalToGlobalMappingBlock(). 259323b833fSBarry Smith 260323b833fSBarry Smith Not Collective, but communicator may have more than one process 261323b833fSBarry Smith 262323b833fSBarry Smith Input Parameters: 263323b833fSBarry Smith + inmap - original point-wise mapping 264323b833fSBarry Smith - bs - block size 265323b833fSBarry Smith 266323b833fSBarry Smith Output Parameter: 26769eb54c3SBarry Smith . outmap - block based mapping; the indices are relative to BLOCKS, not individual vector or matrix entries. 268323b833fSBarry Smith 269323b833fSBarry Smith Level: advanced 270323b833fSBarry Smith 271323b833fSBarry Smith Concepts: mapping^local to global 272323b833fSBarry Smith 273323b833fSBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingCreateIS() 274323b833fSBarry Smith @*/ 2757087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingBlock(ISLocalToGlobalMapping inmap,PetscInt bs,ISLocalToGlobalMapping *outmap) 276323b833fSBarry Smith { 2776849ba73SBarry Smith PetscErrorCode ierr; 27832dcc486SBarry Smith PetscInt *ii,i,n; 279323b833fSBarry Smith 280323b833fSBarry Smith PetscFunctionBegin; 2810700a824SBarry Smith PetscValidHeaderSpecific(inmap,IS_LTOGM_CLASSID,1); 282b2beed0aSJed Brown PetscValidPointer(outmap,3); 283323b833fSBarry Smith if (bs > 1) { 284323b833fSBarry Smith n = inmap->n/bs; 285e32f2f54SBarry Smith if (n*bs != inmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Pointwise mapping length is not divisible by block size"); 286785e854fSJed Brown ierr = PetscMalloc1(n,&ii);CHKERRQ(ierr); 287f6e5521dSKarl Rupp for (i=0; i<n; i++) ii[i] = inmap->indices[bs*i]/bs; 288ce94432eSBarry Smith ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)inmap),n,ii,PETSC_OWN_POINTER,outmap);CHKERRQ(ierr); 289323b833fSBarry Smith } else { 290323b833fSBarry Smith ierr = PetscObjectReference((PetscObject)inmap);CHKERRQ(ierr); 291c3122656SLisandro Dalcin *outmap = inmap; 292323b833fSBarry Smith } 293323b833fSBarry Smith PetscFunctionReturn(0); 294323b833fSBarry Smith } 295323b833fSBarry Smith 2964a2ae208SSatish Balay #undef __FUNCT__ 2978ab951edSJed Brown #define __FUNCT__ "ISLocalToGlobalMappingUnBlock" 298b2beed0aSJed Brown /*@ 299b2beed0aSJed Brown ISLocalToGlobalMappingUnBlock - Creates a scalar index version of a blocked 300b2beed0aSJed Brown ISLocalToGlobalMapping 301b2beed0aSJed Brown 302b2beed0aSJed Brown Not Collective, but communicator may have more than one process 303b2beed0aSJed Brown 304b2beed0aSJed Brown Input Parameter: 305b2beed0aSJed Brown + inmap - block based mapping; the indices are relative to BLOCKS, not individual vector or matrix entries. 306b2beed0aSJed Brown - bs - block size 307b2beed0aSJed Brown 308b2beed0aSJed Brown Output Parameter: 309b2beed0aSJed Brown . outmap - pointwise mapping 310b2beed0aSJed Brown 311b2beed0aSJed Brown Level: advanced 312b2beed0aSJed Brown 313b2beed0aSJed Brown Concepts: mapping^local to global 314b2beed0aSJed Brown 315b2beed0aSJed Brown .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingBlock() 316b2beed0aSJed Brown @*/ 3177087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingUnBlock(ISLocalToGlobalMapping inmap,PetscInt bs,ISLocalToGlobalMapping *outmap) 318b2beed0aSJed Brown { 319b2beed0aSJed Brown PetscErrorCode ierr; 320b2beed0aSJed Brown PetscInt *ii,i,n; 321b2beed0aSJed Brown 322b2beed0aSJed Brown PetscFunctionBegin; 323b2beed0aSJed Brown PetscValidHeaderSpecific(inmap,IS_LTOGM_CLASSID,1); 324b2beed0aSJed Brown PetscValidPointer(outmap,2); 325b2beed0aSJed Brown if (bs > 1) { 326b2beed0aSJed Brown n = inmap->n*bs; 327785e854fSJed Brown ierr = PetscMalloc1(n,&ii);CHKERRQ(ierr); 328f6e5521dSKarl Rupp for (i=0; i<n; i++) ii[i] = inmap->indices[i/bs]*bs + (i%bs); 329ce94432eSBarry Smith ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)inmap),n,ii,PETSC_OWN_POINTER,outmap);CHKERRQ(ierr); 330b2beed0aSJed Brown } else { 331b2beed0aSJed Brown ierr = PetscObjectReference((PetscObject)inmap);CHKERRQ(ierr); 332b2beed0aSJed Brown *outmap = inmap; 333b2beed0aSJed Brown } 334b2beed0aSJed Brown PetscFunctionReturn(0); 335b2beed0aSJed Brown } 336b2beed0aSJed Brown 337b2beed0aSJed Brown #undef __FUNCT__ 3384a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingDestroy" 33990f02eecSBarry Smith /*@ 34090f02eecSBarry Smith ISLocalToGlobalMappingDestroy - Destroys a mapping between a local (0 to n) 34190f02eecSBarry Smith ordering and a global parallel ordering. 34290f02eecSBarry Smith 3430f5bd95cSBarry Smith Note Collective 344b9cd556bSLois Curfman McInnes 34590f02eecSBarry Smith Input Parameters: 34690f02eecSBarry Smith . mapping - mapping data structure 34790f02eecSBarry Smith 348a997ad1aSLois Curfman McInnes Level: advanced 349a997ad1aSLois Curfman McInnes 3503acfe500SLois Curfman McInnes .seealso: ISLocalToGlobalMappingCreate() 35190f02eecSBarry Smith @*/ 3526bf464f9SBarry Smith PetscErrorCode ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping *mapping) 35390f02eecSBarry Smith { 354dfbe8321SBarry Smith PetscErrorCode ierr; 3555fd66863SKarl Rupp 3563a40ed3dSBarry Smith PetscFunctionBegin; 3576bf464f9SBarry Smith if (!*mapping) PetscFunctionReturn(0); 3586bf464f9SBarry Smith PetscValidHeaderSpecific((*mapping),IS_LTOGM_CLASSID,1); 359997056adSBarry Smith if (--((PetscObject)(*mapping))->refct > 0) {*mapping = 0;PetscFunctionReturn(0);} 3606bf464f9SBarry Smith ierr = PetscFree((*mapping)->indices);CHKERRQ(ierr); 3616bf464f9SBarry Smith ierr = PetscFree((*mapping)->globals);CHKERRQ(ierr); 362d38fa0fbSBarry Smith ierr = PetscHeaderDestroy(mapping);CHKERRQ(ierr); 363992144d0SBarry Smith *mapping = 0; 3643a40ed3dSBarry Smith PetscFunctionReturn(0); 36590f02eecSBarry Smith } 36690f02eecSBarry Smith 3674a2ae208SSatish Balay #undef __FUNCT__ 3684a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingApplyIS" 36990f02eecSBarry Smith /*@ 3703acfe500SLois Curfman McInnes ISLocalToGlobalMappingApplyIS - Creates from an IS in the local numbering 3713acfe500SLois Curfman McInnes a new index set using the global numbering defined in an ISLocalToGlobalMapping 3723acfe500SLois Curfman McInnes context. 37390f02eecSBarry Smith 374b9cd556bSLois Curfman McInnes Not collective 375b9cd556bSLois Curfman McInnes 37690f02eecSBarry Smith Input Parameters: 377b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 378b9cd556bSLois Curfman McInnes - is - index set in local numbering 37990f02eecSBarry Smith 38090f02eecSBarry Smith Output Parameters: 38190f02eecSBarry Smith . newis - index set in global numbering 38290f02eecSBarry Smith 383a997ad1aSLois Curfman McInnes Level: advanced 384a997ad1aSLois Curfman McInnes 385273d9f13SBarry Smith Concepts: mapping^local to global 3863acfe500SLois Curfman McInnes 38790f02eecSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 388d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy(), ISGlobalToLocalMappingApply() 38990f02eecSBarry Smith @*/ 3907087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping,IS is,IS *newis) 39190f02eecSBarry Smith { 3926849ba73SBarry Smith PetscErrorCode ierr; 3935d0c19d7SBarry Smith PetscInt n,i,*idxmap,*idxout,Nmax = mapping->n; 3945d0c19d7SBarry Smith const PetscInt *idxin; 3953a40ed3dSBarry Smith 3963a40ed3dSBarry Smith PetscFunctionBegin; 3970700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 3980700a824SBarry Smith PetscValidHeaderSpecific(is,IS_CLASSID,2); 3994482741eSBarry Smith PetscValidPointer(newis,3); 40090f02eecSBarry Smith 4013b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 40290f02eecSBarry Smith ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 40390f02eecSBarry Smith idxmap = mapping->indices; 40490f02eecSBarry Smith 405785e854fSJed Brown ierr = PetscMalloc1(n,&idxout);CHKERRQ(ierr); 40690f02eecSBarry Smith for (i=0; i<n; i++) { 4077904a332SBarry Smith if (idxin[i] >= Nmax) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local index %D too large %D (max) at %D",idxin[i],Nmax-1,i); 40890f02eecSBarry Smith idxout[i] = idxmap[idxin[i]]; 40990f02eecSBarry Smith } 4103b9aefa3SBarry Smith ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 411543f3098SMatthew G. Knepley ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is),n,idxout,PETSC_OWN_POINTER,newis);CHKERRQ(ierr); 4123a40ed3dSBarry Smith PetscFunctionReturn(0); 41390f02eecSBarry Smith } 41490f02eecSBarry Smith 415afcb2eb5SJed Brown #undef __FUNCT__ 416afcb2eb5SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingApply" 417b89cb25eSSatish Balay /*@ 4183acfe500SLois Curfman McInnes ISLocalToGlobalMappingApply - Takes a list of integers in a local numbering 4193acfe500SLois Curfman McInnes and converts them to the global numbering. 42090f02eecSBarry Smith 421b9cd556bSLois Curfman McInnes Not collective 422b9cd556bSLois Curfman McInnes 423bb25748dSBarry Smith Input Parameters: 424b9cd556bSLois Curfman McInnes + mapping - the local to global mapping context 425bb25748dSBarry Smith . N - number of integers 426b9cd556bSLois Curfman McInnes - in - input indices in local numbering 427bb25748dSBarry Smith 428bb25748dSBarry Smith Output Parameter: 429bb25748dSBarry Smith . out - indices in global numbering 430bb25748dSBarry Smith 431b9cd556bSLois Curfman McInnes Notes: 432b9cd556bSLois Curfman McInnes The in and out array parameters may be identical. 433d4bb536fSBarry Smith 434a997ad1aSLois Curfman McInnes Level: advanced 435a997ad1aSLois Curfman McInnes 436bb25748dSBarry Smith .seealso: ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 4370752156aSBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 438d4bb536fSBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 439bb25748dSBarry Smith 440273d9f13SBarry Smith Concepts: mapping^local to global 441afcb2eb5SJed Brown @*/ 442afcb2eb5SJed Brown PetscErrorCode ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping,PetscInt N,const PetscInt in[],PetscInt out[]) 443afcb2eb5SJed Brown { 444afcb2eb5SJed Brown PetscInt i,Nmax = mapping->n; 445afcb2eb5SJed Brown const PetscInt *idx = mapping->indices; 446d4bb536fSBarry Smith 447afcb2eb5SJed Brown PetscFunctionBegin; 448afcb2eb5SJed Brown for (i=0; i<N; i++) { 449afcb2eb5SJed Brown if (in[i] < 0) { 450afcb2eb5SJed Brown out[i] = in[i]; 451afcb2eb5SJed Brown continue; 452afcb2eb5SJed Brown } 453afcb2eb5SJed Brown if (in[i] >= Nmax) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local index %D too large %D (max) at %D",in[i],Nmax,i); 454afcb2eb5SJed Brown out[i] = idx[in[i]]; 455afcb2eb5SJed Brown } 456afcb2eb5SJed Brown PetscFunctionReturn(0); 457afcb2eb5SJed Brown } 458d4bb536fSBarry Smith 459d4bb536fSBarry Smith /* -----------------------------------------------------------------------------------------*/ 460d4bb536fSBarry Smith 4614a2ae208SSatish Balay #undef __FUNCT__ 4624a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingSetUp_Private" 463d4bb536fSBarry Smith /* 464d4bb536fSBarry Smith Creates the global fields in the ISLocalToGlobalMapping structure 465d4bb536fSBarry Smith */ 4666849ba73SBarry Smith static PetscErrorCode ISGlobalToLocalMappingSetUp_Private(ISLocalToGlobalMapping mapping) 467d4bb536fSBarry Smith { 4686849ba73SBarry Smith PetscErrorCode ierr; 46932dcc486SBarry Smith PetscInt i,*idx = mapping->indices,n = mapping->n,end,start,*globals; 470d4bb536fSBarry Smith 4713a40ed3dSBarry Smith PetscFunctionBegin; 472d4bb536fSBarry Smith end = 0; 473ec268f7cSJed Brown start = PETSC_MAX_INT; 474d4bb536fSBarry Smith 475d4bb536fSBarry Smith for (i=0; i<n; i++) { 476d4bb536fSBarry Smith if (idx[i] < 0) continue; 477d4bb536fSBarry Smith if (idx[i] < start) start = idx[i]; 478d4bb536fSBarry Smith if (idx[i] > end) end = idx[i]; 479d4bb536fSBarry Smith } 480d4bb536fSBarry Smith if (start > end) {start = 0; end = -1;} 481d4bb536fSBarry Smith mapping->globalstart = start; 482d4bb536fSBarry Smith mapping->globalend = end; 483d4bb536fSBarry Smith 484785e854fSJed Brown ierr = PetscMalloc1((end-start+2),&globals);CHKERRQ(ierr); 485b0a32e0cSBarry Smith mapping->globals = globals; 486f6e5521dSKarl Rupp for (i=0; i<end-start+1; i++) globals[i] = -1; 487d4bb536fSBarry Smith for (i=0; i<n; i++) { 488d4bb536fSBarry Smith if (idx[i] < 0) continue; 489d4bb536fSBarry Smith globals[idx[i] - start] = i; 490d4bb536fSBarry Smith } 491d4bb536fSBarry Smith 4923bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mapping,(end-start+1)*sizeof(PetscInt));CHKERRQ(ierr); 4933a40ed3dSBarry Smith PetscFunctionReturn(0); 494d4bb536fSBarry Smith } 495d4bb536fSBarry Smith 4964a2ae208SSatish Balay #undef __FUNCT__ 4974a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingApply" 498d4bb536fSBarry Smith /*@ 499a997ad1aSLois Curfman McInnes ISGlobalToLocalMappingApply - Provides the local numbering for a list of integers 500a997ad1aSLois Curfman McInnes specified with a global numbering. 501d4bb536fSBarry Smith 502b9cd556bSLois Curfman McInnes Not collective 503b9cd556bSLois Curfman McInnes 504d4bb536fSBarry Smith Input Parameters: 505b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 506d4bb536fSBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 507d4bb536fSBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 508d4bb536fSBarry Smith . n - number of global indices to map 509b9cd556bSLois Curfman McInnes - idx - global indices to map 510d4bb536fSBarry Smith 511d4bb536fSBarry Smith Output Parameters: 512b9cd556bSLois Curfman McInnes + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 513b9cd556bSLois Curfman McInnes - idxout - local index of each global index, one must pass in an array long enough 514e182c471SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApply() with 5150298fd71SBarry Smith idxout == NULL to determine the required length (returned in nout) 516e182c471SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApply() 517e182c471SBarry Smith a second time to set the values. 518d4bb536fSBarry Smith 519b9cd556bSLois Curfman McInnes Notes: 5200298fd71SBarry Smith Either nout or idxout may be NULL. idx and idxout may be identical. 521d4bb536fSBarry Smith 5220f5bd95cSBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 5230f5bd95cSBarry Smith array to compute these. 5240f5bd95cSBarry Smith 525a997ad1aSLois Curfman McInnes Level: advanced 526a997ad1aSLois Curfman McInnes 52732fd6b96SBarry Smith Developer Note: The manual page states that idx and idxout may be identical but the calling 52832fd6b96SBarry Smith sequence declares idx as const so it cannot be the same as idxout. 52932fd6b96SBarry Smith 530273d9f13SBarry Smith Concepts: mapping^global to local 531d4bb536fSBarry Smith 532d4bb536fSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 533d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy() 534d4bb536fSBarry Smith @*/ 5357087cfbeSBarry Smith PetscErrorCode ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 53632dcc486SBarry Smith PetscInt n,const PetscInt idx[],PetscInt *nout,PetscInt idxout[]) 537d4bb536fSBarry Smith { 53832dcc486SBarry Smith PetscInt i,*globals,nf = 0,tmp,start,end; 5396849ba73SBarry Smith PetscErrorCode ierr; 540d4bb536fSBarry Smith 5413a40ed3dSBarry Smith PetscFunctionBegin; 5420700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 543d4bb536fSBarry Smith if (!mapping->globals) { 544d4bb536fSBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 545d4bb536fSBarry Smith } 546d4bb536fSBarry Smith globals = mapping->globals; 547d4bb536fSBarry Smith start = mapping->globalstart; 548d4bb536fSBarry Smith end = mapping->globalend; 549d4bb536fSBarry Smith 550d4bb536fSBarry Smith if (type == IS_GTOLM_MASK) { 551d4bb536fSBarry Smith if (idxout) { 552d4bb536fSBarry Smith for (i=0; i<n; i++) { 553d4bb536fSBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 554d4bb536fSBarry Smith else if (idx[i] < start) idxout[i] = -1; 555d4bb536fSBarry Smith else if (idx[i] > end) idxout[i] = -1; 556d4bb536fSBarry Smith else idxout[i] = globals[idx[i] - start]; 557d4bb536fSBarry Smith } 558d4bb536fSBarry Smith } 559d4bb536fSBarry Smith if (nout) *nout = n; 560d4bb536fSBarry Smith } else { 561d4bb536fSBarry Smith if (idxout) { 562d4bb536fSBarry Smith for (i=0; i<n; i++) { 563d4bb536fSBarry Smith if (idx[i] < 0) continue; 564d4bb536fSBarry Smith if (idx[i] < start) continue; 565d4bb536fSBarry Smith if (idx[i] > end) continue; 566d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 567d4bb536fSBarry Smith if (tmp < 0) continue; 568d4bb536fSBarry Smith idxout[nf++] = tmp; 569d4bb536fSBarry Smith } 570d4bb536fSBarry Smith } else { 571d4bb536fSBarry Smith for (i=0; i<n; i++) { 572d4bb536fSBarry Smith if (idx[i] < 0) continue; 573d4bb536fSBarry Smith if (idx[i] < start) continue; 574d4bb536fSBarry Smith if (idx[i] > end) continue; 575d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 576d4bb536fSBarry Smith if (tmp < 0) continue; 577d4bb536fSBarry Smith nf++; 578d4bb536fSBarry Smith } 579d4bb536fSBarry Smith } 580d4bb536fSBarry Smith if (nout) *nout = nf; 581d4bb536fSBarry Smith } 5823a40ed3dSBarry Smith PetscFunctionReturn(0); 583d4bb536fSBarry Smith } 58490f02eecSBarry Smith 5854a2ae208SSatish Balay #undef __FUNCT__ 5864a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingGetInfo" 58789d82c54SBarry Smith /*@C 58889d82c54SBarry Smith ISLocalToGlobalMappingGetInfo - Gets the neighbor information for each processor and 58989d82c54SBarry Smith each index shared by more than one processor 59089d82c54SBarry Smith 59189d82c54SBarry Smith Collective on ISLocalToGlobalMapping 59289d82c54SBarry Smith 59389d82c54SBarry Smith Input Parameters: 59489d82c54SBarry Smith . mapping - the mapping from local to global indexing 59589d82c54SBarry Smith 59689d82c54SBarry Smith Output Parameter: 59789d82c54SBarry Smith + nproc - number of processors that are connected to this one 59889d82c54SBarry Smith . proc - neighboring processors 59907b52d57SBarry Smith . numproc - number of indices for each subdomain (processor) 6003463a7baSJed Brown - indices - indices of nodes (in local numbering) shared with neighbors (sorted by global numbering) 60189d82c54SBarry Smith 60289d82c54SBarry Smith Level: advanced 60389d82c54SBarry Smith 604273d9f13SBarry Smith Concepts: mapping^local to global 60589d82c54SBarry Smith 6062cfcea29SBarry Smith Fortran Usage: 6072cfcea29SBarry Smith $ ISLocalToGlobalMpngGetInfoSize(ISLocalToGlobalMapping,PetscInt nproc,PetscInt numprocmax,ierr) followed by 6082cfcea29SBarry Smith $ ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping,PetscInt nproc, PetscInt procs[nproc],PetscInt numprocs[nproc], 6092cfcea29SBarry Smith PetscInt indices[nproc][numprocmax],ierr) 6102cfcea29SBarry Smith There is no ISLocalToGlobalMappingRestoreInfo() in Fortran. You must make sure that procs[], numprocs[] and 6112cfcea29SBarry Smith indices[][] are large enough arrays, either by allocating them dynamically or defining static ones large enough. 6122cfcea29SBarry Smith 6132cfcea29SBarry Smith 61407b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 61507b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo() 61689d82c54SBarry Smith @*/ 6177087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 61889d82c54SBarry Smith { 6196849ba73SBarry Smith PetscErrorCode ierr; 62097f1f81fSBarry Smith PetscMPIInt size,rank,tag1,tag2,tag3,*len,*source,imdex; 62132dcc486SBarry Smith PetscInt i,n = mapping->n,Ng,ng,max = 0,*lindices = mapping->indices; 62232dcc486SBarry Smith PetscInt *nprocs,*owner,nsends,*sends,j,*starts,nmax,nrecvs,*recvs,proc; 62397f1f81fSBarry Smith PetscInt cnt,scale,*ownedsenders,*nownedsenders,rstart,nowned; 62432dcc486SBarry Smith PetscInt node,nownedm,nt,*sends2,nsends2,*starts2,*lens2,*dest,nrecvs2,*starts3,*recvs2,k,*bprocs,*tmp; 62532dcc486SBarry Smith PetscInt first_procs,first_numprocs,*first_indices; 62689d82c54SBarry Smith MPI_Request *recv_waits,*send_waits; 62730dcb7c9SBarry Smith MPI_Status recv_status,*send_status,*recv_statuses; 628ce94432eSBarry Smith MPI_Comm comm; 629ace3abfcSBarry Smith PetscBool debug = PETSC_FALSE; 63089d82c54SBarry Smith 63189d82c54SBarry Smith PetscFunctionBegin; 6320700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 633ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)mapping,&comm);CHKERRQ(ierr); 63424cf384cSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 63524cf384cSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 63624cf384cSBarry Smith if (size == 1) { 63724cf384cSBarry Smith *nproc = 0; 6380298fd71SBarry Smith *procs = NULL; 63932dcc486SBarry Smith ierr = PetscMalloc(sizeof(PetscInt),numprocs);CHKERRQ(ierr); 6401e2105dcSBarry Smith (*numprocs)[0] = 0; 64132dcc486SBarry Smith ierr = PetscMalloc(sizeof(PetscInt*),indices);CHKERRQ(ierr); 6420298fd71SBarry Smith (*indices)[0] = NULL; 64324cf384cSBarry Smith PetscFunctionReturn(0); 64424cf384cSBarry Smith } 64524cf384cSBarry Smith 6460298fd71SBarry Smith ierr = PetscOptionsGetBool(NULL,"-islocaltoglobalmappinggetinfo_debug",&debug,NULL);CHKERRQ(ierr); 64707b52d57SBarry Smith 6483677ff5aSBarry Smith /* 6493677ff5aSBarry Smith Notes on ISLocalToGlobalMappingGetInfo 6503677ff5aSBarry Smith 6513677ff5aSBarry Smith globally owned node - the nodes that have been assigned to this processor in global 6523677ff5aSBarry Smith numbering, just for this routine. 6533677ff5aSBarry Smith 6543677ff5aSBarry Smith nontrivial globally owned node - node assigned to this processor that is on a subdomain 6553677ff5aSBarry Smith boundary (i.e. is has more than one local owner) 6563677ff5aSBarry Smith 6573677ff5aSBarry Smith locally owned node - node that exists on this processors subdomain 6583677ff5aSBarry Smith 6593677ff5aSBarry Smith nontrivial locally owned node - node that is not in the interior (i.e. has more than one 6603677ff5aSBarry Smith local subdomain 6613677ff5aSBarry Smith */ 66224cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag1);CHKERRQ(ierr); 66324cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag2);CHKERRQ(ierr); 66424cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag3);CHKERRQ(ierr); 66589d82c54SBarry Smith 66689d82c54SBarry Smith for (i=0; i<n; i++) { 66789d82c54SBarry Smith if (lindices[i] > max) max = lindices[i]; 66889d82c54SBarry Smith } 66932dcc486SBarry Smith ierr = MPI_Allreduce(&max,&Ng,1,MPIU_INT,MPI_MAX,comm);CHKERRQ(ierr); 67078058e43SBarry Smith Ng++; 67189d82c54SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 67289d82c54SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 673bc8ff85bSBarry Smith scale = Ng/size + 1; 674a2e34c3dSBarry Smith ng = scale; if (rank == size-1) ng = Ng - scale*(size-1); ng = PetscMax(1,ng); 675caba0dd0SBarry Smith rstart = scale*rank; 67689d82c54SBarry Smith 67789d82c54SBarry Smith /* determine ownership ranges of global indices */ 678785e854fSJed Brown ierr = PetscMalloc1(2*size,&nprocs);CHKERRQ(ierr); 67932dcc486SBarry Smith ierr = PetscMemzero(nprocs,2*size*sizeof(PetscInt));CHKERRQ(ierr); 68089d82c54SBarry Smith 68189d82c54SBarry Smith /* determine owners of each local node */ 682785e854fSJed Brown ierr = PetscMalloc1(n,&owner);CHKERRQ(ierr); 68389d82c54SBarry Smith for (i=0; i<n; i++) { 6843677ff5aSBarry Smith proc = lindices[i]/scale; /* processor that globally owns this index */ 68527c402fcSBarry Smith nprocs[2*proc+1] = 1; /* processor globally owns at least one of ours */ 6863677ff5aSBarry Smith owner[i] = proc; 68727c402fcSBarry Smith nprocs[2*proc]++; /* count of how many that processor globally owns of ours */ 68889d82c54SBarry Smith } 68927c402fcSBarry Smith nsends = 0; for (i=0; i<size; i++) nsends += nprocs[2*i+1]; 6907904a332SBarry Smith ierr = PetscInfo1(mapping,"Number of global owners for my local data %D\n",nsends);CHKERRQ(ierr); 69189d82c54SBarry Smith 69289d82c54SBarry Smith /* inform other processors of number of messages and max length*/ 69327c402fcSBarry Smith ierr = PetscMaxSum(comm,nprocs,&nmax,&nrecvs);CHKERRQ(ierr); 6947904a332SBarry Smith ierr = PetscInfo1(mapping,"Number of local owners for my global data %D\n",nrecvs);CHKERRQ(ierr); 69589d82c54SBarry Smith 69689d82c54SBarry Smith /* post receives for owned rows */ 697785e854fSJed Brown ierr = PetscMalloc1((2*nrecvs+1)*(nmax+1),&recvs);CHKERRQ(ierr); 698785e854fSJed Brown ierr = PetscMalloc1((nrecvs+1),&recv_waits);CHKERRQ(ierr); 69989d82c54SBarry Smith for (i=0; i<nrecvs; i++) { 70032dcc486SBarry Smith ierr = MPI_Irecv(recvs+2*nmax*i,2*nmax,MPIU_INT,MPI_ANY_SOURCE,tag1,comm,recv_waits+i);CHKERRQ(ierr); 70189d82c54SBarry Smith } 70289d82c54SBarry Smith 70389d82c54SBarry Smith /* pack messages containing lists of local nodes to owners */ 704785e854fSJed Brown ierr = PetscMalloc1((2*n+1),&sends);CHKERRQ(ierr); 705785e854fSJed Brown ierr = PetscMalloc1((size+1),&starts);CHKERRQ(ierr); 70689d82c54SBarry Smith starts[0] = 0; 707f6e5521dSKarl Rupp for (i=1; i<size; i++) starts[i] = starts[i-1] + 2*nprocs[2*i-2]; 70889d82c54SBarry Smith for (i=0; i<n; i++) { 70989d82c54SBarry Smith sends[starts[owner[i]]++] = lindices[i]; 71030dcb7c9SBarry Smith sends[starts[owner[i]]++] = i; 71189d82c54SBarry Smith } 71289d82c54SBarry Smith ierr = PetscFree(owner);CHKERRQ(ierr); 71389d82c54SBarry Smith starts[0] = 0; 714f6e5521dSKarl Rupp for (i=1; i<size; i++) starts[i] = starts[i-1] + 2*nprocs[2*i-2]; 71589d82c54SBarry Smith 71689d82c54SBarry Smith /* send the messages */ 717785e854fSJed Brown ierr = PetscMalloc1((nsends+1),&send_waits);CHKERRQ(ierr); 718785e854fSJed Brown ierr = PetscMalloc1((nsends+1),&dest);CHKERRQ(ierr); 71989d82c54SBarry Smith cnt = 0; 72089d82c54SBarry Smith for (i=0; i<size; i++) { 72127c402fcSBarry Smith if (nprocs[2*i]) { 72232dcc486SBarry Smith ierr = MPI_Isend(sends+starts[i],2*nprocs[2*i],MPIU_INT,i,tag1,comm,send_waits+cnt);CHKERRQ(ierr); 72330dcb7c9SBarry Smith dest[cnt] = i; 72489d82c54SBarry Smith cnt++; 72589d82c54SBarry Smith } 72689d82c54SBarry Smith } 72789d82c54SBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 72889d82c54SBarry Smith 72989d82c54SBarry Smith /* wait on receives */ 730785e854fSJed Brown ierr = PetscMalloc1((nrecvs+1),&source);CHKERRQ(ierr); 731785e854fSJed Brown ierr = PetscMalloc1((nrecvs+1),&len);CHKERRQ(ierr); 73289d82c54SBarry Smith cnt = nrecvs; 733785e854fSJed Brown ierr = PetscMalloc1((ng+1),&nownedsenders);CHKERRQ(ierr); 73432dcc486SBarry Smith ierr = PetscMemzero(nownedsenders,ng*sizeof(PetscInt));CHKERRQ(ierr); 73589d82c54SBarry Smith while (cnt) { 73689d82c54SBarry Smith ierr = MPI_Waitany(nrecvs,recv_waits,&imdex,&recv_status);CHKERRQ(ierr); 73789d82c54SBarry Smith /* unpack receives into our local space */ 73832dcc486SBarry Smith ierr = MPI_Get_count(&recv_status,MPIU_INT,&len[imdex]);CHKERRQ(ierr); 73989d82c54SBarry Smith source[imdex] = recv_status.MPI_SOURCE; 74030dcb7c9SBarry Smith len[imdex] = len[imdex]/2; 741caba0dd0SBarry Smith /* count how many local owners for each of my global owned indices */ 74230dcb7c9SBarry Smith for (i=0; i<len[imdex]; i++) nownedsenders[recvs[2*imdex*nmax+2*i]-rstart]++; 74389d82c54SBarry Smith cnt--; 74489d82c54SBarry Smith } 74589d82c54SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 74689d82c54SBarry Smith 74730dcb7c9SBarry Smith /* count how many globally owned indices are on an edge multiplied by how many processors own them. */ 748bc8ff85bSBarry Smith nowned = 0; 749bc8ff85bSBarry Smith nownedm = 0; 750bc8ff85bSBarry Smith for (i=0; i<ng; i++) { 751bc8ff85bSBarry Smith if (nownedsenders[i] > 1) {nownedm += nownedsenders[i]; nowned++;} 752bc8ff85bSBarry Smith } 753bc8ff85bSBarry Smith 754bc8ff85bSBarry Smith /* create single array to contain rank of all local owners of each globally owned index */ 755785e854fSJed Brown ierr = PetscMalloc1((nownedm+1),&ownedsenders);CHKERRQ(ierr); 756785e854fSJed Brown ierr = PetscMalloc1((ng+1),&starts);CHKERRQ(ierr); 757bc8ff85bSBarry Smith starts[0] = 0; 758bc8ff85bSBarry Smith for (i=1; i<ng; i++) { 759bc8ff85bSBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 760bc8ff85bSBarry Smith else starts[i] = starts[i-1]; 761bc8ff85bSBarry Smith } 762bc8ff85bSBarry Smith 76330dcb7c9SBarry Smith /* for each nontrival globally owned node list all arriving processors */ 764bc8ff85bSBarry Smith for (i=0; i<nrecvs; i++) { 765bc8ff85bSBarry Smith for (j=0; j<len[i]; j++) { 76630dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 767f6e5521dSKarl Rupp if (nownedsenders[node] > 1) ownedsenders[starts[node]++] = source[i]; 768bc8ff85bSBarry Smith } 769bc8ff85bSBarry Smith } 770bc8ff85bSBarry Smith 77107b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 77230dcb7c9SBarry Smith starts[0] = 0; 77330dcb7c9SBarry Smith for (i=1; i<ng; i++) { 77430dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 77530dcb7c9SBarry Smith else starts[i] = starts[i-1]; 77630dcb7c9SBarry Smith } 77730dcb7c9SBarry Smith for (i=0; i<ng; i++) { 77830dcb7c9SBarry Smith if (nownedsenders[i] > 1) { 7797904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] global node %D local owner processors: ",rank,i+rstart);CHKERRQ(ierr); 78030dcb7c9SBarry Smith for (j=0; j<nownedsenders[i]; j++) { 7817904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",ownedsenders[starts[i]+j]);CHKERRQ(ierr); 78230dcb7c9SBarry Smith } 78330dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 78430dcb7c9SBarry Smith } 78530dcb7c9SBarry Smith } 7860ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 78707b52d57SBarry Smith } /* ----------------------------------- */ 78830dcb7c9SBarry Smith 7893677ff5aSBarry Smith /* wait on original sends */ 7903a96401aSBarry Smith if (nsends) { 791785e854fSJed Brown ierr = PetscMalloc1(nsends,&send_status);CHKERRQ(ierr); 7923a96401aSBarry Smith ierr = MPI_Waitall(nsends,send_waits,send_status);CHKERRQ(ierr); 7933a96401aSBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 7943a96401aSBarry Smith } 79589d82c54SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 7963a96401aSBarry Smith ierr = PetscFree(sends);CHKERRQ(ierr); 7973677ff5aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 7983677ff5aSBarry Smith 7993677ff5aSBarry Smith /* pack messages to send back to local owners */ 80030dcb7c9SBarry Smith starts[0] = 0; 80130dcb7c9SBarry Smith for (i=1; i<ng; i++) { 80230dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 80330dcb7c9SBarry Smith else starts[i] = starts[i-1]; 80430dcb7c9SBarry Smith } 80530dcb7c9SBarry Smith nsends2 = nrecvs; 806785e854fSJed Brown ierr = PetscMalloc1((nsends2+1),&nprocs);CHKERRQ(ierr); /* length of each message */ 80730dcb7c9SBarry Smith for (i=0; i<nrecvs; i++) { 80830dcb7c9SBarry Smith nprocs[i] = 1; 80930dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 81030dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 811f6e5521dSKarl Rupp if (nownedsenders[node] > 1) nprocs[i] += 2 + nownedsenders[node]; 81230dcb7c9SBarry Smith } 81330dcb7c9SBarry Smith } 814f6e5521dSKarl Rupp nt = 0; 815f6e5521dSKarl Rupp for (i=0; i<nsends2; i++) nt += nprocs[i]; 816f6e5521dSKarl Rupp 817785e854fSJed Brown ierr = PetscMalloc1((nt+1),&sends2);CHKERRQ(ierr); 818785e854fSJed Brown ierr = PetscMalloc1((nsends2+1),&starts2);CHKERRQ(ierr); 819f6e5521dSKarl Rupp 820f6e5521dSKarl Rupp starts2[0] = 0; 821f6e5521dSKarl Rupp for (i=1; i<nsends2; i++) starts2[i] = starts2[i-1] + nprocs[i-1]; 82230dcb7c9SBarry Smith /* 82330dcb7c9SBarry Smith Each message is 1 + nprocs[i] long, and consists of 82430dcb7c9SBarry Smith (0) the number of nodes being sent back 82530dcb7c9SBarry Smith (1) the local node number, 82630dcb7c9SBarry Smith (2) the number of processors sharing it, 82730dcb7c9SBarry Smith (3) the processors sharing it 82830dcb7c9SBarry Smith */ 82930dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 83030dcb7c9SBarry Smith cnt = 1; 83130dcb7c9SBarry Smith sends2[starts2[i]] = 0; 83230dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 83330dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 83430dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 83530dcb7c9SBarry Smith sends2[starts2[i]]++; 83630dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = recvs[2*i*nmax+2*j+1]; 83730dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = nownedsenders[node]; 83832dcc486SBarry Smith ierr = PetscMemcpy(&sends2[starts2[i]+cnt],&ownedsenders[starts[node]],nownedsenders[node]*sizeof(PetscInt));CHKERRQ(ierr); 83930dcb7c9SBarry Smith cnt += nownedsenders[node]; 84030dcb7c9SBarry Smith } 84130dcb7c9SBarry Smith } 84230dcb7c9SBarry Smith } 84330dcb7c9SBarry Smith 84430dcb7c9SBarry Smith /* receive the message lengths */ 84530dcb7c9SBarry Smith nrecvs2 = nsends; 846785e854fSJed Brown ierr = PetscMalloc1((nrecvs2+1),&lens2);CHKERRQ(ierr); 847785e854fSJed Brown ierr = PetscMalloc1((nrecvs2+1),&starts3);CHKERRQ(ierr); 848785e854fSJed Brown ierr = PetscMalloc1((nrecvs2+1),&recv_waits);CHKERRQ(ierr); 84930dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 850d44834fbSBarry Smith ierr = MPI_Irecv(&lens2[i],1,MPIU_INT,dest[i],tag2,comm,recv_waits+i);CHKERRQ(ierr); 85130dcb7c9SBarry Smith } 852d44834fbSBarry Smith 8538a8e0b3aSBarry Smith /* send the message lengths */ 8548a8e0b3aSBarry Smith for (i=0; i<nsends2; i++) { 8558a8e0b3aSBarry Smith ierr = MPI_Send(&nprocs[i],1,MPIU_INT,source[i],tag2,comm);CHKERRQ(ierr); 8568a8e0b3aSBarry Smith } 8578a8e0b3aSBarry Smith 858d44834fbSBarry Smith /* wait on receives of lens */ 8590c468ba9SBarry Smith if (nrecvs2) { 860785e854fSJed Brown ierr = PetscMalloc1(nrecvs2,&recv_statuses);CHKERRQ(ierr); 861d44834fbSBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 862d44834fbSBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 8630c468ba9SBarry Smith } 864a2ea699eSBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 865d44834fbSBarry Smith 86630dcb7c9SBarry Smith starts3[0] = 0; 867d44834fbSBarry Smith nt = 0; 86830dcb7c9SBarry Smith for (i=0; i<nrecvs2-1; i++) { 86930dcb7c9SBarry Smith starts3[i+1] = starts3[i] + lens2[i]; 870d44834fbSBarry Smith nt += lens2[i]; 87130dcb7c9SBarry Smith } 87276466f69SStefano Zampini if (nrecvs2) nt += lens2[nrecvs2-1]; 873d44834fbSBarry Smith 874785e854fSJed Brown ierr = PetscMalloc1((nt+1),&recvs2);CHKERRQ(ierr); 875785e854fSJed Brown ierr = PetscMalloc1((nrecvs2+1),&recv_waits);CHKERRQ(ierr); 87652b72c4aSBarry Smith for (i=0; i<nrecvs2; i++) { 87732dcc486SBarry Smith ierr = MPI_Irecv(recvs2+starts3[i],lens2[i],MPIU_INT,dest[i],tag3,comm,recv_waits+i);CHKERRQ(ierr); 87830dcb7c9SBarry Smith } 87930dcb7c9SBarry Smith 88030dcb7c9SBarry Smith /* send the messages */ 881785e854fSJed Brown ierr = PetscMalloc1((nsends2+1),&send_waits);CHKERRQ(ierr); 88230dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 88332dcc486SBarry Smith ierr = MPI_Isend(sends2+starts2[i],nprocs[i],MPIU_INT,source[i],tag3,comm,send_waits+i);CHKERRQ(ierr); 88430dcb7c9SBarry Smith } 88530dcb7c9SBarry Smith 88630dcb7c9SBarry Smith /* wait on receives */ 8870c468ba9SBarry Smith if (nrecvs2) { 888785e854fSJed Brown ierr = PetscMalloc1(nrecvs2,&recv_statuses);CHKERRQ(ierr); 88930dcb7c9SBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 89030dcb7c9SBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 8910c468ba9SBarry Smith } 89230dcb7c9SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 89330dcb7c9SBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 89430dcb7c9SBarry Smith 89507b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 89630dcb7c9SBarry Smith cnt = 0; 89730dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 89830dcb7c9SBarry Smith nt = recvs2[cnt++]; 89930dcb7c9SBarry Smith for (j=0; j<nt; j++) { 9007904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] local node %D number of subdomains %D: ",rank,recvs2[cnt],recvs2[cnt+1]);CHKERRQ(ierr); 90130dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 9027904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",recvs2[cnt+2+k]);CHKERRQ(ierr); 90330dcb7c9SBarry Smith } 90430dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 90530dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 90630dcb7c9SBarry Smith } 90730dcb7c9SBarry Smith } 9080ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 90907b52d57SBarry Smith } /* ----------------------------------- */ 91030dcb7c9SBarry Smith 91130dcb7c9SBarry Smith /* count number subdomains for each local node */ 912785e854fSJed Brown ierr = PetscMalloc1(size,&nprocs);CHKERRQ(ierr); 91332dcc486SBarry Smith ierr = PetscMemzero(nprocs,size*sizeof(PetscInt));CHKERRQ(ierr); 91430dcb7c9SBarry Smith cnt = 0; 91530dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 91630dcb7c9SBarry Smith nt = recvs2[cnt++]; 91730dcb7c9SBarry Smith for (j=0; j<nt; j++) { 918f6e5521dSKarl Rupp for (k=0; k<recvs2[cnt+1]; k++) nprocs[recvs2[cnt+2+k]]++; 91930dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 92030dcb7c9SBarry Smith } 92130dcb7c9SBarry Smith } 92230dcb7c9SBarry Smith nt = 0; for (i=0; i<size; i++) nt += (nprocs[i] > 0); 92330dcb7c9SBarry Smith *nproc = nt; 924785e854fSJed Brown ierr = PetscMalloc1((nt+1),procs);CHKERRQ(ierr); 925785e854fSJed Brown ierr = PetscMalloc1((nt+1),numprocs);CHKERRQ(ierr); 926785e854fSJed Brown ierr = PetscMalloc1((nt+1),indices);CHKERRQ(ierr); 9270298fd71SBarry Smith for (i=0;i<nt+1;i++) (*indices)[i]=NULL; 928785e854fSJed Brown ierr = PetscMalloc1(size,&bprocs);CHKERRQ(ierr); 92930dcb7c9SBarry Smith cnt = 0; 93030dcb7c9SBarry Smith for (i=0; i<size; i++) { 93130dcb7c9SBarry Smith if (nprocs[i] > 0) { 93230dcb7c9SBarry Smith bprocs[i] = cnt; 93330dcb7c9SBarry Smith (*procs)[cnt] = i; 93430dcb7c9SBarry Smith (*numprocs)[cnt] = nprocs[i]; 935785e854fSJed Brown ierr = PetscMalloc1(nprocs[i],&(*indices)[cnt]);CHKERRQ(ierr); 93630dcb7c9SBarry Smith cnt++; 93730dcb7c9SBarry Smith } 93830dcb7c9SBarry Smith } 93930dcb7c9SBarry Smith 94030dcb7c9SBarry Smith /* make the list of subdomains for each nontrivial local node */ 94132dcc486SBarry Smith ierr = PetscMemzero(*numprocs,nt*sizeof(PetscInt));CHKERRQ(ierr); 94230dcb7c9SBarry Smith cnt = 0; 94330dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 94430dcb7c9SBarry Smith nt = recvs2[cnt++]; 94530dcb7c9SBarry Smith for (j=0; j<nt; j++) { 946f6e5521dSKarl Rupp for (k=0; k<recvs2[cnt+1]; k++) (*indices)[bprocs[recvs2[cnt+2+k]]][(*numprocs)[bprocs[recvs2[cnt+2+k]]]++] = recvs2[cnt]; 94730dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 94830dcb7c9SBarry Smith } 94930dcb7c9SBarry Smith } 95030dcb7c9SBarry Smith ierr = PetscFree(bprocs);CHKERRQ(ierr); 95107b52d57SBarry Smith ierr = PetscFree(recvs2);CHKERRQ(ierr); 95230dcb7c9SBarry Smith 95307b52d57SBarry Smith /* sort the node indexing by their global numbers */ 95407b52d57SBarry Smith nt = *nproc; 95507b52d57SBarry Smith for (i=0; i<nt; i++) { 956785e854fSJed Brown ierr = PetscMalloc1(((*numprocs)[i]),&tmp);CHKERRQ(ierr); 957f6e5521dSKarl Rupp for (j=0; j<(*numprocs)[i]; j++) tmp[j] = lindices[(*indices)[i][j]]; 95807b52d57SBarry Smith ierr = PetscSortIntWithArray((*numprocs)[i],tmp,(*indices)[i]);CHKERRQ(ierr); 95907b52d57SBarry Smith ierr = PetscFree(tmp);CHKERRQ(ierr); 96007b52d57SBarry Smith } 96107b52d57SBarry Smith 96207b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 96330dcb7c9SBarry Smith nt = *nproc; 96430dcb7c9SBarry Smith for (i=0; i<nt; i++) { 9657904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] subdomain %D number of indices %D: ",rank,(*procs)[i],(*numprocs)[i]);CHKERRQ(ierr); 96630dcb7c9SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 9677904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",(*indices)[i][j]);CHKERRQ(ierr); 96830dcb7c9SBarry Smith } 96930dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 97030dcb7c9SBarry Smith } 9710ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 97207b52d57SBarry Smith } /* ----------------------------------- */ 97330dcb7c9SBarry Smith 97430dcb7c9SBarry Smith /* wait on sends */ 97530dcb7c9SBarry Smith if (nsends2) { 976785e854fSJed Brown ierr = PetscMalloc1(nsends2,&send_status);CHKERRQ(ierr); 97730dcb7c9SBarry Smith ierr = MPI_Waitall(nsends2,send_waits,send_status);CHKERRQ(ierr); 97830dcb7c9SBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 97930dcb7c9SBarry Smith } 98030dcb7c9SBarry Smith 98130dcb7c9SBarry Smith ierr = PetscFree(starts3);CHKERRQ(ierr); 98230dcb7c9SBarry Smith ierr = PetscFree(dest);CHKERRQ(ierr); 98330dcb7c9SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 9843677ff5aSBarry Smith 985bc8ff85bSBarry Smith ierr = PetscFree(nownedsenders);CHKERRQ(ierr); 986bc8ff85bSBarry Smith ierr = PetscFree(ownedsenders);CHKERRQ(ierr); 987bc8ff85bSBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 98830dcb7c9SBarry Smith ierr = PetscFree(starts2);CHKERRQ(ierr); 98930dcb7c9SBarry Smith ierr = PetscFree(lens2);CHKERRQ(ierr); 99089d82c54SBarry Smith 99189d82c54SBarry Smith ierr = PetscFree(source);CHKERRQ(ierr); 99297f1f81fSBarry Smith ierr = PetscFree(len);CHKERRQ(ierr); 99389d82c54SBarry Smith ierr = PetscFree(recvs);CHKERRQ(ierr); 9943a96401aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 99530dcb7c9SBarry Smith ierr = PetscFree(sends2);CHKERRQ(ierr); 99624cf384cSBarry Smith 99724cf384cSBarry Smith /* put the information about myself as the first entry in the list */ 99824cf384cSBarry Smith first_procs = (*procs)[0]; 99924cf384cSBarry Smith first_numprocs = (*numprocs)[0]; 100024cf384cSBarry Smith first_indices = (*indices)[0]; 100124cf384cSBarry Smith for (i=0; i<*nproc; i++) { 100224cf384cSBarry Smith if ((*procs)[i] == rank) { 100324cf384cSBarry Smith (*procs)[0] = (*procs)[i]; 100424cf384cSBarry Smith (*numprocs)[0] = (*numprocs)[i]; 100524cf384cSBarry Smith (*indices)[0] = (*indices)[i]; 100624cf384cSBarry Smith (*procs)[i] = first_procs; 100724cf384cSBarry Smith (*numprocs)[i] = first_numprocs; 100824cf384cSBarry Smith (*indices)[i] = first_indices; 100924cf384cSBarry Smith break; 101024cf384cSBarry Smith } 101124cf384cSBarry Smith } 101289d82c54SBarry Smith PetscFunctionReturn(0); 101389d82c54SBarry Smith } 101489d82c54SBarry Smith 10154a2ae208SSatish Balay #undef __FUNCT__ 10164a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingRestoreInfo" 101707b52d57SBarry Smith /*@C 101807b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo - Frees the memory allocated by ISLocalToGlobalMappingGetInfo() 101989d82c54SBarry Smith 102007b52d57SBarry Smith Collective on ISLocalToGlobalMapping 102107b52d57SBarry Smith 102207b52d57SBarry Smith Input Parameters: 102307b52d57SBarry Smith . mapping - the mapping from local to global indexing 102407b52d57SBarry Smith 102507b52d57SBarry Smith Output Parameter: 102607b52d57SBarry Smith + nproc - number of processors that are connected to this one 102707b52d57SBarry Smith . proc - neighboring processors 102807b52d57SBarry Smith . numproc - number of indices for each processor 102907b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 103007b52d57SBarry Smith 103107b52d57SBarry Smith Level: advanced 103207b52d57SBarry Smith 103307b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 103407b52d57SBarry Smith ISLocalToGlobalMappingGetInfo() 103507b52d57SBarry Smith @*/ 10367087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 103707b52d57SBarry Smith { 10386849ba73SBarry Smith PetscErrorCode ierr; 103932dcc486SBarry Smith PetscInt i; 104007b52d57SBarry Smith 104107b52d57SBarry Smith PetscFunctionBegin; 104205b42c5fSBarry Smith ierr = PetscFree(*procs);CHKERRQ(ierr); 104305b42c5fSBarry Smith ierr = PetscFree(*numprocs);CHKERRQ(ierr); 104400ff320aSBarry Smith if (*indices) { 104505b42c5fSBarry Smith ierr = PetscFree((*indices)[0]);CHKERRQ(ierr); 104600ff320aSBarry Smith for (i=1; i<*nproc; i++) { 104705b42c5fSBarry Smith ierr = PetscFree((*indices)[i]);CHKERRQ(ierr); 104807b52d57SBarry Smith } 104907b52d57SBarry Smith ierr = PetscFree(*indices);CHKERRQ(ierr); 105024cf384cSBarry Smith } 105107b52d57SBarry Smith PetscFunctionReturn(0); 105207b52d57SBarry Smith } 105386994e45SJed Brown 105486994e45SJed Brown #undef __FUNCT__ 105586994e45SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingGetIndices" 105686994e45SJed Brown /*@C 105786994e45SJed Brown ISLocalToGlobalMappingGetIndices - Get global indices for every local point 105886994e45SJed Brown 105986994e45SJed Brown Not Collective 106086994e45SJed Brown 106186994e45SJed Brown Input Arguments: 106286994e45SJed Brown . ltog - local to global mapping 106386994e45SJed Brown 106486994e45SJed Brown Output Arguments: 106586994e45SJed Brown . array - array of indices 106686994e45SJed Brown 106786994e45SJed Brown Level: advanced 106886994e45SJed Brown 106986994e45SJed Brown .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingRestoreIndices() 107086994e45SJed Brown @*/ 10717087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingGetIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 107286994e45SJed Brown { 107386994e45SJed Brown PetscFunctionBegin; 107486994e45SJed Brown PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 107586994e45SJed Brown PetscValidPointer(array,2); 107686994e45SJed Brown *array = ltog->indices; 107786994e45SJed Brown PetscFunctionReturn(0); 107886994e45SJed Brown } 107986994e45SJed Brown 108086994e45SJed Brown #undef __FUNCT__ 108186994e45SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingRestoreIndices" 108286994e45SJed Brown /*@C 108386994e45SJed Brown ISLocalToGlobalMappingRestoreIndices - Restore indices obtained with ISLocalToGlobalMappingRestoreIndices() 108486994e45SJed Brown 108586994e45SJed Brown Not Collective 108686994e45SJed Brown 108786994e45SJed Brown Input Arguments: 108886994e45SJed Brown + ltog - local to global mapping 108986994e45SJed Brown - array - array of indices 109086994e45SJed Brown 109186994e45SJed Brown Level: advanced 109286994e45SJed Brown 109386994e45SJed Brown .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingGetIndices() 109486994e45SJed Brown @*/ 10957087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 109686994e45SJed Brown { 109786994e45SJed Brown PetscFunctionBegin; 109886994e45SJed Brown PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 109986994e45SJed Brown PetscValidPointer(array,2); 110086994e45SJed Brown if (*array != ltog->indices) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Trying to return mismatched pointer"); 11010298fd71SBarry Smith *array = NULL; 110286994e45SJed Brown PetscFunctionReturn(0); 110386994e45SJed Brown } 1104f7efa3c7SJed Brown 1105f7efa3c7SJed Brown #undef __FUNCT__ 1106f7efa3c7SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingConcatenate" 1107f7efa3c7SJed Brown /*@C 1108f7efa3c7SJed Brown ISLocalToGlobalMappingConcatenate - Create a new mapping that concatenates a list of mappings 1109f7efa3c7SJed Brown 1110f7efa3c7SJed Brown Not Collective 1111f7efa3c7SJed Brown 1112f7efa3c7SJed Brown Input Arguments: 1113f7efa3c7SJed Brown + comm - communicator for the new mapping, must contain the communicator of every mapping to concatenate 1114f7efa3c7SJed Brown . n - number of mappings to concatenate 1115f7efa3c7SJed Brown - ltogs - local to global mappings 1116f7efa3c7SJed Brown 1117f7efa3c7SJed Brown Output Arguments: 1118f7efa3c7SJed Brown . ltogcat - new mapping 1119f7efa3c7SJed Brown 1120f7efa3c7SJed Brown Level: advanced 1121f7efa3c7SJed Brown 1122f7efa3c7SJed Brown .seealso: ISLocalToGlobalMappingCreate() 1123f7efa3c7SJed Brown @*/ 1124f7efa3c7SJed Brown PetscErrorCode ISLocalToGlobalMappingConcatenate(MPI_Comm comm,PetscInt n,const ISLocalToGlobalMapping ltogs[],ISLocalToGlobalMapping *ltogcat) 1125f7efa3c7SJed Brown { 1126f7efa3c7SJed Brown PetscInt i,cnt,m,*idx; 1127f7efa3c7SJed Brown PetscErrorCode ierr; 1128f7efa3c7SJed Brown 1129f7efa3c7SJed Brown PetscFunctionBegin; 1130f7efa3c7SJed Brown if (n < 0) SETERRQ1(comm,PETSC_ERR_ARG_OUTOFRANGE,"Must have a non-negative number of mappings, given %D",n); 1131f7efa3c7SJed Brown if (n > 0) PetscValidPointer(ltogs,3); 1132f7efa3c7SJed Brown for (i=0; i<n; i++) PetscValidHeaderSpecific(ltogs[i],IS_LTOGM_CLASSID,3); 1133f7efa3c7SJed Brown PetscValidPointer(ltogcat,4); 1134f7efa3c7SJed Brown for (cnt=0,i=0; i<n; i++) { 1135f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetSize(ltogs[i],&m);CHKERRQ(ierr); 1136f7efa3c7SJed Brown cnt += m; 1137f7efa3c7SJed Brown } 1138785e854fSJed Brown ierr = PetscMalloc1(cnt,&idx);CHKERRQ(ierr); 1139f7efa3c7SJed Brown for (cnt=0,i=0; i<n; i++) { 1140f7efa3c7SJed Brown const PetscInt *subidx; 1141f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetSize(ltogs[i],&m);CHKERRQ(ierr); 1142f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetIndices(ltogs[i],&subidx);CHKERRQ(ierr); 1143f7efa3c7SJed Brown ierr = PetscMemcpy(&idx[cnt],subidx,m*sizeof(PetscInt));CHKERRQ(ierr); 1144f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingRestoreIndices(ltogs[i],&subidx);CHKERRQ(ierr); 1145f7efa3c7SJed Brown cnt += m; 1146f7efa3c7SJed Brown } 1147f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingCreate(comm,cnt,idx,PETSC_OWN_POINTER,ltogcat);CHKERRQ(ierr); 1148f7efa3c7SJed Brown PetscFunctionReturn(0); 1149f7efa3c7SJed Brown } 115004a59952SBarry Smith 115104a59952SBarry Smith 1152