xref: /petsc/src/dm/impls/composite/pack.c (revision ca4278ab6ce90dbb1af7ca493a2ed9b5f422c16c)
147c6ae99SBarry Smith 
2ccd284c7SBarry Smith #include <../src/dm/impls/composite/packimpl.h>       /*I  "petscdmcomposite.h"  I*/
3af0996ceSBarry Smith #include <petsc/private/isimpl.h>
42764a2aaSMatthew G. Knepley #include <petscds.h>
547c6ae99SBarry Smith 
647c6ae99SBarry Smith /*@C
747c6ae99SBarry Smith     DMCompositeSetCoupling - Sets user provided routines that compute the coupling between the
8bebe2cf6SSatish Balay       separate 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 
326bf464f9SBarry Smith PetscErrorCode  DMDestroy_Composite(DM dm)
3347c6ae99SBarry Smith {
3447c6ae99SBarry Smith   PetscErrorCode         ierr;
3547c6ae99SBarry Smith   struct DMCompositeLink *next, *prev;
3647c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
3747c6ae99SBarry Smith 
3847c6ae99SBarry Smith   PetscFunctionBegin;
3947c6ae99SBarry Smith   next = com->next;
4047c6ae99SBarry Smith   while (next) {
4147c6ae99SBarry Smith     prev = next;
4247c6ae99SBarry Smith     next = next->next;
43fcfd50ebSBarry Smith     ierr = DMDestroy(&prev->dm);CHKERRQ(ierr);
4447c6ae99SBarry Smith     ierr = PetscFree(prev->grstarts);CHKERRQ(ierr);
4547c6ae99SBarry Smith     ierr = PetscFree(prev);CHKERRQ(ierr);
4647c6ae99SBarry Smith   }
47435a35e8SMatthew G Knepley   /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */
48435a35e8SMatthew G Knepley   ierr = PetscFree(com);CHKERRQ(ierr);
4947c6ae99SBarry Smith   PetscFunctionReturn(0);
5047c6ae99SBarry Smith }
5147c6ae99SBarry Smith 
527087cfbeSBarry Smith PetscErrorCode  DMView_Composite(DM dm,PetscViewer v)
5347c6ae99SBarry Smith {
5447c6ae99SBarry Smith   PetscErrorCode ierr;
5547c6ae99SBarry Smith   PetscBool      iascii;
5647c6ae99SBarry Smith   DM_Composite   *com = (DM_Composite*)dm->data;
5747c6ae99SBarry Smith 
5847c6ae99SBarry Smith   PetscFunctionBegin;
59251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
6047c6ae99SBarry Smith   if (iascii) {
6147c6ae99SBarry Smith     struct DMCompositeLink *lnk = com->next;
6247c6ae99SBarry Smith     PetscInt               i;
6347c6ae99SBarry Smith 
6447c6ae99SBarry Smith     ierr = PetscViewerASCIIPrintf(v,"DM (%s)\n",((PetscObject)dm)->prefix ? ((PetscObject)dm)->prefix : "no prefix");CHKERRQ(ierr);
659ae5db72SJed Brown     ierr = PetscViewerASCIIPrintf(v,"  contains %D DMs\n",com->nDM);CHKERRQ(ierr);
6647c6ae99SBarry Smith     ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr);
6747c6ae99SBarry Smith     for (i=0; lnk; lnk=lnk->next,i++) {
689ae5db72SJed Brown       ierr = PetscViewerASCIIPrintf(v,"Link %D: DM of type %s\n",i,((PetscObject)lnk->dm)->type_name);CHKERRQ(ierr);
6947c6ae99SBarry Smith       ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr);
7047c6ae99SBarry Smith       ierr = DMView(lnk->dm,v);CHKERRQ(ierr);
7147c6ae99SBarry Smith       ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr);
7247c6ae99SBarry Smith     }
7347c6ae99SBarry Smith     ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr);
7447c6ae99SBarry Smith   }
7547c6ae99SBarry Smith   PetscFunctionReturn(0);
7647c6ae99SBarry Smith }
7747c6ae99SBarry Smith 
7847c6ae99SBarry Smith /* --------------------------------------------------------------------------------------*/
797087cfbeSBarry Smith PetscErrorCode  DMSetUp_Composite(DM dm)
8047c6ae99SBarry Smith {
8147c6ae99SBarry Smith   PetscErrorCode         ierr;
8247c6ae99SBarry Smith   PetscInt               nprev = 0;
8347c6ae99SBarry Smith   PetscMPIInt            rank,size;
8447c6ae99SBarry Smith   DM_Composite           *com  = (DM_Composite*)dm->data;
8547c6ae99SBarry Smith   struct DMCompositeLink *next = com->next;
8647c6ae99SBarry Smith   PetscLayout            map;
8747c6ae99SBarry Smith 
8847c6ae99SBarry Smith   PetscFunctionBegin;
89ce94432eSBarry Smith   if (com->setup) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Packer has already been setup");
90ce94432eSBarry Smith   ierr = PetscLayoutCreate(PetscObjectComm((PetscObject)dm),&map);CHKERRQ(ierr);
9147c6ae99SBarry Smith   ierr = PetscLayoutSetLocalSize(map,com->n);CHKERRQ(ierr);
9247c6ae99SBarry Smith   ierr = PetscLayoutSetSize(map,PETSC_DETERMINE);CHKERRQ(ierr);
9347c6ae99SBarry Smith   ierr = PetscLayoutSetBlockSize(map,1);CHKERRQ(ierr);
9447c6ae99SBarry Smith   ierr = PetscLayoutSetUp(map);CHKERRQ(ierr);
9547c6ae99SBarry Smith   ierr = PetscLayoutGetSize(map,&com->N);CHKERRQ(ierr);
960298fd71SBarry Smith   ierr = PetscLayoutGetRange(map,&com->rstart,NULL);CHKERRQ(ierr);
97fcfd50ebSBarry Smith   ierr = PetscLayoutDestroy(&map);CHKERRQ(ierr);
9847c6ae99SBarry Smith 
999ae5db72SJed Brown   /* now set the rstart for each linked vector */
100ce94432eSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
101ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm),&size);CHKERRQ(ierr);
10247c6ae99SBarry Smith   while (next) {
10347c6ae99SBarry Smith     next->rstart  = nprev;
10406ebdd98SJed Brown     nprev        += next->n;
10547c6ae99SBarry Smith     next->grstart = com->rstart + next->rstart;
106785e854fSJed Brown     ierr          = PetscMalloc1(size,&next->grstarts);CHKERRQ(ierr);
107ce94432eSBarry Smith     ierr          = MPI_Allgather(&next->grstart,1,MPIU_INT,next->grstarts,1,MPIU_INT,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
10847c6ae99SBarry Smith     next          = next->next;
10947c6ae99SBarry Smith   }
11047c6ae99SBarry Smith   com->setup = PETSC_TRUE;
11147c6ae99SBarry Smith   PetscFunctionReturn(0);
11247c6ae99SBarry Smith }
11347c6ae99SBarry Smith 
11447c6ae99SBarry Smith /* ----------------------------------------------------------------------------------*/
11547c6ae99SBarry Smith 
11673e31fe2SJed Brown /*@
11747c6ae99SBarry Smith     DMCompositeGetNumberDM - Get's the number of DM objects in the DMComposite
11847c6ae99SBarry Smith        representation.
11947c6ae99SBarry Smith 
12047c6ae99SBarry Smith     Not Collective
12147c6ae99SBarry Smith 
12247c6ae99SBarry Smith     Input Parameter:
12347c6ae99SBarry Smith .    dm - the packer object
12447c6ae99SBarry Smith 
12547c6ae99SBarry Smith     Output Parameter:
12647c6ae99SBarry Smith .     nDM - the number of DMs
12747c6ae99SBarry Smith 
12847c6ae99SBarry Smith     Level: beginner
12947c6ae99SBarry Smith 
13047c6ae99SBarry Smith @*/
1317087cfbeSBarry Smith PetscErrorCode  DMCompositeGetNumberDM(DM dm,PetscInt *nDM)
13247c6ae99SBarry Smith {
13347c6ae99SBarry Smith   DM_Composite *com = (DM_Composite*)dm->data;
1345fd66863SKarl Rupp 
13547c6ae99SBarry Smith   PetscFunctionBegin;
13647c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
13747c6ae99SBarry Smith   *nDM = com->nDM;
13847c6ae99SBarry Smith   PetscFunctionReturn(0);
13947c6ae99SBarry Smith }
14047c6ae99SBarry Smith 
14147c6ae99SBarry Smith 
14247c6ae99SBarry Smith /*@C
14347c6ae99SBarry Smith     DMCompositeGetAccess - Allows one to access the individual packed vectors in their global
14447c6ae99SBarry Smith        representation.
14547c6ae99SBarry Smith 
14647c6ae99SBarry Smith     Collective on DMComposite
14747c6ae99SBarry Smith 
1489ae5db72SJed Brown     Input Parameters:
14947c6ae99SBarry Smith +    dm - the packer object
1509ae5db72SJed Brown -    gvec - the global vector
1519ae5db72SJed Brown 
1529ae5db72SJed Brown     Output Parameters:
1530298fd71SBarry Smith .    Vec* ... - the packed parallel vectors, NULL for those that are not needed
15447c6ae99SBarry Smith 
15547c6ae99SBarry Smith     Notes: Use DMCompositeRestoreAccess() to return the vectors when you no longer need them
15647c6ae99SBarry Smith 
157f73e5cebSJed Brown     Fortran Notes:
158f73e5cebSJed Brown 
159f73e5cebSJed Brown     Fortran callers must use numbered versions of this routine, e.g., DMCompositeGetAccess4(dm,gvec,vec1,vec2,vec3,vec4)
160f73e5cebSJed Brown     or use the alternative interface DMCompositeGetAccessArray().
161f73e5cebSJed Brown 
16247c6ae99SBarry Smith     Level: advanced
16347c6ae99SBarry Smith 
164f73e5cebSJed Brown .seealso: DMCompositeGetEntries(), DMCompositeScatter()
16547c6ae99SBarry Smith @*/
1667087cfbeSBarry Smith PetscErrorCode  DMCompositeGetAccess(DM dm,Vec gvec,...)
16747c6ae99SBarry Smith {
16847c6ae99SBarry Smith   va_list                Argp;
16947c6ae99SBarry Smith   PetscErrorCode         ierr;
17047c6ae99SBarry Smith   struct DMCompositeLink *next;
17147c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
1725edff71fSBarry Smith   PetscInt               readonly;
17347c6ae99SBarry Smith 
17447c6ae99SBarry Smith   PetscFunctionBegin;
17547c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
17647c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
17747c6ae99SBarry Smith   next = com->next;
17847c6ae99SBarry Smith   if (!com->setup) {
179d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
18047c6ae99SBarry Smith   }
18147c6ae99SBarry Smith 
1825edff71fSBarry Smith   ierr = VecLockGet(gvec,&readonly);CHKERRQ(ierr);
18347c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
18447c6ae99SBarry Smith   va_start(Argp,gvec);
18547c6ae99SBarry Smith   while (next) {
18647c6ae99SBarry Smith     Vec *vec;
18747c6ae99SBarry Smith     vec = va_arg(Argp, Vec*);
1889ae5db72SJed Brown     if (vec) {
1899ae5db72SJed Brown       ierr = DMGetGlobalVector(next->dm,vec);CHKERRQ(ierr);
1905edff71fSBarry Smith       if (readonly) {
1915edff71fSBarry Smith         const PetscScalar *array;
1925edff71fSBarry Smith         ierr = VecGetArrayRead(gvec,&array);CHKERRQ(ierr);
1935edff71fSBarry Smith         ierr = VecPlaceArray(*vec,array+next->rstart);CHKERRQ(ierr);
1945edff71fSBarry Smith         ierr = VecLockPush(*vec);CHKERRQ(ierr);
1955edff71fSBarry Smith         ierr = VecRestoreArrayRead(gvec,&array);CHKERRQ(ierr);
1965edff71fSBarry Smith       } else {
1975edff71fSBarry Smith         PetscScalar *array;
1989ae5db72SJed Brown         ierr = VecGetArray(gvec,&array);CHKERRQ(ierr);
1999ae5db72SJed Brown         ierr = VecPlaceArray(*vec,array+next->rstart);CHKERRQ(ierr);
2009ae5db72SJed Brown         ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr);
20147c6ae99SBarry Smith       }
2025edff71fSBarry Smith     }
20347c6ae99SBarry Smith     next = next->next;
20447c6ae99SBarry Smith   }
20547c6ae99SBarry Smith   va_end(Argp);
20647c6ae99SBarry Smith   PetscFunctionReturn(0);
20747c6ae99SBarry Smith }
20847c6ae99SBarry Smith 
209f73e5cebSJed Brown /*@C
210f73e5cebSJed Brown     DMCompositeGetAccessArray - Allows one to access the individual packed vectors in their global
211f73e5cebSJed Brown        representation.
212f73e5cebSJed Brown 
213f73e5cebSJed Brown     Collective on DMComposite
214f73e5cebSJed Brown 
215f73e5cebSJed Brown     Input Parameters:
216f73e5cebSJed Brown +    dm - the packer object
217f73e5cebSJed Brown .    pvec - packed vector
218f73e5cebSJed Brown .    nwanted - number of vectors wanted
2190298fd71SBarry Smith -    wanted - sorted array of vectors wanted, or NULL to get all vectors
220f73e5cebSJed Brown 
221f73e5cebSJed Brown     Output Parameters:
222f73e5cebSJed Brown .    vecs - array of requested global vectors (must be allocated)
223f73e5cebSJed Brown 
224f73e5cebSJed Brown     Notes: Use DMCompositeRestoreAccessArray() to return the vectors when you no longer need them
225f73e5cebSJed Brown 
226f73e5cebSJed Brown     Level: advanced
227f73e5cebSJed Brown 
228f73e5cebSJed Brown .seealso: DMCompositeGetAccess(), DMCompositeGetEntries(), DMCompositeScatter(), DMCompositeGather()
229f73e5cebSJed Brown @*/
230f73e5cebSJed Brown PetscErrorCode  DMCompositeGetAccessArray(DM dm,Vec pvec,PetscInt nwanted,const PetscInt *wanted,Vec *vecs)
231f73e5cebSJed Brown {
232f73e5cebSJed Brown   PetscErrorCode         ierr;
233f73e5cebSJed Brown   struct DMCompositeLink *link;
234f73e5cebSJed Brown   PetscInt               i,wnum;
235f73e5cebSJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
236bee642f7SBarry Smith   PetscInt               readonly;
237f73e5cebSJed Brown 
238f73e5cebSJed Brown   PetscFunctionBegin;
239f73e5cebSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
240f73e5cebSJed Brown   PetscValidHeaderSpecific(pvec,VEC_CLASSID,2);
241f73e5cebSJed Brown   if (!com->setup) {
242f73e5cebSJed Brown     ierr = DMSetUp(dm);CHKERRQ(ierr);
243f73e5cebSJed Brown   }
244f73e5cebSJed Brown 
245bee642f7SBarry Smith   ierr = VecLockGet(pvec,&readonly);CHKERRQ(ierr);
246f73e5cebSJed Brown   for (i=0,wnum=0,link=com->next; link && wnum<nwanted; i++,link=link->next) {
247f73e5cebSJed Brown     if (!wanted || i == wanted[wnum]) {
248f73e5cebSJed Brown       Vec v;
249f73e5cebSJed Brown       ierr = DMGetGlobalVector(link->dm,&v);CHKERRQ(ierr);
250bee642f7SBarry Smith       if (readonly) {
251bee642f7SBarry Smith         const PetscScalar *array;
252bee642f7SBarry Smith         ierr = VecGetArrayRead(pvec,&array);CHKERRQ(ierr);
253bee642f7SBarry Smith         ierr = VecPlaceArray(v,array+link->rstart);CHKERRQ(ierr);
254bee642f7SBarry Smith         ierr = VecLockPush(v);CHKERRQ(ierr);
255bee642f7SBarry Smith         ierr = VecRestoreArrayRead(pvec,&array);CHKERRQ(ierr);
256bee642f7SBarry Smith       } else {
257bee642f7SBarry Smith         PetscScalar *array;
258f73e5cebSJed Brown         ierr = VecGetArray(pvec,&array);CHKERRQ(ierr);
259f73e5cebSJed Brown         ierr = VecPlaceArray(v,array+link->rstart);CHKERRQ(ierr);
260f73e5cebSJed Brown         ierr = VecRestoreArray(pvec,&array);CHKERRQ(ierr);
261bee642f7SBarry Smith       }
262f73e5cebSJed Brown       vecs[wnum++] = v;
263f73e5cebSJed Brown     }
264f73e5cebSJed Brown   }
265f73e5cebSJed Brown   PetscFunctionReturn(0);
266f73e5cebSJed Brown }
267f73e5cebSJed Brown 
2687ac2b803SAlex Fikl /*@C
2697ac2b803SAlex Fikl     DMCompositeGetLocalAccessArray - Allows one to access the individual
2707ac2b803SAlex Fikl     packed vectors in their local representation.
2717ac2b803SAlex Fikl 
2727ac2b803SAlex Fikl     Collective on DMComposite.
2737ac2b803SAlex Fikl 
2747ac2b803SAlex Fikl     Input Parameters:
2757ac2b803SAlex Fikl +    dm - the packer object
2767ac2b803SAlex Fikl .    pvec - packed vector
2777ac2b803SAlex Fikl .    nwanted - number of vectors wanted
2787ac2b803SAlex Fikl -    wanted - sorted array of vectors wanted, or NULL to get all vectors
2797ac2b803SAlex Fikl 
2807ac2b803SAlex Fikl     Output Parameters:
2817ac2b803SAlex Fikl .    vecs - array of requested local vectors (must be allocated)
2827ac2b803SAlex Fikl 
2837ac2b803SAlex Fikl     Notes: Use DMCompositeRestoreLocalAccessArray() to return the vectors
2847ac2b803SAlex Fikl     when you no longer need them.
2857ac2b803SAlex Fikl 
2867ac2b803SAlex Fikl     Level: advanced
2877ac2b803SAlex Fikl 
2887ac2b803SAlex Fikl .seealso: DMCompositeRestoreLocalAccessArray(), DMCompositeGetAccess(),
2897ac2b803SAlex Fikl DMCompositeGetEntries(), DMCompositeScatter(), DMCompositeGather()
2907ac2b803SAlex Fikl @*/
2917ac2b803SAlex Fikl PetscErrorCode  DMCompositeGetLocalAccessArray(DM dm,Vec pvec,PetscInt nwanted,const PetscInt *wanted,Vec *vecs)
2927ac2b803SAlex Fikl {
2937ac2b803SAlex Fikl   PetscErrorCode         ierr;
2947ac2b803SAlex Fikl   struct DMCompositeLink *link;
2957ac2b803SAlex Fikl   PetscInt               i,wnum;
2967ac2b803SAlex Fikl   DM_Composite           *com = (DM_Composite*)dm->data;
2977ac2b803SAlex Fikl   PetscInt               readonly;
2987ac2b803SAlex Fikl   PetscInt               nlocal = 0;
2997ac2b803SAlex Fikl 
3007ac2b803SAlex Fikl   PetscFunctionBegin;
3017ac2b803SAlex Fikl   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3027ac2b803SAlex Fikl   PetscValidHeaderSpecific(pvec,VEC_CLASSID,2);
3037ac2b803SAlex Fikl   if (!com->setup) {
3047ac2b803SAlex Fikl     ierr = DMSetUp(dm);CHKERRQ(ierr);
3057ac2b803SAlex Fikl   }
3067ac2b803SAlex Fikl 
3077ac2b803SAlex Fikl   ierr = VecLockGet(pvec,&readonly);CHKERRQ(ierr);
3087ac2b803SAlex Fikl   for (i=0,wnum=0,link=com->next; link && wnum<nwanted; i++,link=link->next) {
3097ac2b803SAlex Fikl     if (!wanted || i == wanted[wnum]) {
3107ac2b803SAlex Fikl       Vec v;
3117ac2b803SAlex Fikl       ierr = DMGetLocalVector(link->dm,&v);CHKERRQ(ierr);
3127ac2b803SAlex Fikl       if (readonly) {
3137ac2b803SAlex Fikl         const PetscScalar *array;
3147ac2b803SAlex Fikl         ierr = VecGetArrayRead(pvec,&array);CHKERRQ(ierr);
3157ac2b803SAlex Fikl         ierr = VecPlaceArray(v,array+nlocal);CHKERRQ(ierr);
3167ac2b803SAlex Fikl         ierr = VecLockPush(v);CHKERRQ(ierr);
3177ac2b803SAlex Fikl         ierr = VecRestoreArrayRead(pvec,&array);CHKERRQ(ierr);
3187ac2b803SAlex Fikl       } else {
3197ac2b803SAlex Fikl         PetscScalar *array;
3207ac2b803SAlex Fikl         ierr = VecGetArray(pvec,&array);CHKERRQ(ierr);
3217ac2b803SAlex Fikl         ierr = VecPlaceArray(v,array+nlocal);CHKERRQ(ierr);
3227ac2b803SAlex Fikl         ierr = VecRestoreArray(pvec,&array);CHKERRQ(ierr);
3237ac2b803SAlex Fikl       }
3247ac2b803SAlex Fikl       vecs[wnum++] = v;
3257ac2b803SAlex Fikl     }
3267ac2b803SAlex Fikl 
3277ac2b803SAlex Fikl     nlocal += link->nlocal;
3287ac2b803SAlex Fikl   }
3297ac2b803SAlex Fikl 
3307ac2b803SAlex Fikl   PetscFunctionReturn(0);
3317ac2b803SAlex Fikl }
3327ac2b803SAlex Fikl 
33347c6ae99SBarry Smith /*@C
334aa219208SBarry Smith     DMCompositeRestoreAccess - Returns the vectors obtained with DMCompositeGetAccess()
33547c6ae99SBarry Smith        representation.
33647c6ae99SBarry Smith 
33747c6ae99SBarry Smith     Collective on DMComposite
33847c6ae99SBarry Smith 
3399ae5db72SJed Brown     Input Parameters:
34047c6ae99SBarry Smith +    dm - the packer object
34147c6ae99SBarry Smith .    gvec - the global vector
3420298fd71SBarry Smith -    Vec* ... - the individual parallel vectors, NULL for those that are not needed
34347c6ae99SBarry Smith 
34447c6ae99SBarry Smith     Level: advanced
34547c6ae99SBarry Smith 
3469ae5db72SJed Brown .seealso  DMCompositeAddDM(), DMCreateGlobalVector(),
3476eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeScatter(),
348aa219208SBarry Smith          DMCompositeRestoreAccess(), DMCompositeGetAccess()
34947c6ae99SBarry Smith 
35047c6ae99SBarry Smith @*/
3517087cfbeSBarry Smith PetscErrorCode  DMCompositeRestoreAccess(DM dm,Vec gvec,...)
35247c6ae99SBarry Smith {
35347c6ae99SBarry Smith   va_list                Argp;
35447c6ae99SBarry Smith   PetscErrorCode         ierr;
35547c6ae99SBarry Smith   struct DMCompositeLink *next;
35647c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
3575edff71fSBarry Smith   PetscInt               readonly;
35847c6ae99SBarry Smith 
35947c6ae99SBarry Smith   PetscFunctionBegin;
36047c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
36147c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
36247c6ae99SBarry Smith   next = com->next;
36347c6ae99SBarry Smith   if (!com->setup) {
364d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
36547c6ae99SBarry Smith   }
36647c6ae99SBarry Smith 
3675edff71fSBarry Smith   ierr = VecLockGet(gvec,&readonly);CHKERRQ(ierr);
36847c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
36947c6ae99SBarry Smith   va_start(Argp,gvec);
37047c6ae99SBarry Smith   while (next) {
37147c6ae99SBarry Smith     Vec *vec;
37247c6ae99SBarry Smith     vec = va_arg(Argp, Vec*);
3739ae5db72SJed Brown     if (vec) {
3749ae5db72SJed Brown       ierr = VecResetArray(*vec);CHKERRQ(ierr);
3755edff71fSBarry Smith       if (readonly) {
3765edff71fSBarry Smith         ierr = VecLockPop(*vec);CHKERRQ(ierr);
3775edff71fSBarry Smith       }
378bee642f7SBarry Smith       ierr = DMRestoreGlobalVector(next->dm,vec);CHKERRQ(ierr);
37947c6ae99SBarry Smith     }
38047c6ae99SBarry Smith     next = next->next;
38147c6ae99SBarry Smith   }
38247c6ae99SBarry Smith   va_end(Argp);
38347c6ae99SBarry Smith   PetscFunctionReturn(0);
38447c6ae99SBarry Smith }
38547c6ae99SBarry Smith 
386f73e5cebSJed Brown /*@C
387f73e5cebSJed Brown     DMCompositeRestoreAccessArray - Returns the vectors obtained with DMCompositeGetAccessArray()
388f73e5cebSJed Brown 
389f73e5cebSJed Brown     Collective on DMComposite
390f73e5cebSJed Brown 
391f73e5cebSJed Brown     Input Parameters:
392f73e5cebSJed Brown +    dm - the packer object
393f73e5cebSJed Brown .    pvec - packed vector
394f73e5cebSJed Brown .    nwanted - number of vectors wanted
3950298fd71SBarry Smith .    wanted - sorted array of vectors wanted, or NULL to get all vectors
396f73e5cebSJed Brown -    vecs - array of global vectors to return
397f73e5cebSJed Brown 
398f73e5cebSJed Brown     Level: advanced
399f73e5cebSJed Brown 
400f73e5cebSJed Brown .seealso: DMCompositeRestoreAccess(), DMCompositeRestoreEntries(), DMCompositeScatter(), DMCompositeGather()
401f73e5cebSJed Brown @*/
402f73e5cebSJed Brown PetscErrorCode  DMCompositeRestoreAccessArray(DM dm,Vec pvec,PetscInt nwanted,const PetscInt *wanted,Vec *vecs)
403f73e5cebSJed Brown {
404f73e5cebSJed Brown   PetscErrorCode         ierr;
405f73e5cebSJed Brown   struct DMCompositeLink *link;
406f73e5cebSJed Brown   PetscInt               i,wnum;
407f73e5cebSJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
408bee642f7SBarry Smith   PetscInt               readonly;
409f73e5cebSJed Brown 
410f73e5cebSJed Brown   PetscFunctionBegin;
411f73e5cebSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
412f73e5cebSJed Brown   PetscValidHeaderSpecific(pvec,VEC_CLASSID,2);
413f73e5cebSJed Brown   if (!com->setup) {
414f73e5cebSJed Brown     ierr = DMSetUp(dm);CHKERRQ(ierr);
415f73e5cebSJed Brown   }
416f73e5cebSJed Brown 
417bee642f7SBarry Smith   ierr = VecLockGet(pvec,&readonly);CHKERRQ(ierr);
418f73e5cebSJed Brown   for (i=0,wnum=0,link=com->next; link && wnum<nwanted; i++,link=link->next) {
419f73e5cebSJed Brown     if (!wanted || i == wanted[wnum]) {
420f73e5cebSJed Brown       ierr = VecResetArray(vecs[wnum]);CHKERRQ(ierr);
421bee642f7SBarry Smith       if (readonly) {
422bee642f7SBarry Smith         ierr = VecLockPop(vecs[wnum]);CHKERRQ(ierr);
423bee642f7SBarry Smith       }
424f73e5cebSJed Brown       ierr = DMRestoreGlobalVector(link->dm,&vecs[wnum]);CHKERRQ(ierr);
425f73e5cebSJed Brown       wnum++;
426f73e5cebSJed Brown     }
427f73e5cebSJed Brown   }
428f73e5cebSJed Brown   PetscFunctionReturn(0);
429f73e5cebSJed Brown }
430f73e5cebSJed Brown 
4317ac2b803SAlex Fikl /*@C
4327ac2b803SAlex Fikl     DMCompositeRestoreLocalAccessArray - Returns the vectors obtained with DMCompositeGetLocalAccessArray().
4337ac2b803SAlex Fikl 
4347ac2b803SAlex Fikl     Collective on DMComposite.
4357ac2b803SAlex Fikl 
4367ac2b803SAlex Fikl     Input Parameters:
4377ac2b803SAlex Fikl +    dm - the packer object
4387ac2b803SAlex Fikl .    pvec - packed vector
4397ac2b803SAlex Fikl .    nwanted - number of vectors wanted
4407ac2b803SAlex Fikl .    wanted - sorted array of vectors wanted, or NULL to restore all vectors
4417ac2b803SAlex Fikl -    vecs - array of local vectors to return
4427ac2b803SAlex Fikl 
4437ac2b803SAlex Fikl     Level: advanced
4447ac2b803SAlex Fikl 
4457ac2b803SAlex Fikl     Notes:
4467ac2b803SAlex Fikl     nwanted and wanted must match the values given to DMCompositeGetLocalAccessArray()
4477ac2b803SAlex Fikl     otherwise the call will fail.
4487ac2b803SAlex Fikl 
4497ac2b803SAlex Fikl .seealso: DMCompositeGetLocalAccessArray(), DMCompositeRestoreAccessArray(),
4507ac2b803SAlex Fikl DMCompositeRestoreAccess(), DMCompositeRestoreEntries(),
4517ac2b803SAlex Fikl DMCompositeScatter(), DMCompositeGather()
4527ac2b803SAlex Fikl @*/
4537ac2b803SAlex Fikl PetscErrorCode  DMCompositeRestoreLocalAccessArray(DM dm,Vec pvec,PetscInt nwanted,const PetscInt *wanted,Vec *vecs)
4547ac2b803SAlex Fikl {
4557ac2b803SAlex Fikl   PetscErrorCode         ierr;
4567ac2b803SAlex Fikl   struct DMCompositeLink *link;
4577ac2b803SAlex Fikl   PetscInt               i,wnum;
4587ac2b803SAlex Fikl   DM_Composite           *com = (DM_Composite*)dm->data;
4597ac2b803SAlex Fikl   PetscInt               readonly;
4607ac2b803SAlex Fikl 
4617ac2b803SAlex Fikl   PetscFunctionBegin;
4627ac2b803SAlex Fikl   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4637ac2b803SAlex Fikl   PetscValidHeaderSpecific(pvec,VEC_CLASSID,2);
4647ac2b803SAlex Fikl   if (!com->setup) {
4657ac2b803SAlex Fikl     ierr = DMSetUp(dm);CHKERRQ(ierr);
4667ac2b803SAlex Fikl   }
4677ac2b803SAlex Fikl 
4687ac2b803SAlex Fikl   ierr = VecLockGet(pvec,&readonly);CHKERRQ(ierr);
4697ac2b803SAlex Fikl   for (i=0,wnum=0,link=com->next; link && wnum<nwanted; i++,link=link->next) {
4707ac2b803SAlex Fikl     if (!wanted || i == wanted[wnum]) {
4717ac2b803SAlex Fikl       ierr = VecResetArray(vecs[wnum]);CHKERRQ(ierr);
4727ac2b803SAlex Fikl       if (readonly) {
4737ac2b803SAlex Fikl         ierr = VecLockPop(vecs[wnum]);CHKERRQ(ierr);
4747ac2b803SAlex Fikl       }
4757ac2b803SAlex Fikl       ierr = DMRestoreLocalVector(link->dm,&vecs[wnum]);CHKERRQ(ierr);
4767ac2b803SAlex Fikl       wnum++;
4777ac2b803SAlex Fikl     }
4787ac2b803SAlex Fikl   }
4797ac2b803SAlex Fikl   PetscFunctionReturn(0);
4807ac2b803SAlex Fikl }
4817ac2b803SAlex Fikl 
48247c6ae99SBarry Smith /*@C
48347c6ae99SBarry Smith     DMCompositeScatter - Scatters from a global packed vector into its individual local vectors
48447c6ae99SBarry Smith 
48547c6ae99SBarry Smith     Collective on DMComposite
48647c6ae99SBarry Smith 
4879ae5db72SJed Brown     Input Parameters:
48847c6ae99SBarry Smith +    dm - the packer object
48947c6ae99SBarry Smith .    gvec - the global vector
4900298fd71SBarry Smith -    Vec ... - the individual sequential vectors, NULL for those that are not needed
49147c6ae99SBarry Smith 
49247c6ae99SBarry Smith     Level: advanced
49347c6ae99SBarry Smith 
4946f3c3dcfSJed Brown     Notes:
4956f3c3dcfSJed Brown     DMCompositeScatterArray() is a non-variadic alternative that is often more convenient for library callers and is
4966f3c3dcfSJed Brown     accessible from Fortran.
4976f3c3dcfSJed Brown 
4989ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
4996eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
50047c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries()
5016f3c3dcfSJed Brown          DMCompositeScatterArray()
50247c6ae99SBarry Smith 
50347c6ae99SBarry Smith @*/
5047087cfbeSBarry Smith PetscErrorCode  DMCompositeScatter(DM dm,Vec gvec,...)
50547c6ae99SBarry Smith {
50647c6ae99SBarry Smith   va_list                Argp;
50747c6ae99SBarry Smith   PetscErrorCode         ierr;
50847c6ae99SBarry Smith   struct DMCompositeLink *next;
5098fd8f222SJed Brown   PetscInt               cnt;
51047c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
51147c6ae99SBarry Smith 
51247c6ae99SBarry Smith   PetscFunctionBegin;
51347c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
51447c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
51547c6ae99SBarry Smith   if (!com->setup) {
516d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
51747c6ae99SBarry Smith   }
51847c6ae99SBarry Smith 
51947c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
52047c6ae99SBarry Smith   va_start(Argp,gvec);
5218fd8f222SJed Brown   for (cnt=3,next=com->next; next; cnt++,next=next->next) {
5229ae5db72SJed Brown     Vec local;
5239ae5db72SJed Brown     local = va_arg(Argp, Vec);
5249ae5db72SJed Brown     if (local) {
5259ae5db72SJed Brown       Vec               global;
5265edff71fSBarry Smith       const PetscScalar *array;
5279ae5db72SJed Brown       PetscValidHeaderSpecific(local,VEC_CLASSID,cnt);
5289ae5db72SJed Brown       ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
5295edff71fSBarry Smith       ierr = VecGetArrayRead(gvec,&array);CHKERRQ(ierr);
5309ae5db72SJed Brown       ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr);
5319ae5db72SJed Brown       ierr = DMGlobalToLocalBegin(next->dm,global,INSERT_VALUES,local);CHKERRQ(ierr);
5329ae5db72SJed Brown       ierr = DMGlobalToLocalEnd(next->dm,global,INSERT_VALUES,local);CHKERRQ(ierr);
5335edff71fSBarry Smith       ierr = VecRestoreArrayRead(gvec,&array);CHKERRQ(ierr);
5349ae5db72SJed Brown       ierr = VecResetArray(global);CHKERRQ(ierr);
5359ae5db72SJed Brown       ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
53647c6ae99SBarry Smith     }
53747c6ae99SBarry Smith   }
53847c6ae99SBarry Smith   va_end(Argp);
53947c6ae99SBarry Smith   PetscFunctionReturn(0);
54047c6ae99SBarry Smith }
54147c6ae99SBarry Smith 
5426f3c3dcfSJed Brown /*@
5436f3c3dcfSJed Brown     DMCompositeScatterArray - Scatters from a global packed vector into its individual local vectors
5446f3c3dcfSJed Brown 
5456f3c3dcfSJed Brown     Collective on DMComposite
5466f3c3dcfSJed Brown 
5476f3c3dcfSJed Brown     Input Parameters:
5486f3c3dcfSJed Brown +    dm - the packer object
5496f3c3dcfSJed Brown .    gvec - the global vector
5506f3c3dcfSJed Brown .    lvecs - array of local vectors, NULL for any that are not needed
5516f3c3dcfSJed Brown 
5526f3c3dcfSJed Brown     Level: advanced
5536f3c3dcfSJed Brown 
5546f3c3dcfSJed Brown     Note:
555907376e6SBarry Smith     This is a non-variadic alternative to DMCompositeScatter()
5566f3c3dcfSJed Brown 
5576f3c3dcfSJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector()
5586f3c3dcfSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
5596f3c3dcfSJed Brown          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries()
5606f3c3dcfSJed Brown 
5616f3c3dcfSJed Brown @*/
5626f3c3dcfSJed Brown PetscErrorCode  DMCompositeScatterArray(DM dm,Vec gvec,Vec *lvecs)
5636f3c3dcfSJed Brown {
5646f3c3dcfSJed Brown   PetscErrorCode         ierr;
5656f3c3dcfSJed Brown   struct DMCompositeLink *next;
5666f3c3dcfSJed Brown   PetscInt               i;
5676f3c3dcfSJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
5686f3c3dcfSJed Brown 
5696f3c3dcfSJed Brown   PetscFunctionBegin;
5706f3c3dcfSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5716f3c3dcfSJed Brown   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
5726f3c3dcfSJed Brown   if (!com->setup) {
5736f3c3dcfSJed Brown     ierr = DMSetUp(dm);CHKERRQ(ierr);
5746f3c3dcfSJed Brown   }
5756f3c3dcfSJed Brown 
5766f3c3dcfSJed Brown   /* loop over packed objects, handling one at at time */
5776f3c3dcfSJed Brown   for (i=0,next=com->next; next; next=next->next,i++) {
5786f3c3dcfSJed Brown     if (lvecs[i]) {
5796f3c3dcfSJed Brown       Vec         global;
580c5d31e75SLisandro Dalcin       const PetscScalar *array;
5816f3c3dcfSJed Brown       PetscValidHeaderSpecific(lvecs[i],VEC_CLASSID,3);
5826f3c3dcfSJed Brown       ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
583c5d31e75SLisandro Dalcin       ierr = VecGetArrayRead(gvec,&array);CHKERRQ(ierr);
584c5d31e75SLisandro Dalcin       ierr = VecPlaceArray(global,(PetscScalar*)array+next->rstart);CHKERRQ(ierr);
5856f3c3dcfSJed Brown       ierr = DMGlobalToLocalBegin(next->dm,global,INSERT_VALUES,lvecs[i]);CHKERRQ(ierr);
5866f3c3dcfSJed Brown       ierr = DMGlobalToLocalEnd(next->dm,global,INSERT_VALUES,lvecs[i]);CHKERRQ(ierr);
587c5d31e75SLisandro Dalcin       ierr = VecRestoreArrayRead(gvec,&array);CHKERRQ(ierr);
5886f3c3dcfSJed Brown       ierr = VecResetArray(global);CHKERRQ(ierr);
5896f3c3dcfSJed Brown       ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
5906f3c3dcfSJed Brown     }
5916f3c3dcfSJed Brown   }
5926f3c3dcfSJed Brown   PetscFunctionReturn(0);
5936f3c3dcfSJed Brown }
5946f3c3dcfSJed Brown 
59547c6ae99SBarry Smith /*@C
59647c6ae99SBarry Smith     DMCompositeGather - Gathers into a global packed vector from its individual local vectors
59747c6ae99SBarry Smith 
59847c6ae99SBarry Smith     Collective on DMComposite
59947c6ae99SBarry Smith 
60047c6ae99SBarry Smith     Input Parameter:
60147c6ae99SBarry Smith +    dm - the packer object
60247c6ae99SBarry Smith .    gvec - the global vector
603907376e6SBarry Smith .    imode - INSERT_VALUES or ADD_VALUES
6040298fd71SBarry Smith -    Vec ... - the individual sequential vectors, NULL for any that are not needed
60547c6ae99SBarry Smith 
60647c6ae99SBarry Smith     Level: advanced
60747c6ae99SBarry Smith 
6089ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
6096eb61c8cSJed Brown          DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
61047c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries()
61147c6ae99SBarry Smith 
61247c6ae99SBarry Smith @*/
6131dac896bSSatish Balay PetscErrorCode  DMCompositeGather(DM dm,InsertMode imode,Vec gvec,...)
61447c6ae99SBarry Smith {
61547c6ae99SBarry Smith   va_list                Argp;
61647c6ae99SBarry Smith   PetscErrorCode         ierr;
61747c6ae99SBarry Smith   struct DMCompositeLink *next;
61847c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
6198fd8f222SJed Brown   PetscInt               cnt;
62047c6ae99SBarry Smith 
62147c6ae99SBarry Smith   PetscFunctionBegin;
62247c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
62347c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
62447c6ae99SBarry Smith   if (!com->setup) {
625d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
62647c6ae99SBarry Smith   }
62747c6ae99SBarry Smith 
62847c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
6291dac896bSSatish Balay   va_start(Argp,gvec);
6308fd8f222SJed Brown   for (cnt=3,next=com->next; next; cnt++,next=next->next) {
6319ae5db72SJed Brown     Vec local;
6329ae5db72SJed Brown     local = va_arg(Argp, Vec);
6339ae5db72SJed Brown     if (local) {
63447c6ae99SBarry Smith       PetscScalar *array;
6359ae5db72SJed Brown       Vec         global;
6369ae5db72SJed Brown       PetscValidHeaderSpecific(local,VEC_CLASSID,cnt);
6379ae5db72SJed Brown       ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
6389ae5db72SJed Brown       ierr = VecGetArray(gvec,&array);CHKERRQ(ierr);
6399ae5db72SJed Brown       ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr);
6409ae5db72SJed Brown       ierr = DMLocalToGlobalBegin(next->dm,local,imode,global);CHKERRQ(ierr);
6419ae5db72SJed Brown       ierr = DMLocalToGlobalEnd(next->dm,local,imode,global);CHKERRQ(ierr);
6429ae5db72SJed Brown       ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr);
6439ae5db72SJed Brown       ierr = VecResetArray(global);CHKERRQ(ierr);
6449ae5db72SJed Brown       ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
64547c6ae99SBarry Smith     }
64647c6ae99SBarry Smith   }
64747c6ae99SBarry Smith   va_end(Argp);
64847c6ae99SBarry Smith   PetscFunctionReturn(0);
64947c6ae99SBarry Smith }
65047c6ae99SBarry Smith 
6516f3c3dcfSJed Brown /*@
6526f3c3dcfSJed Brown     DMCompositeGatherArray - Gathers into a global packed vector from its individual local vectors
6536f3c3dcfSJed Brown 
6546f3c3dcfSJed Brown     Collective on DMComposite
6556f3c3dcfSJed Brown 
6566f3c3dcfSJed Brown     Input Parameter:
6576f3c3dcfSJed Brown +    dm - the packer object
6586f3c3dcfSJed Brown .    gvec - the global vector
659907376e6SBarry Smith .    imode - INSERT_VALUES or ADD_VALUES
6606f3c3dcfSJed Brown -    lvecs - the individual sequential vectors, NULL for any that are not needed
6616f3c3dcfSJed Brown 
6626f3c3dcfSJed Brown     Level: advanced
6636f3c3dcfSJed Brown 
6646f3c3dcfSJed Brown     Notes:
6656f3c3dcfSJed Brown     This is a non-variadic alternative to DMCompositeGather().
6666f3c3dcfSJed Brown 
6676f3c3dcfSJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
6686f3c3dcfSJed Brown          DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
6696f3c3dcfSJed Brown          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries(),
6706f3c3dcfSJed Brown @*/
6711dac896bSSatish Balay PetscErrorCode  DMCompositeGatherArray(DM dm,InsertMode imode,Vec gvec,Vec *lvecs)
6726f3c3dcfSJed Brown {
6736f3c3dcfSJed Brown   PetscErrorCode         ierr;
6746f3c3dcfSJed Brown   struct DMCompositeLink *next;
6756f3c3dcfSJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
6766f3c3dcfSJed Brown   PetscInt               i;
6776f3c3dcfSJed Brown 
6786f3c3dcfSJed Brown   PetscFunctionBegin;
6796f3c3dcfSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6806f3c3dcfSJed Brown   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
6816f3c3dcfSJed Brown   if (!com->setup) {
6826f3c3dcfSJed Brown     ierr = DMSetUp(dm);CHKERRQ(ierr);
6836f3c3dcfSJed Brown   }
6846f3c3dcfSJed Brown 
6856f3c3dcfSJed Brown   /* loop over packed objects, handling one at at time */
6866f3c3dcfSJed Brown   for (next=com->next,i=0; next; next=next->next,i++) {
6876f3c3dcfSJed Brown     if (lvecs[i]) {
6886f3c3dcfSJed Brown       PetscScalar *array;
6896f3c3dcfSJed Brown       Vec         global;
6906f3c3dcfSJed Brown       PetscValidHeaderSpecific(lvecs[i],VEC_CLASSID,3);
6916f3c3dcfSJed Brown       ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
6926f3c3dcfSJed Brown       ierr = VecGetArray(gvec,&array);CHKERRQ(ierr);
6936f3c3dcfSJed Brown       ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr);
6946f3c3dcfSJed Brown       ierr = DMLocalToGlobalBegin(next->dm,lvecs[i],imode,global);CHKERRQ(ierr);
6956f3c3dcfSJed Brown       ierr = DMLocalToGlobalEnd(next->dm,lvecs[i],imode,global);CHKERRQ(ierr);
6966f3c3dcfSJed Brown       ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr);
6976f3c3dcfSJed Brown       ierr = VecResetArray(global);CHKERRQ(ierr);
6986f3c3dcfSJed Brown       ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
6996f3c3dcfSJed Brown     }
7006f3c3dcfSJed Brown   }
7016f3c3dcfSJed Brown   PetscFunctionReturn(0);
7026f3c3dcfSJed Brown }
7036f3c3dcfSJed Brown 
70447c6ae99SBarry Smith /*@C
705aa219208SBarry Smith     DMCompositeAddDM - adds a DM  vector to a DMComposite
70647c6ae99SBarry Smith 
70747c6ae99SBarry Smith     Collective on DMComposite
70847c6ae99SBarry Smith 
70947c6ae99SBarry Smith     Input Parameter:
71047c6ae99SBarry Smith +    dm - the packer object
71147c6ae99SBarry Smith -    dm - the DM object, if the DM is a da you will need to caste it with a (DM)
71247c6ae99SBarry Smith 
71347c6ae99SBarry Smith     Level: advanced
71447c6ae99SBarry Smith 
7150c010503SBarry Smith .seealso DMDestroy(), DMCompositeGather(), DMCompositeAddDM(), DMCreateGlobalVector(),
7166eb61c8cSJed Brown          DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
71747c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries()
71847c6ae99SBarry Smith 
71947c6ae99SBarry Smith @*/
7207087cfbeSBarry Smith PetscErrorCode  DMCompositeAddDM(DM dmc,DM dm)
72147c6ae99SBarry Smith {
72247c6ae99SBarry Smith   PetscErrorCode         ierr;
72306ebdd98SJed Brown   PetscInt               n,nlocal;
72447c6ae99SBarry Smith   struct DMCompositeLink *mine,*next;
72506ebdd98SJed Brown   Vec                    global,local;
72647c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dmc->data;
72747c6ae99SBarry Smith 
72847c6ae99SBarry Smith   PetscFunctionBegin;
72947c6ae99SBarry Smith   PetscValidHeaderSpecific(dmc,DM_CLASSID,1);
73047c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,2);
73147c6ae99SBarry Smith   next = com->next;
732ce94432eSBarry Smith   if (com->setup) SETERRQ(PetscObjectComm((PetscObject)dmc),PETSC_ERR_ARG_WRONGSTATE,"Cannot add a DM once you have used the DMComposite");
73347c6ae99SBarry Smith 
73447c6ae99SBarry Smith   /* create new link */
735b00a9115SJed Brown   ierr = PetscNew(&mine);CHKERRQ(ierr);
73647c6ae99SBarry Smith   ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);
73747c6ae99SBarry Smith   ierr = DMGetGlobalVector(dm,&global);CHKERRQ(ierr);
73847c6ae99SBarry Smith   ierr = VecGetLocalSize(global,&n);CHKERRQ(ierr);
73947c6ae99SBarry Smith   ierr = DMRestoreGlobalVector(dm,&global);CHKERRQ(ierr);
74006ebdd98SJed Brown   ierr = DMGetLocalVector(dm,&local);CHKERRQ(ierr);
74106ebdd98SJed Brown   ierr = VecGetSize(local,&nlocal);CHKERRQ(ierr);
74206ebdd98SJed Brown   ierr = DMRestoreLocalVector(dm,&local);CHKERRQ(ierr);
7438865f1eaSKarl Rupp 
74447c6ae99SBarry Smith   mine->n      = n;
74506ebdd98SJed Brown   mine->nlocal = nlocal;
74647c6ae99SBarry Smith   mine->dm     = dm;
7470298fd71SBarry Smith   mine->next   = NULL;
74847c6ae99SBarry Smith   com->n      += n;
7497ac2b803SAlex Fikl   com->nghost += nlocal;
75047c6ae99SBarry Smith 
75147c6ae99SBarry Smith   /* add to end of list */
7528865f1eaSKarl Rupp   if (!next) com->next = mine;
7538865f1eaSKarl Rupp   else {
75447c6ae99SBarry Smith     while (next->next) next = next->next;
75547c6ae99SBarry Smith     next->next = mine;
75647c6ae99SBarry Smith   }
75747c6ae99SBarry Smith   com->nDM++;
75847c6ae99SBarry Smith   com->nmine++;
75947c6ae99SBarry Smith   PetscFunctionReturn(0);
76047c6ae99SBarry Smith }
76147c6ae99SBarry Smith 
7629804daf3SBarry Smith #include <petscdraw.h>
76326887b52SJed Brown PETSC_EXTERN PetscErrorCode  VecView_MPI(Vec,PetscViewer);
7647087cfbeSBarry Smith PetscErrorCode  VecView_DMComposite(Vec gvec,PetscViewer viewer)
76547c6ae99SBarry Smith {
76647c6ae99SBarry Smith   DM                     dm;
76747c6ae99SBarry Smith   PetscErrorCode         ierr;
76847c6ae99SBarry Smith   struct DMCompositeLink *next;
76947c6ae99SBarry Smith   PetscBool              isdraw;
770cef07954SSatish Balay   DM_Composite           *com;
77147c6ae99SBarry Smith 
77247c6ae99SBarry Smith   PetscFunctionBegin;
773c688c046SMatthew G Knepley   ierr = VecGetDM(gvec, &dm);CHKERRQ(ierr);
774ce94432eSBarry Smith   if (!dm) SETERRQ(PetscObjectComm((PetscObject)gvec),PETSC_ERR_ARG_WRONG,"Vector not generated from a DMComposite");
77547c6ae99SBarry Smith   com  = (DM_Composite*)dm->data;
77647c6ae99SBarry Smith   next = com->next;
77747c6ae99SBarry Smith 
778251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
77947c6ae99SBarry Smith   if (!isdraw) {
78047c6ae99SBarry Smith     /* do I really want to call this? */
78147c6ae99SBarry Smith     ierr = VecView_MPI(gvec,viewer);CHKERRQ(ierr);
78247c6ae99SBarry Smith   } else {
78347c6ae99SBarry Smith     PetscInt cnt = 0;
78447c6ae99SBarry Smith 
78547c6ae99SBarry Smith     /* loop over packed objects, handling one at at time */
78647c6ae99SBarry Smith     while (next) {
78747c6ae99SBarry Smith       Vec               vec;
788*ca4278abSLisandro Dalcin       const PetscScalar *array;
78947c6ae99SBarry Smith       PetscInt          bs;
79047c6ae99SBarry Smith 
7919ae5db72SJed Brown       /* Should use VecGetSubVector() eventually, but would need to forward the DM for that to work */
7929ae5db72SJed Brown       ierr = DMGetGlobalVector(next->dm,&vec);CHKERRQ(ierr);
793*ca4278abSLisandro Dalcin       ierr = VecGetArrayRead(gvec,&array);CHKERRQ(ierr);
794*ca4278abSLisandro Dalcin       ierr = VecPlaceArray(vec,(PetscScalar*)array+next->rstart);CHKERRQ(ierr);
795*ca4278abSLisandro Dalcin       ierr = VecRestoreArrayRead(gvec,&array);CHKERRQ(ierr);
79647c6ae99SBarry Smith       ierr = VecView(vec,viewer);CHKERRQ(ierr);
7979ae5db72SJed Brown       ierr = VecResetArray(vec);CHKERRQ(ierr);
798*ca4278abSLisandro Dalcin       ierr = VecGetBlockSize(vec,&bs);CHKERRQ(ierr);
7999ae5db72SJed Brown       ierr = DMRestoreGlobalVector(next->dm,&vec);CHKERRQ(ierr);
80047c6ae99SBarry Smith       ierr = PetscViewerDrawBaseAdd(viewer,bs);CHKERRQ(ierr);
80147c6ae99SBarry Smith       cnt += bs;
80247c6ae99SBarry Smith       next = next->next;
80347c6ae99SBarry Smith     }
80447c6ae99SBarry Smith     ierr = PetscViewerDrawBaseAdd(viewer,-cnt);CHKERRQ(ierr);
80547c6ae99SBarry Smith   }
80647c6ae99SBarry Smith   PetscFunctionReturn(0);
80747c6ae99SBarry Smith }
80847c6ae99SBarry Smith 
8097087cfbeSBarry Smith PetscErrorCode  DMCreateGlobalVector_Composite(DM dm,Vec *gvec)
81047c6ae99SBarry Smith {
81147c6ae99SBarry Smith   PetscErrorCode ierr;
81247c6ae99SBarry Smith   DM_Composite   *com = (DM_Composite*)dm->data;
81347c6ae99SBarry Smith 
81447c6ae99SBarry Smith   PetscFunctionBegin;
81547c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
816d7bf68aeSBarry Smith   ierr = DMSetUp(dm);CHKERRQ(ierr);
817ce94432eSBarry Smith   ierr = VecCreateMPI(PetscObjectComm((PetscObject)dm),com->n,com->N,gvec);CHKERRQ(ierr);
818c688c046SMatthew G Knepley   ierr = VecSetDM(*gvec, dm);CHKERRQ(ierr);
81947c6ae99SBarry Smith   ierr = VecSetOperation(*gvec,VECOP_VIEW,(void (*)(void))VecView_DMComposite);CHKERRQ(ierr);
82047c6ae99SBarry Smith   PetscFunctionReturn(0);
82147c6ae99SBarry Smith }
82247c6ae99SBarry Smith 
8237087cfbeSBarry Smith PetscErrorCode  DMCreateLocalVector_Composite(DM dm,Vec *lvec)
82447c6ae99SBarry Smith {
82547c6ae99SBarry Smith   PetscErrorCode ierr;
82647c6ae99SBarry Smith   DM_Composite   *com = (DM_Composite*)dm->data;
82747c6ae99SBarry Smith 
82847c6ae99SBarry Smith   PetscFunctionBegin;
82947c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
83047c6ae99SBarry Smith   if (!com->setup) {
831d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
83247c6ae99SBarry Smith   }
833f0e01b1fSVincent Le Chenadec   ierr = VecCreateSeq(PETSC_COMM_SELF,com->nghost,lvec);CHKERRQ(ierr);
834c688c046SMatthew G Knepley   ierr = VecSetDM(*lvec, dm);CHKERRQ(ierr);
83547c6ae99SBarry Smith   PetscFunctionReturn(0);
83647c6ae99SBarry Smith }
83747c6ae99SBarry Smith 
83847c6ae99SBarry Smith /*@C
8399ae5db72SJed Brown     DMCompositeGetISLocalToGlobalMappings - gets an ISLocalToGlobalMapping for each DM in the DMComposite, maps to the composite global space
84047c6ae99SBarry Smith 
84106ebdd98SJed Brown     Collective on DM
84247c6ae99SBarry Smith 
84347c6ae99SBarry Smith     Input Parameter:
84447c6ae99SBarry Smith .    dm - the packer object
84547c6ae99SBarry Smith 
84647c6ae99SBarry Smith     Output Parameters:
8479ae5db72SJed Brown .    ltogs - the individual mappings for each packed vector. Note that this includes
8489ae5db72SJed Brown            all the ghost points that individual ghosted DMDA's may have.
84947c6ae99SBarry Smith 
85047c6ae99SBarry Smith     Level: advanced
85147c6ae99SBarry Smith 
85247c6ae99SBarry Smith     Notes:
8536eb61c8cSJed Brown        Each entry of ltogs should be destroyed with ISLocalToGlobalMappingDestroy(), the ltogs array should be freed with PetscFree().
85447c6ae99SBarry Smith 
8559ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
85647c6ae99SBarry Smith          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetAccess(), DMCompositeScatter(),
85747c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(),DMCompositeGetEntries()
85847c6ae99SBarry Smith 
85947c6ae99SBarry Smith @*/
8607087cfbeSBarry Smith PetscErrorCode  DMCompositeGetISLocalToGlobalMappings(DM dm,ISLocalToGlobalMapping **ltogs)
86147c6ae99SBarry Smith {
86247c6ae99SBarry Smith   PetscErrorCode         ierr;
86347c6ae99SBarry Smith   PetscInt               i,*idx,n,cnt;
86447c6ae99SBarry Smith   struct DMCompositeLink *next;
86547c6ae99SBarry Smith   PetscMPIInt            rank;
86647c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
86747c6ae99SBarry Smith 
86847c6ae99SBarry Smith   PetscFunctionBegin;
86947c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
870728e99d6SJed Brown   ierr = DMSetUp(dm);CHKERRQ(ierr);
871854ce69bSBarry Smith   ierr = PetscMalloc1(com->nDM,ltogs);CHKERRQ(ierr);
87247c6ae99SBarry Smith   next = com->next;
873ce94432eSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
87447c6ae99SBarry Smith 
87547c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
87647c6ae99SBarry Smith   cnt = 0;
87747c6ae99SBarry Smith   while (next) {
8786eb61c8cSJed Brown     ISLocalToGlobalMapping ltog;
8796eb61c8cSJed Brown     PetscMPIInt            size;
88086994e45SJed Brown     const PetscInt         *suboff,*indices;
8816eb61c8cSJed Brown     Vec                    global;
88247c6ae99SBarry Smith 
8836eb61c8cSJed Brown     /* Get sub-DM global indices for each local dof */
8841411c6eeSJed Brown     ierr = DMGetLocalToGlobalMapping(next->dm,&ltog);CHKERRQ(ierr);
8856eb61c8cSJed Brown     ierr = ISLocalToGlobalMappingGetSize(ltog,&n);CHKERRQ(ierr);
88686994e45SJed Brown     ierr = ISLocalToGlobalMappingGetIndices(ltog,&indices);CHKERRQ(ierr);
887785e854fSJed Brown     ierr = PetscMalloc1(n,&idx);CHKERRQ(ierr);
88847c6ae99SBarry Smith 
8896eb61c8cSJed Brown     /* Get the offsets for the sub-DM global vector */
8906eb61c8cSJed Brown     ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
8916eb61c8cSJed Brown     ierr = VecGetOwnershipRanges(global,&suboff);CHKERRQ(ierr);
892ce94432eSBarry Smith     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)global),&size);CHKERRQ(ierr);
8936eb61c8cSJed Brown 
8946eb61c8cSJed Brown     /* Shift the sub-DM definition of the global space to the composite global space */
8956eb61c8cSJed Brown     for (i=0; i<n; i++) {
89686994e45SJed Brown       PetscInt subi = indices[i],lo = 0,hi = size,t;
8976eb61c8cSJed Brown       /* Binary search to find which rank owns subi */
8986eb61c8cSJed Brown       while (hi-lo > 1) {
8996eb61c8cSJed Brown         t = lo + (hi-lo)/2;
9006eb61c8cSJed Brown         if (suboff[t] > subi) hi = t;
9016eb61c8cSJed Brown         else                  lo = t;
9026eb61c8cSJed Brown       }
9036eb61c8cSJed Brown       idx[i] = subi - suboff[lo] + next->grstarts[lo];
9046eb61c8cSJed Brown     }
90586994e45SJed Brown     ierr = ISLocalToGlobalMappingRestoreIndices(ltog,&indices);CHKERRQ(ierr);
906f0413b6fSBarry Smith     ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)dm),1,n,idx,PETSC_OWN_POINTER,&(*ltogs)[cnt]);CHKERRQ(ierr);
9076eb61c8cSJed Brown     ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
90847c6ae99SBarry Smith     next = next->next;
90947c6ae99SBarry Smith     cnt++;
91047c6ae99SBarry Smith   }
91147c6ae99SBarry Smith   PetscFunctionReturn(0);
91247c6ae99SBarry Smith }
91347c6ae99SBarry Smith 
91487c85e80SJed Brown /*@C
9159ae5db72SJed Brown    DMCompositeGetLocalISs - Gets index sets for each component of a composite local vector
91687c85e80SJed Brown 
91787c85e80SJed Brown    Not Collective
91887c85e80SJed Brown 
91987c85e80SJed Brown    Input Arguments:
92087c85e80SJed Brown . dm - composite DM
92187c85e80SJed Brown 
92287c85e80SJed Brown    Output Arguments:
92387c85e80SJed Brown . is - array of serial index sets for each each component of the DMComposite
92487c85e80SJed Brown 
92587c85e80SJed Brown    Level: intermediate
92687c85e80SJed Brown 
92787c85e80SJed Brown    Notes:
92887c85e80SJed Brown    At present, a composite local vector does not normally exist.  This function is used to provide index sets for
92987c85e80SJed Brown    MatGetLocalSubMatrix().  In the future, the scatters for each entry in the DMComposite may be be merged into a single
9309ae5db72SJed Brown    scatter to a composite local vector.  The user should not typically need to know which is being done.
93187c85e80SJed Brown 
93287c85e80SJed Brown    To get the composite global indices at all local points (including ghosts), use DMCompositeGetISLocalToGlobalMappings().
93387c85e80SJed Brown 
93487c85e80SJed Brown    To get index sets for pieces of the composite global vector, use DMCompositeGetGlobalISs().
93587c85e80SJed Brown 
93687c85e80SJed Brown    Each returned IS should be destroyed with ISDestroy(), the array should be freed with PetscFree().
93787c85e80SJed Brown 
93887c85e80SJed Brown .seealso: DMCompositeGetGlobalISs(), DMCompositeGetISLocalToGlobalMappings(), MatGetLocalSubMatrix(), MatCreateLocalRef()
93987c85e80SJed Brown @*/
9407087cfbeSBarry Smith PetscErrorCode  DMCompositeGetLocalISs(DM dm,IS **is)
94187c85e80SJed Brown {
94287c85e80SJed Brown   PetscErrorCode         ierr;
94387c85e80SJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
94487c85e80SJed Brown   struct DMCompositeLink *link;
94587c85e80SJed Brown   PetscInt               cnt,start;
94687c85e80SJed Brown 
94787c85e80SJed Brown   PetscFunctionBegin;
94887c85e80SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
94987c85e80SJed Brown   PetscValidPointer(is,2);
950785e854fSJed Brown   ierr = PetscMalloc1(com->nmine,is);CHKERRQ(ierr);
95106ebdd98SJed Brown   for (cnt=0,start=0,link=com->next; link; start+=link->nlocal,cnt++,link=link->next) {
952520db06cSJed Brown     PetscInt bs;
9539ae5db72SJed Brown     ierr = ISCreateStride(PETSC_COMM_SELF,link->nlocal,start,1,&(*is)[cnt]);CHKERRQ(ierr);
9541411c6eeSJed Brown     ierr = DMGetBlockSize(link->dm,&bs);CHKERRQ(ierr);
955520db06cSJed Brown     ierr = ISSetBlockSize((*is)[cnt],bs);CHKERRQ(ierr);
956520db06cSJed Brown   }
95787c85e80SJed Brown   PetscFunctionReturn(0);
95887c85e80SJed Brown }
95987c85e80SJed Brown 
96047c6ae99SBarry Smith /*@C
96147c6ae99SBarry Smith     DMCompositeGetGlobalISs - Gets the index sets for each composed object
96247c6ae99SBarry Smith 
96347c6ae99SBarry Smith     Collective on DMComposite
96447c6ae99SBarry Smith 
96547c6ae99SBarry Smith     Input Parameter:
96647c6ae99SBarry Smith .    dm - the packer object
96747c6ae99SBarry Smith 
96847c6ae99SBarry Smith     Output Parameters:
96947c6ae99SBarry Smith .    is - the array of index sets
97047c6ae99SBarry Smith 
97147c6ae99SBarry Smith     Level: advanced
97247c6ae99SBarry Smith 
97347c6ae99SBarry Smith     Notes:
97447c6ae99SBarry Smith        The is entries should be destroyed with ISDestroy(), the is array should be freed with PetscFree()
97547c6ae99SBarry Smith 
97647c6ae99SBarry Smith        These could be used to extract a subset of vector entries for a "multi-physics" preconditioner
97747c6ae99SBarry Smith 
9786eb61c8cSJed Brown        Use DMCompositeGetLocalISs() for index sets in the packed local numbering, and
9796eb61c8cSJed Brown        DMCompositeGetISLocalToGlobalMappings() for to map local sub-DM (including ghost) indices to packed global
9806eb61c8cSJed Brown        indices.
98147c6ae99SBarry Smith 
982f3cb0f7eSJed Brown     Fortran Notes:
983f3cb0f7eSJed Brown 
984f3cb0f7eSJed Brown        The output argument 'is' must be an allocated array of sufficient length, which can be learned using DMCompositeGetNumberDM().
985f3cb0f7eSJed Brown 
9869ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
98747c6ae99SBarry Smith          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetAccess(), DMCompositeScatter(),
98847c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(),DMCompositeGetEntries()
98947c6ae99SBarry Smith 
99047c6ae99SBarry Smith @*/
9917087cfbeSBarry Smith PetscErrorCode  DMCompositeGetGlobalISs(DM dm,IS *is[])
99247c6ae99SBarry Smith {
99347c6ae99SBarry Smith   PetscErrorCode         ierr;
99466bb578eSMark Adams   PetscInt               cnt = 0;
99547c6ae99SBarry Smith   struct DMCompositeLink *next;
99647c6ae99SBarry Smith   PetscMPIInt            rank;
99747c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
99847c6ae99SBarry Smith 
99947c6ae99SBarry Smith   PetscFunctionBegin;
100047c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1001854ce69bSBarry Smith   ierr = PetscMalloc1(com->nDM,is);CHKERRQ(ierr);
100247c6ae99SBarry Smith   next = com->next;
1003ce94432eSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
100447c6ae99SBarry Smith 
100547c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
100647c6ae99SBarry Smith   while (next) {
100766bb578eSMark Adams     ierr = ISCreateStride(PetscObjectComm((PetscObject)dm),next->n,next->grstart,1,&(*is)[cnt]);CHKERRQ(ierr);
10080f21e855SMatthew G. Knepley     if (dm->prob) {
100965c226d8SMatthew G. Knepley       MatNullSpace space;
101065c226d8SMatthew G. Knepley       Mat          pmat;
10110f21e855SMatthew G. Knepley       PetscObject  disc;
10120f21e855SMatthew G. Knepley       PetscInt     Nf;
101365c226d8SMatthew G. Knepley 
10142764a2aaSMatthew G. Knepley       ierr = PetscDSGetNumFields(dm->prob, &Nf);CHKERRQ(ierr);
1015f24dd8d2SMatthew G. Knepley       if (cnt < Nf) {
10162764a2aaSMatthew G. Knepley         ierr = PetscDSGetDiscretization(dm->prob, cnt, &disc);CHKERRQ(ierr);
10170f21e855SMatthew G. Knepley         ierr = PetscObjectQuery(disc, "nullspace", (PetscObject*) &space);CHKERRQ(ierr);
1018aac2dd2dSMatthew G. Knepley         if (space) {ierr = PetscObjectCompose((PetscObject) (*is)[cnt], "nullspace", (PetscObject) space);CHKERRQ(ierr);}
10190f21e855SMatthew G. Knepley         ierr = PetscObjectQuery(disc, "nearnullspace", (PetscObject*) &space);CHKERRQ(ierr);
1020aac2dd2dSMatthew G. Knepley         if (space) {ierr = PetscObjectCompose((PetscObject) (*is)[cnt], "nearnullspace", (PetscObject) space);CHKERRQ(ierr);}
10210f21e855SMatthew G. Knepley         ierr = PetscObjectQuery(disc, "pmat", (PetscObject*) &pmat);CHKERRQ(ierr);
1022aac2dd2dSMatthew G. Knepley         if (pmat) {ierr = PetscObjectCompose((PetscObject) (*is)[cnt], "pmat", (PetscObject) pmat);CHKERRQ(ierr);}
102365c226d8SMatthew G. Knepley       }
1024f24dd8d2SMatthew G. Knepley     }
102547c6ae99SBarry Smith     cnt++;
102647c6ae99SBarry Smith     next = next->next;
102747c6ae99SBarry Smith   }
102847c6ae99SBarry Smith   PetscFunctionReturn(0);
102947c6ae99SBarry Smith }
103047c6ae99SBarry Smith 
103121c9b008SJed Brown PetscErrorCode DMCreateFieldIS_Composite(DM dm, PetscInt *numFields,char ***fieldNames, IS **fields)
10324d343eeaSMatthew G Knepley {
10334d343eeaSMatthew G Knepley   PetscInt       nDM;
10344d343eeaSMatthew G Knepley   DM             *dms;
10354d343eeaSMatthew G Knepley   PetscInt       i;
10364d343eeaSMatthew G Knepley   PetscErrorCode ierr;
10374d343eeaSMatthew G Knepley 
10384d343eeaSMatthew G Knepley   PetscFunctionBegin;
10394d343eeaSMatthew G Knepley   ierr = DMCompositeGetNumberDM(dm, &nDM);CHKERRQ(ierr);
10408865f1eaSKarl Rupp   if (numFields) *numFields = nDM;
10414d343eeaSMatthew G Knepley   ierr = DMCompositeGetGlobalISs(dm, fields);CHKERRQ(ierr);
10424d343eeaSMatthew G Knepley   if (fieldNames) {
1043785e854fSJed Brown     ierr = PetscMalloc1(nDM, &dms);CHKERRQ(ierr);
1044785e854fSJed Brown     ierr = PetscMalloc1(nDM, fieldNames);CHKERRQ(ierr);
10454d343eeaSMatthew G Knepley     ierr = DMCompositeGetEntriesArray(dm, dms);CHKERRQ(ierr);
10464d343eeaSMatthew G Knepley     for (i=0; i<nDM; i++) {
10474d343eeaSMatthew G Knepley       char       buf[256];
10484d343eeaSMatthew G Knepley       const char *splitname;
10494d343eeaSMatthew G Knepley 
10504d343eeaSMatthew G Knepley       /* Split naming precedence: object name, prefix, number */
10514d343eeaSMatthew G Knepley       splitname = ((PetscObject) dm)->name;
10524d343eeaSMatthew G Knepley       if (!splitname) {
10534d343eeaSMatthew G Knepley         ierr = PetscObjectGetOptionsPrefix((PetscObject)dms[i],&splitname);CHKERRQ(ierr);
10544d343eeaSMatthew G Knepley         if (splitname) {
10554d343eeaSMatthew G Knepley           size_t len;
10568caf3d72SBarry Smith           ierr                 = PetscStrncpy(buf,splitname,sizeof(buf));CHKERRQ(ierr);
10578caf3d72SBarry Smith           buf[sizeof(buf) - 1] = 0;
10584d343eeaSMatthew G Knepley           ierr                 = PetscStrlen(buf,&len);CHKERRQ(ierr);
10594d343eeaSMatthew G Knepley           if (buf[len-1] == '_') buf[len-1] = 0; /* Remove trailing underscore if it was used */
10604d343eeaSMatthew G Knepley           splitname = buf;
10614d343eeaSMatthew G Knepley         }
10624d343eeaSMatthew G Knepley       }
10634d343eeaSMatthew G Knepley       if (!splitname) {
10648caf3d72SBarry Smith         ierr      = PetscSNPrintf(buf,sizeof(buf),"%D",i);CHKERRQ(ierr);
10654d343eeaSMatthew G Knepley         splitname = buf;
10664d343eeaSMatthew G Knepley       }
106721c9b008SJed Brown       ierr = PetscStrallocpy(splitname,&(*fieldNames)[i]);CHKERRQ(ierr);
10684d343eeaSMatthew G Knepley     }
10694d343eeaSMatthew G Knepley     ierr = PetscFree(dms);CHKERRQ(ierr);
10704d343eeaSMatthew G Knepley   }
10714d343eeaSMatthew G Knepley   PetscFunctionReturn(0);
10724d343eeaSMatthew G Knepley }
10734d343eeaSMatthew G Knepley 
1074e7c4fc90SDmitry Karpeev /*
1075e7c4fc90SDmitry Karpeev  This could take over from DMCreateFieldIS(), as it is more general,
10760298fd71SBarry Smith  making DMCreateFieldIS() a special case -- calling with dmlist == NULL;
1077e7c4fc90SDmitry Karpeev  At this point it's probably best to be less intrusive, however.
1078e7c4fc90SDmitry Karpeev  */
107916621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecomposition_Composite(DM dm, PetscInt *len,char ***namelist, IS **islist, DM **dmlist)
1080e7c4fc90SDmitry Karpeev {
1081e7c4fc90SDmitry Karpeev   PetscInt       nDM;
1082e7c4fc90SDmitry Karpeev   PetscInt       i;
1083e7c4fc90SDmitry Karpeev   PetscErrorCode ierr;
1084e7c4fc90SDmitry Karpeev 
1085e7c4fc90SDmitry Karpeev   PetscFunctionBegin;
1086e7c4fc90SDmitry Karpeev   ierr = DMCreateFieldIS_Composite(dm, len, namelist, islist);CHKERRQ(ierr);
1087e7c4fc90SDmitry Karpeev   if (dmlist) {
1088e7c4fc90SDmitry Karpeev     ierr = DMCompositeGetNumberDM(dm, &nDM);CHKERRQ(ierr);
1089785e854fSJed Brown     ierr = PetscMalloc1(nDM, dmlist);CHKERRQ(ierr);
1090e7c4fc90SDmitry Karpeev     ierr = DMCompositeGetEntriesArray(dm, *dmlist);CHKERRQ(ierr);
1091e7c4fc90SDmitry Karpeev     for (i=0; i<nDM; i++) {
1092e7c4fc90SDmitry Karpeev       ierr = PetscObjectReference((PetscObject)((*dmlist)[i]));CHKERRQ(ierr);
1093e7c4fc90SDmitry Karpeev     }
1094e7c4fc90SDmitry Karpeev   }
1095e7c4fc90SDmitry Karpeev   PetscFunctionReturn(0);
1096e7c4fc90SDmitry Karpeev }
1097e7c4fc90SDmitry Karpeev 
1098e7c4fc90SDmitry Karpeev 
1099e7c4fc90SDmitry Karpeev 
110047c6ae99SBarry Smith /* -------------------------------------------------------------------------------------*/
110147c6ae99SBarry Smith /*@C
11029ae5db72SJed Brown     DMCompositeGetLocalVectors - Gets local vectors for each part of a DMComposite.
110347c6ae99SBarry Smith        Use DMCompositeRestoreLocalVectors() to return them.
110447c6ae99SBarry Smith 
110547c6ae99SBarry Smith     Not Collective
110647c6ae99SBarry Smith 
110747c6ae99SBarry Smith     Input Parameter:
110847c6ae99SBarry Smith .    dm - the packer object
110947c6ae99SBarry Smith 
111047c6ae99SBarry Smith     Output Parameter:
11119ae5db72SJed Brown .   Vec ... - the individual sequential Vecs
111247c6ae99SBarry Smith 
111347c6ae99SBarry Smith     Level: advanced
111447c6ae99SBarry Smith 
11159ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
11166eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
111747c6ae99SBarry Smith          DMCompositeRestoreLocalVectors(), DMCompositeScatter(), DMCompositeGetEntries()
111847c6ae99SBarry Smith 
111947c6ae99SBarry Smith @*/
11207087cfbeSBarry Smith PetscErrorCode  DMCompositeGetLocalVectors(DM dm,...)
112147c6ae99SBarry Smith {
112247c6ae99SBarry Smith   va_list                Argp;
112347c6ae99SBarry Smith   PetscErrorCode         ierr;
112447c6ae99SBarry Smith   struct DMCompositeLink *next;
112547c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
112647c6ae99SBarry Smith 
112747c6ae99SBarry Smith   PetscFunctionBegin;
112847c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
112947c6ae99SBarry Smith   next = com->next;
113047c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
113147c6ae99SBarry Smith   va_start(Argp,dm);
113247c6ae99SBarry Smith   while (next) {
113347c6ae99SBarry Smith     Vec *vec;
113447c6ae99SBarry Smith     vec = va_arg(Argp, Vec*);
113506930112SJed Brown     if (vec) {ierr = DMGetLocalVector(next->dm,vec);CHKERRQ(ierr);}
113647c6ae99SBarry Smith     next = next->next;
113747c6ae99SBarry Smith   }
113847c6ae99SBarry Smith   va_end(Argp);
113947c6ae99SBarry Smith   PetscFunctionReturn(0);
114047c6ae99SBarry Smith }
114147c6ae99SBarry Smith 
114247c6ae99SBarry Smith /*@C
11439ae5db72SJed Brown     DMCompositeRestoreLocalVectors - Restores local vectors for each part of a DMComposite.
114447c6ae99SBarry Smith 
114547c6ae99SBarry Smith     Not Collective
114647c6ae99SBarry Smith 
114747c6ae99SBarry Smith     Input Parameter:
114847c6ae99SBarry Smith .    dm - the packer object
114947c6ae99SBarry Smith 
115047c6ae99SBarry Smith     Output Parameter:
11519ae5db72SJed Brown .   Vec ... - the individual sequential Vecs
115247c6ae99SBarry Smith 
115347c6ae99SBarry Smith     Level: advanced
115447c6ae99SBarry Smith 
11559ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
11566eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
115747c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeScatter(), DMCompositeGetEntries()
115847c6ae99SBarry Smith 
115947c6ae99SBarry Smith @*/
11607087cfbeSBarry Smith PetscErrorCode  DMCompositeRestoreLocalVectors(DM dm,...)
116147c6ae99SBarry Smith {
116247c6ae99SBarry Smith   va_list                Argp;
116347c6ae99SBarry Smith   PetscErrorCode         ierr;
116447c6ae99SBarry Smith   struct DMCompositeLink *next;
116547c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
116647c6ae99SBarry Smith 
116747c6ae99SBarry Smith   PetscFunctionBegin;
116847c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
116947c6ae99SBarry Smith   next = com->next;
117047c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
117147c6ae99SBarry Smith   va_start(Argp,dm);
117247c6ae99SBarry Smith   while (next) {
117347c6ae99SBarry Smith     Vec *vec;
117447c6ae99SBarry Smith     vec = va_arg(Argp, Vec*);
117506930112SJed Brown     if (vec) {ierr = DMRestoreLocalVector(next->dm,vec);CHKERRQ(ierr);}
117647c6ae99SBarry Smith     next = next->next;
117747c6ae99SBarry Smith   }
117847c6ae99SBarry Smith   va_end(Argp);
117947c6ae99SBarry Smith   PetscFunctionReturn(0);
118047c6ae99SBarry Smith }
118147c6ae99SBarry Smith 
118247c6ae99SBarry Smith /* -------------------------------------------------------------------------------------*/
118347c6ae99SBarry Smith /*@C
11849ae5db72SJed Brown     DMCompositeGetEntries - Gets the DM for each entry in a DMComposite.
118547c6ae99SBarry Smith 
118647c6ae99SBarry Smith     Not Collective
118747c6ae99SBarry Smith 
118847c6ae99SBarry Smith     Input Parameter:
118947c6ae99SBarry Smith .    dm - the packer object
119047c6ae99SBarry Smith 
119147c6ae99SBarry Smith     Output Parameter:
11929ae5db72SJed Brown .   DM ... - the individual entries (DMs)
119347c6ae99SBarry Smith 
119447c6ae99SBarry Smith     Level: advanced
119547c6ae99SBarry Smith 
11962fa5ba8aSJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), DMCompositeGetEntriesArray()
11976eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
119847c6ae99SBarry Smith          DMCompositeRestoreLocalVectors(), DMCompositeGetLocalVectors(),  DMCompositeScatter(),
119947c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors()
120047c6ae99SBarry Smith 
120147c6ae99SBarry Smith @*/
12027087cfbeSBarry Smith PetscErrorCode  DMCompositeGetEntries(DM dm,...)
120347c6ae99SBarry Smith {
120447c6ae99SBarry Smith   va_list                Argp;
120547c6ae99SBarry Smith   struct DMCompositeLink *next;
120647c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
120747c6ae99SBarry Smith 
120847c6ae99SBarry Smith   PetscFunctionBegin;
120947c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
121047c6ae99SBarry Smith   next = com->next;
121147c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
121247c6ae99SBarry Smith   va_start(Argp,dm);
121347c6ae99SBarry Smith   while (next) {
121447c6ae99SBarry Smith     DM *dmn;
121547c6ae99SBarry Smith     dmn = va_arg(Argp, DM*);
12169ae5db72SJed Brown     if (dmn) *dmn = next->dm;
121747c6ae99SBarry Smith     next = next->next;
121847c6ae99SBarry Smith   }
121947c6ae99SBarry Smith   va_end(Argp);
122047c6ae99SBarry Smith   PetscFunctionReturn(0);
122147c6ae99SBarry Smith }
122247c6ae99SBarry Smith 
1223dbab29e1SMark F. Adams /*@C
12242fa5ba8aSJed Brown     DMCompositeGetEntriesArray - Gets the DM for each entry in a DMComposite.
12252fa5ba8aSJed Brown 
12262fa5ba8aSJed Brown     Not Collective
12272fa5ba8aSJed Brown 
12282fa5ba8aSJed Brown     Input Parameter:
1229907376e6SBarry Smith .    dm - the packer object
1230907376e6SBarry Smith 
1231907376e6SBarry Smith     Output Parameter:
1232907376e6SBarry Smith .    dms - array of sufficient length (see DMCompositeGetNumberDM()) to hold the individual DMs
12332fa5ba8aSJed Brown 
12342fa5ba8aSJed Brown     Level: advanced
12352fa5ba8aSJed Brown 
12362fa5ba8aSJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), DMCompositeGetEntries()
12372fa5ba8aSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
12382fa5ba8aSJed Brown          DMCompositeRestoreLocalVectors(), DMCompositeGetLocalVectors(),  DMCompositeScatter(),
12392fa5ba8aSJed Brown          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors()
12402fa5ba8aSJed Brown 
12412fa5ba8aSJed Brown @*/
12422fa5ba8aSJed Brown PetscErrorCode DMCompositeGetEntriesArray(DM dm,DM dms[])
12432fa5ba8aSJed Brown {
12442fa5ba8aSJed Brown   struct DMCompositeLink *next;
12452fa5ba8aSJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
12462fa5ba8aSJed Brown   PetscInt               i;
12472fa5ba8aSJed Brown 
12482fa5ba8aSJed Brown   PetscFunctionBegin;
12492fa5ba8aSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
12502fa5ba8aSJed Brown   /* loop over packed objects, handling one at at time */
12512fa5ba8aSJed Brown   for (next=com->next,i=0; next; next=next->next,i++) dms[i] = next->dm;
12522fa5ba8aSJed Brown   PetscFunctionReturn(0);
12532fa5ba8aSJed Brown }
12542fa5ba8aSJed Brown 
12557087cfbeSBarry Smith PetscErrorCode  DMRefine_Composite(DM dmi,MPI_Comm comm,DM *fine)
125647c6ae99SBarry Smith {
125747c6ae99SBarry Smith   PetscErrorCode         ierr;
125847c6ae99SBarry Smith   struct DMCompositeLink *next;
125947c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dmi->data;
126047c6ae99SBarry Smith   DM                     dm;
126147c6ae99SBarry Smith 
126247c6ae99SBarry Smith   PetscFunctionBegin;
126347c6ae99SBarry Smith   PetscValidHeaderSpecific(dmi,DM_CLASSID,1);
1264ce94432eSBarry Smith   if (comm == MPI_COMM_NULL) {
1265ce94432eSBarry Smith     ierr = PetscObjectGetComm((PetscObject)dmi,&comm);CHKERRQ(ierr);
1266ce94432eSBarry Smith   }
12672ce3a92bSJed Brown   ierr = DMSetUp(dmi);CHKERRQ(ierr);
126847c6ae99SBarry Smith   next = com->next;
126947c6ae99SBarry Smith   ierr = DMCompositeCreate(comm,fine);CHKERRQ(ierr);
127047c6ae99SBarry Smith 
127147c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
127247c6ae99SBarry Smith   while (next) {
127347c6ae99SBarry Smith     ierr = DMRefine(next->dm,comm,&dm);CHKERRQ(ierr);
127447c6ae99SBarry Smith     ierr = DMCompositeAddDM(*fine,dm);CHKERRQ(ierr);
127547c6ae99SBarry Smith     ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr);
127647c6ae99SBarry Smith     next = next->next;
127747c6ae99SBarry Smith   }
127847c6ae99SBarry Smith   PetscFunctionReturn(0);
127947c6ae99SBarry Smith }
128047c6ae99SBarry Smith 
128114354c39SJed Brown PetscErrorCode  DMCoarsen_Composite(DM dmi,MPI_Comm comm,DM *fine)
128214354c39SJed Brown {
128314354c39SJed Brown   PetscErrorCode         ierr;
128414354c39SJed Brown   struct DMCompositeLink *next;
128514354c39SJed Brown   DM_Composite           *com = (DM_Composite*)dmi->data;
128614354c39SJed Brown   DM                     dm;
128714354c39SJed Brown 
128814354c39SJed Brown   PetscFunctionBegin;
128914354c39SJed Brown   PetscValidHeaderSpecific(dmi,DM_CLASSID,1);
12902ce3a92bSJed Brown   ierr = DMSetUp(dmi);CHKERRQ(ierr);
12912ee06e3bSJed Brown   if (comm == MPI_COMM_NULL) {
129225296bd5SBarry Smith     ierr = PetscObjectGetComm((PetscObject)dmi,&comm);CHKERRQ(ierr);
129325296bd5SBarry Smith   }
129414354c39SJed Brown   next = com->next;
129514354c39SJed Brown   ierr = DMCompositeCreate(comm,fine);CHKERRQ(ierr);
129614354c39SJed Brown 
129714354c39SJed Brown   /* loop over packed objects, handling one at at time */
129814354c39SJed Brown   while (next) {
129914354c39SJed Brown     ierr = DMCoarsen(next->dm,comm,&dm);CHKERRQ(ierr);
130014354c39SJed Brown     ierr = DMCompositeAddDM(*fine,dm);CHKERRQ(ierr);
130114354c39SJed Brown     ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr);
130214354c39SJed Brown     next = next->next;
130314354c39SJed Brown   }
130414354c39SJed Brown   PetscFunctionReturn(0);
130514354c39SJed Brown }
130647c6ae99SBarry Smith 
1307e727c939SJed Brown PetscErrorCode  DMCreateInterpolation_Composite(DM coarse,DM fine,Mat *A,Vec *v)
130847c6ae99SBarry Smith {
130947c6ae99SBarry Smith   PetscErrorCode         ierr;
13109ae5db72SJed Brown   PetscInt               m,n,M,N,nDM,i;
131147c6ae99SBarry Smith   struct DMCompositeLink *nextc;
131247c6ae99SBarry Smith   struct DMCompositeLink *nextf;
131325296bd5SBarry Smith   Vec                    gcoarse,gfine,*vecs;
131447c6ae99SBarry Smith   DM_Composite           *comcoarse = (DM_Composite*)coarse->data;
131547c6ae99SBarry Smith   DM_Composite           *comfine   = (DM_Composite*)fine->data;
13169ae5db72SJed Brown   Mat                    *mats;
131747c6ae99SBarry Smith 
131847c6ae99SBarry Smith   PetscFunctionBegin;
131947c6ae99SBarry Smith   PetscValidHeaderSpecific(coarse,DM_CLASSID,1);
132047c6ae99SBarry Smith   PetscValidHeaderSpecific(fine,DM_CLASSID,2);
1321f692024eSJed Brown   ierr = DMSetUp(coarse);CHKERRQ(ierr);
1322f692024eSJed Brown   ierr = DMSetUp(fine);CHKERRQ(ierr);
132347c6ae99SBarry Smith   /* use global vectors only for determining matrix layout */
13249ae5db72SJed Brown   ierr = DMGetGlobalVector(coarse,&gcoarse);CHKERRQ(ierr);
13259ae5db72SJed Brown   ierr = DMGetGlobalVector(fine,&gfine);CHKERRQ(ierr);
132647c6ae99SBarry Smith   ierr = VecGetLocalSize(gcoarse,&n);CHKERRQ(ierr);
132747c6ae99SBarry Smith   ierr = VecGetLocalSize(gfine,&m);CHKERRQ(ierr);
132847c6ae99SBarry Smith   ierr = VecGetSize(gcoarse,&N);CHKERRQ(ierr);
132947c6ae99SBarry Smith   ierr = VecGetSize(gfine,&M);CHKERRQ(ierr);
13309ae5db72SJed Brown   ierr = DMRestoreGlobalVector(coarse,&gcoarse);CHKERRQ(ierr);
13319ae5db72SJed Brown   ierr = DMRestoreGlobalVector(fine,&gfine);CHKERRQ(ierr);
133247c6ae99SBarry Smith 
13339ae5db72SJed Brown   nDM = comfine->nDM;
1334ce94432eSBarry 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);
13351795a4d1SJed Brown   ierr = PetscCalloc1(nDM*nDM,&mats);CHKERRQ(ierr);
133625296bd5SBarry Smith   if (v) {
13371795a4d1SJed Brown     ierr = PetscCalloc1(nDM,&vecs);CHKERRQ(ierr);
133825296bd5SBarry Smith   }
133947c6ae99SBarry Smith 
134047c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
13419ae5db72SJed Brown   for (nextc=comcoarse->next,nextf=comfine->next,i=0; nextc; nextc=nextc->next,nextf=nextf->next,i++) {
134225296bd5SBarry Smith     if (!v) {
13430298fd71SBarry Smith       ierr = DMCreateInterpolation(nextc->dm,nextf->dm,&mats[i*nDM+i],NULL);CHKERRQ(ierr);
134425296bd5SBarry Smith     } else {
134525296bd5SBarry Smith       ierr = DMCreateInterpolation(nextc->dm,nextf->dm,&mats[i*nDM+i],&vecs[i]);CHKERRQ(ierr);
134625296bd5SBarry Smith     }
134747c6ae99SBarry Smith   }
1348ce94432eSBarry Smith   ierr = MatCreateNest(PetscObjectComm((PetscObject)fine),nDM,NULL,nDM,NULL,mats,A);CHKERRQ(ierr);
134925296bd5SBarry Smith   if (v) {
1350ce94432eSBarry Smith     ierr = VecCreateNest(PetscObjectComm((PetscObject)fine),nDM,NULL,vecs,v);CHKERRQ(ierr);
135125296bd5SBarry Smith   }
13529ae5db72SJed Brown   for (i=0; i<nDM*nDM; i++) {ierr = MatDestroy(&mats[i]);CHKERRQ(ierr);}
13539ae5db72SJed Brown   ierr = PetscFree(mats);CHKERRQ(ierr);
135425296bd5SBarry Smith   if (v) {
135525296bd5SBarry Smith     for (i=0; i<nDM; i++) {ierr = VecDestroy(&vecs[i]);CHKERRQ(ierr);}
135625296bd5SBarry Smith     ierr = PetscFree(vecs);CHKERRQ(ierr);
135725296bd5SBarry Smith   }
135847c6ae99SBarry Smith   PetscFunctionReturn(0);
135947c6ae99SBarry Smith }
136047c6ae99SBarry Smith 
1361184d77edSJed Brown static PetscErrorCode DMGetLocalToGlobalMapping_Composite(DM dm)
13621411c6eeSJed Brown {
13631411c6eeSJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
13641411c6eeSJed Brown   ISLocalToGlobalMapping *ltogs;
1365f7efa3c7SJed Brown   PetscInt               i;
13661411c6eeSJed Brown   PetscErrorCode         ierr;
13671411c6eeSJed Brown 
13681411c6eeSJed Brown   PetscFunctionBegin;
13691411c6eeSJed Brown   /* Set the ISLocalToGlobalMapping on the new matrix */
13701411c6eeSJed Brown   ierr = DMCompositeGetISLocalToGlobalMappings(dm,&ltogs);CHKERRQ(ierr);
1371ce94432eSBarry Smith   ierr = ISLocalToGlobalMappingConcatenate(PetscObjectComm((PetscObject)dm),com->nDM,ltogs,&dm->ltogmap);CHKERRQ(ierr);
13729ae5db72SJed Brown   for (i=0; i<com->nDM; i++) {ierr = ISLocalToGlobalMappingDestroy(&ltogs[i]);CHKERRQ(ierr);}
13731411c6eeSJed Brown   ierr = PetscFree(ltogs);CHKERRQ(ierr);
13741411c6eeSJed Brown   PetscFunctionReturn(0);
13751411c6eeSJed Brown }
13761411c6eeSJed Brown 
13771411c6eeSJed Brown 
1378b412c318SBarry Smith PetscErrorCode  DMCreateColoring_Composite(DM dm,ISColoringType ctype,ISColoring *coloring)
137947c6ae99SBarry Smith {
138047c6ae99SBarry Smith   PetscErrorCode  ierr;
138147c6ae99SBarry Smith   PetscInt        n,i,cnt;
138247c6ae99SBarry Smith   ISColoringValue *colors;
138347c6ae99SBarry Smith   PetscBool       dense  = PETSC_FALSE;
138447c6ae99SBarry Smith   ISColoringValue maxcol = 0;
138547c6ae99SBarry Smith   DM_Composite    *com   = (DM_Composite*)dm->data;
138647c6ae99SBarry Smith 
138747c6ae99SBarry Smith   PetscFunctionBegin;
138847c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
13895bdb020cSBarry Smith   if (ctype == IS_COLORING_LOCAL) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only global coloring supported");
1390e3247f34SBarry Smith   else if (ctype == IS_COLORING_GLOBAL) {
139147c6ae99SBarry Smith     n = com->n;
1392ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"Unknown ISColoringType");
1393785e854fSJed Brown   ierr = PetscMalloc1(n,&colors);CHKERRQ(ierr); /* freed in ISColoringDestroy() */
139447c6ae99SBarry Smith 
1395c5929fdfSBarry Smith   ierr = PetscOptionsGetBool(((PetscObject)dm)->options,((PetscObject)dm)->prefix,"-dmcomposite_dense_jacobian",&dense,NULL);CHKERRQ(ierr);
139647c6ae99SBarry Smith   if (dense) {
139747c6ae99SBarry Smith     for (i=0; i<n; i++) {
139847c6ae99SBarry Smith       colors[i] = (ISColoringValue)(com->rstart + i);
139947c6ae99SBarry Smith     }
140047c6ae99SBarry Smith     maxcol = com->N;
140147c6ae99SBarry Smith   } else {
140247c6ae99SBarry Smith     struct DMCompositeLink *next = com->next;
140347c6ae99SBarry Smith     PetscMPIInt            rank;
140447c6ae99SBarry Smith 
1405ce94432eSBarry Smith     ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
140647c6ae99SBarry Smith     cnt  = 0;
140747c6ae99SBarry Smith     while (next) {
140847c6ae99SBarry Smith       ISColoring lcoloring;
140947c6ae99SBarry Smith 
1410b412c318SBarry Smith       ierr = DMCreateColoring(next->dm,IS_COLORING_GLOBAL,&lcoloring);CHKERRQ(ierr);
141147c6ae99SBarry Smith       for (i=0; i<lcoloring->N; i++) {
141247c6ae99SBarry Smith         colors[cnt++] = maxcol + lcoloring->colors[i];
141347c6ae99SBarry Smith       }
141447c6ae99SBarry Smith       maxcol += lcoloring->n;
1415fcfd50ebSBarry Smith       ierr    = ISColoringDestroy(&lcoloring);CHKERRQ(ierr);
141647c6ae99SBarry Smith       next    = next->next;
141747c6ae99SBarry Smith     }
141847c6ae99SBarry Smith   }
1419aaf3ff59SMatthew G. Knepley   ierr = ISColoringCreate(PetscObjectComm((PetscObject)dm),maxcol,n,colors,PETSC_OWN_POINTER,coloring);CHKERRQ(ierr);
142047c6ae99SBarry Smith   PetscFunctionReturn(0);
142147c6ae99SBarry Smith }
142247c6ae99SBarry Smith 
14237087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalBegin_Composite(DM dm,Vec gvec,InsertMode mode,Vec lvec)
142447c6ae99SBarry Smith {
142547c6ae99SBarry Smith   PetscErrorCode         ierr;
142647c6ae99SBarry Smith   struct DMCompositeLink *next;
142747c6ae99SBarry Smith   PetscScalar            *garray,*larray;
142847c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
142947c6ae99SBarry Smith 
143047c6ae99SBarry Smith   PetscFunctionBegin;
143147c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
143247c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
143339d35262SVincent Le Chenadec 
143447c6ae99SBarry Smith   if (!com->setup) {
1435d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
143647c6ae99SBarry Smith   }
143739d35262SVincent Le Chenadec 
143847c6ae99SBarry Smith   ierr = VecGetArray(gvec,&garray);CHKERRQ(ierr);
143947c6ae99SBarry Smith   ierr = VecGetArray(lvec,&larray);CHKERRQ(ierr);
144047c6ae99SBarry Smith 
144147c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
144239d35262SVincent Le Chenadec   next = com->next;
144347c6ae99SBarry Smith   while (next) {
144447c6ae99SBarry Smith     Vec      local,global;
144547c6ae99SBarry Smith     PetscInt N;
144647c6ae99SBarry Smith 
144747c6ae99SBarry Smith     ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
144847c6ae99SBarry Smith     ierr = VecGetLocalSize(global,&N);CHKERRQ(ierr);
144947c6ae99SBarry Smith     ierr = VecPlaceArray(global,garray);CHKERRQ(ierr);
145047c6ae99SBarry Smith     ierr = DMGetLocalVector(next->dm,&local);CHKERRQ(ierr);
145147c6ae99SBarry Smith     ierr = VecPlaceArray(local,larray);CHKERRQ(ierr);
145247c6ae99SBarry Smith     ierr = DMGlobalToLocalBegin(next->dm,global,mode,local);CHKERRQ(ierr);
145347c6ae99SBarry Smith     ierr = DMGlobalToLocalEnd(next->dm,global,mode,local);CHKERRQ(ierr);
145447c6ae99SBarry Smith     ierr = VecResetArray(global);CHKERRQ(ierr);
145547c6ae99SBarry Smith     ierr = VecResetArray(local);CHKERRQ(ierr);
145647c6ae99SBarry Smith     ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
145739d35262SVincent Le Chenadec     ierr = DMRestoreLocalVector(next->dm,&local);CHKERRQ(ierr);
145839d35262SVincent Le Chenadec 
145906ebdd98SJed Brown     larray += next->nlocal;
146039d35262SVincent Le Chenadec     garray += next->n;
146147c6ae99SBarry Smith     next    = next->next;
146247c6ae99SBarry Smith   }
146347c6ae99SBarry Smith 
14640298fd71SBarry Smith   ierr = VecRestoreArray(gvec,NULL);CHKERRQ(ierr);
14650298fd71SBarry Smith   ierr = VecRestoreArray(lvec,NULL);CHKERRQ(ierr);
146647c6ae99SBarry Smith   PetscFunctionReturn(0);
146747c6ae99SBarry Smith }
146847c6ae99SBarry Smith 
14697087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalEnd_Composite(DM dm,Vec gvec,InsertMode mode,Vec lvec)
14700c010503SBarry Smith {
14710c010503SBarry Smith   PetscFunctionBegin;
147239d35262SVincent Le Chenadec   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
147339d35262SVincent Le Chenadec   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
147439d35262SVincent Le Chenadec   PetscValidHeaderSpecific(lvec,VEC_CLASSID,4);
147539d35262SVincent Le Chenadec   PetscFunctionReturn(0);
147639d35262SVincent Le Chenadec }
147739d35262SVincent Le Chenadec 
147839d35262SVincent Le Chenadec PetscErrorCode  DMLocalToGlobalBegin_Composite(DM dm,Vec lvec,InsertMode mode,Vec gvec)
147939d35262SVincent Le Chenadec {
148039d35262SVincent Le Chenadec   PetscErrorCode         ierr;
148139d35262SVincent Le Chenadec   struct DMCompositeLink *next;
148239d35262SVincent Le Chenadec   PetscScalar            *larray,*garray;
148339d35262SVincent Le Chenadec   DM_Composite           *com = (DM_Composite*)dm->data;
148439d35262SVincent Le Chenadec 
148539d35262SVincent Le Chenadec   PetscFunctionBegin;
148639d35262SVincent Le Chenadec   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
148739d35262SVincent Le Chenadec   PetscValidHeaderSpecific(lvec,VEC_CLASSID,2);
148839d35262SVincent Le Chenadec   PetscValidHeaderSpecific(gvec,VEC_CLASSID,4);
148939d35262SVincent Le Chenadec 
149039d35262SVincent Le Chenadec   if (!com->setup) {
149139d35262SVincent Le Chenadec     ierr = DMSetUp(dm);CHKERRQ(ierr);
149239d35262SVincent Le Chenadec   }
149339d35262SVincent Le Chenadec 
149439d35262SVincent Le Chenadec   ierr = VecGetArray(lvec,&larray);CHKERRQ(ierr);
149539d35262SVincent Le Chenadec   ierr = VecGetArray(gvec,&garray);CHKERRQ(ierr);
149639d35262SVincent Le Chenadec 
149739d35262SVincent Le Chenadec   /* loop over packed objects, handling one at at time */
149839d35262SVincent Le Chenadec   next = com->next;
149939d35262SVincent Le Chenadec   while (next) {
150039d35262SVincent Le Chenadec     Vec      global,local;
150139d35262SVincent Le Chenadec 
150239d35262SVincent Le Chenadec     ierr = DMGetLocalVector(next->dm,&local);CHKERRQ(ierr);
150339d35262SVincent Le Chenadec     ierr = VecPlaceArray(local,larray);CHKERRQ(ierr);
150439d35262SVincent Le Chenadec     ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
150539d35262SVincent Le Chenadec     ierr = VecPlaceArray(global,garray);CHKERRQ(ierr);
150639d35262SVincent Le Chenadec     ierr = DMLocalToGlobalBegin(next->dm,local,mode,global);CHKERRQ(ierr);
150739d35262SVincent Le Chenadec     ierr = DMLocalToGlobalEnd(next->dm,local,mode,global);CHKERRQ(ierr);
150839d35262SVincent Le Chenadec     ierr = VecResetArray(local);CHKERRQ(ierr);
150939d35262SVincent Le Chenadec     ierr = VecResetArray(global);CHKERRQ(ierr);
151039d35262SVincent Le Chenadec     ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
151139d35262SVincent Le Chenadec     ierr = DMRestoreLocalVector(next->dm,&local);CHKERRQ(ierr);
151239d35262SVincent Le Chenadec 
151339d35262SVincent Le Chenadec     garray += next->n;
151439d35262SVincent Le Chenadec     larray += next->nlocal;
151539d35262SVincent Le Chenadec     next    = next->next;
151639d35262SVincent Le Chenadec   }
151739d35262SVincent Le Chenadec 
151839d35262SVincent Le Chenadec   ierr = VecRestoreArray(gvec,NULL);CHKERRQ(ierr);
151939d35262SVincent Le Chenadec   ierr = VecRestoreArray(lvec,NULL);CHKERRQ(ierr);
152039d35262SVincent Le Chenadec 
152139d35262SVincent Le Chenadec   PetscFunctionReturn(0);
152239d35262SVincent Le Chenadec }
152339d35262SVincent Le Chenadec 
152439d35262SVincent Le Chenadec PetscErrorCode  DMLocalToGlobalEnd_Composite(DM dm,Vec lvec,InsertMode mode,Vec gvec)
152539d35262SVincent Le Chenadec {
152639d35262SVincent Le Chenadec   PetscFunctionBegin;
152739d35262SVincent Le Chenadec   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
152839d35262SVincent Le Chenadec   PetscValidHeaderSpecific(lvec,VEC_CLASSID,2);
152939d35262SVincent Le Chenadec   PetscValidHeaderSpecific(gvec,VEC_CLASSID,4);
153039d35262SVincent Le Chenadec   PetscFunctionReturn(0);
153139d35262SVincent Le Chenadec }
153239d35262SVincent Le Chenadec 
153339d35262SVincent Le Chenadec PetscErrorCode  DMLocalToLocalBegin_Composite(DM dm,Vec vec1,InsertMode mode,Vec vec2)
153439d35262SVincent Le Chenadec {
153539d35262SVincent Le Chenadec   PetscErrorCode         ierr;
153639d35262SVincent Le Chenadec   struct DMCompositeLink *next;
153739d35262SVincent Le Chenadec   PetscScalar            *array1,*array2;
153839d35262SVincent Le Chenadec   DM_Composite           *com = (DM_Composite*)dm->data;
153939d35262SVincent Le Chenadec 
154039d35262SVincent Le Chenadec   PetscFunctionBegin;
154139d35262SVincent Le Chenadec   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
154239d35262SVincent Le Chenadec   PetscValidHeaderSpecific(vec1,VEC_CLASSID,2);
154339d35262SVincent Le Chenadec   PetscValidHeaderSpecific(vec2,VEC_CLASSID,4);
154439d35262SVincent Le Chenadec 
154539d35262SVincent Le Chenadec   if (!com->setup) {
154639d35262SVincent Le Chenadec     ierr = DMSetUp(dm);CHKERRQ(ierr);
154739d35262SVincent Le Chenadec   }
154839d35262SVincent Le Chenadec 
154939d35262SVincent Le Chenadec   ierr = VecGetArray(vec1,&array1);CHKERRQ(ierr);
155039d35262SVincent Le Chenadec   ierr = VecGetArray(vec2,&array2);CHKERRQ(ierr);
155139d35262SVincent Le Chenadec 
155239d35262SVincent Le Chenadec   /* loop over packed objects, handling one at at time */
155339d35262SVincent Le Chenadec   next = com->next;
155439d35262SVincent Le Chenadec   while (next) {
155539d35262SVincent Le Chenadec     Vec      local1,local2;
155639d35262SVincent Le Chenadec 
155739d35262SVincent Le Chenadec     ierr = DMGetLocalVector(next->dm,&local1);CHKERRQ(ierr);
155839d35262SVincent Le Chenadec     ierr = VecPlaceArray(local1,array1);CHKERRQ(ierr);
155939d35262SVincent Le Chenadec     ierr = DMGetLocalVector(next->dm,&local2);CHKERRQ(ierr);
156039d35262SVincent Le Chenadec     ierr = VecPlaceArray(local2,array2);CHKERRQ(ierr);
156139d35262SVincent Le Chenadec     ierr = DMLocalToLocalBegin(next->dm,local1,mode,local2);CHKERRQ(ierr);
156239d35262SVincent Le Chenadec     ierr = DMLocalToLocalEnd(next->dm,local1,mode,local2);CHKERRQ(ierr);
156339d35262SVincent Le Chenadec     ierr = VecResetArray(local2);CHKERRQ(ierr);
156439d35262SVincent Le Chenadec     ierr = DMRestoreLocalVector(next->dm,&local2);CHKERRQ(ierr);
156539d35262SVincent Le Chenadec     ierr = VecResetArray(local1);CHKERRQ(ierr);
156639d35262SVincent Le Chenadec     ierr = DMRestoreLocalVector(next->dm,&local1);CHKERRQ(ierr);
156739d35262SVincent Le Chenadec 
156839d35262SVincent Le Chenadec     array1 += next->nlocal;
156939d35262SVincent Le Chenadec     array2 += next->nlocal;
157039d35262SVincent Le Chenadec     next    = next->next;
157139d35262SVincent Le Chenadec   }
157239d35262SVincent Le Chenadec 
157339d35262SVincent Le Chenadec   ierr = VecRestoreArray(vec1,NULL);CHKERRQ(ierr);
157439d35262SVincent Le Chenadec   ierr = VecRestoreArray(vec2,NULL);CHKERRQ(ierr);
157539d35262SVincent Le Chenadec 
157639d35262SVincent Le Chenadec   PetscFunctionReturn(0);
157739d35262SVincent Le Chenadec }
157839d35262SVincent Le Chenadec 
157939d35262SVincent Le Chenadec PetscErrorCode  DMLocalToLocalEnd_Composite(DM dm,Vec lvec,InsertMode mode,Vec gvec)
158039d35262SVincent Le Chenadec {
158139d35262SVincent Le Chenadec   PetscFunctionBegin;
158239d35262SVincent Le Chenadec   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
158339d35262SVincent Le Chenadec   PetscValidHeaderSpecific(lvec,VEC_CLASSID,2);
158439d35262SVincent Le Chenadec   PetscValidHeaderSpecific(gvec,VEC_CLASSID,4);
15850c010503SBarry Smith   PetscFunctionReturn(0);
15860c010503SBarry Smith }
158747c6ae99SBarry Smith 
15886ae3a549SBarry Smith /*MC
15896ae3a549SBarry Smith    DMCOMPOSITE = "composite" - A DM object that is used to manage data for a collection of DMs
15906ae3a549SBarry Smith 
15916ae3a549SBarry Smith   Level: intermediate
15926ae3a549SBarry Smith 
15931abcec8cSBarry Smith .seealso: DMType, DM, DMDACreate(), DMCreate(), DMSetType(), DMCompositeCreate()
15946ae3a549SBarry Smith M*/
15956ae3a549SBarry Smith 
15966ae3a549SBarry Smith 
15978cc058d9SJed Brown PETSC_EXTERN PetscErrorCode DMCreate_Composite(DM p)
1598a4121054SBarry Smith {
1599a4121054SBarry Smith   PetscErrorCode ierr;
1600a4121054SBarry Smith   DM_Composite   *com;
1601a4121054SBarry Smith 
1602a4121054SBarry Smith   PetscFunctionBegin;
1603b00a9115SJed Brown   ierr          = PetscNewLog(p,&com);CHKERRQ(ierr);
1604a4121054SBarry Smith   p->data       = com;
1605a4121054SBarry Smith   ierr          = PetscObjectChangeTypeName((PetscObject)p,"DMComposite");CHKERRQ(ierr);
1606a4121054SBarry Smith   com->n        = 0;
16077ac2b803SAlex Fikl   com->nghost   = 0;
16080298fd71SBarry Smith   com->next     = NULL;
1609a4121054SBarry Smith   com->nDM      = 0;
1610a4121054SBarry Smith 
1611a4121054SBarry Smith   p->ops->createglobalvector              = DMCreateGlobalVector_Composite;
1612a4121054SBarry Smith   p->ops->createlocalvector               = DMCreateLocalVector_Composite;
1613184d77edSJed Brown   p->ops->getlocaltoglobalmapping         = DMGetLocalToGlobalMapping_Composite;
16144d343eeaSMatthew G Knepley   p->ops->createfieldis                   = DMCreateFieldIS_Composite;
161516621825SDmitry Karpeev   p->ops->createfielddecomposition        = DMCreateFieldDecomposition_Composite;
1616a4121054SBarry Smith   p->ops->refine                          = DMRefine_Composite;
161714354c39SJed Brown   p->ops->coarsen                         = DMCoarsen_Composite;
161825296bd5SBarry Smith   p->ops->createinterpolation             = DMCreateInterpolation_Composite;
161925296bd5SBarry Smith   p->ops->creatematrix                    = DMCreateMatrix_Composite;
1620e727c939SJed Brown   p->ops->getcoloring                     = DMCreateColoring_Composite;
1621a4121054SBarry Smith   p->ops->globaltolocalbegin              = DMGlobalToLocalBegin_Composite;
1622a4121054SBarry Smith   p->ops->globaltolocalend                = DMGlobalToLocalEnd_Composite;
162339d35262SVincent Le Chenadec   p->ops->localtoglobalbegin              = DMLocalToGlobalBegin_Composite;
162439d35262SVincent Le Chenadec   p->ops->localtoglobalend                = DMLocalToGlobalEnd_Composite;
162539d35262SVincent Le Chenadec   p->ops->localtolocalbegin               = DMLocalToLocalBegin_Composite;
162639d35262SVincent Le Chenadec   p->ops->localtolocalend                 = DMLocalToLocalEnd_Composite;
1627a4121054SBarry Smith   p->ops->destroy                         = DMDestroy_Composite;
1628a4121054SBarry Smith   p->ops->view                            = DMView_Composite;
1629a4121054SBarry Smith   p->ops->setup                           = DMSetUp_Composite;
1630a4121054SBarry Smith   PetscFunctionReturn(0);
1631a4121054SBarry Smith }
1632a4121054SBarry Smith 
16330c010503SBarry Smith /*@C
16340c010503SBarry Smith     DMCompositeCreate - Creates a vector packer, used to generate "composite"
16350c010503SBarry Smith       vectors made up of several subvectors.
16360c010503SBarry Smith 
16370c010503SBarry Smith     Collective on MPI_Comm
163847c6ae99SBarry Smith 
163947c6ae99SBarry Smith     Input Parameter:
16400c010503SBarry Smith .   comm - the processors that will share the global vector
16410c010503SBarry Smith 
16420c010503SBarry Smith     Output Parameters:
16430c010503SBarry Smith .   packer - the packer object
164447c6ae99SBarry Smith 
164547c6ae99SBarry Smith     Level: advanced
164647c6ae99SBarry Smith 
16471abcec8cSBarry Smith .seealso DMDestroy(), DMCompositeAddDM(), DMCompositeScatter(), DMCOMPOSITE,DMCreate()
16486eb61c8cSJed Brown          DMCompositeGather(), DMCreateGlobalVector(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess()
164947c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries()
165047c6ae99SBarry Smith 
165147c6ae99SBarry Smith @*/
16527087cfbeSBarry Smith PetscErrorCode  DMCompositeCreate(MPI_Comm comm,DM *packer)
165347c6ae99SBarry Smith {
16540c010503SBarry Smith   PetscErrorCode ierr;
16550c010503SBarry Smith 
165647c6ae99SBarry Smith   PetscFunctionBegin;
16570c010503SBarry Smith   PetscValidPointer(packer,2);
1658a4121054SBarry Smith   ierr = DMCreate(comm,packer);CHKERRQ(ierr);
1659a4121054SBarry Smith   ierr = DMSetType(*packer,DMCOMPOSITE);CHKERRQ(ierr);
166047c6ae99SBarry Smith   PetscFunctionReturn(0);
166147c6ae99SBarry Smith }
1662