xref: /petsc/src/dm/impls/composite/pack.c (revision f73e5ceb545c3b2c6fd9fefc5673afd82126bd7a)
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;
9547c6ae99SBarry Smith   if (com->setup) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Packer has already been setup");
9647c6ae99SBarry Smith   ierr = PetscLayoutCreate(((PetscObject)dm)->comm,&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);
10247c6ae99SBarry Smith   ierr = PetscLayoutGetRange(map,&com->rstart,PETSC_NULL);CHKERRQ(ierr);
103fcfd50ebSBarry Smith   ierr = PetscLayoutDestroy(&map);CHKERRQ(ierr);
10447c6ae99SBarry Smith 
1059ae5db72SJed Brown   /* now set the rstart for each linked vector */
10647c6ae99SBarry Smith   ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr);
10747c6ae99SBarry Smith   ierr = MPI_Comm_size(((PetscObject)dm)->comm,&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);
11347c6ae99SBarry Smith     ierr          = MPI_Allgather(&next->grstart,1,MPIU_INT,next->grstarts,1,MPIU_INT,((PetscObject)dm)->comm);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 #include <stdarg.h>
12347c6ae99SBarry Smith 
12447c6ae99SBarry Smith #undef __FUNCT__
12547c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetNumberDM"
12673e31fe2SJed Brown /*@
12747c6ae99SBarry Smith     DMCompositeGetNumberDM - Get's the number of DM objects in the DMComposite
12847c6ae99SBarry Smith        representation.
12947c6ae99SBarry Smith 
13047c6ae99SBarry Smith     Not Collective
13147c6ae99SBarry Smith 
13247c6ae99SBarry Smith     Input Parameter:
13347c6ae99SBarry Smith .    dm - the packer object
13447c6ae99SBarry Smith 
13547c6ae99SBarry Smith     Output Parameter:
13647c6ae99SBarry Smith .     nDM - the number of DMs
13747c6ae99SBarry Smith 
13847c6ae99SBarry Smith     Level: beginner
13947c6ae99SBarry Smith 
14047c6ae99SBarry Smith @*/
1417087cfbeSBarry Smith PetscErrorCode  DMCompositeGetNumberDM(DM dm,PetscInt *nDM)
14247c6ae99SBarry Smith {
14347c6ae99SBarry Smith   DM_Composite *com = (DM_Composite*)dm->data;
1445fd66863SKarl Rupp 
14547c6ae99SBarry Smith   PetscFunctionBegin;
14647c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
14747c6ae99SBarry Smith   *nDM = com->nDM;
14847c6ae99SBarry Smith   PetscFunctionReturn(0);
14947c6ae99SBarry Smith }
15047c6ae99SBarry Smith 
15147c6ae99SBarry Smith 
15247c6ae99SBarry Smith #undef __FUNCT__
15347c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetAccess"
15447c6ae99SBarry Smith /*@C
15547c6ae99SBarry Smith     DMCompositeGetAccess - Allows one to access the individual packed vectors in their global
15647c6ae99SBarry Smith        representation.
15747c6ae99SBarry Smith 
15847c6ae99SBarry Smith     Collective on DMComposite
15947c6ae99SBarry Smith 
1609ae5db72SJed Brown     Input Parameters:
16147c6ae99SBarry Smith +    dm - the packer object
1629ae5db72SJed Brown -    gvec - the global vector
1639ae5db72SJed Brown 
1649ae5db72SJed Brown     Output Parameters:
1659ae5db72SJed Brown .    Vec* ... - the packed parallel vectors, PETSC_NULL for those that are not needed
16647c6ae99SBarry Smith 
16747c6ae99SBarry Smith     Notes: Use DMCompositeRestoreAccess() to return the vectors when you no longer need them
16847c6ae99SBarry Smith 
169*f73e5cebSJed Brown     Fortran Notes:
170*f73e5cebSJed Brown 
171*f73e5cebSJed Brown     Fortran callers must use numbered versions of this routine, e.g., DMCompositeGetAccess4(dm,gvec,vec1,vec2,vec3,vec4)
172*f73e5cebSJed Brown     or use the alternative interface DMCompositeGetAccessArray().
173*f73e5cebSJed Brown 
17447c6ae99SBarry Smith     Level: advanced
17547c6ae99SBarry Smith 
176*f73e5cebSJed Brown .seealso: DMCompositeGetEntries(), DMCompositeScatter()
17747c6ae99SBarry Smith @*/
1787087cfbeSBarry Smith PetscErrorCode  DMCompositeGetAccess(DM dm,Vec gvec,...)
17947c6ae99SBarry Smith {
18047c6ae99SBarry Smith   va_list                Argp;
18147c6ae99SBarry Smith   PetscErrorCode         ierr;
18247c6ae99SBarry Smith   struct DMCompositeLink *next;
18347c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
18447c6ae99SBarry Smith 
18547c6ae99SBarry Smith   PetscFunctionBegin;
18647c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
18747c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
18847c6ae99SBarry Smith   next = com->next;
18947c6ae99SBarry Smith   if (!com->setup) {
190d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
19147c6ae99SBarry Smith   }
19247c6ae99SBarry Smith 
19347c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
19447c6ae99SBarry Smith   va_start(Argp,gvec);
19547c6ae99SBarry Smith   while (next) {
19647c6ae99SBarry Smith     Vec *vec;
19747c6ae99SBarry Smith     vec = va_arg(Argp, Vec*);
1989ae5db72SJed Brown     if (vec) {
1999ae5db72SJed Brown       PetscScalar *array;
2009ae5db72SJed Brown       ierr = DMGetGlobalVector(next->dm,vec);CHKERRQ(ierr);
2019ae5db72SJed Brown       ierr = VecGetArray(gvec,&array);CHKERRQ(ierr);
2029ae5db72SJed Brown       ierr = VecPlaceArray(*vec,array+next->rstart);CHKERRQ(ierr);
2039ae5db72SJed Brown       ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr);
20447c6ae99SBarry Smith     }
20547c6ae99SBarry Smith     next = next->next;
20647c6ae99SBarry Smith   }
20747c6ae99SBarry Smith   va_end(Argp);
20847c6ae99SBarry Smith   PetscFunctionReturn(0);
20947c6ae99SBarry Smith }
21047c6ae99SBarry Smith 
21147c6ae99SBarry Smith #undef __FUNCT__
212*f73e5cebSJed Brown #define __FUNCT__ "DMCompositeGetAccessArray"
213*f73e5cebSJed Brown /*@C
214*f73e5cebSJed Brown     DMCompositeGetAccessArray - Allows one to access the individual packed vectors in their global
215*f73e5cebSJed Brown        representation.
216*f73e5cebSJed Brown 
217*f73e5cebSJed Brown     Collective on DMComposite
218*f73e5cebSJed Brown 
219*f73e5cebSJed Brown     Input Parameters:
220*f73e5cebSJed Brown +    dm - the packer object
221*f73e5cebSJed Brown .    pvec - packed vector
222*f73e5cebSJed Brown .    nwanted - number of vectors wanted
223*f73e5cebSJed Brown -    wanted - sorted array of vectors wanted, or PETSC_NULL to get all vectors
224*f73e5cebSJed Brown 
225*f73e5cebSJed Brown     Output Parameters:
226*f73e5cebSJed Brown .    vecs - array of requested global vectors (must be allocated)
227*f73e5cebSJed Brown 
228*f73e5cebSJed Brown     Notes: Use DMCompositeRestoreAccessArray() to return the vectors when you no longer need them
229*f73e5cebSJed Brown 
230*f73e5cebSJed Brown     Level: advanced
231*f73e5cebSJed Brown 
232*f73e5cebSJed Brown .seealso: DMCompositeGetAccess(), DMCompositeGetEntries(), DMCompositeScatter(), DMCompositeGather()
233*f73e5cebSJed Brown @*/
234*f73e5cebSJed Brown PetscErrorCode  DMCompositeGetAccessArray(DM dm,Vec pvec,PetscInt nwanted,const PetscInt *wanted,Vec *vecs)
235*f73e5cebSJed Brown {
236*f73e5cebSJed Brown   PetscErrorCode         ierr;
237*f73e5cebSJed Brown   struct DMCompositeLink *link;
238*f73e5cebSJed Brown   PetscInt               i,wnum;
239*f73e5cebSJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
240*f73e5cebSJed Brown 
241*f73e5cebSJed Brown   PetscFunctionBegin;
242*f73e5cebSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
243*f73e5cebSJed Brown   PetscValidHeaderSpecific(pvec,VEC_CLASSID,2);
244*f73e5cebSJed Brown   if (!com->setup) {
245*f73e5cebSJed Brown     ierr = DMSetUp(dm);CHKERRQ(ierr);
246*f73e5cebSJed Brown   }
247*f73e5cebSJed Brown 
248*f73e5cebSJed Brown   for (i=0,wnum=0,link=com->next; link && wnum<nwanted; i++,link=link->next) {
249*f73e5cebSJed Brown     if (!wanted || i == wanted[wnum]) {
250*f73e5cebSJed Brown       PetscScalar *array;
251*f73e5cebSJed Brown       Vec v;
252*f73e5cebSJed Brown       ierr = DMGetGlobalVector(link->dm,&v);CHKERRQ(ierr);
253*f73e5cebSJed Brown       ierr = VecGetArray(pvec,&array);CHKERRQ(ierr);
254*f73e5cebSJed Brown       ierr = VecPlaceArray(v,array+link->rstart);CHKERRQ(ierr);
255*f73e5cebSJed Brown       ierr = VecRestoreArray(pvec,&array);CHKERRQ(ierr);
256*f73e5cebSJed Brown       vecs[wnum++] = v;
257*f73e5cebSJed Brown     }
258*f73e5cebSJed Brown   }
259*f73e5cebSJed Brown   PetscFunctionReturn(0);
260*f73e5cebSJed Brown }
261*f73e5cebSJed Brown 
262*f73e5cebSJed Brown #undef __FUNCT__
26347c6ae99SBarry Smith #define __FUNCT__ "DMCompositeRestoreAccess"
26447c6ae99SBarry Smith /*@C
265aa219208SBarry Smith     DMCompositeRestoreAccess - Returns the vectors obtained with DMCompositeGetAccess()
26647c6ae99SBarry Smith        representation.
26747c6ae99SBarry Smith 
26847c6ae99SBarry Smith     Collective on DMComposite
26947c6ae99SBarry Smith 
2709ae5db72SJed Brown     Input Parameters:
27147c6ae99SBarry Smith +    dm - the packer object
27247c6ae99SBarry Smith .    gvec - the global vector
2739ae5db72SJed Brown -    Vec* ... - the individual parallel vectors, PETSC_NULL for those that are not needed
27447c6ae99SBarry Smith 
27547c6ae99SBarry Smith     Level: advanced
27647c6ae99SBarry Smith 
2779ae5db72SJed Brown .seealso  DMCompositeAddDM(), DMCreateGlobalVector(),
2786eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeScatter(),
279aa219208SBarry Smith          DMCompositeRestoreAccess(), DMCompositeGetAccess()
28047c6ae99SBarry Smith 
28147c6ae99SBarry Smith @*/
2827087cfbeSBarry Smith PetscErrorCode  DMCompositeRestoreAccess(DM dm,Vec gvec,...)
28347c6ae99SBarry Smith {
28447c6ae99SBarry Smith   va_list                Argp;
28547c6ae99SBarry Smith   PetscErrorCode         ierr;
28647c6ae99SBarry Smith   struct DMCompositeLink *next;
28747c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
28847c6ae99SBarry Smith 
28947c6ae99SBarry Smith   PetscFunctionBegin;
29047c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
29147c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
29247c6ae99SBarry Smith   next = com->next;
29347c6ae99SBarry Smith   if (!com->setup) {
294d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
29547c6ae99SBarry Smith   }
29647c6ae99SBarry Smith 
29747c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
29847c6ae99SBarry Smith   va_start(Argp,gvec);
29947c6ae99SBarry Smith   while (next) {
30047c6ae99SBarry Smith     Vec *vec;
30147c6ae99SBarry Smith     vec = va_arg(Argp, Vec*);
3029ae5db72SJed Brown     if (vec) {
3039ae5db72SJed Brown       ierr = VecResetArray(*vec);CHKERRQ(ierr);
3049ae5db72SJed Brown       ierr = DMRestoreGlobalVector(next->dm,vec);CHKERRQ(ierr);
30547c6ae99SBarry Smith     }
30647c6ae99SBarry Smith     next = next->next;
30747c6ae99SBarry Smith   }
30847c6ae99SBarry Smith   va_end(Argp);
30947c6ae99SBarry Smith   PetscFunctionReturn(0);
31047c6ae99SBarry Smith }
31147c6ae99SBarry Smith 
31247c6ae99SBarry Smith #undef __FUNCT__
313*f73e5cebSJed Brown #define __FUNCT__ "DMCompositeRestoreAccessArray"
314*f73e5cebSJed Brown /*@C
315*f73e5cebSJed Brown     DMCompositeRestoreAccessArray - Returns the vectors obtained with DMCompositeGetAccessArray()
316*f73e5cebSJed Brown 
317*f73e5cebSJed Brown     Collective on DMComposite
318*f73e5cebSJed Brown 
319*f73e5cebSJed Brown     Input Parameters:
320*f73e5cebSJed Brown +    dm - the packer object
321*f73e5cebSJed Brown .    pvec - packed vector
322*f73e5cebSJed Brown .    nwanted - number of vectors wanted
323*f73e5cebSJed Brown .    wanted - sorted array of vectors wanted, or PETSC_NULL to get all vectors
324*f73e5cebSJed Brown -    vecs - array of global vectors to return
325*f73e5cebSJed Brown 
326*f73e5cebSJed Brown     Level: advanced
327*f73e5cebSJed Brown 
328*f73e5cebSJed Brown .seealso: DMCompositeRestoreAccess(), DMCompositeRestoreEntries(), DMCompositeScatter(), DMCompositeGather()
329*f73e5cebSJed Brown @*/
330*f73e5cebSJed Brown PetscErrorCode  DMCompositeRestoreAccessArray(DM dm,Vec pvec,PetscInt nwanted,const PetscInt *wanted,Vec *vecs)
331*f73e5cebSJed Brown {
332*f73e5cebSJed Brown   PetscErrorCode         ierr;
333*f73e5cebSJed Brown   struct DMCompositeLink *link;
334*f73e5cebSJed Brown   PetscInt               i,wnum;
335*f73e5cebSJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
336*f73e5cebSJed Brown 
337*f73e5cebSJed Brown   PetscFunctionBegin;
338*f73e5cebSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
339*f73e5cebSJed Brown   PetscValidHeaderSpecific(pvec,VEC_CLASSID,2);
340*f73e5cebSJed Brown   if (!com->setup) {
341*f73e5cebSJed Brown     ierr = DMSetUp(dm);CHKERRQ(ierr);
342*f73e5cebSJed Brown   }
343*f73e5cebSJed Brown 
344*f73e5cebSJed Brown   for (i=0,wnum=0,link=com->next; link && wnum<nwanted; i++,link=link->next) {
345*f73e5cebSJed Brown     if (!wanted || i == wanted[wnum]) {
346*f73e5cebSJed Brown       ierr = VecResetArray(vecs[wnum]);CHKERRQ(ierr);
347*f73e5cebSJed Brown       ierr = DMRestoreGlobalVector(link->dm,&vecs[wnum]);CHKERRQ(ierr);
348*f73e5cebSJed Brown       wnum++;
349*f73e5cebSJed Brown     }
350*f73e5cebSJed Brown   }
351*f73e5cebSJed Brown   PetscFunctionReturn(0);
352*f73e5cebSJed Brown }
353*f73e5cebSJed Brown 
354*f73e5cebSJed Brown #undef __FUNCT__
35547c6ae99SBarry Smith #define __FUNCT__ "DMCompositeScatter"
35647c6ae99SBarry Smith /*@C
35747c6ae99SBarry Smith     DMCompositeScatter - Scatters from a global packed vector into its individual local vectors
35847c6ae99SBarry Smith 
35947c6ae99SBarry Smith     Collective on DMComposite
36047c6ae99SBarry Smith 
3619ae5db72SJed Brown     Input Parameters:
36247c6ae99SBarry Smith +    dm - the packer object
36347c6ae99SBarry Smith .    gvec - the global vector
3649ae5db72SJed Brown -    Vec ... - the individual sequential vectors, PETSC_NULL for those that are not needed
36547c6ae99SBarry Smith 
36647c6ae99SBarry Smith     Level: advanced
36747c6ae99SBarry Smith 
3689ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
3696eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
37047c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries()
37147c6ae99SBarry Smith 
37247c6ae99SBarry Smith @*/
3737087cfbeSBarry Smith PetscErrorCode  DMCompositeScatter(DM dm,Vec gvec,...)
37447c6ae99SBarry Smith {
37547c6ae99SBarry Smith   va_list                Argp;
37647c6ae99SBarry Smith   PetscErrorCode         ierr;
37747c6ae99SBarry Smith   struct DMCompositeLink *next;
3788fd8f222SJed Brown   PetscInt               cnt;
37947c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
38047c6ae99SBarry Smith 
38147c6ae99SBarry Smith   PetscFunctionBegin;
38247c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
38347c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
38447c6ae99SBarry Smith   if (!com->setup) {
385d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
38647c6ae99SBarry Smith   }
38747c6ae99SBarry Smith 
38847c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
38947c6ae99SBarry Smith   va_start(Argp,gvec);
3908fd8f222SJed Brown   for (cnt=3,next=com->next; next; cnt++,next=next->next) {
3919ae5db72SJed Brown     Vec local;
3929ae5db72SJed Brown     local = va_arg(Argp, Vec);
3939ae5db72SJed Brown     if (local) {
3949ae5db72SJed Brown       Vec         global;
39547c6ae99SBarry Smith       PetscScalar *array;
3969ae5db72SJed Brown       PetscValidHeaderSpecific(local,VEC_CLASSID,cnt);
3979ae5db72SJed Brown       ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
3989ae5db72SJed Brown       ierr = VecGetArray(gvec,&array);CHKERRQ(ierr);
3999ae5db72SJed Brown       ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr);
4009ae5db72SJed Brown       ierr = DMGlobalToLocalBegin(next->dm,global,INSERT_VALUES,local);CHKERRQ(ierr);
4019ae5db72SJed Brown       ierr = DMGlobalToLocalEnd(next->dm,global,INSERT_VALUES,local);CHKERRQ(ierr);
4029ae5db72SJed Brown       ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr);
4039ae5db72SJed Brown       ierr = VecResetArray(global);CHKERRQ(ierr);
4049ae5db72SJed Brown       ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
40547c6ae99SBarry Smith     }
40647c6ae99SBarry Smith   }
40747c6ae99SBarry Smith   va_end(Argp);
40847c6ae99SBarry Smith   PetscFunctionReturn(0);
40947c6ae99SBarry Smith }
41047c6ae99SBarry Smith 
41147c6ae99SBarry Smith #undef __FUNCT__
41247c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGather"
41347c6ae99SBarry Smith /*@C
41447c6ae99SBarry Smith     DMCompositeGather - Gathers into a global packed vector from its individual local vectors
41547c6ae99SBarry Smith 
41647c6ae99SBarry Smith     Collective on DMComposite
41747c6ae99SBarry Smith 
41847c6ae99SBarry Smith     Input Parameter:
41947c6ae99SBarry Smith +    dm - the packer object
42047c6ae99SBarry Smith .    gvec - the global vector
4219ae5db72SJed Brown -    Vec ... - the individual sequential vectors, PETSC_NULL for any that are not needed
42247c6ae99SBarry Smith 
42347c6ae99SBarry Smith     Level: advanced
42447c6ae99SBarry Smith 
4259ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
4266eb61c8cSJed Brown          DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
42747c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries()
42847c6ae99SBarry Smith 
42947c6ae99SBarry Smith @*/
4307087cfbeSBarry Smith PetscErrorCode  DMCompositeGather(DM dm,Vec gvec,InsertMode imode,...)
43147c6ae99SBarry Smith {
43247c6ae99SBarry Smith   va_list                Argp;
43347c6ae99SBarry Smith   PetscErrorCode         ierr;
43447c6ae99SBarry Smith   struct DMCompositeLink *next;
43547c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
4368fd8f222SJed Brown   PetscInt               cnt;
43747c6ae99SBarry Smith 
43847c6ae99SBarry Smith   PetscFunctionBegin;
43947c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
44047c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
44147c6ae99SBarry Smith   if (!com->setup) {
442d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
44347c6ae99SBarry Smith   }
44447c6ae99SBarry Smith 
44547c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
446df0c820aSJed Brown   va_start(Argp,imode);
4478fd8f222SJed Brown   for (cnt=3,next=com->next; next; cnt++,next=next->next) {
4489ae5db72SJed Brown     Vec local;
4499ae5db72SJed Brown     local = va_arg(Argp, Vec);
4509ae5db72SJed Brown     if (local) {
45147c6ae99SBarry Smith       PetscScalar *array;
4529ae5db72SJed Brown       Vec         global;
4539ae5db72SJed Brown       PetscValidHeaderSpecific(local,VEC_CLASSID,cnt);
4549ae5db72SJed Brown       ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
4559ae5db72SJed Brown       ierr = VecGetArray(gvec,&array);CHKERRQ(ierr);
4569ae5db72SJed Brown       ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr);
4579ae5db72SJed Brown       ierr = DMLocalToGlobalBegin(next->dm,local,imode,global);CHKERRQ(ierr);
4589ae5db72SJed Brown       ierr = DMLocalToGlobalEnd(next->dm,local,imode,global);CHKERRQ(ierr);
4599ae5db72SJed Brown       ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr);
4609ae5db72SJed Brown       ierr = VecResetArray(global);CHKERRQ(ierr);
4619ae5db72SJed Brown       ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
46247c6ae99SBarry Smith     }
46347c6ae99SBarry Smith   }
46447c6ae99SBarry Smith   va_end(Argp);
46547c6ae99SBarry Smith   PetscFunctionReturn(0);
46647c6ae99SBarry Smith }
46747c6ae99SBarry Smith 
46847c6ae99SBarry Smith #undef __FUNCT__
46947c6ae99SBarry Smith #define __FUNCT__ "DMCompositeAddDM"
47047c6ae99SBarry Smith /*@C
471aa219208SBarry Smith     DMCompositeAddDM - adds a DM  vector to a DMComposite
47247c6ae99SBarry Smith 
47347c6ae99SBarry Smith     Collective on DMComposite
47447c6ae99SBarry Smith 
47547c6ae99SBarry Smith     Input Parameter:
47647c6ae99SBarry Smith +    dm - the packer object
47747c6ae99SBarry Smith -    dm - the DM object, if the DM is a da you will need to caste it with a (DM)
47847c6ae99SBarry Smith 
47947c6ae99SBarry Smith     Level: advanced
48047c6ae99SBarry Smith 
4810c010503SBarry Smith .seealso DMDestroy(), DMCompositeGather(), DMCompositeAddDM(), DMCreateGlobalVector(),
4826eb61c8cSJed Brown          DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
48347c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries()
48447c6ae99SBarry Smith 
48547c6ae99SBarry Smith @*/
4867087cfbeSBarry Smith PetscErrorCode  DMCompositeAddDM(DM dmc,DM dm)
48747c6ae99SBarry Smith {
48847c6ae99SBarry Smith   PetscErrorCode         ierr;
48906ebdd98SJed Brown   PetscInt               n,nlocal;
49047c6ae99SBarry Smith   struct DMCompositeLink *mine,*next;
49106ebdd98SJed Brown   Vec                    global,local;
49247c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dmc->data;
49347c6ae99SBarry Smith 
49447c6ae99SBarry Smith   PetscFunctionBegin;
49547c6ae99SBarry Smith   PetscValidHeaderSpecific(dmc,DM_CLASSID,1);
49647c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,2);
49747c6ae99SBarry Smith   next = com->next;
498aa219208SBarry Smith   if (com->setup) SETERRQ(((PetscObject)dmc)->comm,PETSC_ERR_ARG_WRONGSTATE,"Cannot add a DM once you have used the DMComposite");
49947c6ae99SBarry Smith 
50047c6ae99SBarry Smith   /* create new link */
50147c6ae99SBarry Smith   ierr = PetscNew(struct DMCompositeLink,&mine);CHKERRQ(ierr);
50247c6ae99SBarry Smith   ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);
50347c6ae99SBarry Smith   ierr = DMGetGlobalVector(dm,&global);CHKERRQ(ierr);
50447c6ae99SBarry Smith   ierr = VecGetLocalSize(global,&n);CHKERRQ(ierr);
50547c6ae99SBarry Smith   ierr = DMRestoreGlobalVector(dm,&global);CHKERRQ(ierr);
50606ebdd98SJed Brown   ierr = DMGetLocalVector(dm,&local);CHKERRQ(ierr);
50706ebdd98SJed Brown   ierr = VecGetSize(local,&nlocal);CHKERRQ(ierr);
50806ebdd98SJed Brown   ierr = DMRestoreLocalVector(dm,&local);CHKERRQ(ierr);
5098865f1eaSKarl Rupp 
51047c6ae99SBarry Smith   mine->n      = n;
51106ebdd98SJed Brown   mine->nlocal = nlocal;
51247c6ae99SBarry Smith   mine->dm     = dm;
51347c6ae99SBarry Smith   mine->next   = PETSC_NULL;
51447c6ae99SBarry Smith   com->n      += n;
51547c6ae99SBarry Smith 
51647c6ae99SBarry Smith   /* add to end of list */
5178865f1eaSKarl Rupp   if (!next) com->next = mine;
5188865f1eaSKarl Rupp   else {
51947c6ae99SBarry Smith     while (next->next) next = next->next;
52047c6ae99SBarry Smith     next->next = mine;
52147c6ae99SBarry Smith   }
52247c6ae99SBarry Smith   com->nDM++;
52347c6ae99SBarry Smith   com->nmine++;
52447c6ae99SBarry Smith   PetscFunctionReturn(0);
52547c6ae99SBarry Smith }
52647c6ae99SBarry Smith 
5277087cfbeSBarry Smith extern PetscErrorCode  VecView_MPI(Vec,PetscViewer);
52847c6ae99SBarry Smith EXTERN_C_BEGIN
52947c6ae99SBarry Smith #undef __FUNCT__
53047c6ae99SBarry Smith #define __FUNCT__ "VecView_DMComposite"
5317087cfbeSBarry Smith PetscErrorCode  VecView_DMComposite(Vec gvec,PetscViewer viewer)
53247c6ae99SBarry Smith {
53347c6ae99SBarry Smith   DM                     dm;
53447c6ae99SBarry Smith   PetscErrorCode         ierr;
53547c6ae99SBarry Smith   struct DMCompositeLink *next;
53647c6ae99SBarry Smith   PetscBool              isdraw;
537cef07954SSatish Balay   DM_Composite           *com;
53847c6ae99SBarry Smith 
53947c6ae99SBarry Smith   PetscFunctionBegin;
540c688c046SMatthew G Knepley   ierr = VecGetDM(gvec, &dm);CHKERRQ(ierr);
54147c6ae99SBarry Smith   if (!dm) SETERRQ(((PetscObject)gvec)->comm,PETSC_ERR_ARG_WRONG,"Vector not generated from a DMComposite");
54247c6ae99SBarry Smith   com  = (DM_Composite*)dm->data;
54347c6ae99SBarry Smith   next = com->next;
54447c6ae99SBarry Smith 
545251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
54647c6ae99SBarry Smith   if (!isdraw) {
54747c6ae99SBarry Smith     /* do I really want to call this? */
54847c6ae99SBarry Smith     ierr = VecView_MPI(gvec,viewer);CHKERRQ(ierr);
54947c6ae99SBarry Smith   } else {
55047c6ae99SBarry Smith     PetscInt cnt = 0;
55147c6ae99SBarry Smith 
55247c6ae99SBarry Smith     /* loop over packed objects, handling one at at time */
55347c6ae99SBarry Smith     while (next) {
55447c6ae99SBarry Smith       Vec         vec;
5559ae5db72SJed Brown       PetscScalar *array;
55647c6ae99SBarry Smith       PetscInt    bs;
55747c6ae99SBarry Smith 
5589ae5db72SJed Brown       /* Should use VecGetSubVector() eventually, but would need to forward the DM for that to work */
5599ae5db72SJed Brown       ierr = DMGetGlobalVector(next->dm,&vec);CHKERRQ(ierr);
5609ae5db72SJed Brown       ierr = VecGetArray(gvec,&array);CHKERRQ(ierr);
5619ae5db72SJed Brown       ierr = VecPlaceArray(vec,array+next->rstart);CHKERRQ(ierr);
5629ae5db72SJed Brown       ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr);
56347c6ae99SBarry Smith       ierr = VecView(vec,viewer);CHKERRQ(ierr);
56447c6ae99SBarry Smith       ierr = VecGetBlockSize(vec,&bs);CHKERRQ(ierr);
5659ae5db72SJed Brown       ierr = VecResetArray(vec);CHKERRQ(ierr);
5669ae5db72SJed Brown       ierr = DMRestoreGlobalVector(next->dm,&vec);CHKERRQ(ierr);
56747c6ae99SBarry Smith       ierr = PetscViewerDrawBaseAdd(viewer,bs);CHKERRQ(ierr);
56847c6ae99SBarry Smith       cnt += bs;
56947c6ae99SBarry Smith       next = next->next;
57047c6ae99SBarry Smith     }
57147c6ae99SBarry Smith     ierr = PetscViewerDrawBaseAdd(viewer,-cnt);CHKERRQ(ierr);
57247c6ae99SBarry Smith   }
57347c6ae99SBarry Smith   PetscFunctionReturn(0);
57447c6ae99SBarry Smith }
57547c6ae99SBarry Smith EXTERN_C_END
57647c6ae99SBarry Smith 
57747c6ae99SBarry Smith 
57847c6ae99SBarry Smith #undef __FUNCT__
5790c010503SBarry Smith #define __FUNCT__ "DMCreateGlobalVector_Composite"
5807087cfbeSBarry Smith PetscErrorCode  DMCreateGlobalVector_Composite(DM dm,Vec *gvec)
58147c6ae99SBarry Smith {
58247c6ae99SBarry Smith   PetscErrorCode ierr;
58347c6ae99SBarry Smith   DM_Composite   *com = (DM_Composite*)dm->data;
58447c6ae99SBarry Smith 
58547c6ae99SBarry Smith   PetscFunctionBegin;
58647c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
587d7bf68aeSBarry Smith   ierr = DMSetUp(dm);CHKERRQ(ierr);
58847c6ae99SBarry Smith   ierr = VecCreateMPI(((PetscObject)dm)->comm,com->n,com->N,gvec);CHKERRQ(ierr);
589c688c046SMatthew G Knepley   ierr = VecSetDM(*gvec, dm);CHKERRQ(ierr);
59047c6ae99SBarry Smith   ierr = VecSetOperation(*gvec,VECOP_VIEW,(void (*)(void))VecView_DMComposite);CHKERRQ(ierr);
59147c6ae99SBarry Smith   PetscFunctionReturn(0);
59247c6ae99SBarry Smith }
59347c6ae99SBarry Smith 
59447c6ae99SBarry Smith #undef __FUNCT__
5950c010503SBarry Smith #define __FUNCT__ "DMCreateLocalVector_Composite"
5967087cfbeSBarry Smith PetscErrorCode  DMCreateLocalVector_Composite(DM dm,Vec *lvec)
59747c6ae99SBarry Smith {
59847c6ae99SBarry Smith   PetscErrorCode ierr;
59947c6ae99SBarry Smith   DM_Composite   *com = (DM_Composite*)dm->data;
60047c6ae99SBarry Smith 
60147c6ae99SBarry Smith   PetscFunctionBegin;
60247c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
60347c6ae99SBarry Smith   if (!com->setup) {
604d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
60547c6ae99SBarry Smith   }
60647c6ae99SBarry Smith   ierr = VecCreateSeq(((PetscObject)dm)->comm,com->nghost,lvec);CHKERRQ(ierr);
607c688c046SMatthew G Knepley   ierr = VecSetDM(*lvec, dm);CHKERRQ(ierr);
60847c6ae99SBarry Smith   PetscFunctionReturn(0);
60947c6ae99SBarry Smith }
61047c6ae99SBarry Smith 
61147c6ae99SBarry Smith #undef __FUNCT__
6126eb61c8cSJed Brown #define __FUNCT__ "DMCompositeGetISLocalToGlobalMappings"
61347c6ae99SBarry Smith /*@C
6149ae5db72SJed Brown     DMCompositeGetISLocalToGlobalMappings - gets an ISLocalToGlobalMapping for each DM in the DMComposite, maps to the composite global space
61547c6ae99SBarry Smith 
61606ebdd98SJed Brown     Collective on DM
61747c6ae99SBarry Smith 
61847c6ae99SBarry Smith     Input Parameter:
61947c6ae99SBarry Smith .    dm - the packer object
62047c6ae99SBarry Smith 
62147c6ae99SBarry Smith     Output Parameters:
6229ae5db72SJed Brown .    ltogs - the individual mappings for each packed vector. Note that this includes
6239ae5db72SJed Brown            all the ghost points that individual ghosted DMDA's may have.
62447c6ae99SBarry Smith 
62547c6ae99SBarry Smith     Level: advanced
62647c6ae99SBarry Smith 
62747c6ae99SBarry Smith     Notes:
6286eb61c8cSJed Brown        Each entry of ltogs should be destroyed with ISLocalToGlobalMappingDestroy(), the ltogs array should be freed with PetscFree().
62947c6ae99SBarry Smith 
6309ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
63147c6ae99SBarry Smith          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetAccess(), DMCompositeScatter(),
63247c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(),DMCompositeGetEntries()
63347c6ae99SBarry Smith 
63447c6ae99SBarry Smith @*/
6357087cfbeSBarry Smith PetscErrorCode  DMCompositeGetISLocalToGlobalMappings(DM dm,ISLocalToGlobalMapping **ltogs)
63647c6ae99SBarry Smith {
63747c6ae99SBarry Smith   PetscErrorCode         ierr;
63847c6ae99SBarry Smith   PetscInt               i,*idx,n,cnt;
63947c6ae99SBarry Smith   struct DMCompositeLink *next;
64047c6ae99SBarry Smith   PetscMPIInt            rank;
64147c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
64247c6ae99SBarry Smith 
64347c6ae99SBarry Smith   PetscFunctionBegin;
64447c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
645728e99d6SJed Brown   ierr = DMSetUp(dm);CHKERRQ(ierr);
6469ae5db72SJed Brown   ierr = PetscMalloc((com->nDM)*sizeof(ISLocalToGlobalMapping),ltogs);CHKERRQ(ierr);
64747c6ae99SBarry Smith   next = com->next;
64847c6ae99SBarry Smith   ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr);
64947c6ae99SBarry Smith 
65047c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
65147c6ae99SBarry Smith   cnt = 0;
65247c6ae99SBarry Smith   while (next) {
6536eb61c8cSJed Brown     ISLocalToGlobalMapping ltog;
6546eb61c8cSJed Brown     PetscMPIInt            size;
65586994e45SJed Brown     const PetscInt         *suboff,*indices;
6566eb61c8cSJed Brown     Vec                    global;
65747c6ae99SBarry Smith 
6586eb61c8cSJed Brown     /* Get sub-DM global indices for each local dof */
6591411c6eeSJed Brown     ierr = DMGetLocalToGlobalMapping(next->dm,&ltog);CHKERRQ(ierr);
6606eb61c8cSJed Brown     ierr = ISLocalToGlobalMappingGetSize(ltog,&n);CHKERRQ(ierr);
66186994e45SJed Brown     ierr = ISLocalToGlobalMappingGetIndices(ltog,&indices);CHKERRQ(ierr);
66247c6ae99SBarry Smith     ierr = PetscMalloc(n*sizeof(PetscInt),&idx);CHKERRQ(ierr);
66347c6ae99SBarry Smith 
6646eb61c8cSJed Brown     /* Get the offsets for the sub-DM global vector */
6656eb61c8cSJed Brown     ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
6666eb61c8cSJed Brown     ierr = VecGetOwnershipRanges(global,&suboff);CHKERRQ(ierr);
6676eb61c8cSJed Brown     ierr = MPI_Comm_size(((PetscObject)global)->comm,&size);CHKERRQ(ierr);
6686eb61c8cSJed Brown 
6696eb61c8cSJed Brown     /* Shift the sub-DM definition of the global space to the composite global space */
6706eb61c8cSJed Brown     for (i=0; i<n; i++) {
67186994e45SJed Brown       PetscInt subi = indices[i],lo = 0,hi = size,t;
6726eb61c8cSJed Brown       /* Binary search to find which rank owns subi */
6736eb61c8cSJed Brown       while (hi-lo > 1) {
6746eb61c8cSJed Brown         t = lo + (hi-lo)/2;
6756eb61c8cSJed Brown         if (suboff[t] > subi) hi = t;
6766eb61c8cSJed Brown         else                  lo = t;
6776eb61c8cSJed Brown       }
6786eb61c8cSJed Brown       idx[i] = subi - suboff[lo] + next->grstarts[lo];
6796eb61c8cSJed Brown     }
68086994e45SJed Brown     ierr = ISLocalToGlobalMappingRestoreIndices(ltog,&indices);CHKERRQ(ierr);
6816eb61c8cSJed Brown     ierr = ISLocalToGlobalMappingCreate(((PetscObject)dm)->comm,n,idx,PETSC_OWN_POINTER,&(*ltogs)[cnt]);CHKERRQ(ierr);
6826eb61c8cSJed Brown     ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
68347c6ae99SBarry Smith     next = next->next;
68447c6ae99SBarry Smith     cnt++;
68547c6ae99SBarry Smith   }
68647c6ae99SBarry Smith   PetscFunctionReturn(0);
68747c6ae99SBarry Smith }
68847c6ae99SBarry Smith 
68947c6ae99SBarry Smith #undef __FUNCT__
69087c85e80SJed Brown #define __FUNCT__ "DMCompositeGetLocalISs"
69187c85e80SJed Brown /*@C
6929ae5db72SJed Brown    DMCompositeGetLocalISs - Gets index sets for each component of a composite local vector
69387c85e80SJed Brown 
69487c85e80SJed Brown    Not Collective
69587c85e80SJed Brown 
69687c85e80SJed Brown    Input Arguments:
69787c85e80SJed Brown . dm - composite DM
69887c85e80SJed Brown 
69987c85e80SJed Brown    Output Arguments:
70087c85e80SJed Brown . is - array of serial index sets for each each component of the DMComposite
70187c85e80SJed Brown 
70287c85e80SJed Brown    Level: intermediate
70387c85e80SJed Brown 
70487c85e80SJed Brown    Notes:
70587c85e80SJed Brown    At present, a composite local vector does not normally exist.  This function is used to provide index sets for
70687c85e80SJed Brown    MatGetLocalSubMatrix().  In the future, the scatters for each entry in the DMComposite may be be merged into a single
7079ae5db72SJed Brown    scatter to a composite local vector.  The user should not typically need to know which is being done.
70887c85e80SJed Brown 
70987c85e80SJed Brown    To get the composite global indices at all local points (including ghosts), use DMCompositeGetISLocalToGlobalMappings().
71087c85e80SJed Brown 
71187c85e80SJed Brown    To get index sets for pieces of the composite global vector, use DMCompositeGetGlobalISs().
71287c85e80SJed Brown 
71387c85e80SJed Brown    Each returned IS should be destroyed with ISDestroy(), the array should be freed with PetscFree().
71487c85e80SJed Brown 
71587c85e80SJed Brown .seealso: DMCompositeGetGlobalISs(), DMCompositeGetISLocalToGlobalMappings(), MatGetLocalSubMatrix(), MatCreateLocalRef()
71687c85e80SJed Brown @*/
7177087cfbeSBarry Smith PetscErrorCode  DMCompositeGetLocalISs(DM dm,IS **is)
71887c85e80SJed Brown {
71987c85e80SJed Brown   PetscErrorCode         ierr;
72087c85e80SJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
72187c85e80SJed Brown   struct DMCompositeLink *link;
72287c85e80SJed Brown   PetscInt               cnt,start;
72387c85e80SJed Brown 
72487c85e80SJed Brown   PetscFunctionBegin;
72587c85e80SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
72687c85e80SJed Brown   PetscValidPointer(is,2);
72787c85e80SJed Brown   ierr = PetscMalloc(com->nmine*sizeof(IS),is);CHKERRQ(ierr);
72806ebdd98SJed Brown   for (cnt=0,start=0,link=com->next; link; start+=link->nlocal,cnt++,link=link->next) {
729520db06cSJed Brown     PetscInt bs;
7309ae5db72SJed Brown     ierr = ISCreateStride(PETSC_COMM_SELF,link->nlocal,start,1,&(*is)[cnt]);CHKERRQ(ierr);
7311411c6eeSJed Brown     ierr = DMGetBlockSize(link->dm,&bs);CHKERRQ(ierr);
732520db06cSJed Brown     ierr = ISSetBlockSize((*is)[cnt],bs);CHKERRQ(ierr);
733520db06cSJed Brown   }
73487c85e80SJed Brown   PetscFunctionReturn(0);
73587c85e80SJed Brown }
73687c85e80SJed Brown 
73787c85e80SJed Brown #undef __FUNCT__
73847c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetGlobalISs"
73947c6ae99SBarry Smith /*@C
74047c6ae99SBarry Smith     DMCompositeGetGlobalISs - Gets the index sets for each composed object
74147c6ae99SBarry Smith 
74247c6ae99SBarry Smith     Collective on DMComposite
74347c6ae99SBarry Smith 
74447c6ae99SBarry Smith     Input Parameter:
74547c6ae99SBarry Smith .    dm - the packer object
74647c6ae99SBarry Smith 
74747c6ae99SBarry Smith     Output Parameters:
74847c6ae99SBarry Smith .    is - the array of index sets
74947c6ae99SBarry Smith 
75047c6ae99SBarry Smith     Level: advanced
75147c6ae99SBarry Smith 
75247c6ae99SBarry Smith     Notes:
75347c6ae99SBarry Smith        The is entries should be destroyed with ISDestroy(), the is array should be freed with PetscFree()
75447c6ae99SBarry Smith 
75547c6ae99SBarry Smith        These could be used to extract a subset of vector entries for a "multi-physics" preconditioner
75647c6ae99SBarry Smith 
7576eb61c8cSJed Brown        Use DMCompositeGetLocalISs() for index sets in the packed local numbering, and
7586eb61c8cSJed Brown        DMCompositeGetISLocalToGlobalMappings() for to map local sub-DM (including ghost) indices to packed global
7596eb61c8cSJed Brown        indices.
76047c6ae99SBarry Smith 
7619ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
76247c6ae99SBarry Smith          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetAccess(), DMCompositeScatter(),
76347c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(),DMCompositeGetEntries()
76447c6ae99SBarry Smith 
76547c6ae99SBarry Smith @*/
7666eb61c8cSJed Brown 
7677087cfbeSBarry Smith PetscErrorCode  DMCompositeGetGlobalISs(DM dm,IS *is[])
76847c6ae99SBarry Smith {
76947c6ae99SBarry Smith   PetscErrorCode         ierr;
77047c6ae99SBarry Smith   PetscInt               cnt = 0,*idx,i;
77147c6ae99SBarry Smith   struct DMCompositeLink *next;
77247c6ae99SBarry Smith   PetscMPIInt            rank;
77347c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
77447c6ae99SBarry Smith 
77547c6ae99SBarry Smith   PetscFunctionBegin;
77647c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7779ae5db72SJed Brown   ierr = PetscMalloc((com->nDM)*sizeof(IS),is);CHKERRQ(ierr);
77847c6ae99SBarry Smith   next = com->next;
77947c6ae99SBarry Smith   ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr);
78047c6ae99SBarry Smith 
78147c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
78247c6ae99SBarry Smith   while (next) {
78347c6ae99SBarry Smith     ierr = PetscMalloc(next->n*sizeof(PetscInt),&idx);CHKERRQ(ierr);
78447c6ae99SBarry Smith     for (i=0; i<next->n; i++) idx[i] = next->grstart + i;
78547c6ae99SBarry Smith     ierr = ISCreateGeneral(((PetscObject)dm)->comm,next->n,idx,PETSC_OWN_POINTER,&(*is)[cnt]);CHKERRQ(ierr);
78647c6ae99SBarry Smith     cnt++;
78747c6ae99SBarry Smith     next = next->next;
78847c6ae99SBarry Smith   }
78947c6ae99SBarry Smith   PetscFunctionReturn(0);
79047c6ae99SBarry Smith }
79147c6ae99SBarry Smith 
7924d343eeaSMatthew G Knepley #undef __FUNCT__
7934d343eeaSMatthew G Knepley #define __FUNCT__ "DMCreateFieldIS_Composite"
79421c9b008SJed Brown PetscErrorCode DMCreateFieldIS_Composite(DM dm, PetscInt *numFields,char ***fieldNames, IS **fields)
7954d343eeaSMatthew G Knepley {
7964d343eeaSMatthew G Knepley   PetscInt       nDM;
7974d343eeaSMatthew G Knepley   DM             *dms;
7984d343eeaSMatthew G Knepley   PetscInt       i;
7994d343eeaSMatthew G Knepley   PetscErrorCode ierr;
8004d343eeaSMatthew G Knepley 
8014d343eeaSMatthew G Knepley   PetscFunctionBegin;
8024d343eeaSMatthew G Knepley   ierr = DMCompositeGetNumberDM(dm, &nDM);CHKERRQ(ierr);
8038865f1eaSKarl Rupp   if (numFields) *numFields = nDM;
8044d343eeaSMatthew G Knepley   ierr = DMCompositeGetGlobalISs(dm, fields);CHKERRQ(ierr);
8054d343eeaSMatthew G Knepley   if (fieldNames) {
8064d343eeaSMatthew G Knepley     ierr = PetscMalloc(nDM*sizeof(DM), &dms);CHKERRQ(ierr);
8074d343eeaSMatthew G Knepley     ierr = PetscMalloc(nDM*sizeof(const char*), fieldNames);CHKERRQ(ierr);
8084d343eeaSMatthew G Knepley     ierr = DMCompositeGetEntriesArray(dm, dms);CHKERRQ(ierr);
8094d343eeaSMatthew G Knepley     for (i=0; i<nDM; i++) {
8104d343eeaSMatthew G Knepley       char       buf[256];
8114d343eeaSMatthew G Knepley       const char *splitname;
8124d343eeaSMatthew G Knepley 
8134d343eeaSMatthew G Knepley       /* Split naming precedence: object name, prefix, number */
8144d343eeaSMatthew G Knepley       splitname = ((PetscObject) dm)->name;
8154d343eeaSMatthew G Knepley       if (!splitname) {
8164d343eeaSMatthew G Knepley         ierr = PetscObjectGetOptionsPrefix((PetscObject)dms[i],&splitname);CHKERRQ(ierr);
8174d343eeaSMatthew G Knepley         if (splitname) {
8184d343eeaSMatthew G Knepley           size_t len;
8198caf3d72SBarry Smith           ierr                 = PetscStrncpy(buf,splitname,sizeof(buf));CHKERRQ(ierr);
8208caf3d72SBarry Smith           buf[sizeof(buf) - 1] = 0;
8214d343eeaSMatthew G Knepley           ierr                 = PetscStrlen(buf,&len);CHKERRQ(ierr);
8224d343eeaSMatthew G Knepley           if (buf[len-1] == '_') buf[len-1] = 0; /* Remove trailing underscore if it was used */
8234d343eeaSMatthew G Knepley           splitname = buf;
8244d343eeaSMatthew G Knepley         }
8254d343eeaSMatthew G Knepley       }
8264d343eeaSMatthew G Knepley       if (!splitname) {
8278caf3d72SBarry Smith         ierr      = PetscSNPrintf(buf,sizeof(buf),"%D",i);CHKERRQ(ierr);
8284d343eeaSMatthew G Knepley         splitname = buf;
8294d343eeaSMatthew G Knepley       }
83021c9b008SJed Brown       ierr = PetscStrallocpy(splitname,&(*fieldNames)[i]);CHKERRQ(ierr);
8314d343eeaSMatthew G Knepley     }
8324d343eeaSMatthew G Knepley     ierr = PetscFree(dms);CHKERRQ(ierr);
8334d343eeaSMatthew G Knepley   }
8344d343eeaSMatthew G Knepley   PetscFunctionReturn(0);
8354d343eeaSMatthew G Knepley }
8364d343eeaSMatthew G Knepley 
837e7c4fc90SDmitry Karpeev /*
838e7c4fc90SDmitry Karpeev  This could take over from DMCreateFieldIS(), as it is more general,
839e7c4fc90SDmitry Karpeev  making DMCreateFieldIS() a special case -- calling with dmlist == PETSC_NULL;
840e7c4fc90SDmitry Karpeev  At this point it's probably best to be less intrusive, however.
841e7c4fc90SDmitry Karpeev  */
842e7c4fc90SDmitry Karpeev #undef __FUNCT__
84316621825SDmitry Karpeev #define __FUNCT__ "DMCreateFieldDecomposition_Composite"
84416621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecomposition_Composite(DM dm, PetscInt *len,char ***namelist, IS **islist, DM **dmlist)
845e7c4fc90SDmitry Karpeev {
846e7c4fc90SDmitry Karpeev   PetscInt       nDM;
847e7c4fc90SDmitry Karpeev   PetscInt       i;
848e7c4fc90SDmitry Karpeev   PetscErrorCode ierr;
849e7c4fc90SDmitry Karpeev 
850e7c4fc90SDmitry Karpeev   PetscFunctionBegin;
851e7c4fc90SDmitry Karpeev   ierr = DMCreateFieldIS_Composite(dm, len, namelist, islist);CHKERRQ(ierr);
852e7c4fc90SDmitry Karpeev   if (dmlist) {
853e7c4fc90SDmitry Karpeev     ierr = DMCompositeGetNumberDM(dm, &nDM);CHKERRQ(ierr);
854e7c4fc90SDmitry Karpeev     ierr = PetscMalloc(nDM*sizeof(DM), dmlist);CHKERRQ(ierr);
855e7c4fc90SDmitry Karpeev     ierr = DMCompositeGetEntriesArray(dm, *dmlist);CHKERRQ(ierr);
856e7c4fc90SDmitry Karpeev     for (i=0; i<nDM; i++) {
857e7c4fc90SDmitry Karpeev       ierr = PetscObjectReference((PetscObject)((*dmlist)[i]));CHKERRQ(ierr);
858e7c4fc90SDmitry Karpeev     }
859e7c4fc90SDmitry Karpeev   }
860e7c4fc90SDmitry Karpeev   PetscFunctionReturn(0);
861e7c4fc90SDmitry Karpeev }
862e7c4fc90SDmitry Karpeev 
863e7c4fc90SDmitry Karpeev 
864e7c4fc90SDmitry Karpeev 
86547c6ae99SBarry Smith /* -------------------------------------------------------------------------------------*/
86647c6ae99SBarry Smith #undef __FUNCT__
86747c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetLocalVectors"
86847c6ae99SBarry Smith /*@C
8699ae5db72SJed Brown     DMCompositeGetLocalVectors - Gets local vectors for each part of a DMComposite.
87047c6ae99SBarry Smith        Use DMCompositeRestoreLocalVectors() to return them.
87147c6ae99SBarry Smith 
87247c6ae99SBarry Smith     Not Collective
87347c6ae99SBarry Smith 
87447c6ae99SBarry Smith     Input Parameter:
87547c6ae99SBarry Smith .    dm - the packer object
87647c6ae99SBarry Smith 
87747c6ae99SBarry Smith     Output Parameter:
8789ae5db72SJed Brown .   Vec ... - the individual sequential Vecs
87947c6ae99SBarry Smith 
88047c6ae99SBarry Smith     Level: advanced
88147c6ae99SBarry Smith 
8829ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
8836eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
88447c6ae99SBarry Smith          DMCompositeRestoreLocalVectors(), DMCompositeScatter(), DMCompositeGetEntries()
88547c6ae99SBarry Smith 
88647c6ae99SBarry Smith @*/
8877087cfbeSBarry Smith PetscErrorCode  DMCompositeGetLocalVectors(DM dm,...)
88847c6ae99SBarry Smith {
88947c6ae99SBarry Smith   va_list                Argp;
89047c6ae99SBarry Smith   PetscErrorCode         ierr;
89147c6ae99SBarry Smith   struct DMCompositeLink *next;
89247c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
89347c6ae99SBarry Smith 
89447c6ae99SBarry Smith   PetscFunctionBegin;
89547c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
89647c6ae99SBarry Smith   next = com->next;
89747c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
89847c6ae99SBarry Smith   va_start(Argp,dm);
89947c6ae99SBarry Smith   while (next) {
90047c6ae99SBarry Smith     Vec *vec;
90147c6ae99SBarry Smith     vec = va_arg(Argp, Vec*);
90206930112SJed Brown     if (vec) {ierr = DMGetLocalVector(next->dm,vec);CHKERRQ(ierr);}
90347c6ae99SBarry Smith     next = next->next;
90447c6ae99SBarry Smith   }
90547c6ae99SBarry Smith   va_end(Argp);
90647c6ae99SBarry Smith   PetscFunctionReturn(0);
90747c6ae99SBarry Smith }
90847c6ae99SBarry Smith 
90947c6ae99SBarry Smith #undef __FUNCT__
91047c6ae99SBarry Smith #define __FUNCT__ "DMCompositeRestoreLocalVectors"
91147c6ae99SBarry Smith /*@C
9129ae5db72SJed Brown     DMCompositeRestoreLocalVectors - Restores local vectors for each part of a DMComposite.
91347c6ae99SBarry Smith 
91447c6ae99SBarry Smith     Not Collective
91547c6ae99SBarry Smith 
91647c6ae99SBarry Smith     Input Parameter:
91747c6ae99SBarry Smith .    dm - the packer object
91847c6ae99SBarry Smith 
91947c6ae99SBarry Smith     Output Parameter:
9209ae5db72SJed Brown .   Vec ... - the individual sequential Vecs
92147c6ae99SBarry Smith 
92247c6ae99SBarry Smith     Level: advanced
92347c6ae99SBarry Smith 
9249ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
9256eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
92647c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeScatter(), DMCompositeGetEntries()
92747c6ae99SBarry Smith 
92847c6ae99SBarry Smith @*/
9297087cfbeSBarry Smith PetscErrorCode  DMCompositeRestoreLocalVectors(DM dm,...)
93047c6ae99SBarry Smith {
93147c6ae99SBarry Smith   va_list                Argp;
93247c6ae99SBarry Smith   PetscErrorCode         ierr;
93347c6ae99SBarry Smith   struct DMCompositeLink *next;
93447c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
93547c6ae99SBarry Smith 
93647c6ae99SBarry Smith   PetscFunctionBegin;
93747c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
93847c6ae99SBarry Smith   next = com->next;
93947c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
94047c6ae99SBarry Smith   va_start(Argp,dm);
94147c6ae99SBarry Smith   while (next) {
94247c6ae99SBarry Smith     Vec *vec;
94347c6ae99SBarry Smith     vec = va_arg(Argp, Vec*);
94406930112SJed Brown     if (vec) {ierr = DMRestoreLocalVector(next->dm,vec);CHKERRQ(ierr);}
94547c6ae99SBarry Smith     next = next->next;
94647c6ae99SBarry Smith   }
94747c6ae99SBarry Smith   va_end(Argp);
94847c6ae99SBarry Smith   PetscFunctionReturn(0);
94947c6ae99SBarry Smith }
95047c6ae99SBarry Smith 
95147c6ae99SBarry Smith /* -------------------------------------------------------------------------------------*/
95247c6ae99SBarry Smith #undef __FUNCT__
95347c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetEntries"
95447c6ae99SBarry Smith /*@C
9559ae5db72SJed Brown     DMCompositeGetEntries - Gets the DM for each entry in a DMComposite.
95647c6ae99SBarry Smith 
95747c6ae99SBarry Smith     Not Collective
95847c6ae99SBarry Smith 
95947c6ae99SBarry Smith     Input Parameter:
96047c6ae99SBarry Smith .    dm - the packer object
96147c6ae99SBarry Smith 
96247c6ae99SBarry Smith     Output Parameter:
9639ae5db72SJed Brown .   DM ... - the individual entries (DMs)
96447c6ae99SBarry Smith 
96547c6ae99SBarry Smith     Level: advanced
96647c6ae99SBarry Smith 
9672fa5ba8aSJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), DMCompositeGetEntriesArray()
9686eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
96947c6ae99SBarry Smith          DMCompositeRestoreLocalVectors(), DMCompositeGetLocalVectors(),  DMCompositeScatter(),
97047c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors()
97147c6ae99SBarry Smith 
97247c6ae99SBarry Smith @*/
9737087cfbeSBarry Smith PetscErrorCode  DMCompositeGetEntries(DM dm,...)
97447c6ae99SBarry Smith {
97547c6ae99SBarry Smith   va_list                Argp;
97647c6ae99SBarry Smith   struct DMCompositeLink *next;
97747c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
97847c6ae99SBarry Smith 
97947c6ae99SBarry Smith   PetscFunctionBegin;
98047c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
98147c6ae99SBarry Smith   next = com->next;
98247c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
98347c6ae99SBarry Smith   va_start(Argp,dm);
98447c6ae99SBarry Smith   while (next) {
98547c6ae99SBarry Smith     DM *dmn;
98647c6ae99SBarry Smith     dmn = va_arg(Argp, DM*);
9879ae5db72SJed Brown     if (dmn) *dmn = next->dm;
98847c6ae99SBarry Smith     next = next->next;
98947c6ae99SBarry Smith   }
99047c6ae99SBarry Smith   va_end(Argp);
99147c6ae99SBarry Smith   PetscFunctionReturn(0);
99247c6ae99SBarry Smith }
99347c6ae99SBarry Smith 
99447c6ae99SBarry Smith #undef __FUNCT__
9952fa5ba8aSJed Brown #define __FUNCT__ "DMCompositeGetEntriesArray"
996dbab29e1SMark F. Adams /*@C
9972fa5ba8aSJed Brown     DMCompositeGetEntriesArray - Gets the DM for each entry in a DMComposite.
9982fa5ba8aSJed Brown 
9992fa5ba8aSJed Brown     Not Collective
10002fa5ba8aSJed Brown 
10012fa5ba8aSJed Brown     Input Parameter:
10022fa5ba8aSJed Brown +    dm - the packer object
10032fa5ba8aSJed Brown -    dms - array of sufficient length (see DMCompositeGetNumberDM()), holds the DMs on output
10042fa5ba8aSJed Brown 
10052fa5ba8aSJed Brown     Level: advanced
10062fa5ba8aSJed Brown 
10072fa5ba8aSJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), DMCompositeGetEntries()
10082fa5ba8aSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
10092fa5ba8aSJed Brown          DMCompositeRestoreLocalVectors(), DMCompositeGetLocalVectors(),  DMCompositeScatter(),
10102fa5ba8aSJed Brown          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors()
10112fa5ba8aSJed Brown 
10122fa5ba8aSJed Brown @*/
10132fa5ba8aSJed Brown PetscErrorCode DMCompositeGetEntriesArray(DM dm,DM dms[])
10142fa5ba8aSJed Brown {
10152fa5ba8aSJed Brown   struct DMCompositeLink *next;
10162fa5ba8aSJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
10172fa5ba8aSJed Brown   PetscInt               i;
10182fa5ba8aSJed Brown 
10192fa5ba8aSJed Brown   PetscFunctionBegin;
10202fa5ba8aSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
10212fa5ba8aSJed Brown   /* loop over packed objects, handling one at at time */
10222fa5ba8aSJed Brown   for (next=com->next,i=0; next; next=next->next,i++) dms[i] = next->dm;
10232fa5ba8aSJed Brown   PetscFunctionReturn(0);
10242fa5ba8aSJed Brown }
10252fa5ba8aSJed Brown 
10262fa5ba8aSJed Brown #undef __FUNCT__
10270c010503SBarry Smith #define __FUNCT__ "DMRefine_Composite"
10287087cfbeSBarry Smith PetscErrorCode  DMRefine_Composite(DM dmi,MPI_Comm comm,DM *fine)
102947c6ae99SBarry Smith {
103047c6ae99SBarry Smith   PetscErrorCode         ierr;
103147c6ae99SBarry Smith   struct DMCompositeLink *next;
103247c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dmi->data;
103347c6ae99SBarry Smith   DM                     dm;
103447c6ae99SBarry Smith 
103547c6ae99SBarry Smith   PetscFunctionBegin;
103647c6ae99SBarry Smith   PetscValidHeaderSpecific(dmi,DM_CLASSID,1);
10372ee06e3bSJed Brown   if (comm == MPI_COMM_NULL) comm = ((PetscObject)dmi)->comm;
10382ce3a92bSJed Brown   ierr = DMSetUp(dmi);CHKERRQ(ierr);
103947c6ae99SBarry Smith   next = com->next;
104047c6ae99SBarry Smith   ierr = DMCompositeCreate(comm,fine);CHKERRQ(ierr);
104147c6ae99SBarry Smith 
104247c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
104347c6ae99SBarry Smith   while (next) {
104447c6ae99SBarry Smith     ierr = DMRefine(next->dm,comm,&dm);CHKERRQ(ierr);
104547c6ae99SBarry Smith     ierr = DMCompositeAddDM(*fine,dm);CHKERRQ(ierr);
104647c6ae99SBarry Smith     ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr);
104747c6ae99SBarry Smith     next = next->next;
104847c6ae99SBarry Smith   }
104947c6ae99SBarry Smith   PetscFunctionReturn(0);
105047c6ae99SBarry Smith }
105147c6ae99SBarry Smith 
105214354c39SJed Brown #undef __FUNCT__
105314354c39SJed Brown #define __FUNCT__ "DMCoarsen_Composite"
105414354c39SJed Brown PetscErrorCode  DMCoarsen_Composite(DM dmi,MPI_Comm comm,DM *fine)
105514354c39SJed Brown {
105614354c39SJed Brown   PetscErrorCode         ierr;
105714354c39SJed Brown   struct DMCompositeLink *next;
105814354c39SJed Brown   DM_Composite           *com = (DM_Composite*)dmi->data;
105914354c39SJed Brown   DM                     dm;
106014354c39SJed Brown 
106114354c39SJed Brown   PetscFunctionBegin;
106214354c39SJed Brown   PetscValidHeaderSpecific(dmi,DM_CLASSID,1);
10632ce3a92bSJed Brown   ierr = DMSetUp(dmi);CHKERRQ(ierr);
10642ee06e3bSJed Brown   if (comm == MPI_COMM_NULL) {
106525296bd5SBarry Smith     ierr = PetscObjectGetComm((PetscObject)dmi,&comm);CHKERRQ(ierr);
106625296bd5SBarry Smith   }
106714354c39SJed Brown   next = com->next;
106814354c39SJed Brown   ierr = DMCompositeCreate(comm,fine);CHKERRQ(ierr);
106914354c39SJed Brown 
107014354c39SJed Brown   /* loop over packed objects, handling one at at time */
107114354c39SJed Brown   while (next) {
107214354c39SJed Brown     ierr = DMCoarsen(next->dm,comm,&dm);CHKERRQ(ierr);
107314354c39SJed Brown     ierr = DMCompositeAddDM(*fine,dm);CHKERRQ(ierr);
107414354c39SJed Brown     ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr);
107514354c39SJed Brown     next = next->next;
107614354c39SJed Brown   }
107714354c39SJed Brown   PetscFunctionReturn(0);
107814354c39SJed Brown }
107947c6ae99SBarry Smith 
108047c6ae99SBarry Smith #undef __FUNCT__
1081e727c939SJed Brown #define __FUNCT__ "DMCreateInterpolation_Composite"
1082e727c939SJed Brown PetscErrorCode  DMCreateInterpolation_Composite(DM coarse,DM fine,Mat *A,Vec *v)
108347c6ae99SBarry Smith {
108447c6ae99SBarry Smith   PetscErrorCode         ierr;
10859ae5db72SJed Brown   PetscInt               m,n,M,N,nDM,i;
108647c6ae99SBarry Smith   struct DMCompositeLink *nextc;
108747c6ae99SBarry Smith   struct DMCompositeLink *nextf;
108825296bd5SBarry Smith   Vec                    gcoarse,gfine,*vecs;
108947c6ae99SBarry Smith   DM_Composite           *comcoarse = (DM_Composite*)coarse->data;
109047c6ae99SBarry Smith   DM_Composite           *comfine   = (DM_Composite*)fine->data;
10919ae5db72SJed Brown   Mat                    *mats;
109247c6ae99SBarry Smith 
109347c6ae99SBarry Smith   PetscFunctionBegin;
109447c6ae99SBarry Smith   PetscValidHeaderSpecific(coarse,DM_CLASSID,1);
109547c6ae99SBarry Smith   PetscValidHeaderSpecific(fine,DM_CLASSID,2);
1096f692024eSJed Brown   ierr = DMSetUp(coarse);CHKERRQ(ierr);
1097f692024eSJed Brown   ierr = DMSetUp(fine);CHKERRQ(ierr);
109847c6ae99SBarry Smith   /* use global vectors only for determining matrix layout */
10999ae5db72SJed Brown   ierr = DMGetGlobalVector(coarse,&gcoarse);CHKERRQ(ierr);
11009ae5db72SJed Brown   ierr = DMGetGlobalVector(fine,&gfine);CHKERRQ(ierr);
110147c6ae99SBarry Smith   ierr = VecGetLocalSize(gcoarse,&n);CHKERRQ(ierr);
110247c6ae99SBarry Smith   ierr = VecGetLocalSize(gfine,&m);CHKERRQ(ierr);
110347c6ae99SBarry Smith   ierr = VecGetSize(gcoarse,&N);CHKERRQ(ierr);
110447c6ae99SBarry Smith   ierr = VecGetSize(gfine,&M);CHKERRQ(ierr);
11059ae5db72SJed Brown   ierr = DMRestoreGlobalVector(coarse,&gcoarse);CHKERRQ(ierr);
11069ae5db72SJed Brown   ierr = DMRestoreGlobalVector(fine,&gfine);CHKERRQ(ierr);
110747c6ae99SBarry Smith 
11089ae5db72SJed Brown   nDM = comfine->nDM;
11099ae5db72SJed Brown   if (nDM != comcoarse->nDM) SETERRQ2(((PetscObject)fine)->comm,PETSC_ERR_ARG_INCOMP,"Fine DMComposite has %D entries, but coarse has %D",nDM,comcoarse->nDM);
11109ae5db72SJed Brown   ierr = PetscMalloc(nDM*nDM*sizeof(Mat),&mats);CHKERRQ(ierr);
11119ae5db72SJed Brown   ierr = PetscMemzero(mats,nDM*nDM*sizeof(Mat));CHKERRQ(ierr);
111225296bd5SBarry Smith   if (v) {
111325296bd5SBarry Smith     ierr = PetscMalloc(nDM*sizeof(Vec),&vecs);CHKERRQ(ierr);
111425296bd5SBarry Smith     ierr = PetscMemzero(vecs,nDM*sizeof(Vec));CHKERRQ(ierr);
111525296bd5SBarry Smith   }
111647c6ae99SBarry Smith 
111747c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
11189ae5db72SJed Brown   for (nextc=comcoarse->next,nextf=comfine->next,i=0; nextc; nextc=nextc->next,nextf=nextf->next,i++) {
111925296bd5SBarry Smith     if (!v) {
1120e727c939SJed Brown       ierr = DMCreateInterpolation(nextc->dm,nextf->dm,&mats[i*nDM+i],PETSC_NULL);CHKERRQ(ierr);
112125296bd5SBarry Smith     } else {
112225296bd5SBarry Smith       ierr = DMCreateInterpolation(nextc->dm,nextf->dm,&mats[i*nDM+i],&vecs[i]);CHKERRQ(ierr);
112325296bd5SBarry Smith     }
112447c6ae99SBarry Smith   }
11259ae5db72SJed Brown   ierr = MatCreateNest(((PetscObject)fine)->comm,nDM,PETSC_NULL,nDM,PETSC_NULL,mats,A);CHKERRQ(ierr);
112625296bd5SBarry Smith   if (v) {
112725296bd5SBarry Smith     ierr = VecCreateNest(((PetscObject)fine)->comm,nDM,PETSC_NULL,vecs,v);CHKERRQ(ierr);
112825296bd5SBarry Smith   }
11299ae5db72SJed Brown   for (i=0; i<nDM*nDM; i++) {ierr = MatDestroy(&mats[i]);CHKERRQ(ierr);}
11309ae5db72SJed Brown   ierr = PetscFree(mats);CHKERRQ(ierr);
113125296bd5SBarry Smith   if (v) {
113225296bd5SBarry Smith     for (i=0; i<nDM; i++) {ierr = VecDestroy(&vecs[i]);CHKERRQ(ierr);}
113325296bd5SBarry Smith     ierr = PetscFree(vecs);CHKERRQ(ierr);
113425296bd5SBarry Smith   }
113547c6ae99SBarry Smith   PetscFunctionReturn(0);
113647c6ae99SBarry Smith }
113747c6ae99SBarry Smith 
113847c6ae99SBarry Smith #undef __FUNCT__
11391411c6eeSJed Brown #define __FUNCT__ "DMCreateLocalToGlobalMapping_Composite"
11401411c6eeSJed Brown static PetscErrorCode DMCreateLocalToGlobalMapping_Composite(DM dm)
11411411c6eeSJed Brown {
11421411c6eeSJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
11431411c6eeSJed Brown   ISLocalToGlobalMapping *ltogs;
1144f7efa3c7SJed Brown   PetscInt               i;
11451411c6eeSJed Brown   PetscErrorCode         ierr;
11461411c6eeSJed Brown 
11471411c6eeSJed Brown   PetscFunctionBegin;
11481411c6eeSJed Brown   /* Set the ISLocalToGlobalMapping on the new matrix */
11491411c6eeSJed Brown   ierr = DMCompositeGetISLocalToGlobalMappings(dm,&ltogs);CHKERRQ(ierr);
11509ae5db72SJed Brown   ierr = ISLocalToGlobalMappingConcatenate(((PetscObject)dm)->comm,com->nDM,ltogs,&dm->ltogmap);CHKERRQ(ierr);
11519ae5db72SJed Brown   for (i=0; i<com->nDM; i++) {ierr = ISLocalToGlobalMappingDestroy(&ltogs[i]);CHKERRQ(ierr);}
11521411c6eeSJed Brown   ierr = PetscFree(ltogs);CHKERRQ(ierr);
11531411c6eeSJed Brown   PetscFunctionReturn(0);
11541411c6eeSJed Brown }
11551411c6eeSJed Brown 
11561411c6eeSJed Brown 
11571411c6eeSJed Brown #undef __FUNCT__
1158e727c939SJed Brown #define __FUNCT__ "DMCreateColoring_Composite"
115919fd82e9SBarry Smith PetscErrorCode  DMCreateColoring_Composite(DM dm,ISColoringType ctype,MatType mtype,ISColoring *coloring)
116047c6ae99SBarry Smith {
116147c6ae99SBarry Smith   PetscErrorCode  ierr;
116247c6ae99SBarry Smith   PetscInt        n,i,cnt;
116347c6ae99SBarry Smith   ISColoringValue *colors;
116447c6ae99SBarry Smith   PetscBool       dense  = PETSC_FALSE;
116547c6ae99SBarry Smith   ISColoringValue maxcol = 0;
116647c6ae99SBarry Smith   DM_Composite    *com   = (DM_Composite*)dm->data;
116747c6ae99SBarry Smith 
116847c6ae99SBarry Smith   PetscFunctionBegin;
116947c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
11709805c61eSBarry Smith   if (ctype == IS_COLORING_GHOSTED) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"Only global coloring supported");
1171e3247f34SBarry Smith   else if (ctype == IS_COLORING_GLOBAL) {
117247c6ae99SBarry Smith     n = com->n;
117347c6ae99SBarry Smith   } else SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Unknown ISColoringType");
117447c6ae99SBarry Smith   ierr = PetscMalloc(n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr); /* freed in ISColoringDestroy() */
117547c6ae99SBarry Smith 
1176671f6225SBarry Smith   ierr = PetscOptionsGetBool(PETSC_NULL,"-dmcomposite_dense_jacobian",&dense,PETSC_NULL);CHKERRQ(ierr);
117747c6ae99SBarry Smith   if (dense) {
117847c6ae99SBarry Smith     for (i=0; i<n; i++) {
117947c6ae99SBarry Smith       colors[i] = (ISColoringValue)(com->rstart + i);
118047c6ae99SBarry Smith     }
118147c6ae99SBarry Smith     maxcol = com->N;
118247c6ae99SBarry Smith   } else {
118347c6ae99SBarry Smith     struct DMCompositeLink *next = com->next;
118447c6ae99SBarry Smith     PetscMPIInt            rank;
118547c6ae99SBarry Smith 
118647c6ae99SBarry Smith     ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr);
118747c6ae99SBarry Smith     cnt  = 0;
118847c6ae99SBarry Smith     while (next) {
118947c6ae99SBarry Smith       ISColoring lcoloring;
119047c6ae99SBarry Smith 
1191e727c939SJed Brown       ierr = DMCreateColoring(next->dm,IS_COLORING_GLOBAL,mtype,&lcoloring);CHKERRQ(ierr);
119247c6ae99SBarry Smith       for (i=0; i<lcoloring->N; i++) {
119347c6ae99SBarry Smith         colors[cnt++] = maxcol + lcoloring->colors[i];
119447c6ae99SBarry Smith       }
119547c6ae99SBarry Smith       maxcol += lcoloring->n;
1196fcfd50ebSBarry Smith       ierr    = ISColoringDestroy(&lcoloring);CHKERRQ(ierr);
119747c6ae99SBarry Smith       next    = next->next;
119847c6ae99SBarry Smith     }
119947c6ae99SBarry Smith   }
120047c6ae99SBarry Smith   ierr = ISColoringCreate(((PetscObject)dm)->comm,maxcol,n,colors,coloring);CHKERRQ(ierr);
120147c6ae99SBarry Smith   PetscFunctionReturn(0);
120247c6ae99SBarry Smith }
120347c6ae99SBarry Smith 
120447c6ae99SBarry Smith #undef __FUNCT__
12050c010503SBarry Smith #define __FUNCT__ "DMGlobalToLocalBegin_Composite"
12067087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalBegin_Composite(DM dm,Vec gvec,InsertMode mode,Vec lvec)
120747c6ae99SBarry Smith {
120847c6ae99SBarry Smith   PetscErrorCode         ierr;
120947c6ae99SBarry Smith   struct DMCompositeLink *next;
121047c6ae99SBarry Smith   PetscInt               cnt = 3;
121147c6ae99SBarry Smith   PetscMPIInt            rank;
121247c6ae99SBarry Smith   PetscScalar            *garray,*larray;
121347c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
121447c6ae99SBarry Smith 
121547c6ae99SBarry Smith   PetscFunctionBegin;
121647c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
121747c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
121847c6ae99SBarry Smith   next = com->next;
121947c6ae99SBarry Smith   if (!com->setup) {
1220d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
122147c6ae99SBarry Smith   }
122247c6ae99SBarry Smith   ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr);
122347c6ae99SBarry Smith   ierr = VecGetArray(gvec,&garray);CHKERRQ(ierr);
122447c6ae99SBarry Smith   ierr = VecGetArray(lvec,&larray);CHKERRQ(ierr);
122547c6ae99SBarry Smith 
122647c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
122747c6ae99SBarry Smith   while (next) {
122847c6ae99SBarry Smith     Vec      local,global;
122947c6ae99SBarry Smith     PetscInt N;
123047c6ae99SBarry Smith 
123147c6ae99SBarry Smith     ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
123247c6ae99SBarry Smith     ierr = VecGetLocalSize(global,&N);CHKERRQ(ierr);
123347c6ae99SBarry Smith     ierr = VecPlaceArray(global,garray);CHKERRQ(ierr);
123447c6ae99SBarry Smith     ierr = DMGetLocalVector(next->dm,&local);CHKERRQ(ierr);
123547c6ae99SBarry Smith     ierr = VecPlaceArray(local,larray);CHKERRQ(ierr);
123647c6ae99SBarry Smith     ierr = DMGlobalToLocalBegin(next->dm,global,mode,local);CHKERRQ(ierr);
123747c6ae99SBarry Smith     ierr = DMGlobalToLocalEnd(next->dm,global,mode,local);CHKERRQ(ierr);
123847c6ae99SBarry Smith     ierr = VecResetArray(global);CHKERRQ(ierr);
123947c6ae99SBarry Smith     ierr = VecResetArray(local);CHKERRQ(ierr);
124047c6ae99SBarry Smith     ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
124147c6ae99SBarry Smith     ierr = DMRestoreGlobalVector(next->dm,&local);CHKERRQ(ierr);
124247c6ae99SBarry Smith     cnt++;
124306ebdd98SJed Brown     larray += next->nlocal;
124447c6ae99SBarry Smith     next    = next->next;
124547c6ae99SBarry Smith   }
124647c6ae99SBarry Smith 
124747c6ae99SBarry Smith   ierr = VecRestoreArray(gvec,PETSC_NULL);CHKERRQ(ierr);
124847c6ae99SBarry Smith   ierr = VecRestoreArray(lvec,PETSC_NULL);CHKERRQ(ierr);
124947c6ae99SBarry Smith   PetscFunctionReturn(0);
125047c6ae99SBarry Smith }
125147c6ae99SBarry Smith 
125247c6ae99SBarry Smith #undef __FUNCT__
12530c010503SBarry Smith #define __FUNCT__ "DMGlobalToLocalEnd_Composite"
12547087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalEnd_Composite(DM dm,Vec gvec,InsertMode mode,Vec lvec)
12550c010503SBarry Smith {
12560c010503SBarry Smith   PetscFunctionBegin;
12570c010503SBarry Smith   PetscFunctionReturn(0);
12580c010503SBarry Smith }
125947c6ae99SBarry Smith 
12606ae3a549SBarry Smith /*MC
12616ae3a549SBarry Smith    DMCOMPOSITE = "composite" - A DM object that is used to manage data for a collection of DMs
12626ae3a549SBarry Smith 
12636ae3a549SBarry Smith 
12646ae3a549SBarry Smith 
12656ae3a549SBarry Smith   Level: intermediate
12666ae3a549SBarry Smith 
12676ae3a549SBarry Smith .seealso: DMType, DMCOMPOSITE, DMDACreate(), DMCreate(), DMSetType(), DMCompositeCreate()
12686ae3a549SBarry Smith M*/
12696ae3a549SBarry Smith 
12706ae3a549SBarry Smith 
1271a4121054SBarry Smith EXTERN_C_BEGIN
1272a4121054SBarry Smith #undef __FUNCT__
1273a4121054SBarry Smith #define __FUNCT__ "DMCreate_Composite"
12747087cfbeSBarry Smith PetscErrorCode  DMCreate_Composite(DM p)
1275a4121054SBarry Smith {
1276a4121054SBarry Smith   PetscErrorCode ierr;
1277a4121054SBarry Smith   DM_Composite   *com;
1278a4121054SBarry Smith 
1279a4121054SBarry Smith   PetscFunctionBegin;
1280a4121054SBarry Smith   ierr      = PetscNewLog(p,DM_Composite,&com);CHKERRQ(ierr);
1281a4121054SBarry Smith   p->data   = com;
1282a4121054SBarry Smith   ierr      = PetscObjectChangeTypeName((PetscObject)p,"DMComposite");CHKERRQ(ierr);
1283a4121054SBarry Smith   com->n    = 0;
1284a4121054SBarry Smith   com->next = PETSC_NULL;
1285a4121054SBarry Smith   com->nDM  = 0;
1286a4121054SBarry Smith 
1287a4121054SBarry Smith   p->ops->createglobalvector              = DMCreateGlobalVector_Composite;
1288a4121054SBarry Smith   p->ops->createlocalvector               = DMCreateLocalVector_Composite;
12891411c6eeSJed Brown   p->ops->createlocaltoglobalmapping      = DMCreateLocalToGlobalMapping_Composite;
12901411c6eeSJed Brown   p->ops->createlocaltoglobalmappingblock = 0;
12914d343eeaSMatthew G Knepley   p->ops->createfieldis                   = DMCreateFieldIS_Composite;
129216621825SDmitry Karpeev   p->ops->createfielddecomposition        = DMCreateFieldDecomposition_Composite;
1293a4121054SBarry Smith   p->ops->refine                          = DMRefine_Composite;
129414354c39SJed Brown   p->ops->coarsen                         = DMCoarsen_Composite;
129525296bd5SBarry Smith   p->ops->createinterpolation             = DMCreateInterpolation_Composite;
129625296bd5SBarry Smith   p->ops->creatematrix                    = DMCreateMatrix_Composite;
1297e727c939SJed Brown   p->ops->getcoloring                     = DMCreateColoring_Composite;
1298a4121054SBarry Smith   p->ops->globaltolocalbegin              = DMGlobalToLocalBegin_Composite;
1299a4121054SBarry Smith   p->ops->globaltolocalend                = DMGlobalToLocalEnd_Composite;
1300a4121054SBarry Smith   p->ops->destroy                         = DMDestroy_Composite;
1301a4121054SBarry Smith   p->ops->view                            = DMView_Composite;
1302a4121054SBarry Smith   p->ops->setup                           = DMSetUp_Composite;
1303a4121054SBarry Smith   PetscFunctionReturn(0);
1304a4121054SBarry Smith }
1305a4121054SBarry Smith EXTERN_C_END
1306a4121054SBarry Smith 
13070c010503SBarry Smith #undef __FUNCT__
13080c010503SBarry Smith #define __FUNCT__ "DMCompositeCreate"
13090c010503SBarry Smith /*@C
13100c010503SBarry Smith     DMCompositeCreate - Creates a vector packer, used to generate "composite"
13110c010503SBarry Smith       vectors made up of several subvectors.
13120c010503SBarry Smith 
13130c010503SBarry Smith     Collective on MPI_Comm
131447c6ae99SBarry Smith 
131547c6ae99SBarry Smith     Input Parameter:
13160c010503SBarry Smith .   comm - the processors that will share the global vector
13170c010503SBarry Smith 
13180c010503SBarry Smith     Output Parameters:
13190c010503SBarry Smith .   packer - the packer object
132047c6ae99SBarry Smith 
132147c6ae99SBarry Smith     Level: advanced
132247c6ae99SBarry Smith 
13239ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCompositeScatter(),
13246eb61c8cSJed Brown          DMCompositeGather(), DMCreateGlobalVector(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess()
132547c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries()
132647c6ae99SBarry Smith 
132747c6ae99SBarry Smith @*/
13287087cfbeSBarry Smith PetscErrorCode  DMCompositeCreate(MPI_Comm comm,DM *packer)
132947c6ae99SBarry Smith {
13300c010503SBarry Smith   PetscErrorCode ierr;
13310c010503SBarry Smith 
133247c6ae99SBarry Smith   PetscFunctionBegin;
13330c010503SBarry Smith   PetscValidPointer(packer,2);
1334a4121054SBarry Smith   ierr = DMCreate(comm,packer);CHKERRQ(ierr);
1335a4121054SBarry Smith   ierr = DMSetType(*packer,DMCOMPOSITE);CHKERRQ(ierr);
133647c6ae99SBarry Smith   PetscFunctionReturn(0);
133747c6ae99SBarry Smith }
1338