xref: /petsc/src/dm/impls/composite/pack.c (revision c5d31e7540f9cc340e570ea515bda94a0dc45b35)
147c6ae99SBarry Smith 
2ccd284c7SBarry Smith #include <../src/dm/impls/composite/packimpl.h>       /*I  "petscdmcomposite.h"  I*/
301e13f73SMatthew G. Knepley #include <petsc-private/isimpl.h>
42764a2aaSMatthew G. Knepley #include <petscds.h>
547c6ae99SBarry Smith 
647c6ae99SBarry Smith #undef __FUNCT__
747c6ae99SBarry Smith #define __FUNCT__ "DMCompositeSetCoupling"
847c6ae99SBarry Smith /*@C
947c6ae99SBarry Smith     DMCompositeSetCoupling - Sets user provided routines that compute the coupling between the
109ae5db72SJed Brown       seperate components (DMs) in a DMto build the correct matrix nonzero structure.
1147c6ae99SBarry Smith 
1247c6ae99SBarry Smith 
1347c6ae99SBarry Smith     Logically Collective on MPI_Comm
1447c6ae99SBarry Smith 
1547c6ae99SBarry Smith     Input Parameter:
1647c6ae99SBarry Smith +   dm - the composite object
1747c6ae99SBarry Smith -   formcouplelocations - routine to set the nonzero locations in the matrix
1847c6ae99SBarry Smith 
1947c6ae99SBarry Smith     Level: advanced
2047c6ae99SBarry Smith 
211b2093e4SBarry Smith     Notes: See DMSetApplicationContext() and DMGetApplicationContext() for how to get user information into
2247c6ae99SBarry Smith         this routine
2347c6ae99SBarry Smith 
2447c6ae99SBarry Smith @*/
257087cfbeSBarry Smith PetscErrorCode  DMCompositeSetCoupling(DM dm,PetscErrorCode (*FormCoupleLocations)(DM,Mat,PetscInt*,PetscInt*,PetscInt,PetscInt,PetscInt,PetscInt))
2647c6ae99SBarry Smith {
2747c6ae99SBarry Smith   DM_Composite *com = (DM_Composite*)dm->data;
2847c6ae99SBarry Smith 
2947c6ae99SBarry Smith   PetscFunctionBegin;
3047c6ae99SBarry Smith   com->FormCoupleLocations = FormCoupleLocations;
3147c6ae99SBarry Smith   PetscFunctionReturn(0);
3247c6ae99SBarry Smith }
3347c6ae99SBarry Smith 
3447c6ae99SBarry Smith #undef __FUNCT__
350c010503SBarry Smith #define __FUNCT__ "DMDestroy_Composite"
366bf464f9SBarry Smith PetscErrorCode  DMDestroy_Composite(DM dm)
3747c6ae99SBarry Smith {
3847c6ae99SBarry Smith   PetscErrorCode         ierr;
3947c6ae99SBarry Smith   struct DMCompositeLink *next, *prev;
4047c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
4147c6ae99SBarry Smith 
4247c6ae99SBarry Smith   PetscFunctionBegin;
4347c6ae99SBarry Smith   next = com->next;
4447c6ae99SBarry Smith   while (next) {
4547c6ae99SBarry Smith     prev = next;
4647c6ae99SBarry Smith     next = next->next;
47fcfd50ebSBarry Smith     ierr = DMDestroy(&prev->dm);CHKERRQ(ierr);
4847c6ae99SBarry Smith     ierr = PetscFree(prev->grstarts);CHKERRQ(ierr);
4947c6ae99SBarry Smith     ierr = PetscFree(prev);CHKERRQ(ierr);
5047c6ae99SBarry Smith   }
51435a35e8SMatthew G Knepley   /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */
52435a35e8SMatthew G Knepley   ierr = PetscFree(com);CHKERRQ(ierr);
5347c6ae99SBarry Smith   PetscFunctionReturn(0);
5447c6ae99SBarry Smith }
5547c6ae99SBarry Smith 
5647c6ae99SBarry Smith #undef __FUNCT__
570c010503SBarry Smith #define __FUNCT__ "DMView_Composite"
587087cfbeSBarry Smith PetscErrorCode  DMView_Composite(DM dm,PetscViewer v)
5947c6ae99SBarry Smith {
6047c6ae99SBarry Smith   PetscErrorCode ierr;
6147c6ae99SBarry Smith   PetscBool      iascii;
6247c6ae99SBarry Smith   DM_Composite   *com = (DM_Composite*)dm->data;
6347c6ae99SBarry Smith 
6447c6ae99SBarry Smith   PetscFunctionBegin;
65251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
6647c6ae99SBarry Smith   if (iascii) {
6747c6ae99SBarry Smith     struct DMCompositeLink *lnk = com->next;
6847c6ae99SBarry Smith     PetscInt               i;
6947c6ae99SBarry Smith 
7047c6ae99SBarry Smith     ierr = PetscViewerASCIIPrintf(v,"DM (%s)\n",((PetscObject)dm)->prefix ? ((PetscObject)dm)->prefix : "no prefix");CHKERRQ(ierr);
719ae5db72SJed Brown     ierr = PetscViewerASCIIPrintf(v,"  contains %D DMs\n",com->nDM);CHKERRQ(ierr);
7247c6ae99SBarry Smith     ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr);
7347c6ae99SBarry Smith     for (i=0; lnk; lnk=lnk->next,i++) {
749ae5db72SJed Brown       ierr = PetscViewerASCIIPrintf(v,"Link %D: DM of type %s\n",i,((PetscObject)lnk->dm)->type_name);CHKERRQ(ierr);
7547c6ae99SBarry Smith       ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr);
7647c6ae99SBarry Smith       ierr = DMView(lnk->dm,v);CHKERRQ(ierr);
7747c6ae99SBarry Smith       ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr);
7847c6ae99SBarry Smith     }
7947c6ae99SBarry Smith     ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr);
8047c6ae99SBarry Smith   }
8147c6ae99SBarry Smith   PetscFunctionReturn(0);
8247c6ae99SBarry Smith }
8347c6ae99SBarry Smith 
8447c6ae99SBarry Smith /* --------------------------------------------------------------------------------------*/
8547c6ae99SBarry Smith #undef __FUNCT__
86d7bf68aeSBarry Smith #define __FUNCT__ "DMSetUp_Composite"
877087cfbeSBarry Smith PetscErrorCode  DMSetUp_Composite(DM dm)
8847c6ae99SBarry Smith {
8947c6ae99SBarry Smith   PetscErrorCode         ierr;
9047c6ae99SBarry Smith   PetscInt               nprev = 0;
9147c6ae99SBarry Smith   PetscMPIInt            rank,size;
9247c6ae99SBarry Smith   DM_Composite           *com  = (DM_Composite*)dm->data;
9347c6ae99SBarry Smith   struct DMCompositeLink *next = com->next;
9447c6ae99SBarry Smith   PetscLayout            map;
9547c6ae99SBarry Smith 
9647c6ae99SBarry Smith   PetscFunctionBegin;
97ce94432eSBarry Smith   if (com->setup) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Packer has already been setup");
98ce94432eSBarry Smith   ierr = PetscLayoutCreate(PetscObjectComm((PetscObject)dm),&map);CHKERRQ(ierr);
9947c6ae99SBarry Smith   ierr = PetscLayoutSetLocalSize(map,com->n);CHKERRQ(ierr);
10047c6ae99SBarry Smith   ierr = PetscLayoutSetSize(map,PETSC_DETERMINE);CHKERRQ(ierr);
10147c6ae99SBarry Smith   ierr = PetscLayoutSetBlockSize(map,1);CHKERRQ(ierr);
10247c6ae99SBarry Smith   ierr = PetscLayoutSetUp(map);CHKERRQ(ierr);
10347c6ae99SBarry Smith   ierr = PetscLayoutGetSize(map,&com->N);CHKERRQ(ierr);
1040298fd71SBarry Smith   ierr = PetscLayoutGetRange(map,&com->rstart,NULL);CHKERRQ(ierr);
105fcfd50ebSBarry Smith   ierr = PetscLayoutDestroy(&map);CHKERRQ(ierr);
10647c6ae99SBarry Smith 
1079ae5db72SJed Brown   /* now set the rstart for each linked vector */
108ce94432eSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
109ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm),&size);CHKERRQ(ierr);
11047c6ae99SBarry Smith   while (next) {
11147c6ae99SBarry Smith     next->rstart  = nprev;
11206ebdd98SJed Brown     nprev        += next->n;
11347c6ae99SBarry Smith     next->grstart = com->rstart + next->rstart;
114785e854fSJed Brown     ierr          = PetscMalloc1(size,&next->grstarts);CHKERRQ(ierr);
115ce94432eSBarry Smith     ierr          = MPI_Allgather(&next->grstart,1,MPIU_INT,next->grstarts,1,MPIU_INT,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
11647c6ae99SBarry Smith     next          = next->next;
11747c6ae99SBarry Smith   }
11847c6ae99SBarry Smith   com->setup = PETSC_TRUE;
11947c6ae99SBarry Smith   PetscFunctionReturn(0);
12047c6ae99SBarry Smith }
12147c6ae99SBarry Smith 
12247c6ae99SBarry Smith /* ----------------------------------------------------------------------------------*/
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:
1650298fd71SBarry Smith .    Vec* ... - the packed parallel vectors, 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 
169f73e5cebSJed Brown     Fortran Notes:
170f73e5cebSJed Brown 
171f73e5cebSJed Brown     Fortran callers must use numbered versions of this routine, e.g., DMCompositeGetAccess4(dm,gvec,vec1,vec2,vec3,vec4)
172f73e5cebSJed Brown     or use the alternative interface DMCompositeGetAccessArray().
173f73e5cebSJed Brown 
17447c6ae99SBarry Smith     Level: advanced
17547c6ae99SBarry Smith 
176f73e5cebSJed 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;
1845edff71fSBarry Smith   PetscInt               readonly;
18547c6ae99SBarry Smith 
18647c6ae99SBarry Smith   PetscFunctionBegin;
18747c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
18847c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
18947c6ae99SBarry Smith   next = com->next;
19047c6ae99SBarry Smith   if (!com->setup) {
191d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
19247c6ae99SBarry Smith   }
19347c6ae99SBarry Smith 
1945edff71fSBarry Smith   ierr = VecLockGet(gvec,&readonly);CHKERRQ(ierr);
19547c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
19647c6ae99SBarry Smith   va_start(Argp,gvec);
19747c6ae99SBarry Smith   while (next) {
19847c6ae99SBarry Smith     Vec *vec;
19947c6ae99SBarry Smith     vec = va_arg(Argp, Vec*);
2009ae5db72SJed Brown     if (vec) {
2019ae5db72SJed Brown       ierr = DMGetGlobalVector(next->dm,vec);CHKERRQ(ierr);
2025edff71fSBarry Smith       if (readonly) {
2035edff71fSBarry Smith         const PetscScalar *array;
2045edff71fSBarry Smith         ierr = VecGetArrayRead(gvec,&array);CHKERRQ(ierr);
2055edff71fSBarry Smith         ierr = VecPlaceArray(*vec,array+next->rstart);CHKERRQ(ierr);
2065edff71fSBarry Smith         ierr = VecLockPush(*vec);CHKERRQ(ierr);
2075edff71fSBarry Smith         ierr = VecRestoreArrayRead(gvec,&array);CHKERRQ(ierr);
2085edff71fSBarry Smith       } else {
2095edff71fSBarry Smith         PetscScalar *array;
2109ae5db72SJed Brown         ierr = VecGetArray(gvec,&array);CHKERRQ(ierr);
2119ae5db72SJed Brown         ierr = VecPlaceArray(*vec,array+next->rstart);CHKERRQ(ierr);
2129ae5db72SJed Brown         ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr);
21347c6ae99SBarry Smith       }
2145edff71fSBarry Smith     }
21547c6ae99SBarry Smith     next = next->next;
21647c6ae99SBarry Smith   }
21747c6ae99SBarry Smith   va_end(Argp);
21847c6ae99SBarry Smith   PetscFunctionReturn(0);
21947c6ae99SBarry Smith }
22047c6ae99SBarry Smith 
22147c6ae99SBarry Smith #undef __FUNCT__
222f73e5cebSJed Brown #define __FUNCT__ "DMCompositeGetAccessArray"
223f73e5cebSJed Brown /*@C
224f73e5cebSJed Brown     DMCompositeGetAccessArray - Allows one to access the individual packed vectors in their global
225f73e5cebSJed Brown        representation.
226f73e5cebSJed Brown 
227f73e5cebSJed Brown     Collective on DMComposite
228f73e5cebSJed Brown 
229f73e5cebSJed Brown     Input Parameters:
230f73e5cebSJed Brown +    dm - the packer object
231f73e5cebSJed Brown .    pvec - packed vector
232f73e5cebSJed Brown .    nwanted - number of vectors wanted
2330298fd71SBarry Smith -    wanted - sorted array of vectors wanted, or NULL to get all vectors
234f73e5cebSJed Brown 
235f73e5cebSJed Brown     Output Parameters:
236f73e5cebSJed Brown .    vecs - array of requested global vectors (must be allocated)
237f73e5cebSJed Brown 
238f73e5cebSJed Brown     Notes: Use DMCompositeRestoreAccessArray() to return the vectors when you no longer need them
239f73e5cebSJed Brown 
240f73e5cebSJed Brown     Level: advanced
241f73e5cebSJed Brown 
242f73e5cebSJed Brown .seealso: DMCompositeGetAccess(), DMCompositeGetEntries(), DMCompositeScatter(), DMCompositeGather()
243f73e5cebSJed Brown @*/
244f73e5cebSJed Brown PetscErrorCode  DMCompositeGetAccessArray(DM dm,Vec pvec,PetscInt nwanted,const PetscInt *wanted,Vec *vecs)
245f73e5cebSJed Brown {
246f73e5cebSJed Brown   PetscErrorCode         ierr;
247f73e5cebSJed Brown   struct DMCompositeLink *link;
248f73e5cebSJed Brown   PetscInt               i,wnum;
249f73e5cebSJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
250f73e5cebSJed Brown 
251f73e5cebSJed Brown   PetscFunctionBegin;
252f73e5cebSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
253f73e5cebSJed Brown   PetscValidHeaderSpecific(pvec,VEC_CLASSID,2);
254f73e5cebSJed Brown   if (!com->setup) {
255f73e5cebSJed Brown     ierr = DMSetUp(dm);CHKERRQ(ierr);
256f73e5cebSJed Brown   }
257f73e5cebSJed Brown 
258f73e5cebSJed Brown   for (i=0,wnum=0,link=com->next; link && wnum<nwanted; i++,link=link->next) {
259f73e5cebSJed Brown     if (!wanted || i == wanted[wnum]) {
260f73e5cebSJed Brown       PetscScalar *array;
261f73e5cebSJed Brown       Vec v;
262f73e5cebSJed Brown       ierr = DMGetGlobalVector(link->dm,&v);CHKERRQ(ierr);
263f73e5cebSJed Brown       ierr = VecGetArray(pvec,&array);CHKERRQ(ierr);
264f73e5cebSJed Brown       ierr = VecPlaceArray(v,array+link->rstart);CHKERRQ(ierr);
265f73e5cebSJed Brown       ierr = VecRestoreArray(pvec,&array);CHKERRQ(ierr);
266f73e5cebSJed Brown       vecs[wnum++] = v;
267f73e5cebSJed Brown     }
268f73e5cebSJed Brown   }
269f73e5cebSJed Brown   PetscFunctionReturn(0);
270f73e5cebSJed Brown }
271f73e5cebSJed Brown 
272f73e5cebSJed Brown #undef __FUNCT__
27347c6ae99SBarry Smith #define __FUNCT__ "DMCompositeRestoreAccess"
27447c6ae99SBarry Smith /*@C
275aa219208SBarry Smith     DMCompositeRestoreAccess - Returns the vectors obtained with DMCompositeGetAccess()
27647c6ae99SBarry Smith        representation.
27747c6ae99SBarry Smith 
27847c6ae99SBarry Smith     Collective on DMComposite
27947c6ae99SBarry Smith 
2809ae5db72SJed Brown     Input Parameters:
28147c6ae99SBarry Smith +    dm - the packer object
28247c6ae99SBarry Smith .    gvec - the global vector
2830298fd71SBarry Smith -    Vec* ... - the individual parallel vectors, NULL for those that are not needed
28447c6ae99SBarry Smith 
28547c6ae99SBarry Smith     Level: advanced
28647c6ae99SBarry Smith 
2879ae5db72SJed Brown .seealso  DMCompositeAddDM(), DMCreateGlobalVector(),
2886eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeScatter(),
289aa219208SBarry Smith          DMCompositeRestoreAccess(), DMCompositeGetAccess()
29047c6ae99SBarry Smith 
29147c6ae99SBarry Smith @*/
2927087cfbeSBarry Smith PetscErrorCode  DMCompositeRestoreAccess(DM dm,Vec gvec,...)
29347c6ae99SBarry Smith {
29447c6ae99SBarry Smith   va_list                Argp;
29547c6ae99SBarry Smith   PetscErrorCode         ierr;
29647c6ae99SBarry Smith   struct DMCompositeLink *next;
29747c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
2985edff71fSBarry Smith   PetscInt               readonly;
29947c6ae99SBarry Smith 
30047c6ae99SBarry Smith   PetscFunctionBegin;
30147c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
30247c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
30347c6ae99SBarry Smith   next = com->next;
30447c6ae99SBarry Smith   if (!com->setup) {
305d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
30647c6ae99SBarry Smith   }
30747c6ae99SBarry Smith 
3085edff71fSBarry Smith   ierr = VecLockGet(gvec,&readonly);CHKERRQ(ierr);
30947c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
31047c6ae99SBarry Smith   va_start(Argp,gvec);
31147c6ae99SBarry Smith   while (next) {
31247c6ae99SBarry Smith     Vec *vec;
31347c6ae99SBarry Smith     vec = va_arg(Argp, Vec*);
3149ae5db72SJed Brown     if (vec) {
3159ae5db72SJed Brown       ierr = VecResetArray(*vec);CHKERRQ(ierr);
3165edff71fSBarry Smith       if (readonly) {
3175edff71fSBarry Smith         ierr = VecLockPop(*vec);CHKERRQ(ierr);
3189ae5db72SJed Brown         ierr = DMRestoreGlobalVector(next->dm,vec);CHKERRQ(ierr);
3195edff71fSBarry Smith       } else {
3205edff71fSBarry Smith         ierr = DMRestoreGlobalVector(next->dm,vec);CHKERRQ(ierr);
3215edff71fSBarry Smith       }
32247c6ae99SBarry Smith     }
32347c6ae99SBarry Smith     next = next->next;
32447c6ae99SBarry Smith   }
32547c6ae99SBarry Smith   va_end(Argp);
32647c6ae99SBarry Smith   PetscFunctionReturn(0);
32747c6ae99SBarry Smith }
32847c6ae99SBarry Smith 
32947c6ae99SBarry Smith #undef __FUNCT__
330f73e5cebSJed Brown #define __FUNCT__ "DMCompositeRestoreAccessArray"
331f73e5cebSJed Brown /*@C
332f73e5cebSJed Brown     DMCompositeRestoreAccessArray - Returns the vectors obtained with DMCompositeGetAccessArray()
333f73e5cebSJed Brown 
334f73e5cebSJed Brown     Collective on DMComposite
335f73e5cebSJed Brown 
336f73e5cebSJed Brown     Input Parameters:
337f73e5cebSJed Brown +    dm - the packer object
338f73e5cebSJed Brown .    pvec - packed vector
339f73e5cebSJed Brown .    nwanted - number of vectors wanted
3400298fd71SBarry Smith .    wanted - sorted array of vectors wanted, or NULL to get all vectors
341f73e5cebSJed Brown -    vecs - array of global vectors to return
342f73e5cebSJed Brown 
343f73e5cebSJed Brown     Level: advanced
344f73e5cebSJed Brown 
345f73e5cebSJed Brown .seealso: DMCompositeRestoreAccess(), DMCompositeRestoreEntries(), DMCompositeScatter(), DMCompositeGather()
346f73e5cebSJed Brown @*/
347f73e5cebSJed Brown PetscErrorCode  DMCompositeRestoreAccessArray(DM dm,Vec pvec,PetscInt nwanted,const PetscInt *wanted,Vec *vecs)
348f73e5cebSJed Brown {
349f73e5cebSJed Brown   PetscErrorCode         ierr;
350f73e5cebSJed Brown   struct DMCompositeLink *link;
351f73e5cebSJed Brown   PetscInt               i,wnum;
352f73e5cebSJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
353f73e5cebSJed Brown 
354f73e5cebSJed Brown   PetscFunctionBegin;
355f73e5cebSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
356f73e5cebSJed Brown   PetscValidHeaderSpecific(pvec,VEC_CLASSID,2);
357f73e5cebSJed Brown   if (!com->setup) {
358f73e5cebSJed Brown     ierr = DMSetUp(dm);CHKERRQ(ierr);
359f73e5cebSJed Brown   }
360f73e5cebSJed Brown 
361f73e5cebSJed Brown   for (i=0,wnum=0,link=com->next; link && wnum<nwanted; i++,link=link->next) {
362f73e5cebSJed Brown     if (!wanted || i == wanted[wnum]) {
363f73e5cebSJed Brown       ierr = VecResetArray(vecs[wnum]);CHKERRQ(ierr);
364f73e5cebSJed Brown       ierr = DMRestoreGlobalVector(link->dm,&vecs[wnum]);CHKERRQ(ierr);
365f73e5cebSJed Brown       wnum++;
366f73e5cebSJed Brown     }
367f73e5cebSJed Brown   }
368f73e5cebSJed Brown   PetscFunctionReturn(0);
369f73e5cebSJed Brown }
370f73e5cebSJed Brown 
371f73e5cebSJed Brown #undef __FUNCT__
37247c6ae99SBarry Smith #define __FUNCT__ "DMCompositeScatter"
37347c6ae99SBarry Smith /*@C
37447c6ae99SBarry Smith     DMCompositeScatter - Scatters from a global packed vector into its individual local vectors
37547c6ae99SBarry Smith 
37647c6ae99SBarry Smith     Collective on DMComposite
37747c6ae99SBarry Smith 
3789ae5db72SJed Brown     Input Parameters:
37947c6ae99SBarry Smith +    dm - the packer object
38047c6ae99SBarry Smith .    gvec - the global vector
3810298fd71SBarry Smith -    Vec ... - the individual sequential vectors, NULL for those that are not needed
38247c6ae99SBarry Smith 
38347c6ae99SBarry Smith     Level: advanced
38447c6ae99SBarry Smith 
3856f3c3dcfSJed Brown     Notes:
3866f3c3dcfSJed Brown     DMCompositeScatterArray() is a non-variadic alternative that is often more convenient for library callers and is
3876f3c3dcfSJed Brown     accessible from Fortran.
3886f3c3dcfSJed Brown 
3899ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
3906eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
39147c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries()
3926f3c3dcfSJed Brown          DMCompositeScatterArray()
39347c6ae99SBarry Smith 
39447c6ae99SBarry Smith @*/
3957087cfbeSBarry Smith PetscErrorCode  DMCompositeScatter(DM dm,Vec gvec,...)
39647c6ae99SBarry Smith {
39747c6ae99SBarry Smith   va_list                Argp;
39847c6ae99SBarry Smith   PetscErrorCode         ierr;
39947c6ae99SBarry Smith   struct DMCompositeLink *next;
4008fd8f222SJed Brown   PetscInt               cnt;
40147c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
40247c6ae99SBarry Smith 
40347c6ae99SBarry Smith   PetscFunctionBegin;
40447c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
40547c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
40647c6ae99SBarry Smith   if (!com->setup) {
407d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
40847c6ae99SBarry Smith   }
40947c6ae99SBarry Smith 
41047c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
41147c6ae99SBarry Smith   va_start(Argp,gvec);
4128fd8f222SJed Brown   for (cnt=3,next=com->next; next; cnt++,next=next->next) {
4139ae5db72SJed Brown     Vec local;
4149ae5db72SJed Brown     local = va_arg(Argp, Vec);
4159ae5db72SJed Brown     if (local) {
4169ae5db72SJed Brown       Vec               global;
4175edff71fSBarry Smith       const PetscScalar *array;
4189ae5db72SJed Brown       PetscValidHeaderSpecific(local,VEC_CLASSID,cnt);
4199ae5db72SJed Brown       ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
4205edff71fSBarry Smith       ierr = VecGetArrayRead(gvec,&array);CHKERRQ(ierr);
4219ae5db72SJed Brown       ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr);
4229ae5db72SJed Brown       ierr = DMGlobalToLocalBegin(next->dm,global,INSERT_VALUES,local);CHKERRQ(ierr);
4239ae5db72SJed Brown       ierr = DMGlobalToLocalEnd(next->dm,global,INSERT_VALUES,local);CHKERRQ(ierr);
4245edff71fSBarry Smith       ierr = VecRestoreArrayRead(gvec,&array);CHKERRQ(ierr);
4259ae5db72SJed Brown       ierr = VecResetArray(global);CHKERRQ(ierr);
4269ae5db72SJed Brown       ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
42747c6ae99SBarry Smith     }
42847c6ae99SBarry Smith   }
42947c6ae99SBarry Smith   va_end(Argp);
43047c6ae99SBarry Smith   PetscFunctionReturn(0);
43147c6ae99SBarry Smith }
43247c6ae99SBarry Smith 
43347c6ae99SBarry Smith #undef __FUNCT__
4346f3c3dcfSJed Brown #define __FUNCT__ "DMCompositeScatterArray"
4356f3c3dcfSJed Brown /*@
4366f3c3dcfSJed Brown     DMCompositeScatterArray - Scatters from a global packed vector into its individual local vectors
4376f3c3dcfSJed Brown 
4386f3c3dcfSJed Brown     Collective on DMComposite
4396f3c3dcfSJed Brown 
4406f3c3dcfSJed Brown     Input Parameters:
4416f3c3dcfSJed Brown +    dm - the packer object
4426f3c3dcfSJed Brown .    gvec - the global vector
4436f3c3dcfSJed Brown .    lvecs - array of local vectors, NULL for any that are not needed
4446f3c3dcfSJed Brown 
4456f3c3dcfSJed Brown     Level: advanced
4466f3c3dcfSJed Brown 
4476f3c3dcfSJed Brown     Note:
448907376e6SBarry Smith     This is a non-variadic alternative to DMCompositeScatter()
4496f3c3dcfSJed Brown 
4506f3c3dcfSJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector()
4516f3c3dcfSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
4526f3c3dcfSJed Brown          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries()
4536f3c3dcfSJed Brown 
4546f3c3dcfSJed Brown @*/
4556f3c3dcfSJed Brown PetscErrorCode  DMCompositeScatterArray(DM dm,Vec gvec,Vec *lvecs)
4566f3c3dcfSJed Brown {
4576f3c3dcfSJed Brown   PetscErrorCode         ierr;
4586f3c3dcfSJed Brown   struct DMCompositeLink *next;
4596f3c3dcfSJed Brown   PetscInt               i;
4606f3c3dcfSJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
4616f3c3dcfSJed Brown 
4626f3c3dcfSJed Brown   PetscFunctionBegin;
4636f3c3dcfSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4646f3c3dcfSJed Brown   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
4656f3c3dcfSJed Brown   if (!com->setup) {
4666f3c3dcfSJed Brown     ierr = DMSetUp(dm);CHKERRQ(ierr);
4676f3c3dcfSJed Brown   }
4686f3c3dcfSJed Brown 
4696f3c3dcfSJed Brown   /* loop over packed objects, handling one at at time */
4706f3c3dcfSJed Brown   for (i=0,next=com->next; next; next=next->next,i++) {
4716f3c3dcfSJed Brown     if (lvecs[i]) {
4726f3c3dcfSJed Brown       Vec         global;
473*c5d31e75SLisandro Dalcin       const PetscScalar *array;
4746f3c3dcfSJed Brown       PetscValidHeaderSpecific(lvecs[i],VEC_CLASSID,3);
4756f3c3dcfSJed Brown       ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
476*c5d31e75SLisandro Dalcin       ierr = VecGetArrayRead(gvec,&array);CHKERRQ(ierr);
477*c5d31e75SLisandro Dalcin       ierr = VecPlaceArray(global,(PetscScalar*)array+next->rstart);CHKERRQ(ierr);
4786f3c3dcfSJed Brown       ierr = DMGlobalToLocalBegin(next->dm,global,INSERT_VALUES,lvecs[i]);CHKERRQ(ierr);
4796f3c3dcfSJed Brown       ierr = DMGlobalToLocalEnd(next->dm,global,INSERT_VALUES,lvecs[i]);CHKERRQ(ierr);
480*c5d31e75SLisandro Dalcin       ierr = VecRestoreArrayRead(gvec,&array);CHKERRQ(ierr);
4816f3c3dcfSJed Brown       ierr = VecResetArray(global);CHKERRQ(ierr);
4826f3c3dcfSJed Brown       ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
4836f3c3dcfSJed Brown     }
4846f3c3dcfSJed Brown   }
4856f3c3dcfSJed Brown   PetscFunctionReturn(0);
4866f3c3dcfSJed Brown }
4876f3c3dcfSJed Brown 
4886f3c3dcfSJed Brown #undef __FUNCT__
48947c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGather"
49047c6ae99SBarry Smith /*@C
49147c6ae99SBarry Smith     DMCompositeGather - Gathers into a global packed vector from its individual local vectors
49247c6ae99SBarry Smith 
49347c6ae99SBarry Smith     Collective on DMComposite
49447c6ae99SBarry Smith 
49547c6ae99SBarry Smith     Input Parameter:
49647c6ae99SBarry Smith +    dm - the packer object
49747c6ae99SBarry Smith .    gvec - the global vector
498907376e6SBarry Smith .    imode - INSERT_VALUES or ADD_VALUES
4990298fd71SBarry Smith -    Vec ... - the individual sequential vectors, NULL for any that are not needed
50047c6ae99SBarry Smith 
50147c6ae99SBarry Smith     Level: advanced
50247c6ae99SBarry Smith 
5039ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
5046eb61c8cSJed Brown          DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
50547c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries()
50647c6ae99SBarry Smith 
50747c6ae99SBarry Smith @*/
5087087cfbeSBarry Smith PetscErrorCode  DMCompositeGather(DM dm,Vec gvec,InsertMode imode,...)
50947c6ae99SBarry Smith {
51047c6ae99SBarry Smith   va_list                Argp;
51147c6ae99SBarry Smith   PetscErrorCode         ierr;
51247c6ae99SBarry Smith   struct DMCompositeLink *next;
51347c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
5148fd8f222SJed Brown   PetscInt               cnt;
51547c6ae99SBarry Smith 
51647c6ae99SBarry Smith   PetscFunctionBegin;
51747c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
51847c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
51947c6ae99SBarry Smith   if (!com->setup) {
520d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
52147c6ae99SBarry Smith   }
52247c6ae99SBarry Smith 
52347c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
524df0c820aSJed Brown   va_start(Argp,imode);
5258fd8f222SJed Brown   for (cnt=3,next=com->next; next; cnt++,next=next->next) {
5269ae5db72SJed Brown     Vec local;
5279ae5db72SJed Brown     local = va_arg(Argp, Vec);
5289ae5db72SJed Brown     if (local) {
52947c6ae99SBarry Smith       PetscScalar *array;
5309ae5db72SJed Brown       Vec         global;
5319ae5db72SJed Brown       PetscValidHeaderSpecific(local,VEC_CLASSID,cnt);
5329ae5db72SJed Brown       ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
5339ae5db72SJed Brown       ierr = VecGetArray(gvec,&array);CHKERRQ(ierr);
5349ae5db72SJed Brown       ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr);
5359ae5db72SJed Brown       ierr = DMLocalToGlobalBegin(next->dm,local,imode,global);CHKERRQ(ierr);
5369ae5db72SJed Brown       ierr = DMLocalToGlobalEnd(next->dm,local,imode,global);CHKERRQ(ierr);
5379ae5db72SJed Brown       ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr);
5389ae5db72SJed Brown       ierr = VecResetArray(global);CHKERRQ(ierr);
5399ae5db72SJed Brown       ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
54047c6ae99SBarry Smith     }
54147c6ae99SBarry Smith   }
54247c6ae99SBarry Smith   va_end(Argp);
54347c6ae99SBarry Smith   PetscFunctionReturn(0);
54447c6ae99SBarry Smith }
54547c6ae99SBarry Smith 
54647c6ae99SBarry Smith #undef __FUNCT__
5476f3c3dcfSJed Brown #define __FUNCT__ "DMCompositeGatherArray"
5486f3c3dcfSJed Brown /*@
5496f3c3dcfSJed Brown     DMCompositeGatherArray - Gathers into a global packed vector from its individual local vectors
5506f3c3dcfSJed Brown 
5516f3c3dcfSJed Brown     Collective on DMComposite
5526f3c3dcfSJed Brown 
5536f3c3dcfSJed Brown     Input Parameter:
5546f3c3dcfSJed Brown +    dm - the packer object
5556f3c3dcfSJed Brown .    gvec - the global vector
556907376e6SBarry Smith .    imode - INSERT_VALUES or ADD_VALUES
5576f3c3dcfSJed Brown -    lvecs - the individual sequential vectors, NULL for any that are not needed
5586f3c3dcfSJed Brown 
5596f3c3dcfSJed Brown     Level: advanced
5606f3c3dcfSJed Brown 
5616f3c3dcfSJed Brown     Notes:
5626f3c3dcfSJed Brown     This is a non-variadic alternative to DMCompositeGather().
5636f3c3dcfSJed Brown 
5646f3c3dcfSJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
5656f3c3dcfSJed Brown          DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
5666f3c3dcfSJed Brown          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries(),
5676f3c3dcfSJed Brown @*/
5686f3c3dcfSJed Brown PetscErrorCode  DMCompositeGatherArray(DM dm,Vec gvec,InsertMode imode,Vec *lvecs)
5696f3c3dcfSJed Brown {
5706f3c3dcfSJed Brown   PetscErrorCode         ierr;
5716f3c3dcfSJed Brown   struct DMCompositeLink *next;
5726f3c3dcfSJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
5736f3c3dcfSJed Brown   PetscInt               i;
5746f3c3dcfSJed Brown 
5756f3c3dcfSJed Brown   PetscFunctionBegin;
5766f3c3dcfSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5776f3c3dcfSJed Brown   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
5786f3c3dcfSJed Brown   if (!com->setup) {
5796f3c3dcfSJed Brown     ierr = DMSetUp(dm);CHKERRQ(ierr);
5806f3c3dcfSJed Brown   }
5816f3c3dcfSJed Brown 
5826f3c3dcfSJed Brown   /* loop over packed objects, handling one at at time */
5836f3c3dcfSJed Brown   for (next=com->next,i=0; next; next=next->next,i++) {
5846f3c3dcfSJed Brown     if (lvecs[i]) {
5856f3c3dcfSJed Brown       PetscScalar *array;
5866f3c3dcfSJed Brown       Vec         global;
5876f3c3dcfSJed Brown       PetscValidHeaderSpecific(lvecs[i],VEC_CLASSID,3);
5886f3c3dcfSJed Brown       ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
5896f3c3dcfSJed Brown       ierr = VecGetArray(gvec,&array);CHKERRQ(ierr);
5906f3c3dcfSJed Brown       ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr);
5916f3c3dcfSJed Brown       ierr = DMLocalToGlobalBegin(next->dm,lvecs[i],imode,global);CHKERRQ(ierr);
5926f3c3dcfSJed Brown       ierr = DMLocalToGlobalEnd(next->dm,lvecs[i],imode,global);CHKERRQ(ierr);
5936f3c3dcfSJed Brown       ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr);
5946f3c3dcfSJed Brown       ierr = VecResetArray(global);CHKERRQ(ierr);
5956f3c3dcfSJed Brown       ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
5966f3c3dcfSJed Brown     }
5976f3c3dcfSJed Brown   }
5986f3c3dcfSJed Brown   PetscFunctionReturn(0);
5996f3c3dcfSJed Brown }
6006f3c3dcfSJed Brown 
6016f3c3dcfSJed Brown #undef __FUNCT__
60247c6ae99SBarry Smith #define __FUNCT__ "DMCompositeAddDM"
60347c6ae99SBarry Smith /*@C
604aa219208SBarry Smith     DMCompositeAddDM - adds a DM  vector to a DMComposite
60547c6ae99SBarry Smith 
60647c6ae99SBarry Smith     Collective on DMComposite
60747c6ae99SBarry Smith 
60847c6ae99SBarry Smith     Input Parameter:
60947c6ae99SBarry Smith +    dm - the packer object
61047c6ae99SBarry Smith -    dm - the DM object, if the DM is a da you will need to caste it with a (DM)
61147c6ae99SBarry Smith 
61247c6ae99SBarry Smith     Level: advanced
61347c6ae99SBarry Smith 
6140c010503SBarry Smith .seealso DMDestroy(), DMCompositeGather(), DMCompositeAddDM(), DMCreateGlobalVector(),
6156eb61c8cSJed Brown          DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
61647c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries()
61747c6ae99SBarry Smith 
61847c6ae99SBarry Smith @*/
6197087cfbeSBarry Smith PetscErrorCode  DMCompositeAddDM(DM dmc,DM dm)
62047c6ae99SBarry Smith {
62147c6ae99SBarry Smith   PetscErrorCode         ierr;
62206ebdd98SJed Brown   PetscInt               n,nlocal;
62347c6ae99SBarry Smith   struct DMCompositeLink *mine,*next;
62406ebdd98SJed Brown   Vec                    global,local;
62547c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dmc->data;
62647c6ae99SBarry Smith 
62747c6ae99SBarry Smith   PetscFunctionBegin;
62847c6ae99SBarry Smith   PetscValidHeaderSpecific(dmc,DM_CLASSID,1);
62947c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,2);
63047c6ae99SBarry Smith   next = com->next;
631ce94432eSBarry Smith   if (com->setup) SETERRQ(PetscObjectComm((PetscObject)dmc),PETSC_ERR_ARG_WRONGSTATE,"Cannot add a DM once you have used the DMComposite");
63247c6ae99SBarry Smith 
63347c6ae99SBarry Smith   /* create new link */
634b00a9115SJed Brown   ierr = PetscNew(&mine);CHKERRQ(ierr);
63547c6ae99SBarry Smith   ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);
63647c6ae99SBarry Smith   ierr = DMGetGlobalVector(dm,&global);CHKERRQ(ierr);
63747c6ae99SBarry Smith   ierr = VecGetLocalSize(global,&n);CHKERRQ(ierr);
63847c6ae99SBarry Smith   ierr = DMRestoreGlobalVector(dm,&global);CHKERRQ(ierr);
63906ebdd98SJed Brown   ierr = DMGetLocalVector(dm,&local);CHKERRQ(ierr);
64006ebdd98SJed Brown   ierr = VecGetSize(local,&nlocal);CHKERRQ(ierr);
64106ebdd98SJed Brown   ierr = DMRestoreLocalVector(dm,&local);CHKERRQ(ierr);
6428865f1eaSKarl Rupp 
64347c6ae99SBarry Smith   mine->n      = n;
64406ebdd98SJed Brown   mine->nlocal = nlocal;
64547c6ae99SBarry Smith   mine->dm     = dm;
6460298fd71SBarry Smith   mine->next   = NULL;
64747c6ae99SBarry Smith   com->n      += n;
64847c6ae99SBarry Smith 
64947c6ae99SBarry Smith   /* add to end of list */
6508865f1eaSKarl Rupp   if (!next) com->next = mine;
6518865f1eaSKarl Rupp   else {
65247c6ae99SBarry Smith     while (next->next) next = next->next;
65347c6ae99SBarry Smith     next->next = mine;
65447c6ae99SBarry Smith   }
65547c6ae99SBarry Smith   com->nDM++;
65647c6ae99SBarry Smith   com->nmine++;
65747c6ae99SBarry Smith   PetscFunctionReturn(0);
65847c6ae99SBarry Smith }
65947c6ae99SBarry Smith 
6609804daf3SBarry Smith #include <petscdraw.h>
66126887b52SJed Brown PETSC_EXTERN PetscErrorCode  VecView_MPI(Vec,PetscViewer);
66247c6ae99SBarry Smith #undef __FUNCT__
66347c6ae99SBarry Smith #define __FUNCT__ "VecView_DMComposite"
6647087cfbeSBarry Smith PetscErrorCode  VecView_DMComposite(Vec gvec,PetscViewer viewer)
66547c6ae99SBarry Smith {
66647c6ae99SBarry Smith   DM                     dm;
66747c6ae99SBarry Smith   PetscErrorCode         ierr;
66847c6ae99SBarry Smith   struct DMCompositeLink *next;
66947c6ae99SBarry Smith   PetscBool              isdraw;
670cef07954SSatish Balay   DM_Composite           *com;
67147c6ae99SBarry Smith 
67247c6ae99SBarry Smith   PetscFunctionBegin;
673c688c046SMatthew G Knepley   ierr = VecGetDM(gvec, &dm);CHKERRQ(ierr);
674ce94432eSBarry Smith   if (!dm) SETERRQ(PetscObjectComm((PetscObject)gvec),PETSC_ERR_ARG_WRONG,"Vector not generated from a DMComposite");
67547c6ae99SBarry Smith   com  = (DM_Composite*)dm->data;
67647c6ae99SBarry Smith   next = com->next;
67747c6ae99SBarry Smith 
678251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
67947c6ae99SBarry Smith   if (!isdraw) {
68047c6ae99SBarry Smith     /* do I really want to call this? */
68147c6ae99SBarry Smith     ierr = VecView_MPI(gvec,viewer);CHKERRQ(ierr);
68247c6ae99SBarry Smith   } else {
68347c6ae99SBarry Smith     PetscInt cnt = 0;
68447c6ae99SBarry Smith 
68547c6ae99SBarry Smith     /* loop over packed objects, handling one at at time */
68647c6ae99SBarry Smith     while (next) {
68747c6ae99SBarry Smith       Vec         vec;
6889ae5db72SJed Brown       PetscScalar *array;
68947c6ae99SBarry Smith       PetscInt    bs;
69047c6ae99SBarry Smith 
6919ae5db72SJed Brown       /* Should use VecGetSubVector() eventually, but would need to forward the DM for that to work */
6929ae5db72SJed Brown       ierr = DMGetGlobalVector(next->dm,&vec);CHKERRQ(ierr);
6939ae5db72SJed Brown       ierr = VecGetArray(gvec,&array);CHKERRQ(ierr);
6949ae5db72SJed Brown       ierr = VecPlaceArray(vec,array+next->rstart);CHKERRQ(ierr);
6959ae5db72SJed Brown       ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr);
69647c6ae99SBarry Smith       ierr = VecView(vec,viewer);CHKERRQ(ierr);
69747c6ae99SBarry Smith       ierr = VecGetBlockSize(vec,&bs);CHKERRQ(ierr);
6989ae5db72SJed Brown       ierr = VecResetArray(vec);CHKERRQ(ierr);
6999ae5db72SJed Brown       ierr = DMRestoreGlobalVector(next->dm,&vec);CHKERRQ(ierr);
70047c6ae99SBarry Smith       ierr = PetscViewerDrawBaseAdd(viewer,bs);CHKERRQ(ierr);
70147c6ae99SBarry Smith       cnt += bs;
70247c6ae99SBarry Smith       next = next->next;
70347c6ae99SBarry Smith     }
70447c6ae99SBarry Smith     ierr = PetscViewerDrawBaseAdd(viewer,-cnt);CHKERRQ(ierr);
70547c6ae99SBarry Smith   }
70647c6ae99SBarry Smith   PetscFunctionReturn(0);
70747c6ae99SBarry Smith }
70847c6ae99SBarry Smith 
70947c6ae99SBarry Smith #undef __FUNCT__
7100c010503SBarry Smith #define __FUNCT__ "DMCreateGlobalVector_Composite"
7117087cfbeSBarry Smith PetscErrorCode  DMCreateGlobalVector_Composite(DM dm,Vec *gvec)
71247c6ae99SBarry Smith {
71347c6ae99SBarry Smith   PetscErrorCode ierr;
71447c6ae99SBarry Smith   DM_Composite   *com = (DM_Composite*)dm->data;
71547c6ae99SBarry Smith 
71647c6ae99SBarry Smith   PetscFunctionBegin;
71747c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
718d7bf68aeSBarry Smith   ierr = DMSetUp(dm);CHKERRQ(ierr);
719ce94432eSBarry Smith   ierr = VecCreateMPI(PetscObjectComm((PetscObject)dm),com->n,com->N,gvec);CHKERRQ(ierr);
720c688c046SMatthew G Knepley   ierr = VecSetDM(*gvec, dm);CHKERRQ(ierr);
72147c6ae99SBarry Smith   ierr = VecSetOperation(*gvec,VECOP_VIEW,(void (*)(void))VecView_DMComposite);CHKERRQ(ierr);
72247c6ae99SBarry Smith   PetscFunctionReturn(0);
72347c6ae99SBarry Smith }
72447c6ae99SBarry Smith 
72547c6ae99SBarry Smith #undef __FUNCT__
7260c010503SBarry Smith #define __FUNCT__ "DMCreateLocalVector_Composite"
7277087cfbeSBarry Smith PetscErrorCode  DMCreateLocalVector_Composite(DM dm,Vec *lvec)
72847c6ae99SBarry Smith {
72947c6ae99SBarry Smith   PetscErrorCode ierr;
73047c6ae99SBarry Smith   DM_Composite   *com = (DM_Composite*)dm->data;
73147c6ae99SBarry Smith 
73247c6ae99SBarry Smith   PetscFunctionBegin;
73347c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
73447c6ae99SBarry Smith   if (!com->setup) {
735d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
73647c6ae99SBarry Smith   }
737ce94432eSBarry Smith   ierr = VecCreateSeq(PetscObjectComm((PetscObject)dm),com->nghost,lvec);CHKERRQ(ierr);
738c688c046SMatthew G Knepley   ierr = VecSetDM(*lvec, dm);CHKERRQ(ierr);
73947c6ae99SBarry Smith   PetscFunctionReturn(0);
74047c6ae99SBarry Smith }
74147c6ae99SBarry Smith 
74247c6ae99SBarry Smith #undef __FUNCT__
7436eb61c8cSJed Brown #define __FUNCT__ "DMCompositeGetISLocalToGlobalMappings"
74447c6ae99SBarry Smith /*@C
7459ae5db72SJed Brown     DMCompositeGetISLocalToGlobalMappings - gets an ISLocalToGlobalMapping for each DM in the DMComposite, maps to the composite global space
74647c6ae99SBarry Smith 
74706ebdd98SJed Brown     Collective on DM
74847c6ae99SBarry Smith 
74947c6ae99SBarry Smith     Input Parameter:
75047c6ae99SBarry Smith .    dm - the packer object
75147c6ae99SBarry Smith 
75247c6ae99SBarry Smith     Output Parameters:
7539ae5db72SJed Brown .    ltogs - the individual mappings for each packed vector. Note that this includes
7549ae5db72SJed Brown            all the ghost points that individual ghosted DMDA's may have.
75547c6ae99SBarry Smith 
75647c6ae99SBarry Smith     Level: advanced
75747c6ae99SBarry Smith 
75847c6ae99SBarry Smith     Notes:
7596eb61c8cSJed Brown        Each entry of ltogs should be destroyed with ISLocalToGlobalMappingDestroy(), the ltogs array should be freed with PetscFree().
76047c6ae99SBarry Smith 
7619ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
76247c6ae99SBarry Smith          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetAccess(), DMCompositeScatter(),
76347c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(),DMCompositeGetEntries()
76447c6ae99SBarry Smith 
76547c6ae99SBarry Smith @*/
7667087cfbeSBarry Smith PetscErrorCode  DMCompositeGetISLocalToGlobalMappings(DM dm,ISLocalToGlobalMapping **ltogs)
76747c6ae99SBarry Smith {
76847c6ae99SBarry Smith   PetscErrorCode         ierr;
76947c6ae99SBarry Smith   PetscInt               i,*idx,n,cnt;
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);
776728e99d6SJed Brown   ierr = DMSetUp(dm);CHKERRQ(ierr);
777854ce69bSBarry Smith   ierr = PetscMalloc1(com->nDM,ltogs);CHKERRQ(ierr);
77847c6ae99SBarry Smith   next = com->next;
779ce94432eSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
78047c6ae99SBarry Smith 
78147c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
78247c6ae99SBarry Smith   cnt = 0;
78347c6ae99SBarry Smith   while (next) {
7846eb61c8cSJed Brown     ISLocalToGlobalMapping ltog;
7856eb61c8cSJed Brown     PetscMPIInt            size;
78686994e45SJed Brown     const PetscInt         *suboff,*indices;
7876eb61c8cSJed Brown     Vec                    global;
78847c6ae99SBarry Smith 
7896eb61c8cSJed Brown     /* Get sub-DM global indices for each local dof */
7901411c6eeSJed Brown     ierr = DMGetLocalToGlobalMapping(next->dm,&ltog);CHKERRQ(ierr);
7916eb61c8cSJed Brown     ierr = ISLocalToGlobalMappingGetSize(ltog,&n);CHKERRQ(ierr);
79286994e45SJed Brown     ierr = ISLocalToGlobalMappingGetIndices(ltog,&indices);CHKERRQ(ierr);
793785e854fSJed Brown     ierr = PetscMalloc1(n,&idx);CHKERRQ(ierr);
79447c6ae99SBarry Smith 
7956eb61c8cSJed Brown     /* Get the offsets for the sub-DM global vector */
7966eb61c8cSJed Brown     ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
7976eb61c8cSJed Brown     ierr = VecGetOwnershipRanges(global,&suboff);CHKERRQ(ierr);
798ce94432eSBarry Smith     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)global),&size);CHKERRQ(ierr);
7996eb61c8cSJed Brown 
8006eb61c8cSJed Brown     /* Shift the sub-DM definition of the global space to the composite global space */
8016eb61c8cSJed Brown     for (i=0; i<n; i++) {
80286994e45SJed Brown       PetscInt subi = indices[i],lo = 0,hi = size,t;
8036eb61c8cSJed Brown       /* Binary search to find which rank owns subi */
8046eb61c8cSJed Brown       while (hi-lo > 1) {
8056eb61c8cSJed Brown         t = lo + (hi-lo)/2;
8066eb61c8cSJed Brown         if (suboff[t] > subi) hi = t;
8076eb61c8cSJed Brown         else                  lo = t;
8086eb61c8cSJed Brown       }
8096eb61c8cSJed Brown       idx[i] = subi - suboff[lo] + next->grstarts[lo];
8106eb61c8cSJed Brown     }
81186994e45SJed Brown     ierr = ISLocalToGlobalMappingRestoreIndices(ltog,&indices);CHKERRQ(ierr);
812f0413b6fSBarry Smith     ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)dm),1,n,idx,PETSC_OWN_POINTER,&(*ltogs)[cnt]);CHKERRQ(ierr);
8136eb61c8cSJed Brown     ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
81447c6ae99SBarry Smith     next = next->next;
81547c6ae99SBarry Smith     cnt++;
81647c6ae99SBarry Smith   }
81747c6ae99SBarry Smith   PetscFunctionReturn(0);
81847c6ae99SBarry Smith }
81947c6ae99SBarry Smith 
82047c6ae99SBarry Smith #undef __FUNCT__
82187c85e80SJed Brown #define __FUNCT__ "DMCompositeGetLocalISs"
82287c85e80SJed Brown /*@C
8239ae5db72SJed Brown    DMCompositeGetLocalISs - Gets index sets for each component of a composite local vector
82487c85e80SJed Brown 
82587c85e80SJed Brown    Not Collective
82687c85e80SJed Brown 
82787c85e80SJed Brown    Input Arguments:
82887c85e80SJed Brown . dm - composite DM
82987c85e80SJed Brown 
83087c85e80SJed Brown    Output Arguments:
83187c85e80SJed Brown . is - array of serial index sets for each each component of the DMComposite
83287c85e80SJed Brown 
83387c85e80SJed Brown    Level: intermediate
83487c85e80SJed Brown 
83587c85e80SJed Brown    Notes:
83687c85e80SJed Brown    At present, a composite local vector does not normally exist.  This function is used to provide index sets for
83787c85e80SJed Brown    MatGetLocalSubMatrix().  In the future, the scatters for each entry in the DMComposite may be be merged into a single
8389ae5db72SJed Brown    scatter to a composite local vector.  The user should not typically need to know which is being done.
83987c85e80SJed Brown 
84087c85e80SJed Brown    To get the composite global indices at all local points (including ghosts), use DMCompositeGetISLocalToGlobalMappings().
84187c85e80SJed Brown 
84287c85e80SJed Brown    To get index sets for pieces of the composite global vector, use DMCompositeGetGlobalISs().
84387c85e80SJed Brown 
84487c85e80SJed Brown    Each returned IS should be destroyed with ISDestroy(), the array should be freed with PetscFree().
84587c85e80SJed Brown 
84687c85e80SJed Brown .seealso: DMCompositeGetGlobalISs(), DMCompositeGetISLocalToGlobalMappings(), MatGetLocalSubMatrix(), MatCreateLocalRef()
84787c85e80SJed Brown @*/
8487087cfbeSBarry Smith PetscErrorCode  DMCompositeGetLocalISs(DM dm,IS **is)
84987c85e80SJed Brown {
85087c85e80SJed Brown   PetscErrorCode         ierr;
85187c85e80SJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
85287c85e80SJed Brown   struct DMCompositeLink *link;
85387c85e80SJed Brown   PetscInt               cnt,start;
85487c85e80SJed Brown 
85587c85e80SJed Brown   PetscFunctionBegin;
85687c85e80SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
85787c85e80SJed Brown   PetscValidPointer(is,2);
858785e854fSJed Brown   ierr = PetscMalloc1(com->nmine,is);CHKERRQ(ierr);
85906ebdd98SJed Brown   for (cnt=0,start=0,link=com->next; link; start+=link->nlocal,cnt++,link=link->next) {
860520db06cSJed Brown     PetscInt bs;
8619ae5db72SJed Brown     ierr = ISCreateStride(PETSC_COMM_SELF,link->nlocal,start,1,&(*is)[cnt]);CHKERRQ(ierr);
8621411c6eeSJed Brown     ierr = DMGetBlockSize(link->dm,&bs);CHKERRQ(ierr);
863520db06cSJed Brown     ierr = ISSetBlockSize((*is)[cnt],bs);CHKERRQ(ierr);
864520db06cSJed Brown   }
86587c85e80SJed Brown   PetscFunctionReturn(0);
86687c85e80SJed Brown }
86787c85e80SJed Brown 
86887c85e80SJed Brown #undef __FUNCT__
86947c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetGlobalISs"
87047c6ae99SBarry Smith /*@C
87147c6ae99SBarry Smith     DMCompositeGetGlobalISs - Gets the index sets for each composed object
87247c6ae99SBarry Smith 
87347c6ae99SBarry Smith     Collective on DMComposite
87447c6ae99SBarry Smith 
87547c6ae99SBarry Smith     Input Parameter:
87647c6ae99SBarry Smith .    dm - the packer object
87747c6ae99SBarry Smith 
87847c6ae99SBarry Smith     Output Parameters:
87947c6ae99SBarry Smith .    is - the array of index sets
88047c6ae99SBarry Smith 
88147c6ae99SBarry Smith     Level: advanced
88247c6ae99SBarry Smith 
88347c6ae99SBarry Smith     Notes:
88447c6ae99SBarry Smith        The is entries should be destroyed with ISDestroy(), the is array should be freed with PetscFree()
88547c6ae99SBarry Smith 
88647c6ae99SBarry Smith        These could be used to extract a subset of vector entries for a "multi-physics" preconditioner
88747c6ae99SBarry Smith 
8886eb61c8cSJed Brown        Use DMCompositeGetLocalISs() for index sets in the packed local numbering, and
8896eb61c8cSJed Brown        DMCompositeGetISLocalToGlobalMappings() for to map local sub-DM (including ghost) indices to packed global
8906eb61c8cSJed Brown        indices.
89147c6ae99SBarry Smith 
8929ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
89347c6ae99SBarry Smith          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetAccess(), DMCompositeScatter(),
89447c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(),DMCompositeGetEntries()
89547c6ae99SBarry Smith 
89647c6ae99SBarry Smith @*/
8976eb61c8cSJed Brown 
8987087cfbeSBarry Smith PetscErrorCode  DMCompositeGetGlobalISs(DM dm,IS *is[])
89947c6ae99SBarry Smith {
90047c6ae99SBarry Smith   PetscErrorCode         ierr;
90166bb578eSMark Adams   PetscInt               cnt = 0;
90247c6ae99SBarry Smith   struct DMCompositeLink *next;
90347c6ae99SBarry Smith   PetscMPIInt            rank;
90447c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
90547c6ae99SBarry Smith 
90647c6ae99SBarry Smith   PetscFunctionBegin;
90747c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
908854ce69bSBarry Smith   ierr = PetscMalloc1(com->nDM,is);CHKERRQ(ierr);
90947c6ae99SBarry Smith   next = com->next;
910ce94432eSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
91147c6ae99SBarry Smith 
91247c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
91347c6ae99SBarry Smith   while (next) {
91466bb578eSMark Adams     ierr = ISCreateStride(PetscObjectComm((PetscObject)dm),next->n,next->grstart,1,&(*is)[cnt]);CHKERRQ(ierr);
9150f21e855SMatthew G. Knepley     if (dm->prob) {
91665c226d8SMatthew G. Knepley       MatNullSpace space;
91765c226d8SMatthew G. Knepley       Mat          pmat;
9180f21e855SMatthew G. Knepley       PetscObject  disc;
9190f21e855SMatthew G. Knepley       PetscInt     Nf;
92065c226d8SMatthew G. Knepley 
9212764a2aaSMatthew G. Knepley       ierr = PetscDSGetNumFields(dm->prob, &Nf);CHKERRQ(ierr);
922f24dd8d2SMatthew G. Knepley       if (cnt < Nf) {
9232764a2aaSMatthew G. Knepley         ierr = PetscDSGetDiscretization(dm->prob, cnt, &disc);CHKERRQ(ierr);
9240f21e855SMatthew G. Knepley         ierr = PetscObjectQuery(disc, "nullspace", (PetscObject*) &space);CHKERRQ(ierr);
925aac2dd2dSMatthew G. Knepley         if (space) {ierr = PetscObjectCompose((PetscObject) (*is)[cnt], "nullspace", (PetscObject) space);CHKERRQ(ierr);}
9260f21e855SMatthew G. Knepley         ierr = PetscObjectQuery(disc, "nearnullspace", (PetscObject*) &space);CHKERRQ(ierr);
927aac2dd2dSMatthew G. Knepley         if (space) {ierr = PetscObjectCompose((PetscObject) (*is)[cnt], "nearnullspace", (PetscObject) space);CHKERRQ(ierr);}
9280f21e855SMatthew G. Knepley         ierr = PetscObjectQuery(disc, "pmat", (PetscObject*) &pmat);CHKERRQ(ierr);
929aac2dd2dSMatthew G. Knepley         if (pmat) {ierr = PetscObjectCompose((PetscObject) (*is)[cnt], "pmat", (PetscObject) pmat);CHKERRQ(ierr);}
93065c226d8SMatthew G. Knepley       }
931f24dd8d2SMatthew G. Knepley     }
93247c6ae99SBarry Smith     cnt++;
93347c6ae99SBarry Smith     next = next->next;
93447c6ae99SBarry Smith   }
93547c6ae99SBarry Smith   PetscFunctionReturn(0);
93647c6ae99SBarry Smith }
93747c6ae99SBarry Smith 
9384d343eeaSMatthew G Knepley #undef __FUNCT__
9394d343eeaSMatthew G Knepley #define __FUNCT__ "DMCreateFieldIS_Composite"
94021c9b008SJed Brown PetscErrorCode DMCreateFieldIS_Composite(DM dm, PetscInt *numFields,char ***fieldNames, IS **fields)
9414d343eeaSMatthew G Knepley {
9424d343eeaSMatthew G Knepley   PetscInt       nDM;
9434d343eeaSMatthew G Knepley   DM             *dms;
9444d343eeaSMatthew G Knepley   PetscInt       i;
9454d343eeaSMatthew G Knepley   PetscErrorCode ierr;
9464d343eeaSMatthew G Knepley 
9474d343eeaSMatthew G Knepley   PetscFunctionBegin;
9484d343eeaSMatthew G Knepley   ierr = DMCompositeGetNumberDM(dm, &nDM);CHKERRQ(ierr);
9498865f1eaSKarl Rupp   if (numFields) *numFields = nDM;
9504d343eeaSMatthew G Knepley   ierr = DMCompositeGetGlobalISs(dm, fields);CHKERRQ(ierr);
9514d343eeaSMatthew G Knepley   if (fieldNames) {
952785e854fSJed Brown     ierr = PetscMalloc1(nDM, &dms);CHKERRQ(ierr);
953785e854fSJed Brown     ierr = PetscMalloc1(nDM, fieldNames);CHKERRQ(ierr);
9544d343eeaSMatthew G Knepley     ierr = DMCompositeGetEntriesArray(dm, dms);CHKERRQ(ierr);
9554d343eeaSMatthew G Knepley     for (i=0; i<nDM; i++) {
9564d343eeaSMatthew G Knepley       char       buf[256];
9574d343eeaSMatthew G Knepley       const char *splitname;
9584d343eeaSMatthew G Knepley 
9594d343eeaSMatthew G Knepley       /* Split naming precedence: object name, prefix, number */
9604d343eeaSMatthew G Knepley       splitname = ((PetscObject) dm)->name;
9614d343eeaSMatthew G Knepley       if (!splitname) {
9624d343eeaSMatthew G Knepley         ierr = PetscObjectGetOptionsPrefix((PetscObject)dms[i],&splitname);CHKERRQ(ierr);
9634d343eeaSMatthew G Knepley         if (splitname) {
9644d343eeaSMatthew G Knepley           size_t len;
9658caf3d72SBarry Smith           ierr                 = PetscStrncpy(buf,splitname,sizeof(buf));CHKERRQ(ierr);
9668caf3d72SBarry Smith           buf[sizeof(buf) - 1] = 0;
9674d343eeaSMatthew G Knepley           ierr                 = PetscStrlen(buf,&len);CHKERRQ(ierr);
9684d343eeaSMatthew G Knepley           if (buf[len-1] == '_') buf[len-1] = 0; /* Remove trailing underscore if it was used */
9694d343eeaSMatthew G Knepley           splitname = buf;
9704d343eeaSMatthew G Knepley         }
9714d343eeaSMatthew G Knepley       }
9724d343eeaSMatthew G Knepley       if (!splitname) {
9738caf3d72SBarry Smith         ierr      = PetscSNPrintf(buf,sizeof(buf),"%D",i);CHKERRQ(ierr);
9744d343eeaSMatthew G Knepley         splitname = buf;
9754d343eeaSMatthew G Knepley       }
97621c9b008SJed Brown       ierr = PetscStrallocpy(splitname,&(*fieldNames)[i]);CHKERRQ(ierr);
9774d343eeaSMatthew G Knepley     }
9784d343eeaSMatthew G Knepley     ierr = PetscFree(dms);CHKERRQ(ierr);
9794d343eeaSMatthew G Knepley   }
9804d343eeaSMatthew G Knepley   PetscFunctionReturn(0);
9814d343eeaSMatthew G Knepley }
9824d343eeaSMatthew G Knepley 
983e7c4fc90SDmitry Karpeev /*
984e7c4fc90SDmitry Karpeev  This could take over from DMCreateFieldIS(), as it is more general,
9850298fd71SBarry Smith  making DMCreateFieldIS() a special case -- calling with dmlist == NULL;
986e7c4fc90SDmitry Karpeev  At this point it's probably best to be less intrusive, however.
987e7c4fc90SDmitry Karpeev  */
988e7c4fc90SDmitry Karpeev #undef __FUNCT__
98916621825SDmitry Karpeev #define __FUNCT__ "DMCreateFieldDecomposition_Composite"
99016621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecomposition_Composite(DM dm, PetscInt *len,char ***namelist, IS **islist, DM **dmlist)
991e7c4fc90SDmitry Karpeev {
992e7c4fc90SDmitry Karpeev   PetscInt       nDM;
993e7c4fc90SDmitry Karpeev   PetscInt       i;
994e7c4fc90SDmitry Karpeev   PetscErrorCode ierr;
995e7c4fc90SDmitry Karpeev 
996e7c4fc90SDmitry Karpeev   PetscFunctionBegin;
997e7c4fc90SDmitry Karpeev   ierr = DMCreateFieldIS_Composite(dm, len, namelist, islist);CHKERRQ(ierr);
998e7c4fc90SDmitry Karpeev   if (dmlist) {
999e7c4fc90SDmitry Karpeev     ierr = DMCompositeGetNumberDM(dm, &nDM);CHKERRQ(ierr);
1000785e854fSJed Brown     ierr = PetscMalloc1(nDM, dmlist);CHKERRQ(ierr);
1001e7c4fc90SDmitry Karpeev     ierr = DMCompositeGetEntriesArray(dm, *dmlist);CHKERRQ(ierr);
1002e7c4fc90SDmitry Karpeev     for (i=0; i<nDM; i++) {
1003e7c4fc90SDmitry Karpeev       ierr = PetscObjectReference((PetscObject)((*dmlist)[i]));CHKERRQ(ierr);
1004e7c4fc90SDmitry Karpeev     }
1005e7c4fc90SDmitry Karpeev   }
1006e7c4fc90SDmitry Karpeev   PetscFunctionReturn(0);
1007e7c4fc90SDmitry Karpeev }
1008e7c4fc90SDmitry Karpeev 
1009e7c4fc90SDmitry Karpeev 
1010e7c4fc90SDmitry Karpeev 
101147c6ae99SBarry Smith /* -------------------------------------------------------------------------------------*/
101247c6ae99SBarry Smith #undef __FUNCT__
101347c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetLocalVectors"
101447c6ae99SBarry Smith /*@C
10159ae5db72SJed Brown     DMCompositeGetLocalVectors - Gets local vectors for each part of a DMComposite.
101647c6ae99SBarry Smith        Use DMCompositeRestoreLocalVectors() to return them.
101747c6ae99SBarry Smith 
101847c6ae99SBarry Smith     Not Collective
101947c6ae99SBarry Smith 
102047c6ae99SBarry Smith     Input Parameter:
102147c6ae99SBarry Smith .    dm - the packer object
102247c6ae99SBarry Smith 
102347c6ae99SBarry Smith     Output Parameter:
10249ae5db72SJed Brown .   Vec ... - the individual sequential Vecs
102547c6ae99SBarry Smith 
102647c6ae99SBarry Smith     Level: advanced
102747c6ae99SBarry Smith 
10289ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
10296eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
103047c6ae99SBarry Smith          DMCompositeRestoreLocalVectors(), DMCompositeScatter(), DMCompositeGetEntries()
103147c6ae99SBarry Smith 
103247c6ae99SBarry Smith @*/
10337087cfbeSBarry Smith PetscErrorCode  DMCompositeGetLocalVectors(DM dm,...)
103447c6ae99SBarry Smith {
103547c6ae99SBarry Smith   va_list                Argp;
103647c6ae99SBarry Smith   PetscErrorCode         ierr;
103747c6ae99SBarry Smith   struct DMCompositeLink *next;
103847c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
103947c6ae99SBarry Smith 
104047c6ae99SBarry Smith   PetscFunctionBegin;
104147c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
104247c6ae99SBarry Smith   next = com->next;
104347c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
104447c6ae99SBarry Smith   va_start(Argp,dm);
104547c6ae99SBarry Smith   while (next) {
104647c6ae99SBarry Smith     Vec *vec;
104747c6ae99SBarry Smith     vec = va_arg(Argp, Vec*);
104806930112SJed Brown     if (vec) {ierr = DMGetLocalVector(next->dm,vec);CHKERRQ(ierr);}
104947c6ae99SBarry Smith     next = next->next;
105047c6ae99SBarry Smith   }
105147c6ae99SBarry Smith   va_end(Argp);
105247c6ae99SBarry Smith   PetscFunctionReturn(0);
105347c6ae99SBarry Smith }
105447c6ae99SBarry Smith 
105547c6ae99SBarry Smith #undef __FUNCT__
105647c6ae99SBarry Smith #define __FUNCT__ "DMCompositeRestoreLocalVectors"
105747c6ae99SBarry Smith /*@C
10589ae5db72SJed Brown     DMCompositeRestoreLocalVectors - Restores local vectors for each part of a DMComposite.
105947c6ae99SBarry Smith 
106047c6ae99SBarry Smith     Not Collective
106147c6ae99SBarry Smith 
106247c6ae99SBarry Smith     Input Parameter:
106347c6ae99SBarry Smith .    dm - the packer object
106447c6ae99SBarry Smith 
106547c6ae99SBarry Smith     Output Parameter:
10669ae5db72SJed Brown .   Vec ... - the individual sequential Vecs
106747c6ae99SBarry Smith 
106847c6ae99SBarry Smith     Level: advanced
106947c6ae99SBarry Smith 
10709ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
10716eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
107247c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeScatter(), DMCompositeGetEntries()
107347c6ae99SBarry Smith 
107447c6ae99SBarry Smith @*/
10757087cfbeSBarry Smith PetscErrorCode  DMCompositeRestoreLocalVectors(DM dm,...)
107647c6ae99SBarry Smith {
107747c6ae99SBarry Smith   va_list                Argp;
107847c6ae99SBarry Smith   PetscErrorCode         ierr;
107947c6ae99SBarry Smith   struct DMCompositeLink *next;
108047c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
108147c6ae99SBarry Smith 
108247c6ae99SBarry Smith   PetscFunctionBegin;
108347c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
108447c6ae99SBarry Smith   next = com->next;
108547c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
108647c6ae99SBarry Smith   va_start(Argp,dm);
108747c6ae99SBarry Smith   while (next) {
108847c6ae99SBarry Smith     Vec *vec;
108947c6ae99SBarry Smith     vec = va_arg(Argp, Vec*);
109006930112SJed Brown     if (vec) {ierr = DMRestoreLocalVector(next->dm,vec);CHKERRQ(ierr);}
109147c6ae99SBarry Smith     next = next->next;
109247c6ae99SBarry Smith   }
109347c6ae99SBarry Smith   va_end(Argp);
109447c6ae99SBarry Smith   PetscFunctionReturn(0);
109547c6ae99SBarry Smith }
109647c6ae99SBarry Smith 
109747c6ae99SBarry Smith /* -------------------------------------------------------------------------------------*/
109847c6ae99SBarry Smith #undef __FUNCT__
109947c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetEntries"
110047c6ae99SBarry Smith /*@C
11019ae5db72SJed Brown     DMCompositeGetEntries - Gets the DM for each entry in a DMComposite.
110247c6ae99SBarry Smith 
110347c6ae99SBarry Smith     Not Collective
110447c6ae99SBarry Smith 
110547c6ae99SBarry Smith     Input Parameter:
110647c6ae99SBarry Smith .    dm - the packer object
110747c6ae99SBarry Smith 
110847c6ae99SBarry Smith     Output Parameter:
11099ae5db72SJed Brown .   DM ... - the individual entries (DMs)
111047c6ae99SBarry Smith 
111147c6ae99SBarry Smith     Level: advanced
111247c6ae99SBarry Smith 
11132fa5ba8aSJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), DMCompositeGetEntriesArray()
11146eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
111547c6ae99SBarry Smith          DMCompositeRestoreLocalVectors(), DMCompositeGetLocalVectors(),  DMCompositeScatter(),
111647c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors()
111747c6ae99SBarry Smith 
111847c6ae99SBarry Smith @*/
11197087cfbeSBarry Smith PetscErrorCode  DMCompositeGetEntries(DM dm,...)
112047c6ae99SBarry Smith {
112147c6ae99SBarry Smith   va_list                Argp;
112247c6ae99SBarry Smith   struct DMCompositeLink *next;
112347c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
112447c6ae99SBarry Smith 
112547c6ae99SBarry Smith   PetscFunctionBegin;
112647c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
112747c6ae99SBarry Smith   next = com->next;
112847c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
112947c6ae99SBarry Smith   va_start(Argp,dm);
113047c6ae99SBarry Smith   while (next) {
113147c6ae99SBarry Smith     DM *dmn;
113247c6ae99SBarry Smith     dmn = va_arg(Argp, DM*);
11339ae5db72SJed Brown     if (dmn) *dmn = next->dm;
113447c6ae99SBarry Smith     next = next->next;
113547c6ae99SBarry Smith   }
113647c6ae99SBarry Smith   va_end(Argp);
113747c6ae99SBarry Smith   PetscFunctionReturn(0);
113847c6ae99SBarry Smith }
113947c6ae99SBarry Smith 
114047c6ae99SBarry Smith #undef __FUNCT__
11412fa5ba8aSJed Brown #define __FUNCT__ "DMCompositeGetEntriesArray"
1142dbab29e1SMark F. Adams /*@C
11432fa5ba8aSJed Brown     DMCompositeGetEntriesArray - Gets the DM for each entry in a DMComposite.
11442fa5ba8aSJed Brown 
11452fa5ba8aSJed Brown     Not Collective
11462fa5ba8aSJed Brown 
11472fa5ba8aSJed Brown     Input Parameter:
1148907376e6SBarry Smith .    dm - the packer object
1149907376e6SBarry Smith 
1150907376e6SBarry Smith     Output Parameter:
1151907376e6SBarry Smith .    dms - array of sufficient length (see DMCompositeGetNumberDM()) to hold the individual DMs
11522fa5ba8aSJed Brown 
11532fa5ba8aSJed Brown     Level: advanced
11542fa5ba8aSJed Brown 
11552fa5ba8aSJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), DMCompositeGetEntries()
11562fa5ba8aSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
11572fa5ba8aSJed Brown          DMCompositeRestoreLocalVectors(), DMCompositeGetLocalVectors(),  DMCompositeScatter(),
11582fa5ba8aSJed Brown          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors()
11592fa5ba8aSJed Brown 
11602fa5ba8aSJed Brown @*/
11612fa5ba8aSJed Brown PetscErrorCode DMCompositeGetEntriesArray(DM dm,DM dms[])
11622fa5ba8aSJed Brown {
11632fa5ba8aSJed Brown   struct DMCompositeLink *next;
11642fa5ba8aSJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
11652fa5ba8aSJed Brown   PetscInt               i;
11662fa5ba8aSJed Brown 
11672fa5ba8aSJed Brown   PetscFunctionBegin;
11682fa5ba8aSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
11692fa5ba8aSJed Brown   /* loop over packed objects, handling one at at time */
11702fa5ba8aSJed Brown   for (next=com->next,i=0; next; next=next->next,i++) dms[i] = next->dm;
11712fa5ba8aSJed Brown   PetscFunctionReturn(0);
11722fa5ba8aSJed Brown }
11732fa5ba8aSJed Brown 
11742fa5ba8aSJed Brown #undef __FUNCT__
11750c010503SBarry Smith #define __FUNCT__ "DMRefine_Composite"
11767087cfbeSBarry Smith PetscErrorCode  DMRefine_Composite(DM dmi,MPI_Comm comm,DM *fine)
117747c6ae99SBarry Smith {
117847c6ae99SBarry Smith   PetscErrorCode         ierr;
117947c6ae99SBarry Smith   struct DMCompositeLink *next;
118047c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dmi->data;
118147c6ae99SBarry Smith   DM                     dm;
118247c6ae99SBarry Smith 
118347c6ae99SBarry Smith   PetscFunctionBegin;
118447c6ae99SBarry Smith   PetscValidHeaderSpecific(dmi,DM_CLASSID,1);
1185ce94432eSBarry Smith   if (comm == MPI_COMM_NULL) {
1186ce94432eSBarry Smith     ierr = PetscObjectGetComm((PetscObject)dmi,&comm);CHKERRQ(ierr);
1187ce94432eSBarry Smith   }
11882ce3a92bSJed Brown   ierr = DMSetUp(dmi);CHKERRQ(ierr);
118947c6ae99SBarry Smith   next = com->next;
119047c6ae99SBarry Smith   ierr = DMCompositeCreate(comm,fine);CHKERRQ(ierr);
119147c6ae99SBarry Smith 
119247c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
119347c6ae99SBarry Smith   while (next) {
119447c6ae99SBarry Smith     ierr = DMRefine(next->dm,comm,&dm);CHKERRQ(ierr);
119547c6ae99SBarry Smith     ierr = DMCompositeAddDM(*fine,dm);CHKERRQ(ierr);
119647c6ae99SBarry Smith     ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr);
119747c6ae99SBarry Smith     next = next->next;
119847c6ae99SBarry Smith   }
119947c6ae99SBarry Smith   PetscFunctionReturn(0);
120047c6ae99SBarry Smith }
120147c6ae99SBarry Smith 
120214354c39SJed Brown #undef __FUNCT__
120314354c39SJed Brown #define __FUNCT__ "DMCoarsen_Composite"
120414354c39SJed Brown PetscErrorCode  DMCoarsen_Composite(DM dmi,MPI_Comm comm,DM *fine)
120514354c39SJed Brown {
120614354c39SJed Brown   PetscErrorCode         ierr;
120714354c39SJed Brown   struct DMCompositeLink *next;
120814354c39SJed Brown   DM_Composite           *com = (DM_Composite*)dmi->data;
120914354c39SJed Brown   DM                     dm;
121014354c39SJed Brown 
121114354c39SJed Brown   PetscFunctionBegin;
121214354c39SJed Brown   PetscValidHeaderSpecific(dmi,DM_CLASSID,1);
12132ce3a92bSJed Brown   ierr = DMSetUp(dmi);CHKERRQ(ierr);
12142ee06e3bSJed Brown   if (comm == MPI_COMM_NULL) {
121525296bd5SBarry Smith     ierr = PetscObjectGetComm((PetscObject)dmi,&comm);CHKERRQ(ierr);
121625296bd5SBarry Smith   }
121714354c39SJed Brown   next = com->next;
121814354c39SJed Brown   ierr = DMCompositeCreate(comm,fine);CHKERRQ(ierr);
121914354c39SJed Brown 
122014354c39SJed Brown   /* loop over packed objects, handling one at at time */
122114354c39SJed Brown   while (next) {
122214354c39SJed Brown     ierr = DMCoarsen(next->dm,comm,&dm);CHKERRQ(ierr);
122314354c39SJed Brown     ierr = DMCompositeAddDM(*fine,dm);CHKERRQ(ierr);
122414354c39SJed Brown     ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr);
122514354c39SJed Brown     next = next->next;
122614354c39SJed Brown   }
122714354c39SJed Brown   PetscFunctionReturn(0);
122814354c39SJed Brown }
122947c6ae99SBarry Smith 
123047c6ae99SBarry Smith #undef __FUNCT__
1231e727c939SJed Brown #define __FUNCT__ "DMCreateInterpolation_Composite"
1232e727c939SJed Brown PetscErrorCode  DMCreateInterpolation_Composite(DM coarse,DM fine,Mat *A,Vec *v)
123347c6ae99SBarry Smith {
123447c6ae99SBarry Smith   PetscErrorCode         ierr;
12359ae5db72SJed Brown   PetscInt               m,n,M,N,nDM,i;
123647c6ae99SBarry Smith   struct DMCompositeLink *nextc;
123747c6ae99SBarry Smith   struct DMCompositeLink *nextf;
123825296bd5SBarry Smith   Vec                    gcoarse,gfine,*vecs;
123947c6ae99SBarry Smith   DM_Composite           *comcoarse = (DM_Composite*)coarse->data;
124047c6ae99SBarry Smith   DM_Composite           *comfine   = (DM_Composite*)fine->data;
12419ae5db72SJed Brown   Mat                    *mats;
124247c6ae99SBarry Smith 
124347c6ae99SBarry Smith   PetscFunctionBegin;
124447c6ae99SBarry Smith   PetscValidHeaderSpecific(coarse,DM_CLASSID,1);
124547c6ae99SBarry Smith   PetscValidHeaderSpecific(fine,DM_CLASSID,2);
1246f692024eSJed Brown   ierr = DMSetUp(coarse);CHKERRQ(ierr);
1247f692024eSJed Brown   ierr = DMSetUp(fine);CHKERRQ(ierr);
124847c6ae99SBarry Smith   /* use global vectors only for determining matrix layout */
12499ae5db72SJed Brown   ierr = DMGetGlobalVector(coarse,&gcoarse);CHKERRQ(ierr);
12509ae5db72SJed Brown   ierr = DMGetGlobalVector(fine,&gfine);CHKERRQ(ierr);
125147c6ae99SBarry Smith   ierr = VecGetLocalSize(gcoarse,&n);CHKERRQ(ierr);
125247c6ae99SBarry Smith   ierr = VecGetLocalSize(gfine,&m);CHKERRQ(ierr);
125347c6ae99SBarry Smith   ierr = VecGetSize(gcoarse,&N);CHKERRQ(ierr);
125447c6ae99SBarry Smith   ierr = VecGetSize(gfine,&M);CHKERRQ(ierr);
12559ae5db72SJed Brown   ierr = DMRestoreGlobalVector(coarse,&gcoarse);CHKERRQ(ierr);
12569ae5db72SJed Brown   ierr = DMRestoreGlobalVector(fine,&gfine);CHKERRQ(ierr);
125747c6ae99SBarry Smith 
12589ae5db72SJed Brown   nDM = comfine->nDM;
1259ce94432eSBarry 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);
12601795a4d1SJed Brown   ierr = PetscCalloc1(nDM*nDM,&mats);CHKERRQ(ierr);
126125296bd5SBarry Smith   if (v) {
12621795a4d1SJed Brown     ierr = PetscCalloc1(nDM,&vecs);CHKERRQ(ierr);
126325296bd5SBarry Smith   }
126447c6ae99SBarry Smith 
126547c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
12669ae5db72SJed Brown   for (nextc=comcoarse->next,nextf=comfine->next,i=0; nextc; nextc=nextc->next,nextf=nextf->next,i++) {
126725296bd5SBarry Smith     if (!v) {
12680298fd71SBarry Smith       ierr = DMCreateInterpolation(nextc->dm,nextf->dm,&mats[i*nDM+i],NULL);CHKERRQ(ierr);
126925296bd5SBarry Smith     } else {
127025296bd5SBarry Smith       ierr = DMCreateInterpolation(nextc->dm,nextf->dm,&mats[i*nDM+i],&vecs[i]);CHKERRQ(ierr);
127125296bd5SBarry Smith     }
127247c6ae99SBarry Smith   }
1273ce94432eSBarry Smith   ierr = MatCreateNest(PetscObjectComm((PetscObject)fine),nDM,NULL,nDM,NULL,mats,A);CHKERRQ(ierr);
127425296bd5SBarry Smith   if (v) {
1275ce94432eSBarry Smith     ierr = VecCreateNest(PetscObjectComm((PetscObject)fine),nDM,NULL,vecs,v);CHKERRQ(ierr);
127625296bd5SBarry Smith   }
12779ae5db72SJed Brown   for (i=0; i<nDM*nDM; i++) {ierr = MatDestroy(&mats[i]);CHKERRQ(ierr);}
12789ae5db72SJed Brown   ierr = PetscFree(mats);CHKERRQ(ierr);
127925296bd5SBarry Smith   if (v) {
128025296bd5SBarry Smith     for (i=0; i<nDM; i++) {ierr = VecDestroy(&vecs[i]);CHKERRQ(ierr);}
128125296bd5SBarry Smith     ierr = PetscFree(vecs);CHKERRQ(ierr);
128225296bd5SBarry Smith   }
128347c6ae99SBarry Smith   PetscFunctionReturn(0);
128447c6ae99SBarry Smith }
128547c6ae99SBarry Smith 
128647c6ae99SBarry Smith #undef __FUNCT__
1287184d77edSJed Brown #define __FUNCT__ "DMGetLocalToGlobalMapping_Composite"
1288184d77edSJed Brown static PetscErrorCode DMGetLocalToGlobalMapping_Composite(DM dm)
12891411c6eeSJed Brown {
12901411c6eeSJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
12911411c6eeSJed Brown   ISLocalToGlobalMapping *ltogs;
1292f7efa3c7SJed Brown   PetscInt               i;
12931411c6eeSJed Brown   PetscErrorCode         ierr;
12941411c6eeSJed Brown 
12951411c6eeSJed Brown   PetscFunctionBegin;
12961411c6eeSJed Brown   /* Set the ISLocalToGlobalMapping on the new matrix */
12971411c6eeSJed Brown   ierr = DMCompositeGetISLocalToGlobalMappings(dm,&ltogs);CHKERRQ(ierr);
1298ce94432eSBarry Smith   ierr = ISLocalToGlobalMappingConcatenate(PetscObjectComm((PetscObject)dm),com->nDM,ltogs,&dm->ltogmap);CHKERRQ(ierr);
12999ae5db72SJed Brown   for (i=0; i<com->nDM; i++) {ierr = ISLocalToGlobalMappingDestroy(&ltogs[i]);CHKERRQ(ierr);}
13001411c6eeSJed Brown   ierr = PetscFree(ltogs);CHKERRQ(ierr);
13011411c6eeSJed Brown   PetscFunctionReturn(0);
13021411c6eeSJed Brown }
13031411c6eeSJed Brown 
13041411c6eeSJed Brown 
13051411c6eeSJed Brown #undef __FUNCT__
1306e727c939SJed Brown #define __FUNCT__ "DMCreateColoring_Composite"
1307b412c318SBarry Smith PetscErrorCode  DMCreateColoring_Composite(DM dm,ISColoringType ctype,ISColoring *coloring)
130847c6ae99SBarry Smith {
130947c6ae99SBarry Smith   PetscErrorCode  ierr;
131047c6ae99SBarry Smith   PetscInt        n,i,cnt;
131147c6ae99SBarry Smith   ISColoringValue *colors;
131247c6ae99SBarry Smith   PetscBool       dense  = PETSC_FALSE;
131347c6ae99SBarry Smith   ISColoringValue maxcol = 0;
131447c6ae99SBarry Smith   DM_Composite    *com   = (DM_Composite*)dm->data;
131547c6ae99SBarry Smith 
131647c6ae99SBarry Smith   PetscFunctionBegin;
131747c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1318ce94432eSBarry Smith   if (ctype == IS_COLORING_GHOSTED) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only global coloring supported");
1319e3247f34SBarry Smith   else if (ctype == IS_COLORING_GLOBAL) {
132047c6ae99SBarry Smith     n = com->n;
1321ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"Unknown ISColoringType");
1322785e854fSJed Brown   ierr = PetscMalloc1(n,&colors);CHKERRQ(ierr); /* freed in ISColoringDestroy() */
132347c6ae99SBarry Smith 
13240298fd71SBarry Smith   ierr = PetscOptionsGetBool(NULL,"-dmcomposite_dense_jacobian",&dense,NULL);CHKERRQ(ierr);
132547c6ae99SBarry Smith   if (dense) {
132647c6ae99SBarry Smith     for (i=0; i<n; i++) {
132747c6ae99SBarry Smith       colors[i] = (ISColoringValue)(com->rstart + i);
132847c6ae99SBarry Smith     }
132947c6ae99SBarry Smith     maxcol = com->N;
133047c6ae99SBarry Smith   } else {
133147c6ae99SBarry Smith     struct DMCompositeLink *next = com->next;
133247c6ae99SBarry Smith     PetscMPIInt            rank;
133347c6ae99SBarry Smith 
1334ce94432eSBarry Smith     ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
133547c6ae99SBarry Smith     cnt  = 0;
133647c6ae99SBarry Smith     while (next) {
133747c6ae99SBarry Smith       ISColoring lcoloring;
133847c6ae99SBarry Smith 
1339b412c318SBarry Smith       ierr = DMCreateColoring(next->dm,IS_COLORING_GLOBAL,&lcoloring);CHKERRQ(ierr);
134047c6ae99SBarry Smith       for (i=0; i<lcoloring->N; i++) {
134147c6ae99SBarry Smith         colors[cnt++] = maxcol + lcoloring->colors[i];
134247c6ae99SBarry Smith       }
134347c6ae99SBarry Smith       maxcol += lcoloring->n;
1344fcfd50ebSBarry Smith       ierr    = ISColoringDestroy(&lcoloring);CHKERRQ(ierr);
134547c6ae99SBarry Smith       next    = next->next;
134647c6ae99SBarry Smith     }
134747c6ae99SBarry Smith   }
1348aaf3ff59SMatthew G. Knepley   ierr = ISColoringCreate(PetscObjectComm((PetscObject)dm),maxcol,n,colors,PETSC_OWN_POINTER,coloring);CHKERRQ(ierr);
134947c6ae99SBarry Smith   PetscFunctionReturn(0);
135047c6ae99SBarry Smith }
135147c6ae99SBarry Smith 
135247c6ae99SBarry Smith #undef __FUNCT__
13530c010503SBarry Smith #define __FUNCT__ "DMGlobalToLocalBegin_Composite"
13547087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalBegin_Composite(DM dm,Vec gvec,InsertMode mode,Vec lvec)
135547c6ae99SBarry Smith {
135647c6ae99SBarry Smith   PetscErrorCode         ierr;
135747c6ae99SBarry Smith   struct DMCompositeLink *next;
135847c6ae99SBarry Smith   PetscInt               cnt = 3;
135947c6ae99SBarry Smith   PetscMPIInt            rank;
136047c6ae99SBarry Smith   PetscScalar            *garray,*larray;
136147c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
136247c6ae99SBarry Smith 
136347c6ae99SBarry Smith   PetscFunctionBegin;
136447c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
136547c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
136647c6ae99SBarry Smith   next = com->next;
136747c6ae99SBarry Smith   if (!com->setup) {
1368d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
136947c6ae99SBarry Smith   }
1370ce94432eSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
137147c6ae99SBarry Smith   ierr = VecGetArray(gvec,&garray);CHKERRQ(ierr);
137247c6ae99SBarry Smith   ierr = VecGetArray(lvec,&larray);CHKERRQ(ierr);
137347c6ae99SBarry Smith 
137447c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
137547c6ae99SBarry Smith   while (next) {
137647c6ae99SBarry Smith     Vec      local,global;
137747c6ae99SBarry Smith     PetscInt N;
137847c6ae99SBarry Smith 
137947c6ae99SBarry Smith     ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
138047c6ae99SBarry Smith     ierr = VecGetLocalSize(global,&N);CHKERRQ(ierr);
138147c6ae99SBarry Smith     ierr = VecPlaceArray(global,garray);CHKERRQ(ierr);
138247c6ae99SBarry Smith     ierr = DMGetLocalVector(next->dm,&local);CHKERRQ(ierr);
138347c6ae99SBarry Smith     ierr = VecPlaceArray(local,larray);CHKERRQ(ierr);
138447c6ae99SBarry Smith     ierr = DMGlobalToLocalBegin(next->dm,global,mode,local);CHKERRQ(ierr);
138547c6ae99SBarry Smith     ierr = DMGlobalToLocalEnd(next->dm,global,mode,local);CHKERRQ(ierr);
138647c6ae99SBarry Smith     ierr = VecResetArray(global);CHKERRQ(ierr);
138747c6ae99SBarry Smith     ierr = VecResetArray(local);CHKERRQ(ierr);
138847c6ae99SBarry Smith     ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
138947c6ae99SBarry Smith     ierr = DMRestoreGlobalVector(next->dm,&local);CHKERRQ(ierr);
139047c6ae99SBarry Smith     cnt++;
139106ebdd98SJed Brown     larray += next->nlocal;
139247c6ae99SBarry Smith     next    = next->next;
139347c6ae99SBarry Smith   }
139447c6ae99SBarry Smith 
13950298fd71SBarry Smith   ierr = VecRestoreArray(gvec,NULL);CHKERRQ(ierr);
13960298fd71SBarry Smith   ierr = VecRestoreArray(lvec,NULL);CHKERRQ(ierr);
139747c6ae99SBarry Smith   PetscFunctionReturn(0);
139847c6ae99SBarry Smith }
139947c6ae99SBarry Smith 
140047c6ae99SBarry Smith #undef __FUNCT__
14010c010503SBarry Smith #define __FUNCT__ "DMGlobalToLocalEnd_Composite"
14027087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalEnd_Composite(DM dm,Vec gvec,InsertMode mode,Vec lvec)
14030c010503SBarry Smith {
14040c010503SBarry Smith   PetscFunctionBegin;
14050c010503SBarry Smith   PetscFunctionReturn(0);
14060c010503SBarry Smith }
140747c6ae99SBarry Smith 
14086ae3a549SBarry Smith /*MC
14096ae3a549SBarry Smith    DMCOMPOSITE = "composite" - A DM object that is used to manage data for a collection of DMs
14106ae3a549SBarry Smith 
14116ae3a549SBarry Smith   Level: intermediate
14126ae3a549SBarry Smith 
14131abcec8cSBarry Smith .seealso: DMType, DM, DMDACreate(), DMCreate(), DMSetType(), DMCompositeCreate()
14146ae3a549SBarry Smith M*/
14156ae3a549SBarry Smith 
14166ae3a549SBarry Smith 
1417a4121054SBarry Smith #undef __FUNCT__
1418a4121054SBarry Smith #define __FUNCT__ "DMCreate_Composite"
14198cc058d9SJed Brown PETSC_EXTERN PetscErrorCode DMCreate_Composite(DM p)
1420a4121054SBarry Smith {
1421a4121054SBarry Smith   PetscErrorCode ierr;
1422a4121054SBarry Smith   DM_Composite   *com;
1423a4121054SBarry Smith 
1424a4121054SBarry Smith   PetscFunctionBegin;
1425b00a9115SJed Brown   ierr      = PetscNewLog(p,&com);CHKERRQ(ierr);
1426a4121054SBarry Smith   p->data   = com;
1427a4121054SBarry Smith   ierr      = PetscObjectChangeTypeName((PetscObject)p,"DMComposite");CHKERRQ(ierr);
1428a4121054SBarry Smith   com->n    = 0;
14290298fd71SBarry Smith   com->next = NULL;
1430a4121054SBarry Smith   com->nDM  = 0;
1431a4121054SBarry Smith 
1432a4121054SBarry Smith   p->ops->createglobalvector              = DMCreateGlobalVector_Composite;
1433a4121054SBarry Smith   p->ops->createlocalvector               = DMCreateLocalVector_Composite;
1434184d77edSJed Brown   p->ops->getlocaltoglobalmapping         = DMGetLocalToGlobalMapping_Composite;
14354d343eeaSMatthew G Knepley   p->ops->createfieldis                   = DMCreateFieldIS_Composite;
143616621825SDmitry Karpeev   p->ops->createfielddecomposition        = DMCreateFieldDecomposition_Composite;
1437a4121054SBarry Smith   p->ops->refine                          = DMRefine_Composite;
143814354c39SJed Brown   p->ops->coarsen                         = DMCoarsen_Composite;
143925296bd5SBarry Smith   p->ops->createinterpolation             = DMCreateInterpolation_Composite;
144025296bd5SBarry Smith   p->ops->creatematrix                    = DMCreateMatrix_Composite;
1441e727c939SJed Brown   p->ops->getcoloring                     = DMCreateColoring_Composite;
1442a4121054SBarry Smith   p->ops->globaltolocalbegin              = DMGlobalToLocalBegin_Composite;
1443a4121054SBarry Smith   p->ops->globaltolocalend                = DMGlobalToLocalEnd_Composite;
1444a4121054SBarry Smith   p->ops->destroy                         = DMDestroy_Composite;
1445a4121054SBarry Smith   p->ops->view                            = DMView_Composite;
1446a4121054SBarry Smith   p->ops->setup                           = DMSetUp_Composite;
1447a4121054SBarry Smith   PetscFunctionReturn(0);
1448a4121054SBarry Smith }
1449a4121054SBarry Smith 
14500c010503SBarry Smith #undef __FUNCT__
14510c010503SBarry Smith #define __FUNCT__ "DMCompositeCreate"
14520c010503SBarry Smith /*@C
14530c010503SBarry Smith     DMCompositeCreate - Creates a vector packer, used to generate "composite"
14540c010503SBarry Smith       vectors made up of several subvectors.
14550c010503SBarry Smith 
14560c010503SBarry Smith     Collective on MPI_Comm
145747c6ae99SBarry Smith 
145847c6ae99SBarry Smith     Input Parameter:
14590c010503SBarry Smith .   comm - the processors that will share the global vector
14600c010503SBarry Smith 
14610c010503SBarry Smith     Output Parameters:
14620c010503SBarry Smith .   packer - the packer object
146347c6ae99SBarry Smith 
146447c6ae99SBarry Smith     Level: advanced
146547c6ae99SBarry Smith 
14661abcec8cSBarry Smith .seealso DMDestroy(), DMCompositeAddDM(), DMCompositeScatter(), DMCOMPOSITE,DMCreate()
14676eb61c8cSJed Brown          DMCompositeGather(), DMCreateGlobalVector(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess()
146847c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries()
146947c6ae99SBarry Smith 
147047c6ae99SBarry Smith @*/
14717087cfbeSBarry Smith PetscErrorCode  DMCompositeCreate(MPI_Comm comm,DM *packer)
147247c6ae99SBarry Smith {
14730c010503SBarry Smith   PetscErrorCode ierr;
14740c010503SBarry Smith 
147547c6ae99SBarry Smith   PetscFunctionBegin;
14760c010503SBarry Smith   PetscValidPointer(packer,2);
1477a4121054SBarry Smith   ierr = DMCreate(comm,packer);CHKERRQ(ierr);
1478a4121054SBarry Smith   ierr = DMSetType(*packer,DMCOMPOSITE);CHKERRQ(ierr);
147947c6ae99SBarry Smith   PetscFunctionReturn(0);
148047c6ae99SBarry Smith }
1481