12362add9SBarry Smith 2af0996ceSBarry Smith #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" 34565245c5SBarry Smith /*@ 35107e9a97SBarry 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: 43107e9a97SBarry Smith . n - the number of entries in the local mapping, ISLocalToGlobalMappingGetIndices() returns an array of this length 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); 56107e9a97SBarry Smith *n = mapping->bs*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) { 9498c3331eSBarry 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 119f0413b6fSBarry Smith Notes: the block size of the IS determines the block size of the mapping 120a997ad1aSLois Curfman McInnes Level: advanced 121a997ad1aSLois Curfman McInnes 122273d9f13SBarry Smith Concepts: mapping^local to global 1232bdab257SBarry Smith 1242bdab257SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 1252bdab257SBarry Smith @*/ 1267087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingCreateIS(IS is,ISLocalToGlobalMapping *mapping) 1272bdab257SBarry Smith { 1286849ba73SBarry Smith PetscErrorCode ierr; 1293bbf0e92SBarry Smith PetscInt n,bs; 1305d0c19d7SBarry Smith const PetscInt *indices; 1312bdab257SBarry Smith MPI_Comm comm; 1323bbf0e92SBarry Smith PetscBool isblock; 1333a40ed3dSBarry Smith 1343a40ed3dSBarry Smith PetscFunctionBegin; 1350700a824SBarry Smith PetscValidHeaderSpecific(is,IS_CLASSID,1); 1364482741eSBarry Smith PetscValidPointer(mapping,2); 1372bdab257SBarry Smith 1382bdab257SBarry Smith ierr = PetscObjectGetComm((PetscObject)is,&comm);CHKERRQ(ierr); 1393b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 1403bbf0e92SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)is,ISBLOCK,&isblock);CHKERRQ(ierr); 1416006e8d2SBarry Smith if (!isblock) { 142f0413b6fSBarry Smith ierr = ISGetIndices(is,&indices);CHKERRQ(ierr); 143f0413b6fSBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,1,n,indices,PETSC_COPY_VALUES,mapping);CHKERRQ(ierr); 1442bdab257SBarry Smith ierr = ISRestoreIndices(is,&indices);CHKERRQ(ierr); 1456006e8d2SBarry Smith } else { 1466006e8d2SBarry Smith ierr = ISGetBlockSize(is,&bs);CHKERRQ(ierr); 147f0413b6fSBarry Smith ierr = ISBlockGetIndices(is,&indices);CHKERRQ(ierr); 14828bc9809SBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,bs,n/bs,indices,PETSC_COPY_VALUES,mapping);CHKERRQ(ierr); 149f0413b6fSBarry Smith ierr = ISBlockRestoreIndices(is,&indices);CHKERRQ(ierr); 1506006e8d2SBarry Smith } 1513a40ed3dSBarry Smith PetscFunctionReturn(0); 1522bdab257SBarry Smith } 1535a5d4f66SBarry Smith 154a4d96a55SJed Brown #undef __FUNCT__ 155a4d96a55SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingCreateSF" 156a4d96a55SJed Brown /*@C 157a4d96a55SJed Brown ISLocalToGlobalMappingCreateSF - Creates a mapping between a local (0 to n) 158a4d96a55SJed Brown ordering and a global parallel ordering. 159a4d96a55SJed Brown 160a4d96a55SJed Brown Collective 161a4d96a55SJed Brown 162a4d96a55SJed Brown Input Parameter: 163a4d96a55SJed Brown + sf - star forest mapping contiguous local indices to (rank, offset) 164a4d96a55SJed Brown - start - first global index on this process 165a4d96a55SJed Brown 166a4d96a55SJed Brown Output Parameter: 167a4d96a55SJed Brown . mapping - new mapping data structure 168a4d96a55SJed Brown 169a4d96a55SJed Brown Level: advanced 170a4d96a55SJed Brown 171a4d96a55SJed Brown Concepts: mapping^local to global 172a4d96a55SJed Brown 173a4d96a55SJed Brown .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingCreateIS() 174a4d96a55SJed Brown @*/ 175a4d96a55SJed Brown PetscErrorCode ISLocalToGlobalMappingCreateSF(PetscSF sf,PetscInt start,ISLocalToGlobalMapping *mapping) 176a4d96a55SJed Brown { 177a4d96a55SJed Brown PetscErrorCode ierr; 178a4d96a55SJed Brown PetscInt i,maxlocal,nroots,nleaves,*globals,*ltog; 179a4d96a55SJed Brown const PetscInt *ilocal; 180a4d96a55SJed Brown MPI_Comm comm; 181a4d96a55SJed Brown 182a4d96a55SJed Brown PetscFunctionBegin; 183a4d96a55SJed Brown PetscValidHeaderSpecific(sf,PETSCSF_CLASSID,1); 184a4d96a55SJed Brown PetscValidPointer(mapping,3); 185a4d96a55SJed Brown 186a4d96a55SJed Brown ierr = PetscObjectGetComm((PetscObject)sf,&comm);CHKERRQ(ierr); 1870298fd71SBarry Smith ierr = PetscSFGetGraph(sf,&nroots,&nleaves,&ilocal,NULL);CHKERRQ(ierr); 188f6e5521dSKarl Rupp if (ilocal) { 189f6e5521dSKarl Rupp for (i=0,maxlocal=0; i<nleaves; i++) maxlocal = PetscMax(maxlocal,ilocal[i]+1); 190f6e5521dSKarl Rupp } 191a4d96a55SJed Brown else maxlocal = nleaves; 192785e854fSJed Brown ierr = PetscMalloc1(nroots,&globals);CHKERRQ(ierr); 193785e854fSJed Brown ierr = PetscMalloc1(maxlocal,<og);CHKERRQ(ierr); 194a4d96a55SJed Brown for (i=0; i<nroots; i++) globals[i] = start + i; 195a4d96a55SJed Brown for (i=0; i<maxlocal; i++) ltog[i] = -1; 196a4d96a55SJed Brown ierr = PetscSFBcastBegin(sf,MPIU_INT,globals,ltog);CHKERRQ(ierr); 197a4d96a55SJed Brown ierr = PetscSFBcastEnd(sf,MPIU_INT,globals,ltog);CHKERRQ(ierr); 198f0413b6fSBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,1,maxlocal,ltog,PETSC_OWN_POINTER,mapping);CHKERRQ(ierr); 199a4d96a55SJed Brown ierr = PetscFree(globals);CHKERRQ(ierr); 200a4d96a55SJed Brown PetscFunctionReturn(0); 201a4d96a55SJed Brown } 202b46b645bSBarry Smith 2034a2ae208SSatish Balay #undef __FUNCT__ 20445b6f7e9SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingGetBlockSize" 20545b6f7e9SBarry Smith /*@ 20645b6f7e9SBarry Smith ISLocalToGlobalMappingGetBlockSize - Gets the blocksize of the mapping 20745b6f7e9SBarry Smith ordering and a global parallel ordering. 20845b6f7e9SBarry Smith 20945b6f7e9SBarry Smith Not Collective 21045b6f7e9SBarry Smith 21145b6f7e9SBarry Smith Input Parameters: 21245b6f7e9SBarry Smith . mapping - mapping data structure 21345b6f7e9SBarry Smith 21445b6f7e9SBarry Smith Output Parameter: 21545b6f7e9SBarry Smith . bs - the blocksize 21645b6f7e9SBarry Smith 21745b6f7e9SBarry Smith Level: advanced 21845b6f7e9SBarry Smith 21945b6f7e9SBarry Smith Concepts: mapping^local to global 22045b6f7e9SBarry Smith 22145b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 22245b6f7e9SBarry Smith @*/ 22345b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetBlockSize(ISLocalToGlobalMapping mapping,PetscInt *bs) 22445b6f7e9SBarry Smith { 22545b6f7e9SBarry Smith PetscFunctionBegin; 226cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 22745b6f7e9SBarry Smith *bs = mapping->bs; 22845b6f7e9SBarry Smith PetscFunctionReturn(0); 22945b6f7e9SBarry Smith } 23045b6f7e9SBarry Smith 23145b6f7e9SBarry Smith #undef __FUNCT__ 2324a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreate" 233ba5bb76aSSatish Balay /*@ 23490f02eecSBarry Smith ISLocalToGlobalMappingCreate - Creates a mapping between a local (0 to n) 23590f02eecSBarry Smith ordering and a global parallel ordering. 2362362add9SBarry Smith 23789d82c54SBarry Smith Not Collective, but communicator may have more than one process 238b9cd556bSLois Curfman McInnes 2392362add9SBarry Smith Input Parameters: 24089d82c54SBarry Smith + comm - MPI communicator 241f0413b6fSBarry Smith . bs - the block size 24228bc9809SBarry Smith . n - the number of local elements divided by the block size, or equivalently the number of block indices 24328bc9809SBarry Smith . indices - the global index for each local element, these do not need to be in increasing order (sorted), these values should not be scaled (i.e. multiplied) by the blocksize bs 244d5ad8652SBarry Smith - mode - see PetscCopyMode 2452362add9SBarry Smith 246a997ad1aSLois Curfman McInnes Output Parameter: 24790f02eecSBarry Smith . mapping - new mapping data structure 2482362add9SBarry Smith 249f0413b6fSBarry Smith Notes: There is one integer value in indices per block and it represents the actual indices bs*idx + j, where j=0,..,bs-1 250a997ad1aSLois Curfman McInnes Level: advanced 251a997ad1aSLois Curfman McInnes 252273d9f13SBarry Smith Concepts: mapping^local to global 2532362add9SBarry Smith 254d5ad8652SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 2552362add9SBarry Smith @*/ 256f0413b6fSBarry Smith PetscErrorCode ISLocalToGlobalMappingCreate(MPI_Comm cm,PetscInt bs,PetscInt n,const PetscInt indices[],PetscCopyMode mode,ISLocalToGlobalMapping *mapping) 2572362add9SBarry Smith { 2586849ba73SBarry Smith PetscErrorCode ierr; 25932dcc486SBarry Smith PetscInt *in; 260b46b645bSBarry Smith 261b46b645bSBarry Smith PetscFunctionBegin; 26273911063SBarry Smith if (n) PetscValidIntPointer(indices,3); 2634482741eSBarry Smith PetscValidPointer(mapping,4); 264b46b645bSBarry Smith 2650298fd71SBarry Smith *mapping = NULL; 266607a6623SBarry Smith ierr = ISInitializePackage();CHKERRQ(ierr); 2672362add9SBarry Smith 268*73107ff1SLisandro Dalcin ierr = PetscHeaderCreate(*mapping,IS_LTOGM_CLASSID,"ISLocalToGlobalMapping","Local to global mapping","IS", 26952e6d16bSBarry Smith cm,ISLocalToGlobalMappingDestroy,ISLocalToGlobalMappingView);CHKERRQ(ierr); 270d4bb536fSBarry Smith (*mapping)->n = n; 271f0413b6fSBarry Smith (*mapping)->bs = bs; 272d4bb536fSBarry Smith /* 273d4bb536fSBarry Smith Do not create the global to local mapping. This is only created if 274d4bb536fSBarry Smith ISGlobalToLocalMapping() is called 275d4bb536fSBarry Smith */ 276d4bb536fSBarry Smith (*mapping)->globals = 0; 277d5ad8652SBarry Smith if (mode == PETSC_COPY_VALUES) { 278785e854fSJed Brown ierr = PetscMalloc1(n,&in);CHKERRQ(ierr); 279d5ad8652SBarry Smith ierr = PetscMemcpy(in,indices,n*sizeof(PetscInt));CHKERRQ(ierr); 280d5ad8652SBarry Smith (*mapping)->indices = in; 2816389a1a1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)*mapping,n*sizeof(PetscInt));CHKERRQ(ierr); 2826389a1a1SBarry Smith } else if (mode == PETSC_OWN_POINTER) { 2836389a1a1SBarry Smith (*mapping)->indices = (PetscInt*)indices; 2846389a1a1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)*mapping,n*sizeof(PetscInt));CHKERRQ(ierr); 2856389a1a1SBarry Smith } 286f6e5521dSKarl Rupp else SETERRQ(cm,PETSC_ERR_SUP,"Cannot currently use PETSC_USE_POINTER"); 287d96308ebSBarry Smith ierr = PetscStrallocpy("basic",&((PetscObject)*mapping)->type_name);CHKERRQ(ierr); 2883a40ed3dSBarry Smith PetscFunctionReturn(0); 2892362add9SBarry Smith } 2902362add9SBarry Smith 2914a2ae208SSatish Balay #undef __FUNCT__ 2924a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingDestroy" 29390f02eecSBarry Smith /*@ 29490f02eecSBarry Smith ISLocalToGlobalMappingDestroy - Destroys a mapping between a local (0 to n) 29590f02eecSBarry Smith ordering and a global parallel ordering. 29690f02eecSBarry Smith 2970f5bd95cSBarry Smith Note Collective 298b9cd556bSLois Curfman McInnes 29990f02eecSBarry Smith Input Parameters: 30090f02eecSBarry Smith . mapping - mapping data structure 30190f02eecSBarry Smith 302a997ad1aSLois Curfman McInnes Level: advanced 303a997ad1aSLois Curfman McInnes 3043acfe500SLois Curfman McInnes .seealso: ISLocalToGlobalMappingCreate() 30590f02eecSBarry Smith @*/ 3066bf464f9SBarry Smith PetscErrorCode ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping *mapping) 30790f02eecSBarry Smith { 308dfbe8321SBarry Smith PetscErrorCode ierr; 3095fd66863SKarl Rupp 3103a40ed3dSBarry Smith PetscFunctionBegin; 3116bf464f9SBarry Smith if (!*mapping) PetscFunctionReturn(0); 3126bf464f9SBarry Smith PetscValidHeaderSpecific((*mapping),IS_LTOGM_CLASSID,1); 313997056adSBarry Smith if (--((PetscObject)(*mapping))->refct > 0) {*mapping = 0;PetscFunctionReturn(0);} 3146bf464f9SBarry Smith ierr = PetscFree((*mapping)->indices);CHKERRQ(ierr); 3156bf464f9SBarry Smith ierr = PetscFree((*mapping)->globals);CHKERRQ(ierr); 316d38fa0fbSBarry Smith ierr = PetscHeaderDestroy(mapping);CHKERRQ(ierr); 317992144d0SBarry Smith *mapping = 0; 3183a40ed3dSBarry Smith PetscFunctionReturn(0); 31990f02eecSBarry Smith } 32090f02eecSBarry Smith 3214a2ae208SSatish Balay #undef __FUNCT__ 3224a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingApplyIS" 32390f02eecSBarry Smith /*@ 3243acfe500SLois Curfman McInnes ISLocalToGlobalMappingApplyIS - Creates from an IS in the local numbering 3253acfe500SLois Curfman McInnes a new index set using the global numbering defined in an ISLocalToGlobalMapping 3263acfe500SLois Curfman McInnes context. 32790f02eecSBarry Smith 328b9cd556bSLois Curfman McInnes Not collective 329b9cd556bSLois Curfman McInnes 33090f02eecSBarry Smith Input Parameters: 331b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 332b9cd556bSLois Curfman McInnes - is - index set in local numbering 33390f02eecSBarry Smith 33490f02eecSBarry Smith Output Parameters: 33590f02eecSBarry Smith . newis - index set in global numbering 33690f02eecSBarry Smith 337a997ad1aSLois Curfman McInnes Level: advanced 338a997ad1aSLois Curfman McInnes 339273d9f13SBarry Smith Concepts: mapping^local to global 3403acfe500SLois Curfman McInnes 34190f02eecSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 342d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy(), ISGlobalToLocalMappingApply() 34390f02eecSBarry Smith @*/ 3447087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping,IS is,IS *newis) 34590f02eecSBarry Smith { 3466849ba73SBarry Smith PetscErrorCode ierr; 347e24637baSBarry Smith PetscInt n,*idxout; 3485d0c19d7SBarry Smith const PetscInt *idxin; 3493a40ed3dSBarry Smith 3503a40ed3dSBarry Smith PetscFunctionBegin; 3510700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 3520700a824SBarry Smith PetscValidHeaderSpecific(is,IS_CLASSID,2); 3534482741eSBarry Smith PetscValidPointer(newis,3); 35490f02eecSBarry Smith 3553b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 35690f02eecSBarry Smith ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 357785e854fSJed Brown ierr = PetscMalloc1(n,&idxout);CHKERRQ(ierr); 358e24637baSBarry Smith ierr = ISLocalToGlobalMappingApply(mapping,n,idxin,idxout);CHKERRQ(ierr); 3593b9aefa3SBarry Smith ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 360543f3098SMatthew G. Knepley ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is),n,idxout,PETSC_OWN_POINTER,newis);CHKERRQ(ierr); 3613a40ed3dSBarry Smith PetscFunctionReturn(0); 36290f02eecSBarry Smith } 36390f02eecSBarry Smith 364afcb2eb5SJed Brown #undef __FUNCT__ 365afcb2eb5SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingApply" 366b89cb25eSSatish Balay /*@ 3673acfe500SLois Curfman McInnes ISLocalToGlobalMappingApply - Takes a list of integers in a local numbering 3683acfe500SLois Curfman McInnes and converts them to the global numbering. 36990f02eecSBarry Smith 370b9cd556bSLois Curfman McInnes Not collective 371b9cd556bSLois Curfman McInnes 372bb25748dSBarry Smith Input Parameters: 373b9cd556bSLois Curfman McInnes + mapping - the local to global mapping context 374bb25748dSBarry Smith . N - number of integers 375b9cd556bSLois Curfman McInnes - in - input indices in local numbering 376bb25748dSBarry Smith 377bb25748dSBarry Smith Output Parameter: 378bb25748dSBarry Smith . out - indices in global numbering 379bb25748dSBarry Smith 380b9cd556bSLois Curfman McInnes Notes: 381b9cd556bSLois Curfman McInnes The in and out array parameters may be identical. 382d4bb536fSBarry Smith 383a997ad1aSLois Curfman McInnes Level: advanced 384a997ad1aSLois Curfman McInnes 38545b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingApplyBlock(), ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 3860752156aSBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 387d4bb536fSBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 388bb25748dSBarry Smith 389273d9f13SBarry Smith Concepts: mapping^local to global 390afcb2eb5SJed Brown @*/ 391afcb2eb5SJed Brown PetscErrorCode ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping,PetscInt N,const PetscInt in[],PetscInt out[]) 392afcb2eb5SJed Brown { 393cbc1caf0SMatthew G. Knepley PetscInt i,bs,Nmax; 39445b6f7e9SBarry Smith 39545b6f7e9SBarry Smith PetscFunctionBegin; 396cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 397cbc1caf0SMatthew G. Knepley bs = mapping->bs; 398cbc1caf0SMatthew G. Knepley Nmax = bs*mapping->n; 39945b6f7e9SBarry Smith if (bs == 1) { 400cbc1caf0SMatthew G. Knepley const PetscInt *idx = mapping->indices; 40145b6f7e9SBarry Smith for (i=0; i<N; i++) { 40245b6f7e9SBarry Smith if (in[i] < 0) { 40345b6f7e9SBarry Smith out[i] = in[i]; 40445b6f7e9SBarry Smith continue; 40545b6f7e9SBarry Smith } 406e24637baSBarry Smith if (in[i] >= Nmax) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local index %D too large %D (max) at %D",in[i],Nmax-1,i); 40745b6f7e9SBarry Smith out[i] = idx[in[i]]; 40845b6f7e9SBarry Smith } 40945b6f7e9SBarry Smith } else { 410cbc1caf0SMatthew G. Knepley const PetscInt *idx = mapping->indices; 41145b6f7e9SBarry Smith for (i=0; i<N; i++) { 41245b6f7e9SBarry Smith if (in[i] < 0) { 41345b6f7e9SBarry Smith out[i] = in[i]; 41445b6f7e9SBarry Smith continue; 41545b6f7e9SBarry Smith } 416e24637baSBarry Smith if (in[i] >= Nmax) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local index %D too large %D (max) at %D",in[i],Nmax-1,i); 41745b6f7e9SBarry Smith out[i] = idx[in[i]/bs]*bs + (in[i] % bs); 41845b6f7e9SBarry Smith } 41945b6f7e9SBarry Smith } 42045b6f7e9SBarry Smith PetscFunctionReturn(0); 42145b6f7e9SBarry Smith } 42245b6f7e9SBarry Smith 42345b6f7e9SBarry Smith #undef __FUNCT__ 42445b6f7e9SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingApplyBlock" 42545b6f7e9SBarry Smith /*@ 4266006e8d2SBarry Smith ISLocalToGlobalMappingApplyBlock - Takes a list of integers in a local block numbering and converts them to the global block numbering 42745b6f7e9SBarry Smith 42845b6f7e9SBarry Smith Not collective 42945b6f7e9SBarry Smith 43045b6f7e9SBarry Smith Input Parameters: 43145b6f7e9SBarry Smith + mapping - the local to global mapping context 43245b6f7e9SBarry Smith . N - number of integers 4336006e8d2SBarry Smith - in - input indices in local block numbering 43445b6f7e9SBarry Smith 43545b6f7e9SBarry Smith Output Parameter: 4366006e8d2SBarry Smith . out - indices in global block numbering 43745b6f7e9SBarry Smith 43845b6f7e9SBarry Smith Notes: 43945b6f7e9SBarry Smith The in and out array parameters may be identical. 44045b6f7e9SBarry Smith 4416006e8d2SBarry Smith Example: 4426006e8d2SBarry Smith If the index values are {0,1,6,7} set with a call to ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,2,2,{0,3}) then the mapping applied to 0 4436006e8d2SBarry Smith (the first block) would produce 0 and the mapping applied to 1 (the second block) would produce 3. 4446006e8d2SBarry Smith 44545b6f7e9SBarry Smith Level: advanced 44645b6f7e9SBarry Smith 44745b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 44845b6f7e9SBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 44945b6f7e9SBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 45045b6f7e9SBarry Smith 45145b6f7e9SBarry Smith Concepts: mapping^local to global 45245b6f7e9SBarry Smith @*/ 45345b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingApplyBlock(ISLocalToGlobalMapping mapping,PetscInt N,const PetscInt in[],PetscInt out[]) 45445b6f7e9SBarry Smith { 455cbc1caf0SMatthew G. Knepley 456cbc1caf0SMatthew G. Knepley PetscFunctionBegin; 457cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 458cbc1caf0SMatthew G. Knepley { 459afcb2eb5SJed Brown PetscInt i,Nmax = mapping->n; 460afcb2eb5SJed Brown const PetscInt *idx = mapping->indices; 461d4bb536fSBarry Smith 462afcb2eb5SJed Brown for (i=0; i<N; i++) { 463afcb2eb5SJed Brown if (in[i] < 0) { 464afcb2eb5SJed Brown out[i] = in[i]; 465afcb2eb5SJed Brown continue; 466afcb2eb5SJed Brown } 467e24637baSBarry Smith if (in[i] >= Nmax) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local block index %D too large %D (max) at %D",in[i],Nmax-1,i); 468afcb2eb5SJed Brown out[i] = idx[in[i]]; 469afcb2eb5SJed Brown } 470cbc1caf0SMatthew G. Knepley } 471afcb2eb5SJed Brown PetscFunctionReturn(0); 472afcb2eb5SJed Brown } 473d4bb536fSBarry Smith 474d4bb536fSBarry Smith /* -----------------------------------------------------------------------------------------*/ 475d4bb536fSBarry Smith 4764a2ae208SSatish Balay #undef __FUNCT__ 4774a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingSetUp_Private" 478d4bb536fSBarry Smith /* 479d4bb536fSBarry Smith Creates the global fields in the ISLocalToGlobalMapping structure 480d4bb536fSBarry Smith */ 4816849ba73SBarry Smith static PetscErrorCode ISGlobalToLocalMappingSetUp_Private(ISLocalToGlobalMapping mapping) 482d4bb536fSBarry Smith { 4836849ba73SBarry Smith PetscErrorCode ierr; 48432dcc486SBarry Smith PetscInt i,*idx = mapping->indices,n = mapping->n,end,start,*globals; 485d4bb536fSBarry Smith 4863a40ed3dSBarry Smith PetscFunctionBegin; 487d4bb536fSBarry Smith end = 0; 488ec268f7cSJed Brown start = PETSC_MAX_INT; 489d4bb536fSBarry Smith 490d4bb536fSBarry Smith for (i=0; i<n; i++) { 491d4bb536fSBarry Smith if (idx[i] < 0) continue; 492d4bb536fSBarry Smith if (idx[i] < start) start = idx[i]; 493d4bb536fSBarry Smith if (idx[i] > end) end = idx[i]; 494d4bb536fSBarry Smith } 495d4bb536fSBarry Smith if (start > end) {start = 0; end = -1;} 496d4bb536fSBarry Smith mapping->globalstart = start; 497d4bb536fSBarry Smith mapping->globalend = end; 498d4bb536fSBarry Smith 499854ce69bSBarry Smith ierr = PetscMalloc1(end-start+2,&globals);CHKERRQ(ierr); 500b0a32e0cSBarry Smith mapping->globals = globals; 501f6e5521dSKarl Rupp for (i=0; i<end-start+1; i++) globals[i] = -1; 502d4bb536fSBarry Smith for (i=0; i<n; i++) { 503d4bb536fSBarry Smith if (idx[i] < 0) continue; 504d4bb536fSBarry Smith globals[idx[i] - start] = i; 505d4bb536fSBarry Smith } 506d4bb536fSBarry Smith 5073bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mapping,(end-start+1)*sizeof(PetscInt));CHKERRQ(ierr); 5083a40ed3dSBarry Smith PetscFunctionReturn(0); 509d4bb536fSBarry Smith } 510d4bb536fSBarry Smith 5114a2ae208SSatish Balay #undef __FUNCT__ 5124a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingApply" 513d4bb536fSBarry Smith /*@ 514a997ad1aSLois Curfman McInnes ISGlobalToLocalMappingApply - Provides the local numbering for a list of integers 515a997ad1aSLois Curfman McInnes specified with a global numbering. 516d4bb536fSBarry Smith 517b9cd556bSLois Curfman McInnes Not collective 518b9cd556bSLois Curfman McInnes 519d4bb536fSBarry Smith Input Parameters: 520b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 521d4bb536fSBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 522d4bb536fSBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 523d4bb536fSBarry Smith . n - number of global indices to map 524b9cd556bSLois Curfman McInnes - idx - global indices to map 525d4bb536fSBarry Smith 526d4bb536fSBarry Smith Output Parameters: 527b9cd556bSLois Curfman McInnes + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 528b9cd556bSLois Curfman McInnes - idxout - local index of each global index, one must pass in an array long enough 529e182c471SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApply() with 5300298fd71SBarry Smith idxout == NULL to determine the required length (returned in nout) 531e182c471SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApply() 532e182c471SBarry Smith a second time to set the values. 533d4bb536fSBarry Smith 534b9cd556bSLois Curfman McInnes Notes: 5350298fd71SBarry Smith Either nout or idxout may be NULL. idx and idxout may be identical. 536d4bb536fSBarry Smith 5370f5bd95cSBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 5380f5bd95cSBarry Smith array to compute these. 5390f5bd95cSBarry Smith 540a997ad1aSLois Curfman McInnes Level: advanced 541a997ad1aSLois Curfman McInnes 54232fd6b96SBarry Smith Developer Note: The manual page states that idx and idxout may be identical but the calling 54332fd6b96SBarry Smith sequence declares idx as const so it cannot be the same as idxout. 54432fd6b96SBarry Smith 545273d9f13SBarry Smith Concepts: mapping^global to local 546d4bb536fSBarry Smith 5479d90f715SBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISGlobalToLocalMappingApplyBlock(), ISLocalToGlobalMappingCreate(), 548d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy() 549d4bb536fSBarry Smith @*/ 5507087cfbeSBarry Smith PetscErrorCode ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 55132dcc486SBarry Smith PetscInt n,const PetscInt idx[],PetscInt *nout,PetscInt idxout[]) 552d4bb536fSBarry Smith { 5539d90f715SBarry Smith PetscInt i,*globals,nf = 0,tmp,start,end,bs; 5549d90f715SBarry Smith PetscErrorCode ierr; 5559d90f715SBarry Smith 5569d90f715SBarry Smith PetscFunctionBegin; 5579d90f715SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 5589d90f715SBarry Smith if (!mapping->globals) { 5599d90f715SBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 5609d90f715SBarry Smith } 5619d90f715SBarry Smith globals = mapping->globals; 5629d90f715SBarry Smith start = mapping->globalstart; 5639d90f715SBarry Smith end = mapping->globalend; 5649d90f715SBarry Smith bs = mapping->bs; 5659d90f715SBarry Smith 5669d90f715SBarry Smith if (type == IS_GTOLM_MASK) { 5679d90f715SBarry Smith if (idxout) { 5689d90f715SBarry Smith for (i=0; i<n; i++) { 5699d90f715SBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 5709d90f715SBarry Smith else if (idx[i] < bs*start) idxout[i] = -1; 571663bb84eSBarry Smith else if (idx[i] > bs*(end+1)-1) idxout[i] = -1; 5729d90f715SBarry Smith else idxout[i] = bs*globals[idx[i]/bs - start] + (idx[i] % bs); 5739d90f715SBarry Smith } 5749d90f715SBarry Smith } 5759d90f715SBarry Smith if (nout) *nout = n; 5769d90f715SBarry Smith } else { 5779d90f715SBarry Smith if (idxout) { 5789d90f715SBarry Smith for (i=0; i<n; i++) { 5799d90f715SBarry Smith if (idx[i] < 0) continue; 5809d90f715SBarry Smith if (idx[i] < bs*start) continue; 581663bb84eSBarry Smith if (idx[i] > bs*(end+1)-1) continue; 5829d90f715SBarry Smith tmp = bs*globals[idx[i]/bs - start] + (idx[i] % bs); 5839d90f715SBarry Smith if (tmp < 0) continue; 5849d90f715SBarry Smith idxout[nf++] = tmp; 5859d90f715SBarry Smith } 5869d90f715SBarry Smith } else { 5879d90f715SBarry Smith for (i=0; i<n; i++) { 5889d90f715SBarry Smith if (idx[i] < 0) continue; 5899d90f715SBarry Smith if (idx[i] < bs*start) continue; 590663bb84eSBarry Smith if (idx[i] > bs*(end+1)-1) continue; 5919d90f715SBarry Smith tmp = bs*globals[idx[i]/bs - start] + (idx[i] % bs); 5929d90f715SBarry Smith if (tmp < 0) continue; 5939d90f715SBarry Smith nf++; 5949d90f715SBarry Smith } 5959d90f715SBarry Smith } 5969d90f715SBarry Smith if (nout) *nout = nf; 5979d90f715SBarry Smith } 5989d90f715SBarry Smith PetscFunctionReturn(0); 5999d90f715SBarry Smith } 6009d90f715SBarry Smith 6019d90f715SBarry Smith #undef __FUNCT__ 602d4fe737eSStefano Zampini #define __FUNCT__ "ISGlobalToLocalMappingApplyIS" 603d4fe737eSStefano Zampini /*@ 604d4fe737eSStefano Zampini ISGlobalToLocalMappingApplyIS - Creates from an IS in the global numbering 605d4fe737eSStefano Zampini a new index set using the local numbering defined in an ISLocalToGlobalMapping 606d4fe737eSStefano Zampini context. 607d4fe737eSStefano Zampini 608d4fe737eSStefano Zampini Not collective 609d4fe737eSStefano Zampini 610d4fe737eSStefano Zampini Input Parameters: 611d4fe737eSStefano Zampini + mapping - mapping between local and global numbering 612d4fe737eSStefano Zampini - is - index set in global numbering 613d4fe737eSStefano Zampini 614d4fe737eSStefano Zampini Output Parameters: 615d4fe737eSStefano Zampini . newis - index set in local numbering 616d4fe737eSStefano Zampini 617d4fe737eSStefano Zampini Level: advanced 618d4fe737eSStefano Zampini 619d4fe737eSStefano Zampini Concepts: mapping^local to global 620d4fe737eSStefano Zampini 621d4fe737eSStefano Zampini .seealso: ISGlobalToLocalMappingApply(), ISLocalToGlobalMappingCreate(), 622d4fe737eSStefano Zampini ISLocalToGlobalMappingDestroy() 623d4fe737eSStefano Zampini @*/ 624d4fe737eSStefano Zampini PetscErrorCode ISGlobalToLocalMappingApplyIS(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, IS is,IS *newis) 625d4fe737eSStefano Zampini { 626d4fe737eSStefano Zampini PetscErrorCode ierr; 627d4fe737eSStefano Zampini PetscInt n,nout,*idxout; 628d4fe737eSStefano Zampini const PetscInt *idxin; 629d4fe737eSStefano Zampini 630d4fe737eSStefano Zampini PetscFunctionBegin; 631d4fe737eSStefano Zampini PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 632d4fe737eSStefano Zampini PetscValidHeaderSpecific(is,IS_CLASSID,3); 633d4fe737eSStefano Zampini PetscValidPointer(newis,4); 634d4fe737eSStefano Zampini 635d4fe737eSStefano Zampini ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 636d4fe737eSStefano Zampini ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 637d4fe737eSStefano Zampini if (type == IS_GTOLM_MASK) { 638d4fe737eSStefano Zampini ierr = PetscMalloc1(n,&idxout);CHKERRQ(ierr); 639d4fe737eSStefano Zampini } else { 640d4fe737eSStefano Zampini ierr = ISGlobalToLocalMappingApply(mapping,type,n,idxin,&nout,NULL);CHKERRQ(ierr); 641d4fe737eSStefano Zampini ierr = PetscMalloc1(nout,&idxout);CHKERRQ(ierr); 642d4fe737eSStefano Zampini } 643d4fe737eSStefano Zampini ierr = ISGlobalToLocalMappingApply(mapping,type,n,idxin,&nout,idxout);CHKERRQ(ierr); 644d4fe737eSStefano Zampini ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 645d4fe737eSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is),nout,idxout,PETSC_OWN_POINTER,newis);CHKERRQ(ierr); 646d4fe737eSStefano Zampini PetscFunctionReturn(0); 647d4fe737eSStefano Zampini } 648d4fe737eSStefano Zampini 649d4fe737eSStefano Zampini #undef __FUNCT__ 6509d90f715SBarry Smith #define __FUNCT__ "ISGlobalToLocalMappingApplyBlock" 6519d90f715SBarry Smith /*@ 6529d90f715SBarry Smith ISGlobalToLocalMappingApplyBlock - Provides the local block numbering for a list of integers 6539d90f715SBarry Smith specified with a block global numbering. 6549d90f715SBarry Smith 6559d90f715SBarry Smith Not collective 6569d90f715SBarry Smith 6579d90f715SBarry Smith Input Parameters: 6589d90f715SBarry Smith + mapping - mapping between local and global numbering 6599d90f715SBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 6609d90f715SBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 6619d90f715SBarry Smith . n - number of global indices to map 6629d90f715SBarry Smith - idx - global indices to map 6639d90f715SBarry Smith 6649d90f715SBarry Smith Output Parameters: 6659d90f715SBarry Smith + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 6669d90f715SBarry Smith - idxout - local index of each global index, one must pass in an array long enough 6679d90f715SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApplyBlock() with 6689d90f715SBarry Smith idxout == NULL to determine the required length (returned in nout) 6699d90f715SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApplyBlock() 6709d90f715SBarry Smith a second time to set the values. 6719d90f715SBarry Smith 6729d90f715SBarry Smith Notes: 6739d90f715SBarry Smith Either nout or idxout may be NULL. idx and idxout may be identical. 6749d90f715SBarry Smith 6759d90f715SBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 6769d90f715SBarry Smith array to compute these. 6779d90f715SBarry Smith 6789d90f715SBarry Smith Level: advanced 6799d90f715SBarry Smith 6809d90f715SBarry Smith Developer Note: The manual page states that idx and idxout may be identical but the calling 6819d90f715SBarry Smith sequence declares idx as const so it cannot be the same as idxout. 6829d90f715SBarry Smith 6839d90f715SBarry Smith Concepts: mapping^global to local 6849d90f715SBarry Smith 6859d90f715SBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISGlobalToLocalMappingApply(), ISLocalToGlobalMappingCreate(), 6869d90f715SBarry Smith ISLocalToGlobalMappingDestroy() 6879d90f715SBarry Smith @*/ 6889d90f715SBarry Smith PetscErrorCode ISGlobalToLocalMappingApplyBlock(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 6899d90f715SBarry Smith PetscInt n,const PetscInt idx[],PetscInt *nout,PetscInt idxout[]) 6909d90f715SBarry Smith { 69132dcc486SBarry Smith PetscInt i,*globals,nf = 0,tmp,start,end; 6926849ba73SBarry Smith PetscErrorCode ierr; 693d4bb536fSBarry Smith 6943a40ed3dSBarry Smith PetscFunctionBegin; 6950700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 696d4bb536fSBarry Smith if (!mapping->globals) { 697d4bb536fSBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 698d4bb536fSBarry Smith } 699d4bb536fSBarry Smith globals = mapping->globals; 700d4bb536fSBarry Smith start = mapping->globalstart; 701d4bb536fSBarry Smith end = mapping->globalend; 702d4bb536fSBarry Smith 703d4bb536fSBarry Smith if (type == IS_GTOLM_MASK) { 704d4bb536fSBarry Smith if (idxout) { 705d4bb536fSBarry Smith for (i=0; i<n; i++) { 706d4bb536fSBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 707d4bb536fSBarry Smith else if (idx[i] < start) idxout[i] = -1; 708d4bb536fSBarry Smith else if (idx[i] > end) idxout[i] = -1; 709d4bb536fSBarry Smith else idxout[i] = globals[idx[i] - start]; 710d4bb536fSBarry Smith } 711d4bb536fSBarry Smith } 712d4bb536fSBarry Smith if (nout) *nout = n; 713d4bb536fSBarry Smith } else { 714d4bb536fSBarry Smith if (idxout) { 715d4bb536fSBarry Smith for (i=0; i<n; i++) { 716d4bb536fSBarry Smith if (idx[i] < 0) continue; 717d4bb536fSBarry Smith if (idx[i] < start) continue; 718d4bb536fSBarry Smith if (idx[i] > end) continue; 719d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 720d4bb536fSBarry Smith if (tmp < 0) continue; 721d4bb536fSBarry Smith idxout[nf++] = tmp; 722d4bb536fSBarry Smith } 723d4bb536fSBarry Smith } else { 724d4bb536fSBarry Smith for (i=0; i<n; i++) { 725d4bb536fSBarry Smith if (idx[i] < 0) continue; 726d4bb536fSBarry Smith if (idx[i] < start) continue; 727d4bb536fSBarry Smith if (idx[i] > end) continue; 728d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 729d4bb536fSBarry Smith if (tmp < 0) continue; 730d4bb536fSBarry Smith nf++; 731d4bb536fSBarry Smith } 732d4bb536fSBarry Smith } 733d4bb536fSBarry Smith if (nout) *nout = nf; 734d4bb536fSBarry Smith } 7353a40ed3dSBarry Smith PetscFunctionReturn(0); 736d4bb536fSBarry Smith } 73790f02eecSBarry Smith 7384a2ae208SSatish Balay #undef __FUNCT__ 7396a818285SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingGetBlockInfo" 74089d82c54SBarry Smith /*@C 7416a818285SBarry Smith ISLocalToGlobalMappingGetBlockInfo - Gets the neighbor information for each processor and 74289d82c54SBarry Smith each index shared by more than one processor 74389d82c54SBarry Smith 74489d82c54SBarry Smith Collective on ISLocalToGlobalMapping 74589d82c54SBarry Smith 74689d82c54SBarry Smith Input Parameters: 74789d82c54SBarry Smith . mapping - the mapping from local to global indexing 74889d82c54SBarry Smith 74989d82c54SBarry Smith Output Parameter: 75089d82c54SBarry Smith + nproc - number of processors that are connected to this one 75189d82c54SBarry Smith . proc - neighboring processors 75207b52d57SBarry Smith . numproc - number of indices for each subdomain (processor) 7533463a7baSJed Brown - indices - indices of nodes (in local numbering) shared with neighbors (sorted by global numbering) 75489d82c54SBarry Smith 75589d82c54SBarry Smith Level: advanced 75689d82c54SBarry Smith 757273d9f13SBarry Smith Concepts: mapping^local to global 75889d82c54SBarry Smith 7592cfcea29SBarry Smith Fortran Usage: 7602cfcea29SBarry Smith $ ISLocalToGlobalMpngGetInfoSize(ISLocalToGlobalMapping,PetscInt nproc,PetscInt numprocmax,ierr) followed by 7612cfcea29SBarry Smith $ ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping,PetscInt nproc, PetscInt procs[nproc],PetscInt numprocs[nproc], 7622cfcea29SBarry Smith PetscInt indices[nproc][numprocmax],ierr) 7632cfcea29SBarry Smith There is no ISLocalToGlobalMappingRestoreInfo() in Fortran. You must make sure that procs[], numprocs[] and 7642cfcea29SBarry Smith indices[][] are large enough arrays, either by allocating them dynamically or defining static ones large enough. 7652cfcea29SBarry Smith 7662cfcea29SBarry Smith 76707b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 76807b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo() 76989d82c54SBarry Smith @*/ 7706a818285SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetBlockInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 77189d82c54SBarry Smith { 7726849ba73SBarry Smith PetscErrorCode ierr; 77397f1f81fSBarry Smith PetscMPIInt size,rank,tag1,tag2,tag3,*len,*source,imdex; 77432dcc486SBarry Smith PetscInt i,n = mapping->n,Ng,ng,max = 0,*lindices = mapping->indices; 77532dcc486SBarry Smith PetscInt *nprocs,*owner,nsends,*sends,j,*starts,nmax,nrecvs,*recvs,proc; 77697f1f81fSBarry Smith PetscInt cnt,scale,*ownedsenders,*nownedsenders,rstart,nowned; 77732dcc486SBarry Smith PetscInt node,nownedm,nt,*sends2,nsends2,*starts2,*lens2,*dest,nrecvs2,*starts3,*recvs2,k,*bprocs,*tmp; 77832dcc486SBarry Smith PetscInt first_procs,first_numprocs,*first_indices; 77989d82c54SBarry Smith MPI_Request *recv_waits,*send_waits; 78030dcb7c9SBarry Smith MPI_Status recv_status,*send_status,*recv_statuses; 781ce94432eSBarry Smith MPI_Comm comm; 782ace3abfcSBarry Smith PetscBool debug = PETSC_FALSE; 78389d82c54SBarry Smith 78489d82c54SBarry Smith PetscFunctionBegin; 7850700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 786ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)mapping,&comm);CHKERRQ(ierr); 78724cf384cSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 78824cf384cSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 78924cf384cSBarry Smith if (size == 1) { 79024cf384cSBarry Smith *nproc = 0; 7910298fd71SBarry Smith *procs = NULL; 79232dcc486SBarry Smith ierr = PetscMalloc(sizeof(PetscInt),numprocs);CHKERRQ(ierr); 7931e2105dcSBarry Smith (*numprocs)[0] = 0; 79432dcc486SBarry Smith ierr = PetscMalloc(sizeof(PetscInt*),indices);CHKERRQ(ierr); 7950298fd71SBarry Smith (*indices)[0] = NULL; 79624cf384cSBarry Smith PetscFunctionReturn(0); 79724cf384cSBarry Smith } 79824cf384cSBarry Smith 7990298fd71SBarry Smith ierr = PetscOptionsGetBool(NULL,"-islocaltoglobalmappinggetinfo_debug",&debug,NULL);CHKERRQ(ierr); 80007b52d57SBarry Smith 8013677ff5aSBarry Smith /* 8026a818285SBarry Smith Notes on ISLocalToGlobalMappingGetBlockInfo 8033677ff5aSBarry Smith 8043677ff5aSBarry Smith globally owned node - the nodes that have been assigned to this processor in global 8053677ff5aSBarry Smith numbering, just for this routine. 8063677ff5aSBarry Smith 8073677ff5aSBarry Smith nontrivial globally owned node - node assigned to this processor that is on a subdomain 8083677ff5aSBarry Smith boundary (i.e. is has more than one local owner) 8093677ff5aSBarry Smith 8103677ff5aSBarry Smith locally owned node - node that exists on this processors subdomain 8113677ff5aSBarry Smith 8123677ff5aSBarry Smith nontrivial locally owned node - node that is not in the interior (i.e. has more than one 8133677ff5aSBarry Smith local subdomain 8143677ff5aSBarry Smith */ 81524cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag1);CHKERRQ(ierr); 81624cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag2);CHKERRQ(ierr); 81724cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag3);CHKERRQ(ierr); 81889d82c54SBarry Smith 81989d82c54SBarry Smith for (i=0; i<n; i++) { 82089d82c54SBarry Smith if (lindices[i] > max) max = lindices[i]; 82189d82c54SBarry Smith } 82232dcc486SBarry Smith ierr = MPI_Allreduce(&max,&Ng,1,MPIU_INT,MPI_MAX,comm);CHKERRQ(ierr); 82378058e43SBarry Smith Ng++; 82489d82c54SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 82589d82c54SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 826bc8ff85bSBarry Smith scale = Ng/size + 1; 827a2e34c3dSBarry Smith ng = scale; if (rank == size-1) ng = Ng - scale*(size-1); ng = PetscMax(1,ng); 828caba0dd0SBarry Smith rstart = scale*rank; 82989d82c54SBarry Smith 83089d82c54SBarry Smith /* determine ownership ranges of global indices */ 831785e854fSJed Brown ierr = PetscMalloc1(2*size,&nprocs);CHKERRQ(ierr); 83232dcc486SBarry Smith ierr = PetscMemzero(nprocs,2*size*sizeof(PetscInt));CHKERRQ(ierr); 83389d82c54SBarry Smith 83489d82c54SBarry Smith /* determine owners of each local node */ 835785e854fSJed Brown ierr = PetscMalloc1(n,&owner);CHKERRQ(ierr); 83689d82c54SBarry Smith for (i=0; i<n; i++) { 8373677ff5aSBarry Smith proc = lindices[i]/scale; /* processor that globally owns this index */ 83827c402fcSBarry Smith nprocs[2*proc+1] = 1; /* processor globally owns at least one of ours */ 8393677ff5aSBarry Smith owner[i] = proc; 84027c402fcSBarry Smith nprocs[2*proc]++; /* count of how many that processor globally owns of ours */ 84189d82c54SBarry Smith } 84227c402fcSBarry Smith nsends = 0; for (i=0; i<size; i++) nsends += nprocs[2*i+1]; 8437904a332SBarry Smith ierr = PetscInfo1(mapping,"Number of global owners for my local data %D\n",nsends);CHKERRQ(ierr); 84489d82c54SBarry Smith 84589d82c54SBarry Smith /* inform other processors of number of messages and max length*/ 84627c402fcSBarry Smith ierr = PetscMaxSum(comm,nprocs,&nmax,&nrecvs);CHKERRQ(ierr); 8477904a332SBarry Smith ierr = PetscInfo1(mapping,"Number of local owners for my global data %D\n",nrecvs);CHKERRQ(ierr); 84889d82c54SBarry Smith 84989d82c54SBarry Smith /* post receives for owned rows */ 850785e854fSJed Brown ierr = PetscMalloc1((2*nrecvs+1)*(nmax+1),&recvs);CHKERRQ(ierr); 851854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&recv_waits);CHKERRQ(ierr); 85289d82c54SBarry Smith for (i=0; i<nrecvs; i++) { 85332dcc486SBarry Smith ierr = MPI_Irecv(recvs+2*nmax*i,2*nmax,MPIU_INT,MPI_ANY_SOURCE,tag1,comm,recv_waits+i);CHKERRQ(ierr); 85489d82c54SBarry Smith } 85589d82c54SBarry Smith 85689d82c54SBarry Smith /* pack messages containing lists of local nodes to owners */ 857854ce69bSBarry Smith ierr = PetscMalloc1(2*n+1,&sends);CHKERRQ(ierr); 858854ce69bSBarry Smith ierr = PetscMalloc1(size+1,&starts);CHKERRQ(ierr); 85989d82c54SBarry Smith starts[0] = 0; 860f6e5521dSKarl Rupp for (i=1; i<size; i++) starts[i] = starts[i-1] + 2*nprocs[2*i-2]; 86189d82c54SBarry Smith for (i=0; i<n; i++) { 86289d82c54SBarry Smith sends[starts[owner[i]]++] = lindices[i]; 86330dcb7c9SBarry Smith sends[starts[owner[i]]++] = i; 86489d82c54SBarry Smith } 86589d82c54SBarry Smith ierr = PetscFree(owner);CHKERRQ(ierr); 86689d82c54SBarry Smith starts[0] = 0; 867f6e5521dSKarl Rupp for (i=1; i<size; i++) starts[i] = starts[i-1] + 2*nprocs[2*i-2]; 86889d82c54SBarry Smith 86989d82c54SBarry Smith /* send the messages */ 870854ce69bSBarry Smith ierr = PetscMalloc1(nsends+1,&send_waits);CHKERRQ(ierr); 871854ce69bSBarry Smith ierr = PetscMalloc1(nsends+1,&dest);CHKERRQ(ierr); 87289d82c54SBarry Smith cnt = 0; 87389d82c54SBarry Smith for (i=0; i<size; i++) { 87427c402fcSBarry Smith if (nprocs[2*i]) { 87532dcc486SBarry Smith ierr = MPI_Isend(sends+starts[i],2*nprocs[2*i],MPIU_INT,i,tag1,comm,send_waits+cnt);CHKERRQ(ierr); 87630dcb7c9SBarry Smith dest[cnt] = i; 87789d82c54SBarry Smith cnt++; 87889d82c54SBarry Smith } 87989d82c54SBarry Smith } 88089d82c54SBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 88189d82c54SBarry Smith 88289d82c54SBarry Smith /* wait on receives */ 883854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&source);CHKERRQ(ierr); 884854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&len);CHKERRQ(ierr); 88589d82c54SBarry Smith cnt = nrecvs; 886854ce69bSBarry Smith ierr = PetscMalloc1(ng+1,&nownedsenders);CHKERRQ(ierr); 88732dcc486SBarry Smith ierr = PetscMemzero(nownedsenders,ng*sizeof(PetscInt));CHKERRQ(ierr); 88889d82c54SBarry Smith while (cnt) { 88989d82c54SBarry Smith ierr = MPI_Waitany(nrecvs,recv_waits,&imdex,&recv_status);CHKERRQ(ierr); 89089d82c54SBarry Smith /* unpack receives into our local space */ 89132dcc486SBarry Smith ierr = MPI_Get_count(&recv_status,MPIU_INT,&len[imdex]);CHKERRQ(ierr); 89289d82c54SBarry Smith source[imdex] = recv_status.MPI_SOURCE; 89330dcb7c9SBarry Smith len[imdex] = len[imdex]/2; 894caba0dd0SBarry Smith /* count how many local owners for each of my global owned indices */ 89530dcb7c9SBarry Smith for (i=0; i<len[imdex]; i++) nownedsenders[recvs[2*imdex*nmax+2*i]-rstart]++; 89689d82c54SBarry Smith cnt--; 89789d82c54SBarry Smith } 89889d82c54SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 89989d82c54SBarry Smith 90030dcb7c9SBarry Smith /* count how many globally owned indices are on an edge multiplied by how many processors own them. */ 901bc8ff85bSBarry Smith nowned = 0; 902bc8ff85bSBarry Smith nownedm = 0; 903bc8ff85bSBarry Smith for (i=0; i<ng; i++) { 904bc8ff85bSBarry Smith if (nownedsenders[i] > 1) {nownedm += nownedsenders[i]; nowned++;} 905bc8ff85bSBarry Smith } 906bc8ff85bSBarry Smith 907bc8ff85bSBarry Smith /* create single array to contain rank of all local owners of each globally owned index */ 908854ce69bSBarry Smith ierr = PetscMalloc1(nownedm+1,&ownedsenders);CHKERRQ(ierr); 909854ce69bSBarry Smith ierr = PetscMalloc1(ng+1,&starts);CHKERRQ(ierr); 910bc8ff85bSBarry Smith starts[0] = 0; 911bc8ff85bSBarry Smith for (i=1; i<ng; i++) { 912bc8ff85bSBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 913bc8ff85bSBarry Smith else starts[i] = starts[i-1]; 914bc8ff85bSBarry Smith } 915bc8ff85bSBarry Smith 91630dcb7c9SBarry Smith /* for each nontrival globally owned node list all arriving processors */ 917bc8ff85bSBarry Smith for (i=0; i<nrecvs; i++) { 918bc8ff85bSBarry Smith for (j=0; j<len[i]; j++) { 91930dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 920f6e5521dSKarl Rupp if (nownedsenders[node] > 1) ownedsenders[starts[node]++] = source[i]; 921bc8ff85bSBarry Smith } 922bc8ff85bSBarry Smith } 923bc8ff85bSBarry Smith 92407b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 92530dcb7c9SBarry Smith starts[0] = 0; 92630dcb7c9SBarry Smith for (i=1; i<ng; i++) { 92730dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 92830dcb7c9SBarry Smith else starts[i] = starts[i-1]; 92930dcb7c9SBarry Smith } 93030dcb7c9SBarry Smith for (i=0; i<ng; i++) { 93130dcb7c9SBarry Smith if (nownedsenders[i] > 1) { 9327904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] global node %D local owner processors: ",rank,i+rstart);CHKERRQ(ierr); 93330dcb7c9SBarry Smith for (j=0; j<nownedsenders[i]; j++) { 9347904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",ownedsenders[starts[i]+j]);CHKERRQ(ierr); 93530dcb7c9SBarry Smith } 93630dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 93730dcb7c9SBarry Smith } 93830dcb7c9SBarry Smith } 9390ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 94007b52d57SBarry Smith } /* ----------------------------------- */ 94130dcb7c9SBarry Smith 9423677ff5aSBarry Smith /* wait on original sends */ 9433a96401aSBarry Smith if (nsends) { 944785e854fSJed Brown ierr = PetscMalloc1(nsends,&send_status);CHKERRQ(ierr); 9453a96401aSBarry Smith ierr = MPI_Waitall(nsends,send_waits,send_status);CHKERRQ(ierr); 9463a96401aSBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 9473a96401aSBarry Smith } 94889d82c54SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 9493a96401aSBarry Smith ierr = PetscFree(sends);CHKERRQ(ierr); 9503677ff5aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 9513677ff5aSBarry Smith 9523677ff5aSBarry Smith /* pack messages to send back to local owners */ 95330dcb7c9SBarry Smith starts[0] = 0; 95430dcb7c9SBarry Smith for (i=1; i<ng; i++) { 95530dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 95630dcb7c9SBarry Smith else starts[i] = starts[i-1]; 95730dcb7c9SBarry Smith } 95830dcb7c9SBarry Smith nsends2 = nrecvs; 959854ce69bSBarry Smith ierr = PetscMalloc1(nsends2+1,&nprocs);CHKERRQ(ierr); /* length of each message */ 96030dcb7c9SBarry Smith for (i=0; i<nrecvs; i++) { 96130dcb7c9SBarry Smith nprocs[i] = 1; 96230dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 96330dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 964f6e5521dSKarl Rupp if (nownedsenders[node] > 1) nprocs[i] += 2 + nownedsenders[node]; 96530dcb7c9SBarry Smith } 96630dcb7c9SBarry Smith } 967f6e5521dSKarl Rupp nt = 0; 968f6e5521dSKarl Rupp for (i=0; i<nsends2; i++) nt += nprocs[i]; 969f6e5521dSKarl Rupp 970854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,&sends2);CHKERRQ(ierr); 971854ce69bSBarry Smith ierr = PetscMalloc1(nsends2+1,&starts2);CHKERRQ(ierr); 972f6e5521dSKarl Rupp 973f6e5521dSKarl Rupp starts2[0] = 0; 974f6e5521dSKarl Rupp for (i=1; i<nsends2; i++) starts2[i] = starts2[i-1] + nprocs[i-1]; 97530dcb7c9SBarry Smith /* 97630dcb7c9SBarry Smith Each message is 1 + nprocs[i] long, and consists of 97730dcb7c9SBarry Smith (0) the number of nodes being sent back 97830dcb7c9SBarry Smith (1) the local node number, 97930dcb7c9SBarry Smith (2) the number of processors sharing it, 98030dcb7c9SBarry Smith (3) the processors sharing it 98130dcb7c9SBarry Smith */ 98230dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 98330dcb7c9SBarry Smith cnt = 1; 98430dcb7c9SBarry Smith sends2[starts2[i]] = 0; 98530dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 98630dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 98730dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 98830dcb7c9SBarry Smith sends2[starts2[i]]++; 98930dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = recvs[2*i*nmax+2*j+1]; 99030dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = nownedsenders[node]; 99132dcc486SBarry Smith ierr = PetscMemcpy(&sends2[starts2[i]+cnt],&ownedsenders[starts[node]],nownedsenders[node]*sizeof(PetscInt));CHKERRQ(ierr); 99230dcb7c9SBarry Smith cnt += nownedsenders[node]; 99330dcb7c9SBarry Smith } 99430dcb7c9SBarry Smith } 99530dcb7c9SBarry Smith } 99630dcb7c9SBarry Smith 99730dcb7c9SBarry Smith /* receive the message lengths */ 99830dcb7c9SBarry Smith nrecvs2 = nsends; 999854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&lens2);CHKERRQ(ierr); 1000854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&starts3);CHKERRQ(ierr); 1001854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&recv_waits);CHKERRQ(ierr); 100230dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 1003d44834fbSBarry Smith ierr = MPI_Irecv(&lens2[i],1,MPIU_INT,dest[i],tag2,comm,recv_waits+i);CHKERRQ(ierr); 100430dcb7c9SBarry Smith } 1005d44834fbSBarry Smith 10068a8e0b3aSBarry Smith /* send the message lengths */ 10078a8e0b3aSBarry Smith for (i=0; i<nsends2; i++) { 10088a8e0b3aSBarry Smith ierr = MPI_Send(&nprocs[i],1,MPIU_INT,source[i],tag2,comm);CHKERRQ(ierr); 10098a8e0b3aSBarry Smith } 10108a8e0b3aSBarry Smith 1011d44834fbSBarry Smith /* wait on receives of lens */ 10120c468ba9SBarry Smith if (nrecvs2) { 1013785e854fSJed Brown ierr = PetscMalloc1(nrecvs2,&recv_statuses);CHKERRQ(ierr); 1014d44834fbSBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 1015d44834fbSBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 10160c468ba9SBarry Smith } 1017a2ea699eSBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 1018d44834fbSBarry Smith 101930dcb7c9SBarry Smith starts3[0] = 0; 1020d44834fbSBarry Smith nt = 0; 102130dcb7c9SBarry Smith for (i=0; i<nrecvs2-1; i++) { 102230dcb7c9SBarry Smith starts3[i+1] = starts3[i] + lens2[i]; 1023d44834fbSBarry Smith nt += lens2[i]; 102430dcb7c9SBarry Smith } 102576466f69SStefano Zampini if (nrecvs2) nt += lens2[nrecvs2-1]; 1026d44834fbSBarry Smith 1027854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,&recvs2);CHKERRQ(ierr); 1028854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&recv_waits);CHKERRQ(ierr); 102952b72c4aSBarry Smith for (i=0; i<nrecvs2; i++) { 103032dcc486SBarry Smith ierr = MPI_Irecv(recvs2+starts3[i],lens2[i],MPIU_INT,dest[i],tag3,comm,recv_waits+i);CHKERRQ(ierr); 103130dcb7c9SBarry Smith } 103230dcb7c9SBarry Smith 103330dcb7c9SBarry Smith /* send the messages */ 1034854ce69bSBarry Smith ierr = PetscMalloc1(nsends2+1,&send_waits);CHKERRQ(ierr); 103530dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 103632dcc486SBarry Smith ierr = MPI_Isend(sends2+starts2[i],nprocs[i],MPIU_INT,source[i],tag3,comm,send_waits+i);CHKERRQ(ierr); 103730dcb7c9SBarry Smith } 103830dcb7c9SBarry Smith 103930dcb7c9SBarry Smith /* wait on receives */ 10400c468ba9SBarry Smith if (nrecvs2) { 1041785e854fSJed Brown ierr = PetscMalloc1(nrecvs2,&recv_statuses);CHKERRQ(ierr); 104230dcb7c9SBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 104330dcb7c9SBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 10440c468ba9SBarry Smith } 104530dcb7c9SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 104630dcb7c9SBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 104730dcb7c9SBarry Smith 104807b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 104930dcb7c9SBarry Smith cnt = 0; 105030dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 105130dcb7c9SBarry Smith nt = recvs2[cnt++]; 105230dcb7c9SBarry Smith for (j=0; j<nt; j++) { 10537904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] local node %D number of subdomains %D: ",rank,recvs2[cnt],recvs2[cnt+1]);CHKERRQ(ierr); 105430dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 10557904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",recvs2[cnt+2+k]);CHKERRQ(ierr); 105630dcb7c9SBarry Smith } 105730dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 105830dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 105930dcb7c9SBarry Smith } 106030dcb7c9SBarry Smith } 10610ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 106207b52d57SBarry Smith } /* ----------------------------------- */ 106330dcb7c9SBarry Smith 106430dcb7c9SBarry Smith /* count number subdomains for each local node */ 1065785e854fSJed Brown ierr = PetscMalloc1(size,&nprocs);CHKERRQ(ierr); 106632dcc486SBarry Smith ierr = PetscMemzero(nprocs,size*sizeof(PetscInt));CHKERRQ(ierr); 106730dcb7c9SBarry Smith cnt = 0; 106830dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 106930dcb7c9SBarry Smith nt = recvs2[cnt++]; 107030dcb7c9SBarry Smith for (j=0; j<nt; j++) { 1071f6e5521dSKarl Rupp for (k=0; k<recvs2[cnt+1]; k++) nprocs[recvs2[cnt+2+k]]++; 107230dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 107330dcb7c9SBarry Smith } 107430dcb7c9SBarry Smith } 107530dcb7c9SBarry Smith nt = 0; for (i=0; i<size; i++) nt += (nprocs[i] > 0); 107630dcb7c9SBarry Smith *nproc = nt; 1077854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,procs);CHKERRQ(ierr); 1078854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,numprocs);CHKERRQ(ierr); 1079854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,indices);CHKERRQ(ierr); 10800298fd71SBarry Smith for (i=0;i<nt+1;i++) (*indices)[i]=NULL; 1081785e854fSJed Brown ierr = PetscMalloc1(size,&bprocs);CHKERRQ(ierr); 108230dcb7c9SBarry Smith cnt = 0; 108330dcb7c9SBarry Smith for (i=0; i<size; i++) { 108430dcb7c9SBarry Smith if (nprocs[i] > 0) { 108530dcb7c9SBarry Smith bprocs[i] = cnt; 108630dcb7c9SBarry Smith (*procs)[cnt] = i; 108730dcb7c9SBarry Smith (*numprocs)[cnt] = nprocs[i]; 1088785e854fSJed Brown ierr = PetscMalloc1(nprocs[i],&(*indices)[cnt]);CHKERRQ(ierr); 108930dcb7c9SBarry Smith cnt++; 109030dcb7c9SBarry Smith } 109130dcb7c9SBarry Smith } 109230dcb7c9SBarry Smith 109330dcb7c9SBarry Smith /* make the list of subdomains for each nontrivial local node */ 109432dcc486SBarry Smith ierr = PetscMemzero(*numprocs,nt*sizeof(PetscInt));CHKERRQ(ierr); 109530dcb7c9SBarry Smith cnt = 0; 109630dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 109730dcb7c9SBarry Smith nt = recvs2[cnt++]; 109830dcb7c9SBarry Smith for (j=0; j<nt; j++) { 1099f6e5521dSKarl Rupp for (k=0; k<recvs2[cnt+1]; k++) (*indices)[bprocs[recvs2[cnt+2+k]]][(*numprocs)[bprocs[recvs2[cnt+2+k]]]++] = recvs2[cnt]; 110030dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 110130dcb7c9SBarry Smith } 110230dcb7c9SBarry Smith } 110330dcb7c9SBarry Smith ierr = PetscFree(bprocs);CHKERRQ(ierr); 110407b52d57SBarry Smith ierr = PetscFree(recvs2);CHKERRQ(ierr); 110530dcb7c9SBarry Smith 110607b52d57SBarry Smith /* sort the node indexing by their global numbers */ 110707b52d57SBarry Smith nt = *nproc; 110807b52d57SBarry Smith for (i=0; i<nt; i++) { 1109854ce69bSBarry Smith ierr = PetscMalloc1((*numprocs)[i],&tmp);CHKERRQ(ierr); 1110f6e5521dSKarl Rupp for (j=0; j<(*numprocs)[i]; j++) tmp[j] = lindices[(*indices)[i][j]]; 111107b52d57SBarry Smith ierr = PetscSortIntWithArray((*numprocs)[i],tmp,(*indices)[i]);CHKERRQ(ierr); 111207b52d57SBarry Smith ierr = PetscFree(tmp);CHKERRQ(ierr); 111307b52d57SBarry Smith } 111407b52d57SBarry Smith 111507b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 111630dcb7c9SBarry Smith nt = *nproc; 111730dcb7c9SBarry Smith for (i=0; i<nt; i++) { 11187904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] subdomain %D number of indices %D: ",rank,(*procs)[i],(*numprocs)[i]);CHKERRQ(ierr); 111930dcb7c9SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 11207904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",(*indices)[i][j]);CHKERRQ(ierr); 112130dcb7c9SBarry Smith } 112230dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 112330dcb7c9SBarry Smith } 11240ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 112507b52d57SBarry Smith } /* ----------------------------------- */ 112630dcb7c9SBarry Smith 112730dcb7c9SBarry Smith /* wait on sends */ 112830dcb7c9SBarry Smith if (nsends2) { 1129785e854fSJed Brown ierr = PetscMalloc1(nsends2,&send_status);CHKERRQ(ierr); 113030dcb7c9SBarry Smith ierr = MPI_Waitall(nsends2,send_waits,send_status);CHKERRQ(ierr); 113130dcb7c9SBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 113230dcb7c9SBarry Smith } 113330dcb7c9SBarry Smith 113430dcb7c9SBarry Smith ierr = PetscFree(starts3);CHKERRQ(ierr); 113530dcb7c9SBarry Smith ierr = PetscFree(dest);CHKERRQ(ierr); 113630dcb7c9SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 11373677ff5aSBarry Smith 1138bc8ff85bSBarry Smith ierr = PetscFree(nownedsenders);CHKERRQ(ierr); 1139bc8ff85bSBarry Smith ierr = PetscFree(ownedsenders);CHKERRQ(ierr); 1140bc8ff85bSBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 114130dcb7c9SBarry Smith ierr = PetscFree(starts2);CHKERRQ(ierr); 114230dcb7c9SBarry Smith ierr = PetscFree(lens2);CHKERRQ(ierr); 114389d82c54SBarry Smith 114489d82c54SBarry Smith ierr = PetscFree(source);CHKERRQ(ierr); 114597f1f81fSBarry Smith ierr = PetscFree(len);CHKERRQ(ierr); 114689d82c54SBarry Smith ierr = PetscFree(recvs);CHKERRQ(ierr); 11473a96401aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 114830dcb7c9SBarry Smith ierr = PetscFree(sends2);CHKERRQ(ierr); 114924cf384cSBarry Smith 115024cf384cSBarry Smith /* put the information about myself as the first entry in the list */ 115124cf384cSBarry Smith first_procs = (*procs)[0]; 115224cf384cSBarry Smith first_numprocs = (*numprocs)[0]; 115324cf384cSBarry Smith first_indices = (*indices)[0]; 115424cf384cSBarry Smith for (i=0; i<*nproc; i++) { 115524cf384cSBarry Smith if ((*procs)[i] == rank) { 115624cf384cSBarry Smith (*procs)[0] = (*procs)[i]; 115724cf384cSBarry Smith (*numprocs)[0] = (*numprocs)[i]; 115824cf384cSBarry Smith (*indices)[0] = (*indices)[i]; 115924cf384cSBarry Smith (*procs)[i] = first_procs; 116024cf384cSBarry Smith (*numprocs)[i] = first_numprocs; 116124cf384cSBarry Smith (*indices)[i] = first_indices; 116224cf384cSBarry Smith break; 116324cf384cSBarry Smith } 116424cf384cSBarry Smith } 116589d82c54SBarry Smith PetscFunctionReturn(0); 116689d82c54SBarry Smith } 116789d82c54SBarry Smith 11684a2ae208SSatish Balay #undef __FUNCT__ 11696a818285SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingRestoreBlockInfo" 11706a818285SBarry Smith /*@C 11716a818285SBarry Smith ISLocalToGlobalMappingRestoreBlockInfo - Frees the memory allocated by ISLocalToGlobalMappingGetBlockInfo() 11726a818285SBarry Smith 11736a818285SBarry Smith Collective on ISLocalToGlobalMapping 11746a818285SBarry Smith 11756a818285SBarry Smith Input Parameters: 11766a818285SBarry Smith . mapping - the mapping from local to global indexing 11776a818285SBarry Smith 11786a818285SBarry Smith Output Parameter: 11796a818285SBarry Smith + nproc - number of processors that are connected to this one 11806a818285SBarry Smith . proc - neighboring processors 11816a818285SBarry Smith . numproc - number of indices for each processor 11826a818285SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 11836a818285SBarry Smith 11846a818285SBarry Smith Level: advanced 11856a818285SBarry Smith 11866a818285SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 11876a818285SBarry Smith ISLocalToGlobalMappingGetInfo() 11886a818285SBarry Smith @*/ 11896a818285SBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreBlockInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 11906a818285SBarry Smith { 11916a818285SBarry Smith PetscErrorCode ierr; 11926a818285SBarry Smith PetscInt i; 11936a818285SBarry Smith 11946a818285SBarry Smith PetscFunctionBegin; 1195cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 11966a818285SBarry Smith ierr = PetscFree(*procs);CHKERRQ(ierr); 11976a818285SBarry Smith ierr = PetscFree(*numprocs);CHKERRQ(ierr); 11986a818285SBarry Smith if (*indices) { 11996a818285SBarry Smith ierr = PetscFree((*indices)[0]);CHKERRQ(ierr); 12006a818285SBarry Smith for (i=1; i<*nproc; i++) { 12016a818285SBarry Smith ierr = PetscFree((*indices)[i]);CHKERRQ(ierr); 12026a818285SBarry Smith } 12036a818285SBarry Smith ierr = PetscFree(*indices);CHKERRQ(ierr); 12046a818285SBarry Smith } 12056a818285SBarry Smith PetscFunctionReturn(0); 12066a818285SBarry Smith } 12076a818285SBarry Smith 12086a818285SBarry Smith #undef __FUNCT__ 12096a818285SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingGetInfo" 12106a818285SBarry Smith /*@C 12116a818285SBarry Smith ISLocalToGlobalMappingGetInfo - Gets the neighbor information for each processor and 12126a818285SBarry Smith each index shared by more than one processor 12136a818285SBarry Smith 12146a818285SBarry Smith Collective on ISLocalToGlobalMapping 12156a818285SBarry Smith 12166a818285SBarry Smith Input Parameters: 12176a818285SBarry Smith . mapping - the mapping from local to global indexing 12186a818285SBarry Smith 12196a818285SBarry Smith Output Parameter: 12206a818285SBarry Smith + nproc - number of processors that are connected to this one 12216a818285SBarry Smith . proc - neighboring processors 12226a818285SBarry Smith . numproc - number of indices for each subdomain (processor) 12236a818285SBarry Smith - indices - indices of nodes (in local numbering) shared with neighbors (sorted by global numbering) 12246a818285SBarry Smith 12256a818285SBarry Smith Level: advanced 12266a818285SBarry Smith 12276a818285SBarry Smith Concepts: mapping^local to global 12286a818285SBarry Smith 12296a818285SBarry Smith Fortran Usage: 12306a818285SBarry Smith $ ISLocalToGlobalMpngGetInfoSize(ISLocalToGlobalMapping,PetscInt nproc,PetscInt numprocmax,ierr) followed by 12316a818285SBarry Smith $ ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping,PetscInt nproc, PetscInt procs[nproc],PetscInt numprocs[nproc], 12326a818285SBarry Smith PetscInt indices[nproc][numprocmax],ierr) 12336a818285SBarry Smith There is no ISLocalToGlobalMappingRestoreInfo() in Fortran. You must make sure that procs[], numprocs[] and 12346a818285SBarry Smith indices[][] are large enough arrays, either by allocating them dynamically or defining static ones large enough. 12356a818285SBarry Smith 12366a818285SBarry Smith 12376a818285SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 12386a818285SBarry Smith ISLocalToGlobalMappingRestoreInfo() 12396a818285SBarry Smith @*/ 12406a818285SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 12416a818285SBarry Smith { 12426a818285SBarry Smith PetscErrorCode ierr; 12436a818285SBarry Smith PetscInt **bindices = NULL,bs = mapping->bs,i,j,k; 12446a818285SBarry Smith 12456a818285SBarry Smith PetscFunctionBegin; 12466a818285SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 12476a818285SBarry Smith ierr = ISLocalToGlobalMappingGetBlockInfo(mapping,nproc,procs,numprocs,&bindices);CHKERRQ(ierr); 1248732f65e3SBarry Smith ierr = PetscCalloc1(*nproc,&*indices);CHKERRQ(ierr); 12496a818285SBarry Smith for (i=0; i<*nproc; i++) { 12506a818285SBarry Smith ierr = PetscMalloc1(bs*(*numprocs)[i],&(*indices)[i]);CHKERRQ(ierr); 12516a818285SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 12526a818285SBarry Smith for (k=0; k<bs; k++) { 12536a818285SBarry Smith (*indices)[i][j*bs+k] = bs*bindices[i][j] + k; 12546a818285SBarry Smith } 12556a818285SBarry Smith } 12566a818285SBarry Smith (*numprocs)[i] *= bs; 12576a818285SBarry Smith } 12586a818285SBarry Smith if (bindices) { 12596a818285SBarry Smith ierr = PetscFree(bindices[0]);CHKERRQ(ierr); 12606a818285SBarry Smith for (i=1; i<*nproc; i++) { 12616a818285SBarry Smith ierr = PetscFree(bindices[i]);CHKERRQ(ierr); 12626a818285SBarry Smith } 12636a818285SBarry Smith ierr = PetscFree(bindices);CHKERRQ(ierr); 12646a818285SBarry Smith } 12656a818285SBarry Smith PetscFunctionReturn(0); 12666a818285SBarry Smith } 12676a818285SBarry Smith 12686a818285SBarry Smith #undef __FUNCT__ 12694a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingRestoreInfo" 127007b52d57SBarry Smith /*@C 127107b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo - Frees the memory allocated by ISLocalToGlobalMappingGetInfo() 127289d82c54SBarry Smith 127307b52d57SBarry Smith Collective on ISLocalToGlobalMapping 127407b52d57SBarry Smith 127507b52d57SBarry Smith Input Parameters: 127607b52d57SBarry Smith . mapping - the mapping from local to global indexing 127707b52d57SBarry Smith 127807b52d57SBarry Smith Output Parameter: 127907b52d57SBarry Smith + nproc - number of processors that are connected to this one 128007b52d57SBarry Smith . proc - neighboring processors 128107b52d57SBarry Smith . numproc - number of indices for each processor 128207b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 128307b52d57SBarry Smith 128407b52d57SBarry Smith Level: advanced 128507b52d57SBarry Smith 128607b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 128707b52d57SBarry Smith ISLocalToGlobalMappingGetInfo() 128807b52d57SBarry Smith @*/ 12897087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 129007b52d57SBarry Smith { 12916849ba73SBarry Smith PetscErrorCode ierr; 129207b52d57SBarry Smith 129307b52d57SBarry Smith PetscFunctionBegin; 12946a818285SBarry Smith ierr = ISLocalToGlobalMappingRestoreBlockInfo(mapping,nproc,procs,numprocs,indices);CHKERRQ(ierr); 129507b52d57SBarry Smith PetscFunctionReturn(0); 129607b52d57SBarry Smith } 129786994e45SJed Brown 129886994e45SJed Brown #undef __FUNCT__ 129986994e45SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingGetIndices" 130086994e45SJed Brown /*@C 1301107e9a97SBarry Smith ISLocalToGlobalMappingGetIndices - Get global indices for every local point that is mapped 130286994e45SJed Brown 130386994e45SJed Brown Not Collective 130486994e45SJed Brown 130586994e45SJed Brown Input Arguments: 130686994e45SJed Brown . ltog - local to global mapping 130786994e45SJed Brown 130886994e45SJed Brown Output Arguments: 1309565245c5SBarry Smith . array - array of indices, the length of this array may be obtained with ISLocalToGlobalMappingGetSize() 131086994e45SJed Brown 131186994e45SJed Brown Level: advanced 131286994e45SJed Brown 1313107e9a97SBarry Smith Notes: ISLocalToGlobalMappingGetSize() returns the length the this array 1314107e9a97SBarry Smith 1315107e9a97SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingRestoreIndices(), ISLocalToGlobalMappingGetBlockIndices(), ISLocalToGlobalMappingRestoreBlockIndices() 131686994e45SJed Brown @*/ 13177087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingGetIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 131886994e45SJed Brown { 131986994e45SJed Brown PetscFunctionBegin; 132086994e45SJed Brown PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 132186994e45SJed Brown PetscValidPointer(array,2); 132245b6f7e9SBarry Smith if (ltog->bs == 1) { 132386994e45SJed Brown *array = ltog->indices; 132445b6f7e9SBarry Smith } else { 132545b6f7e9SBarry Smith PetscInt *jj,k,i,j,n = ltog->n, bs = ltog->bs; 132645b6f7e9SBarry Smith const PetscInt *ii; 132745b6f7e9SBarry Smith PetscErrorCode ierr; 132845b6f7e9SBarry Smith 132945b6f7e9SBarry Smith ierr = PetscMalloc1(bs*n,&jj);CHKERRQ(ierr); 133045b6f7e9SBarry Smith *array = jj; 133145b6f7e9SBarry Smith k = 0; 133245b6f7e9SBarry Smith ii = ltog->indices; 133345b6f7e9SBarry Smith for (i=0; i<n; i++) 133445b6f7e9SBarry Smith for (j=0; j<bs; j++) 133545b6f7e9SBarry Smith jj[k++] = bs*ii[i] + j; 133645b6f7e9SBarry Smith } 133786994e45SJed Brown PetscFunctionReturn(0); 133886994e45SJed Brown } 133986994e45SJed Brown 134086994e45SJed Brown #undef __FUNCT__ 134186994e45SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingRestoreIndices" 134286994e45SJed Brown /*@C 134386994e45SJed Brown ISLocalToGlobalMappingRestoreIndices - Restore indices obtained with ISLocalToGlobalMappingRestoreIndices() 134486994e45SJed Brown 134586994e45SJed Brown Not Collective 134686994e45SJed Brown 134786994e45SJed Brown Input Arguments: 134886994e45SJed Brown + ltog - local to global mapping 134986994e45SJed Brown - array - array of indices 135086994e45SJed Brown 135186994e45SJed Brown Level: advanced 135286994e45SJed Brown 135386994e45SJed Brown .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingGetIndices() 135486994e45SJed Brown @*/ 13557087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 135686994e45SJed Brown { 135786994e45SJed Brown PetscFunctionBegin; 135886994e45SJed Brown PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 135986994e45SJed Brown PetscValidPointer(array,2); 136045b6f7e9SBarry Smith if (ltog->bs == 1 && *array != ltog->indices) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Trying to return mismatched pointer"); 136145b6f7e9SBarry Smith 136245b6f7e9SBarry Smith if (ltog->bs > 1) { 136345b6f7e9SBarry Smith PetscErrorCode ierr; 136445b6f7e9SBarry Smith ierr = PetscFree(*(void**)array);CHKERRQ(ierr); 136545b6f7e9SBarry Smith } 136645b6f7e9SBarry Smith PetscFunctionReturn(0); 136745b6f7e9SBarry Smith } 136845b6f7e9SBarry Smith 136945b6f7e9SBarry Smith #undef __FUNCT__ 137045b6f7e9SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingGetBlockIndices" 137145b6f7e9SBarry Smith /*@C 137245b6f7e9SBarry Smith ISLocalToGlobalMappingGetBlockIndices - Get global indices for every local block 137345b6f7e9SBarry Smith 137445b6f7e9SBarry Smith Not Collective 137545b6f7e9SBarry Smith 137645b6f7e9SBarry Smith Input Arguments: 137745b6f7e9SBarry Smith . ltog - local to global mapping 137845b6f7e9SBarry Smith 137945b6f7e9SBarry Smith Output Arguments: 138045b6f7e9SBarry Smith . array - array of indices 138145b6f7e9SBarry Smith 138245b6f7e9SBarry Smith Level: advanced 138345b6f7e9SBarry Smith 138445b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingRestoreBlockIndices() 138545b6f7e9SBarry Smith @*/ 138645b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetBlockIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 138745b6f7e9SBarry Smith { 138845b6f7e9SBarry Smith PetscFunctionBegin; 138945b6f7e9SBarry Smith PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 139045b6f7e9SBarry Smith PetscValidPointer(array,2); 139145b6f7e9SBarry Smith *array = ltog->indices; 139245b6f7e9SBarry Smith PetscFunctionReturn(0); 139345b6f7e9SBarry Smith } 139445b6f7e9SBarry Smith 139545b6f7e9SBarry Smith #undef __FUNCT__ 139645b6f7e9SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingRestoreBlockIndices" 139745b6f7e9SBarry Smith /*@C 139845b6f7e9SBarry Smith ISLocalToGlobalMappingRestoreBlockIndices - Restore indices obtained with ISLocalToGlobalMappingGetBlockIndices() 139945b6f7e9SBarry Smith 140045b6f7e9SBarry Smith Not Collective 140145b6f7e9SBarry Smith 140245b6f7e9SBarry Smith Input Arguments: 140345b6f7e9SBarry Smith + ltog - local to global mapping 140445b6f7e9SBarry Smith - array - array of indices 140545b6f7e9SBarry Smith 140645b6f7e9SBarry Smith Level: advanced 140745b6f7e9SBarry Smith 140845b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingGetIndices() 140945b6f7e9SBarry Smith @*/ 141045b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreBlockIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 141145b6f7e9SBarry Smith { 141245b6f7e9SBarry Smith PetscFunctionBegin; 141345b6f7e9SBarry Smith PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 141445b6f7e9SBarry Smith PetscValidPointer(array,2); 141586994e45SJed Brown if (*array != ltog->indices) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Trying to return mismatched pointer"); 14160298fd71SBarry Smith *array = NULL; 141786994e45SJed Brown PetscFunctionReturn(0); 141886994e45SJed Brown } 1419f7efa3c7SJed Brown 1420f7efa3c7SJed Brown #undef __FUNCT__ 1421f7efa3c7SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingConcatenate" 1422f7efa3c7SJed Brown /*@C 1423f7efa3c7SJed Brown ISLocalToGlobalMappingConcatenate - Create a new mapping that concatenates a list of mappings 1424f7efa3c7SJed Brown 1425f7efa3c7SJed Brown Not Collective 1426f7efa3c7SJed Brown 1427f7efa3c7SJed Brown Input Arguments: 1428f7efa3c7SJed Brown + comm - communicator for the new mapping, must contain the communicator of every mapping to concatenate 1429f7efa3c7SJed Brown . n - number of mappings to concatenate 1430f7efa3c7SJed Brown - ltogs - local to global mappings 1431f7efa3c7SJed Brown 1432f7efa3c7SJed Brown Output Arguments: 1433f7efa3c7SJed Brown . ltogcat - new mapping 1434f7efa3c7SJed Brown 14359d90f715SBarry Smith Note: this currently always returns a mapping with block size of 1 14369d90f715SBarry Smith 14379d90f715SBarry Smith Developer Note: If all the input mapping have the same block size we could easily handle that as a special case 14389d90f715SBarry Smith 1439f7efa3c7SJed Brown Level: advanced 1440f7efa3c7SJed Brown 1441f7efa3c7SJed Brown .seealso: ISLocalToGlobalMappingCreate() 1442f7efa3c7SJed Brown @*/ 1443f7efa3c7SJed Brown PetscErrorCode ISLocalToGlobalMappingConcatenate(MPI_Comm comm,PetscInt n,const ISLocalToGlobalMapping ltogs[],ISLocalToGlobalMapping *ltogcat) 1444f7efa3c7SJed Brown { 1445f7efa3c7SJed Brown PetscInt i,cnt,m,*idx; 1446f7efa3c7SJed Brown PetscErrorCode ierr; 1447f7efa3c7SJed Brown 1448f7efa3c7SJed Brown PetscFunctionBegin; 1449f7efa3c7SJed Brown if (n < 0) SETERRQ1(comm,PETSC_ERR_ARG_OUTOFRANGE,"Must have a non-negative number of mappings, given %D",n); 1450f7efa3c7SJed Brown if (n > 0) PetscValidPointer(ltogs,3); 1451f7efa3c7SJed Brown for (i=0; i<n; i++) PetscValidHeaderSpecific(ltogs[i],IS_LTOGM_CLASSID,3); 1452f7efa3c7SJed Brown PetscValidPointer(ltogcat,4); 1453f7efa3c7SJed Brown for (cnt=0,i=0; i<n; i++) { 1454f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetSize(ltogs[i],&m);CHKERRQ(ierr); 1455f7efa3c7SJed Brown cnt += m; 1456f7efa3c7SJed Brown } 1457785e854fSJed Brown ierr = PetscMalloc1(cnt,&idx);CHKERRQ(ierr); 1458f7efa3c7SJed Brown for (cnt=0,i=0; i<n; i++) { 1459f7efa3c7SJed Brown const PetscInt *subidx; 1460f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetSize(ltogs[i],&m);CHKERRQ(ierr); 1461f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetIndices(ltogs[i],&subidx);CHKERRQ(ierr); 1462f7efa3c7SJed Brown ierr = PetscMemcpy(&idx[cnt],subidx,m*sizeof(PetscInt));CHKERRQ(ierr); 1463f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingRestoreIndices(ltogs[i],&subidx);CHKERRQ(ierr); 1464f7efa3c7SJed Brown cnt += m; 1465f7efa3c7SJed Brown } 1466f0413b6fSBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,1,cnt,idx,PETSC_OWN_POINTER,ltogcat);CHKERRQ(ierr); 1467f7efa3c7SJed Brown PetscFunctionReturn(0); 1468f7efa3c7SJed Brown } 146904a59952SBarry Smith 147004a59952SBarry Smith 1471