12362add9SBarry Smith 2af0996ceSBarry Smith #include <petsc/private/isimpl.h> /*I "petscis.h" I*/ 3e8f14785SLisandro Dalcin #include <petsc/private/hashmapi.h> 40c312b8eSJed Brown #include <petscsf.h> 5665c2dedSJed Brown #include <petscviewer.h> 62362add9SBarry Smith 77087cfbeSBarry Smith PetscClassId IS_LTOGM_CLASSID; 8268a049cSStefano Zampini static PetscErrorCode ISLocalToGlobalMappingGetBlockInfo_Private(ISLocalToGlobalMapping,PetscInt*,PetscInt**,PetscInt**,PetscInt***); 98e58c17dSMatthew Knepley 10413f72f0SBarry Smith typedef struct { 11413f72f0SBarry Smith PetscInt *globals; 12413f72f0SBarry Smith } ISLocalToGlobalMapping_Basic; 13413f72f0SBarry Smith 14413f72f0SBarry Smith typedef struct { 15e8f14785SLisandro Dalcin PetscHMapI globalht; 16413f72f0SBarry Smith } ISLocalToGlobalMapping_Hash; 17413f72f0SBarry Smith 186528b96dSMatthew G. Knepley /*@C 196528b96dSMatthew G. Knepley ISGetPointRange - Returns a description of the points in an IS suitable for traversal 20413f72f0SBarry Smith 216528b96dSMatthew G. Knepley Not collective 226528b96dSMatthew G. Knepley 236528b96dSMatthew G. Knepley Input Parameter: 246528b96dSMatthew G. Knepley . pointIS - The IS object 256528b96dSMatthew G. Knepley 266528b96dSMatthew G. Knepley Output Parameters: 276528b96dSMatthew G. Knepley + pStart - The first index, see notes 286528b96dSMatthew G. Knepley . pEnd - One past the last index, see notes 296528b96dSMatthew G. Knepley - points - The indices, see notes 306528b96dSMatthew G. Knepley 316528b96dSMatthew G. Knepley Notes: 326528b96dSMatthew G. Knepley If the IS contains contiguous indices in an ISSTRIDE, then the indices are contained in [pStart, pEnd) and points = NULL. Otherwise, pStart = 0, pEnd = numIndices, and points is an array of the indices. This supports the following pattern 336528b96dSMatthew G. Knepley $ ISGetPointRange(is, &pStart, &pEnd, &points); 346528b96dSMatthew G. Knepley $ for (p = pStart; p < pEnd; ++p) { 356528b96dSMatthew G. Knepley $ const PetscInt point = points ? points[p] : p; 366528b96dSMatthew G. Knepley $ } 376528b96dSMatthew G. Knepley $ ISRestorePointRange(is, &pstart, &pEnd, &points); 386528b96dSMatthew G. Knepley 396528b96dSMatthew G. Knepley Level: intermediate 406528b96dSMatthew G. Knepley 416528b96dSMatthew G. Knepley .seealso: ISRestorePointRange(), ISGetPointSubrange(), ISGetIndices(), ISCreateStride() 426528b96dSMatthew G. Knepley @*/ 439305a4c7SMatthew G. Knepley PetscErrorCode ISGetPointRange(IS pointIS, PetscInt *pStart, PetscInt *pEnd, const PetscInt **points) 449305a4c7SMatthew G. Knepley { 459305a4c7SMatthew G. Knepley PetscInt numCells, step = 1; 469305a4c7SMatthew G. Knepley PetscBool isStride; 479305a4c7SMatthew G. Knepley PetscErrorCode ierr; 489305a4c7SMatthew G. Knepley 499305a4c7SMatthew G. Knepley PetscFunctionBeginHot; 509305a4c7SMatthew G. Knepley *pStart = 0; 519305a4c7SMatthew G. Knepley *points = NULL; 529305a4c7SMatthew G. Knepley ierr = ISGetLocalSize(pointIS, &numCells);CHKERRQ(ierr); 539305a4c7SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) pointIS, ISSTRIDE, &isStride);CHKERRQ(ierr); 549305a4c7SMatthew G. Knepley if (isStride) {ierr = ISStrideGetInfo(pointIS, pStart, &step);CHKERRQ(ierr);} 559305a4c7SMatthew G. Knepley *pEnd = *pStart + numCells; 569305a4c7SMatthew G. Knepley if (!isStride || step != 1) {ierr = ISGetIndices(pointIS, points);CHKERRQ(ierr);} 579305a4c7SMatthew G. Knepley PetscFunctionReturn(0); 589305a4c7SMatthew G. Knepley } 599305a4c7SMatthew G. Knepley 606528b96dSMatthew G. Knepley /*@C 616528b96dSMatthew G. Knepley ISRestorePointRange - Destroys the traversal description 626528b96dSMatthew G. Knepley 636528b96dSMatthew G. Knepley Not collective 646528b96dSMatthew G. Knepley 656528b96dSMatthew G. Knepley Input Parameters: 666528b96dSMatthew G. Knepley + pointIS - The IS object 676528b96dSMatthew G. Knepley . pStart - The first index, from ISGetPointRange() 686528b96dSMatthew G. Knepley . pEnd - One past the last index, from ISGetPointRange() 696528b96dSMatthew G. Knepley - points - The indices, from ISGetPointRange() 706528b96dSMatthew G. Knepley 716528b96dSMatthew G. Knepley Notes: 726528b96dSMatthew G. Knepley If the IS contains contiguous indices in an ISSTRIDE, then the indices are contained in [pStart, pEnd) and points = NULL. Otherwise, pStart = 0, pEnd = numIndices, and points is an array of the indices. This supports the following pattern 736528b96dSMatthew G. Knepley $ ISGetPointRange(is, &pStart, &pEnd, &points); 746528b96dSMatthew G. Knepley $ for (p = pStart; p < pEnd; ++p) { 756528b96dSMatthew G. Knepley $ const PetscInt point = points ? points[p] : p; 766528b96dSMatthew G. Knepley $ } 776528b96dSMatthew G. Knepley $ ISRestorePointRange(is, &pstart, &pEnd, &points); 786528b96dSMatthew G. Knepley 796528b96dSMatthew G. Knepley Level: intermediate 806528b96dSMatthew G. Knepley 816528b96dSMatthew G. Knepley .seealso: ISGetPointRange(), ISGetPointSubrange(), ISGetIndices(), ISCreateStride() 826528b96dSMatthew G. Knepley @*/ 839305a4c7SMatthew G. Knepley PetscErrorCode ISRestorePointRange(IS pointIS, PetscInt *pStart, PetscInt *pEnd, const PetscInt **points) 849305a4c7SMatthew G. Knepley { 859305a4c7SMatthew G. Knepley PetscInt step = 1; 869305a4c7SMatthew G. Knepley PetscBool isStride; 879305a4c7SMatthew G. Knepley PetscErrorCode ierr; 889305a4c7SMatthew G. Knepley 899305a4c7SMatthew G. Knepley PetscFunctionBeginHot; 909305a4c7SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) pointIS, ISSTRIDE, &isStride);CHKERRQ(ierr); 919305a4c7SMatthew G. Knepley if (isStride) {ierr = ISStrideGetInfo(pointIS, pStart, &step);CHKERRQ(ierr);} 929305a4c7SMatthew G. Knepley if (!isStride || step != 1) {ierr = ISGetIndices(pointIS, points);CHKERRQ(ierr);} 939305a4c7SMatthew G. Knepley PetscFunctionReturn(0); 949305a4c7SMatthew G. Knepley } 959305a4c7SMatthew G. Knepley 966528b96dSMatthew G. Knepley /*@C 976528b96dSMatthew G. Knepley ISGetPointSubrange - Configures the input IS to be a subrange for the traversal information given 986528b96dSMatthew G. Knepley 996528b96dSMatthew G. Knepley Not collective 1006528b96dSMatthew G. Knepley 1016528b96dSMatthew G. Knepley Input Parameters: 1026528b96dSMatthew G. Knepley + subpointIS - The IS object to be configured 1036528b96dSMatthew G. Knepley . pStar t - The first index of the subrange 1046528b96dSMatthew G. Knepley . pEnd - One past the last index for the subrange 1056528b96dSMatthew G. Knepley - points - The indices for the entire range, from ISGetPointRange() 1066528b96dSMatthew G. Knepley 1076528b96dSMatthew G. Knepley Output Parameters: 1086528b96dSMatthew G. Knepley . subpointIS - The IS object now configured to be a subrange 1096528b96dSMatthew G. Knepley 1106528b96dSMatthew G. Knepley Notes: 1116528b96dSMatthew G. Knepley The input IS will now respond properly to calls to ISGetPointRange() and return the subrange. 1126528b96dSMatthew G. Knepley 1136528b96dSMatthew G. Knepley Level: intermediate 1146528b96dSMatthew G. Knepley 1156528b96dSMatthew G. Knepley .seealso: ISGetPointRange(), ISRestorePointRange(), ISGetIndices(), ISCreateStride() 1166528b96dSMatthew G. Knepley @*/ 1179305a4c7SMatthew G. Knepley PetscErrorCode ISGetPointSubrange(IS subpointIS, PetscInt pStart, PetscInt pEnd, const PetscInt *points) 1189305a4c7SMatthew G. Knepley { 1199305a4c7SMatthew G. Knepley PetscErrorCode ierr; 1209305a4c7SMatthew G. Knepley 1219305a4c7SMatthew G. Knepley PetscFunctionBeginHot; 1229305a4c7SMatthew G. Knepley if (points) { 1239305a4c7SMatthew G. Knepley ierr = ISSetType(subpointIS, ISGENERAL);CHKERRQ(ierr); 1249305a4c7SMatthew G. Knepley ierr = ISGeneralSetIndices(subpointIS, pEnd-pStart, &points[pStart], PETSC_USE_POINTER);CHKERRQ(ierr); 1259305a4c7SMatthew G. Knepley } else { 1269305a4c7SMatthew G. Knepley ierr = ISSetType(subpointIS, ISSTRIDE);CHKERRQ(ierr); 1279305a4c7SMatthew G. Knepley ierr = ISStrideSetStride(subpointIS, pEnd-pStart, pStart, 1);CHKERRQ(ierr); 1289305a4c7SMatthew G. Knepley } 1299305a4c7SMatthew G. Knepley PetscFunctionReturn(0); 1309305a4c7SMatthew G. Knepley } 1319305a4c7SMatthew G. Knepley 132413f72f0SBarry Smith /* -----------------------------------------------------------------------------------------*/ 133413f72f0SBarry Smith 134413f72f0SBarry Smith /* 135413f72f0SBarry Smith Creates the global mapping information in the ISLocalToGlobalMapping structure 136413f72f0SBarry Smith 137413f72f0SBarry Smith If the user has not selected how to handle the global to local mapping then use HASH for "large" problems 138413f72f0SBarry Smith */ 139413f72f0SBarry Smith static PetscErrorCode ISGlobalToLocalMappingSetUp(ISLocalToGlobalMapping mapping) 140413f72f0SBarry Smith { 141413f72f0SBarry Smith PetscInt i,*idx = mapping->indices,n = mapping->n,end,start; 142413f72f0SBarry Smith PetscErrorCode ierr; 143413f72f0SBarry Smith 144413f72f0SBarry Smith PetscFunctionBegin; 145413f72f0SBarry Smith if (mapping->data) PetscFunctionReturn(0); 146413f72f0SBarry Smith end = 0; 147413f72f0SBarry Smith start = PETSC_MAX_INT; 148413f72f0SBarry Smith 149413f72f0SBarry Smith for (i=0; i<n; i++) { 150413f72f0SBarry Smith if (idx[i] < 0) continue; 151413f72f0SBarry Smith if (idx[i] < start) start = idx[i]; 152413f72f0SBarry Smith if (idx[i] > end) end = idx[i]; 153413f72f0SBarry Smith } 154413f72f0SBarry Smith if (start > end) {start = 0; end = -1;} 155413f72f0SBarry Smith mapping->globalstart = start; 156413f72f0SBarry Smith mapping->globalend = end; 157413f72f0SBarry Smith if (!((PetscObject)mapping)->type_name) { 158413f72f0SBarry Smith if ((end - start) > PetscMax(4*n,1000000)) { 1597f79407eSBarry Smith ierr = ISLocalToGlobalMappingSetType(mapping,ISLOCALTOGLOBALMAPPINGHASH);CHKERRQ(ierr); 160413f72f0SBarry Smith } else { 1617f79407eSBarry Smith ierr = ISLocalToGlobalMappingSetType(mapping,ISLOCALTOGLOBALMAPPINGBASIC);CHKERRQ(ierr); 162413f72f0SBarry Smith } 163413f72f0SBarry Smith } 164413f72f0SBarry Smith ierr = (*mapping->ops->globaltolocalmappingsetup)(mapping);CHKERRQ(ierr); 165413f72f0SBarry Smith PetscFunctionReturn(0); 166413f72f0SBarry Smith } 167413f72f0SBarry Smith 168413f72f0SBarry Smith static PetscErrorCode ISGlobalToLocalMappingSetUp_Basic(ISLocalToGlobalMapping mapping) 169413f72f0SBarry Smith { 170413f72f0SBarry Smith PetscErrorCode ierr; 171413f72f0SBarry Smith PetscInt i,*idx = mapping->indices,n = mapping->n,end,start,*globals; 172413f72f0SBarry Smith ISLocalToGlobalMapping_Basic *map; 173413f72f0SBarry Smith 174413f72f0SBarry Smith PetscFunctionBegin; 175413f72f0SBarry Smith start = mapping->globalstart; 176413f72f0SBarry Smith end = mapping->globalend; 177413f72f0SBarry Smith ierr = PetscNew(&map);CHKERRQ(ierr); 178413f72f0SBarry Smith ierr = PetscMalloc1(end-start+2,&globals);CHKERRQ(ierr); 179413f72f0SBarry Smith map->globals = globals; 180413f72f0SBarry Smith for (i=0; i<end-start+1; i++) globals[i] = -1; 181413f72f0SBarry Smith for (i=0; i<n; i++) { 182413f72f0SBarry Smith if (idx[i] < 0) continue; 183413f72f0SBarry Smith globals[idx[i] - start] = i; 184413f72f0SBarry Smith } 185413f72f0SBarry Smith mapping->data = (void*)map; 186413f72f0SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mapping,(end-start+1)*sizeof(PetscInt));CHKERRQ(ierr); 187413f72f0SBarry Smith PetscFunctionReturn(0); 188413f72f0SBarry Smith } 189413f72f0SBarry Smith 190413f72f0SBarry Smith static PetscErrorCode ISGlobalToLocalMappingSetUp_Hash(ISLocalToGlobalMapping mapping) 191413f72f0SBarry Smith { 192413f72f0SBarry Smith PetscErrorCode ierr; 193413f72f0SBarry Smith PetscInt i,*idx = mapping->indices,n = mapping->n; 194413f72f0SBarry Smith ISLocalToGlobalMapping_Hash *map; 195413f72f0SBarry Smith 196413f72f0SBarry Smith PetscFunctionBegin; 197413f72f0SBarry Smith ierr = PetscNew(&map);CHKERRQ(ierr); 198e8f14785SLisandro Dalcin ierr = PetscHMapICreate(&map->globalht);CHKERRQ(ierr); 199413f72f0SBarry Smith for (i=0; i<n; i++) { 200413f72f0SBarry Smith if (idx[i] < 0) continue; 201e8f14785SLisandro Dalcin ierr = PetscHMapISet(map->globalht,idx[i],i);CHKERRQ(ierr); 202413f72f0SBarry Smith } 203413f72f0SBarry Smith mapping->data = (void*)map; 204413f72f0SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mapping,2*n*sizeof(PetscInt));CHKERRQ(ierr); 205413f72f0SBarry Smith PetscFunctionReturn(0); 206413f72f0SBarry Smith } 207413f72f0SBarry Smith 208413f72f0SBarry Smith static PetscErrorCode ISLocalToGlobalMappingDestroy_Basic(ISLocalToGlobalMapping mapping) 209413f72f0SBarry Smith { 210413f72f0SBarry Smith PetscErrorCode ierr; 211413f72f0SBarry Smith ISLocalToGlobalMapping_Basic *map = (ISLocalToGlobalMapping_Basic *)mapping->data; 212413f72f0SBarry Smith 213413f72f0SBarry Smith PetscFunctionBegin; 214413f72f0SBarry Smith if (!map) PetscFunctionReturn(0); 215413f72f0SBarry Smith ierr = PetscFree(map->globals);CHKERRQ(ierr); 216413f72f0SBarry Smith ierr = PetscFree(mapping->data);CHKERRQ(ierr); 217413f72f0SBarry Smith PetscFunctionReturn(0); 218413f72f0SBarry Smith } 219413f72f0SBarry Smith 220413f72f0SBarry Smith static PetscErrorCode ISLocalToGlobalMappingDestroy_Hash(ISLocalToGlobalMapping mapping) 221413f72f0SBarry Smith { 222413f72f0SBarry Smith PetscErrorCode ierr; 223413f72f0SBarry Smith ISLocalToGlobalMapping_Hash *map = (ISLocalToGlobalMapping_Hash*)mapping->data; 224413f72f0SBarry Smith 225413f72f0SBarry Smith PetscFunctionBegin; 226413f72f0SBarry Smith if (!map) PetscFunctionReturn(0); 227e8f14785SLisandro Dalcin ierr = PetscHMapIDestroy(&map->globalht);CHKERRQ(ierr); 228413f72f0SBarry Smith ierr = PetscFree(mapping->data);CHKERRQ(ierr); 229413f72f0SBarry Smith PetscFunctionReturn(0); 230413f72f0SBarry Smith } 231413f72f0SBarry Smith 232413f72f0SBarry Smith #define GTOLTYPE _Basic 233413f72f0SBarry Smith #define GTOLNAME _Basic 234541bf97eSAdrian Croucher #define GTOLBS mapping->bs 235413f72f0SBarry Smith #define GTOL(g, local) do { \ 236413f72f0SBarry Smith local = map->globals[g/bs - start]; \ 2370040bde1SJunchao Zhang if (local >= 0) local = bs*local + (g % bs); \ 238413f72f0SBarry Smith } while (0) 239541bf97eSAdrian Croucher 240413f72f0SBarry Smith #include <../src/vec/is/utils/isltog.h> 241413f72f0SBarry Smith 242413f72f0SBarry Smith #define GTOLTYPE _Basic 243413f72f0SBarry Smith #define GTOLNAME Block_Basic 244541bf97eSAdrian Croucher #define GTOLBS 1 245413f72f0SBarry Smith #define GTOL(g, local) do { \ 246413f72f0SBarry Smith local = map->globals[g - start]; \ 247413f72f0SBarry Smith } while (0) 248413f72f0SBarry Smith #include <../src/vec/is/utils/isltog.h> 249413f72f0SBarry Smith 250413f72f0SBarry Smith #define GTOLTYPE _Hash 251413f72f0SBarry Smith #define GTOLNAME _Hash 252541bf97eSAdrian Croucher #define GTOLBS mapping->bs 253413f72f0SBarry Smith #define GTOL(g, local) do { \ 254e8f14785SLisandro Dalcin (void)PetscHMapIGet(map->globalht,g/bs,&local); \ 2550040bde1SJunchao Zhang if (local >= 0) local = bs*local + (g % bs); \ 256413f72f0SBarry Smith } while (0) 257413f72f0SBarry Smith #include <../src/vec/is/utils/isltog.h> 258413f72f0SBarry Smith 259413f72f0SBarry Smith #define GTOLTYPE _Hash 260413f72f0SBarry Smith #define GTOLNAME Block_Hash 261541bf97eSAdrian Croucher #define GTOLBS 1 262413f72f0SBarry Smith #define GTOL(g, local) do { \ 263e8f14785SLisandro Dalcin (void)PetscHMapIGet(map->globalht,g,&local); \ 264413f72f0SBarry Smith } while (0) 265413f72f0SBarry Smith #include <../src/vec/is/utils/isltog.h> 266413f72f0SBarry Smith 2676658fb44Sstefano_zampini /*@ 2686658fb44Sstefano_zampini ISLocalToGlobalMappingDuplicate - Duplicates the local to global mapping object 2696658fb44Sstefano_zampini 2706658fb44Sstefano_zampini Not Collective 2716658fb44Sstefano_zampini 2726658fb44Sstefano_zampini Input Parameter: 2736658fb44Sstefano_zampini . ltog - local to global mapping 2746658fb44Sstefano_zampini 2756658fb44Sstefano_zampini Output Parameter: 2766658fb44Sstefano_zampini . nltog - the duplicated local to global mapping 2776658fb44Sstefano_zampini 2786658fb44Sstefano_zampini Level: advanced 2796658fb44Sstefano_zampini 2806658fb44Sstefano_zampini .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 2816658fb44Sstefano_zampini @*/ 2826658fb44Sstefano_zampini PetscErrorCode ISLocalToGlobalMappingDuplicate(ISLocalToGlobalMapping ltog,ISLocalToGlobalMapping* nltog) 2836658fb44Sstefano_zampini { 2846658fb44Sstefano_zampini PetscErrorCode ierr; 2856658fb44Sstefano_zampini 2866658fb44Sstefano_zampini PetscFunctionBegin; 2876658fb44Sstefano_zampini PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 2886658fb44Sstefano_zampini ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)ltog),ltog->bs,ltog->n,ltog->indices,PETSC_COPY_VALUES,nltog);CHKERRQ(ierr); 2896658fb44Sstefano_zampini PetscFunctionReturn(0); 2906658fb44Sstefano_zampini } 2916658fb44Sstefano_zampini 292565245c5SBarry Smith /*@ 293107e9a97SBarry Smith ISLocalToGlobalMappingGetSize - Gets the local size of a local to global mapping 2943b9aefa3SBarry Smith 2953b9aefa3SBarry Smith Not Collective 2963b9aefa3SBarry Smith 2973b9aefa3SBarry Smith Input Parameter: 2983b9aefa3SBarry Smith . ltog - local to global mapping 2993b9aefa3SBarry Smith 3003b9aefa3SBarry Smith Output Parameter: 301107e9a97SBarry Smith . n - the number of entries in the local mapping, ISLocalToGlobalMappingGetIndices() returns an array of this length 3023b9aefa3SBarry Smith 3033b9aefa3SBarry Smith Level: advanced 3043b9aefa3SBarry Smith 3053b9aefa3SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 3063b9aefa3SBarry Smith @*/ 3077087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingGetSize(ISLocalToGlobalMapping mapping,PetscInt *n) 3083b9aefa3SBarry Smith { 3093b9aefa3SBarry Smith PetscFunctionBegin; 3100700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 3114482741eSBarry Smith PetscValidIntPointer(n,2); 312107e9a97SBarry Smith *n = mapping->bs*mapping->n; 3133b9aefa3SBarry Smith PetscFunctionReturn(0); 3143b9aefa3SBarry Smith } 3153b9aefa3SBarry Smith 3165a5d4f66SBarry Smith /*@C 317fe2efc57SMark ISLocalToGlobalMappingViewFromOptions - View from Options 318fe2efc57SMark 319fe2efc57SMark Collective on ISLocalToGlobalMapping 320fe2efc57SMark 321fe2efc57SMark Input Parameters: 322fe2efc57SMark + A - the local to global mapping object 323736c3998SJose E. Roman . obj - Optional object 324736c3998SJose E. Roman - name - command line option 325fe2efc57SMark 326fe2efc57SMark Level: intermediate 327fe2efc57SMark .seealso: ISLocalToGlobalMapping, ISLocalToGlobalMappingView, PetscObjectViewFromOptions(), ISLocalToGlobalMappingCreate() 328fe2efc57SMark @*/ 329fe2efc57SMark PetscErrorCode ISLocalToGlobalMappingViewFromOptions(ISLocalToGlobalMapping A,PetscObject obj,const char name[]) 330fe2efc57SMark { 331fe2efc57SMark PetscErrorCode ierr; 332fe2efc57SMark 333fe2efc57SMark PetscFunctionBegin; 334fe2efc57SMark PetscValidHeaderSpecific(A,IS_LTOGM_CLASSID,1); 335fe2efc57SMark ierr = PetscObjectViewFromOptions((PetscObject)A,obj,name);CHKERRQ(ierr); 336fe2efc57SMark PetscFunctionReturn(0); 337fe2efc57SMark } 338fe2efc57SMark 339fe2efc57SMark /*@C 3405a5d4f66SBarry Smith ISLocalToGlobalMappingView - View a local to global mapping 3415a5d4f66SBarry Smith 342b9cd556bSLois Curfman McInnes Not Collective 343b9cd556bSLois Curfman McInnes 3445a5d4f66SBarry Smith Input Parameters: 3453b9aefa3SBarry Smith + ltog - local to global mapping 3463b9aefa3SBarry Smith - viewer - viewer 3475a5d4f66SBarry Smith 348a997ad1aSLois Curfman McInnes Level: advanced 349a997ad1aSLois Curfman McInnes 3505a5d4f66SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 3515a5d4f66SBarry Smith @*/ 3527087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingView(ISLocalToGlobalMapping mapping,PetscViewer viewer) 3535a5d4f66SBarry Smith { 35432dcc486SBarry Smith PetscInt i; 35532dcc486SBarry Smith PetscMPIInt rank; 356ace3abfcSBarry Smith PetscBool iascii; 3576849ba73SBarry Smith PetscErrorCode ierr; 3585a5d4f66SBarry Smith 3595a5d4f66SBarry Smith PetscFunctionBegin; 3600700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 3613050cee2SBarry Smith if (!viewer) { 362ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mapping),&viewer);CHKERRQ(ierr); 3633050cee2SBarry Smith } 3640700a824SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 3655a5d4f66SBarry Smith 366ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mapping),&rank);CHKERRMPI(ierr); 367251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 36832077d6dSBarry Smith if (iascii) { 36998c3331eSBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mapping,viewer);CHKERRQ(ierr); 3701575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 3715a5d4f66SBarry Smith for (i=0; i<mapping->n; i++) { 3727904a332SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] %D %D\n",rank,i,mapping->indices[i]);CHKERRQ(ierr); 3736831982aSBarry Smith } 374b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 3751575c14dSBarry Smith ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 3761575c14dSBarry Smith } 3775a5d4f66SBarry Smith PetscFunctionReturn(0); 3785a5d4f66SBarry Smith } 3795a5d4f66SBarry Smith 3801f428162SBarry Smith /*@ 3812bdab257SBarry Smith ISLocalToGlobalMappingCreateIS - Creates a mapping between a local (0 to n) 3822bdab257SBarry Smith ordering and a global parallel ordering. 3832bdab257SBarry Smith 3840f5bd95cSBarry Smith Not collective 385b9cd556bSLois Curfman McInnes 386a997ad1aSLois Curfman McInnes Input Parameter: 3878c03b21aSDmitry Karpeev . is - index set containing the global numbers for each local number 3882bdab257SBarry Smith 389a997ad1aSLois Curfman McInnes Output Parameter: 3902bdab257SBarry Smith . mapping - new mapping data structure 3912bdab257SBarry Smith 39295452b02SPatrick Sanan Notes: 39395452b02SPatrick Sanan the block size of the IS determines the block size of the mapping 394a997ad1aSLois Curfman McInnes Level: advanced 395a997ad1aSLois Curfman McInnes 3967e99dc12SLawrence Mitchell .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingSetFromOptions() 3972bdab257SBarry Smith @*/ 3987087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingCreateIS(IS is,ISLocalToGlobalMapping *mapping) 3992bdab257SBarry Smith { 4006849ba73SBarry Smith PetscErrorCode ierr; 4013bbf0e92SBarry Smith PetscInt n,bs; 4025d0c19d7SBarry Smith const PetscInt *indices; 4032bdab257SBarry Smith MPI_Comm comm; 4043bbf0e92SBarry Smith PetscBool isblock; 4053a40ed3dSBarry Smith 4063a40ed3dSBarry Smith PetscFunctionBegin; 4070700a824SBarry Smith PetscValidHeaderSpecific(is,IS_CLASSID,1); 4084482741eSBarry Smith PetscValidPointer(mapping,2); 4092bdab257SBarry Smith 4102bdab257SBarry Smith ierr = PetscObjectGetComm((PetscObject)is,&comm);CHKERRQ(ierr); 4113b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 4123bbf0e92SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)is,ISBLOCK,&isblock);CHKERRQ(ierr); 4136006e8d2SBarry Smith if (!isblock) { 414f0413b6fSBarry Smith ierr = ISGetIndices(is,&indices);CHKERRQ(ierr); 415f0413b6fSBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,1,n,indices,PETSC_COPY_VALUES,mapping);CHKERRQ(ierr); 4162bdab257SBarry Smith ierr = ISRestoreIndices(is,&indices);CHKERRQ(ierr); 4176006e8d2SBarry Smith } else { 4186006e8d2SBarry Smith ierr = ISGetBlockSize(is,&bs);CHKERRQ(ierr); 419f0413b6fSBarry Smith ierr = ISBlockGetIndices(is,&indices);CHKERRQ(ierr); 42028bc9809SBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,bs,n/bs,indices,PETSC_COPY_VALUES,mapping);CHKERRQ(ierr); 421f0413b6fSBarry Smith ierr = ISBlockRestoreIndices(is,&indices);CHKERRQ(ierr); 4226006e8d2SBarry Smith } 4233a40ed3dSBarry Smith PetscFunctionReturn(0); 4242bdab257SBarry Smith } 4255a5d4f66SBarry Smith 426a4d96a55SJed Brown /*@C 427a4d96a55SJed Brown ISLocalToGlobalMappingCreateSF - Creates a mapping between a local (0 to n) 428a4d96a55SJed Brown ordering and a global parallel ordering. 429a4d96a55SJed Brown 430a4d96a55SJed Brown Collective 431a4d96a55SJed Brown 432d8d19677SJose E. Roman Input Parameters: 433a4d96a55SJed Brown + sf - star forest mapping contiguous local indices to (rank, offset) 4349a535bafSVaclav Hapla - start - first global index on this process, or PETSC_DECIDE to compute contiguous global numbering automatically 435a4d96a55SJed Brown 436a4d96a55SJed Brown Output Parameter: 437a4d96a55SJed Brown . mapping - new mapping data structure 438a4d96a55SJed Brown 439a4d96a55SJed Brown Level: advanced 440a4d96a55SJed Brown 4419a535bafSVaclav Hapla Notes: 4429a535bafSVaclav Hapla If any processor calls this with start = PETSC_DECIDE then all processors must, otherwise the program will hang. 4439a535bafSVaclav Hapla 4447e99dc12SLawrence Mitchell .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingSetFromOptions() 445a4d96a55SJed Brown @*/ 446a4d96a55SJed Brown PetscErrorCode ISLocalToGlobalMappingCreateSF(PetscSF sf,PetscInt start,ISLocalToGlobalMapping *mapping) 447a4d96a55SJed Brown { 448a4d96a55SJed Brown PetscErrorCode ierr; 449a4d96a55SJed Brown PetscInt i,maxlocal,nroots,nleaves,*globals,*ltog; 450a4d96a55SJed Brown const PetscInt *ilocal; 451a4d96a55SJed Brown MPI_Comm comm; 452a4d96a55SJed Brown 453a4d96a55SJed Brown PetscFunctionBegin; 454a4d96a55SJed Brown PetscValidHeaderSpecific(sf,PETSCSF_CLASSID,1); 455a4d96a55SJed Brown PetscValidPointer(mapping,3); 456a4d96a55SJed Brown 457a4d96a55SJed Brown ierr = PetscObjectGetComm((PetscObject)sf,&comm);CHKERRQ(ierr); 4580298fd71SBarry Smith ierr = PetscSFGetGraph(sf,&nroots,&nleaves,&ilocal,NULL);CHKERRQ(ierr); 4599a535bafSVaclav Hapla if (start == PETSC_DECIDE) { 4609a535bafSVaclav Hapla start = 0; 4619a535bafSVaclav Hapla ierr = MPI_Exscan(&nroots,&start,1,MPIU_INT,MPI_SUM,comm);CHKERRMPI(ierr); 4629a535bafSVaclav Hapla } else if (start < 0) SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "start must be nonnegative or PETSC_DECIDE"); 463f6e5521dSKarl Rupp if (ilocal) { 464f6e5521dSKarl Rupp for (i=0,maxlocal=0; i<nleaves; i++) maxlocal = PetscMax(maxlocal,ilocal[i]+1); 465f6e5521dSKarl Rupp } 466a4d96a55SJed Brown else maxlocal = nleaves; 467785e854fSJed Brown ierr = PetscMalloc1(nroots,&globals);CHKERRQ(ierr); 468785e854fSJed Brown ierr = PetscMalloc1(maxlocal,<og);CHKERRQ(ierr); 469a4d96a55SJed Brown for (i=0; i<nroots; i++) globals[i] = start + i; 470a4d96a55SJed Brown for (i=0; i<maxlocal; i++) ltog[i] = -1; 471ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(sf,MPIU_INT,globals,ltog,MPI_REPLACE);CHKERRQ(ierr); 472ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(sf,MPIU_INT,globals,ltog,MPI_REPLACE);CHKERRQ(ierr); 473f0413b6fSBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,1,maxlocal,ltog,PETSC_OWN_POINTER,mapping);CHKERRQ(ierr); 474a4d96a55SJed Brown ierr = PetscFree(globals);CHKERRQ(ierr); 475a4d96a55SJed Brown PetscFunctionReturn(0); 476a4d96a55SJed Brown } 477b46b645bSBarry Smith 47863fa5c83Sstefano_zampini /*@ 47963fa5c83Sstefano_zampini ISLocalToGlobalMappingSetBlockSize - Sets the blocksize of the mapping 48063fa5c83Sstefano_zampini 48163fa5c83Sstefano_zampini Not collective 48263fa5c83Sstefano_zampini 48363fa5c83Sstefano_zampini Input Parameters: 484a2b725a8SWilliam Gropp + mapping - mapping data structure 485a2b725a8SWilliam Gropp - bs - the blocksize 48663fa5c83Sstefano_zampini 48763fa5c83Sstefano_zampini Level: advanced 48863fa5c83Sstefano_zampini 48963fa5c83Sstefano_zampini .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 49063fa5c83Sstefano_zampini @*/ 49163fa5c83Sstefano_zampini PetscErrorCode ISLocalToGlobalMappingSetBlockSize(ISLocalToGlobalMapping mapping,PetscInt bs) 49263fa5c83Sstefano_zampini { 493a59f3c4dSstefano_zampini PetscInt *nid; 494a59f3c4dSstefano_zampini const PetscInt *oid; 495a59f3c4dSstefano_zampini PetscInt i,cn,on,obs,nn; 49663fa5c83Sstefano_zampini PetscErrorCode ierr; 49763fa5c83Sstefano_zampini 49863fa5c83Sstefano_zampini PetscFunctionBegin; 49963fa5c83Sstefano_zampini PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 50063fa5c83Sstefano_zampini if (bs < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid block size %D",bs); 50163fa5c83Sstefano_zampini if (bs == mapping->bs) PetscFunctionReturn(0); 50263fa5c83Sstefano_zampini on = mapping->n; 50363fa5c83Sstefano_zampini obs = mapping->bs; 50463fa5c83Sstefano_zampini oid = mapping->indices; 50563fa5c83Sstefano_zampini nn = (on*obs)/bs; 50663fa5c83Sstefano_zampini if ((on*obs)%bs) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Block size %D is inconsistent with block size %D and number of block indices %D",bs,obs,on); 507a59f3c4dSstefano_zampini 50863fa5c83Sstefano_zampini ierr = PetscMalloc1(nn,&nid);CHKERRQ(ierr); 509a59f3c4dSstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(mapping,&oid);CHKERRQ(ierr); 510a59f3c4dSstefano_zampini for (i=0;i<nn;i++) { 511a59f3c4dSstefano_zampini PetscInt j; 512a59f3c4dSstefano_zampini for (j=0,cn=0;j<bs-1;j++) { 513a59f3c4dSstefano_zampini if (oid[i*bs+j] < 0) { cn++; continue; } 514a59f3c4dSstefano_zampini if (oid[i*bs+j] != oid[i*bs+j+1]-1) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Block sizes %D and %D are incompatible with the block indices: non consecutive indices %D %D",bs,obs,oid[i*bs+j],oid[i*bs+j+1]); 515a59f3c4dSstefano_zampini } 516a59f3c4dSstefano_zampini if (oid[i*bs+j] < 0) cn++; 5178b7cb0e6Sstefano_zampini if (cn) { 518a59f3c4dSstefano_zampini if (cn != bs) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Block sizes %D and %D are incompatible with the block indices: invalid number of negative entries in block %D",bs,obs,cn); 519a59f3c4dSstefano_zampini nid[i] = -1; 5208b7cb0e6Sstefano_zampini } else { 521a59f3c4dSstefano_zampini nid[i] = oid[i*bs]/bs; 52263fa5c83Sstefano_zampini } 52363fa5c83Sstefano_zampini } 524a59f3c4dSstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(mapping,&oid);CHKERRQ(ierr); 525a59f3c4dSstefano_zampini 52663fa5c83Sstefano_zampini mapping->n = nn; 52763fa5c83Sstefano_zampini mapping->bs = bs; 52863fa5c83Sstefano_zampini ierr = PetscFree(mapping->indices);CHKERRQ(ierr); 52963fa5c83Sstefano_zampini mapping->indices = nid; 530c9345713Sstefano_zampini mapping->globalstart = 0; 531c9345713Sstefano_zampini mapping->globalend = 0; 5321bd0b88eSStefano Zampini 5331bd0b88eSStefano Zampini /* reset the cached information */ 5341bd0b88eSStefano Zampini ierr = PetscFree(mapping->info_procs);CHKERRQ(ierr); 5351bd0b88eSStefano Zampini ierr = PetscFree(mapping->info_numprocs);CHKERRQ(ierr); 5361bd0b88eSStefano Zampini if (mapping->info_indices) { 5371bd0b88eSStefano Zampini PetscInt i; 5381bd0b88eSStefano Zampini 5391bd0b88eSStefano Zampini ierr = PetscFree((mapping->info_indices)[0]);CHKERRQ(ierr); 5401bd0b88eSStefano Zampini for (i=1; i<mapping->info_nproc; i++) { 5411bd0b88eSStefano Zampini ierr = PetscFree(mapping->info_indices[i]);CHKERRQ(ierr); 5421bd0b88eSStefano Zampini } 5431bd0b88eSStefano Zampini ierr = PetscFree(mapping->info_indices);CHKERRQ(ierr); 5441bd0b88eSStefano Zampini } 5451bd0b88eSStefano Zampini mapping->info_cached = PETSC_FALSE; 5461bd0b88eSStefano Zampini 547413f72f0SBarry Smith if (mapping->ops->destroy) { 548413f72f0SBarry Smith ierr = (*mapping->ops->destroy)(mapping);CHKERRQ(ierr); 549413f72f0SBarry Smith } 55063fa5c83Sstefano_zampini PetscFunctionReturn(0); 55163fa5c83Sstefano_zampini } 55263fa5c83Sstefano_zampini 55345b6f7e9SBarry Smith /*@ 55445b6f7e9SBarry Smith ISLocalToGlobalMappingGetBlockSize - Gets the blocksize of the mapping 55545b6f7e9SBarry Smith ordering and a global parallel ordering. 55645b6f7e9SBarry Smith 55745b6f7e9SBarry Smith Not Collective 55845b6f7e9SBarry Smith 55945b6f7e9SBarry Smith Input Parameters: 56045b6f7e9SBarry Smith . mapping - mapping data structure 56145b6f7e9SBarry Smith 56245b6f7e9SBarry Smith Output Parameter: 56345b6f7e9SBarry Smith . bs - the blocksize 56445b6f7e9SBarry Smith 56545b6f7e9SBarry Smith Level: advanced 56645b6f7e9SBarry Smith 56745b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 56845b6f7e9SBarry Smith @*/ 56945b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetBlockSize(ISLocalToGlobalMapping mapping,PetscInt *bs) 57045b6f7e9SBarry Smith { 57145b6f7e9SBarry Smith PetscFunctionBegin; 572cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 57345b6f7e9SBarry Smith *bs = mapping->bs; 57445b6f7e9SBarry Smith PetscFunctionReturn(0); 57545b6f7e9SBarry Smith } 57645b6f7e9SBarry Smith 577ba5bb76aSSatish Balay /*@ 57890f02eecSBarry Smith ISLocalToGlobalMappingCreate - Creates a mapping between a local (0 to n) 57990f02eecSBarry Smith ordering and a global parallel ordering. 5802362add9SBarry Smith 58189d82c54SBarry Smith Not Collective, but communicator may have more than one process 582b9cd556bSLois Curfman McInnes 5832362add9SBarry Smith Input Parameters: 58489d82c54SBarry Smith + comm - MPI communicator 585f0413b6fSBarry Smith . bs - the block size 58628bc9809SBarry Smith . n - the number of local elements divided by the block size, or equivalently the number of block indices 58728bc9809SBarry 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 588d5ad8652SBarry Smith - mode - see PetscCopyMode 5892362add9SBarry Smith 590a997ad1aSLois Curfman McInnes Output Parameter: 59190f02eecSBarry Smith . mapping - new mapping data structure 5922362add9SBarry Smith 59395452b02SPatrick Sanan Notes: 59495452b02SPatrick Sanan There is one integer value in indices per block and it represents the actual indices bs*idx + j, where j=0,..,bs-1 595413f72f0SBarry Smith 5969a7b7924SJed Brown For "small" problems when using ISGlobalToLocalMappingApply() and ISGlobalToLocalMappingApplyBlock(), the ISLocalToGlobalMappingType of ISLOCALTOGLOBALMAPPINGBASIC will be used; 597413f72f0SBarry Smith this uses more memory but is faster; this approach is not scalable for extremely large mappings. For large problems ISLOCALTOGLOBALMAPPINGHASH is used, this is scalable. 598413f72f0SBarry Smith Use ISLocalToGlobalMappingSetType() or call ISLocalToGlobalMappingSetFromOptions() with the option -islocaltoglobalmapping_type <basic,hash> to control which is used. 599413f72f0SBarry Smith 600a997ad1aSLois Curfman McInnes Level: advanced 601a997ad1aSLois Curfman McInnes 602413f72f0SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingSetFromOptions(), ISLOCALTOGLOBALMAPPINGBASIC, ISLOCALTOGLOBALMAPPINGHASH 603413f72f0SBarry Smith ISLocalToGlobalMappingSetType(), ISLocalToGlobalMappingType 6042362add9SBarry Smith @*/ 60560c7cefcSBarry Smith PetscErrorCode ISLocalToGlobalMappingCreate(MPI_Comm comm,PetscInt bs,PetscInt n,const PetscInt indices[],PetscCopyMode mode,ISLocalToGlobalMapping *mapping) 6062362add9SBarry Smith { 6076849ba73SBarry Smith PetscErrorCode ierr; 60832dcc486SBarry Smith PetscInt *in; 609b46b645bSBarry Smith 610b46b645bSBarry Smith PetscFunctionBegin; 611064a246eSJacob Faibussowitsch if (n) PetscValidIntPointer(indices,4); 612064a246eSJacob Faibussowitsch PetscValidPointer(mapping,6); 613b46b645bSBarry Smith 6140298fd71SBarry Smith *mapping = NULL; 615607a6623SBarry Smith ierr = ISInitializePackage();CHKERRQ(ierr); 6162362add9SBarry Smith 617*e8a52743SVaclav Hapla ierr = PetscHeaderCreate(*mapping,IS_LTOGM_CLASSID,"ISLocalToGlobalMapping","Local to global mapping","IS",comm,ISLocalToGlobalMappingDestroy,ISLocalToGlobalMappingView);CHKERRQ(ierr); 618d4bb536fSBarry Smith (*mapping)->n = n; 619f0413b6fSBarry Smith (*mapping)->bs = bs; 620d5ad8652SBarry Smith if (mode == PETSC_COPY_VALUES) { 621785e854fSJed Brown ierr = PetscMalloc1(n,&in);CHKERRQ(ierr); 622580bdb30SBarry Smith ierr = PetscArraycpy(in,indices,n);CHKERRQ(ierr); 623d5ad8652SBarry Smith (*mapping)->indices = in; 6246389a1a1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)*mapping,n*sizeof(PetscInt));CHKERRQ(ierr); 6256389a1a1SBarry Smith } else if (mode == PETSC_OWN_POINTER) { 6266389a1a1SBarry Smith (*mapping)->indices = (PetscInt*)indices; 6276389a1a1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)*mapping,n*sizeof(PetscInt));CHKERRQ(ierr); 6286389a1a1SBarry Smith } 62960c7cefcSBarry Smith else SETERRQ(comm,PETSC_ERR_SUP,"Cannot currently use PETSC_USE_POINTER"); 6303a40ed3dSBarry Smith PetscFunctionReturn(0); 6312362add9SBarry Smith } 6322362add9SBarry Smith 633413f72f0SBarry Smith PetscFunctionList ISLocalToGlobalMappingList = NULL; 634413f72f0SBarry Smith 63590f02eecSBarry Smith /*@ 6367e99dc12SLawrence Mitchell ISLocalToGlobalMappingSetFromOptions - Set mapping options from the options database. 6377e99dc12SLawrence Mitchell 6387e99dc12SLawrence Mitchell Not collective 6397e99dc12SLawrence Mitchell 6407e99dc12SLawrence Mitchell Input Parameters: 6417e99dc12SLawrence Mitchell . mapping - mapping data structure 6427e99dc12SLawrence Mitchell 6437e99dc12SLawrence Mitchell Level: advanced 6447e99dc12SLawrence Mitchell 6457e99dc12SLawrence Mitchell @*/ 6467e99dc12SLawrence Mitchell PetscErrorCode ISLocalToGlobalMappingSetFromOptions(ISLocalToGlobalMapping mapping) 6477e99dc12SLawrence Mitchell { 6487e99dc12SLawrence Mitchell PetscErrorCode ierr; 649413f72f0SBarry Smith char type[256]; 650413f72f0SBarry Smith ISLocalToGlobalMappingType defaulttype = "Not set"; 6517e99dc12SLawrence Mitchell PetscBool flg; 6527e99dc12SLawrence Mitchell 6537e99dc12SLawrence Mitchell PetscFunctionBegin; 6547e99dc12SLawrence Mitchell PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 655413f72f0SBarry Smith ierr = ISLocalToGlobalMappingRegisterAll();CHKERRQ(ierr); 6567e99dc12SLawrence Mitchell ierr = PetscObjectOptionsBegin((PetscObject)mapping);CHKERRQ(ierr); 657413f72f0SBarry Smith ierr = PetscOptionsFList("-islocaltoglobalmapping_type","ISLocalToGlobalMapping method","ISLocalToGlobalMappingSetType",ISLocalToGlobalMappingList,(char*)(((PetscObject)mapping)->type_name) ? ((PetscObject)mapping)->type_name : defaulttype,type,256,&flg);CHKERRQ(ierr); 658413f72f0SBarry Smith if (flg) { 659413f72f0SBarry Smith ierr = ISLocalToGlobalMappingSetType(mapping,type);CHKERRQ(ierr); 660413f72f0SBarry Smith } 6617e99dc12SLawrence Mitchell ierr = PetscOptionsEnd();CHKERRQ(ierr); 6627e99dc12SLawrence Mitchell PetscFunctionReturn(0); 6637e99dc12SLawrence Mitchell } 6647e99dc12SLawrence Mitchell 6657e99dc12SLawrence Mitchell /*@ 66690f02eecSBarry Smith ISLocalToGlobalMappingDestroy - Destroys a mapping between a local (0 to n) 66790f02eecSBarry Smith ordering and a global parallel ordering. 66890f02eecSBarry Smith 6690f5bd95cSBarry Smith Note Collective 670b9cd556bSLois Curfman McInnes 67190f02eecSBarry Smith Input Parameters: 67290f02eecSBarry Smith . mapping - mapping data structure 67390f02eecSBarry Smith 674a997ad1aSLois Curfman McInnes Level: advanced 675a997ad1aSLois Curfman McInnes 6763acfe500SLois Curfman McInnes .seealso: ISLocalToGlobalMappingCreate() 67790f02eecSBarry Smith @*/ 6786bf464f9SBarry Smith PetscErrorCode ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping *mapping) 67990f02eecSBarry Smith { 680dfbe8321SBarry Smith PetscErrorCode ierr; 6815fd66863SKarl Rupp 6823a40ed3dSBarry Smith PetscFunctionBegin; 6836bf464f9SBarry Smith if (!*mapping) PetscFunctionReturn(0); 6846bf464f9SBarry Smith PetscValidHeaderSpecific((*mapping),IS_LTOGM_CLASSID,1); 6854c8fdceaSLisandro Dalcin if (--((PetscObject)(*mapping))->refct > 0) {*mapping = NULL;PetscFunctionReturn(0);} 6866bf464f9SBarry Smith ierr = PetscFree((*mapping)->indices);CHKERRQ(ierr); 687268a049cSStefano Zampini ierr = PetscFree((*mapping)->info_procs);CHKERRQ(ierr); 688268a049cSStefano Zampini ierr = PetscFree((*mapping)->info_numprocs);CHKERRQ(ierr); 689268a049cSStefano Zampini if ((*mapping)->info_indices) { 690268a049cSStefano Zampini PetscInt i; 691268a049cSStefano Zampini 692268a049cSStefano Zampini ierr = PetscFree(((*mapping)->info_indices)[0]);CHKERRQ(ierr); 693268a049cSStefano Zampini for (i=1; i<(*mapping)->info_nproc; i++) { 694268a049cSStefano Zampini ierr = PetscFree(((*mapping)->info_indices)[i]);CHKERRQ(ierr); 695268a049cSStefano Zampini } 696268a049cSStefano Zampini ierr = PetscFree((*mapping)->info_indices);CHKERRQ(ierr); 697268a049cSStefano Zampini } 6981bd0b88eSStefano Zampini if ((*mapping)->info_nodei) { 6991bd0b88eSStefano Zampini ierr = PetscFree(((*mapping)->info_nodei)[0]);CHKERRQ(ierr); 7001bd0b88eSStefano Zampini } 701071fcb05SBarry Smith ierr = PetscFree2((*mapping)->info_nodec,(*mapping)->info_nodei);CHKERRQ(ierr); 702413f72f0SBarry Smith if ((*mapping)->ops->destroy) { 703413f72f0SBarry Smith ierr = (*(*mapping)->ops->destroy)(*mapping);CHKERRQ(ierr); 704413f72f0SBarry Smith } 705d38fa0fbSBarry Smith ierr = PetscHeaderDestroy(mapping);CHKERRQ(ierr); 7064c8fdceaSLisandro Dalcin *mapping = NULL; 7073a40ed3dSBarry Smith PetscFunctionReturn(0); 70890f02eecSBarry Smith } 70990f02eecSBarry Smith 71090f02eecSBarry Smith /*@ 7113acfe500SLois Curfman McInnes ISLocalToGlobalMappingApplyIS - Creates from an IS in the local numbering 7123acfe500SLois Curfman McInnes a new index set using the global numbering defined in an ISLocalToGlobalMapping 7133acfe500SLois Curfman McInnes context. 71490f02eecSBarry Smith 7154cb36875SStefano Zampini Collective on is 716b9cd556bSLois Curfman McInnes 71790f02eecSBarry Smith Input Parameters: 718b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 719b9cd556bSLois Curfman McInnes - is - index set in local numbering 72090f02eecSBarry Smith 72190f02eecSBarry Smith Output Parameters: 72290f02eecSBarry Smith . newis - index set in global numbering 72390f02eecSBarry Smith 7244cb36875SStefano Zampini Notes: 7254cb36875SStefano Zampini The output IS will have the same communicator of the input IS. 7264cb36875SStefano Zampini 727a997ad1aSLois Curfman McInnes Level: advanced 728a997ad1aSLois Curfman McInnes 72990f02eecSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 730d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy(), ISGlobalToLocalMappingApply() 73190f02eecSBarry Smith @*/ 7327087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping,IS is,IS *newis) 73390f02eecSBarry Smith { 7346849ba73SBarry Smith PetscErrorCode ierr; 735e24637baSBarry Smith PetscInt n,*idxout; 7365d0c19d7SBarry Smith const PetscInt *idxin; 7373a40ed3dSBarry Smith 7383a40ed3dSBarry Smith PetscFunctionBegin; 7390700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 7400700a824SBarry Smith PetscValidHeaderSpecific(is,IS_CLASSID,2); 7414482741eSBarry Smith PetscValidPointer(newis,3); 74290f02eecSBarry Smith 7433b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 74490f02eecSBarry Smith ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 745785e854fSJed Brown ierr = PetscMalloc1(n,&idxout);CHKERRQ(ierr); 746e24637baSBarry Smith ierr = ISLocalToGlobalMappingApply(mapping,n,idxin,idxout);CHKERRQ(ierr); 7473b9aefa3SBarry Smith ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 748543f3098SMatthew G. Knepley ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is),n,idxout,PETSC_OWN_POINTER,newis);CHKERRQ(ierr); 7493a40ed3dSBarry Smith PetscFunctionReturn(0); 75090f02eecSBarry Smith } 75190f02eecSBarry Smith 752b89cb25eSSatish Balay /*@ 7533acfe500SLois Curfman McInnes ISLocalToGlobalMappingApply - Takes a list of integers in a local numbering 7543acfe500SLois Curfman McInnes and converts them to the global numbering. 75590f02eecSBarry Smith 756b9cd556bSLois Curfman McInnes Not collective 757b9cd556bSLois Curfman McInnes 758bb25748dSBarry Smith Input Parameters: 759b9cd556bSLois Curfman McInnes + mapping - the local to global mapping context 760bb25748dSBarry Smith . N - number of integers 761b9cd556bSLois Curfman McInnes - in - input indices in local numbering 762bb25748dSBarry Smith 763bb25748dSBarry Smith Output Parameter: 764bb25748dSBarry Smith . out - indices in global numbering 765bb25748dSBarry Smith 766b9cd556bSLois Curfman McInnes Notes: 767b9cd556bSLois Curfman McInnes The in and out array parameters may be identical. 768d4bb536fSBarry Smith 769a997ad1aSLois Curfman McInnes Level: advanced 770a997ad1aSLois Curfman McInnes 77145b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingApplyBlock(), ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 7720752156aSBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 773d4bb536fSBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 774bb25748dSBarry Smith 775afcb2eb5SJed Brown @*/ 776afcb2eb5SJed Brown PetscErrorCode ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping,PetscInt N,const PetscInt in[],PetscInt out[]) 777afcb2eb5SJed Brown { 778cbc1caf0SMatthew G. Knepley PetscInt i,bs,Nmax; 77945b6f7e9SBarry Smith 78045b6f7e9SBarry Smith PetscFunctionBegin; 781cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 782cbc1caf0SMatthew G. Knepley bs = mapping->bs; 783cbc1caf0SMatthew G. Knepley Nmax = bs*mapping->n; 78445b6f7e9SBarry Smith if (bs == 1) { 785cbc1caf0SMatthew G. Knepley const PetscInt *idx = mapping->indices; 78645b6f7e9SBarry Smith for (i=0; i<N; i++) { 78745b6f7e9SBarry Smith if (in[i] < 0) { 78845b6f7e9SBarry Smith out[i] = in[i]; 78945b6f7e9SBarry Smith continue; 79045b6f7e9SBarry Smith } 791e24637baSBarry 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); 79245b6f7e9SBarry Smith out[i] = idx[in[i]]; 79345b6f7e9SBarry Smith } 79445b6f7e9SBarry Smith } else { 795cbc1caf0SMatthew G. Knepley const PetscInt *idx = mapping->indices; 79645b6f7e9SBarry Smith for (i=0; i<N; i++) { 79745b6f7e9SBarry Smith if (in[i] < 0) { 79845b6f7e9SBarry Smith out[i] = in[i]; 79945b6f7e9SBarry Smith continue; 80045b6f7e9SBarry Smith } 801e24637baSBarry 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); 80245b6f7e9SBarry Smith out[i] = idx[in[i]/bs]*bs + (in[i] % bs); 80345b6f7e9SBarry Smith } 80445b6f7e9SBarry Smith } 80545b6f7e9SBarry Smith PetscFunctionReturn(0); 80645b6f7e9SBarry Smith } 80745b6f7e9SBarry Smith 80845b6f7e9SBarry Smith /*@ 8096006e8d2SBarry Smith ISLocalToGlobalMappingApplyBlock - Takes a list of integers in a local block numbering and converts them to the global block numbering 81045b6f7e9SBarry Smith 81145b6f7e9SBarry Smith Not collective 81245b6f7e9SBarry Smith 81345b6f7e9SBarry Smith Input Parameters: 81445b6f7e9SBarry Smith + mapping - the local to global mapping context 81545b6f7e9SBarry Smith . N - number of integers 8166006e8d2SBarry Smith - in - input indices in local block numbering 81745b6f7e9SBarry Smith 81845b6f7e9SBarry Smith Output Parameter: 8196006e8d2SBarry Smith . out - indices in global block numbering 82045b6f7e9SBarry Smith 82145b6f7e9SBarry Smith Notes: 82245b6f7e9SBarry Smith The in and out array parameters may be identical. 82345b6f7e9SBarry Smith 8246006e8d2SBarry Smith Example: 8256006e8d2SBarry 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 8266006e8d2SBarry Smith (the first block) would produce 0 and the mapping applied to 1 (the second block) would produce 3. 8276006e8d2SBarry Smith 82845b6f7e9SBarry Smith Level: advanced 82945b6f7e9SBarry Smith 83045b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 83145b6f7e9SBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 83245b6f7e9SBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 83345b6f7e9SBarry Smith 83445b6f7e9SBarry Smith @*/ 83545b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingApplyBlock(ISLocalToGlobalMapping mapping,PetscInt N,const PetscInt in[],PetscInt out[]) 83645b6f7e9SBarry Smith { 837cbc1caf0SMatthew G. Knepley 838cbc1caf0SMatthew G. Knepley PetscFunctionBegin; 839cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 840cbc1caf0SMatthew G. Knepley { 841afcb2eb5SJed Brown PetscInt i,Nmax = mapping->n; 842afcb2eb5SJed Brown const PetscInt *idx = mapping->indices; 843d4bb536fSBarry Smith 844afcb2eb5SJed Brown for (i=0; i<N; i++) { 845afcb2eb5SJed Brown if (in[i] < 0) { 846afcb2eb5SJed Brown out[i] = in[i]; 847afcb2eb5SJed Brown continue; 848afcb2eb5SJed Brown } 849e24637baSBarry 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); 850afcb2eb5SJed Brown out[i] = idx[in[i]]; 851afcb2eb5SJed Brown } 852cbc1caf0SMatthew G. Knepley } 853afcb2eb5SJed Brown PetscFunctionReturn(0); 854afcb2eb5SJed Brown } 855d4bb536fSBarry Smith 8567e99dc12SLawrence Mitchell /*@ 857a997ad1aSLois Curfman McInnes ISGlobalToLocalMappingApply - Provides the local numbering for a list of integers 858a997ad1aSLois Curfman McInnes specified with a global numbering. 859d4bb536fSBarry Smith 860b9cd556bSLois Curfman McInnes Not collective 861b9cd556bSLois Curfman McInnes 862d4bb536fSBarry Smith Input Parameters: 863b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 8640040bde1SJunchao Zhang . type - IS_GTOLM_MASK - maps global indices with no local value to -1 in the output list (i.e., mask them) 865d4bb536fSBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 866d4bb536fSBarry Smith . n - number of global indices to map 867b9cd556bSLois Curfman McInnes - idx - global indices to map 868d4bb536fSBarry Smith 869d4bb536fSBarry Smith Output Parameters: 870b9cd556bSLois Curfman McInnes + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 871b9cd556bSLois Curfman McInnes - idxout - local index of each global index, one must pass in an array long enough 872e182c471SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApply() with 8730298fd71SBarry Smith idxout == NULL to determine the required length (returned in nout) 874e182c471SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApply() 875e182c471SBarry Smith a second time to set the values. 876d4bb536fSBarry Smith 877b9cd556bSLois Curfman McInnes Notes: 8780298fd71SBarry Smith Either nout or idxout may be NULL. idx and idxout may be identical. 879d4bb536fSBarry Smith 8809a7b7924SJed Brown For "small" problems when using ISGlobalToLocalMappingApply() and ISGlobalToLocalMappingApplyBlock(), the ISLocalToGlobalMappingType of ISLOCALTOGLOBALMAPPINGBASIC will be used; 881413f72f0SBarry Smith this uses more memory but is faster; this approach is not scalable for extremely large mappings. For large problems ISLOCALTOGLOBALMAPPINGHASH is used, this is scalable. 882413f72f0SBarry Smith Use ISLocalToGlobalMappingSetType() or call ISLocalToGlobalMappingSetFromOptions() with the option -islocaltoglobalmapping_type <basic,hash> to control which is used. 8830f5bd95cSBarry Smith 884a997ad1aSLois Curfman McInnes Level: advanced 885a997ad1aSLois Curfman McInnes 88632fd6b96SBarry Smith Developer Note: The manual page states that idx and idxout may be identical but the calling 88732fd6b96SBarry Smith sequence declares idx as const so it cannot be the same as idxout. 88832fd6b96SBarry Smith 8899d90f715SBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISGlobalToLocalMappingApplyBlock(), ISLocalToGlobalMappingCreate(), 890413f72f0SBarry Smith ISLocalToGlobalMappingDestroy() 891d4bb536fSBarry Smith @*/ 892413f72f0SBarry Smith PetscErrorCode ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingMode type,PetscInt n,const PetscInt idx[],PetscInt *nout,PetscInt idxout[]) 893d4bb536fSBarry Smith { 8949d90f715SBarry Smith PetscErrorCode ierr; 8959d90f715SBarry Smith 8969d90f715SBarry Smith PetscFunctionBegin; 8979d90f715SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 898413f72f0SBarry Smith if (!mapping->data) { 899413f72f0SBarry Smith ierr = ISGlobalToLocalMappingSetUp(mapping);CHKERRQ(ierr); 9009d90f715SBarry Smith } 901413f72f0SBarry Smith ierr = (*mapping->ops->globaltolocalmappingapply)(mapping,type,n,idx,nout,idxout);CHKERRQ(ierr); 9029d90f715SBarry Smith PetscFunctionReturn(0); 9039d90f715SBarry Smith } 9049d90f715SBarry Smith 905d4fe737eSStefano Zampini /*@ 906d4fe737eSStefano Zampini ISGlobalToLocalMappingApplyIS - Creates from an IS in the global numbering 907d4fe737eSStefano Zampini a new index set using the local numbering defined in an ISLocalToGlobalMapping 908d4fe737eSStefano Zampini context. 909d4fe737eSStefano Zampini 910d4fe737eSStefano Zampini Not collective 911d4fe737eSStefano Zampini 912d4fe737eSStefano Zampini Input Parameters: 913d4fe737eSStefano Zampini + mapping - mapping between local and global numbering 9140040bde1SJunchao Zhang . type - IS_GTOLM_MASK - maps global indices with no local value to -1 in the output list (i.e., mask them) 9152785b321SStefano Zampini IS_GTOLM_DROP - drops the indices with no local value from the output list 916d4fe737eSStefano Zampini - is - index set in global numbering 917d4fe737eSStefano Zampini 918d4fe737eSStefano Zampini Output Parameters: 919d4fe737eSStefano Zampini . newis - index set in local numbering 920d4fe737eSStefano Zampini 9214cb36875SStefano Zampini Notes: 9224cb36875SStefano Zampini The output IS will be sequential, as it encodes a purely local operation 9234cb36875SStefano Zampini 924d4fe737eSStefano Zampini Level: advanced 925d4fe737eSStefano Zampini 926d4fe737eSStefano Zampini .seealso: ISGlobalToLocalMappingApply(), ISLocalToGlobalMappingCreate(), 927d4fe737eSStefano Zampini ISLocalToGlobalMappingDestroy() 928d4fe737eSStefano Zampini @*/ 929413f72f0SBarry Smith PetscErrorCode ISGlobalToLocalMappingApplyIS(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingMode type,IS is,IS *newis) 930d4fe737eSStefano Zampini { 931d4fe737eSStefano Zampini PetscErrorCode ierr; 932d4fe737eSStefano Zampini PetscInt n,nout,*idxout; 933d4fe737eSStefano Zampini const PetscInt *idxin; 934d4fe737eSStefano Zampini 935d4fe737eSStefano Zampini PetscFunctionBegin; 936d4fe737eSStefano Zampini PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 937d4fe737eSStefano Zampini PetscValidHeaderSpecific(is,IS_CLASSID,3); 938d4fe737eSStefano Zampini PetscValidPointer(newis,4); 939d4fe737eSStefano Zampini 940d4fe737eSStefano Zampini ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 941d4fe737eSStefano Zampini ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 942d4fe737eSStefano Zampini if (type == IS_GTOLM_MASK) { 943d4fe737eSStefano Zampini ierr = PetscMalloc1(n,&idxout);CHKERRQ(ierr); 944d4fe737eSStefano Zampini } else { 945d4fe737eSStefano Zampini ierr = ISGlobalToLocalMappingApply(mapping,type,n,idxin,&nout,NULL);CHKERRQ(ierr); 946d4fe737eSStefano Zampini ierr = PetscMalloc1(nout,&idxout);CHKERRQ(ierr); 947d4fe737eSStefano Zampini } 948d4fe737eSStefano Zampini ierr = ISGlobalToLocalMappingApply(mapping,type,n,idxin,&nout,idxout);CHKERRQ(ierr); 949d4fe737eSStefano Zampini ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 9504cb36875SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nout,idxout,PETSC_OWN_POINTER,newis);CHKERRQ(ierr); 951d4fe737eSStefano Zampini PetscFunctionReturn(0); 952d4fe737eSStefano Zampini } 953d4fe737eSStefano Zampini 9549d90f715SBarry Smith /*@ 9559d90f715SBarry Smith ISGlobalToLocalMappingApplyBlock - Provides the local block numbering for a list of integers 9569d90f715SBarry Smith specified with a block global numbering. 9579d90f715SBarry Smith 9589d90f715SBarry Smith Not collective 9599d90f715SBarry Smith 9609d90f715SBarry Smith Input Parameters: 9619d90f715SBarry Smith + mapping - mapping between local and global numbering 9620040bde1SJunchao Zhang . type - IS_GTOLM_MASK - maps global indices with no local value to -1 in the output list (i.e., mask them) 9639d90f715SBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 9649d90f715SBarry Smith . n - number of global indices to map 9659d90f715SBarry Smith - idx - global indices to map 9669d90f715SBarry Smith 9679d90f715SBarry Smith Output Parameters: 9689d90f715SBarry Smith + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 9699d90f715SBarry Smith - idxout - local index of each global index, one must pass in an array long enough 9709d90f715SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApplyBlock() with 9719d90f715SBarry Smith idxout == NULL to determine the required length (returned in nout) 9729d90f715SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApplyBlock() 9739d90f715SBarry Smith a second time to set the values. 9749d90f715SBarry Smith 9759d90f715SBarry Smith Notes: 9769d90f715SBarry Smith Either nout or idxout may be NULL. idx and idxout may be identical. 9779d90f715SBarry Smith 9789a7b7924SJed Brown For "small" problems when using ISGlobalToLocalMappingApply() and ISGlobalToLocalMappingApplyBlock(), the ISLocalToGlobalMappingType of ISLOCALTOGLOBALMAPPINGBASIC will be used; 979413f72f0SBarry Smith this uses more memory but is faster; this approach is not scalable for extremely large mappings. For large problems ISLOCALTOGLOBALMAPPINGHASH is used, this is scalable. 980413f72f0SBarry Smith Use ISLocalToGlobalMappingSetType() or call ISLocalToGlobalMappingSetFromOptions() with the option -islocaltoglobalmapping_type <basic,hash> to control which is used. 9819d90f715SBarry Smith 9829d90f715SBarry Smith Level: advanced 9839d90f715SBarry Smith 9849d90f715SBarry Smith Developer Note: The manual page states that idx and idxout may be identical but the calling 9859d90f715SBarry Smith sequence declares idx as const so it cannot be the same as idxout. 9869d90f715SBarry Smith 9879d90f715SBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISGlobalToLocalMappingApply(), ISLocalToGlobalMappingCreate(), 988413f72f0SBarry Smith ISLocalToGlobalMappingDestroy() 9899d90f715SBarry Smith @*/ 990413f72f0SBarry Smith PetscErrorCode ISGlobalToLocalMappingApplyBlock(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingMode type, 9919d90f715SBarry Smith PetscInt n,const PetscInt idx[],PetscInt *nout,PetscInt idxout[]) 9929d90f715SBarry Smith { 9936849ba73SBarry Smith PetscErrorCode ierr; 994d4bb536fSBarry Smith 9953a40ed3dSBarry Smith PetscFunctionBegin; 9960700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 997413f72f0SBarry Smith if (!mapping->data) { 998413f72f0SBarry Smith ierr = ISGlobalToLocalMappingSetUp(mapping);CHKERRQ(ierr); 999d4bb536fSBarry Smith } 1000413f72f0SBarry Smith ierr = (*mapping->ops->globaltolocalmappingapplyblock)(mapping,type,n,idx,nout,idxout);CHKERRQ(ierr); 10013a40ed3dSBarry Smith PetscFunctionReturn(0); 1002d4bb536fSBarry Smith } 100390f02eecSBarry Smith 100489d82c54SBarry Smith /*@C 10056a818285SBarry Smith ISLocalToGlobalMappingGetBlockInfo - Gets the neighbor information for each processor and 100689d82c54SBarry Smith each index shared by more than one processor 100789d82c54SBarry Smith 100889d82c54SBarry Smith Collective on ISLocalToGlobalMapping 100989d82c54SBarry Smith 1010f899ff85SJose E. Roman Input Parameter: 101189d82c54SBarry Smith . mapping - the mapping from local to global indexing 101289d82c54SBarry Smith 1013d8d19677SJose E. Roman Output Parameters: 101489d82c54SBarry Smith + nproc - number of processors that are connected to this one 101589d82c54SBarry Smith . proc - neighboring processors 101607b52d57SBarry Smith . numproc - number of indices for each subdomain (processor) 10173463a7baSJed Brown - indices - indices of nodes (in local numbering) shared with neighbors (sorted by global numbering) 101889d82c54SBarry Smith 101989d82c54SBarry Smith Level: advanced 102089d82c54SBarry Smith 10212cfcea29SBarry Smith Fortran Usage: 10222cfcea29SBarry Smith $ ISLocalToGlobalMpngGetInfoSize(ISLocalToGlobalMapping,PetscInt nproc,PetscInt numprocmax,ierr) followed by 10232cfcea29SBarry Smith $ ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping,PetscInt nproc, PetscInt procs[nproc],PetscInt numprocs[nproc], 10242cfcea29SBarry Smith PetscInt indices[nproc][numprocmax],ierr) 10252cfcea29SBarry Smith There is no ISLocalToGlobalMappingRestoreInfo() in Fortran. You must make sure that procs[], numprocs[] and 10262cfcea29SBarry Smith indices[][] are large enough arrays, either by allocating them dynamically or defining static ones large enough. 10272cfcea29SBarry Smith 102807b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 102907b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo() 103089d82c54SBarry Smith @*/ 10316a818285SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetBlockInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 103289d82c54SBarry Smith { 10336849ba73SBarry Smith PetscErrorCode ierr; 1034268a049cSStefano Zampini 1035268a049cSStefano Zampini PetscFunctionBegin; 1036268a049cSStefano Zampini PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 1037268a049cSStefano Zampini if (mapping->info_cached) { 1038268a049cSStefano Zampini *nproc = mapping->info_nproc; 1039268a049cSStefano Zampini *procs = mapping->info_procs; 1040268a049cSStefano Zampini *numprocs = mapping->info_numprocs; 1041268a049cSStefano Zampini *indices = mapping->info_indices; 1042268a049cSStefano Zampini } else { 1043268a049cSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockInfo_Private(mapping,nproc,procs,numprocs,indices);CHKERRQ(ierr); 1044268a049cSStefano Zampini } 1045268a049cSStefano Zampini PetscFunctionReturn(0); 1046268a049cSStefano Zampini } 1047268a049cSStefano Zampini 1048268a049cSStefano Zampini static PetscErrorCode ISLocalToGlobalMappingGetBlockInfo_Private(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 1049268a049cSStefano Zampini { 1050268a049cSStefano Zampini PetscErrorCode ierr; 105197f1f81fSBarry Smith PetscMPIInt size,rank,tag1,tag2,tag3,*len,*source,imdex; 105232dcc486SBarry Smith PetscInt i,n = mapping->n,Ng,ng,max = 0,*lindices = mapping->indices; 105332dcc486SBarry Smith PetscInt *nprocs,*owner,nsends,*sends,j,*starts,nmax,nrecvs,*recvs,proc; 105497f1f81fSBarry Smith PetscInt cnt,scale,*ownedsenders,*nownedsenders,rstart,nowned; 105532dcc486SBarry Smith PetscInt node,nownedm,nt,*sends2,nsends2,*starts2,*lens2,*dest,nrecvs2,*starts3,*recvs2,k,*bprocs,*tmp; 105632dcc486SBarry Smith PetscInt first_procs,first_numprocs,*first_indices; 105789d82c54SBarry Smith MPI_Request *recv_waits,*send_waits; 105830dcb7c9SBarry Smith MPI_Status recv_status,*send_status,*recv_statuses; 1059ce94432eSBarry Smith MPI_Comm comm; 1060ace3abfcSBarry Smith PetscBool debug = PETSC_FALSE; 106189d82c54SBarry Smith 106289d82c54SBarry Smith PetscFunctionBegin; 1063ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)mapping,&comm);CHKERRQ(ierr); 1064ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 1065ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 106624cf384cSBarry Smith if (size == 1) { 106724cf384cSBarry Smith *nproc = 0; 10680298fd71SBarry Smith *procs = NULL; 106995dccacaSBarry Smith ierr = PetscNew(numprocs);CHKERRQ(ierr); 10701e2105dcSBarry Smith (*numprocs)[0] = 0; 107195dccacaSBarry Smith ierr = PetscNew(indices);CHKERRQ(ierr); 10720298fd71SBarry Smith (*indices)[0] = NULL; 1073268a049cSStefano Zampini /* save info for reuse */ 1074268a049cSStefano Zampini mapping->info_nproc = *nproc; 1075268a049cSStefano Zampini mapping->info_procs = *procs; 1076268a049cSStefano Zampini mapping->info_numprocs = *numprocs; 1077268a049cSStefano Zampini mapping->info_indices = *indices; 1078268a049cSStefano Zampini mapping->info_cached = PETSC_TRUE; 107924cf384cSBarry Smith PetscFunctionReturn(0); 108024cf384cSBarry Smith } 108124cf384cSBarry Smith 1082c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject)mapping)->options,NULL,"-islocaltoglobalmappinggetinfo_debug",&debug,NULL);CHKERRQ(ierr); 108307b52d57SBarry Smith 10843677ff5aSBarry Smith /* 10856a818285SBarry Smith Notes on ISLocalToGlobalMappingGetBlockInfo 10863677ff5aSBarry Smith 10873677ff5aSBarry Smith globally owned node - the nodes that have been assigned to this processor in global 10883677ff5aSBarry Smith numbering, just for this routine. 10893677ff5aSBarry Smith 10903677ff5aSBarry Smith nontrivial globally owned node - node assigned to this processor that is on a subdomain 10913677ff5aSBarry Smith boundary (i.e. is has more than one local owner) 10923677ff5aSBarry Smith 10933677ff5aSBarry Smith locally owned node - node that exists on this processors subdomain 10943677ff5aSBarry Smith 10953677ff5aSBarry Smith nontrivial locally owned node - node that is not in the interior (i.e. has more than one 10963677ff5aSBarry Smith local subdomain 10973677ff5aSBarry Smith */ 109824cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag1);CHKERRQ(ierr); 109924cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag2);CHKERRQ(ierr); 110024cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag3);CHKERRQ(ierr); 110189d82c54SBarry Smith 110289d82c54SBarry Smith for (i=0; i<n; i++) { 110389d82c54SBarry Smith if (lindices[i] > max) max = lindices[i]; 110489d82c54SBarry Smith } 1105820f2d46SBarry Smith ierr = MPIU_Allreduce(&max,&Ng,1,MPIU_INT,MPI_MAX,comm);CHKERRMPI(ierr); 110678058e43SBarry Smith Ng++; 110755b25c41SPierre Jolivet ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 110855b25c41SPierre Jolivet ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 1109bc8ff85bSBarry Smith scale = Ng/size + 1; 1110a2e34c3dSBarry Smith ng = scale; if (rank == size-1) ng = Ng - scale*(size-1); ng = PetscMax(1,ng); 1111caba0dd0SBarry Smith rstart = scale*rank; 111289d82c54SBarry Smith 111389d82c54SBarry Smith /* determine ownership ranges of global indices */ 1114785e854fSJed Brown ierr = PetscMalloc1(2*size,&nprocs);CHKERRQ(ierr); 1115580bdb30SBarry Smith ierr = PetscArrayzero(nprocs,2*size);CHKERRQ(ierr); 111689d82c54SBarry Smith 111789d82c54SBarry Smith /* determine owners of each local node */ 1118785e854fSJed Brown ierr = PetscMalloc1(n,&owner);CHKERRQ(ierr); 111989d82c54SBarry Smith for (i=0; i<n; i++) { 11203677ff5aSBarry Smith proc = lindices[i]/scale; /* processor that globally owns this index */ 112127c402fcSBarry Smith nprocs[2*proc+1] = 1; /* processor globally owns at least one of ours */ 11223677ff5aSBarry Smith owner[i] = proc; 112327c402fcSBarry Smith nprocs[2*proc]++; /* count of how many that processor globally owns of ours */ 112489d82c54SBarry Smith } 112527c402fcSBarry Smith nsends = 0; for (i=0; i<size; i++) nsends += nprocs[2*i+1]; 11267904a332SBarry Smith ierr = PetscInfo1(mapping,"Number of global owners for my local data %D\n",nsends);CHKERRQ(ierr); 112789d82c54SBarry Smith 112889d82c54SBarry Smith /* inform other processors of number of messages and max length*/ 112927c402fcSBarry Smith ierr = PetscMaxSum(comm,nprocs,&nmax,&nrecvs);CHKERRQ(ierr); 11307904a332SBarry Smith ierr = PetscInfo1(mapping,"Number of local owners for my global data %D\n",nrecvs);CHKERRQ(ierr); 113189d82c54SBarry Smith 113289d82c54SBarry Smith /* post receives for owned rows */ 1133785e854fSJed Brown ierr = PetscMalloc1((2*nrecvs+1)*(nmax+1),&recvs);CHKERRQ(ierr); 1134854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&recv_waits);CHKERRQ(ierr); 113589d82c54SBarry Smith for (i=0; i<nrecvs; i++) { 1136ffc4695bSBarry Smith ierr = MPI_Irecv(recvs+2*nmax*i,2*nmax,MPIU_INT,MPI_ANY_SOURCE,tag1,comm,recv_waits+i);CHKERRMPI(ierr); 113789d82c54SBarry Smith } 113889d82c54SBarry Smith 113989d82c54SBarry Smith /* pack messages containing lists of local nodes to owners */ 1140854ce69bSBarry Smith ierr = PetscMalloc1(2*n+1,&sends);CHKERRQ(ierr); 1141854ce69bSBarry Smith ierr = PetscMalloc1(size+1,&starts);CHKERRQ(ierr); 114289d82c54SBarry Smith starts[0] = 0; 1143f6e5521dSKarl Rupp for (i=1; i<size; i++) starts[i] = starts[i-1] + 2*nprocs[2*i-2]; 114489d82c54SBarry Smith for (i=0; i<n; i++) { 114589d82c54SBarry Smith sends[starts[owner[i]]++] = lindices[i]; 114630dcb7c9SBarry Smith sends[starts[owner[i]]++] = i; 114789d82c54SBarry Smith } 114889d82c54SBarry Smith ierr = PetscFree(owner);CHKERRQ(ierr); 114989d82c54SBarry Smith starts[0] = 0; 1150f6e5521dSKarl Rupp for (i=1; i<size; i++) starts[i] = starts[i-1] + 2*nprocs[2*i-2]; 115189d82c54SBarry Smith 115289d82c54SBarry Smith /* send the messages */ 1153854ce69bSBarry Smith ierr = PetscMalloc1(nsends+1,&send_waits);CHKERRQ(ierr); 1154854ce69bSBarry Smith ierr = PetscMalloc1(nsends+1,&dest);CHKERRQ(ierr); 115589d82c54SBarry Smith cnt = 0; 115689d82c54SBarry Smith for (i=0; i<size; i++) { 115727c402fcSBarry Smith if (nprocs[2*i]) { 115855b25c41SPierre Jolivet ierr = MPI_Isend(sends+starts[i],2*nprocs[2*i],MPIU_INT,i,tag1,comm,send_waits+cnt);CHKERRMPI(ierr); 115930dcb7c9SBarry Smith dest[cnt] = i; 116089d82c54SBarry Smith cnt++; 116189d82c54SBarry Smith } 116289d82c54SBarry Smith } 116389d82c54SBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 116489d82c54SBarry Smith 116589d82c54SBarry Smith /* wait on receives */ 1166854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&source);CHKERRQ(ierr); 1167854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&len);CHKERRQ(ierr); 116889d82c54SBarry Smith cnt = nrecvs; 1169580bdb30SBarry Smith ierr = PetscCalloc1(ng+1,&nownedsenders);CHKERRQ(ierr); 117089d82c54SBarry Smith while (cnt) { 1171ffc4695bSBarry Smith ierr = MPI_Waitany(nrecvs,recv_waits,&imdex,&recv_status);CHKERRMPI(ierr); 117289d82c54SBarry Smith /* unpack receives into our local space */ 117355b25c41SPierre Jolivet ierr = MPI_Get_count(&recv_status,MPIU_INT,&len[imdex]);CHKERRMPI(ierr); 117489d82c54SBarry Smith source[imdex] = recv_status.MPI_SOURCE; 117530dcb7c9SBarry Smith len[imdex] = len[imdex]/2; 1176caba0dd0SBarry Smith /* count how many local owners for each of my global owned indices */ 117730dcb7c9SBarry Smith for (i=0; i<len[imdex]; i++) nownedsenders[recvs[2*imdex*nmax+2*i]-rstart]++; 117889d82c54SBarry Smith cnt--; 117989d82c54SBarry Smith } 118089d82c54SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 118189d82c54SBarry Smith 118230dcb7c9SBarry Smith /* count how many globally owned indices are on an edge multiplied by how many processors own them. */ 1183bc8ff85bSBarry Smith nowned = 0; 1184bc8ff85bSBarry Smith nownedm = 0; 1185bc8ff85bSBarry Smith for (i=0; i<ng; i++) { 1186bc8ff85bSBarry Smith if (nownedsenders[i] > 1) {nownedm += nownedsenders[i]; nowned++;} 1187bc8ff85bSBarry Smith } 1188bc8ff85bSBarry Smith 1189bc8ff85bSBarry Smith /* create single array to contain rank of all local owners of each globally owned index */ 1190854ce69bSBarry Smith ierr = PetscMalloc1(nownedm+1,&ownedsenders);CHKERRQ(ierr); 1191854ce69bSBarry Smith ierr = PetscMalloc1(ng+1,&starts);CHKERRQ(ierr); 1192bc8ff85bSBarry Smith starts[0] = 0; 1193bc8ff85bSBarry Smith for (i=1; i<ng; i++) { 1194bc8ff85bSBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 1195bc8ff85bSBarry Smith else starts[i] = starts[i-1]; 1196bc8ff85bSBarry Smith } 1197bc8ff85bSBarry Smith 119830dcb7c9SBarry Smith /* for each nontrival globally owned node list all arriving processors */ 1199bc8ff85bSBarry Smith for (i=0; i<nrecvs; i++) { 1200bc8ff85bSBarry Smith for (j=0; j<len[i]; j++) { 120130dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 1202f6e5521dSKarl Rupp if (nownedsenders[node] > 1) ownedsenders[starts[node]++] = source[i]; 1203bc8ff85bSBarry Smith } 1204bc8ff85bSBarry Smith } 1205bc8ff85bSBarry Smith 120607b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 120730dcb7c9SBarry Smith starts[0] = 0; 120830dcb7c9SBarry Smith for (i=1; i<ng; i++) { 120930dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 121030dcb7c9SBarry Smith else starts[i] = starts[i-1]; 121130dcb7c9SBarry Smith } 121230dcb7c9SBarry Smith for (i=0; i<ng; i++) { 121330dcb7c9SBarry Smith if (nownedsenders[i] > 1) { 12147904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] global node %D local owner processors: ",rank,i+rstart);CHKERRQ(ierr); 121530dcb7c9SBarry Smith for (j=0; j<nownedsenders[i]; j++) { 12167904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",ownedsenders[starts[i]+j]);CHKERRQ(ierr); 121730dcb7c9SBarry Smith } 121830dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 121930dcb7c9SBarry Smith } 122030dcb7c9SBarry Smith } 12210ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 122207b52d57SBarry Smith } /* ----------------------------------- */ 122330dcb7c9SBarry Smith 12243677ff5aSBarry Smith /* wait on original sends */ 12253a96401aSBarry Smith if (nsends) { 1226785e854fSJed Brown ierr = PetscMalloc1(nsends,&send_status);CHKERRQ(ierr); 1227ffc4695bSBarry Smith ierr = MPI_Waitall(nsends,send_waits,send_status);CHKERRMPI(ierr); 12283a96401aSBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 12293a96401aSBarry Smith } 123089d82c54SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 12313a96401aSBarry Smith ierr = PetscFree(sends);CHKERRQ(ierr); 12323677ff5aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 12333677ff5aSBarry Smith 12343677ff5aSBarry Smith /* pack messages to send back to local owners */ 123530dcb7c9SBarry Smith starts[0] = 0; 123630dcb7c9SBarry Smith for (i=1; i<ng; i++) { 123730dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 123830dcb7c9SBarry Smith else starts[i] = starts[i-1]; 123930dcb7c9SBarry Smith } 124030dcb7c9SBarry Smith nsends2 = nrecvs; 1241854ce69bSBarry Smith ierr = PetscMalloc1(nsends2+1,&nprocs);CHKERRQ(ierr); /* length of each message */ 124230dcb7c9SBarry Smith for (i=0; i<nrecvs; i++) { 124330dcb7c9SBarry Smith nprocs[i] = 1; 124430dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 124530dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 1246f6e5521dSKarl Rupp if (nownedsenders[node] > 1) nprocs[i] += 2 + nownedsenders[node]; 124730dcb7c9SBarry Smith } 124830dcb7c9SBarry Smith } 1249f6e5521dSKarl Rupp nt = 0; 1250f6e5521dSKarl Rupp for (i=0; i<nsends2; i++) nt += nprocs[i]; 1251f6e5521dSKarl Rupp 1252854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,&sends2);CHKERRQ(ierr); 1253854ce69bSBarry Smith ierr = PetscMalloc1(nsends2+1,&starts2);CHKERRQ(ierr); 1254f6e5521dSKarl Rupp 1255f6e5521dSKarl Rupp starts2[0] = 0; 1256f6e5521dSKarl Rupp for (i=1; i<nsends2; i++) starts2[i] = starts2[i-1] + nprocs[i-1]; 125730dcb7c9SBarry Smith /* 125830dcb7c9SBarry Smith Each message is 1 + nprocs[i] long, and consists of 125930dcb7c9SBarry Smith (0) the number of nodes being sent back 126030dcb7c9SBarry Smith (1) the local node number, 126130dcb7c9SBarry Smith (2) the number of processors sharing it, 126230dcb7c9SBarry Smith (3) the processors sharing it 126330dcb7c9SBarry Smith */ 126430dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 126530dcb7c9SBarry Smith cnt = 1; 126630dcb7c9SBarry Smith sends2[starts2[i]] = 0; 126730dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 126830dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 126930dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 127030dcb7c9SBarry Smith sends2[starts2[i]]++; 127130dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = recvs[2*i*nmax+2*j+1]; 127230dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = nownedsenders[node]; 1273580bdb30SBarry Smith ierr = PetscArraycpy(&sends2[starts2[i]+cnt],&ownedsenders[starts[node]],nownedsenders[node]);CHKERRQ(ierr); 127430dcb7c9SBarry Smith cnt += nownedsenders[node]; 127530dcb7c9SBarry Smith } 127630dcb7c9SBarry Smith } 127730dcb7c9SBarry Smith } 127830dcb7c9SBarry Smith 127930dcb7c9SBarry Smith /* receive the message lengths */ 128030dcb7c9SBarry Smith nrecvs2 = nsends; 1281854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&lens2);CHKERRQ(ierr); 1282854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&starts3);CHKERRQ(ierr); 1283854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&recv_waits);CHKERRQ(ierr); 128430dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 1285ffc4695bSBarry Smith ierr = MPI_Irecv(&lens2[i],1,MPIU_INT,dest[i],tag2,comm,recv_waits+i);CHKERRMPI(ierr); 128630dcb7c9SBarry Smith } 1287d44834fbSBarry Smith 12888a8e0b3aSBarry Smith /* send the message lengths */ 12898a8e0b3aSBarry Smith for (i=0; i<nsends2; i++) { 1290ffc4695bSBarry Smith ierr = MPI_Send(&nprocs[i],1,MPIU_INT,source[i],tag2,comm);CHKERRMPI(ierr); 12918a8e0b3aSBarry Smith } 12928a8e0b3aSBarry Smith 1293d44834fbSBarry Smith /* wait on receives of lens */ 12940c468ba9SBarry Smith if (nrecvs2) { 1295785e854fSJed Brown ierr = PetscMalloc1(nrecvs2,&recv_statuses);CHKERRQ(ierr); 1296ffc4695bSBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRMPI(ierr); 1297d44834fbSBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 12980c468ba9SBarry Smith } 1299a2ea699eSBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 1300d44834fbSBarry Smith 130130dcb7c9SBarry Smith starts3[0] = 0; 1302d44834fbSBarry Smith nt = 0; 130330dcb7c9SBarry Smith for (i=0; i<nrecvs2-1; i++) { 130430dcb7c9SBarry Smith starts3[i+1] = starts3[i] + lens2[i]; 1305d44834fbSBarry Smith nt += lens2[i]; 130630dcb7c9SBarry Smith } 130776466f69SStefano Zampini if (nrecvs2) nt += lens2[nrecvs2-1]; 1308d44834fbSBarry Smith 1309854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,&recvs2);CHKERRQ(ierr); 1310854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&recv_waits);CHKERRQ(ierr); 131152b72c4aSBarry Smith for (i=0; i<nrecvs2; i++) { 1312ffc4695bSBarry Smith ierr = MPI_Irecv(recvs2+starts3[i],lens2[i],MPIU_INT,dest[i],tag3,comm,recv_waits+i);CHKERRMPI(ierr); 131330dcb7c9SBarry Smith } 131430dcb7c9SBarry Smith 131530dcb7c9SBarry Smith /* send the messages */ 1316854ce69bSBarry Smith ierr = PetscMalloc1(nsends2+1,&send_waits);CHKERRQ(ierr); 131730dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 1318ffc4695bSBarry Smith ierr = MPI_Isend(sends2+starts2[i],nprocs[i],MPIU_INT,source[i],tag3,comm,send_waits+i);CHKERRMPI(ierr); 131930dcb7c9SBarry Smith } 132030dcb7c9SBarry Smith 132130dcb7c9SBarry Smith /* wait on receives */ 13220c468ba9SBarry Smith if (nrecvs2) { 1323785e854fSJed Brown ierr = PetscMalloc1(nrecvs2,&recv_statuses);CHKERRQ(ierr); 1324ffc4695bSBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRMPI(ierr); 132530dcb7c9SBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 13260c468ba9SBarry Smith } 132730dcb7c9SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 132830dcb7c9SBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 132930dcb7c9SBarry Smith 133007b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 133130dcb7c9SBarry Smith cnt = 0; 133230dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 133330dcb7c9SBarry Smith nt = recvs2[cnt++]; 133430dcb7c9SBarry Smith for (j=0; j<nt; j++) { 13357904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] local node %D number of subdomains %D: ",rank,recvs2[cnt],recvs2[cnt+1]);CHKERRQ(ierr); 133630dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 13377904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",recvs2[cnt+2+k]);CHKERRQ(ierr); 133830dcb7c9SBarry Smith } 133930dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 134030dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 134130dcb7c9SBarry Smith } 134230dcb7c9SBarry Smith } 13430ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 134407b52d57SBarry Smith } /* ----------------------------------- */ 134530dcb7c9SBarry Smith 134630dcb7c9SBarry Smith /* count number subdomains for each local node */ 1347580bdb30SBarry Smith ierr = PetscCalloc1(size,&nprocs);CHKERRQ(ierr); 134830dcb7c9SBarry Smith cnt = 0; 134930dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 135030dcb7c9SBarry Smith nt = recvs2[cnt++]; 135130dcb7c9SBarry Smith for (j=0; j<nt; j++) { 1352f6e5521dSKarl Rupp for (k=0; k<recvs2[cnt+1]; k++) nprocs[recvs2[cnt+2+k]]++; 135330dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 135430dcb7c9SBarry Smith } 135530dcb7c9SBarry Smith } 135630dcb7c9SBarry Smith nt = 0; for (i=0; i<size; i++) nt += (nprocs[i] > 0); 135730dcb7c9SBarry Smith *nproc = nt; 1358854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,procs);CHKERRQ(ierr); 1359854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,numprocs);CHKERRQ(ierr); 1360854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,indices);CHKERRQ(ierr); 13610298fd71SBarry Smith for (i=0;i<nt+1;i++) (*indices)[i]=NULL; 1362785e854fSJed Brown ierr = PetscMalloc1(size,&bprocs);CHKERRQ(ierr); 136330dcb7c9SBarry Smith cnt = 0; 136430dcb7c9SBarry Smith for (i=0; i<size; i++) { 136530dcb7c9SBarry Smith if (nprocs[i] > 0) { 136630dcb7c9SBarry Smith bprocs[i] = cnt; 136730dcb7c9SBarry Smith (*procs)[cnt] = i; 136830dcb7c9SBarry Smith (*numprocs)[cnt] = nprocs[i]; 1369785e854fSJed Brown ierr = PetscMalloc1(nprocs[i],&(*indices)[cnt]);CHKERRQ(ierr); 137030dcb7c9SBarry Smith cnt++; 137130dcb7c9SBarry Smith } 137230dcb7c9SBarry Smith } 137330dcb7c9SBarry Smith 137430dcb7c9SBarry Smith /* make the list of subdomains for each nontrivial local node */ 1375580bdb30SBarry Smith ierr = PetscArrayzero(*numprocs,nt);CHKERRQ(ierr); 137630dcb7c9SBarry Smith cnt = 0; 137730dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 137830dcb7c9SBarry Smith nt = recvs2[cnt++]; 137930dcb7c9SBarry Smith for (j=0; j<nt; j++) { 1380f6e5521dSKarl Rupp for (k=0; k<recvs2[cnt+1]; k++) (*indices)[bprocs[recvs2[cnt+2+k]]][(*numprocs)[bprocs[recvs2[cnt+2+k]]]++] = recvs2[cnt]; 138130dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 138230dcb7c9SBarry Smith } 138330dcb7c9SBarry Smith } 138430dcb7c9SBarry Smith ierr = PetscFree(bprocs);CHKERRQ(ierr); 138507b52d57SBarry Smith ierr = PetscFree(recvs2);CHKERRQ(ierr); 138630dcb7c9SBarry Smith 138707b52d57SBarry Smith /* sort the node indexing by their global numbers */ 138807b52d57SBarry Smith nt = *nproc; 138907b52d57SBarry Smith for (i=0; i<nt; i++) { 1390854ce69bSBarry Smith ierr = PetscMalloc1((*numprocs)[i],&tmp);CHKERRQ(ierr); 1391f6e5521dSKarl Rupp for (j=0; j<(*numprocs)[i]; j++) tmp[j] = lindices[(*indices)[i][j]]; 139207b52d57SBarry Smith ierr = PetscSortIntWithArray((*numprocs)[i],tmp,(*indices)[i]);CHKERRQ(ierr); 139307b52d57SBarry Smith ierr = PetscFree(tmp);CHKERRQ(ierr); 139407b52d57SBarry Smith } 139507b52d57SBarry Smith 139607b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 139730dcb7c9SBarry Smith nt = *nproc; 139830dcb7c9SBarry Smith for (i=0; i<nt; i++) { 13997904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] subdomain %D number of indices %D: ",rank,(*procs)[i],(*numprocs)[i]);CHKERRQ(ierr); 140030dcb7c9SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 14017904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",(*indices)[i][j]);CHKERRQ(ierr); 140230dcb7c9SBarry Smith } 140330dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 140430dcb7c9SBarry Smith } 14050ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 140607b52d57SBarry Smith } /* ----------------------------------- */ 140730dcb7c9SBarry Smith 140830dcb7c9SBarry Smith /* wait on sends */ 140930dcb7c9SBarry Smith if (nsends2) { 1410785e854fSJed Brown ierr = PetscMalloc1(nsends2,&send_status);CHKERRQ(ierr); 1411ffc4695bSBarry Smith ierr = MPI_Waitall(nsends2,send_waits,send_status);CHKERRMPI(ierr); 141230dcb7c9SBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 141330dcb7c9SBarry Smith } 141430dcb7c9SBarry Smith 141530dcb7c9SBarry Smith ierr = PetscFree(starts3);CHKERRQ(ierr); 141630dcb7c9SBarry Smith ierr = PetscFree(dest);CHKERRQ(ierr); 141730dcb7c9SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 14183677ff5aSBarry Smith 1419bc8ff85bSBarry Smith ierr = PetscFree(nownedsenders);CHKERRQ(ierr); 1420bc8ff85bSBarry Smith ierr = PetscFree(ownedsenders);CHKERRQ(ierr); 1421bc8ff85bSBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 142230dcb7c9SBarry Smith ierr = PetscFree(starts2);CHKERRQ(ierr); 142330dcb7c9SBarry Smith ierr = PetscFree(lens2);CHKERRQ(ierr); 142489d82c54SBarry Smith 142589d82c54SBarry Smith ierr = PetscFree(source);CHKERRQ(ierr); 142697f1f81fSBarry Smith ierr = PetscFree(len);CHKERRQ(ierr); 142789d82c54SBarry Smith ierr = PetscFree(recvs);CHKERRQ(ierr); 14283a96401aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 142930dcb7c9SBarry Smith ierr = PetscFree(sends2);CHKERRQ(ierr); 143024cf384cSBarry Smith 143124cf384cSBarry Smith /* put the information about myself as the first entry in the list */ 143224cf384cSBarry Smith first_procs = (*procs)[0]; 143324cf384cSBarry Smith first_numprocs = (*numprocs)[0]; 143424cf384cSBarry Smith first_indices = (*indices)[0]; 143524cf384cSBarry Smith for (i=0; i<*nproc; i++) { 143624cf384cSBarry Smith if ((*procs)[i] == rank) { 143724cf384cSBarry Smith (*procs)[0] = (*procs)[i]; 143824cf384cSBarry Smith (*numprocs)[0] = (*numprocs)[i]; 143924cf384cSBarry Smith (*indices)[0] = (*indices)[i]; 144024cf384cSBarry Smith (*procs)[i] = first_procs; 144124cf384cSBarry Smith (*numprocs)[i] = first_numprocs; 144224cf384cSBarry Smith (*indices)[i] = first_indices; 144324cf384cSBarry Smith break; 144424cf384cSBarry Smith } 144524cf384cSBarry Smith } 1446268a049cSStefano Zampini 1447268a049cSStefano Zampini /* save info for reuse */ 1448268a049cSStefano Zampini mapping->info_nproc = *nproc; 1449268a049cSStefano Zampini mapping->info_procs = *procs; 1450268a049cSStefano Zampini mapping->info_numprocs = *numprocs; 1451268a049cSStefano Zampini mapping->info_indices = *indices; 1452268a049cSStefano Zampini mapping->info_cached = PETSC_TRUE; 145389d82c54SBarry Smith PetscFunctionReturn(0); 145489d82c54SBarry Smith } 145589d82c54SBarry Smith 14566a818285SBarry Smith /*@C 14576a818285SBarry Smith ISLocalToGlobalMappingRestoreBlockInfo - Frees the memory allocated by ISLocalToGlobalMappingGetBlockInfo() 14586a818285SBarry Smith 14596a818285SBarry Smith Collective on ISLocalToGlobalMapping 14606a818285SBarry Smith 1461f899ff85SJose E. Roman Input Parameter: 14626a818285SBarry Smith . mapping - the mapping from local to global indexing 14636a818285SBarry Smith 1464d8d19677SJose E. Roman Output Parameters: 14656a818285SBarry Smith + nproc - number of processors that are connected to this one 14666a818285SBarry Smith . proc - neighboring processors 14676a818285SBarry Smith . numproc - number of indices for each processor 14686a818285SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 14696a818285SBarry Smith 14706a818285SBarry Smith Level: advanced 14716a818285SBarry Smith 14726a818285SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 14736a818285SBarry Smith ISLocalToGlobalMappingGetInfo() 14746a818285SBarry Smith @*/ 14756a818285SBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreBlockInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 14766a818285SBarry Smith { 14776a818285SBarry Smith PetscErrorCode ierr; 14786a818285SBarry Smith 14796a818285SBarry Smith PetscFunctionBegin; 1480cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 1481268a049cSStefano Zampini if (mapping->info_free) { 14826a818285SBarry Smith ierr = PetscFree(*numprocs);CHKERRQ(ierr); 14836a818285SBarry Smith if (*indices) { 1484268a049cSStefano Zampini PetscInt i; 1485268a049cSStefano Zampini 14866a818285SBarry Smith ierr = PetscFree((*indices)[0]);CHKERRQ(ierr); 14876a818285SBarry Smith for (i=1; i<*nproc; i++) { 14886a818285SBarry Smith ierr = PetscFree((*indices)[i]);CHKERRQ(ierr); 14896a818285SBarry Smith } 14906a818285SBarry Smith ierr = PetscFree(*indices);CHKERRQ(ierr); 14916a818285SBarry Smith } 1492268a049cSStefano Zampini } 1493268a049cSStefano Zampini *nproc = 0; 1494268a049cSStefano Zampini *procs = NULL; 1495268a049cSStefano Zampini *numprocs = NULL; 1496268a049cSStefano Zampini *indices = NULL; 14976a818285SBarry Smith PetscFunctionReturn(0); 14986a818285SBarry Smith } 14996a818285SBarry Smith 15006a818285SBarry Smith /*@C 15016a818285SBarry Smith ISLocalToGlobalMappingGetInfo - Gets the neighbor information for each processor and 15026a818285SBarry Smith each index shared by more than one processor 15036a818285SBarry Smith 15046a818285SBarry Smith Collective on ISLocalToGlobalMapping 15056a818285SBarry Smith 1506f899ff85SJose E. Roman Input Parameter: 15076a818285SBarry Smith . mapping - the mapping from local to global indexing 15086a818285SBarry Smith 1509d8d19677SJose E. Roman Output Parameters: 15106a818285SBarry Smith + nproc - number of processors that are connected to this one 15116a818285SBarry Smith . proc - neighboring processors 15126a818285SBarry Smith . numproc - number of indices for each subdomain (processor) 15136a818285SBarry Smith - indices - indices of nodes (in local numbering) shared with neighbors (sorted by global numbering) 15146a818285SBarry Smith 15156a818285SBarry Smith Level: advanced 15166a818285SBarry Smith 15171bd0b88eSStefano Zampini Notes: The user needs to call ISLocalToGlobalMappingRestoreInfo when the data is no longer needed. 15181bd0b88eSStefano Zampini 15196a818285SBarry Smith Fortran Usage: 15206a818285SBarry Smith $ ISLocalToGlobalMpngGetInfoSize(ISLocalToGlobalMapping,PetscInt nproc,PetscInt numprocmax,ierr) followed by 15216a818285SBarry Smith $ ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping,PetscInt nproc, PetscInt procs[nproc],PetscInt numprocs[nproc], 15226a818285SBarry Smith PetscInt indices[nproc][numprocmax],ierr) 15236a818285SBarry Smith There is no ISLocalToGlobalMappingRestoreInfo() in Fortran. You must make sure that procs[], numprocs[] and 15246a818285SBarry Smith indices[][] are large enough arrays, either by allocating them dynamically or defining static ones large enough. 15256a818285SBarry Smith 15266a818285SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 15276a818285SBarry Smith ISLocalToGlobalMappingRestoreInfo() 15286a818285SBarry Smith @*/ 15296a818285SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 15306a818285SBarry Smith { 15316a818285SBarry Smith PetscErrorCode ierr; 1532268a049cSStefano Zampini PetscInt **bindices = NULL,*bnumprocs = NULL,bs = mapping->bs,i,j,k; 15336a818285SBarry Smith 15346a818285SBarry Smith PetscFunctionBegin; 15356a818285SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 1536268a049cSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockInfo(mapping,nproc,procs,&bnumprocs,&bindices);CHKERRQ(ierr); 1537268a049cSStefano Zampini if (bs > 1) { /* we need to expand the cached info */ 1538732f65e3SBarry Smith ierr = PetscCalloc1(*nproc,&*indices);CHKERRQ(ierr); 1539268a049cSStefano Zampini ierr = PetscCalloc1(*nproc,&*numprocs);CHKERRQ(ierr); 15406a818285SBarry Smith for (i=0; i<*nproc; i++) { 1541268a049cSStefano Zampini ierr = PetscMalloc1(bs*bnumprocs[i],&(*indices)[i]);CHKERRQ(ierr); 1542268a049cSStefano Zampini for (j=0; j<bnumprocs[i]; j++) { 15436a818285SBarry Smith for (k=0; k<bs; k++) { 15446a818285SBarry Smith (*indices)[i][j*bs+k] = bs*bindices[i][j] + k; 15456a818285SBarry Smith } 15466a818285SBarry Smith } 1547268a049cSStefano Zampini (*numprocs)[i] = bnumprocs[i]*bs; 15486a818285SBarry Smith } 1549268a049cSStefano Zampini mapping->info_free = PETSC_TRUE; 1550268a049cSStefano Zampini } else { 1551268a049cSStefano Zampini *numprocs = bnumprocs; 1552268a049cSStefano Zampini *indices = bindices; 15536a818285SBarry Smith } 15546a818285SBarry Smith PetscFunctionReturn(0); 15556a818285SBarry Smith } 15566a818285SBarry Smith 155707b52d57SBarry Smith /*@C 155807b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo - Frees the memory allocated by ISLocalToGlobalMappingGetInfo() 155989d82c54SBarry Smith 156007b52d57SBarry Smith Collective on ISLocalToGlobalMapping 156107b52d57SBarry Smith 1562f899ff85SJose E. Roman Input Parameter: 156307b52d57SBarry Smith . mapping - the mapping from local to global indexing 156407b52d57SBarry Smith 1565d8d19677SJose E. Roman Output Parameters: 156607b52d57SBarry Smith + nproc - number of processors that are connected to this one 156707b52d57SBarry Smith . proc - neighboring processors 156807b52d57SBarry Smith . numproc - number of indices for each processor 156907b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 157007b52d57SBarry Smith 157107b52d57SBarry Smith Level: advanced 157207b52d57SBarry Smith 157307b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 157407b52d57SBarry Smith ISLocalToGlobalMappingGetInfo() 157507b52d57SBarry Smith @*/ 15767087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 157707b52d57SBarry Smith { 15786849ba73SBarry Smith PetscErrorCode ierr; 157907b52d57SBarry Smith 158007b52d57SBarry Smith PetscFunctionBegin; 15816a818285SBarry Smith ierr = ISLocalToGlobalMappingRestoreBlockInfo(mapping,nproc,procs,numprocs,indices);CHKERRQ(ierr); 158207b52d57SBarry Smith PetscFunctionReturn(0); 158307b52d57SBarry Smith } 158486994e45SJed Brown 158586994e45SJed Brown /*@C 15861bd0b88eSStefano Zampini ISLocalToGlobalMappingGetNodeInfo - Gets the neighbor information for each node 15871bd0b88eSStefano Zampini 15881bd0b88eSStefano Zampini Collective on ISLocalToGlobalMapping 15891bd0b88eSStefano Zampini 1590f899ff85SJose E. Roman Input Parameter: 15911bd0b88eSStefano Zampini . mapping - the mapping from local to global indexing 15921bd0b88eSStefano Zampini 1593d8d19677SJose E. Roman Output Parameters: 15941bd0b88eSStefano Zampini + nnodes - number of local nodes (same ISLocalToGlobalMappingGetSize()) 15951bd0b88eSStefano Zampini . count - number of neighboring processors per node 15961bd0b88eSStefano Zampini - indices - indices of processes sharing the node (sorted) 15971bd0b88eSStefano Zampini 15981bd0b88eSStefano Zampini Level: advanced 15991bd0b88eSStefano Zampini 16001bd0b88eSStefano Zampini Notes: The user needs to call ISLocalToGlobalMappingRestoreInfo when the data is no longer needed. 16011bd0b88eSStefano Zampini 16021bd0b88eSStefano Zampini .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 16031bd0b88eSStefano Zampini ISLocalToGlobalMappingGetInfo(), ISLocalToGlobalMappingRestoreNodeInfo() 16041bd0b88eSStefano Zampini @*/ 16051bd0b88eSStefano Zampini PetscErrorCode ISLocalToGlobalMappingGetNodeInfo(ISLocalToGlobalMapping mapping,PetscInt *nnodes,PetscInt *count[],PetscInt **indices[]) 16061bd0b88eSStefano Zampini { 16071bd0b88eSStefano Zampini PetscInt n; 16081bd0b88eSStefano Zampini PetscErrorCode ierr; 16091bd0b88eSStefano Zampini 16101bd0b88eSStefano Zampini PetscFunctionBegin; 16111bd0b88eSStefano Zampini PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 16121bd0b88eSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mapping,&n);CHKERRQ(ierr); 16131bd0b88eSStefano Zampini if (!mapping->info_nodec) { 16141bd0b88eSStefano Zampini PetscInt i,m,n_neigh,*neigh,*n_shared,**shared; 16151bd0b88eSStefano Zampini 1616071fcb05SBarry Smith ierr = PetscMalloc2(n+1,&mapping->info_nodec,n,&mapping->info_nodei);CHKERRQ(ierr); 16171bd0b88eSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 1618071fcb05SBarry Smith for (i=0;i<n;i++) { mapping->info_nodec[i] = 1;} 1619071fcb05SBarry Smith m = n; 1620071fcb05SBarry Smith mapping->info_nodec[n] = 0; 16211bd0b88eSStefano Zampini for (i=1;i<n_neigh;i++) { 16221bd0b88eSStefano Zampini PetscInt j; 16231bd0b88eSStefano Zampini 16241bd0b88eSStefano Zampini m += n_shared[i]; 16251bd0b88eSStefano Zampini for (j=0;j<n_shared[i];j++) mapping->info_nodec[shared[i][j]] += 1; 16261bd0b88eSStefano Zampini } 16271bd0b88eSStefano Zampini if (n) { ierr = PetscMalloc1(m,&mapping->info_nodei[0]);CHKERRQ(ierr); } 16281bd0b88eSStefano Zampini for (i=1;i<n;i++) mapping->info_nodei[i] = mapping->info_nodei[i-1] + mapping->info_nodec[i-1]; 1629580bdb30SBarry Smith ierr = PetscArrayzero(mapping->info_nodec,n);CHKERRQ(ierr); 16301bd0b88eSStefano Zampini for (i=0;i<n;i++) { mapping->info_nodec[i] = 1; mapping->info_nodei[i][0] = neigh[0]; } 16311bd0b88eSStefano Zampini for (i=1;i<n_neigh;i++) { 16321bd0b88eSStefano Zampini PetscInt j; 16331bd0b88eSStefano Zampini 16341bd0b88eSStefano Zampini for (j=0;j<n_shared[i];j++) { 16351bd0b88eSStefano Zampini PetscInt k = shared[i][j]; 16361bd0b88eSStefano Zampini 16371bd0b88eSStefano Zampini mapping->info_nodei[k][mapping->info_nodec[k]] = neigh[i]; 16381bd0b88eSStefano Zampini mapping->info_nodec[k] += 1; 16391bd0b88eSStefano Zampini } 16401bd0b88eSStefano Zampini } 16411bd0b88eSStefano Zampini for (i=0;i<n;i++) { ierr = PetscSortRemoveDupsInt(&mapping->info_nodec[i],mapping->info_nodei[i]);CHKERRQ(ierr); } 16421bd0b88eSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 16431bd0b88eSStefano Zampini } 16441bd0b88eSStefano Zampini if (nnodes) *nnodes = n; 16451bd0b88eSStefano Zampini if (count) *count = mapping->info_nodec; 16461bd0b88eSStefano Zampini if (indices) *indices = mapping->info_nodei; 16471bd0b88eSStefano Zampini PetscFunctionReturn(0); 16481bd0b88eSStefano Zampini } 16491bd0b88eSStefano Zampini 16501bd0b88eSStefano Zampini /*@C 16511bd0b88eSStefano Zampini ISLocalToGlobalMappingRestoreNodeInfo - Frees the memory allocated by ISLocalToGlobalMappingGetNodeInfo() 16521bd0b88eSStefano Zampini 16531bd0b88eSStefano Zampini Collective on ISLocalToGlobalMapping 16541bd0b88eSStefano Zampini 1655f899ff85SJose E. Roman Input Parameter: 16561bd0b88eSStefano Zampini . mapping - the mapping from local to global indexing 16571bd0b88eSStefano Zampini 1658d8d19677SJose E. Roman Output Parameters: 16591bd0b88eSStefano Zampini + nnodes - number of local nodes 16601bd0b88eSStefano Zampini . count - number of neighboring processors per node 16611bd0b88eSStefano Zampini - indices - indices of processes sharing the node (sorted) 16621bd0b88eSStefano Zampini 16631bd0b88eSStefano Zampini Level: advanced 16641bd0b88eSStefano Zampini 16651bd0b88eSStefano Zampini .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 16661bd0b88eSStefano Zampini ISLocalToGlobalMappingGetInfo() 16671bd0b88eSStefano Zampini @*/ 16681bd0b88eSStefano Zampini PetscErrorCode ISLocalToGlobalMappingRestoreNodeInfo(ISLocalToGlobalMapping mapping,PetscInt *nnodes,PetscInt *count[],PetscInt **indices[]) 16691bd0b88eSStefano Zampini { 16701bd0b88eSStefano Zampini PetscFunctionBegin; 16711bd0b88eSStefano Zampini PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 16721bd0b88eSStefano Zampini if (nnodes) *nnodes = 0; 16731bd0b88eSStefano Zampini if (count) *count = NULL; 16741bd0b88eSStefano Zampini if (indices) *indices = NULL; 16751bd0b88eSStefano Zampini PetscFunctionReturn(0); 16761bd0b88eSStefano Zampini } 16771bd0b88eSStefano Zampini 16781bd0b88eSStefano Zampini /*@C 1679107e9a97SBarry Smith ISLocalToGlobalMappingGetIndices - Get global indices for every local point that is mapped 168086994e45SJed Brown 168186994e45SJed Brown Not Collective 168286994e45SJed Brown 16834165533cSJose E. Roman Input Parameter: 168486994e45SJed Brown . ltog - local to global mapping 168586994e45SJed Brown 16864165533cSJose E. Roman Output Parameter: 1687565245c5SBarry Smith . array - array of indices, the length of this array may be obtained with ISLocalToGlobalMappingGetSize() 168886994e45SJed Brown 168986994e45SJed Brown Level: advanced 169086994e45SJed Brown 169195452b02SPatrick Sanan Notes: 169295452b02SPatrick Sanan ISLocalToGlobalMappingGetSize() returns the length the this array 1693107e9a97SBarry Smith 1694107e9a97SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingRestoreIndices(), ISLocalToGlobalMappingGetBlockIndices(), ISLocalToGlobalMappingRestoreBlockIndices() 169586994e45SJed Brown @*/ 16967087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingGetIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 169786994e45SJed Brown { 169886994e45SJed Brown PetscFunctionBegin; 169986994e45SJed Brown PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 170086994e45SJed Brown PetscValidPointer(array,2); 170145b6f7e9SBarry Smith if (ltog->bs == 1) { 170286994e45SJed Brown *array = ltog->indices; 170345b6f7e9SBarry Smith } else { 170445b6f7e9SBarry Smith PetscInt *jj,k,i,j,n = ltog->n, bs = ltog->bs; 170545b6f7e9SBarry Smith const PetscInt *ii; 170645b6f7e9SBarry Smith PetscErrorCode ierr; 170745b6f7e9SBarry Smith 170845b6f7e9SBarry Smith ierr = PetscMalloc1(bs*n,&jj);CHKERRQ(ierr); 170945b6f7e9SBarry Smith *array = jj; 171045b6f7e9SBarry Smith k = 0; 171145b6f7e9SBarry Smith ii = ltog->indices; 171245b6f7e9SBarry Smith for (i=0; i<n; i++) 171345b6f7e9SBarry Smith for (j=0; j<bs; j++) 171445b6f7e9SBarry Smith jj[k++] = bs*ii[i] + j; 171545b6f7e9SBarry Smith } 171686994e45SJed Brown PetscFunctionReturn(0); 171786994e45SJed Brown } 171886994e45SJed Brown 171986994e45SJed Brown /*@C 1720193a2b41SJulian Andrej ISLocalToGlobalMappingRestoreIndices - Restore indices obtained with ISLocalToGlobalMappingGetIndices() 172186994e45SJed Brown 172286994e45SJed Brown Not Collective 172386994e45SJed Brown 17244165533cSJose E. Roman Input Parameters: 172586994e45SJed Brown + ltog - local to global mapping 172686994e45SJed Brown - array - array of indices 172786994e45SJed Brown 172886994e45SJed Brown Level: advanced 172986994e45SJed Brown 173086994e45SJed Brown .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingGetIndices() 173186994e45SJed Brown @*/ 17327087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 173386994e45SJed Brown { 173486994e45SJed Brown PetscFunctionBegin; 173586994e45SJed Brown PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 173686994e45SJed Brown PetscValidPointer(array,2); 173745b6f7e9SBarry Smith if (ltog->bs == 1 && *array != ltog->indices) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Trying to return mismatched pointer"); 173845b6f7e9SBarry Smith 173945b6f7e9SBarry Smith if (ltog->bs > 1) { 174045b6f7e9SBarry Smith PetscErrorCode ierr; 174145b6f7e9SBarry Smith ierr = PetscFree(*(void**)array);CHKERRQ(ierr); 174245b6f7e9SBarry Smith } 174345b6f7e9SBarry Smith PetscFunctionReturn(0); 174445b6f7e9SBarry Smith } 174545b6f7e9SBarry Smith 174645b6f7e9SBarry Smith /*@C 174745b6f7e9SBarry Smith ISLocalToGlobalMappingGetBlockIndices - Get global indices for every local block 174845b6f7e9SBarry Smith 174945b6f7e9SBarry Smith Not Collective 175045b6f7e9SBarry Smith 17514165533cSJose E. Roman Input Parameter: 175245b6f7e9SBarry Smith . ltog - local to global mapping 175345b6f7e9SBarry Smith 17544165533cSJose E. Roman Output Parameter: 175545b6f7e9SBarry Smith . array - array of indices 175645b6f7e9SBarry Smith 175745b6f7e9SBarry Smith Level: advanced 175845b6f7e9SBarry Smith 175945b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingRestoreBlockIndices() 176045b6f7e9SBarry Smith @*/ 176145b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetBlockIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 176245b6f7e9SBarry Smith { 176345b6f7e9SBarry Smith PetscFunctionBegin; 176445b6f7e9SBarry Smith PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 176545b6f7e9SBarry Smith PetscValidPointer(array,2); 176645b6f7e9SBarry Smith *array = ltog->indices; 176745b6f7e9SBarry Smith PetscFunctionReturn(0); 176845b6f7e9SBarry Smith } 176945b6f7e9SBarry Smith 177045b6f7e9SBarry Smith /*@C 177145b6f7e9SBarry Smith ISLocalToGlobalMappingRestoreBlockIndices - Restore indices obtained with ISLocalToGlobalMappingGetBlockIndices() 177245b6f7e9SBarry Smith 177345b6f7e9SBarry Smith Not Collective 177445b6f7e9SBarry Smith 17754165533cSJose E. Roman Input Parameters: 177645b6f7e9SBarry Smith + ltog - local to global mapping 177745b6f7e9SBarry Smith - array - array of indices 177845b6f7e9SBarry Smith 177945b6f7e9SBarry Smith Level: advanced 178045b6f7e9SBarry Smith 178145b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingGetIndices() 178245b6f7e9SBarry Smith @*/ 178345b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreBlockIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 178445b6f7e9SBarry Smith { 178545b6f7e9SBarry Smith PetscFunctionBegin; 178645b6f7e9SBarry Smith PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 178745b6f7e9SBarry Smith PetscValidPointer(array,2); 178886994e45SJed Brown if (*array != ltog->indices) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Trying to return mismatched pointer"); 17890298fd71SBarry Smith *array = NULL; 179086994e45SJed Brown PetscFunctionReturn(0); 179186994e45SJed Brown } 1792f7efa3c7SJed Brown 1793f7efa3c7SJed Brown /*@C 1794f7efa3c7SJed Brown ISLocalToGlobalMappingConcatenate - Create a new mapping that concatenates a list of mappings 1795f7efa3c7SJed Brown 1796f7efa3c7SJed Brown Not Collective 1797f7efa3c7SJed Brown 17984165533cSJose E. Roman Input Parameters: 1799f7efa3c7SJed Brown + comm - communicator for the new mapping, must contain the communicator of every mapping to concatenate 1800f7efa3c7SJed Brown . n - number of mappings to concatenate 1801f7efa3c7SJed Brown - ltogs - local to global mappings 1802f7efa3c7SJed Brown 18034165533cSJose E. Roman Output Parameter: 1804f7efa3c7SJed Brown . ltogcat - new mapping 1805f7efa3c7SJed Brown 18069d90f715SBarry Smith Note: this currently always returns a mapping with block size of 1 18079d90f715SBarry Smith 18089d90f715SBarry Smith Developer Note: If all the input mapping have the same block size we could easily handle that as a special case 18099d90f715SBarry Smith 1810f7efa3c7SJed Brown Level: advanced 1811f7efa3c7SJed Brown 1812f7efa3c7SJed Brown .seealso: ISLocalToGlobalMappingCreate() 1813f7efa3c7SJed Brown @*/ 1814f7efa3c7SJed Brown PetscErrorCode ISLocalToGlobalMappingConcatenate(MPI_Comm comm,PetscInt n,const ISLocalToGlobalMapping ltogs[],ISLocalToGlobalMapping *ltogcat) 1815f7efa3c7SJed Brown { 1816f7efa3c7SJed Brown PetscInt i,cnt,m,*idx; 1817f7efa3c7SJed Brown PetscErrorCode ierr; 1818f7efa3c7SJed Brown 1819f7efa3c7SJed Brown PetscFunctionBegin; 1820f7efa3c7SJed Brown if (n < 0) SETERRQ1(comm,PETSC_ERR_ARG_OUTOFRANGE,"Must have a non-negative number of mappings, given %D",n); 1821f7efa3c7SJed Brown if (n > 0) PetscValidPointer(ltogs,3); 1822f7efa3c7SJed Brown for (i=0; i<n; i++) PetscValidHeaderSpecific(ltogs[i],IS_LTOGM_CLASSID,3); 1823f7efa3c7SJed Brown PetscValidPointer(ltogcat,4); 1824f7efa3c7SJed Brown for (cnt=0,i=0; i<n; i++) { 1825f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetSize(ltogs[i],&m);CHKERRQ(ierr); 1826f7efa3c7SJed Brown cnt += m; 1827f7efa3c7SJed Brown } 1828785e854fSJed Brown ierr = PetscMalloc1(cnt,&idx);CHKERRQ(ierr); 1829f7efa3c7SJed Brown for (cnt=0,i=0; i<n; i++) { 1830f7efa3c7SJed Brown const PetscInt *subidx; 1831f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetSize(ltogs[i],&m);CHKERRQ(ierr); 1832f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetIndices(ltogs[i],&subidx);CHKERRQ(ierr); 1833580bdb30SBarry Smith ierr = PetscArraycpy(&idx[cnt],subidx,m);CHKERRQ(ierr); 1834f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingRestoreIndices(ltogs[i],&subidx);CHKERRQ(ierr); 1835f7efa3c7SJed Brown cnt += m; 1836f7efa3c7SJed Brown } 1837f0413b6fSBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,1,cnt,idx,PETSC_OWN_POINTER,ltogcat);CHKERRQ(ierr); 1838f7efa3c7SJed Brown PetscFunctionReturn(0); 1839f7efa3c7SJed Brown } 184004a59952SBarry Smith 1841413f72f0SBarry Smith /*MC 1842413f72f0SBarry Smith ISLOCALTOGLOBALMAPPINGBASIC - basic implementation of the ISLocalToGlobalMapping object. When ISGlobalToLocalMappingApply() is 1843413f72f0SBarry Smith used this is good for only small and moderate size problems. 1844413f72f0SBarry Smith 1845413f72f0SBarry Smith Options Database Keys: 1846a2b725a8SWilliam Gropp . -islocaltoglobalmapping_type basic - select this method 1847413f72f0SBarry Smith 1848413f72f0SBarry Smith Level: beginner 1849413f72f0SBarry Smith 1850413f72f0SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingSetType(), ISLOCALTOGLOBALMAPPINGHASH 1851413f72f0SBarry Smith M*/ 1852413f72f0SBarry Smith PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingCreate_Basic(ISLocalToGlobalMapping ltog) 1853413f72f0SBarry Smith { 1854413f72f0SBarry Smith PetscFunctionBegin; 1855413f72f0SBarry Smith ltog->ops->globaltolocalmappingapply = ISGlobalToLocalMappingApply_Basic; 1856413f72f0SBarry Smith ltog->ops->globaltolocalmappingsetup = ISGlobalToLocalMappingSetUp_Basic; 1857413f72f0SBarry Smith ltog->ops->globaltolocalmappingapplyblock = ISGlobalToLocalMappingApplyBlock_Basic; 1858413f72f0SBarry Smith ltog->ops->destroy = ISLocalToGlobalMappingDestroy_Basic; 1859413f72f0SBarry Smith PetscFunctionReturn(0); 1860413f72f0SBarry Smith } 1861413f72f0SBarry Smith 1862413f72f0SBarry Smith /*MC 1863413f72f0SBarry Smith ISLOCALTOGLOBALMAPPINGHASH - hash implementation of the ISLocalToGlobalMapping object. When ISGlobalToLocalMappingApply() is 1864ed56e8eaSBarry Smith used this is good for large memory problems. 1865413f72f0SBarry Smith 1866413f72f0SBarry Smith Options Database Keys: 1867a2b725a8SWilliam Gropp . -islocaltoglobalmapping_type hash - select this method 1868413f72f0SBarry Smith 186995452b02SPatrick Sanan Notes: 187095452b02SPatrick Sanan This is selected automatically for large problems if the user does not set the type. 1871ed56e8eaSBarry Smith 1872413f72f0SBarry Smith Level: beginner 1873413f72f0SBarry Smith 1874413f72f0SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingSetType(), ISLOCALTOGLOBALMAPPINGHASH 1875413f72f0SBarry Smith M*/ 1876413f72f0SBarry Smith PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingCreate_Hash(ISLocalToGlobalMapping ltog) 1877413f72f0SBarry Smith { 1878413f72f0SBarry Smith PetscFunctionBegin; 1879413f72f0SBarry Smith ltog->ops->globaltolocalmappingapply = ISGlobalToLocalMappingApply_Hash; 1880413f72f0SBarry Smith ltog->ops->globaltolocalmappingsetup = ISGlobalToLocalMappingSetUp_Hash; 1881413f72f0SBarry Smith ltog->ops->globaltolocalmappingapplyblock = ISGlobalToLocalMappingApplyBlock_Hash; 1882413f72f0SBarry Smith ltog->ops->destroy = ISLocalToGlobalMappingDestroy_Hash; 1883413f72f0SBarry Smith PetscFunctionReturn(0); 1884413f72f0SBarry Smith } 1885413f72f0SBarry Smith 1886413f72f0SBarry Smith /*@C 1887413f72f0SBarry Smith ISLocalToGlobalMappingRegister - Adds a method for applying a global to local mapping with an ISLocalToGlobalMapping 1888413f72f0SBarry Smith 1889413f72f0SBarry Smith Not Collective 1890413f72f0SBarry Smith 1891413f72f0SBarry Smith Input Parameters: 1892413f72f0SBarry Smith + sname - name of a new method 1893413f72f0SBarry Smith - routine_create - routine to create method context 1894413f72f0SBarry Smith 1895413f72f0SBarry Smith Notes: 1896ed56e8eaSBarry Smith ISLocalToGlobalMappingRegister() may be called multiple times to add several user-defined mappings. 1897413f72f0SBarry Smith 1898413f72f0SBarry Smith Sample usage: 1899413f72f0SBarry Smith .vb 1900413f72f0SBarry Smith ISLocalToGlobalMappingRegister("my_mapper",MyCreate); 1901413f72f0SBarry Smith .ve 1902413f72f0SBarry Smith 1903ed56e8eaSBarry Smith Then, your mapping can be chosen with the procedural interface via 1904413f72f0SBarry Smith $ ISLocalToGlobalMappingSetType(ltog,"my_mapper") 1905413f72f0SBarry Smith or at runtime via the option 1906ed56e8eaSBarry Smith $ -islocaltoglobalmapping_type my_mapper 1907413f72f0SBarry Smith 1908413f72f0SBarry Smith Level: advanced 1909413f72f0SBarry Smith 1910413f72f0SBarry Smith .seealso: ISLocalToGlobalMappingRegisterAll(), ISLocalToGlobalMappingRegisterDestroy(), ISLOCALTOGLOBALMAPPINGBASIC, ISLOCALTOGLOBALMAPPINGHASH 1911413f72f0SBarry Smith 1912413f72f0SBarry Smith @*/ 1913413f72f0SBarry Smith PetscErrorCode ISLocalToGlobalMappingRegister(const char sname[],PetscErrorCode (*function)(ISLocalToGlobalMapping)) 1914413f72f0SBarry Smith { 1915413f72f0SBarry Smith PetscErrorCode ierr; 1916413f72f0SBarry Smith 1917413f72f0SBarry Smith PetscFunctionBegin; 19181d36bdfdSBarry Smith ierr = ISInitializePackage();CHKERRQ(ierr); 1919413f72f0SBarry Smith ierr = PetscFunctionListAdd(&ISLocalToGlobalMappingList,sname,function);CHKERRQ(ierr); 1920413f72f0SBarry Smith PetscFunctionReturn(0); 1921413f72f0SBarry Smith } 1922413f72f0SBarry Smith 1923413f72f0SBarry Smith /*@C 1924ed56e8eaSBarry Smith ISLocalToGlobalMappingSetType - Builds ISLocalToGlobalMapping for a particular global to local mapping approach. 1925413f72f0SBarry Smith 1926413f72f0SBarry Smith Logically Collective on ISLocalToGlobalMapping 1927413f72f0SBarry Smith 1928413f72f0SBarry Smith Input Parameters: 1929413f72f0SBarry Smith + ltog - the ISLocalToGlobalMapping object 1930413f72f0SBarry Smith - type - a known method 1931413f72f0SBarry Smith 1932413f72f0SBarry Smith Options Database Key: 1933ed56e8eaSBarry Smith . -islocaltoglobalmapping_type <method> - Sets the method; use -help for a list 1934413f72f0SBarry Smith of available methods (for instance, basic or hash) 1935413f72f0SBarry Smith 1936413f72f0SBarry Smith Notes: 1937413f72f0SBarry Smith See "petsc/include/petscis.h" for available methods 1938413f72f0SBarry Smith 1939413f72f0SBarry Smith Normally, it is best to use the ISLocalToGlobalMappingSetFromOptions() command and 1940413f72f0SBarry Smith then set the ISLocalToGlobalMapping type from the options database rather than by using 1941413f72f0SBarry Smith this routine. 1942413f72f0SBarry Smith 1943413f72f0SBarry Smith Level: intermediate 1944413f72f0SBarry Smith 1945413f72f0SBarry Smith Developer Note: ISLocalToGlobalMappingRegister() is used to add new types to ISLocalToGlobalMappingList from which they 1946413f72f0SBarry Smith are accessed by ISLocalToGlobalMappingSetType(). 1947413f72f0SBarry Smith 1948413f72f0SBarry Smith .seealso: PCSetType(), ISLocalToGlobalMappingType, ISLocalToGlobalMappingRegister(), ISLocalToGlobalMappingCreate() 1949413f72f0SBarry Smith 1950413f72f0SBarry Smith @*/ 1951413f72f0SBarry Smith PetscErrorCode ISLocalToGlobalMappingSetType(ISLocalToGlobalMapping ltog, ISLocalToGlobalMappingType type) 1952413f72f0SBarry Smith { 1953413f72f0SBarry Smith PetscErrorCode ierr,(*r)(ISLocalToGlobalMapping); 1954413f72f0SBarry Smith PetscBool match; 1955413f72f0SBarry Smith 1956413f72f0SBarry Smith PetscFunctionBegin; 1957413f72f0SBarry Smith PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 1958413f72f0SBarry Smith PetscValidCharPointer(type,2); 1959413f72f0SBarry Smith 1960413f72f0SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)ltog,type,&match);CHKERRQ(ierr); 1961413f72f0SBarry Smith if (match) PetscFunctionReturn(0); 1962413f72f0SBarry Smith 1963413f72f0SBarry Smith ierr = PetscFunctionListFind(ISLocalToGlobalMappingList,type,&r);CHKERRQ(ierr); 1964413f72f0SBarry Smith if (!r) SETERRQ1(PetscObjectComm((PetscObject)ltog),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested ISLocalToGlobalMapping type %s",type); 1965413f72f0SBarry Smith /* Destroy the previous private LTOG context */ 1966413f72f0SBarry Smith if (ltog->ops->destroy) { 1967413f72f0SBarry Smith ierr = (*ltog->ops->destroy)(ltog);CHKERRQ(ierr); 1968413f72f0SBarry Smith ltog->ops->destroy = NULL; 1969413f72f0SBarry Smith } 1970413f72f0SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)ltog,type);CHKERRQ(ierr); 1971413f72f0SBarry Smith ierr = (*r)(ltog);CHKERRQ(ierr); 1972413f72f0SBarry Smith PetscFunctionReturn(0); 1973413f72f0SBarry Smith } 1974413f72f0SBarry Smith 1975413f72f0SBarry Smith PetscBool ISLocalToGlobalMappingRegisterAllCalled = PETSC_FALSE; 1976413f72f0SBarry Smith 1977413f72f0SBarry Smith /*@C 1978413f72f0SBarry Smith ISLocalToGlobalMappingRegisterAll - Registers all of the local to global mapping components in the IS package. 1979413f72f0SBarry Smith 1980413f72f0SBarry Smith Not Collective 1981413f72f0SBarry Smith 1982413f72f0SBarry Smith Level: advanced 1983413f72f0SBarry Smith 1984413f72f0SBarry Smith .seealso: ISRegister(), ISLocalToGlobalRegister() 1985413f72f0SBarry Smith @*/ 1986413f72f0SBarry Smith PetscErrorCode ISLocalToGlobalMappingRegisterAll(void) 1987413f72f0SBarry Smith { 1988413f72f0SBarry Smith PetscErrorCode ierr; 1989413f72f0SBarry Smith 1990413f72f0SBarry Smith PetscFunctionBegin; 1991413f72f0SBarry Smith if (ISLocalToGlobalMappingRegisterAllCalled) PetscFunctionReturn(0); 1992413f72f0SBarry Smith ISLocalToGlobalMappingRegisterAllCalled = PETSC_TRUE; 1993413f72f0SBarry Smith 1994413f72f0SBarry Smith ierr = ISLocalToGlobalMappingRegister(ISLOCALTOGLOBALMAPPINGBASIC, ISLocalToGlobalMappingCreate_Basic);CHKERRQ(ierr); 1995413f72f0SBarry Smith ierr = ISLocalToGlobalMappingRegister(ISLOCALTOGLOBALMAPPINGHASH, ISLocalToGlobalMappingCreate_Hash);CHKERRQ(ierr); 1996413f72f0SBarry Smith PetscFunctionReturn(0); 1997413f72f0SBarry Smith } 1998