xref: /petsc/src/dm/impls/composite/pack.c (revision 9804daf34a45a1225c622b14639ad2e72848b92f)
147c6ae99SBarry Smith 
2ccd284c7SBarry Smith #include <../src/dm/impls/composite/packimpl.h>       /*I  "petscdmcomposite.h"  I*/
347c6ae99SBarry Smith 
447c6ae99SBarry Smith #undef __FUNCT__
547c6ae99SBarry Smith #define __FUNCT__ "DMCompositeSetCoupling"
647c6ae99SBarry Smith /*@C
747c6ae99SBarry Smith     DMCompositeSetCoupling - Sets user provided routines that compute the coupling between the
89ae5db72SJed Brown       seperate components (DMs) in a DMto build the correct matrix nonzero structure.
947c6ae99SBarry Smith 
1047c6ae99SBarry Smith 
1147c6ae99SBarry Smith     Logically Collective on MPI_Comm
1247c6ae99SBarry Smith 
1347c6ae99SBarry Smith     Input Parameter:
1447c6ae99SBarry Smith +   dm - the composite object
1547c6ae99SBarry Smith -   formcouplelocations - routine to set the nonzero locations in the matrix
1647c6ae99SBarry Smith 
1747c6ae99SBarry Smith     Level: advanced
1847c6ae99SBarry Smith 
191b2093e4SBarry Smith     Notes: See DMSetApplicationContext() and DMGetApplicationContext() for how to get user information into
2047c6ae99SBarry Smith         this routine
2147c6ae99SBarry Smith 
2247c6ae99SBarry Smith @*/
237087cfbeSBarry Smith PetscErrorCode  DMCompositeSetCoupling(DM dm,PetscErrorCode (*FormCoupleLocations)(DM,Mat,PetscInt*,PetscInt*,PetscInt,PetscInt,PetscInt,PetscInt))
2447c6ae99SBarry Smith {
2547c6ae99SBarry Smith   DM_Composite *com = (DM_Composite*)dm->data;
2647c6ae99SBarry Smith 
2747c6ae99SBarry Smith   PetscFunctionBegin;
2847c6ae99SBarry Smith   com->FormCoupleLocations = FormCoupleLocations;
2947c6ae99SBarry Smith   PetscFunctionReturn(0);
3047c6ae99SBarry Smith }
3147c6ae99SBarry Smith 
3247c6ae99SBarry Smith #undef __FUNCT__
330c010503SBarry Smith #define __FUNCT__ "DMDestroy_Composite"
346bf464f9SBarry Smith PetscErrorCode  DMDestroy_Composite(DM dm)
3547c6ae99SBarry Smith {
3647c6ae99SBarry Smith   PetscErrorCode         ierr;
3747c6ae99SBarry Smith   struct DMCompositeLink *next, *prev;
3847c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
3947c6ae99SBarry Smith 
4047c6ae99SBarry Smith   PetscFunctionBegin;
4147c6ae99SBarry Smith   next = com->next;
4247c6ae99SBarry Smith   while (next) {
4347c6ae99SBarry Smith     prev = next;
4447c6ae99SBarry Smith     next = next->next;
45fcfd50ebSBarry Smith     ierr = DMDestroy(&prev->dm);CHKERRQ(ierr);
4647c6ae99SBarry Smith     ierr = PetscFree(prev->grstarts);CHKERRQ(ierr);
4747c6ae99SBarry Smith     ierr = PetscFree(prev);CHKERRQ(ierr);
4847c6ae99SBarry Smith   }
49435a35e8SMatthew G Knepley   /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */
50435a35e8SMatthew G Knepley   ierr = PetscFree(com);CHKERRQ(ierr);
5147c6ae99SBarry Smith   PetscFunctionReturn(0);
5247c6ae99SBarry Smith }
5347c6ae99SBarry Smith 
5447c6ae99SBarry Smith #undef __FUNCT__
550c010503SBarry Smith #define __FUNCT__ "DMView_Composite"
567087cfbeSBarry Smith PetscErrorCode  DMView_Composite(DM dm,PetscViewer v)
5747c6ae99SBarry Smith {
5847c6ae99SBarry Smith   PetscErrorCode ierr;
5947c6ae99SBarry Smith   PetscBool      iascii;
6047c6ae99SBarry Smith   DM_Composite   *com = (DM_Composite*)dm->data;
6147c6ae99SBarry Smith 
6247c6ae99SBarry Smith   PetscFunctionBegin;
63251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
6447c6ae99SBarry Smith   if (iascii) {
6547c6ae99SBarry Smith     struct DMCompositeLink *lnk = com->next;
6647c6ae99SBarry Smith     PetscInt               i;
6747c6ae99SBarry Smith 
6847c6ae99SBarry Smith     ierr = PetscViewerASCIIPrintf(v,"DM (%s)\n",((PetscObject)dm)->prefix ? ((PetscObject)dm)->prefix : "no prefix");CHKERRQ(ierr);
699ae5db72SJed Brown     ierr = PetscViewerASCIIPrintf(v,"  contains %D DMs\n",com->nDM);CHKERRQ(ierr);
7047c6ae99SBarry Smith     ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr);
7147c6ae99SBarry Smith     for (i=0; lnk; lnk=lnk->next,i++) {
729ae5db72SJed Brown       ierr = PetscViewerASCIIPrintf(v,"Link %D: DM of type %s\n",i,((PetscObject)lnk->dm)->type_name);CHKERRQ(ierr);
7347c6ae99SBarry Smith       ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr);
7447c6ae99SBarry Smith       ierr = DMView(lnk->dm,v);CHKERRQ(ierr);
7547c6ae99SBarry Smith       ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr);
7647c6ae99SBarry Smith     }
7747c6ae99SBarry Smith     ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr);
7847c6ae99SBarry Smith   }
7947c6ae99SBarry Smith   PetscFunctionReturn(0);
8047c6ae99SBarry Smith }
8147c6ae99SBarry Smith 
8247c6ae99SBarry Smith /* --------------------------------------------------------------------------------------*/
8347c6ae99SBarry Smith #undef __FUNCT__
84d7bf68aeSBarry Smith #define __FUNCT__ "DMSetUp_Composite"
857087cfbeSBarry Smith PetscErrorCode  DMSetUp_Composite(DM dm)
8647c6ae99SBarry Smith {
8747c6ae99SBarry Smith   PetscErrorCode         ierr;
8847c6ae99SBarry Smith   PetscInt               nprev = 0;
8947c6ae99SBarry Smith   PetscMPIInt            rank,size;
9047c6ae99SBarry Smith   DM_Composite           *com  = (DM_Composite*)dm->data;
9147c6ae99SBarry Smith   struct DMCompositeLink *next = com->next;
9247c6ae99SBarry Smith   PetscLayout            map;
9347c6ae99SBarry Smith 
9447c6ae99SBarry Smith   PetscFunctionBegin;
95ce94432eSBarry Smith   if (com->setup) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Packer has already been setup");
96ce94432eSBarry Smith   ierr = PetscLayoutCreate(PetscObjectComm((PetscObject)dm),&map);CHKERRQ(ierr);
9747c6ae99SBarry Smith   ierr = PetscLayoutSetLocalSize(map,com->n);CHKERRQ(ierr);
9847c6ae99SBarry Smith   ierr = PetscLayoutSetSize(map,PETSC_DETERMINE);CHKERRQ(ierr);
9947c6ae99SBarry Smith   ierr = PetscLayoutSetBlockSize(map,1);CHKERRQ(ierr);
10047c6ae99SBarry Smith   ierr = PetscLayoutSetUp(map);CHKERRQ(ierr);
10147c6ae99SBarry Smith   ierr = PetscLayoutGetSize(map,&com->N);CHKERRQ(ierr);
1020298fd71SBarry Smith   ierr = PetscLayoutGetRange(map,&com->rstart,NULL);CHKERRQ(ierr);
103fcfd50ebSBarry Smith   ierr = PetscLayoutDestroy(&map);CHKERRQ(ierr);
10447c6ae99SBarry Smith 
1059ae5db72SJed Brown   /* now set the rstart for each linked vector */
106ce94432eSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
107ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm),&size);CHKERRQ(ierr);
10847c6ae99SBarry Smith   while (next) {
10947c6ae99SBarry Smith     next->rstart  = nprev;
11006ebdd98SJed Brown     nprev        += next->n;
11147c6ae99SBarry Smith     next->grstart = com->rstart + next->rstart;
11247c6ae99SBarry Smith     ierr          = PetscMalloc(size*sizeof(PetscInt),&next->grstarts);CHKERRQ(ierr);
113ce94432eSBarry Smith     ierr          = MPI_Allgather(&next->grstart,1,MPIU_INT,next->grstarts,1,MPIU_INT,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
11447c6ae99SBarry Smith     next          = next->next;
11547c6ae99SBarry Smith   }
11647c6ae99SBarry Smith   com->setup = PETSC_TRUE;
11747c6ae99SBarry Smith   PetscFunctionReturn(0);
11847c6ae99SBarry Smith }
11947c6ae99SBarry Smith 
12047c6ae99SBarry Smith /* ----------------------------------------------------------------------------------*/
12147c6ae99SBarry Smith 
12247c6ae99SBarry Smith #undef __FUNCT__
12347c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetNumberDM"
12473e31fe2SJed Brown /*@
12547c6ae99SBarry Smith     DMCompositeGetNumberDM - Get's the number of DM objects in the DMComposite
12647c6ae99SBarry Smith        representation.
12747c6ae99SBarry Smith 
12847c6ae99SBarry Smith     Not Collective
12947c6ae99SBarry Smith 
13047c6ae99SBarry Smith     Input Parameter:
13147c6ae99SBarry Smith .    dm - the packer object
13247c6ae99SBarry Smith 
13347c6ae99SBarry Smith     Output Parameter:
13447c6ae99SBarry Smith .     nDM - the number of DMs
13547c6ae99SBarry Smith 
13647c6ae99SBarry Smith     Level: beginner
13747c6ae99SBarry Smith 
13847c6ae99SBarry Smith @*/
1397087cfbeSBarry Smith PetscErrorCode  DMCompositeGetNumberDM(DM dm,PetscInt *nDM)
14047c6ae99SBarry Smith {
14147c6ae99SBarry Smith   DM_Composite *com = (DM_Composite*)dm->data;
1425fd66863SKarl Rupp 
14347c6ae99SBarry Smith   PetscFunctionBegin;
14447c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
14547c6ae99SBarry Smith   *nDM = com->nDM;
14647c6ae99SBarry Smith   PetscFunctionReturn(0);
14747c6ae99SBarry Smith }
14847c6ae99SBarry Smith 
14947c6ae99SBarry Smith 
15047c6ae99SBarry Smith #undef __FUNCT__
15147c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetAccess"
15247c6ae99SBarry Smith /*@C
15347c6ae99SBarry Smith     DMCompositeGetAccess - Allows one to access the individual packed vectors in their global
15447c6ae99SBarry Smith        representation.
15547c6ae99SBarry Smith 
15647c6ae99SBarry Smith     Collective on DMComposite
15747c6ae99SBarry Smith 
1589ae5db72SJed Brown     Input Parameters:
15947c6ae99SBarry Smith +    dm - the packer object
1609ae5db72SJed Brown -    gvec - the global vector
1619ae5db72SJed Brown 
1629ae5db72SJed Brown     Output Parameters:
1630298fd71SBarry Smith .    Vec* ... - the packed parallel vectors, NULL for those that are not needed
16447c6ae99SBarry Smith 
16547c6ae99SBarry Smith     Notes: Use DMCompositeRestoreAccess() to return the vectors when you no longer need them
16647c6ae99SBarry Smith 
167f73e5cebSJed Brown     Fortran Notes:
168f73e5cebSJed Brown 
169f73e5cebSJed Brown     Fortran callers must use numbered versions of this routine, e.g., DMCompositeGetAccess4(dm,gvec,vec1,vec2,vec3,vec4)
170f73e5cebSJed Brown     or use the alternative interface DMCompositeGetAccessArray().
171f73e5cebSJed Brown 
17247c6ae99SBarry Smith     Level: advanced
17347c6ae99SBarry Smith 
174f73e5cebSJed Brown .seealso: DMCompositeGetEntries(), DMCompositeScatter()
17547c6ae99SBarry Smith @*/
1767087cfbeSBarry Smith PetscErrorCode  DMCompositeGetAccess(DM dm,Vec gvec,...)
17747c6ae99SBarry Smith {
17847c6ae99SBarry Smith   va_list                Argp;
17947c6ae99SBarry Smith   PetscErrorCode         ierr;
18047c6ae99SBarry Smith   struct DMCompositeLink *next;
18147c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
18247c6ae99SBarry Smith 
18347c6ae99SBarry Smith   PetscFunctionBegin;
18447c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
18547c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
18647c6ae99SBarry Smith   next = com->next;
18747c6ae99SBarry Smith   if (!com->setup) {
188d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
18947c6ae99SBarry Smith   }
19047c6ae99SBarry Smith 
19147c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
19247c6ae99SBarry Smith   va_start(Argp,gvec);
19347c6ae99SBarry Smith   while (next) {
19447c6ae99SBarry Smith     Vec *vec;
19547c6ae99SBarry Smith     vec = va_arg(Argp, Vec*);
1969ae5db72SJed Brown     if (vec) {
1979ae5db72SJed Brown       PetscScalar *array;
1989ae5db72SJed Brown       ierr = DMGetGlobalVector(next->dm,vec);CHKERRQ(ierr);
1999ae5db72SJed Brown       ierr = VecGetArray(gvec,&array);CHKERRQ(ierr);
2009ae5db72SJed Brown       ierr = VecPlaceArray(*vec,array+next->rstart);CHKERRQ(ierr);
2019ae5db72SJed Brown       ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr);
20247c6ae99SBarry Smith     }
20347c6ae99SBarry Smith     next = next->next;
20447c6ae99SBarry Smith   }
20547c6ae99SBarry Smith   va_end(Argp);
20647c6ae99SBarry Smith   PetscFunctionReturn(0);
20747c6ae99SBarry Smith }
20847c6ae99SBarry Smith 
20947c6ae99SBarry Smith #undef __FUNCT__
210f73e5cebSJed Brown #define __FUNCT__ "DMCompositeGetAccessArray"
211f73e5cebSJed Brown /*@C
212f73e5cebSJed Brown     DMCompositeGetAccessArray - Allows one to access the individual packed vectors in their global
213f73e5cebSJed Brown        representation.
214f73e5cebSJed Brown 
215f73e5cebSJed Brown     Collective on DMComposite
216f73e5cebSJed Brown 
217f73e5cebSJed Brown     Input Parameters:
218f73e5cebSJed Brown +    dm - the packer object
219f73e5cebSJed Brown .    pvec - packed vector
220f73e5cebSJed Brown .    nwanted - number of vectors wanted
2210298fd71SBarry Smith -    wanted - sorted array of vectors wanted, or NULL to get all vectors
222f73e5cebSJed Brown 
223f73e5cebSJed Brown     Output Parameters:
224f73e5cebSJed Brown .    vecs - array of requested global vectors (must be allocated)
225f73e5cebSJed Brown 
226f73e5cebSJed Brown     Notes: Use DMCompositeRestoreAccessArray() to return the vectors when you no longer need them
227f73e5cebSJed Brown 
228f73e5cebSJed Brown     Level: advanced
229f73e5cebSJed Brown 
230f73e5cebSJed Brown .seealso: DMCompositeGetAccess(), DMCompositeGetEntries(), DMCompositeScatter(), DMCompositeGather()
231f73e5cebSJed Brown @*/
232f73e5cebSJed Brown PetscErrorCode  DMCompositeGetAccessArray(DM dm,Vec pvec,PetscInt nwanted,const PetscInt *wanted,Vec *vecs)
233f73e5cebSJed Brown {
234f73e5cebSJed Brown   PetscErrorCode         ierr;
235f73e5cebSJed Brown   struct DMCompositeLink *link;
236f73e5cebSJed Brown   PetscInt               i,wnum;
237f73e5cebSJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
238f73e5cebSJed Brown 
239f73e5cebSJed Brown   PetscFunctionBegin;
240f73e5cebSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
241f73e5cebSJed Brown   PetscValidHeaderSpecific(pvec,VEC_CLASSID,2);
242f73e5cebSJed Brown   if (!com->setup) {
243f73e5cebSJed Brown     ierr = DMSetUp(dm);CHKERRQ(ierr);
244f73e5cebSJed Brown   }
245f73e5cebSJed Brown 
246f73e5cebSJed Brown   for (i=0,wnum=0,link=com->next; link && wnum<nwanted; i++,link=link->next) {
247f73e5cebSJed Brown     if (!wanted || i == wanted[wnum]) {
248f73e5cebSJed Brown       PetscScalar *array;
249f73e5cebSJed Brown       Vec v;
250f73e5cebSJed Brown       ierr = DMGetGlobalVector(link->dm,&v);CHKERRQ(ierr);
251f73e5cebSJed Brown       ierr = VecGetArray(pvec,&array);CHKERRQ(ierr);
252f73e5cebSJed Brown       ierr = VecPlaceArray(v,array+link->rstart);CHKERRQ(ierr);
253f73e5cebSJed Brown       ierr = VecRestoreArray(pvec,&array);CHKERRQ(ierr);
254f73e5cebSJed Brown       vecs[wnum++] = v;
255f73e5cebSJed Brown     }
256f73e5cebSJed Brown   }
257f73e5cebSJed Brown   PetscFunctionReturn(0);
258f73e5cebSJed Brown }
259f73e5cebSJed Brown 
260f73e5cebSJed Brown #undef __FUNCT__
26147c6ae99SBarry Smith #define __FUNCT__ "DMCompositeRestoreAccess"
26247c6ae99SBarry Smith /*@C
263aa219208SBarry Smith     DMCompositeRestoreAccess - Returns the vectors obtained with DMCompositeGetAccess()
26447c6ae99SBarry Smith        representation.
26547c6ae99SBarry Smith 
26647c6ae99SBarry Smith     Collective on DMComposite
26747c6ae99SBarry Smith 
2689ae5db72SJed Brown     Input Parameters:
26947c6ae99SBarry Smith +    dm - the packer object
27047c6ae99SBarry Smith .    gvec - the global vector
2710298fd71SBarry Smith -    Vec* ... - the individual parallel vectors, NULL for those that are not needed
27247c6ae99SBarry Smith 
27347c6ae99SBarry Smith     Level: advanced
27447c6ae99SBarry Smith 
2759ae5db72SJed Brown .seealso  DMCompositeAddDM(), DMCreateGlobalVector(),
2766eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeScatter(),
277aa219208SBarry Smith          DMCompositeRestoreAccess(), DMCompositeGetAccess()
27847c6ae99SBarry Smith 
27947c6ae99SBarry Smith @*/
2807087cfbeSBarry Smith PetscErrorCode  DMCompositeRestoreAccess(DM dm,Vec gvec,...)
28147c6ae99SBarry Smith {
28247c6ae99SBarry Smith   va_list                Argp;
28347c6ae99SBarry Smith   PetscErrorCode         ierr;
28447c6ae99SBarry Smith   struct DMCompositeLink *next;
28547c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
28647c6ae99SBarry Smith 
28747c6ae99SBarry Smith   PetscFunctionBegin;
28847c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
28947c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
29047c6ae99SBarry Smith   next = com->next;
29147c6ae99SBarry Smith   if (!com->setup) {
292d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
29347c6ae99SBarry Smith   }
29447c6ae99SBarry Smith 
29547c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
29647c6ae99SBarry Smith   va_start(Argp,gvec);
29747c6ae99SBarry Smith   while (next) {
29847c6ae99SBarry Smith     Vec *vec;
29947c6ae99SBarry Smith     vec = va_arg(Argp, Vec*);
3009ae5db72SJed Brown     if (vec) {
3019ae5db72SJed Brown       ierr = VecResetArray(*vec);CHKERRQ(ierr);
3029ae5db72SJed Brown       ierr = DMRestoreGlobalVector(next->dm,vec);CHKERRQ(ierr);
30347c6ae99SBarry Smith     }
30447c6ae99SBarry Smith     next = next->next;
30547c6ae99SBarry Smith   }
30647c6ae99SBarry Smith   va_end(Argp);
30747c6ae99SBarry Smith   PetscFunctionReturn(0);
30847c6ae99SBarry Smith }
30947c6ae99SBarry Smith 
31047c6ae99SBarry Smith #undef __FUNCT__
311f73e5cebSJed Brown #define __FUNCT__ "DMCompositeRestoreAccessArray"
312f73e5cebSJed Brown /*@C
313f73e5cebSJed Brown     DMCompositeRestoreAccessArray - Returns the vectors obtained with DMCompositeGetAccessArray()
314f73e5cebSJed Brown 
315f73e5cebSJed Brown     Collective on DMComposite
316f73e5cebSJed Brown 
317f73e5cebSJed Brown     Input Parameters:
318f73e5cebSJed Brown +    dm - the packer object
319f73e5cebSJed Brown .    pvec - packed vector
320f73e5cebSJed Brown .    nwanted - number of vectors wanted
3210298fd71SBarry Smith .    wanted - sorted array of vectors wanted, or NULL to get all vectors
322f73e5cebSJed Brown -    vecs - array of global vectors to return
323f73e5cebSJed Brown 
324f73e5cebSJed Brown     Level: advanced
325f73e5cebSJed Brown 
326f73e5cebSJed Brown .seealso: DMCompositeRestoreAccess(), DMCompositeRestoreEntries(), DMCompositeScatter(), DMCompositeGather()
327f73e5cebSJed Brown @*/
328f73e5cebSJed Brown PetscErrorCode  DMCompositeRestoreAccessArray(DM dm,Vec pvec,PetscInt nwanted,const PetscInt *wanted,Vec *vecs)
329f73e5cebSJed Brown {
330f73e5cebSJed Brown   PetscErrorCode         ierr;
331f73e5cebSJed Brown   struct DMCompositeLink *link;
332f73e5cebSJed Brown   PetscInt               i,wnum;
333f73e5cebSJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
334f73e5cebSJed Brown 
335f73e5cebSJed Brown   PetscFunctionBegin;
336f73e5cebSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
337f73e5cebSJed Brown   PetscValidHeaderSpecific(pvec,VEC_CLASSID,2);
338f73e5cebSJed Brown   if (!com->setup) {
339f73e5cebSJed Brown     ierr = DMSetUp(dm);CHKERRQ(ierr);
340f73e5cebSJed Brown   }
341f73e5cebSJed Brown 
342f73e5cebSJed Brown   for (i=0,wnum=0,link=com->next; link && wnum<nwanted; i++,link=link->next) {
343f73e5cebSJed Brown     if (!wanted || i == wanted[wnum]) {
344f73e5cebSJed Brown       ierr = VecResetArray(vecs[wnum]);CHKERRQ(ierr);
345f73e5cebSJed Brown       ierr = DMRestoreGlobalVector(link->dm,&vecs[wnum]);CHKERRQ(ierr);
346f73e5cebSJed Brown       wnum++;
347f73e5cebSJed Brown     }
348f73e5cebSJed Brown   }
349f73e5cebSJed Brown   PetscFunctionReturn(0);
350f73e5cebSJed Brown }
351f73e5cebSJed Brown 
352f73e5cebSJed Brown #undef __FUNCT__
35347c6ae99SBarry Smith #define __FUNCT__ "DMCompositeScatter"
35447c6ae99SBarry Smith /*@C
35547c6ae99SBarry Smith     DMCompositeScatter - Scatters from a global packed vector into its individual local vectors
35647c6ae99SBarry Smith 
35747c6ae99SBarry Smith     Collective on DMComposite
35847c6ae99SBarry Smith 
3599ae5db72SJed Brown     Input Parameters:
36047c6ae99SBarry Smith +    dm - the packer object
36147c6ae99SBarry Smith .    gvec - the global vector
3620298fd71SBarry Smith -    Vec ... - the individual sequential vectors, NULL for those that are not needed
36347c6ae99SBarry Smith 
36447c6ae99SBarry Smith     Level: advanced
36547c6ae99SBarry Smith 
3669ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
3676eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
36847c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries()
36947c6ae99SBarry Smith 
37047c6ae99SBarry Smith @*/
3717087cfbeSBarry Smith PetscErrorCode  DMCompositeScatter(DM dm,Vec gvec,...)
37247c6ae99SBarry Smith {
37347c6ae99SBarry Smith   va_list                Argp;
37447c6ae99SBarry Smith   PetscErrorCode         ierr;
37547c6ae99SBarry Smith   struct DMCompositeLink *next;
3768fd8f222SJed Brown   PetscInt               cnt;
37747c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
37847c6ae99SBarry Smith 
37947c6ae99SBarry Smith   PetscFunctionBegin;
38047c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
38147c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
38247c6ae99SBarry Smith   if (!com->setup) {
383d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
38447c6ae99SBarry Smith   }
38547c6ae99SBarry Smith 
38647c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
38747c6ae99SBarry Smith   va_start(Argp,gvec);
3888fd8f222SJed Brown   for (cnt=3,next=com->next; next; cnt++,next=next->next) {
3899ae5db72SJed Brown     Vec local;
3909ae5db72SJed Brown     local = va_arg(Argp, Vec);
3919ae5db72SJed Brown     if (local) {
3929ae5db72SJed Brown       Vec         global;
39347c6ae99SBarry Smith       PetscScalar *array;
3949ae5db72SJed Brown       PetscValidHeaderSpecific(local,VEC_CLASSID,cnt);
3959ae5db72SJed Brown       ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
3969ae5db72SJed Brown       ierr = VecGetArray(gvec,&array);CHKERRQ(ierr);
3979ae5db72SJed Brown       ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr);
3989ae5db72SJed Brown       ierr = DMGlobalToLocalBegin(next->dm,global,INSERT_VALUES,local);CHKERRQ(ierr);
3999ae5db72SJed Brown       ierr = DMGlobalToLocalEnd(next->dm,global,INSERT_VALUES,local);CHKERRQ(ierr);
4009ae5db72SJed Brown       ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr);
4019ae5db72SJed Brown       ierr = VecResetArray(global);CHKERRQ(ierr);
4029ae5db72SJed Brown       ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
40347c6ae99SBarry Smith     }
40447c6ae99SBarry Smith   }
40547c6ae99SBarry Smith   va_end(Argp);
40647c6ae99SBarry Smith   PetscFunctionReturn(0);
40747c6ae99SBarry Smith }
40847c6ae99SBarry Smith 
40947c6ae99SBarry Smith #undef __FUNCT__
41047c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGather"
41147c6ae99SBarry Smith /*@C
41247c6ae99SBarry Smith     DMCompositeGather - Gathers into a global packed vector from its individual local vectors
41347c6ae99SBarry Smith 
41447c6ae99SBarry Smith     Collective on DMComposite
41547c6ae99SBarry Smith 
41647c6ae99SBarry Smith     Input Parameter:
41747c6ae99SBarry Smith +    dm - the packer object
41847c6ae99SBarry Smith .    gvec - the global vector
4190298fd71SBarry Smith -    Vec ... - the individual sequential vectors, NULL for any that are not needed
42047c6ae99SBarry Smith 
42147c6ae99SBarry Smith     Level: advanced
42247c6ae99SBarry Smith 
4239ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
4246eb61c8cSJed Brown          DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
42547c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries()
42647c6ae99SBarry Smith 
42747c6ae99SBarry Smith @*/
4287087cfbeSBarry Smith PetscErrorCode  DMCompositeGather(DM dm,Vec gvec,InsertMode imode,...)
42947c6ae99SBarry Smith {
43047c6ae99SBarry Smith   va_list                Argp;
43147c6ae99SBarry Smith   PetscErrorCode         ierr;
43247c6ae99SBarry Smith   struct DMCompositeLink *next;
43347c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
4348fd8f222SJed Brown   PetscInt               cnt;
43547c6ae99SBarry Smith 
43647c6ae99SBarry Smith   PetscFunctionBegin;
43747c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
43847c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
43947c6ae99SBarry Smith   if (!com->setup) {
440d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
44147c6ae99SBarry Smith   }
44247c6ae99SBarry Smith 
44347c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
444df0c820aSJed Brown   va_start(Argp,imode);
4458fd8f222SJed Brown   for (cnt=3,next=com->next; next; cnt++,next=next->next) {
4469ae5db72SJed Brown     Vec local;
4479ae5db72SJed Brown     local = va_arg(Argp, Vec);
4489ae5db72SJed Brown     if (local) {
44947c6ae99SBarry Smith       PetscScalar *array;
4509ae5db72SJed Brown       Vec         global;
4519ae5db72SJed Brown       PetscValidHeaderSpecific(local,VEC_CLASSID,cnt);
4529ae5db72SJed Brown       ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
4539ae5db72SJed Brown       ierr = VecGetArray(gvec,&array);CHKERRQ(ierr);
4549ae5db72SJed Brown       ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr);
4559ae5db72SJed Brown       ierr = DMLocalToGlobalBegin(next->dm,local,imode,global);CHKERRQ(ierr);
4569ae5db72SJed Brown       ierr = DMLocalToGlobalEnd(next->dm,local,imode,global);CHKERRQ(ierr);
4579ae5db72SJed Brown       ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr);
4589ae5db72SJed Brown       ierr = VecResetArray(global);CHKERRQ(ierr);
4599ae5db72SJed Brown       ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
46047c6ae99SBarry Smith     }
46147c6ae99SBarry Smith   }
46247c6ae99SBarry Smith   va_end(Argp);
46347c6ae99SBarry Smith   PetscFunctionReturn(0);
46447c6ae99SBarry Smith }
46547c6ae99SBarry Smith 
46647c6ae99SBarry Smith #undef __FUNCT__
46747c6ae99SBarry Smith #define __FUNCT__ "DMCompositeAddDM"
46847c6ae99SBarry Smith /*@C
469aa219208SBarry Smith     DMCompositeAddDM - adds a DM  vector to a DMComposite
47047c6ae99SBarry Smith 
47147c6ae99SBarry Smith     Collective on DMComposite
47247c6ae99SBarry Smith 
47347c6ae99SBarry Smith     Input Parameter:
47447c6ae99SBarry Smith +    dm - the packer object
47547c6ae99SBarry Smith -    dm - the DM object, if the DM is a da you will need to caste it with a (DM)
47647c6ae99SBarry Smith 
47747c6ae99SBarry Smith     Level: advanced
47847c6ae99SBarry Smith 
4790c010503SBarry Smith .seealso DMDestroy(), DMCompositeGather(), DMCompositeAddDM(), DMCreateGlobalVector(),
4806eb61c8cSJed Brown          DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
48147c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries()
48247c6ae99SBarry Smith 
48347c6ae99SBarry Smith @*/
4847087cfbeSBarry Smith PetscErrorCode  DMCompositeAddDM(DM dmc,DM dm)
48547c6ae99SBarry Smith {
48647c6ae99SBarry Smith   PetscErrorCode         ierr;
48706ebdd98SJed Brown   PetscInt               n,nlocal;
48847c6ae99SBarry Smith   struct DMCompositeLink *mine,*next;
48906ebdd98SJed Brown   Vec                    global,local;
49047c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dmc->data;
49147c6ae99SBarry Smith 
49247c6ae99SBarry Smith   PetscFunctionBegin;
49347c6ae99SBarry Smith   PetscValidHeaderSpecific(dmc,DM_CLASSID,1);
49447c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,2);
49547c6ae99SBarry Smith   next = com->next;
496ce94432eSBarry Smith   if (com->setup) SETERRQ(PetscObjectComm((PetscObject)dmc),PETSC_ERR_ARG_WRONGSTATE,"Cannot add a DM once you have used the DMComposite");
49747c6ae99SBarry Smith 
49847c6ae99SBarry Smith   /* create new link */
49947c6ae99SBarry Smith   ierr = PetscNew(struct DMCompositeLink,&mine);CHKERRQ(ierr);
50047c6ae99SBarry Smith   ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);
50147c6ae99SBarry Smith   ierr = DMGetGlobalVector(dm,&global);CHKERRQ(ierr);
50247c6ae99SBarry Smith   ierr = VecGetLocalSize(global,&n);CHKERRQ(ierr);
50347c6ae99SBarry Smith   ierr = DMRestoreGlobalVector(dm,&global);CHKERRQ(ierr);
50406ebdd98SJed Brown   ierr = DMGetLocalVector(dm,&local);CHKERRQ(ierr);
50506ebdd98SJed Brown   ierr = VecGetSize(local,&nlocal);CHKERRQ(ierr);
50606ebdd98SJed Brown   ierr = DMRestoreLocalVector(dm,&local);CHKERRQ(ierr);
5078865f1eaSKarl Rupp 
50847c6ae99SBarry Smith   mine->n      = n;
50906ebdd98SJed Brown   mine->nlocal = nlocal;
51047c6ae99SBarry Smith   mine->dm     = dm;
5110298fd71SBarry Smith   mine->next   = NULL;
51247c6ae99SBarry Smith   com->n      += n;
51347c6ae99SBarry Smith 
51447c6ae99SBarry Smith   /* add to end of list */
5158865f1eaSKarl Rupp   if (!next) com->next = mine;
5168865f1eaSKarl Rupp   else {
51747c6ae99SBarry Smith     while (next->next) next = next->next;
51847c6ae99SBarry Smith     next->next = mine;
51947c6ae99SBarry Smith   }
52047c6ae99SBarry Smith   com->nDM++;
52147c6ae99SBarry Smith   com->nmine++;
52247c6ae99SBarry Smith   PetscFunctionReturn(0);
52347c6ae99SBarry Smith }
52447c6ae99SBarry Smith 
525*9804daf3SBarry Smith #include <petscdraw.h>
5267087cfbeSBarry Smith extern PetscErrorCode  VecView_MPI(Vec,PetscViewer);
52747c6ae99SBarry Smith EXTERN_C_BEGIN
52847c6ae99SBarry Smith #undef __FUNCT__
52947c6ae99SBarry Smith #define __FUNCT__ "VecView_DMComposite"
5307087cfbeSBarry Smith PetscErrorCode  VecView_DMComposite(Vec gvec,PetscViewer viewer)
53147c6ae99SBarry Smith {
53247c6ae99SBarry Smith   DM                     dm;
53347c6ae99SBarry Smith   PetscErrorCode         ierr;
53447c6ae99SBarry Smith   struct DMCompositeLink *next;
53547c6ae99SBarry Smith   PetscBool              isdraw;
536cef07954SSatish Balay   DM_Composite           *com;
53747c6ae99SBarry Smith 
53847c6ae99SBarry Smith   PetscFunctionBegin;
539c688c046SMatthew G Knepley   ierr = VecGetDM(gvec, &dm);CHKERRQ(ierr);
540ce94432eSBarry Smith   if (!dm) SETERRQ(PetscObjectComm((PetscObject)gvec),PETSC_ERR_ARG_WRONG,"Vector not generated from a DMComposite");
54147c6ae99SBarry Smith   com  = (DM_Composite*)dm->data;
54247c6ae99SBarry Smith   next = com->next;
54347c6ae99SBarry Smith 
544251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
54547c6ae99SBarry Smith   if (!isdraw) {
54647c6ae99SBarry Smith     /* do I really want to call this? */
54747c6ae99SBarry Smith     ierr = VecView_MPI(gvec,viewer);CHKERRQ(ierr);
54847c6ae99SBarry Smith   } else {
54947c6ae99SBarry Smith     PetscInt cnt = 0;
55047c6ae99SBarry Smith 
55147c6ae99SBarry Smith     /* loop over packed objects, handling one at at time */
55247c6ae99SBarry Smith     while (next) {
55347c6ae99SBarry Smith       Vec         vec;
5549ae5db72SJed Brown       PetscScalar *array;
55547c6ae99SBarry Smith       PetscInt    bs;
55647c6ae99SBarry Smith 
5579ae5db72SJed Brown       /* Should use VecGetSubVector() eventually, but would need to forward the DM for that to work */
5589ae5db72SJed Brown       ierr = DMGetGlobalVector(next->dm,&vec);CHKERRQ(ierr);
5599ae5db72SJed Brown       ierr = VecGetArray(gvec,&array);CHKERRQ(ierr);
5609ae5db72SJed Brown       ierr = VecPlaceArray(vec,array+next->rstart);CHKERRQ(ierr);
5619ae5db72SJed Brown       ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr);
56247c6ae99SBarry Smith       ierr = VecView(vec,viewer);CHKERRQ(ierr);
56347c6ae99SBarry Smith       ierr = VecGetBlockSize(vec,&bs);CHKERRQ(ierr);
5649ae5db72SJed Brown       ierr = VecResetArray(vec);CHKERRQ(ierr);
5659ae5db72SJed Brown       ierr = DMRestoreGlobalVector(next->dm,&vec);CHKERRQ(ierr);
56647c6ae99SBarry Smith       ierr = PetscViewerDrawBaseAdd(viewer,bs);CHKERRQ(ierr);
56747c6ae99SBarry Smith       cnt += bs;
56847c6ae99SBarry Smith       next = next->next;
56947c6ae99SBarry Smith     }
57047c6ae99SBarry Smith     ierr = PetscViewerDrawBaseAdd(viewer,-cnt);CHKERRQ(ierr);
57147c6ae99SBarry Smith   }
57247c6ae99SBarry Smith   PetscFunctionReturn(0);
57347c6ae99SBarry Smith }
57447c6ae99SBarry Smith EXTERN_C_END
57547c6ae99SBarry Smith 
57647c6ae99SBarry Smith 
57747c6ae99SBarry Smith #undef __FUNCT__
5780c010503SBarry Smith #define __FUNCT__ "DMCreateGlobalVector_Composite"
5797087cfbeSBarry Smith PetscErrorCode  DMCreateGlobalVector_Composite(DM dm,Vec *gvec)
58047c6ae99SBarry Smith {
58147c6ae99SBarry Smith   PetscErrorCode ierr;
58247c6ae99SBarry Smith   DM_Composite   *com = (DM_Composite*)dm->data;
58347c6ae99SBarry Smith 
58447c6ae99SBarry Smith   PetscFunctionBegin;
58547c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
586d7bf68aeSBarry Smith   ierr = DMSetUp(dm);CHKERRQ(ierr);
587ce94432eSBarry Smith   ierr = VecCreateMPI(PetscObjectComm((PetscObject)dm),com->n,com->N,gvec);CHKERRQ(ierr);
588c688c046SMatthew G Knepley   ierr = VecSetDM(*gvec, dm);CHKERRQ(ierr);
58947c6ae99SBarry Smith   ierr = VecSetOperation(*gvec,VECOP_VIEW,(void (*)(void))VecView_DMComposite);CHKERRQ(ierr);
59047c6ae99SBarry Smith   PetscFunctionReturn(0);
59147c6ae99SBarry Smith }
59247c6ae99SBarry Smith 
59347c6ae99SBarry Smith #undef __FUNCT__
5940c010503SBarry Smith #define __FUNCT__ "DMCreateLocalVector_Composite"
5957087cfbeSBarry Smith PetscErrorCode  DMCreateLocalVector_Composite(DM dm,Vec *lvec)
59647c6ae99SBarry Smith {
59747c6ae99SBarry Smith   PetscErrorCode ierr;
59847c6ae99SBarry Smith   DM_Composite   *com = (DM_Composite*)dm->data;
59947c6ae99SBarry Smith 
60047c6ae99SBarry Smith   PetscFunctionBegin;
60147c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
60247c6ae99SBarry Smith   if (!com->setup) {
603d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
60447c6ae99SBarry Smith   }
605ce94432eSBarry Smith   ierr = VecCreateSeq(PetscObjectComm((PetscObject)dm),com->nghost,lvec);CHKERRQ(ierr);
606c688c046SMatthew G Knepley   ierr = VecSetDM(*lvec, dm);CHKERRQ(ierr);
60747c6ae99SBarry Smith   PetscFunctionReturn(0);
60847c6ae99SBarry Smith }
60947c6ae99SBarry Smith 
61047c6ae99SBarry Smith #undef __FUNCT__
6116eb61c8cSJed Brown #define __FUNCT__ "DMCompositeGetISLocalToGlobalMappings"
61247c6ae99SBarry Smith /*@C
6139ae5db72SJed Brown     DMCompositeGetISLocalToGlobalMappings - gets an ISLocalToGlobalMapping for each DM in the DMComposite, maps to the composite global space
61447c6ae99SBarry Smith 
61506ebdd98SJed Brown     Collective on DM
61647c6ae99SBarry Smith 
61747c6ae99SBarry Smith     Input Parameter:
61847c6ae99SBarry Smith .    dm - the packer object
61947c6ae99SBarry Smith 
62047c6ae99SBarry Smith     Output Parameters:
6219ae5db72SJed Brown .    ltogs - the individual mappings for each packed vector. Note that this includes
6229ae5db72SJed Brown            all the ghost points that individual ghosted DMDA's may have.
62347c6ae99SBarry Smith 
62447c6ae99SBarry Smith     Level: advanced
62547c6ae99SBarry Smith 
62647c6ae99SBarry Smith     Notes:
6276eb61c8cSJed Brown        Each entry of ltogs should be destroyed with ISLocalToGlobalMappingDestroy(), the ltogs array should be freed with PetscFree().
62847c6ae99SBarry Smith 
6299ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
63047c6ae99SBarry Smith          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetAccess(), DMCompositeScatter(),
63147c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(),DMCompositeGetEntries()
63247c6ae99SBarry Smith 
63347c6ae99SBarry Smith @*/
6347087cfbeSBarry Smith PetscErrorCode  DMCompositeGetISLocalToGlobalMappings(DM dm,ISLocalToGlobalMapping **ltogs)
63547c6ae99SBarry Smith {
63647c6ae99SBarry Smith   PetscErrorCode         ierr;
63747c6ae99SBarry Smith   PetscInt               i,*idx,n,cnt;
63847c6ae99SBarry Smith   struct DMCompositeLink *next;
63947c6ae99SBarry Smith   PetscMPIInt            rank;
64047c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
64147c6ae99SBarry Smith 
64247c6ae99SBarry Smith   PetscFunctionBegin;
64347c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
644728e99d6SJed Brown   ierr = DMSetUp(dm);CHKERRQ(ierr);
6459ae5db72SJed Brown   ierr = PetscMalloc((com->nDM)*sizeof(ISLocalToGlobalMapping),ltogs);CHKERRQ(ierr);
64647c6ae99SBarry Smith   next = com->next;
647ce94432eSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
64847c6ae99SBarry Smith 
64947c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
65047c6ae99SBarry Smith   cnt = 0;
65147c6ae99SBarry Smith   while (next) {
6526eb61c8cSJed Brown     ISLocalToGlobalMapping ltog;
6536eb61c8cSJed Brown     PetscMPIInt            size;
65486994e45SJed Brown     const PetscInt         *suboff,*indices;
6556eb61c8cSJed Brown     Vec                    global;
65647c6ae99SBarry Smith 
6576eb61c8cSJed Brown     /* Get sub-DM global indices for each local dof */
6581411c6eeSJed Brown     ierr = DMGetLocalToGlobalMapping(next->dm,&ltog);CHKERRQ(ierr);
6596eb61c8cSJed Brown     ierr = ISLocalToGlobalMappingGetSize(ltog,&n);CHKERRQ(ierr);
66086994e45SJed Brown     ierr = ISLocalToGlobalMappingGetIndices(ltog,&indices);CHKERRQ(ierr);
66147c6ae99SBarry Smith     ierr = PetscMalloc(n*sizeof(PetscInt),&idx);CHKERRQ(ierr);
66247c6ae99SBarry Smith 
6636eb61c8cSJed Brown     /* Get the offsets for the sub-DM global vector */
6646eb61c8cSJed Brown     ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
6656eb61c8cSJed Brown     ierr = VecGetOwnershipRanges(global,&suboff);CHKERRQ(ierr);
666ce94432eSBarry Smith     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)global),&size);CHKERRQ(ierr);
6676eb61c8cSJed Brown 
6686eb61c8cSJed Brown     /* Shift the sub-DM definition of the global space to the composite global space */
6696eb61c8cSJed Brown     for (i=0; i<n; i++) {
67086994e45SJed Brown       PetscInt subi = indices[i],lo = 0,hi = size,t;
6716eb61c8cSJed Brown       /* Binary search to find which rank owns subi */
6726eb61c8cSJed Brown       while (hi-lo > 1) {
6736eb61c8cSJed Brown         t = lo + (hi-lo)/2;
6746eb61c8cSJed Brown         if (suboff[t] > subi) hi = t;
6756eb61c8cSJed Brown         else                  lo = t;
6766eb61c8cSJed Brown       }
6776eb61c8cSJed Brown       idx[i] = subi - suboff[lo] + next->grstarts[lo];
6786eb61c8cSJed Brown     }
67986994e45SJed Brown     ierr = ISLocalToGlobalMappingRestoreIndices(ltog,&indices);CHKERRQ(ierr);
680ce94432eSBarry Smith     ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)dm),n,idx,PETSC_OWN_POINTER,&(*ltogs)[cnt]);CHKERRQ(ierr);
6816eb61c8cSJed Brown     ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
68247c6ae99SBarry Smith     next = next->next;
68347c6ae99SBarry Smith     cnt++;
68447c6ae99SBarry Smith   }
68547c6ae99SBarry Smith   PetscFunctionReturn(0);
68647c6ae99SBarry Smith }
68747c6ae99SBarry Smith 
68847c6ae99SBarry Smith #undef __FUNCT__
68987c85e80SJed Brown #define __FUNCT__ "DMCompositeGetLocalISs"
69087c85e80SJed Brown /*@C
6919ae5db72SJed Brown    DMCompositeGetLocalISs - Gets index sets for each component of a composite local vector
69287c85e80SJed Brown 
69387c85e80SJed Brown    Not Collective
69487c85e80SJed Brown 
69587c85e80SJed Brown    Input Arguments:
69687c85e80SJed Brown . dm - composite DM
69787c85e80SJed Brown 
69887c85e80SJed Brown    Output Arguments:
69987c85e80SJed Brown . is - array of serial index sets for each each component of the DMComposite
70087c85e80SJed Brown 
70187c85e80SJed Brown    Level: intermediate
70287c85e80SJed Brown 
70387c85e80SJed Brown    Notes:
70487c85e80SJed Brown    At present, a composite local vector does not normally exist.  This function is used to provide index sets for
70587c85e80SJed Brown    MatGetLocalSubMatrix().  In the future, the scatters for each entry in the DMComposite may be be merged into a single
7069ae5db72SJed Brown    scatter to a composite local vector.  The user should not typically need to know which is being done.
70787c85e80SJed Brown 
70887c85e80SJed Brown    To get the composite global indices at all local points (including ghosts), use DMCompositeGetISLocalToGlobalMappings().
70987c85e80SJed Brown 
71087c85e80SJed Brown    To get index sets for pieces of the composite global vector, use DMCompositeGetGlobalISs().
71187c85e80SJed Brown 
71287c85e80SJed Brown    Each returned IS should be destroyed with ISDestroy(), the array should be freed with PetscFree().
71387c85e80SJed Brown 
71487c85e80SJed Brown .seealso: DMCompositeGetGlobalISs(), DMCompositeGetISLocalToGlobalMappings(), MatGetLocalSubMatrix(), MatCreateLocalRef()
71587c85e80SJed Brown @*/
7167087cfbeSBarry Smith PetscErrorCode  DMCompositeGetLocalISs(DM dm,IS **is)
71787c85e80SJed Brown {
71887c85e80SJed Brown   PetscErrorCode         ierr;
71987c85e80SJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
72087c85e80SJed Brown   struct DMCompositeLink *link;
72187c85e80SJed Brown   PetscInt               cnt,start;
72287c85e80SJed Brown 
72387c85e80SJed Brown   PetscFunctionBegin;
72487c85e80SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
72587c85e80SJed Brown   PetscValidPointer(is,2);
72687c85e80SJed Brown   ierr = PetscMalloc(com->nmine*sizeof(IS),is);CHKERRQ(ierr);
72706ebdd98SJed Brown   for (cnt=0,start=0,link=com->next; link; start+=link->nlocal,cnt++,link=link->next) {
728520db06cSJed Brown     PetscInt bs;
7299ae5db72SJed Brown     ierr = ISCreateStride(PETSC_COMM_SELF,link->nlocal,start,1,&(*is)[cnt]);CHKERRQ(ierr);
7301411c6eeSJed Brown     ierr = DMGetBlockSize(link->dm,&bs);CHKERRQ(ierr);
731520db06cSJed Brown     ierr = ISSetBlockSize((*is)[cnt],bs);CHKERRQ(ierr);
732520db06cSJed Brown   }
73387c85e80SJed Brown   PetscFunctionReturn(0);
73487c85e80SJed Brown }
73587c85e80SJed Brown 
73687c85e80SJed Brown #undef __FUNCT__
73747c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetGlobalISs"
73847c6ae99SBarry Smith /*@C
73947c6ae99SBarry Smith     DMCompositeGetGlobalISs - Gets the index sets for each composed object
74047c6ae99SBarry Smith 
74147c6ae99SBarry Smith     Collective on DMComposite
74247c6ae99SBarry Smith 
74347c6ae99SBarry Smith     Input Parameter:
74447c6ae99SBarry Smith .    dm - the packer object
74547c6ae99SBarry Smith 
74647c6ae99SBarry Smith     Output Parameters:
74747c6ae99SBarry Smith .    is - the array of index sets
74847c6ae99SBarry Smith 
74947c6ae99SBarry Smith     Level: advanced
75047c6ae99SBarry Smith 
75147c6ae99SBarry Smith     Notes:
75247c6ae99SBarry Smith        The is entries should be destroyed with ISDestroy(), the is array should be freed with PetscFree()
75347c6ae99SBarry Smith 
75447c6ae99SBarry Smith        These could be used to extract a subset of vector entries for a "multi-physics" preconditioner
75547c6ae99SBarry Smith 
7566eb61c8cSJed Brown        Use DMCompositeGetLocalISs() for index sets in the packed local numbering, and
7576eb61c8cSJed Brown        DMCompositeGetISLocalToGlobalMappings() for to map local sub-DM (including ghost) indices to packed global
7586eb61c8cSJed Brown        indices.
75947c6ae99SBarry Smith 
7609ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
76147c6ae99SBarry Smith          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetAccess(), DMCompositeScatter(),
76247c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(),DMCompositeGetEntries()
76347c6ae99SBarry Smith 
76447c6ae99SBarry Smith @*/
7656eb61c8cSJed Brown 
7667087cfbeSBarry Smith PetscErrorCode  DMCompositeGetGlobalISs(DM dm,IS *is[])
76747c6ae99SBarry Smith {
76847c6ae99SBarry Smith   PetscErrorCode         ierr;
76947c6ae99SBarry Smith   PetscInt               cnt = 0,*idx,i;
77047c6ae99SBarry Smith   struct DMCompositeLink *next;
77147c6ae99SBarry Smith   PetscMPIInt            rank;
77247c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
77347c6ae99SBarry Smith 
77447c6ae99SBarry Smith   PetscFunctionBegin;
77547c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7769ae5db72SJed Brown   ierr = PetscMalloc((com->nDM)*sizeof(IS),is);CHKERRQ(ierr);
77747c6ae99SBarry Smith   next = com->next;
778ce94432eSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
77947c6ae99SBarry Smith 
78047c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
78147c6ae99SBarry Smith   while (next) {
78247c6ae99SBarry Smith     ierr = PetscMalloc(next->n*sizeof(PetscInt),&idx);CHKERRQ(ierr);
78347c6ae99SBarry Smith     for (i=0; i<next->n; i++) idx[i] = next->grstart + i;
784ce94432eSBarry Smith     ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm),next->n,idx,PETSC_OWN_POINTER,&(*is)[cnt]);CHKERRQ(ierr);
78547c6ae99SBarry Smith     cnt++;
78647c6ae99SBarry Smith     next = next->next;
78747c6ae99SBarry Smith   }
78847c6ae99SBarry Smith   PetscFunctionReturn(0);
78947c6ae99SBarry Smith }
79047c6ae99SBarry Smith 
7914d343eeaSMatthew G Knepley #undef __FUNCT__
7924d343eeaSMatthew G Knepley #define __FUNCT__ "DMCreateFieldIS_Composite"
79321c9b008SJed Brown PetscErrorCode DMCreateFieldIS_Composite(DM dm, PetscInt *numFields,char ***fieldNames, IS **fields)
7944d343eeaSMatthew G Knepley {
7954d343eeaSMatthew G Knepley   PetscInt       nDM;
7964d343eeaSMatthew G Knepley   DM             *dms;
7974d343eeaSMatthew G Knepley   PetscInt       i;
7984d343eeaSMatthew G Knepley   PetscErrorCode ierr;
7994d343eeaSMatthew G Knepley 
8004d343eeaSMatthew G Knepley   PetscFunctionBegin;
8014d343eeaSMatthew G Knepley   ierr = DMCompositeGetNumberDM(dm, &nDM);CHKERRQ(ierr);
8028865f1eaSKarl Rupp   if (numFields) *numFields = nDM;
8034d343eeaSMatthew G Knepley   ierr = DMCompositeGetGlobalISs(dm, fields);CHKERRQ(ierr);
8044d343eeaSMatthew G Knepley   if (fieldNames) {
8054d343eeaSMatthew G Knepley     ierr = PetscMalloc(nDM*sizeof(DM), &dms);CHKERRQ(ierr);
8064d343eeaSMatthew G Knepley     ierr = PetscMalloc(nDM*sizeof(const char*), fieldNames);CHKERRQ(ierr);
8074d343eeaSMatthew G Knepley     ierr = DMCompositeGetEntriesArray(dm, dms);CHKERRQ(ierr);
8084d343eeaSMatthew G Knepley     for (i=0; i<nDM; i++) {
8094d343eeaSMatthew G Knepley       char       buf[256];
8104d343eeaSMatthew G Knepley       const char *splitname;
8114d343eeaSMatthew G Knepley 
8124d343eeaSMatthew G Knepley       /* Split naming precedence: object name, prefix, number */
8134d343eeaSMatthew G Knepley       splitname = ((PetscObject) dm)->name;
8144d343eeaSMatthew G Knepley       if (!splitname) {
8154d343eeaSMatthew G Knepley         ierr = PetscObjectGetOptionsPrefix((PetscObject)dms[i],&splitname);CHKERRQ(ierr);
8164d343eeaSMatthew G Knepley         if (splitname) {
8174d343eeaSMatthew G Knepley           size_t len;
8188caf3d72SBarry Smith           ierr                 = PetscStrncpy(buf,splitname,sizeof(buf));CHKERRQ(ierr);
8198caf3d72SBarry Smith           buf[sizeof(buf) - 1] = 0;
8204d343eeaSMatthew G Knepley           ierr                 = PetscStrlen(buf,&len);CHKERRQ(ierr);
8214d343eeaSMatthew G Knepley           if (buf[len-1] == '_') buf[len-1] = 0; /* Remove trailing underscore if it was used */
8224d343eeaSMatthew G Knepley           splitname = buf;
8234d343eeaSMatthew G Knepley         }
8244d343eeaSMatthew G Knepley       }
8254d343eeaSMatthew G Knepley       if (!splitname) {
8268caf3d72SBarry Smith         ierr      = PetscSNPrintf(buf,sizeof(buf),"%D",i);CHKERRQ(ierr);
8274d343eeaSMatthew G Knepley         splitname = buf;
8284d343eeaSMatthew G Knepley       }
82921c9b008SJed Brown       ierr = PetscStrallocpy(splitname,&(*fieldNames)[i]);CHKERRQ(ierr);
8304d343eeaSMatthew G Knepley     }
8314d343eeaSMatthew G Knepley     ierr = PetscFree(dms);CHKERRQ(ierr);
8324d343eeaSMatthew G Knepley   }
8334d343eeaSMatthew G Knepley   PetscFunctionReturn(0);
8344d343eeaSMatthew G Knepley }
8354d343eeaSMatthew G Knepley 
836e7c4fc90SDmitry Karpeev /*
837e7c4fc90SDmitry Karpeev  This could take over from DMCreateFieldIS(), as it is more general,
8380298fd71SBarry Smith  making DMCreateFieldIS() a special case -- calling with dmlist == NULL;
839e7c4fc90SDmitry Karpeev  At this point it's probably best to be less intrusive, however.
840e7c4fc90SDmitry Karpeev  */
841e7c4fc90SDmitry Karpeev #undef __FUNCT__
84216621825SDmitry Karpeev #define __FUNCT__ "DMCreateFieldDecomposition_Composite"
84316621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecomposition_Composite(DM dm, PetscInt *len,char ***namelist, IS **islist, DM **dmlist)
844e7c4fc90SDmitry Karpeev {
845e7c4fc90SDmitry Karpeev   PetscInt       nDM;
846e7c4fc90SDmitry Karpeev   PetscInt       i;
847e7c4fc90SDmitry Karpeev   PetscErrorCode ierr;
848e7c4fc90SDmitry Karpeev 
849e7c4fc90SDmitry Karpeev   PetscFunctionBegin;
850e7c4fc90SDmitry Karpeev   ierr = DMCreateFieldIS_Composite(dm, len, namelist, islist);CHKERRQ(ierr);
851e7c4fc90SDmitry Karpeev   if (dmlist) {
852e7c4fc90SDmitry Karpeev     ierr = DMCompositeGetNumberDM(dm, &nDM);CHKERRQ(ierr);
853e7c4fc90SDmitry Karpeev     ierr = PetscMalloc(nDM*sizeof(DM), dmlist);CHKERRQ(ierr);
854e7c4fc90SDmitry Karpeev     ierr = DMCompositeGetEntriesArray(dm, *dmlist);CHKERRQ(ierr);
855e7c4fc90SDmitry Karpeev     for (i=0; i<nDM; i++) {
856e7c4fc90SDmitry Karpeev       ierr = PetscObjectReference((PetscObject)((*dmlist)[i]));CHKERRQ(ierr);
857e7c4fc90SDmitry Karpeev     }
858e7c4fc90SDmitry Karpeev   }
859e7c4fc90SDmitry Karpeev   PetscFunctionReturn(0);
860e7c4fc90SDmitry Karpeev }
861e7c4fc90SDmitry Karpeev 
862e7c4fc90SDmitry Karpeev 
863e7c4fc90SDmitry Karpeev 
86447c6ae99SBarry Smith /* -------------------------------------------------------------------------------------*/
86547c6ae99SBarry Smith #undef __FUNCT__
86647c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetLocalVectors"
86747c6ae99SBarry Smith /*@C
8689ae5db72SJed Brown     DMCompositeGetLocalVectors - Gets local vectors for each part of a DMComposite.
86947c6ae99SBarry Smith        Use DMCompositeRestoreLocalVectors() to return them.
87047c6ae99SBarry Smith 
87147c6ae99SBarry Smith     Not Collective
87247c6ae99SBarry Smith 
87347c6ae99SBarry Smith     Input Parameter:
87447c6ae99SBarry Smith .    dm - the packer object
87547c6ae99SBarry Smith 
87647c6ae99SBarry Smith     Output Parameter:
8779ae5db72SJed Brown .   Vec ... - the individual sequential Vecs
87847c6ae99SBarry Smith 
87947c6ae99SBarry Smith     Level: advanced
88047c6ae99SBarry Smith 
8819ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
8826eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
88347c6ae99SBarry Smith          DMCompositeRestoreLocalVectors(), DMCompositeScatter(), DMCompositeGetEntries()
88447c6ae99SBarry Smith 
88547c6ae99SBarry Smith @*/
8867087cfbeSBarry Smith PetscErrorCode  DMCompositeGetLocalVectors(DM dm,...)
88747c6ae99SBarry Smith {
88847c6ae99SBarry Smith   va_list                Argp;
88947c6ae99SBarry Smith   PetscErrorCode         ierr;
89047c6ae99SBarry Smith   struct DMCompositeLink *next;
89147c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
89247c6ae99SBarry Smith 
89347c6ae99SBarry Smith   PetscFunctionBegin;
89447c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
89547c6ae99SBarry Smith   next = com->next;
89647c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
89747c6ae99SBarry Smith   va_start(Argp,dm);
89847c6ae99SBarry Smith   while (next) {
89947c6ae99SBarry Smith     Vec *vec;
90047c6ae99SBarry Smith     vec = va_arg(Argp, Vec*);
90106930112SJed Brown     if (vec) {ierr = DMGetLocalVector(next->dm,vec);CHKERRQ(ierr);}
90247c6ae99SBarry Smith     next = next->next;
90347c6ae99SBarry Smith   }
90447c6ae99SBarry Smith   va_end(Argp);
90547c6ae99SBarry Smith   PetscFunctionReturn(0);
90647c6ae99SBarry Smith }
90747c6ae99SBarry Smith 
90847c6ae99SBarry Smith #undef __FUNCT__
90947c6ae99SBarry Smith #define __FUNCT__ "DMCompositeRestoreLocalVectors"
91047c6ae99SBarry Smith /*@C
9119ae5db72SJed Brown     DMCompositeRestoreLocalVectors - Restores local vectors for each part of a DMComposite.
91247c6ae99SBarry Smith 
91347c6ae99SBarry Smith     Not Collective
91447c6ae99SBarry Smith 
91547c6ae99SBarry Smith     Input Parameter:
91647c6ae99SBarry Smith .    dm - the packer object
91747c6ae99SBarry Smith 
91847c6ae99SBarry Smith     Output Parameter:
9199ae5db72SJed Brown .   Vec ... - the individual sequential Vecs
92047c6ae99SBarry Smith 
92147c6ae99SBarry Smith     Level: advanced
92247c6ae99SBarry Smith 
9239ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
9246eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
92547c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeScatter(), DMCompositeGetEntries()
92647c6ae99SBarry Smith 
92747c6ae99SBarry Smith @*/
9287087cfbeSBarry Smith PetscErrorCode  DMCompositeRestoreLocalVectors(DM dm,...)
92947c6ae99SBarry Smith {
93047c6ae99SBarry Smith   va_list                Argp;
93147c6ae99SBarry Smith   PetscErrorCode         ierr;
93247c6ae99SBarry Smith   struct DMCompositeLink *next;
93347c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
93447c6ae99SBarry Smith 
93547c6ae99SBarry Smith   PetscFunctionBegin;
93647c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
93747c6ae99SBarry Smith   next = com->next;
93847c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
93947c6ae99SBarry Smith   va_start(Argp,dm);
94047c6ae99SBarry Smith   while (next) {
94147c6ae99SBarry Smith     Vec *vec;
94247c6ae99SBarry Smith     vec = va_arg(Argp, Vec*);
94306930112SJed Brown     if (vec) {ierr = DMRestoreLocalVector(next->dm,vec);CHKERRQ(ierr);}
94447c6ae99SBarry Smith     next = next->next;
94547c6ae99SBarry Smith   }
94647c6ae99SBarry Smith   va_end(Argp);
94747c6ae99SBarry Smith   PetscFunctionReturn(0);
94847c6ae99SBarry Smith }
94947c6ae99SBarry Smith 
95047c6ae99SBarry Smith /* -------------------------------------------------------------------------------------*/
95147c6ae99SBarry Smith #undef __FUNCT__
95247c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetEntries"
95347c6ae99SBarry Smith /*@C
9549ae5db72SJed Brown     DMCompositeGetEntries - Gets the DM for each entry in a DMComposite.
95547c6ae99SBarry Smith 
95647c6ae99SBarry Smith     Not Collective
95747c6ae99SBarry Smith 
95847c6ae99SBarry Smith     Input Parameter:
95947c6ae99SBarry Smith .    dm - the packer object
96047c6ae99SBarry Smith 
96147c6ae99SBarry Smith     Output Parameter:
9629ae5db72SJed Brown .   DM ... - the individual entries (DMs)
96347c6ae99SBarry Smith 
96447c6ae99SBarry Smith     Level: advanced
96547c6ae99SBarry Smith 
9662fa5ba8aSJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), DMCompositeGetEntriesArray()
9676eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
96847c6ae99SBarry Smith          DMCompositeRestoreLocalVectors(), DMCompositeGetLocalVectors(),  DMCompositeScatter(),
96947c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors()
97047c6ae99SBarry Smith 
97147c6ae99SBarry Smith @*/
9727087cfbeSBarry Smith PetscErrorCode  DMCompositeGetEntries(DM dm,...)
97347c6ae99SBarry Smith {
97447c6ae99SBarry Smith   va_list                Argp;
97547c6ae99SBarry Smith   struct DMCompositeLink *next;
97647c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
97747c6ae99SBarry Smith 
97847c6ae99SBarry Smith   PetscFunctionBegin;
97947c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
98047c6ae99SBarry Smith   next = com->next;
98147c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
98247c6ae99SBarry Smith   va_start(Argp,dm);
98347c6ae99SBarry Smith   while (next) {
98447c6ae99SBarry Smith     DM *dmn;
98547c6ae99SBarry Smith     dmn = va_arg(Argp, DM*);
9869ae5db72SJed Brown     if (dmn) *dmn = next->dm;
98747c6ae99SBarry Smith     next = next->next;
98847c6ae99SBarry Smith   }
98947c6ae99SBarry Smith   va_end(Argp);
99047c6ae99SBarry Smith   PetscFunctionReturn(0);
99147c6ae99SBarry Smith }
99247c6ae99SBarry Smith 
99347c6ae99SBarry Smith #undef __FUNCT__
9942fa5ba8aSJed Brown #define __FUNCT__ "DMCompositeGetEntriesArray"
995dbab29e1SMark F. Adams /*@C
9962fa5ba8aSJed Brown     DMCompositeGetEntriesArray - Gets the DM for each entry in a DMComposite.
9972fa5ba8aSJed Brown 
9982fa5ba8aSJed Brown     Not Collective
9992fa5ba8aSJed Brown 
10002fa5ba8aSJed Brown     Input Parameter:
10012fa5ba8aSJed Brown +    dm - the packer object
10022fa5ba8aSJed Brown -    dms - array of sufficient length (see DMCompositeGetNumberDM()), holds the DMs on output
10032fa5ba8aSJed Brown 
10042fa5ba8aSJed Brown     Level: advanced
10052fa5ba8aSJed Brown 
10062fa5ba8aSJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), DMCompositeGetEntries()
10072fa5ba8aSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
10082fa5ba8aSJed Brown          DMCompositeRestoreLocalVectors(), DMCompositeGetLocalVectors(),  DMCompositeScatter(),
10092fa5ba8aSJed Brown          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors()
10102fa5ba8aSJed Brown 
10112fa5ba8aSJed Brown @*/
10122fa5ba8aSJed Brown PetscErrorCode DMCompositeGetEntriesArray(DM dm,DM dms[])
10132fa5ba8aSJed Brown {
10142fa5ba8aSJed Brown   struct DMCompositeLink *next;
10152fa5ba8aSJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
10162fa5ba8aSJed Brown   PetscInt               i;
10172fa5ba8aSJed Brown 
10182fa5ba8aSJed Brown   PetscFunctionBegin;
10192fa5ba8aSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
10202fa5ba8aSJed Brown   /* loop over packed objects, handling one at at time */
10212fa5ba8aSJed Brown   for (next=com->next,i=0; next; next=next->next,i++) dms[i] = next->dm;
10222fa5ba8aSJed Brown   PetscFunctionReturn(0);
10232fa5ba8aSJed Brown }
10242fa5ba8aSJed Brown 
10252fa5ba8aSJed Brown #undef __FUNCT__
10260c010503SBarry Smith #define __FUNCT__ "DMRefine_Composite"
10277087cfbeSBarry Smith PetscErrorCode  DMRefine_Composite(DM dmi,MPI_Comm comm,DM *fine)
102847c6ae99SBarry Smith {
102947c6ae99SBarry Smith   PetscErrorCode         ierr;
103047c6ae99SBarry Smith   struct DMCompositeLink *next;
103147c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dmi->data;
103247c6ae99SBarry Smith   DM                     dm;
103347c6ae99SBarry Smith 
103447c6ae99SBarry Smith   PetscFunctionBegin;
103547c6ae99SBarry Smith   PetscValidHeaderSpecific(dmi,DM_CLASSID,1);
1036ce94432eSBarry Smith   if (comm == MPI_COMM_NULL) {
1037ce94432eSBarry Smith     ierr = PetscObjectGetComm((PetscObject)dmi,&comm);CHKERRQ(ierr);
1038ce94432eSBarry Smith   }
10392ce3a92bSJed Brown   ierr = DMSetUp(dmi);CHKERRQ(ierr);
104047c6ae99SBarry Smith   next = com->next;
104147c6ae99SBarry Smith   ierr = DMCompositeCreate(comm,fine);CHKERRQ(ierr);
104247c6ae99SBarry Smith 
104347c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
104447c6ae99SBarry Smith   while (next) {
104547c6ae99SBarry Smith     ierr = DMRefine(next->dm,comm,&dm);CHKERRQ(ierr);
104647c6ae99SBarry Smith     ierr = DMCompositeAddDM(*fine,dm);CHKERRQ(ierr);
104747c6ae99SBarry Smith     ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr);
104847c6ae99SBarry Smith     next = next->next;
104947c6ae99SBarry Smith   }
105047c6ae99SBarry Smith   PetscFunctionReturn(0);
105147c6ae99SBarry Smith }
105247c6ae99SBarry Smith 
105314354c39SJed Brown #undef __FUNCT__
105414354c39SJed Brown #define __FUNCT__ "DMCoarsen_Composite"
105514354c39SJed Brown PetscErrorCode  DMCoarsen_Composite(DM dmi,MPI_Comm comm,DM *fine)
105614354c39SJed Brown {
105714354c39SJed Brown   PetscErrorCode         ierr;
105814354c39SJed Brown   struct DMCompositeLink *next;
105914354c39SJed Brown   DM_Composite           *com = (DM_Composite*)dmi->data;
106014354c39SJed Brown   DM                     dm;
106114354c39SJed Brown 
106214354c39SJed Brown   PetscFunctionBegin;
106314354c39SJed Brown   PetscValidHeaderSpecific(dmi,DM_CLASSID,1);
10642ce3a92bSJed Brown   ierr = DMSetUp(dmi);CHKERRQ(ierr);
10652ee06e3bSJed Brown   if (comm == MPI_COMM_NULL) {
106625296bd5SBarry Smith     ierr = PetscObjectGetComm((PetscObject)dmi,&comm);CHKERRQ(ierr);
106725296bd5SBarry Smith   }
106814354c39SJed Brown   next = com->next;
106914354c39SJed Brown   ierr = DMCompositeCreate(comm,fine);CHKERRQ(ierr);
107014354c39SJed Brown 
107114354c39SJed Brown   /* loop over packed objects, handling one at at time */
107214354c39SJed Brown   while (next) {
107314354c39SJed Brown     ierr = DMCoarsen(next->dm,comm,&dm);CHKERRQ(ierr);
107414354c39SJed Brown     ierr = DMCompositeAddDM(*fine,dm);CHKERRQ(ierr);
107514354c39SJed Brown     ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr);
107614354c39SJed Brown     next = next->next;
107714354c39SJed Brown   }
107814354c39SJed Brown   PetscFunctionReturn(0);
107914354c39SJed Brown }
108047c6ae99SBarry Smith 
108147c6ae99SBarry Smith #undef __FUNCT__
1082e727c939SJed Brown #define __FUNCT__ "DMCreateInterpolation_Composite"
1083e727c939SJed Brown PetscErrorCode  DMCreateInterpolation_Composite(DM coarse,DM fine,Mat *A,Vec *v)
108447c6ae99SBarry Smith {
108547c6ae99SBarry Smith   PetscErrorCode         ierr;
10869ae5db72SJed Brown   PetscInt               m,n,M,N,nDM,i;
108747c6ae99SBarry Smith   struct DMCompositeLink *nextc;
108847c6ae99SBarry Smith   struct DMCompositeLink *nextf;
108925296bd5SBarry Smith   Vec                    gcoarse,gfine,*vecs;
109047c6ae99SBarry Smith   DM_Composite           *comcoarse = (DM_Composite*)coarse->data;
109147c6ae99SBarry Smith   DM_Composite           *comfine   = (DM_Composite*)fine->data;
10929ae5db72SJed Brown   Mat                    *mats;
109347c6ae99SBarry Smith 
109447c6ae99SBarry Smith   PetscFunctionBegin;
109547c6ae99SBarry Smith   PetscValidHeaderSpecific(coarse,DM_CLASSID,1);
109647c6ae99SBarry Smith   PetscValidHeaderSpecific(fine,DM_CLASSID,2);
1097f692024eSJed Brown   ierr = DMSetUp(coarse);CHKERRQ(ierr);
1098f692024eSJed Brown   ierr = DMSetUp(fine);CHKERRQ(ierr);
109947c6ae99SBarry Smith   /* use global vectors only for determining matrix layout */
11009ae5db72SJed Brown   ierr = DMGetGlobalVector(coarse,&gcoarse);CHKERRQ(ierr);
11019ae5db72SJed Brown   ierr = DMGetGlobalVector(fine,&gfine);CHKERRQ(ierr);
110247c6ae99SBarry Smith   ierr = VecGetLocalSize(gcoarse,&n);CHKERRQ(ierr);
110347c6ae99SBarry Smith   ierr = VecGetLocalSize(gfine,&m);CHKERRQ(ierr);
110447c6ae99SBarry Smith   ierr = VecGetSize(gcoarse,&N);CHKERRQ(ierr);
110547c6ae99SBarry Smith   ierr = VecGetSize(gfine,&M);CHKERRQ(ierr);
11069ae5db72SJed Brown   ierr = DMRestoreGlobalVector(coarse,&gcoarse);CHKERRQ(ierr);
11079ae5db72SJed Brown   ierr = DMRestoreGlobalVector(fine,&gfine);CHKERRQ(ierr);
110847c6ae99SBarry Smith 
11099ae5db72SJed Brown   nDM = comfine->nDM;
1110ce94432eSBarry Smith   if (nDM != comcoarse->nDM) SETERRQ2(PetscObjectComm((PetscObject)fine),PETSC_ERR_ARG_INCOMP,"Fine DMComposite has %D entries, but coarse has %D",nDM,comcoarse->nDM);
11119ae5db72SJed Brown   ierr = PetscMalloc(nDM*nDM*sizeof(Mat),&mats);CHKERRQ(ierr);
11129ae5db72SJed Brown   ierr = PetscMemzero(mats,nDM*nDM*sizeof(Mat));CHKERRQ(ierr);
111325296bd5SBarry Smith   if (v) {
111425296bd5SBarry Smith     ierr = PetscMalloc(nDM*sizeof(Vec),&vecs);CHKERRQ(ierr);
111525296bd5SBarry Smith     ierr = PetscMemzero(vecs,nDM*sizeof(Vec));CHKERRQ(ierr);
111625296bd5SBarry Smith   }
111747c6ae99SBarry Smith 
111847c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
11199ae5db72SJed Brown   for (nextc=comcoarse->next,nextf=comfine->next,i=0; nextc; nextc=nextc->next,nextf=nextf->next,i++) {
112025296bd5SBarry Smith     if (!v) {
11210298fd71SBarry Smith       ierr = DMCreateInterpolation(nextc->dm,nextf->dm,&mats[i*nDM+i],NULL);CHKERRQ(ierr);
112225296bd5SBarry Smith     } else {
112325296bd5SBarry Smith       ierr = DMCreateInterpolation(nextc->dm,nextf->dm,&mats[i*nDM+i],&vecs[i]);CHKERRQ(ierr);
112425296bd5SBarry Smith     }
112547c6ae99SBarry Smith   }
1126ce94432eSBarry Smith   ierr = MatCreateNest(PetscObjectComm((PetscObject)fine),nDM,NULL,nDM,NULL,mats,A);CHKERRQ(ierr);
112725296bd5SBarry Smith   if (v) {
1128ce94432eSBarry Smith     ierr = VecCreateNest(PetscObjectComm((PetscObject)fine),nDM,NULL,vecs,v);CHKERRQ(ierr);
112925296bd5SBarry Smith   }
11309ae5db72SJed Brown   for (i=0; i<nDM*nDM; i++) {ierr = MatDestroy(&mats[i]);CHKERRQ(ierr);}
11319ae5db72SJed Brown   ierr = PetscFree(mats);CHKERRQ(ierr);
113225296bd5SBarry Smith   if (v) {
113325296bd5SBarry Smith     for (i=0; i<nDM; i++) {ierr = VecDestroy(&vecs[i]);CHKERRQ(ierr);}
113425296bd5SBarry Smith     ierr = PetscFree(vecs);CHKERRQ(ierr);
113525296bd5SBarry Smith   }
113647c6ae99SBarry Smith   PetscFunctionReturn(0);
113747c6ae99SBarry Smith }
113847c6ae99SBarry Smith 
113947c6ae99SBarry Smith #undef __FUNCT__
11401411c6eeSJed Brown #define __FUNCT__ "DMCreateLocalToGlobalMapping_Composite"
11411411c6eeSJed Brown static PetscErrorCode DMCreateLocalToGlobalMapping_Composite(DM dm)
11421411c6eeSJed Brown {
11431411c6eeSJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
11441411c6eeSJed Brown   ISLocalToGlobalMapping *ltogs;
1145f7efa3c7SJed Brown   PetscInt               i;
11461411c6eeSJed Brown   PetscErrorCode         ierr;
11471411c6eeSJed Brown 
11481411c6eeSJed Brown   PetscFunctionBegin;
11491411c6eeSJed Brown   /* Set the ISLocalToGlobalMapping on the new matrix */
11501411c6eeSJed Brown   ierr = DMCompositeGetISLocalToGlobalMappings(dm,&ltogs);CHKERRQ(ierr);
1151ce94432eSBarry Smith   ierr = ISLocalToGlobalMappingConcatenate(PetscObjectComm((PetscObject)dm),com->nDM,ltogs,&dm->ltogmap);CHKERRQ(ierr);
11529ae5db72SJed Brown   for (i=0; i<com->nDM; i++) {ierr = ISLocalToGlobalMappingDestroy(&ltogs[i]);CHKERRQ(ierr);}
11531411c6eeSJed Brown   ierr = PetscFree(ltogs);CHKERRQ(ierr);
11541411c6eeSJed Brown   PetscFunctionReturn(0);
11551411c6eeSJed Brown }
11561411c6eeSJed Brown 
11571411c6eeSJed Brown 
11581411c6eeSJed Brown #undef __FUNCT__
1159e727c939SJed Brown #define __FUNCT__ "DMCreateColoring_Composite"
116019fd82e9SBarry Smith PetscErrorCode  DMCreateColoring_Composite(DM dm,ISColoringType ctype,MatType mtype,ISColoring *coloring)
116147c6ae99SBarry Smith {
116247c6ae99SBarry Smith   PetscErrorCode  ierr;
116347c6ae99SBarry Smith   PetscInt        n,i,cnt;
116447c6ae99SBarry Smith   ISColoringValue *colors;
116547c6ae99SBarry Smith   PetscBool       dense  = PETSC_FALSE;
116647c6ae99SBarry Smith   ISColoringValue maxcol = 0;
116747c6ae99SBarry Smith   DM_Composite    *com   = (DM_Composite*)dm->data;
116847c6ae99SBarry Smith 
116947c6ae99SBarry Smith   PetscFunctionBegin;
117047c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1171ce94432eSBarry Smith   if (ctype == IS_COLORING_GHOSTED) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only global coloring supported");
1172e3247f34SBarry Smith   else if (ctype == IS_COLORING_GLOBAL) {
117347c6ae99SBarry Smith     n = com->n;
1174ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"Unknown ISColoringType");
117547c6ae99SBarry Smith   ierr = PetscMalloc(n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr); /* freed in ISColoringDestroy() */
117647c6ae99SBarry Smith 
11770298fd71SBarry Smith   ierr = PetscOptionsGetBool(NULL,"-dmcomposite_dense_jacobian",&dense,NULL);CHKERRQ(ierr);
117847c6ae99SBarry Smith   if (dense) {
117947c6ae99SBarry Smith     for (i=0; i<n; i++) {
118047c6ae99SBarry Smith       colors[i] = (ISColoringValue)(com->rstart + i);
118147c6ae99SBarry Smith     }
118247c6ae99SBarry Smith     maxcol = com->N;
118347c6ae99SBarry Smith   } else {
118447c6ae99SBarry Smith     struct DMCompositeLink *next = com->next;
118547c6ae99SBarry Smith     PetscMPIInt            rank;
118647c6ae99SBarry Smith 
1187ce94432eSBarry Smith     ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
118847c6ae99SBarry Smith     cnt  = 0;
118947c6ae99SBarry Smith     while (next) {
119047c6ae99SBarry Smith       ISColoring lcoloring;
119147c6ae99SBarry Smith 
1192e727c939SJed Brown       ierr = DMCreateColoring(next->dm,IS_COLORING_GLOBAL,mtype,&lcoloring);CHKERRQ(ierr);
119347c6ae99SBarry Smith       for (i=0; i<lcoloring->N; i++) {
119447c6ae99SBarry Smith         colors[cnt++] = maxcol + lcoloring->colors[i];
119547c6ae99SBarry Smith       }
119647c6ae99SBarry Smith       maxcol += lcoloring->n;
1197fcfd50ebSBarry Smith       ierr    = ISColoringDestroy(&lcoloring);CHKERRQ(ierr);
119847c6ae99SBarry Smith       next    = next->next;
119947c6ae99SBarry Smith     }
120047c6ae99SBarry Smith   }
1201ce94432eSBarry Smith   ierr = ISColoringCreate(PetscObjectComm((PetscObject)dm),maxcol,n,colors,coloring);CHKERRQ(ierr);
120247c6ae99SBarry Smith   PetscFunctionReturn(0);
120347c6ae99SBarry Smith }
120447c6ae99SBarry Smith 
120547c6ae99SBarry Smith #undef __FUNCT__
12060c010503SBarry Smith #define __FUNCT__ "DMGlobalToLocalBegin_Composite"
12077087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalBegin_Composite(DM dm,Vec gvec,InsertMode mode,Vec lvec)
120847c6ae99SBarry Smith {
120947c6ae99SBarry Smith   PetscErrorCode         ierr;
121047c6ae99SBarry Smith   struct DMCompositeLink *next;
121147c6ae99SBarry Smith   PetscInt               cnt = 3;
121247c6ae99SBarry Smith   PetscMPIInt            rank;
121347c6ae99SBarry Smith   PetscScalar            *garray,*larray;
121447c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
121547c6ae99SBarry Smith 
121647c6ae99SBarry Smith   PetscFunctionBegin;
121747c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
121847c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
121947c6ae99SBarry Smith   next = com->next;
122047c6ae99SBarry Smith   if (!com->setup) {
1221d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
122247c6ae99SBarry Smith   }
1223ce94432eSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
122447c6ae99SBarry Smith   ierr = VecGetArray(gvec,&garray);CHKERRQ(ierr);
122547c6ae99SBarry Smith   ierr = VecGetArray(lvec,&larray);CHKERRQ(ierr);
122647c6ae99SBarry Smith 
122747c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
122847c6ae99SBarry Smith   while (next) {
122947c6ae99SBarry Smith     Vec      local,global;
123047c6ae99SBarry Smith     PetscInt N;
123147c6ae99SBarry Smith 
123247c6ae99SBarry Smith     ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
123347c6ae99SBarry Smith     ierr = VecGetLocalSize(global,&N);CHKERRQ(ierr);
123447c6ae99SBarry Smith     ierr = VecPlaceArray(global,garray);CHKERRQ(ierr);
123547c6ae99SBarry Smith     ierr = DMGetLocalVector(next->dm,&local);CHKERRQ(ierr);
123647c6ae99SBarry Smith     ierr = VecPlaceArray(local,larray);CHKERRQ(ierr);
123747c6ae99SBarry Smith     ierr = DMGlobalToLocalBegin(next->dm,global,mode,local);CHKERRQ(ierr);
123847c6ae99SBarry Smith     ierr = DMGlobalToLocalEnd(next->dm,global,mode,local);CHKERRQ(ierr);
123947c6ae99SBarry Smith     ierr = VecResetArray(global);CHKERRQ(ierr);
124047c6ae99SBarry Smith     ierr = VecResetArray(local);CHKERRQ(ierr);
124147c6ae99SBarry Smith     ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
124247c6ae99SBarry Smith     ierr = DMRestoreGlobalVector(next->dm,&local);CHKERRQ(ierr);
124347c6ae99SBarry Smith     cnt++;
124406ebdd98SJed Brown     larray += next->nlocal;
124547c6ae99SBarry Smith     next    = next->next;
124647c6ae99SBarry Smith   }
124747c6ae99SBarry Smith 
12480298fd71SBarry Smith   ierr = VecRestoreArray(gvec,NULL);CHKERRQ(ierr);
12490298fd71SBarry Smith   ierr = VecRestoreArray(lvec,NULL);CHKERRQ(ierr);
125047c6ae99SBarry Smith   PetscFunctionReturn(0);
125147c6ae99SBarry Smith }
125247c6ae99SBarry Smith 
125347c6ae99SBarry Smith #undef __FUNCT__
12540c010503SBarry Smith #define __FUNCT__ "DMGlobalToLocalEnd_Composite"
12557087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalEnd_Composite(DM dm,Vec gvec,InsertMode mode,Vec lvec)
12560c010503SBarry Smith {
12570c010503SBarry Smith   PetscFunctionBegin;
12580c010503SBarry Smith   PetscFunctionReturn(0);
12590c010503SBarry Smith }
126047c6ae99SBarry Smith 
12616ae3a549SBarry Smith /*MC
12626ae3a549SBarry Smith    DMCOMPOSITE = "composite" - A DM object that is used to manage data for a collection of DMs
12636ae3a549SBarry Smith 
12646ae3a549SBarry Smith 
12656ae3a549SBarry Smith 
12666ae3a549SBarry Smith   Level: intermediate
12676ae3a549SBarry Smith 
12686ae3a549SBarry Smith .seealso: DMType, DMCOMPOSITE, DMDACreate(), DMCreate(), DMSetType(), DMCompositeCreate()
12696ae3a549SBarry Smith M*/
12706ae3a549SBarry Smith 
12716ae3a549SBarry Smith 
1272a4121054SBarry Smith EXTERN_C_BEGIN
1273a4121054SBarry Smith #undef __FUNCT__
1274a4121054SBarry Smith #define __FUNCT__ "DMCreate_Composite"
12757087cfbeSBarry Smith PetscErrorCode  DMCreate_Composite(DM p)
1276a4121054SBarry Smith {
1277a4121054SBarry Smith   PetscErrorCode ierr;
1278a4121054SBarry Smith   DM_Composite   *com;
1279a4121054SBarry Smith 
1280a4121054SBarry Smith   PetscFunctionBegin;
1281a4121054SBarry Smith   ierr      = PetscNewLog(p,DM_Composite,&com);CHKERRQ(ierr);
1282a4121054SBarry Smith   p->data   = com;
1283a4121054SBarry Smith   ierr      = PetscObjectChangeTypeName((PetscObject)p,"DMComposite");CHKERRQ(ierr);
1284a4121054SBarry Smith   com->n    = 0;
12850298fd71SBarry Smith   com->next = NULL;
1286a4121054SBarry Smith   com->nDM  = 0;
1287a4121054SBarry Smith 
1288a4121054SBarry Smith   p->ops->createglobalvector              = DMCreateGlobalVector_Composite;
1289a4121054SBarry Smith   p->ops->createlocalvector               = DMCreateLocalVector_Composite;
12901411c6eeSJed Brown   p->ops->createlocaltoglobalmapping      = DMCreateLocalToGlobalMapping_Composite;
12911411c6eeSJed Brown   p->ops->createlocaltoglobalmappingblock = 0;
12924d343eeaSMatthew G Knepley   p->ops->createfieldis                   = DMCreateFieldIS_Composite;
129316621825SDmitry Karpeev   p->ops->createfielddecomposition        = DMCreateFieldDecomposition_Composite;
1294a4121054SBarry Smith   p->ops->refine                          = DMRefine_Composite;
129514354c39SJed Brown   p->ops->coarsen                         = DMCoarsen_Composite;
129625296bd5SBarry Smith   p->ops->createinterpolation             = DMCreateInterpolation_Composite;
129725296bd5SBarry Smith   p->ops->creatematrix                    = DMCreateMatrix_Composite;
1298e727c939SJed Brown   p->ops->getcoloring                     = DMCreateColoring_Composite;
1299a4121054SBarry Smith   p->ops->globaltolocalbegin              = DMGlobalToLocalBegin_Composite;
1300a4121054SBarry Smith   p->ops->globaltolocalend                = DMGlobalToLocalEnd_Composite;
1301a4121054SBarry Smith   p->ops->destroy                         = DMDestroy_Composite;
1302a4121054SBarry Smith   p->ops->view                            = DMView_Composite;
1303a4121054SBarry Smith   p->ops->setup                           = DMSetUp_Composite;
1304a4121054SBarry Smith   PetscFunctionReturn(0);
1305a4121054SBarry Smith }
1306a4121054SBarry Smith EXTERN_C_END
1307a4121054SBarry Smith 
13080c010503SBarry Smith #undef __FUNCT__
13090c010503SBarry Smith #define __FUNCT__ "DMCompositeCreate"
13100c010503SBarry Smith /*@C
13110c010503SBarry Smith     DMCompositeCreate - Creates a vector packer, used to generate "composite"
13120c010503SBarry Smith       vectors made up of several subvectors.
13130c010503SBarry Smith 
13140c010503SBarry Smith     Collective on MPI_Comm
131547c6ae99SBarry Smith 
131647c6ae99SBarry Smith     Input Parameter:
13170c010503SBarry Smith .   comm - the processors that will share the global vector
13180c010503SBarry Smith 
13190c010503SBarry Smith     Output Parameters:
13200c010503SBarry Smith .   packer - the packer object
132147c6ae99SBarry Smith 
132247c6ae99SBarry Smith     Level: advanced
132347c6ae99SBarry Smith 
13249ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCompositeScatter(),
13256eb61c8cSJed Brown          DMCompositeGather(), DMCreateGlobalVector(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess()
132647c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries()
132747c6ae99SBarry Smith 
132847c6ae99SBarry Smith @*/
13297087cfbeSBarry Smith PetscErrorCode  DMCompositeCreate(MPI_Comm comm,DM *packer)
133047c6ae99SBarry Smith {
13310c010503SBarry Smith   PetscErrorCode ierr;
13320c010503SBarry Smith 
133347c6ae99SBarry Smith   PetscFunctionBegin;
13340c010503SBarry Smith   PetscValidPointer(packer,2);
1335a4121054SBarry Smith   ierr = DMCreate(comm,packer);CHKERRQ(ierr);
1336a4121054SBarry Smith   ierr = DMSetType(*packer,DMCOMPOSITE);CHKERRQ(ierr);
133747c6ae99SBarry Smith   PetscFunctionReturn(0);
133847c6ae99SBarry Smith }
1339