xref: /petsc/src/vec/is/utils/isltog.c (revision 2cfcea2917e9827eeaf4fa9c2e8dd75b054ced7b)
10c735eedSKris Buschelman #define PETSCVEC_DLL
22362add9SBarry Smith 
3e1fa1e0fSSatish Balay #include "petscvec.h"   /*I "petscsys.h" I*/
4e090d566SSatish Balay #include "src/vec/is/isimpl.h"    /*I "petscis.h"  I*/
52362add9SBarry Smith 
60c735eedSKris Buschelman PetscCookie PETSCVEC_DLLEXPORT IS_LTOGM_COOKIE = -1;
78e58c17dSMatthew Knepley 
84a2ae208SSatish Balay #undef __FUNCT__
94a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingGetSize"
103b9aefa3SBarry Smith /*@C
113b9aefa3SBarry Smith     ISLocalToGlobalMappingGetSize - Gets the local size of a local to global mapping.
123b9aefa3SBarry Smith 
133b9aefa3SBarry Smith     Not Collective
143b9aefa3SBarry Smith 
153b9aefa3SBarry Smith     Input Parameter:
163b9aefa3SBarry Smith .   ltog - local to global mapping
173b9aefa3SBarry Smith 
183b9aefa3SBarry Smith     Output Parameter:
193b9aefa3SBarry Smith .   n - the number of entries in the local mapping
203b9aefa3SBarry Smith 
213b9aefa3SBarry Smith     Level: advanced
223b9aefa3SBarry Smith 
23273d9f13SBarry Smith     Concepts: mapping^local to global
243b9aefa3SBarry Smith 
253b9aefa3SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate()
263b9aefa3SBarry Smith @*/
270c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingGetSize(ISLocalToGlobalMapping mapping,PetscInt *n)
283b9aefa3SBarry Smith {
293b9aefa3SBarry Smith   PetscFunctionBegin;
304482741eSBarry Smith   PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE,1);
314482741eSBarry Smith   PetscValidIntPointer(n,2);
323b9aefa3SBarry Smith   *n = mapping->n;
333b9aefa3SBarry Smith   PetscFunctionReturn(0);
343b9aefa3SBarry Smith }
353b9aefa3SBarry Smith 
364a2ae208SSatish Balay #undef __FUNCT__
374a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingView"
385a5d4f66SBarry Smith /*@C
395a5d4f66SBarry Smith     ISLocalToGlobalMappingView - View a local to global mapping
405a5d4f66SBarry Smith 
41b9cd556bSLois Curfman McInnes     Not Collective
42b9cd556bSLois Curfman McInnes 
435a5d4f66SBarry Smith     Input Parameters:
443b9aefa3SBarry Smith +   ltog - local to global mapping
453b9aefa3SBarry Smith -   viewer - viewer
465a5d4f66SBarry Smith 
47a997ad1aSLois Curfman McInnes     Level: advanced
48a997ad1aSLois Curfman McInnes 
49273d9f13SBarry Smith     Concepts: mapping^local to global
505a5d4f66SBarry Smith 
515a5d4f66SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate()
525a5d4f66SBarry Smith @*/
530c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingView(ISLocalToGlobalMapping mapping,PetscViewer viewer)
545a5d4f66SBarry Smith {
5532dcc486SBarry Smith   PetscInt        i;
5632dcc486SBarry Smith   PetscMPIInt     rank;
5732077d6dSBarry Smith   PetscTruth      iascii;
586849ba73SBarry Smith   PetscErrorCode  ierr;
595a5d4f66SBarry Smith 
605a5d4f66SBarry Smith   PetscFunctionBegin;
614482741eSBarry Smith   PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE,1);
62b0a32e0cSBarry Smith   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(mapping->comm);
634482741eSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE,2);
645a5d4f66SBarry Smith 
65f1af5d2fSBarry Smith   ierr = MPI_Comm_rank(mapping->comm,&rank);CHKERRQ(ierr);
6632077d6dSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
6732077d6dSBarry Smith   if (iascii) {
685a5d4f66SBarry Smith     for (i=0; i<mapping->n; i++) {
69b0a32e0cSBarry Smith       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] %d %d\n",rank,i,mapping->indices[i]);CHKERRQ(ierr);
706831982aSBarry Smith     }
71b0a32e0cSBarry Smith     ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
726831982aSBarry Smith   } else {
73958c9bccSBarry Smith     SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported for ISLocalToGlobalMapping",((PetscObject)viewer)->type_name);
745a5d4f66SBarry Smith   }
755a5d4f66SBarry Smith 
765a5d4f66SBarry Smith   PetscFunctionReturn(0);
775a5d4f66SBarry Smith }
785a5d4f66SBarry Smith 
794a2ae208SSatish Balay #undef __FUNCT__
804a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreateIS"
811f428162SBarry Smith /*@
822bdab257SBarry Smith     ISLocalToGlobalMappingCreateIS - Creates a mapping between a local (0 to n)
832bdab257SBarry Smith     ordering and a global parallel ordering.
842bdab257SBarry Smith 
850f5bd95cSBarry Smith     Not collective
86b9cd556bSLois Curfman McInnes 
87a997ad1aSLois Curfman McInnes     Input Parameter:
882bdab257SBarry Smith .   is - index set containing the global numbers for each local
892bdab257SBarry Smith 
90a997ad1aSLois Curfman McInnes     Output Parameter:
912bdab257SBarry Smith .   mapping - new mapping data structure
922bdab257SBarry Smith 
93a997ad1aSLois Curfman McInnes     Level: advanced
94a997ad1aSLois Curfman McInnes 
95273d9f13SBarry Smith     Concepts: mapping^local to global
962bdab257SBarry Smith 
972bdab257SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate()
982bdab257SBarry Smith @*/
990c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingCreateIS(IS is,ISLocalToGlobalMapping *mapping)
1002bdab257SBarry Smith {
1016849ba73SBarry Smith   PetscErrorCode ierr;
10232dcc486SBarry Smith   PetscInt      n,*indices;
1032bdab257SBarry Smith   MPI_Comm comm;
1043a40ed3dSBarry Smith 
1053a40ed3dSBarry Smith   PetscFunctionBegin;
1064482741eSBarry Smith   PetscValidHeaderSpecific(is,IS_COOKIE,1);
1074482741eSBarry Smith   PetscValidPointer(mapping,2);
1082bdab257SBarry Smith 
1092bdab257SBarry Smith   ierr = PetscObjectGetComm((PetscObject)is,&comm);CHKERRQ(ierr);
1103b9aefa3SBarry Smith   ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr);
1112bdab257SBarry Smith   ierr = ISGetIndices(is,&indices);CHKERRQ(ierr);
1122bdab257SBarry Smith   ierr = ISLocalToGlobalMappingCreate(comm,n,indices,mapping);CHKERRQ(ierr);
1132bdab257SBarry Smith   ierr = ISRestoreIndices(is,&indices);CHKERRQ(ierr);
1142bdab257SBarry Smith 
1153a40ed3dSBarry Smith   PetscFunctionReturn(0);
1162bdab257SBarry Smith }
1175a5d4f66SBarry Smith 
118b46b645bSBarry Smith 
1194a2ae208SSatish Balay #undef __FUNCT__
1204a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreate"
121ba5bb76aSSatish Balay /*@
12290f02eecSBarry Smith     ISLocalToGlobalMappingCreate - Creates a mapping between a local (0 to n)
12390f02eecSBarry Smith     ordering and a global parallel ordering.
1242362add9SBarry Smith 
12589d82c54SBarry Smith     Not Collective, but communicator may have more than one process
126b9cd556bSLois Curfman McInnes 
1272362add9SBarry Smith     Input Parameters:
12889d82c54SBarry Smith +   comm - MPI communicator
12990f02eecSBarry Smith .   n - the number of local elements
130b9cd556bSLois Curfman McInnes -   indices - the global index for each local element
1312362add9SBarry Smith 
132a997ad1aSLois Curfman McInnes     Output Parameter:
13390f02eecSBarry Smith .   mapping - new mapping data structure
1342362add9SBarry Smith 
135a997ad1aSLois Curfman McInnes     Level: advanced
136a997ad1aSLois Curfman McInnes 
137273d9f13SBarry Smith     Concepts: mapping^local to global
1382362add9SBarry Smith 
139b46b645bSBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreateNC()
1402362add9SBarry Smith @*/
1410c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingCreate(MPI_Comm cm,PetscInt n,const PetscInt indices[],ISLocalToGlobalMapping *mapping)
1422362add9SBarry Smith {
1436849ba73SBarry Smith   PetscErrorCode ierr;
14432dcc486SBarry Smith   PetscInt       *in;
145b46b645bSBarry Smith 
146b46b645bSBarry Smith   PetscFunctionBegin;
1474482741eSBarry Smith   PetscValidIntPointer(indices,3);
1484482741eSBarry Smith   PetscValidPointer(mapping,4);
1497c334f02SBarry Smith   ierr = PetscMalloc(n*sizeof(PetscInt),&in);CHKERRQ(ierr);
15032dcc486SBarry Smith   ierr = PetscMemcpy(in,indices,n*sizeof(PetscInt));CHKERRQ(ierr);
151b46b645bSBarry Smith   ierr = ISLocalToGlobalMappingCreateNC(cm,n,in,mapping);CHKERRQ(ierr);
152b46b645bSBarry Smith   PetscFunctionReturn(0);
153b46b645bSBarry Smith }
154b46b645bSBarry Smith 
155b46b645bSBarry Smith #undef __FUNCT__
156b46b645bSBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingCreateNC"
157b46b645bSBarry Smith /*@C
158b46b645bSBarry Smith     ISLocalToGlobalMappingCreateNC - Creates a mapping between a local (0 to n)
159b46b645bSBarry Smith     ordering and a global parallel ordering.
160b46b645bSBarry Smith 
161b46b645bSBarry Smith     Not Collective, but communicator may have more than one process
162b46b645bSBarry Smith 
163b46b645bSBarry Smith     Input Parameters:
164b46b645bSBarry Smith +   comm - MPI communicator
165b46b645bSBarry Smith .   n - the number of local elements
166b46b645bSBarry Smith -   indices - the global index for each local element
167b46b645bSBarry Smith 
168b46b645bSBarry Smith     Output Parameter:
169b46b645bSBarry Smith .   mapping - new mapping data structure
170b46b645bSBarry Smith 
171b46b645bSBarry Smith     Level: developer
172b46b645bSBarry Smith 
173b46b645bSBarry Smith     Notes: Does not copy the indices, just keeps the pointer to the indices. The ISLocalToGlobalMappingDestroy()
174b46b645bSBarry Smith     will free the space so it must be obtained with PetscMalloc() and it must not be freed elsewhere.
175b46b645bSBarry Smith 
176b46b645bSBarry Smith     Concepts: mapping^local to global
177b46b645bSBarry Smith 
178b46b645bSBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate()
179b46b645bSBarry Smith @*/
1800c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingCreateNC(MPI_Comm cm,PetscInt n,const PetscInt indices[],ISLocalToGlobalMapping *mapping)
181b46b645bSBarry Smith {
182dfbe8321SBarry Smith   PetscErrorCode ierr;
18323f7533aSBarry Smith 
1843a40ed3dSBarry Smith   PetscFunctionBegin;
185f6c9393fSMatthew Knepley   if (n) {
1864482741eSBarry Smith     PetscValidIntPointer(indices,3);
187f6c9393fSMatthew Knepley   }
1884482741eSBarry Smith   PetscValidPointer(mapping,4);
1898e58c17dSMatthew Knepley   *mapping = PETSC_NULL;
1908e58c17dSMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES
19123f7533aSBarry Smith   ierr = VecInitializePackage(PETSC_NULL);CHKERRQ(ierr);
1928e58c17dSMatthew Knepley #endif
19323f7533aSBarry Smith   if (IS_LTOGM_COOKIE == -1) {
19423f7533aSBarry Smith     ierr = PetscLogClassRegister(&IS_LTOGM_COOKIE,"IS Local to global mapping");CHKERRQ(ierr);
19523f7533aSBarry Smith   }
1962362add9SBarry Smith 
19752e6d16bSBarry Smith   ierr = PetscHeaderCreate(*mapping,_p_ISLocalToGlobalMapping,int,IS_LTOGM_COOKIE,0,"ISLocalToGlobalMapping",
19852e6d16bSBarry Smith                     cm,ISLocalToGlobalMappingDestroy,ISLocalToGlobalMappingView);CHKERRQ(ierr);
19952e6d16bSBarry Smith   ierr = PetscLogObjectMemory(*mapping,sizeof(struct _p_ISLocalToGlobalMapping)+n*sizeof(PetscInt));CHKERRQ(ierr);
200d4bb536fSBarry Smith 
201d4bb536fSBarry Smith   (*mapping)->n       = n;
20232dcc486SBarry Smith   (*mapping)->indices = (PetscInt*)indices;
203d4bb536fSBarry Smith 
204d4bb536fSBarry Smith   /*
205d4bb536fSBarry Smith       Do not create the global to local mapping. This is only created if
206d4bb536fSBarry Smith      ISGlobalToLocalMapping() is called
207d4bb536fSBarry Smith   */
208d4bb536fSBarry Smith   (*mapping)->globals = 0;
2093a40ed3dSBarry Smith   PetscFunctionReturn(0);
2102362add9SBarry Smith }
2112362add9SBarry Smith 
2124a2ae208SSatish Balay #undef __FUNCT__
2134a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingBlock"
214bce096a4SSatish Balay /*@
215323b833fSBarry Smith     ISLocalToGlobalMappingBlock - Creates a blocked index version of an
216323b833fSBarry Smith        ISLocalToGlobalMapping that is appropriate for MatSetLocalToGlobalMappingBlock()
217323b833fSBarry Smith        and VecSetLocalToGlobalMappingBlock().
218323b833fSBarry Smith 
219323b833fSBarry Smith     Not Collective, but communicator may have more than one process
220323b833fSBarry Smith 
221323b833fSBarry Smith     Input Parameters:
222323b833fSBarry Smith +    inmap - original point-wise mapping
223323b833fSBarry Smith -    bs - block size
224323b833fSBarry Smith 
225323b833fSBarry Smith     Output Parameter:
22669eb54c3SBarry Smith .   outmap - block based mapping; the indices are relative to BLOCKS, not individual vector or matrix entries.
227323b833fSBarry Smith 
228323b833fSBarry Smith     Level: advanced
229323b833fSBarry Smith 
230323b833fSBarry Smith     Concepts: mapping^local to global
231323b833fSBarry Smith 
232323b833fSBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingCreateIS()
233323b833fSBarry Smith @*/
2340c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingBlock(ISLocalToGlobalMapping inmap,PetscInt bs,ISLocalToGlobalMapping *outmap)
235323b833fSBarry Smith {
2366849ba73SBarry Smith   PetscErrorCode ierr;
23732dcc486SBarry Smith   PetscInt       *ii,i,n;
238323b833fSBarry Smith 
239323b833fSBarry Smith   PetscFunctionBegin;
240323b833fSBarry Smith   if (bs > 1) {
241323b833fSBarry Smith     n    = inmap->n/bs;
24212ce3465SBarry Smith     if (n*bs != inmap->n) SETERRQ(PETSC_ERR_ARG_INCOMP,"Pointwise mapping length is not divisible by block size");
24332dcc486SBarry Smith     ierr = PetscMalloc(n*sizeof(PetscInt),&ii);CHKERRQ(ierr);
244323b833fSBarry Smith     for (i=0; i<n; i++) {
245db032c9dSBarry Smith       ii[i] = inmap->indices[bs*i]/bs;
246323b833fSBarry Smith     }
247323b833fSBarry Smith     ierr = ISLocalToGlobalMappingCreate(inmap->comm,n,ii,outmap);CHKERRQ(ierr);
248323b833fSBarry Smith     ierr = PetscFree(ii);CHKERRQ(ierr);
249323b833fSBarry Smith   } else {
250323b833fSBarry Smith     *outmap = inmap;
251323b833fSBarry Smith     ierr    = PetscObjectReference((PetscObject)inmap);CHKERRQ(ierr);
252323b833fSBarry Smith   }
253323b833fSBarry Smith   PetscFunctionReturn(0);
254323b833fSBarry Smith }
255323b833fSBarry Smith 
2564a2ae208SSatish Balay #undef __FUNCT__
2574a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingDestroy"
25890f02eecSBarry Smith /*@
25990f02eecSBarry Smith    ISLocalToGlobalMappingDestroy - Destroys a mapping between a local (0 to n)
26090f02eecSBarry Smith    ordering and a global parallel ordering.
26190f02eecSBarry Smith 
2620f5bd95cSBarry Smith    Note Collective
263b9cd556bSLois Curfman McInnes 
26490f02eecSBarry Smith    Input Parameters:
26590f02eecSBarry Smith .  mapping - mapping data structure
26690f02eecSBarry Smith 
267a997ad1aSLois Curfman McInnes    Level: advanced
268a997ad1aSLois Curfman McInnes 
2693acfe500SLois Curfman McInnes .seealso: ISLocalToGlobalMappingCreate()
27090f02eecSBarry Smith @*/
2710c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping mapping)
27290f02eecSBarry Smith {
273dfbe8321SBarry Smith   PetscErrorCode ierr;
2743a40ed3dSBarry Smith   PetscFunctionBegin;
2754482741eSBarry Smith   PetscValidPointer(mapping,1);
2763a40ed3dSBarry Smith   if (--mapping->refct > 0) PetscFunctionReturn(0);
27785614651SBarry Smith   if (mapping->refct < 0) {
278634064b4SBarry Smith     SETERRQ(PETSC_ERR_PLIB,"Mapping already destroyed");
27985614651SBarry Smith   }
28090f02eecSBarry Smith 
281606d414cSSatish Balay   ierr = PetscFree(mapping->indices);CHKERRQ(ierr);
28205b42c5fSBarry Smith   ierr = PetscFree(mapping->globals);CHKERRQ(ierr);
283d38fa0fbSBarry Smith   ierr = PetscHeaderDestroy(mapping);CHKERRQ(ierr);
2843a40ed3dSBarry Smith   PetscFunctionReturn(0);
28590f02eecSBarry Smith }
28690f02eecSBarry Smith 
2874a2ae208SSatish Balay #undef __FUNCT__
2884a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingApplyIS"
28990f02eecSBarry Smith /*@
2903acfe500SLois Curfman McInnes     ISLocalToGlobalMappingApplyIS - Creates from an IS in the local numbering
2913acfe500SLois Curfman McInnes     a new index set using the global numbering defined in an ISLocalToGlobalMapping
2923acfe500SLois Curfman McInnes     context.
29390f02eecSBarry Smith 
294b9cd556bSLois Curfman McInnes     Not collective
295b9cd556bSLois Curfman McInnes 
29690f02eecSBarry Smith     Input Parameters:
297b9cd556bSLois Curfman McInnes +   mapping - mapping between local and global numbering
298b9cd556bSLois Curfman McInnes -   is - index set in local numbering
29990f02eecSBarry Smith 
30090f02eecSBarry Smith     Output Parameters:
30190f02eecSBarry Smith .   newis - index set in global numbering
30290f02eecSBarry Smith 
303a997ad1aSLois Curfman McInnes     Level: advanced
304a997ad1aSLois Curfman McInnes 
305273d9f13SBarry Smith     Concepts: mapping^local to global
3063acfe500SLois Curfman McInnes 
30790f02eecSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(),
308d4bb536fSBarry Smith           ISLocalToGlobalMappingDestroy(), ISGlobalToLocalMappingApply()
30990f02eecSBarry Smith @*/
3100c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping,IS is,IS *newis)
31190f02eecSBarry Smith {
3126849ba73SBarry Smith   PetscErrorCode ierr;
31332dcc486SBarry Smith   PetscInt            n,i,*idxin,*idxmap,*idxout,Nmax = mapping->n;
3143a40ed3dSBarry Smith 
3153a40ed3dSBarry Smith   PetscFunctionBegin;
3164482741eSBarry Smith   PetscValidPointer(mapping,1);
3174482741eSBarry Smith   PetscValidHeaderSpecific(is,IS_COOKIE,2);
3184482741eSBarry Smith   PetscValidPointer(newis,3);
31990f02eecSBarry Smith 
3203b9aefa3SBarry Smith   ierr   = ISGetLocalSize(is,&n);CHKERRQ(ierr);
32190f02eecSBarry Smith   ierr   = ISGetIndices(is,&idxin);CHKERRQ(ierr);
32290f02eecSBarry Smith   idxmap = mapping->indices;
32390f02eecSBarry Smith 
3247c334f02SBarry Smith   ierr = PetscMalloc(n*sizeof(PetscInt),&idxout);CHKERRQ(ierr);
32590f02eecSBarry Smith   for (i=0; i<n; i++) {
326590ac198SBarry Smith     if (idxin[i] >= Nmax) SETERRQ3(PETSC_ERR_ARG_OUTOFRANGE,"Local index %d too large %d (max) at %d",idxin[i],Nmax-1,i);
32790f02eecSBarry Smith     idxout[i] = idxmap[idxin[i]];
32890f02eecSBarry Smith   }
3293b9aefa3SBarry Smith   ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr);
330029af93fSBarry Smith   ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxout,newis);CHKERRQ(ierr);
331606d414cSSatish Balay   ierr = PetscFree(idxout);CHKERRQ(ierr);
3323a40ed3dSBarry Smith   PetscFunctionReturn(0);
33390f02eecSBarry Smith }
33490f02eecSBarry Smith 
33589d82c54SBarry Smith /*MC
3363acfe500SLois Curfman McInnes    ISLocalToGlobalMappingApply - Takes a list of integers in a local numbering
3373acfe500SLois Curfman McInnes    and converts them to the global numbering.
33890f02eecSBarry Smith 
339b9cd556bSLois Curfman McInnes    Not collective
340b9cd556bSLois Curfman McInnes 
341bb25748dSBarry Smith    Input Parameters:
342b9cd556bSLois Curfman McInnes +  mapping - the local to global mapping context
343bb25748dSBarry Smith .  N - number of integers
344b9cd556bSLois Curfman McInnes -  in - input indices in local numbering
345bb25748dSBarry Smith 
346bb25748dSBarry Smith    Output Parameter:
347bb25748dSBarry Smith .  out - indices in global numbering
348bb25748dSBarry Smith 
3493b9aefa3SBarry Smith    Synopsis:
350d360dc6fSBarry Smith    PetscErrorCode ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping,int N,int in[],int out[])
3513b9aefa3SBarry Smith 
352b9cd556bSLois Curfman McInnes    Notes:
353b9cd556bSLois Curfman McInnes    The in and out array parameters may be identical.
354d4bb536fSBarry Smith 
355a997ad1aSLois Curfman McInnes    Level: advanced
356a997ad1aSLois Curfman McInnes 
357bb25748dSBarry Smith .seealso: ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(),
3580752156aSBarry Smith           ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(),
359d4bb536fSBarry Smith           AOPetscToApplication(), ISGlobalToLocalMappingApply()
360bb25748dSBarry Smith 
361273d9f13SBarry Smith     Concepts: mapping^local to global
362d4bb536fSBarry Smith 
36389d82c54SBarry Smith M*/
364d4bb536fSBarry Smith 
365d4bb536fSBarry Smith /* -----------------------------------------------------------------------------------------*/
366d4bb536fSBarry Smith 
3674a2ae208SSatish Balay #undef __FUNCT__
3684a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingSetUp_Private"
369d4bb536fSBarry Smith /*
370d4bb536fSBarry Smith     Creates the global fields in the ISLocalToGlobalMapping structure
371d4bb536fSBarry Smith */
3726849ba73SBarry Smith static PetscErrorCode ISGlobalToLocalMappingSetUp_Private(ISLocalToGlobalMapping mapping)
373d4bb536fSBarry Smith {
3746849ba73SBarry Smith   PetscErrorCode ierr;
37532dcc486SBarry Smith   PetscInt            i,*idx = mapping->indices,n = mapping->n,end,start,*globals;
376d4bb536fSBarry Smith 
3773a40ed3dSBarry Smith   PetscFunctionBegin;
378d4bb536fSBarry Smith   end   = 0;
379d4bb536fSBarry Smith   start = 100000000;
380d4bb536fSBarry Smith 
381d4bb536fSBarry Smith   for (i=0; i<n; i++) {
382d4bb536fSBarry Smith     if (idx[i] < 0) continue;
383d4bb536fSBarry Smith     if (idx[i] < start) start = idx[i];
384d4bb536fSBarry Smith     if (idx[i] > end)   end   = idx[i];
385d4bb536fSBarry Smith   }
386d4bb536fSBarry Smith   if (start > end) {start = 0; end = -1;}
387d4bb536fSBarry Smith   mapping->globalstart = start;
388d4bb536fSBarry Smith   mapping->globalend   = end;
389d4bb536fSBarry Smith 
39032dcc486SBarry Smith   ierr             = PetscMalloc((end-start+2)*sizeof(PetscInt),&globals);CHKERRQ(ierr);
391b0a32e0cSBarry Smith   mapping->globals = globals;
392d4bb536fSBarry Smith   for (i=0; i<end-start+1; i++) {
393d4bb536fSBarry Smith     globals[i] = -1;
394d4bb536fSBarry Smith   }
395d4bb536fSBarry Smith   for (i=0; i<n; i++) {
396d4bb536fSBarry Smith     if (idx[i] < 0) continue;
397d4bb536fSBarry Smith     globals[idx[i] - start] = i;
398d4bb536fSBarry Smith   }
399d4bb536fSBarry Smith 
40052e6d16bSBarry Smith   ierr = PetscLogObjectMemory(mapping,(end-start+1)*sizeof(PetscInt));CHKERRQ(ierr);
4013a40ed3dSBarry Smith   PetscFunctionReturn(0);
402d4bb536fSBarry Smith }
403d4bb536fSBarry Smith 
4044a2ae208SSatish Balay #undef __FUNCT__
4054a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingApply"
406d4bb536fSBarry Smith /*@
407a997ad1aSLois Curfman McInnes     ISGlobalToLocalMappingApply - Provides the local numbering for a list of integers
408a997ad1aSLois Curfman McInnes     specified with a global numbering.
409d4bb536fSBarry Smith 
410b9cd556bSLois Curfman McInnes     Not collective
411b9cd556bSLois Curfman McInnes 
412d4bb536fSBarry Smith     Input Parameters:
413b9cd556bSLois Curfman McInnes +   mapping - mapping between local and global numbering
414d4bb536fSBarry Smith .   type - IS_GTOLM_MASK - replaces global indices with no local value with -1
415d4bb536fSBarry Smith            IS_GTOLM_DROP - drops the indices with no local value from the output list
416d4bb536fSBarry Smith .   n - number of global indices to map
417b9cd556bSLois Curfman McInnes -   idx - global indices to map
418d4bb536fSBarry Smith 
419d4bb536fSBarry Smith     Output Parameters:
420b9cd556bSLois Curfman McInnes +   nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n)
421b9cd556bSLois Curfman McInnes -   idxout - local index of each global index, one must pass in an array long enough
422e182c471SBarry Smith              to hold all the indices. You can call ISGlobalToLocalMappingApply() with
423e182c471SBarry Smith              idxout == PETSC_NULL to determine the required length (returned in nout)
424e182c471SBarry Smith              and then allocate the required space and call ISGlobalToLocalMappingApply()
425e182c471SBarry Smith              a second time to set the values.
426d4bb536fSBarry Smith 
427b9cd556bSLois Curfman McInnes     Notes:
428b9cd556bSLois Curfman McInnes     Either nout or idxout may be PETSC_NULL. idx and idxout may be identical.
429d4bb536fSBarry Smith 
4300f5bd95cSBarry Smith     This is not scalable in memory usage. Each processor requires O(Nglobal) size
4310f5bd95cSBarry Smith     array to compute these.
4320f5bd95cSBarry Smith 
433a997ad1aSLois Curfman McInnes     Level: advanced
434a997ad1aSLois Curfman McInnes 
435273d9f13SBarry Smith     Concepts: mapping^global to local
436d4bb536fSBarry Smith 
437d4bb536fSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(),
438d4bb536fSBarry Smith           ISLocalToGlobalMappingDestroy()
439d4bb536fSBarry Smith @*/
4400c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type,
44132dcc486SBarry Smith                                   PetscInt n,const PetscInt idx[],PetscInt *nout,PetscInt idxout[])
442d4bb536fSBarry Smith {
44332dcc486SBarry Smith   PetscInt i,*globals,nf = 0,tmp,start,end;
4446849ba73SBarry Smith   PetscErrorCode ierr;
445d4bb536fSBarry Smith 
4463a40ed3dSBarry Smith   PetscFunctionBegin;
447d4bb536fSBarry Smith   if (!mapping->globals) {
448d4bb536fSBarry Smith     ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr);
449d4bb536fSBarry Smith   }
450d4bb536fSBarry Smith   globals = mapping->globals;
451d4bb536fSBarry Smith   start   = mapping->globalstart;
452d4bb536fSBarry Smith   end     = mapping->globalend;
453d4bb536fSBarry Smith 
454d4bb536fSBarry Smith   if (type == IS_GTOLM_MASK) {
455d4bb536fSBarry Smith     if (idxout) {
456d4bb536fSBarry Smith       for (i=0; i<n; i++) {
457d4bb536fSBarry Smith         if (idx[i] < 0) idxout[i] = idx[i];
458d4bb536fSBarry Smith         else if (idx[i] < start) idxout[i] = -1;
459d4bb536fSBarry Smith         else if (idx[i] > end)   idxout[i] = -1;
460d4bb536fSBarry Smith         else                     idxout[i] = globals[idx[i] - start];
461d4bb536fSBarry Smith       }
462d4bb536fSBarry Smith     }
463d4bb536fSBarry Smith     if (nout) *nout = n;
464d4bb536fSBarry Smith   } else {
465d4bb536fSBarry Smith     if (idxout) {
466d4bb536fSBarry Smith       for (i=0; i<n; i++) {
467d4bb536fSBarry Smith         if (idx[i] < 0) continue;
468d4bb536fSBarry Smith         if (idx[i] < start) continue;
469d4bb536fSBarry Smith         if (idx[i] > end) continue;
470d4bb536fSBarry Smith         tmp = globals[idx[i] - start];
471d4bb536fSBarry Smith         if (tmp < 0) continue;
472d4bb536fSBarry Smith         idxout[nf++] = tmp;
473d4bb536fSBarry Smith       }
474d4bb536fSBarry Smith     } else {
475d4bb536fSBarry Smith       for (i=0; i<n; i++) {
476d4bb536fSBarry Smith         if (idx[i] < 0) continue;
477d4bb536fSBarry Smith         if (idx[i] < start) continue;
478d4bb536fSBarry Smith         if (idx[i] > end) continue;
479d4bb536fSBarry Smith         tmp = globals[idx[i] - start];
480d4bb536fSBarry Smith         if (tmp < 0) continue;
481d4bb536fSBarry Smith         nf++;
482d4bb536fSBarry Smith       }
483d4bb536fSBarry Smith     }
484d4bb536fSBarry Smith     if (nout) *nout = nf;
485d4bb536fSBarry Smith   }
486d4bb536fSBarry Smith 
4873a40ed3dSBarry Smith   PetscFunctionReturn(0);
488d4bb536fSBarry Smith }
48990f02eecSBarry Smith 
4904a2ae208SSatish Balay #undef __FUNCT__
4914a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingGetInfo"
49289d82c54SBarry Smith /*@C
49389d82c54SBarry Smith     ISLocalToGlobalMappingGetInfo - Gets the neighbor information for each processor and
49489d82c54SBarry Smith      each index shared by more than one processor
49589d82c54SBarry Smith 
49689d82c54SBarry Smith     Collective on ISLocalToGlobalMapping
49789d82c54SBarry Smith 
49889d82c54SBarry Smith     Input Parameters:
49989d82c54SBarry Smith .   mapping - the mapping from local to global indexing
50089d82c54SBarry Smith 
50189d82c54SBarry Smith     Output Parameter:
50289d82c54SBarry Smith +   nproc - number of processors that are connected to this one
50389d82c54SBarry Smith .   proc - neighboring processors
50407b52d57SBarry Smith .   numproc - number of indices for each subdomain (processor)
50507b52d57SBarry Smith -   indices - indices of local nodes shared with neighbor (sorted by global numbering)
50689d82c54SBarry Smith 
50789d82c54SBarry Smith     Level: advanced
50889d82c54SBarry Smith 
509273d9f13SBarry Smith     Concepts: mapping^local to global
51089d82c54SBarry Smith 
511*2cfcea29SBarry Smith     Fortran Usage:
512*2cfcea29SBarry Smith $        ISLocalToGlobalMpngGetInfoSize(ISLocalToGlobalMapping,PetscInt nproc,PetscInt numprocmax,ierr) followed by
513*2cfcea29SBarry Smith $        ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping,PetscInt nproc, PetscInt procs[nproc],PetscInt numprocs[nproc],
514*2cfcea29SBarry Smith           PetscInt indices[nproc][numprocmax],ierr)
515*2cfcea29SBarry Smith         There is no ISLocalToGlobalMappingRestoreInfo() in Fortran. You must make sure that procs[], numprocs[] and
516*2cfcea29SBarry Smith         indices[][] are large enough arrays, either by allocating them dynamically or defining static ones large enough.
517*2cfcea29SBarry Smith 
518*2cfcea29SBarry Smith 
51907b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(),
52007b52d57SBarry Smith           ISLocalToGlobalMappingRestoreInfo()
52189d82c54SBarry Smith @*/
5220c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[])
52389d82c54SBarry Smith {
5246849ba73SBarry Smith   PetscErrorCode ierr;
52597f1f81fSBarry Smith   PetscMPIInt    size,rank,tag1,tag2,tag3,*len,*source,imdex;
52632dcc486SBarry Smith   PetscInt       i,n = mapping->n,Ng,ng,max = 0,*lindices = mapping->indices;
52732dcc486SBarry Smith   PetscInt       *nprocs,*owner,nsends,*sends,j,*starts,nmax,nrecvs,*recvs,proc;
52897f1f81fSBarry Smith   PetscInt       cnt,scale,*ownedsenders,*nownedsenders,rstart,nowned;
52932dcc486SBarry Smith   PetscInt       node,nownedm,nt,*sends2,nsends2,*starts2,*lens2,*dest,nrecvs2,*starts3,*recvs2,k,*bprocs,*tmp;
53032dcc486SBarry Smith   PetscInt       first_procs,first_numprocs,*first_indices;
53189d82c54SBarry Smith   MPI_Request    *recv_waits,*send_waits;
53230dcb7c9SBarry Smith   MPI_Status     recv_status,*send_status,*recv_statuses;
53389d82c54SBarry Smith   MPI_Comm       comm = mapping->comm;
53407b52d57SBarry Smith   PetscTruth     debug = PETSC_FALSE;
53589d82c54SBarry Smith 
53689d82c54SBarry Smith   PetscFunctionBegin;
53724cf384cSBarry Smith   ierr   = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
53824cf384cSBarry Smith   ierr   = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
53924cf384cSBarry Smith   if (size == 1) {
54024cf384cSBarry Smith     *nproc         = 0;
54124cf384cSBarry Smith     *procs         = PETSC_NULL;
54232dcc486SBarry Smith     ierr           = PetscMalloc(sizeof(PetscInt),numprocs);CHKERRQ(ierr);
5431e2105dcSBarry Smith     (*numprocs)[0] = 0;
54432dcc486SBarry Smith     ierr           = PetscMalloc(sizeof(PetscInt*),indices);CHKERRQ(ierr);
5451e2105dcSBarry Smith     (*indices)[0]  = PETSC_NULL;
54624cf384cSBarry Smith     PetscFunctionReturn(0);
54724cf384cSBarry Smith   }
54824cf384cSBarry Smith 
549b0a32e0cSBarry Smith   ierr = PetscOptionsHasName(PETSC_NULL,"-islocaltoglobalmappinggetinfo_debug",&debug);CHKERRQ(ierr);
55007b52d57SBarry Smith 
5513677ff5aSBarry Smith   /*
5523677ff5aSBarry Smith     Notes on ISLocalToGlobalMappingGetInfo
5533677ff5aSBarry Smith 
5543677ff5aSBarry Smith     globally owned node - the nodes that have been assigned to this processor in global
5553677ff5aSBarry Smith            numbering, just for this routine.
5563677ff5aSBarry Smith 
5573677ff5aSBarry Smith     nontrivial globally owned node - node assigned to this processor that is on a subdomain
5583677ff5aSBarry Smith            boundary (i.e. is has more than one local owner)
5593677ff5aSBarry Smith 
5603677ff5aSBarry Smith     locally owned node - node that exists on this processors subdomain
5613677ff5aSBarry Smith 
5623677ff5aSBarry Smith     nontrivial locally owned node - node that is not in the interior (i.e. has more than one
5633677ff5aSBarry Smith            local subdomain
5643677ff5aSBarry Smith   */
56524cf384cSBarry Smith   ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag1);CHKERRQ(ierr);
56624cf384cSBarry Smith   ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag2);CHKERRQ(ierr);
56724cf384cSBarry Smith   ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag3);CHKERRQ(ierr);
56889d82c54SBarry Smith 
56989d82c54SBarry Smith   for (i=0; i<n; i++) {
57089d82c54SBarry Smith     if (lindices[i] > max) max = lindices[i];
57189d82c54SBarry Smith   }
57232dcc486SBarry Smith   ierr   = MPI_Allreduce(&max,&Ng,1,MPIU_INT,MPI_MAX,comm);CHKERRQ(ierr);
57378058e43SBarry Smith   Ng++;
57489d82c54SBarry Smith   ierr   = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
57589d82c54SBarry Smith   ierr   = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
576bc8ff85bSBarry Smith   scale  = Ng/size + 1;
577a2e34c3dSBarry Smith   ng     = scale; if (rank == size-1) ng = Ng - scale*(size-1); ng = PetscMax(1,ng);
578caba0dd0SBarry Smith   rstart = scale*rank;
57989d82c54SBarry Smith 
58089d82c54SBarry Smith   /* determine ownership ranges of global indices */
5817c334f02SBarry Smith   ierr = PetscMalloc(2*size*sizeof(PetscInt),&nprocs);CHKERRQ(ierr);
58232dcc486SBarry Smith   ierr = PetscMemzero(nprocs,2*size*sizeof(PetscInt));CHKERRQ(ierr);
58389d82c54SBarry Smith 
58489d82c54SBarry Smith   /* determine owners of each local node  */
5857c334f02SBarry Smith   ierr = PetscMalloc(n*sizeof(PetscInt),&owner);CHKERRQ(ierr);
58689d82c54SBarry Smith   for (i=0; i<n; i++) {
5873677ff5aSBarry Smith     proc             = lindices[i]/scale; /* processor that globally owns this index */
58827c402fcSBarry Smith     nprocs[2*proc+1] = 1;                 /* processor globally owns at least one of ours */
5893677ff5aSBarry Smith     owner[i]         = proc;
59027c402fcSBarry Smith     nprocs[2*proc]++;                     /* count of how many that processor globally owns of ours */
59189d82c54SBarry Smith   }
59227c402fcSBarry Smith   nsends = 0; for (i=0; i<size; i++) nsends += nprocs[2*i+1];
593ae15b995SBarry Smith   ierr = PetscInfo1(0,"Number of global owners for my local data %d\n",nsends);CHKERRQ(ierr);
59489d82c54SBarry Smith 
59589d82c54SBarry Smith   /* inform other processors of number of messages and max length*/
59627c402fcSBarry Smith   ierr = PetscMaxSum(comm,nprocs,&nmax,&nrecvs);CHKERRQ(ierr);
597ae15b995SBarry Smith   ierr = PetscInfo1(0,"Number of local owners for my global data %d\n",nrecvs);CHKERRQ(ierr);
59889d82c54SBarry Smith 
59989d82c54SBarry Smith   /* post receives for owned rows */
60032dcc486SBarry Smith   ierr = PetscMalloc((2*nrecvs+1)*(nmax+1)*sizeof(PetscInt),&recvs);CHKERRQ(ierr);
601b0a32e0cSBarry Smith   ierr = PetscMalloc((nrecvs+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr);
60289d82c54SBarry Smith   for (i=0; i<nrecvs; i++) {
60332dcc486SBarry Smith     ierr = MPI_Irecv(recvs+2*nmax*i,2*nmax,MPIU_INT,MPI_ANY_SOURCE,tag1,comm,recv_waits+i);CHKERRQ(ierr);
60489d82c54SBarry Smith   }
60589d82c54SBarry Smith 
60689d82c54SBarry Smith   /* pack messages containing lists of local nodes to owners */
60732dcc486SBarry Smith   ierr       = PetscMalloc((2*n+1)*sizeof(PetscInt),&sends);CHKERRQ(ierr);
60832dcc486SBarry Smith   ierr       = PetscMalloc((size+1)*sizeof(PetscInt),&starts);CHKERRQ(ierr);
60989d82c54SBarry Smith   starts[0]  = 0;
61027c402fcSBarry Smith   for (i=1; i<size; i++) { starts[i] = starts[i-1] + 2*nprocs[2*i-2];}
61189d82c54SBarry Smith   for (i=0; i<n; i++) {
61289d82c54SBarry Smith     sends[starts[owner[i]]++] = lindices[i];
61330dcb7c9SBarry Smith     sends[starts[owner[i]]++] = i;
61489d82c54SBarry Smith   }
61589d82c54SBarry Smith   ierr = PetscFree(owner);CHKERRQ(ierr);
61689d82c54SBarry Smith   starts[0]  = 0;
61727c402fcSBarry Smith   for (i=1; i<size; i++) { starts[i] = starts[i-1] + 2*nprocs[2*i-2];}
61889d82c54SBarry Smith 
61989d82c54SBarry Smith   /* send the messages */
620b0a32e0cSBarry Smith   ierr = PetscMalloc((nsends+1)*sizeof(MPI_Request),&send_waits);CHKERRQ(ierr);
62132dcc486SBarry Smith   ierr = PetscMalloc((nsends+1)*sizeof(PetscInt),&dest);CHKERRQ(ierr);
62289d82c54SBarry Smith   cnt = 0;
62389d82c54SBarry Smith   for (i=0; i<size; i++) {
62427c402fcSBarry Smith     if (nprocs[2*i]) {
62532dcc486SBarry Smith       ierr      = MPI_Isend(sends+starts[i],2*nprocs[2*i],MPIU_INT,i,tag1,comm,send_waits+cnt);CHKERRQ(ierr);
62630dcb7c9SBarry Smith       dest[cnt] = i;
62789d82c54SBarry Smith       cnt++;
62889d82c54SBarry Smith     }
62989d82c54SBarry Smith   }
63089d82c54SBarry Smith   ierr = PetscFree(starts);CHKERRQ(ierr);
63189d82c54SBarry Smith 
63289d82c54SBarry Smith   /* wait on receives */
63397f1f81fSBarry Smith   ierr = PetscMalloc((nrecvs+1)*sizeof(PetscMPIInt),&source);CHKERRQ(ierr);
63497f1f81fSBarry Smith   ierr = PetscMalloc((nrecvs+1)*sizeof(PetscMPIInt),&len);CHKERRQ(ierr);
63589d82c54SBarry Smith   cnt  = nrecvs;
63632dcc486SBarry Smith   ierr = PetscMalloc((ng+1)*sizeof(PetscInt),&nownedsenders);CHKERRQ(ierr);
63732dcc486SBarry Smith   ierr = PetscMemzero(nownedsenders,ng*sizeof(PetscInt));CHKERRQ(ierr);
63889d82c54SBarry Smith   while (cnt) {
63989d82c54SBarry Smith     ierr = MPI_Waitany(nrecvs,recv_waits,&imdex,&recv_status);CHKERRQ(ierr);
64089d82c54SBarry Smith     /* unpack receives into our local space */
64132dcc486SBarry Smith     ierr           = MPI_Get_count(&recv_status,MPIU_INT,&len[imdex]);CHKERRQ(ierr);
64289d82c54SBarry Smith     source[imdex]  = recv_status.MPI_SOURCE;
64330dcb7c9SBarry Smith     len[imdex]     = len[imdex]/2;
644caba0dd0SBarry Smith     /* count how many local owners for each of my global owned indices */
64530dcb7c9SBarry Smith     for (i=0; i<len[imdex]; i++) nownedsenders[recvs[2*imdex*nmax+2*i]-rstart]++;
64689d82c54SBarry Smith     cnt--;
64789d82c54SBarry Smith   }
64889d82c54SBarry Smith   ierr = PetscFree(recv_waits);CHKERRQ(ierr);
64989d82c54SBarry Smith 
65030dcb7c9SBarry Smith   /* count how many globally owned indices are on an edge multiplied by how many processors own them. */
651bc8ff85bSBarry Smith   nowned  = 0;
652bc8ff85bSBarry Smith   nownedm = 0;
653bc8ff85bSBarry Smith   for (i=0; i<ng; i++) {
654bc8ff85bSBarry Smith     if (nownedsenders[i] > 1) {nownedm += nownedsenders[i]; nowned++;}
655bc8ff85bSBarry Smith   }
656bc8ff85bSBarry Smith 
657bc8ff85bSBarry Smith   /* create single array to contain rank of all local owners of each globally owned index */
65832dcc486SBarry Smith   ierr      = PetscMalloc((nownedm+1)*sizeof(PetscInt),&ownedsenders);CHKERRQ(ierr);
65932dcc486SBarry Smith   ierr      = PetscMalloc((ng+1)*sizeof(PetscInt),&starts);CHKERRQ(ierr);
660bc8ff85bSBarry Smith   starts[0] = 0;
661bc8ff85bSBarry Smith   for (i=1; i<ng; i++) {
662bc8ff85bSBarry Smith     if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1];
663bc8ff85bSBarry Smith     else starts[i] = starts[i-1];
664bc8ff85bSBarry Smith   }
665bc8ff85bSBarry Smith 
66630dcb7c9SBarry Smith   /* for each nontrival globally owned node list all arriving processors */
667bc8ff85bSBarry Smith   for (i=0; i<nrecvs; i++) {
668bc8ff85bSBarry Smith     for (j=0; j<len[i]; j++) {
66930dcb7c9SBarry Smith       node = recvs[2*i*nmax+2*j]-rstart;
670bc8ff85bSBarry Smith       if (nownedsenders[node] > 1) {
671bc8ff85bSBarry Smith         ownedsenders[starts[node]++] = source[i];
672bc8ff85bSBarry Smith       }
673bc8ff85bSBarry Smith     }
674bc8ff85bSBarry Smith   }
675bc8ff85bSBarry Smith 
67607b52d57SBarry Smith   if (debug) { /* -----------------------------------  */
67730dcb7c9SBarry Smith     starts[0]    = 0;
67830dcb7c9SBarry Smith     for (i=1; i<ng; i++) {
67930dcb7c9SBarry Smith       if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1];
68030dcb7c9SBarry Smith       else starts[i] = starts[i-1];
68130dcb7c9SBarry Smith     }
68230dcb7c9SBarry Smith     for (i=0; i<ng; i++) {
68330dcb7c9SBarry Smith       if (nownedsenders[i] > 1) {
68430dcb7c9SBarry Smith         ierr = PetscSynchronizedPrintf(comm,"[%d] global node %d local owner processors: ",rank,i+rstart);CHKERRQ(ierr);
68530dcb7c9SBarry Smith         for (j=0; j<nownedsenders[i]; j++) {
68630dcb7c9SBarry Smith           ierr = PetscSynchronizedPrintf(comm,"%d ",ownedsenders[starts[i]+j]);CHKERRQ(ierr);
68730dcb7c9SBarry Smith         }
68830dcb7c9SBarry Smith         ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr);
68930dcb7c9SBarry Smith       }
69030dcb7c9SBarry Smith     }
69130dcb7c9SBarry Smith     ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr);
69207b52d57SBarry Smith   }/* -----------------------------------  */
69330dcb7c9SBarry Smith 
6943677ff5aSBarry Smith   /* wait on original sends */
6953a96401aSBarry Smith   if (nsends) {
696b0a32e0cSBarry Smith     ierr = PetscMalloc(nsends*sizeof(MPI_Status),&send_status);CHKERRQ(ierr);
6973a96401aSBarry Smith     ierr = MPI_Waitall(nsends,send_waits,send_status);CHKERRQ(ierr);
6983a96401aSBarry Smith     ierr = PetscFree(send_status);CHKERRQ(ierr);
6993a96401aSBarry Smith   }
70089d82c54SBarry Smith   ierr = PetscFree(send_waits);CHKERRQ(ierr);
7013a96401aSBarry Smith   ierr = PetscFree(sends);CHKERRQ(ierr);
7023677ff5aSBarry Smith   ierr = PetscFree(nprocs);CHKERRQ(ierr);
7033677ff5aSBarry Smith 
7043677ff5aSBarry Smith   /* pack messages to send back to local owners */
70530dcb7c9SBarry Smith   starts[0]    = 0;
70630dcb7c9SBarry Smith   for (i=1; i<ng; i++) {
70730dcb7c9SBarry Smith     if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1];
70830dcb7c9SBarry Smith     else starts[i] = starts[i-1];
70930dcb7c9SBarry Smith   }
71030dcb7c9SBarry Smith   nsends2 = nrecvs;
71132dcc486SBarry Smith   ierr    = PetscMalloc((nsends2+1)*sizeof(PetscInt),&nprocs);CHKERRQ(ierr); /* length of each message */
71230dcb7c9SBarry Smith   for (i=0; i<nrecvs; i++) {
71330dcb7c9SBarry Smith     nprocs[i] = 1;
71430dcb7c9SBarry Smith     for (j=0; j<len[i]; j++) {
71530dcb7c9SBarry Smith       node = recvs[2*i*nmax+2*j]-rstart;
71630dcb7c9SBarry Smith       if (nownedsenders[node] > 1) {
71730dcb7c9SBarry Smith         nprocs[i] += 2 + nownedsenders[node];
71830dcb7c9SBarry Smith       }
71930dcb7c9SBarry Smith     }
72030dcb7c9SBarry Smith   }
72130dcb7c9SBarry Smith   nt = 0; for (i=0; i<nsends2; i++) nt += nprocs[i];
72232dcc486SBarry Smith   ierr = PetscMalloc((nt+1)*sizeof(PetscInt),&sends2);CHKERRQ(ierr);
72332dcc486SBarry Smith   ierr = PetscMalloc((nsends2+1)*sizeof(PetscInt),&starts2);CHKERRQ(ierr);
72430dcb7c9SBarry Smith   starts2[0] = 0; for (i=1; i<nsends2; i++) starts2[i] = starts2[i-1] + nprocs[i-1];
72530dcb7c9SBarry Smith   /*
72630dcb7c9SBarry Smith      Each message is 1 + nprocs[i] long, and consists of
72730dcb7c9SBarry Smith        (0) the number of nodes being sent back
72830dcb7c9SBarry Smith        (1) the local node number,
72930dcb7c9SBarry Smith        (2) the number of processors sharing it,
73030dcb7c9SBarry Smith        (3) the processors sharing it
73130dcb7c9SBarry Smith   */
73230dcb7c9SBarry Smith   for (i=0; i<nsends2; i++) {
73330dcb7c9SBarry Smith     cnt = 1;
73430dcb7c9SBarry Smith     sends2[starts2[i]] = 0;
73530dcb7c9SBarry Smith     for (j=0; j<len[i]; j++) {
73630dcb7c9SBarry Smith       node = recvs[2*i*nmax+2*j]-rstart;
73730dcb7c9SBarry Smith       if (nownedsenders[node] > 1) {
73830dcb7c9SBarry Smith         sends2[starts2[i]]++;
73930dcb7c9SBarry Smith         sends2[starts2[i]+cnt++] = recvs[2*i*nmax+2*j+1];
74030dcb7c9SBarry Smith         sends2[starts2[i]+cnt++] = nownedsenders[node];
74132dcc486SBarry Smith         ierr = PetscMemcpy(&sends2[starts2[i]+cnt],&ownedsenders[starts[node]],nownedsenders[node]*sizeof(PetscInt));CHKERRQ(ierr);
74230dcb7c9SBarry Smith         cnt += nownedsenders[node];
74330dcb7c9SBarry Smith       }
74430dcb7c9SBarry Smith     }
74530dcb7c9SBarry Smith   }
74630dcb7c9SBarry Smith 
74730dcb7c9SBarry Smith   /* receive the message lengths */
74830dcb7c9SBarry Smith   nrecvs2 = nsends;
74932dcc486SBarry Smith   ierr = PetscMalloc((nrecvs2+1)*sizeof(PetscInt),&lens2);CHKERRQ(ierr);
75032dcc486SBarry Smith   ierr = PetscMalloc((nrecvs2+1)*sizeof(PetscInt),&starts3);CHKERRQ(ierr);
751d44834fbSBarry Smith   ierr = PetscMalloc((nrecvs2+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr);
75230dcb7c9SBarry Smith   for (i=0; i<nrecvs2; i++) {
753d44834fbSBarry Smith     ierr = MPI_Irecv(&lens2[i],1,MPIU_INT,dest[i],tag2,comm,recv_waits+i);CHKERRQ(ierr);
75430dcb7c9SBarry Smith   }
755d44834fbSBarry Smith 
7568a8e0b3aSBarry Smith   /* send the message lengths */
7578a8e0b3aSBarry Smith   for (i=0; i<nsends2; i++) {
7588a8e0b3aSBarry Smith     ierr = MPI_Send(&nprocs[i],1,MPIU_INT,source[i],tag2,comm);CHKERRQ(ierr);
7598a8e0b3aSBarry Smith   }
7608a8e0b3aSBarry Smith 
761d44834fbSBarry Smith   /* wait on receives of lens */
7620c468ba9SBarry Smith   if (nrecvs2) {
7630c468ba9SBarry Smith     ierr = PetscMalloc(nrecvs2*sizeof(MPI_Status),&recv_statuses);CHKERRQ(ierr);
764d44834fbSBarry Smith     ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr);
765d44834fbSBarry Smith     ierr = PetscFree(recv_statuses);CHKERRQ(ierr);
7660c468ba9SBarry Smith   }
767d44834fbSBarry Smith   ierr = PetscFree(recv_waits);
768d44834fbSBarry Smith 
76930dcb7c9SBarry Smith   starts3[0] = 0;
770d44834fbSBarry Smith   nt         = 0;
77130dcb7c9SBarry Smith   for (i=0; i<nrecvs2-1; i++) {
77230dcb7c9SBarry Smith     starts3[i+1] = starts3[i] + lens2[i];
773d44834fbSBarry Smith     nt          += lens2[i];
77430dcb7c9SBarry Smith   }
775d44834fbSBarry Smith   nt += lens2[nrecvs2-1];
776d44834fbSBarry Smith 
77732dcc486SBarry Smith   ierr = PetscMalloc((nt+1)*sizeof(PetscInt),&recvs2);CHKERRQ(ierr);
778b0a32e0cSBarry Smith   ierr = PetscMalloc((nrecvs2+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr);
77952b72c4aSBarry Smith   for (i=0; i<nrecvs2; i++) {
78032dcc486SBarry Smith     ierr = MPI_Irecv(recvs2+starts3[i],lens2[i],MPIU_INT,dest[i],tag3,comm,recv_waits+i);CHKERRQ(ierr);
78130dcb7c9SBarry Smith   }
78230dcb7c9SBarry Smith 
78330dcb7c9SBarry Smith   /* send the messages */
784b0a32e0cSBarry Smith   ierr = PetscMalloc((nsends2+1)*sizeof(MPI_Request),&send_waits);CHKERRQ(ierr);
78530dcb7c9SBarry Smith   for (i=0; i<nsends2; i++) {
78632dcc486SBarry Smith     ierr = MPI_Isend(sends2+starts2[i],nprocs[i],MPIU_INT,source[i],tag3,comm,send_waits+i);CHKERRQ(ierr);
78730dcb7c9SBarry Smith   }
78830dcb7c9SBarry Smith 
78930dcb7c9SBarry Smith   /* wait on receives */
7900c468ba9SBarry Smith   if (nrecvs2) {
7910c468ba9SBarry Smith     ierr = PetscMalloc(nrecvs2*sizeof(MPI_Status),&recv_statuses);CHKERRQ(ierr);
79230dcb7c9SBarry Smith     ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr);
79330dcb7c9SBarry Smith     ierr = PetscFree(recv_statuses);CHKERRQ(ierr);
7940c468ba9SBarry Smith   }
79530dcb7c9SBarry Smith   ierr = PetscFree(recv_waits);CHKERRQ(ierr);
79630dcb7c9SBarry Smith   ierr = PetscFree(nprocs);CHKERRQ(ierr);
79730dcb7c9SBarry Smith 
79807b52d57SBarry Smith   if (debug) { /* -----------------------------------  */
79930dcb7c9SBarry Smith     cnt = 0;
80030dcb7c9SBarry Smith     for (i=0; i<nrecvs2; i++) {
80130dcb7c9SBarry Smith       nt = recvs2[cnt++];
80230dcb7c9SBarry Smith       for (j=0; j<nt; j++) {
80330dcb7c9SBarry Smith         ierr = PetscSynchronizedPrintf(comm,"[%d] local node %d number of subdomains %d: ",rank,recvs2[cnt],recvs2[cnt+1]);CHKERRQ(ierr);
80430dcb7c9SBarry Smith         for (k=0; k<recvs2[cnt+1]; k++) {
80530dcb7c9SBarry Smith           ierr = PetscSynchronizedPrintf(comm,"%d ",recvs2[cnt+2+k]);CHKERRQ(ierr);
80630dcb7c9SBarry Smith         }
80730dcb7c9SBarry Smith         cnt += 2 + recvs2[cnt+1];
80830dcb7c9SBarry Smith         ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr);
80930dcb7c9SBarry Smith       }
81030dcb7c9SBarry Smith     }
81130dcb7c9SBarry Smith     ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr);
81207b52d57SBarry Smith   } /* -----------------------------------  */
81330dcb7c9SBarry Smith 
81430dcb7c9SBarry Smith   /* count number subdomains for each local node */
81532dcc486SBarry Smith   ierr = PetscMalloc(size*sizeof(PetscInt),&nprocs);CHKERRQ(ierr);
81632dcc486SBarry Smith   ierr = PetscMemzero(nprocs,size*sizeof(PetscInt));CHKERRQ(ierr);
81730dcb7c9SBarry Smith   cnt  = 0;
81830dcb7c9SBarry Smith   for (i=0; i<nrecvs2; i++) {
81930dcb7c9SBarry Smith     nt = recvs2[cnt++];
82030dcb7c9SBarry Smith     for (j=0; j<nt; j++) {
82130dcb7c9SBarry Smith       for (k=0; k<recvs2[cnt+1]; k++) {
82230dcb7c9SBarry Smith         nprocs[recvs2[cnt+2+k]]++;
82330dcb7c9SBarry Smith       }
82430dcb7c9SBarry Smith       cnt += 2 + recvs2[cnt+1];
82530dcb7c9SBarry Smith     }
82630dcb7c9SBarry Smith   }
82730dcb7c9SBarry Smith   nt = 0; for (i=0; i<size; i++) nt += (nprocs[i] > 0);
82830dcb7c9SBarry Smith   *nproc    = nt;
82932dcc486SBarry Smith   ierr = PetscMalloc((nt+1)*sizeof(PetscInt),procs);CHKERRQ(ierr);
83032dcc486SBarry Smith   ierr = PetscMalloc((nt+1)*sizeof(PetscInt),numprocs);CHKERRQ(ierr);
83132dcc486SBarry Smith   ierr = PetscMalloc((nt+1)*sizeof(PetscInt*),indices);CHKERRQ(ierr);
83232dcc486SBarry Smith   ierr = PetscMalloc(size*sizeof(PetscInt),&bprocs);CHKERRQ(ierr);
83330dcb7c9SBarry Smith   cnt       = 0;
83430dcb7c9SBarry Smith   for (i=0; i<size; i++) {
83530dcb7c9SBarry Smith     if (nprocs[i] > 0) {
83630dcb7c9SBarry Smith       bprocs[i]        = cnt;
83730dcb7c9SBarry Smith       (*procs)[cnt]    = i;
83830dcb7c9SBarry Smith       (*numprocs)[cnt] = nprocs[i];
83932dcc486SBarry Smith       ierr             = PetscMalloc(nprocs[i]*sizeof(PetscInt),&(*indices)[cnt]);CHKERRQ(ierr);
84030dcb7c9SBarry Smith       cnt++;
84130dcb7c9SBarry Smith     }
84230dcb7c9SBarry Smith   }
84330dcb7c9SBarry Smith 
84430dcb7c9SBarry Smith   /* make the list of subdomains for each nontrivial local node */
84532dcc486SBarry Smith   ierr = PetscMemzero(*numprocs,nt*sizeof(PetscInt));CHKERRQ(ierr);
84630dcb7c9SBarry Smith   cnt  = 0;
84730dcb7c9SBarry Smith   for (i=0; i<nrecvs2; i++) {
84830dcb7c9SBarry Smith     nt = recvs2[cnt++];
84930dcb7c9SBarry Smith     for (j=0; j<nt; j++) {
85030dcb7c9SBarry Smith       for (k=0; k<recvs2[cnt+1]; k++) {
85130dcb7c9SBarry Smith         (*indices)[bprocs[recvs2[cnt+2+k]]][(*numprocs)[bprocs[recvs2[cnt+2+k]]]++] = recvs2[cnt];
85230dcb7c9SBarry Smith       }
85330dcb7c9SBarry Smith       cnt += 2 + recvs2[cnt+1];
85430dcb7c9SBarry Smith     }
85530dcb7c9SBarry Smith   }
85630dcb7c9SBarry Smith   ierr = PetscFree(bprocs);CHKERRQ(ierr);
85707b52d57SBarry Smith   ierr = PetscFree(recvs2);CHKERRQ(ierr);
85830dcb7c9SBarry Smith 
85907b52d57SBarry Smith   /* sort the node indexing by their global numbers */
86007b52d57SBarry Smith   nt = *nproc;
86107b52d57SBarry Smith   for (i=0; i<nt; i++) {
86232dcc486SBarry Smith     ierr = PetscMalloc(((*numprocs)[i])*sizeof(PetscInt),&tmp);CHKERRQ(ierr);
86307b52d57SBarry Smith     for (j=0; j<(*numprocs)[i]; j++) {
86407b52d57SBarry Smith       tmp[j] = lindices[(*indices)[i][j]];
86507b52d57SBarry Smith     }
86607b52d57SBarry Smith     ierr = PetscSortIntWithArray((*numprocs)[i],tmp,(*indices)[i]);CHKERRQ(ierr);
86707b52d57SBarry Smith     ierr = PetscFree(tmp);CHKERRQ(ierr);
86807b52d57SBarry Smith   }
86907b52d57SBarry Smith 
87007b52d57SBarry Smith   if (debug) { /* -----------------------------------  */
87130dcb7c9SBarry Smith     nt = *nproc;
87230dcb7c9SBarry Smith     for (i=0; i<nt; i++) {
87330dcb7c9SBarry Smith       ierr = PetscSynchronizedPrintf(comm,"[%d] subdomain %d number of indices %d: ",rank,(*procs)[i],(*numprocs)[i]);CHKERRQ(ierr);
87430dcb7c9SBarry Smith       for (j=0; j<(*numprocs)[i]; j++) {
87530dcb7c9SBarry Smith         ierr = PetscSynchronizedPrintf(comm,"%d ",(*indices)[i][j]);CHKERRQ(ierr);
87630dcb7c9SBarry Smith       }
87730dcb7c9SBarry Smith       ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr);
87830dcb7c9SBarry Smith     }
87930dcb7c9SBarry Smith     ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr);
88007b52d57SBarry Smith   } /* -----------------------------------  */
88130dcb7c9SBarry Smith 
88230dcb7c9SBarry Smith   /* wait on sends */
88330dcb7c9SBarry Smith   if (nsends2) {
884b0a32e0cSBarry Smith     ierr = PetscMalloc(nsends2*sizeof(MPI_Status),&send_status);CHKERRQ(ierr);
88530dcb7c9SBarry Smith     ierr = MPI_Waitall(nsends2,send_waits,send_status);CHKERRQ(ierr);
88630dcb7c9SBarry Smith     ierr = PetscFree(send_status);CHKERRQ(ierr);
88730dcb7c9SBarry Smith   }
88830dcb7c9SBarry Smith 
88930dcb7c9SBarry Smith   ierr = PetscFree(starts3);CHKERRQ(ierr);
89030dcb7c9SBarry Smith   ierr = PetscFree(dest);CHKERRQ(ierr);
89130dcb7c9SBarry Smith   ierr = PetscFree(send_waits);CHKERRQ(ierr);
8923677ff5aSBarry Smith 
893bc8ff85bSBarry Smith   ierr = PetscFree(nownedsenders);CHKERRQ(ierr);
894bc8ff85bSBarry Smith   ierr = PetscFree(ownedsenders);CHKERRQ(ierr);
895bc8ff85bSBarry Smith   ierr = PetscFree(starts);CHKERRQ(ierr);
89630dcb7c9SBarry Smith   ierr = PetscFree(starts2);CHKERRQ(ierr);
89730dcb7c9SBarry Smith   ierr = PetscFree(lens2);CHKERRQ(ierr);
89889d82c54SBarry Smith 
89989d82c54SBarry Smith   ierr = PetscFree(source);CHKERRQ(ierr);
90097f1f81fSBarry Smith   ierr = PetscFree(len);CHKERRQ(ierr);
90189d82c54SBarry Smith   ierr = PetscFree(recvs);CHKERRQ(ierr);
9023a96401aSBarry Smith   ierr = PetscFree(nprocs);CHKERRQ(ierr);
90330dcb7c9SBarry Smith   ierr = PetscFree(sends2);CHKERRQ(ierr);
90424cf384cSBarry Smith 
90524cf384cSBarry Smith   /* put the information about myself as the first entry in the list */
90624cf384cSBarry Smith   first_procs    = (*procs)[0];
90724cf384cSBarry Smith   first_numprocs = (*numprocs)[0];
90824cf384cSBarry Smith   first_indices  = (*indices)[0];
90924cf384cSBarry Smith   for (i=0; i<*nproc; i++) {
91024cf384cSBarry Smith     if ((*procs)[i] == rank) {
91124cf384cSBarry Smith       (*procs)[0]    = (*procs)[i];
91224cf384cSBarry Smith       (*numprocs)[0] = (*numprocs)[i];
91324cf384cSBarry Smith       (*indices)[0]  = (*indices)[i];
91424cf384cSBarry Smith       (*procs)[i]    = first_procs;
91524cf384cSBarry Smith       (*numprocs)[i] = first_numprocs;
91624cf384cSBarry Smith       (*indices)[i]  = first_indices;
91724cf384cSBarry Smith       break;
91824cf384cSBarry Smith     }
91924cf384cSBarry Smith   }
92089d82c54SBarry Smith   PetscFunctionReturn(0);
92189d82c54SBarry Smith }
92289d82c54SBarry Smith 
9234a2ae208SSatish Balay #undef __FUNCT__
9244a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingRestoreInfo"
92507b52d57SBarry Smith /*@C
92607b52d57SBarry Smith     ISLocalToGlobalMappingRestoreInfo - Frees the memory allocated by ISLocalToGlobalMappingGetInfo()
92789d82c54SBarry Smith 
92807b52d57SBarry Smith     Collective on ISLocalToGlobalMapping
92907b52d57SBarry Smith 
93007b52d57SBarry Smith     Input Parameters:
93107b52d57SBarry Smith .   mapping - the mapping from local to global indexing
93207b52d57SBarry Smith 
93307b52d57SBarry Smith     Output Parameter:
93407b52d57SBarry Smith +   nproc - number of processors that are connected to this one
93507b52d57SBarry Smith .   proc - neighboring processors
93607b52d57SBarry Smith .   numproc - number of indices for each processor
93707b52d57SBarry Smith -   indices - indices of local nodes shared with neighbor (sorted by global numbering)
93807b52d57SBarry Smith 
93907b52d57SBarry Smith     Level: advanced
94007b52d57SBarry Smith 
94107b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(),
94207b52d57SBarry Smith           ISLocalToGlobalMappingGetInfo()
94307b52d57SBarry Smith @*/
9440c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingRestoreInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[])
94507b52d57SBarry Smith {
9466849ba73SBarry Smith   PetscErrorCode ierr;
94732dcc486SBarry Smith   PetscInt i;
94807b52d57SBarry Smith 
94907b52d57SBarry Smith   PetscFunctionBegin;
95005b42c5fSBarry Smith   ierr = PetscFree(*procs);CHKERRQ(ierr);
95105b42c5fSBarry Smith   ierr = PetscFree(*numprocs);CHKERRQ(ierr);
95200ff320aSBarry Smith   if (*indices) {
95305b42c5fSBarry Smith     ierr = PetscFree((*indices)[0]);CHKERRQ(ierr);
95400ff320aSBarry Smith     for (i=1; i<*nproc; i++) {
95505b42c5fSBarry Smith       ierr = PetscFree((*indices)[i]);CHKERRQ(ierr);
95607b52d57SBarry Smith     }
95707b52d57SBarry Smith     ierr = PetscFree(*indices);CHKERRQ(ierr);
95824cf384cSBarry Smith   }
95907b52d57SBarry Smith   PetscFunctionReturn(0);
96007b52d57SBarry Smith }
96189d82c54SBarry Smith 
962bc8ff85bSBarry Smith 
963bc8ff85bSBarry Smith 
964bc8ff85bSBarry Smith 
965bc8ff85bSBarry Smith 
966bc8ff85bSBarry Smith 
967bc8ff85bSBarry Smith 
968bc8ff85bSBarry Smith 
969bc8ff85bSBarry Smith 
970bc8ff85bSBarry Smith 
971bc8ff85bSBarry Smith 
972bc8ff85bSBarry Smith 
973bc8ff85bSBarry Smith 
974bc8ff85bSBarry Smith 
975bc8ff85bSBarry Smith 
976bc8ff85bSBarry Smith 
977bc8ff85bSBarry Smith 
97824cf384cSBarry Smith 
979