xref: /petsc/src/dm/impls/composite/pack.c (revision 4d343eea47f3e457863a63f23fb9efcfef73ea2c)
147c6ae99SBarry Smith 
23c48a1e8SJed Brown #include "packimpl.h" /*I   "petscdmcomposite.h"   I*/
347c6ae99SBarry Smith 
447c6ae99SBarry Smith #undef __FUNCT__
547c6ae99SBarry Smith #define __FUNCT__ "DMCompositeSetCoupling"
647c6ae99SBarry Smith /*@C
747c6ae99SBarry Smith     DMCompositeSetCoupling - Sets user provided routines that compute the coupling between the
89ae5db72SJed Brown       seperate components (DMs) in a DMto build the correct matrix nonzero structure.
947c6ae99SBarry Smith 
1047c6ae99SBarry Smith 
1147c6ae99SBarry Smith     Logically Collective on MPI_Comm
1247c6ae99SBarry Smith 
1347c6ae99SBarry Smith     Input Parameter:
1447c6ae99SBarry Smith +   dm - the composite object
1547c6ae99SBarry Smith -   formcouplelocations - routine to set the nonzero locations in the matrix
1647c6ae99SBarry Smith 
1747c6ae99SBarry Smith     Level: advanced
1847c6ae99SBarry Smith 
191b2093e4SBarry Smith     Notes: See DMSetApplicationContext() and DMGetApplicationContext() for how to get user information into
2047c6ae99SBarry Smith         this routine
2147c6ae99SBarry Smith 
2247c6ae99SBarry Smith @*/
237087cfbeSBarry Smith PetscErrorCode  DMCompositeSetCoupling(DM dm,PetscErrorCode (*FormCoupleLocations)(DM,Mat,PetscInt*,PetscInt*,PetscInt,PetscInt,PetscInt,PetscInt))
2447c6ae99SBarry Smith {
2547c6ae99SBarry Smith   DM_Composite *com = (DM_Composite*)dm->data;
2647c6ae99SBarry Smith 
2747c6ae99SBarry Smith   PetscFunctionBegin;
2847c6ae99SBarry Smith   com->FormCoupleLocations = FormCoupleLocations;
2947c6ae99SBarry Smith   PetscFunctionReturn(0);
3047c6ae99SBarry Smith }
3147c6ae99SBarry Smith 
3247c6ae99SBarry Smith #undef __FUNCT__
330c010503SBarry Smith #define __FUNCT__ "DMDestroy_Composite"
346bf464f9SBarry Smith PetscErrorCode  DMDestroy_Composite(DM dm)
3547c6ae99SBarry Smith {
3647c6ae99SBarry Smith   PetscErrorCode         ierr;
3747c6ae99SBarry Smith   struct DMCompositeLink *next, *prev;
3847c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite *)dm->data;
3947c6ae99SBarry Smith 
4047c6ae99SBarry Smith   PetscFunctionBegin;
4147c6ae99SBarry Smith   next = com->next;
4247c6ae99SBarry Smith   while (next) {
4347c6ae99SBarry Smith     prev = next;
4447c6ae99SBarry Smith     next = next->next;
45fcfd50ebSBarry Smith     ierr = DMDestroy(&prev->dm);CHKERRQ(ierr);
4647c6ae99SBarry Smith     ierr = PetscFree(prev->grstarts);CHKERRQ(ierr);
4747c6ae99SBarry Smith     ierr = PetscFree(prev);CHKERRQ(ierr);
4847c6ae99SBarry Smith   }
4947c6ae99SBarry Smith   PetscFunctionReturn(0);
5047c6ae99SBarry Smith }
5147c6ae99SBarry Smith 
5247c6ae99SBarry Smith #undef __FUNCT__
530c010503SBarry Smith #define __FUNCT__ "DMView_Composite"
547087cfbeSBarry Smith PetscErrorCode  DMView_Composite(DM dm,PetscViewer v)
5547c6ae99SBarry Smith {
5647c6ae99SBarry Smith   PetscErrorCode ierr;
5747c6ae99SBarry Smith   PetscBool      iascii;
5847c6ae99SBarry Smith   DM_Composite   *com = (DM_Composite *)dm->data;
5947c6ae99SBarry Smith 
6047c6ae99SBarry Smith   PetscFunctionBegin;
6147c6ae99SBarry Smith   ierr = PetscTypeCompare((PetscObject)v,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
6247c6ae99SBarry Smith   if (iascii) {
6347c6ae99SBarry Smith     struct DMCompositeLink *lnk = com->next;
6447c6ae99SBarry Smith     PetscInt               i;
6547c6ae99SBarry Smith 
6647c6ae99SBarry Smith     ierr = PetscViewerASCIIPrintf(v,"DM (%s)\n",((PetscObject)dm)->prefix?((PetscObject)dm)->prefix:"no prefix");CHKERRQ(ierr);
679ae5db72SJed Brown     ierr = PetscViewerASCIIPrintf(v,"  contains %D DMs\n",com->nDM);CHKERRQ(ierr);
6847c6ae99SBarry Smith     ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr);
6947c6ae99SBarry Smith     for (i=0; lnk; lnk=lnk->next,i++) {
709ae5db72SJed Brown       ierr = PetscViewerASCIIPrintf(v,"Link %D: DM of type %s\n",i,((PetscObject)lnk->dm)->type_name);CHKERRQ(ierr);
7147c6ae99SBarry Smith       ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr);
7247c6ae99SBarry Smith       ierr = DMView(lnk->dm,v);CHKERRQ(ierr);
7347c6ae99SBarry Smith       ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr);
7447c6ae99SBarry Smith     }
7547c6ae99SBarry Smith     ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr);
7647c6ae99SBarry Smith   }
7747c6ae99SBarry Smith   PetscFunctionReturn(0);
7847c6ae99SBarry Smith }
7947c6ae99SBarry Smith 
8047c6ae99SBarry Smith /* --------------------------------------------------------------------------------------*/
8147c6ae99SBarry Smith #undef __FUNCT__
82d7bf68aeSBarry Smith #define __FUNCT__ "DMSetUp_Composite"
837087cfbeSBarry Smith PetscErrorCode  DMSetUp_Composite(DM dm)
8447c6ae99SBarry Smith {
8547c6ae99SBarry Smith   PetscErrorCode         ierr;
8647c6ae99SBarry Smith   PetscInt               nprev = 0;
8747c6ae99SBarry Smith   PetscMPIInt            rank,size;
8847c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
8947c6ae99SBarry Smith   struct DMCompositeLink *next = com->next;
9047c6ae99SBarry Smith   PetscLayout            map;
9147c6ae99SBarry Smith 
9247c6ae99SBarry Smith   PetscFunctionBegin;
9347c6ae99SBarry Smith   if (com->setup) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Packer has already been setup");
9447c6ae99SBarry Smith   ierr = PetscLayoutCreate(((PetscObject)dm)->comm,&map);CHKERRQ(ierr);
9547c6ae99SBarry Smith   ierr = PetscLayoutSetLocalSize(map,com->n);CHKERRQ(ierr);
9647c6ae99SBarry Smith   ierr = PetscLayoutSetSize(map,PETSC_DETERMINE);CHKERRQ(ierr);
9747c6ae99SBarry Smith   ierr = PetscLayoutSetBlockSize(map,1);CHKERRQ(ierr);
9847c6ae99SBarry Smith   ierr = PetscLayoutSetUp(map);CHKERRQ(ierr);
9947c6ae99SBarry Smith   ierr = PetscLayoutGetSize(map,&com->N);CHKERRQ(ierr);
10047c6ae99SBarry Smith   ierr = PetscLayoutGetRange(map,&com->rstart,PETSC_NULL);CHKERRQ(ierr);
101fcfd50ebSBarry Smith   ierr = PetscLayoutDestroy(&map);CHKERRQ(ierr);
10247c6ae99SBarry Smith 
1039ae5db72SJed Brown   /* now set the rstart for each linked vector */
10447c6ae99SBarry Smith   ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr);
10547c6ae99SBarry Smith   ierr = MPI_Comm_size(((PetscObject)dm)->comm,&size);CHKERRQ(ierr);
10647c6ae99SBarry Smith   while (next) {
10747c6ae99SBarry Smith     next->rstart = nprev;
10806ebdd98SJed Brown     nprev += next->n;
10947c6ae99SBarry Smith     next->grstart = com->rstart + next->rstart;
11047c6ae99SBarry Smith     ierr = PetscMalloc(size*sizeof(PetscInt),&next->grstarts);CHKERRQ(ierr);
11147c6ae99SBarry Smith     ierr = MPI_Allgather(&next->grstart,1,MPIU_INT,next->grstarts,1,MPIU_INT,((PetscObject)dm)->comm);CHKERRQ(ierr);
11247c6ae99SBarry Smith     next = next->next;
11347c6ae99SBarry Smith   }
11447c6ae99SBarry Smith   com->setup = PETSC_TRUE;
11547c6ae99SBarry Smith   PetscFunctionReturn(0);
11647c6ae99SBarry Smith }
11747c6ae99SBarry Smith 
11847c6ae99SBarry Smith /* ----------------------------------------------------------------------------------*/
11947c6ae99SBarry Smith 
12047c6ae99SBarry Smith #include <stdarg.h>
12147c6ae99SBarry Smith 
12247c6ae99SBarry Smith #undef __FUNCT__
12347c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetNumberDM"
12447c6ae99SBarry Smith /*@C
12547c6ae99SBarry Smith     DMCompositeGetNumberDM - Get's the number of DM objects in the DMComposite
12647c6ae99SBarry Smith        representation.
12747c6ae99SBarry Smith 
12847c6ae99SBarry Smith     Not Collective
12947c6ae99SBarry Smith 
13047c6ae99SBarry Smith     Input Parameter:
13147c6ae99SBarry Smith .    dm - the packer object
13247c6ae99SBarry Smith 
13347c6ae99SBarry Smith     Output Parameter:
13447c6ae99SBarry Smith .     nDM - the number of DMs
13547c6ae99SBarry Smith 
13647c6ae99SBarry Smith     Level: beginner
13747c6ae99SBarry Smith 
13847c6ae99SBarry Smith @*/
1397087cfbeSBarry Smith PetscErrorCode  DMCompositeGetNumberDM(DM dm,PetscInt *nDM)
14047c6ae99SBarry Smith {
14147c6ae99SBarry Smith   DM_Composite *com = (DM_Composite*)dm->data;
14247c6ae99SBarry Smith   PetscFunctionBegin;
14347c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
14447c6ae99SBarry Smith   *nDM = com->nDM;
14547c6ae99SBarry Smith   PetscFunctionReturn(0);
14647c6ae99SBarry Smith }
14747c6ae99SBarry Smith 
14847c6ae99SBarry Smith 
14947c6ae99SBarry Smith #undef __FUNCT__
15047c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetAccess"
15147c6ae99SBarry Smith /*@C
15247c6ae99SBarry Smith     DMCompositeGetAccess - Allows one to access the individual packed vectors in their global
15347c6ae99SBarry Smith        representation.
15447c6ae99SBarry Smith 
15547c6ae99SBarry Smith     Collective on DMComposite
15647c6ae99SBarry Smith 
1579ae5db72SJed Brown     Input Parameters:
15847c6ae99SBarry Smith +    dm - the packer object
1599ae5db72SJed Brown -    gvec - the global vector
1609ae5db72SJed Brown 
1619ae5db72SJed Brown     Output Parameters:
1629ae5db72SJed Brown .    Vec* ... - the packed parallel vectors, PETSC_NULL for those that are not needed
16347c6ae99SBarry Smith 
16447c6ae99SBarry Smith     Notes: Use DMCompositeRestoreAccess() to return the vectors when you no longer need them
16547c6ae99SBarry Smith 
16647c6ae99SBarry Smith     Level: advanced
16747c6ae99SBarry Smith 
16847c6ae99SBarry Smith @*/
1697087cfbeSBarry Smith PetscErrorCode  DMCompositeGetAccess(DM dm,Vec gvec,...)
17047c6ae99SBarry Smith {
17147c6ae99SBarry Smith   va_list                Argp;
17247c6ae99SBarry Smith   PetscErrorCode         ierr;
17347c6ae99SBarry Smith   struct DMCompositeLink *next;
17447c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
17547c6ae99SBarry Smith 
17647c6ae99SBarry Smith   PetscFunctionBegin;
17747c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
17847c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
17947c6ae99SBarry Smith   next = com->next;
18047c6ae99SBarry Smith   if (!com->setup) {
181d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
18247c6ae99SBarry Smith   }
18347c6ae99SBarry Smith 
18447c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
18547c6ae99SBarry Smith   va_start(Argp,gvec);
18647c6ae99SBarry Smith   while (next) {
18747c6ae99SBarry Smith     Vec *vec;
18847c6ae99SBarry Smith     vec = va_arg(Argp, Vec*);
1899ae5db72SJed Brown     if (vec) {
1909ae5db72SJed Brown       PetscScalar *array;
1919ae5db72SJed Brown       ierr = DMGetGlobalVector(next->dm,vec);CHKERRQ(ierr);
1929ae5db72SJed Brown       ierr = VecGetArray(gvec,&array);CHKERRQ(ierr);
1939ae5db72SJed Brown       ierr = VecPlaceArray(*vec,array+next->rstart);CHKERRQ(ierr);
1949ae5db72SJed Brown       ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr);
19547c6ae99SBarry Smith     }
19647c6ae99SBarry Smith     next = next->next;
19747c6ae99SBarry Smith   }
19847c6ae99SBarry Smith   va_end(Argp);
19947c6ae99SBarry Smith   PetscFunctionReturn(0);
20047c6ae99SBarry Smith }
20147c6ae99SBarry Smith 
20247c6ae99SBarry Smith #undef __FUNCT__
20347c6ae99SBarry Smith #define __FUNCT__ "DMCompositeRestoreAccess"
20447c6ae99SBarry Smith /*@C
205aa219208SBarry Smith     DMCompositeRestoreAccess - Returns the vectors obtained with DMCompositeGetAccess()
20647c6ae99SBarry Smith        representation.
20747c6ae99SBarry Smith 
20847c6ae99SBarry Smith     Collective on DMComposite
20947c6ae99SBarry Smith 
2109ae5db72SJed Brown     Input Parameters:
21147c6ae99SBarry Smith +    dm - the packer object
21247c6ae99SBarry Smith .    gvec - the global vector
2139ae5db72SJed Brown -    Vec* ... - the individual parallel vectors, PETSC_NULL for those that are not needed
21447c6ae99SBarry Smith 
21547c6ae99SBarry Smith     Level: advanced
21647c6ae99SBarry Smith 
2179ae5db72SJed Brown .seealso  DMCompositeAddDM(), DMCreateGlobalVector(),
2186eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeScatter(),
219aa219208SBarry Smith          DMCompositeRestoreAccess(), DMCompositeGetAccess()
22047c6ae99SBarry Smith 
22147c6ae99SBarry Smith @*/
2227087cfbeSBarry Smith PetscErrorCode  DMCompositeRestoreAccess(DM dm,Vec gvec,...)
22347c6ae99SBarry Smith {
22447c6ae99SBarry Smith   va_list                Argp;
22547c6ae99SBarry Smith   PetscErrorCode         ierr;
22647c6ae99SBarry Smith   struct DMCompositeLink *next;
22747c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
22847c6ae99SBarry Smith 
22947c6ae99SBarry Smith   PetscFunctionBegin;
23047c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
23147c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
23247c6ae99SBarry Smith   next = com->next;
23347c6ae99SBarry Smith   if (!com->setup) {
234d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
23547c6ae99SBarry Smith   }
23647c6ae99SBarry Smith 
23747c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
23847c6ae99SBarry Smith   va_start(Argp,gvec);
23947c6ae99SBarry Smith   while (next) {
24047c6ae99SBarry Smith     Vec *vec;
24147c6ae99SBarry Smith     vec = va_arg(Argp, Vec*);
2429ae5db72SJed Brown     if (vec) {
2439ae5db72SJed Brown       ierr = VecResetArray(*vec);CHKERRQ(ierr);
2449ae5db72SJed Brown       ierr = DMRestoreGlobalVector(next->dm,vec);CHKERRQ(ierr);
24547c6ae99SBarry Smith     }
24647c6ae99SBarry Smith     next = next->next;
24747c6ae99SBarry Smith   }
24847c6ae99SBarry Smith   va_end(Argp);
24947c6ae99SBarry Smith   PetscFunctionReturn(0);
25047c6ae99SBarry Smith }
25147c6ae99SBarry Smith 
25247c6ae99SBarry Smith #undef __FUNCT__
25347c6ae99SBarry Smith #define __FUNCT__ "DMCompositeScatter"
25447c6ae99SBarry Smith /*@C
25547c6ae99SBarry Smith     DMCompositeScatter - Scatters from a global packed vector into its individual local vectors
25647c6ae99SBarry Smith 
25747c6ae99SBarry Smith     Collective on DMComposite
25847c6ae99SBarry Smith 
2599ae5db72SJed Brown     Input Parameters:
26047c6ae99SBarry Smith +    dm - the packer object
26147c6ae99SBarry Smith .    gvec - the global vector
2629ae5db72SJed Brown -    Vec ... - the individual sequential vectors, PETSC_NULL for those that are not needed
26347c6ae99SBarry Smith 
26447c6ae99SBarry Smith     Level: advanced
26547c6ae99SBarry Smith 
2669ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
2676eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
26847c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries()
26947c6ae99SBarry Smith 
27047c6ae99SBarry Smith @*/
2717087cfbeSBarry Smith PetscErrorCode  DMCompositeScatter(DM dm,Vec gvec,...)
27247c6ae99SBarry Smith {
27347c6ae99SBarry Smith   va_list                Argp;
27447c6ae99SBarry Smith   PetscErrorCode         ierr;
27547c6ae99SBarry Smith   struct DMCompositeLink *next;
2768fd8f222SJed Brown   PetscInt               cnt;
27747c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
27847c6ae99SBarry Smith 
27947c6ae99SBarry Smith   PetscFunctionBegin;
28047c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
28147c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
28247c6ae99SBarry Smith   if (!com->setup) {
283d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
28447c6ae99SBarry Smith   }
28547c6ae99SBarry Smith 
28647c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
28747c6ae99SBarry Smith   va_start(Argp,gvec);
2888fd8f222SJed Brown   for (cnt=3,next=com->next; next; cnt++,next=next->next) {
2899ae5db72SJed Brown     Vec local;
2909ae5db72SJed Brown     local = va_arg(Argp, Vec);
2919ae5db72SJed Brown     if (local) {
2929ae5db72SJed Brown       Vec global;
29347c6ae99SBarry Smith       PetscScalar *array;
2949ae5db72SJed Brown       PetscValidHeaderSpecific(local,VEC_CLASSID,cnt);
2959ae5db72SJed Brown       ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
2969ae5db72SJed Brown       ierr = VecGetArray(gvec,&array);CHKERRQ(ierr);
2979ae5db72SJed Brown       ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr);
2989ae5db72SJed Brown       ierr = DMGlobalToLocalBegin(next->dm,global,INSERT_VALUES,local);CHKERRQ(ierr);
2999ae5db72SJed Brown       ierr = DMGlobalToLocalEnd(next->dm,global,INSERT_VALUES,local);CHKERRQ(ierr);
3009ae5db72SJed Brown       ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr);
3019ae5db72SJed Brown       ierr = VecResetArray(global);CHKERRQ(ierr);
3029ae5db72SJed Brown       ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
30347c6ae99SBarry Smith     }
30447c6ae99SBarry Smith   }
30547c6ae99SBarry Smith   va_end(Argp);
30647c6ae99SBarry Smith   PetscFunctionReturn(0);
30747c6ae99SBarry Smith }
30847c6ae99SBarry Smith 
30947c6ae99SBarry Smith #undef __FUNCT__
31047c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGather"
31147c6ae99SBarry Smith /*@C
31247c6ae99SBarry Smith     DMCompositeGather - Gathers into a global packed vector from its individual local vectors
31347c6ae99SBarry Smith 
31447c6ae99SBarry Smith     Collective on DMComposite
31547c6ae99SBarry Smith 
31647c6ae99SBarry Smith     Input Parameter:
31747c6ae99SBarry Smith +    dm - the packer object
31847c6ae99SBarry Smith .    gvec - the global vector
3199ae5db72SJed Brown -    Vec ... - the individual sequential vectors, PETSC_NULL for any that are not needed
32047c6ae99SBarry Smith 
32147c6ae99SBarry Smith     Level: advanced
32247c6ae99SBarry Smith 
3239ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
3246eb61c8cSJed Brown          DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
32547c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries()
32647c6ae99SBarry Smith 
32747c6ae99SBarry Smith @*/
3287087cfbeSBarry Smith PetscErrorCode  DMCompositeGather(DM dm,Vec gvec,InsertMode imode,...)
32947c6ae99SBarry Smith {
33047c6ae99SBarry Smith   va_list                Argp;
33147c6ae99SBarry Smith   PetscErrorCode         ierr;
33247c6ae99SBarry Smith   struct DMCompositeLink *next;
33347c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
3348fd8f222SJed Brown   PetscInt               cnt;
33547c6ae99SBarry Smith 
33647c6ae99SBarry Smith   PetscFunctionBegin;
33747c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
33847c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
33947c6ae99SBarry Smith   if (!com->setup) {
340d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
34147c6ae99SBarry Smith   }
34247c6ae99SBarry Smith 
34347c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
344df0c820aSJed Brown   va_start(Argp,imode);
3458fd8f222SJed Brown   for (cnt=3,next=com->next; next; cnt++,next=next->next) {
3469ae5db72SJed Brown     Vec local;
3479ae5db72SJed Brown     local = va_arg(Argp, Vec);
3489ae5db72SJed Brown     if (local) {
34947c6ae99SBarry Smith       PetscScalar    *array;
3509ae5db72SJed Brown       Vec            global;
3519ae5db72SJed Brown       PetscValidHeaderSpecific(local,VEC_CLASSID,cnt);
3529ae5db72SJed Brown       ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
3539ae5db72SJed Brown       ierr = VecGetArray(gvec,&array);CHKERRQ(ierr);
3549ae5db72SJed Brown       ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr);
3559ae5db72SJed Brown       ierr = DMLocalToGlobalBegin(next->dm,local,imode,global);CHKERRQ(ierr);
3569ae5db72SJed Brown       ierr = DMLocalToGlobalEnd(next->dm,local,imode,global);CHKERRQ(ierr);
3579ae5db72SJed Brown       ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr);
3589ae5db72SJed Brown       ierr = VecResetArray(global);CHKERRQ(ierr);
3599ae5db72SJed Brown       ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
36047c6ae99SBarry Smith     }
36147c6ae99SBarry Smith   }
36247c6ae99SBarry Smith   va_end(Argp);
36347c6ae99SBarry Smith   PetscFunctionReturn(0);
36447c6ae99SBarry Smith }
36547c6ae99SBarry Smith 
36647c6ae99SBarry Smith #undef __FUNCT__
36747c6ae99SBarry Smith #define __FUNCT__ "DMCompositeAddDM"
36847c6ae99SBarry Smith /*@C
369aa219208SBarry Smith     DMCompositeAddDM - adds a DM  vector to a DMComposite
37047c6ae99SBarry Smith 
37147c6ae99SBarry Smith     Collective on DMComposite
37247c6ae99SBarry Smith 
37347c6ae99SBarry Smith     Input Parameter:
37447c6ae99SBarry Smith +    dm - the packer object
37547c6ae99SBarry Smith -    dm - the DM object, if the DM is a da you will need to caste it with a (DM)
37647c6ae99SBarry Smith 
37747c6ae99SBarry Smith     Level: advanced
37847c6ae99SBarry Smith 
3790c010503SBarry Smith .seealso DMDestroy(), DMCompositeGather(), DMCompositeAddDM(), DMCreateGlobalVector(),
3806eb61c8cSJed Brown          DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
38147c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries()
38247c6ae99SBarry Smith 
38347c6ae99SBarry Smith @*/
3847087cfbeSBarry Smith PetscErrorCode  DMCompositeAddDM(DM dmc,DM dm)
38547c6ae99SBarry Smith {
38647c6ae99SBarry Smith   PetscErrorCode         ierr;
38706ebdd98SJed Brown   PetscInt               n,nlocal;
38847c6ae99SBarry Smith   struct DMCompositeLink *mine,*next;
38906ebdd98SJed Brown   Vec                    global,local;
39047c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dmc->data;
39147c6ae99SBarry Smith 
39247c6ae99SBarry Smith   PetscFunctionBegin;
39347c6ae99SBarry Smith   PetscValidHeaderSpecific(dmc,DM_CLASSID,1);
39447c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,2);
39547c6ae99SBarry Smith   next = com->next;
396aa219208SBarry Smith   if (com->setup) SETERRQ(((PetscObject)dmc)->comm,PETSC_ERR_ARG_WRONGSTATE,"Cannot add a DM once you have used the DMComposite");
39747c6ae99SBarry Smith 
39847c6ae99SBarry Smith   /* create new link */
39947c6ae99SBarry Smith   ierr = PetscNew(struct DMCompositeLink,&mine);CHKERRQ(ierr);
40047c6ae99SBarry Smith   ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);
40147c6ae99SBarry Smith   ierr = DMGetGlobalVector(dm,&global);CHKERRQ(ierr);
40247c6ae99SBarry Smith   ierr = VecGetLocalSize(global,&n);CHKERRQ(ierr);
40347c6ae99SBarry Smith   ierr = DMRestoreGlobalVector(dm,&global);CHKERRQ(ierr);
40406ebdd98SJed Brown   ierr = DMGetLocalVector(dm,&local);CHKERRQ(ierr);
40506ebdd98SJed Brown   ierr = VecGetSize(local,&nlocal);CHKERRQ(ierr);
40606ebdd98SJed Brown   ierr = DMRestoreLocalVector(dm,&local);CHKERRQ(ierr);
40747c6ae99SBarry Smith   mine->n      = n;
40806ebdd98SJed Brown   mine->nlocal = nlocal;
40947c6ae99SBarry Smith   mine->dm     = dm;
41047c6ae99SBarry Smith   mine->next   = PETSC_NULL;
41147c6ae99SBarry Smith   com->n       += n;
41247c6ae99SBarry Smith 
41347c6ae99SBarry Smith   /* add to end of list */
41447c6ae99SBarry Smith   if (!next) {
41547c6ae99SBarry Smith     com->next = mine;
41647c6ae99SBarry Smith   } else {
41747c6ae99SBarry Smith     while (next->next) next = next->next;
41847c6ae99SBarry Smith     next->next = mine;
41947c6ae99SBarry Smith   }
42047c6ae99SBarry Smith   com->nDM++;
42147c6ae99SBarry Smith   com->nmine++;
42247c6ae99SBarry Smith   PetscFunctionReturn(0);
42347c6ae99SBarry Smith }
42447c6ae99SBarry Smith 
4257087cfbeSBarry Smith extern PetscErrorCode  VecView_MPI(Vec,PetscViewer);
42647c6ae99SBarry Smith EXTERN_C_BEGIN
42747c6ae99SBarry Smith #undef __FUNCT__
42847c6ae99SBarry Smith #define __FUNCT__ "VecView_DMComposite"
4297087cfbeSBarry Smith PetscErrorCode  VecView_DMComposite(Vec gvec,PetscViewer viewer)
43047c6ae99SBarry Smith {
43147c6ae99SBarry Smith   DM                     dm;
43247c6ae99SBarry Smith   PetscErrorCode         ierr;
43347c6ae99SBarry Smith   struct DMCompositeLink *next;
43447c6ae99SBarry Smith   PetscBool              isdraw;
435cef07954SSatish Balay   DM_Composite           *com;
43647c6ae99SBarry Smith 
43747c6ae99SBarry Smith   PetscFunctionBegin;
4383c0c59f3SBarry Smith   ierr = PetscObjectQuery((PetscObject)gvec,"DM",(PetscObject*)&dm);CHKERRQ(ierr);
43947c6ae99SBarry Smith   if (!dm) SETERRQ(((PetscObject)gvec)->comm,PETSC_ERR_ARG_WRONG,"Vector not generated from a DMComposite");
44047c6ae99SBarry Smith   com = (DM_Composite*)dm->data;
44147c6ae99SBarry Smith   next = com->next;
44247c6ae99SBarry Smith 
44347c6ae99SBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
44447c6ae99SBarry Smith   if (!isdraw) {
44547c6ae99SBarry Smith     /* do I really want to call this? */
44647c6ae99SBarry Smith     ierr = VecView_MPI(gvec,viewer);CHKERRQ(ierr);
44747c6ae99SBarry Smith   } else {
44847c6ae99SBarry Smith     PetscInt cnt = 0;
44947c6ae99SBarry Smith 
45047c6ae99SBarry Smith     /* loop over packed objects, handling one at at time */
45147c6ae99SBarry Smith     while (next) {
45247c6ae99SBarry Smith       Vec         vec;
4539ae5db72SJed Brown       PetscScalar *array;
45447c6ae99SBarry Smith       PetscInt    bs;
45547c6ae99SBarry Smith 
4569ae5db72SJed Brown       /* Should use VecGetSubVector() eventually, but would need to forward the DM for that to work */
4579ae5db72SJed Brown       ierr = DMGetGlobalVector(next->dm,&vec);CHKERRQ(ierr);
4589ae5db72SJed Brown       ierr = VecGetArray(gvec,&array);CHKERRQ(ierr);
4599ae5db72SJed Brown       ierr = VecPlaceArray(vec,array+next->rstart);CHKERRQ(ierr);
4609ae5db72SJed Brown       ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr);
46147c6ae99SBarry Smith       ierr = VecView(vec,viewer);CHKERRQ(ierr);
46247c6ae99SBarry Smith       ierr = VecGetBlockSize(vec,&bs);CHKERRQ(ierr);
4639ae5db72SJed Brown       ierr = VecResetArray(vec);CHKERRQ(ierr);
4649ae5db72SJed Brown       ierr = DMRestoreGlobalVector(next->dm,&vec);CHKERRQ(ierr);
46547c6ae99SBarry Smith       ierr = PetscViewerDrawBaseAdd(viewer,bs);CHKERRQ(ierr);
46647c6ae99SBarry Smith       cnt += bs;
46747c6ae99SBarry Smith       next = next->next;
46847c6ae99SBarry Smith     }
46947c6ae99SBarry Smith     ierr = PetscViewerDrawBaseAdd(viewer,-cnt);CHKERRQ(ierr);
47047c6ae99SBarry Smith   }
47147c6ae99SBarry Smith   PetscFunctionReturn(0);
47247c6ae99SBarry Smith }
47347c6ae99SBarry Smith EXTERN_C_END
47447c6ae99SBarry Smith 
47547c6ae99SBarry Smith 
47647c6ae99SBarry Smith #undef __FUNCT__
4770c010503SBarry Smith #define __FUNCT__ "DMCreateGlobalVector_Composite"
4787087cfbeSBarry Smith PetscErrorCode  DMCreateGlobalVector_Composite(DM dm,Vec *gvec)
47947c6ae99SBarry Smith {
48047c6ae99SBarry Smith   PetscErrorCode         ierr;
48147c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
48247c6ae99SBarry Smith 
48347c6ae99SBarry Smith   PetscFunctionBegin;
48447c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
485d7bf68aeSBarry Smith   ierr = DMSetUp(dm);CHKERRQ(ierr);
48647c6ae99SBarry Smith   ierr = VecCreateMPI(((PetscObject)dm)->comm,com->n,com->N,gvec);CHKERRQ(ierr);
4873c0c59f3SBarry Smith   ierr = PetscObjectCompose((PetscObject)*gvec,"DM",(PetscObject)dm);CHKERRQ(ierr);
48847c6ae99SBarry Smith   ierr = VecSetOperation(*gvec,VECOP_VIEW,(void(*)(void))VecView_DMComposite);CHKERRQ(ierr);
48947c6ae99SBarry Smith   PetscFunctionReturn(0);
49047c6ae99SBarry Smith }
49147c6ae99SBarry Smith 
49247c6ae99SBarry Smith #undef __FUNCT__
4930c010503SBarry Smith #define __FUNCT__ "DMCreateLocalVector_Composite"
4947087cfbeSBarry Smith PetscErrorCode  DMCreateLocalVector_Composite(DM dm,Vec *lvec)
49547c6ae99SBarry Smith {
49647c6ae99SBarry Smith   PetscErrorCode         ierr;
49747c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
49847c6ae99SBarry Smith 
49947c6ae99SBarry Smith   PetscFunctionBegin;
50047c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
50147c6ae99SBarry Smith   if (!com->setup) {
502d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
50347c6ae99SBarry Smith   }
50447c6ae99SBarry Smith   ierr = VecCreateSeq(((PetscObject)dm)->comm,com->nghost,lvec);CHKERRQ(ierr);
5053c0c59f3SBarry Smith   ierr = PetscObjectCompose((PetscObject)*lvec,"DM",(PetscObject)dm);CHKERRQ(ierr);
50647c6ae99SBarry Smith   PetscFunctionReturn(0);
50747c6ae99SBarry Smith }
50847c6ae99SBarry Smith 
50947c6ae99SBarry Smith #undef __FUNCT__
5106eb61c8cSJed Brown #define __FUNCT__ "DMCompositeGetISLocalToGlobalMappings"
51147c6ae99SBarry Smith /*@C
5129ae5db72SJed Brown     DMCompositeGetISLocalToGlobalMappings - gets an ISLocalToGlobalMapping for each DM in the DMComposite, maps to the composite global space
51347c6ae99SBarry Smith 
51406ebdd98SJed Brown     Collective on DM
51547c6ae99SBarry Smith 
51647c6ae99SBarry Smith     Input Parameter:
51747c6ae99SBarry Smith .    dm - the packer object
51847c6ae99SBarry Smith 
51947c6ae99SBarry Smith     Output Parameters:
5209ae5db72SJed Brown .    ltogs - the individual mappings for each packed vector. Note that this includes
5219ae5db72SJed Brown            all the ghost points that individual ghosted DMDA's may have.
52247c6ae99SBarry Smith 
52347c6ae99SBarry Smith     Level: advanced
52447c6ae99SBarry Smith 
52547c6ae99SBarry Smith     Notes:
5266eb61c8cSJed Brown        Each entry of ltogs should be destroyed with ISLocalToGlobalMappingDestroy(), the ltogs array should be freed with PetscFree().
52747c6ae99SBarry Smith 
5289ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
52947c6ae99SBarry Smith          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetAccess(), DMCompositeScatter(),
53047c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(),DMCompositeGetEntries()
53147c6ae99SBarry Smith 
53247c6ae99SBarry Smith @*/
5337087cfbeSBarry Smith PetscErrorCode  DMCompositeGetISLocalToGlobalMappings(DM dm,ISLocalToGlobalMapping **ltogs)
53447c6ae99SBarry Smith {
53547c6ae99SBarry Smith   PetscErrorCode         ierr;
53647c6ae99SBarry Smith   PetscInt               i,*idx,n,cnt;
53747c6ae99SBarry Smith   struct DMCompositeLink *next;
53847c6ae99SBarry Smith   PetscMPIInt            rank;
53947c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
54047c6ae99SBarry Smith 
54147c6ae99SBarry Smith   PetscFunctionBegin;
54247c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
543728e99d6SJed Brown   ierr = DMSetUp(dm);CHKERRQ(ierr);
5449ae5db72SJed Brown   ierr = PetscMalloc((com->nDM)*sizeof(ISLocalToGlobalMapping),ltogs);CHKERRQ(ierr);
54547c6ae99SBarry Smith   next = com->next;
54647c6ae99SBarry Smith   ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr);
54747c6ae99SBarry Smith 
54847c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
54947c6ae99SBarry Smith   cnt = 0;
55047c6ae99SBarry Smith   while (next) {
5516eb61c8cSJed Brown     ISLocalToGlobalMapping ltog;
5526eb61c8cSJed Brown     PetscMPIInt            size;
55386994e45SJed Brown     const PetscInt         *suboff,*indices;
5546eb61c8cSJed Brown     Vec                    global;
55547c6ae99SBarry Smith 
5566eb61c8cSJed Brown     /* Get sub-DM global indices for each local dof */
5571411c6eeSJed Brown     ierr = DMGetLocalToGlobalMapping(next->dm,&ltog);CHKERRQ(ierr);
5586eb61c8cSJed Brown     ierr = ISLocalToGlobalMappingGetSize(ltog,&n);CHKERRQ(ierr);
55986994e45SJed Brown     ierr = ISLocalToGlobalMappingGetIndices(ltog,&indices);CHKERRQ(ierr);
56047c6ae99SBarry Smith     ierr = PetscMalloc(n*sizeof(PetscInt),&idx);CHKERRQ(ierr);
56147c6ae99SBarry Smith 
5626eb61c8cSJed Brown     /* Get the offsets for the sub-DM global vector */
5636eb61c8cSJed Brown     ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
5646eb61c8cSJed Brown     ierr = VecGetOwnershipRanges(global,&suboff);CHKERRQ(ierr);
5656eb61c8cSJed Brown     ierr = MPI_Comm_size(((PetscObject)global)->comm,&size);CHKERRQ(ierr);
5666eb61c8cSJed Brown 
5676eb61c8cSJed Brown     /* Shift the sub-DM definition of the global space to the composite global space */
5686eb61c8cSJed Brown     for (i=0; i<n; i++) {
56986994e45SJed Brown       PetscInt subi = indices[i],lo = 0,hi = size,t;
5706eb61c8cSJed Brown       /* Binary search to find which rank owns subi */
5716eb61c8cSJed Brown       while (hi-lo > 1) {
5726eb61c8cSJed Brown         t = lo + (hi-lo)/2;
5736eb61c8cSJed Brown         if (suboff[t] > subi) hi = t;
5746eb61c8cSJed Brown         else                  lo = t;
5756eb61c8cSJed Brown       }
5766eb61c8cSJed Brown       idx[i] = subi - suboff[lo] + next->grstarts[lo];
5776eb61c8cSJed Brown     }
57886994e45SJed Brown     ierr = ISLocalToGlobalMappingRestoreIndices(ltog,&indices);CHKERRQ(ierr);
5796eb61c8cSJed Brown     ierr = ISLocalToGlobalMappingCreate(((PetscObject)dm)->comm,n,idx,PETSC_OWN_POINTER,&(*ltogs)[cnt]);CHKERRQ(ierr);
5806eb61c8cSJed Brown     ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
58147c6ae99SBarry Smith     next = next->next;
58247c6ae99SBarry Smith     cnt++;
58347c6ae99SBarry Smith   }
58447c6ae99SBarry Smith   PetscFunctionReturn(0);
58547c6ae99SBarry Smith }
58647c6ae99SBarry Smith 
58747c6ae99SBarry Smith #undef __FUNCT__
58887c85e80SJed Brown #define __FUNCT__ "DMCompositeGetLocalISs"
58987c85e80SJed Brown /*@C
5909ae5db72SJed Brown    DMCompositeGetLocalISs - Gets index sets for each component of a composite local vector
59187c85e80SJed Brown 
59287c85e80SJed Brown    Not Collective
59387c85e80SJed Brown 
59487c85e80SJed Brown    Input Arguments:
59587c85e80SJed Brown . dm - composite DM
59687c85e80SJed Brown 
59787c85e80SJed Brown    Output Arguments:
59887c85e80SJed Brown . is - array of serial index sets for each each component of the DMComposite
59987c85e80SJed Brown 
60087c85e80SJed Brown    Level: intermediate
60187c85e80SJed Brown 
60287c85e80SJed Brown    Notes:
60387c85e80SJed Brown    At present, a composite local vector does not normally exist.  This function is used to provide index sets for
60487c85e80SJed Brown    MatGetLocalSubMatrix().  In the future, the scatters for each entry in the DMComposite may be be merged into a single
6059ae5db72SJed Brown    scatter to a composite local vector.  The user should not typically need to know which is being done.
60687c85e80SJed Brown 
60787c85e80SJed Brown    To get the composite global indices at all local points (including ghosts), use DMCompositeGetISLocalToGlobalMappings().
60887c85e80SJed Brown 
60987c85e80SJed Brown    To get index sets for pieces of the composite global vector, use DMCompositeGetGlobalISs().
61087c85e80SJed Brown 
61187c85e80SJed Brown    Each returned IS should be destroyed with ISDestroy(), the array should be freed with PetscFree().
61287c85e80SJed Brown 
61387c85e80SJed Brown .seealso: DMCompositeGetGlobalISs(), DMCompositeGetISLocalToGlobalMappings(), MatGetLocalSubMatrix(), MatCreateLocalRef()
61487c85e80SJed Brown @*/
6157087cfbeSBarry Smith PetscErrorCode  DMCompositeGetLocalISs(DM dm,IS **is)
61687c85e80SJed Brown {
61787c85e80SJed Brown   PetscErrorCode         ierr;
61887c85e80SJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
61987c85e80SJed Brown   struct DMCompositeLink *link;
62087c85e80SJed Brown   PetscInt cnt,start;
62187c85e80SJed Brown 
62287c85e80SJed Brown   PetscFunctionBegin;
62387c85e80SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
62487c85e80SJed Brown   PetscValidPointer(is,2);
62587c85e80SJed Brown   ierr = PetscMalloc(com->nmine*sizeof(IS),is);CHKERRQ(ierr);
62606ebdd98SJed Brown   for (cnt=0,start=0,link=com->next; link; start+=link->nlocal,cnt++,link=link->next) {
627520db06cSJed Brown     PetscInt bs;
6289ae5db72SJed Brown     ierr = ISCreateStride(PETSC_COMM_SELF,link->nlocal,start,1,&(*is)[cnt]);CHKERRQ(ierr);
6291411c6eeSJed Brown     ierr = DMGetBlockSize(link->dm,&bs);CHKERRQ(ierr);
630520db06cSJed Brown     ierr = ISSetBlockSize((*is)[cnt],bs);CHKERRQ(ierr);
631520db06cSJed Brown   }
63287c85e80SJed Brown   PetscFunctionReturn(0);
63387c85e80SJed Brown }
63487c85e80SJed Brown 
63587c85e80SJed Brown #undef __FUNCT__
63647c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetGlobalISs"
63747c6ae99SBarry Smith /*@C
63847c6ae99SBarry Smith     DMCompositeGetGlobalISs - Gets the index sets for each composed object
63947c6ae99SBarry Smith 
64047c6ae99SBarry Smith     Collective on DMComposite
64147c6ae99SBarry Smith 
64247c6ae99SBarry Smith     Input Parameter:
64347c6ae99SBarry Smith .    dm - the packer object
64447c6ae99SBarry Smith 
64547c6ae99SBarry Smith     Output Parameters:
64647c6ae99SBarry Smith .    is - the array of index sets
64747c6ae99SBarry Smith 
64847c6ae99SBarry Smith     Level: advanced
64947c6ae99SBarry Smith 
65047c6ae99SBarry Smith     Notes:
65147c6ae99SBarry Smith        The is entries should be destroyed with ISDestroy(), the is array should be freed with PetscFree()
65247c6ae99SBarry Smith 
65347c6ae99SBarry Smith        These could be used to extract a subset of vector entries for a "multi-physics" preconditioner
65447c6ae99SBarry Smith 
6556eb61c8cSJed Brown        Use DMCompositeGetLocalISs() for index sets in the packed local numbering, and
6566eb61c8cSJed Brown        DMCompositeGetISLocalToGlobalMappings() for to map local sub-DM (including ghost) indices to packed global
6576eb61c8cSJed Brown        indices.
65847c6ae99SBarry Smith 
6599ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
66047c6ae99SBarry Smith          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetAccess(), DMCompositeScatter(),
66147c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(),DMCompositeGetEntries()
66247c6ae99SBarry Smith 
66347c6ae99SBarry Smith @*/
6646eb61c8cSJed Brown 
6657087cfbeSBarry Smith PetscErrorCode  DMCompositeGetGlobalISs(DM dm,IS *is[])
66647c6ae99SBarry Smith {
66747c6ae99SBarry Smith   PetscErrorCode         ierr;
66847c6ae99SBarry Smith   PetscInt               cnt = 0,*idx,i;
66947c6ae99SBarry Smith   struct DMCompositeLink *next;
67047c6ae99SBarry Smith   PetscMPIInt            rank;
67147c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
67247c6ae99SBarry Smith 
67347c6ae99SBarry Smith   PetscFunctionBegin;
67447c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6759ae5db72SJed Brown   ierr = PetscMalloc((com->nDM)*sizeof(IS),is);CHKERRQ(ierr);
67647c6ae99SBarry Smith   next = com->next;
67747c6ae99SBarry Smith   ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr);
67847c6ae99SBarry Smith 
67947c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
68047c6ae99SBarry Smith   while (next) {
68147c6ae99SBarry Smith     ierr = PetscMalloc(next->n*sizeof(PetscInt),&idx);CHKERRQ(ierr);
68247c6ae99SBarry Smith     for (i=0; i<next->n; i++) idx[i] = next->grstart + i;
68347c6ae99SBarry Smith     ierr = ISCreateGeneral(((PetscObject)dm)->comm,next->n,idx,PETSC_OWN_POINTER,&(*is)[cnt]);CHKERRQ(ierr);
68447c6ae99SBarry Smith     cnt++;
68547c6ae99SBarry Smith     next = next->next;
68647c6ae99SBarry Smith   }
68747c6ae99SBarry Smith   PetscFunctionReturn(0);
68847c6ae99SBarry Smith }
68947c6ae99SBarry Smith 
690*4d343eeaSMatthew G Knepley #undef __FUNCT__
691*4d343eeaSMatthew G Knepley #define __FUNCT__ "DMCreateFieldIS_Composite"
692*4d343eeaSMatthew G Knepley PetscErrorCode DMCreateFieldIS_Composite(DM dm, PetscInt *numFields, const char ***fieldNames, IS **fields)
693*4d343eeaSMatthew G Knepley {
694*4d343eeaSMatthew G Knepley   PetscInt       nDM;
695*4d343eeaSMatthew G Knepley   DM            *dms;
696*4d343eeaSMatthew G Knepley   PetscInt       i;
697*4d343eeaSMatthew G Knepley   PetscErrorCode ierr;
698*4d343eeaSMatthew G Knepley 
699*4d343eeaSMatthew G Knepley   PetscFunctionBegin;
700*4d343eeaSMatthew G Knepley   ierr = DMCompositeGetNumberDM(dm, &nDM);CHKERRQ(ierr);
701*4d343eeaSMatthew G Knepley   if (numFields) {*numFields = nDM;}
702*4d343eeaSMatthew G Knepley   ierr = DMCompositeGetGlobalISs(dm, fields);CHKERRQ(ierr);
703*4d343eeaSMatthew G Knepley   if (fieldNames) {
704*4d343eeaSMatthew G Knepley     ierr = PetscMalloc(nDM*sizeof(DM), &dms);CHKERRQ(ierr);
705*4d343eeaSMatthew G Knepley     ierr = PetscMalloc(nDM*sizeof(const char *), fieldNames);CHKERRQ(ierr);
706*4d343eeaSMatthew G Knepley     ierr = DMCompositeGetEntriesArray(dm, dms);CHKERRQ(ierr);
707*4d343eeaSMatthew G Knepley     for (i=0; i<nDM; i++) {
708*4d343eeaSMatthew G Knepley       char buf[256];
709*4d343eeaSMatthew G Knepley       const char *splitname;
710*4d343eeaSMatthew G Knepley 
711*4d343eeaSMatthew G Knepley       /* Split naming precedence: object name, prefix, number */
712*4d343eeaSMatthew G Knepley       splitname = ((PetscObject) dm)->name;
713*4d343eeaSMatthew G Knepley       if (!splitname) {
714*4d343eeaSMatthew G Knepley         ierr = PetscObjectGetOptionsPrefix((PetscObject)dms[i],&splitname);CHKERRQ(ierr);
715*4d343eeaSMatthew G Knepley         if (splitname) {
716*4d343eeaSMatthew G Knepley           size_t len;
717*4d343eeaSMatthew G Knepley           ierr = PetscStrncpy(buf,splitname,sizeof buf);CHKERRQ(ierr);
718*4d343eeaSMatthew G Knepley           buf[sizeof buf - 1] = 0;
719*4d343eeaSMatthew G Knepley           ierr = PetscStrlen(buf,&len);CHKERRQ(ierr);
720*4d343eeaSMatthew G Knepley           if (buf[len-1] == '_') buf[len-1] = 0; /* Remove trailing underscore if it was used */
721*4d343eeaSMatthew G Knepley           splitname = buf;
722*4d343eeaSMatthew G Knepley         }
723*4d343eeaSMatthew G Knepley       }
724*4d343eeaSMatthew G Knepley       if (!splitname) {
725*4d343eeaSMatthew G Knepley         ierr = PetscSNPrintf(buf,sizeof buf,"%D",i);CHKERRQ(ierr);
726*4d343eeaSMatthew G Knepley         splitname = buf;
727*4d343eeaSMatthew G Knepley       }
728*4d343eeaSMatthew G Knepley       (*fieldNames)[i] = splitname;
729*4d343eeaSMatthew G Knepley     }
730*4d343eeaSMatthew G Knepley     ierr = PetscFree(dms);CHKERRQ(ierr);
731*4d343eeaSMatthew G Knepley   }
732*4d343eeaSMatthew G Knepley   PetscFunctionReturn(0);
733*4d343eeaSMatthew G Knepley }
734*4d343eeaSMatthew G Knepley 
73547c6ae99SBarry Smith /* -------------------------------------------------------------------------------------*/
73647c6ae99SBarry Smith #undef __FUNCT__
73747c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetLocalVectors"
73847c6ae99SBarry Smith /*@C
7399ae5db72SJed Brown     DMCompositeGetLocalVectors - Gets local vectors for each part of a DMComposite.
74047c6ae99SBarry Smith        Use DMCompositeRestoreLocalVectors() to return them.
74147c6ae99SBarry Smith 
74247c6ae99SBarry Smith     Not Collective
74347c6ae99SBarry Smith 
74447c6ae99SBarry Smith     Input Parameter:
74547c6ae99SBarry Smith .    dm - the packer object
74647c6ae99SBarry Smith 
74747c6ae99SBarry Smith     Output Parameter:
7489ae5db72SJed Brown .   Vec ... - the individual sequential Vecs
74947c6ae99SBarry Smith 
75047c6ae99SBarry Smith     Level: advanced
75147c6ae99SBarry Smith 
7529ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
7536eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
75447c6ae99SBarry Smith          DMCompositeRestoreLocalVectors(), DMCompositeScatter(), DMCompositeGetEntries()
75547c6ae99SBarry Smith 
75647c6ae99SBarry Smith @*/
7577087cfbeSBarry Smith PetscErrorCode  DMCompositeGetLocalVectors(DM dm,...)
75847c6ae99SBarry Smith {
75947c6ae99SBarry Smith   va_list                Argp;
76047c6ae99SBarry Smith   PetscErrorCode         ierr;
76147c6ae99SBarry Smith   struct DMCompositeLink *next;
76247c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
76347c6ae99SBarry Smith 
76447c6ae99SBarry Smith   PetscFunctionBegin;
76547c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
76647c6ae99SBarry Smith   next = com->next;
76747c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
76847c6ae99SBarry Smith   va_start(Argp,dm);
76947c6ae99SBarry Smith   while (next) {
77047c6ae99SBarry Smith     Vec *vec;
77147c6ae99SBarry Smith     vec = va_arg(Argp, Vec*);
7729ae5db72SJed Brown     ierr = DMGetLocalVector(next->dm,vec);CHKERRQ(ierr);
77347c6ae99SBarry Smith     next = next->next;
77447c6ae99SBarry Smith   }
77547c6ae99SBarry Smith   va_end(Argp);
77647c6ae99SBarry Smith   PetscFunctionReturn(0);
77747c6ae99SBarry Smith }
77847c6ae99SBarry Smith 
77947c6ae99SBarry Smith #undef __FUNCT__
78047c6ae99SBarry Smith #define __FUNCT__ "DMCompositeRestoreLocalVectors"
78147c6ae99SBarry Smith /*@C
7829ae5db72SJed Brown     DMCompositeRestoreLocalVectors - Restores local vectors for each part of a DMComposite.
78347c6ae99SBarry Smith 
78447c6ae99SBarry Smith     Not Collective
78547c6ae99SBarry Smith 
78647c6ae99SBarry Smith     Input Parameter:
78747c6ae99SBarry Smith .    dm - the packer object
78847c6ae99SBarry Smith 
78947c6ae99SBarry Smith     Output Parameter:
7909ae5db72SJed Brown .   Vec ... - the individual sequential Vecs
79147c6ae99SBarry Smith 
79247c6ae99SBarry Smith     Level: advanced
79347c6ae99SBarry Smith 
7949ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
7956eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
79647c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeScatter(), DMCompositeGetEntries()
79747c6ae99SBarry Smith 
79847c6ae99SBarry Smith @*/
7997087cfbeSBarry Smith PetscErrorCode  DMCompositeRestoreLocalVectors(DM dm,...)
80047c6ae99SBarry Smith {
80147c6ae99SBarry Smith   va_list                Argp;
80247c6ae99SBarry Smith   PetscErrorCode         ierr;
80347c6ae99SBarry Smith   struct DMCompositeLink *next;
80447c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
80547c6ae99SBarry Smith 
80647c6ae99SBarry Smith   PetscFunctionBegin;
80747c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
80847c6ae99SBarry Smith   next = com->next;
80947c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
81047c6ae99SBarry Smith   va_start(Argp,dm);
81147c6ae99SBarry Smith   while (next) {
81247c6ae99SBarry Smith     Vec *vec;
81347c6ae99SBarry Smith     vec = va_arg(Argp, Vec*);
8149ae5db72SJed Brown     ierr = DMRestoreLocalVector(next->dm,vec);CHKERRQ(ierr);
81547c6ae99SBarry Smith     next = next->next;
81647c6ae99SBarry Smith   }
81747c6ae99SBarry Smith   va_end(Argp);
81847c6ae99SBarry Smith   PetscFunctionReturn(0);
81947c6ae99SBarry Smith }
82047c6ae99SBarry Smith 
82147c6ae99SBarry Smith /* -------------------------------------------------------------------------------------*/
82247c6ae99SBarry Smith #undef __FUNCT__
82347c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetEntries"
82447c6ae99SBarry Smith /*@C
8259ae5db72SJed Brown     DMCompositeGetEntries - Gets the DM for each entry in a DMComposite.
82647c6ae99SBarry Smith 
82747c6ae99SBarry Smith     Not Collective
82847c6ae99SBarry Smith 
82947c6ae99SBarry Smith     Input Parameter:
83047c6ae99SBarry Smith .    dm - the packer object
83147c6ae99SBarry Smith 
83247c6ae99SBarry Smith     Output Parameter:
8339ae5db72SJed Brown .   DM ... - the individual entries (DMs)
83447c6ae99SBarry Smith 
83547c6ae99SBarry Smith     Level: advanced
83647c6ae99SBarry Smith 
8372fa5ba8aSJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), DMCompositeGetEntriesArray()
8386eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
83947c6ae99SBarry Smith          DMCompositeRestoreLocalVectors(), DMCompositeGetLocalVectors(),  DMCompositeScatter(),
84047c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors()
84147c6ae99SBarry Smith 
84247c6ae99SBarry Smith @*/
8437087cfbeSBarry Smith PetscErrorCode  DMCompositeGetEntries(DM dm,...)
84447c6ae99SBarry Smith {
84547c6ae99SBarry Smith   va_list                Argp;
84647c6ae99SBarry Smith   struct DMCompositeLink *next;
84747c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
84847c6ae99SBarry Smith 
84947c6ae99SBarry Smith   PetscFunctionBegin;
85047c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
85147c6ae99SBarry Smith   next = com->next;
85247c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
85347c6ae99SBarry Smith   va_start(Argp,dm);
85447c6ae99SBarry Smith   while (next) {
85547c6ae99SBarry Smith     DM *dmn;
85647c6ae99SBarry Smith     dmn = va_arg(Argp, DM*);
8579ae5db72SJed Brown     if (dmn) *dmn = next->dm;
85847c6ae99SBarry Smith     next = next->next;
85947c6ae99SBarry Smith   }
86047c6ae99SBarry Smith   va_end(Argp);
86147c6ae99SBarry Smith   PetscFunctionReturn(0);
86247c6ae99SBarry Smith }
86347c6ae99SBarry Smith 
86447c6ae99SBarry Smith #undef __FUNCT__
8652fa5ba8aSJed Brown #define __FUNCT__ "DMCompositeGetEntriesArray"
8662fa5ba8aSJed Brown /*@
8672fa5ba8aSJed Brown     DMCompositeGetEntriesArray - Gets the DM for each entry in a DMComposite.
8682fa5ba8aSJed Brown 
8692fa5ba8aSJed Brown     Not Collective
8702fa5ba8aSJed Brown 
8712fa5ba8aSJed Brown     Input Parameter:
8722fa5ba8aSJed Brown +    dm - the packer object
8732fa5ba8aSJed Brown -    dms - array of sufficient length (see DMCompositeGetNumberDM()), holds the DMs on output
8742fa5ba8aSJed Brown 
8752fa5ba8aSJed Brown     Level: advanced
8762fa5ba8aSJed Brown 
8772fa5ba8aSJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), DMCompositeGetEntries()
8782fa5ba8aSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
8792fa5ba8aSJed Brown          DMCompositeRestoreLocalVectors(), DMCompositeGetLocalVectors(),  DMCompositeScatter(),
8802fa5ba8aSJed Brown          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors()
8812fa5ba8aSJed Brown 
8822fa5ba8aSJed Brown @*/
8832fa5ba8aSJed Brown PetscErrorCode DMCompositeGetEntriesArray(DM dm,DM dms[])
8842fa5ba8aSJed Brown {
8852fa5ba8aSJed Brown   struct DMCompositeLink *next;
8862fa5ba8aSJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
8872fa5ba8aSJed Brown   PetscInt               i;
8882fa5ba8aSJed Brown 
8892fa5ba8aSJed Brown   PetscFunctionBegin;
8902fa5ba8aSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
8912fa5ba8aSJed Brown   /* loop over packed objects, handling one at at time */
8922fa5ba8aSJed Brown   for (next=com->next,i=0; next; next=next->next,i++) dms[i] = next->dm;
8932fa5ba8aSJed Brown   PetscFunctionReturn(0);
8942fa5ba8aSJed Brown }
8952fa5ba8aSJed Brown 
8962fa5ba8aSJed Brown #undef __FUNCT__
8970c010503SBarry Smith #define __FUNCT__ "DMRefine_Composite"
8987087cfbeSBarry Smith PetscErrorCode  DMRefine_Composite(DM dmi,MPI_Comm comm,DM *fine)
89947c6ae99SBarry Smith {
90047c6ae99SBarry Smith   PetscErrorCode         ierr;
90147c6ae99SBarry Smith   struct DMCompositeLink *next;
90247c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dmi->data;
90347c6ae99SBarry Smith   DM                     dm;
90447c6ae99SBarry Smith 
90547c6ae99SBarry Smith   PetscFunctionBegin;
90647c6ae99SBarry Smith   PetscValidHeaderSpecific(dmi,DM_CLASSID,1);
9072ce3a92bSJed Brown   ierr = DMSetUp(dmi);CHKERRQ(ierr);
90847c6ae99SBarry Smith   next = com->next;
90947c6ae99SBarry Smith   ierr = DMCompositeCreate(comm,fine);CHKERRQ(ierr);
91047c6ae99SBarry Smith 
91147c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
91247c6ae99SBarry Smith   while (next) {
91347c6ae99SBarry Smith     ierr = DMRefine(next->dm,comm,&dm);CHKERRQ(ierr);
91447c6ae99SBarry Smith     ierr = DMCompositeAddDM(*fine,dm);CHKERRQ(ierr);
91547c6ae99SBarry Smith     ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr);
91647c6ae99SBarry Smith     next = next->next;
91747c6ae99SBarry Smith   }
91847c6ae99SBarry Smith   PetscFunctionReturn(0);
91947c6ae99SBarry Smith }
92047c6ae99SBarry Smith 
92114354c39SJed Brown #undef __FUNCT__
92214354c39SJed Brown #define __FUNCT__ "DMCoarsen_Composite"
92314354c39SJed Brown PetscErrorCode  DMCoarsen_Composite(DM dmi,MPI_Comm comm,DM *fine)
92414354c39SJed Brown {
92514354c39SJed Brown   PetscErrorCode         ierr;
92614354c39SJed Brown   struct DMCompositeLink *next;
92714354c39SJed Brown   DM_Composite           *com = (DM_Composite*)dmi->data;
92814354c39SJed Brown   DM                     dm;
92914354c39SJed Brown 
93014354c39SJed Brown   PetscFunctionBegin;
93114354c39SJed Brown   PetscValidHeaderSpecific(dmi,DM_CLASSID,1);
9322ce3a92bSJed Brown   ierr = DMSetUp(dmi);CHKERRQ(ierr);
93325296bd5SBarry Smith   if (!comm) {
93425296bd5SBarry Smith     ierr = PetscObjectGetComm((PetscObject)dmi,&comm);CHKERRQ(ierr);
93525296bd5SBarry Smith   }
93614354c39SJed Brown   next = com->next;
93714354c39SJed Brown   ierr = DMCompositeCreate(comm,fine);CHKERRQ(ierr);
93814354c39SJed Brown 
93914354c39SJed Brown   /* loop over packed objects, handling one at at time */
94014354c39SJed Brown   while (next) {
94114354c39SJed Brown     ierr = DMCoarsen(next->dm,comm,&dm);CHKERRQ(ierr);
94214354c39SJed Brown     ierr = DMCompositeAddDM(*fine,dm);CHKERRQ(ierr);
94314354c39SJed Brown     ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr);
94414354c39SJed Brown     next = next->next;
94514354c39SJed Brown   }
94614354c39SJed Brown   PetscFunctionReturn(0);
94714354c39SJed Brown }
94847c6ae99SBarry Smith 
94947c6ae99SBarry Smith #undef __FUNCT__
950e727c939SJed Brown #define __FUNCT__ "DMCreateInterpolation_Composite"
951e727c939SJed Brown PetscErrorCode  DMCreateInterpolation_Composite(DM coarse,DM fine,Mat *A,Vec *v)
95247c6ae99SBarry Smith {
95347c6ae99SBarry Smith   PetscErrorCode         ierr;
9549ae5db72SJed Brown   PetscInt               m,n,M,N,nDM,i;
95547c6ae99SBarry Smith   struct DMCompositeLink *nextc;
95647c6ae99SBarry Smith   struct DMCompositeLink *nextf;
95725296bd5SBarry Smith   Vec                    gcoarse,gfine,*vecs;
95847c6ae99SBarry Smith   DM_Composite           *comcoarse = (DM_Composite*)coarse->data;
95947c6ae99SBarry Smith   DM_Composite           *comfine = (DM_Composite*)fine->data;
9609ae5db72SJed Brown   Mat                    *mats;
96147c6ae99SBarry Smith 
96247c6ae99SBarry Smith   PetscFunctionBegin;
96347c6ae99SBarry Smith   PetscValidHeaderSpecific(coarse,DM_CLASSID,1);
96447c6ae99SBarry Smith   PetscValidHeaderSpecific(fine,DM_CLASSID,2);
965f692024eSJed Brown   ierr = DMSetUp(coarse);CHKERRQ(ierr);
966f692024eSJed Brown   ierr = DMSetUp(fine);CHKERRQ(ierr);
96747c6ae99SBarry Smith   /* use global vectors only for determining matrix layout */
9689ae5db72SJed Brown   ierr = DMGetGlobalVector(coarse,&gcoarse);CHKERRQ(ierr);
9699ae5db72SJed Brown   ierr = DMGetGlobalVector(fine,&gfine);CHKERRQ(ierr);
97047c6ae99SBarry Smith   ierr = VecGetLocalSize(gcoarse,&n);CHKERRQ(ierr);
97147c6ae99SBarry Smith   ierr = VecGetLocalSize(gfine,&m);CHKERRQ(ierr);
97247c6ae99SBarry Smith   ierr = VecGetSize(gcoarse,&N);CHKERRQ(ierr);
97347c6ae99SBarry Smith   ierr = VecGetSize(gfine,&M);CHKERRQ(ierr);
9749ae5db72SJed Brown   ierr = DMRestoreGlobalVector(coarse,&gcoarse);CHKERRQ(ierr);
9759ae5db72SJed Brown   ierr = DMRestoreGlobalVector(fine,&gfine);CHKERRQ(ierr);
97647c6ae99SBarry Smith 
9779ae5db72SJed Brown   nDM = comfine->nDM;
9789ae5db72SJed Brown   if (nDM != comcoarse->nDM) SETERRQ2(((PetscObject)fine)->comm,PETSC_ERR_ARG_INCOMP,"Fine DMComposite has %D entries, but coarse has %D",nDM,comcoarse->nDM);
9799ae5db72SJed Brown   ierr = PetscMalloc(nDM*nDM*sizeof(Mat),&mats);CHKERRQ(ierr);
9809ae5db72SJed Brown   ierr = PetscMemzero(mats,nDM*nDM*sizeof(Mat));CHKERRQ(ierr);
98125296bd5SBarry Smith   if (v) {
98225296bd5SBarry Smith     ierr = PetscMalloc(nDM*sizeof(Vec),&vecs);CHKERRQ(ierr);
98325296bd5SBarry Smith     ierr = PetscMemzero(vecs,nDM*sizeof(Vec));CHKERRQ(ierr);
98425296bd5SBarry Smith   }
98547c6ae99SBarry Smith 
98647c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
9879ae5db72SJed Brown   for (nextc=comcoarse->next,nextf=comfine->next,i=0; nextc; nextc=nextc->next,nextf=nextf->next,i++) {
98825296bd5SBarry Smith     if (!v) {
989e727c939SJed Brown       ierr = DMCreateInterpolation(nextc->dm,nextf->dm,&mats[i*nDM+i],PETSC_NULL);CHKERRQ(ierr);
99025296bd5SBarry Smith     } else {
99125296bd5SBarry Smith       ierr = DMCreateInterpolation(nextc->dm,nextf->dm,&mats[i*nDM+i],&vecs[i]);CHKERRQ(ierr);
99225296bd5SBarry Smith     }
99347c6ae99SBarry Smith   }
9949ae5db72SJed Brown   ierr = MatCreateNest(((PetscObject)fine)->comm,nDM,PETSC_NULL,nDM,PETSC_NULL,mats,A);CHKERRQ(ierr);
99525296bd5SBarry Smith   if (v) {
99625296bd5SBarry Smith     ierr = VecCreateNest(((PetscObject)fine)->comm,nDM,PETSC_NULL,vecs,v);CHKERRQ(ierr);
99725296bd5SBarry Smith   }
9989ae5db72SJed Brown   for (i=0; i<nDM*nDM; i++) {ierr = MatDestroy(&mats[i]);CHKERRQ(ierr);}
9999ae5db72SJed Brown   ierr = PetscFree(mats);CHKERRQ(ierr);
100025296bd5SBarry Smith   if (v) {
100125296bd5SBarry Smith     for (i=0; i<nDM; i++) {ierr = VecDestroy(&vecs[i]);CHKERRQ(ierr);}
100225296bd5SBarry Smith     ierr = PetscFree(vecs);CHKERRQ(ierr);
100325296bd5SBarry Smith   }
100447c6ae99SBarry Smith   PetscFunctionReturn(0);
100547c6ae99SBarry Smith }
100647c6ae99SBarry Smith 
100747c6ae99SBarry Smith #undef __FUNCT__
10081411c6eeSJed Brown #define __FUNCT__ "DMCreateLocalToGlobalMapping_Composite"
10091411c6eeSJed Brown static PetscErrorCode DMCreateLocalToGlobalMapping_Composite(DM dm)
10101411c6eeSJed Brown {
10111411c6eeSJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
10121411c6eeSJed Brown   ISLocalToGlobalMapping *ltogs;
1013f7efa3c7SJed Brown   PetscInt               i;
10141411c6eeSJed Brown   PetscErrorCode         ierr;
10151411c6eeSJed Brown 
10161411c6eeSJed Brown   PetscFunctionBegin;
10171411c6eeSJed Brown   /* Set the ISLocalToGlobalMapping on the new matrix */
10181411c6eeSJed Brown   ierr = DMCompositeGetISLocalToGlobalMappings(dm,&ltogs);CHKERRQ(ierr);
10199ae5db72SJed Brown   ierr = ISLocalToGlobalMappingConcatenate(((PetscObject)dm)->comm,com->nDM,ltogs,&dm->ltogmap);CHKERRQ(ierr);
10209ae5db72SJed Brown   for (i=0; i<com->nDM; i++) {ierr = ISLocalToGlobalMappingDestroy(&ltogs[i]);CHKERRQ(ierr);}
10211411c6eeSJed Brown   ierr = PetscFree(ltogs);CHKERRQ(ierr);
10221411c6eeSJed Brown   PetscFunctionReturn(0);
10231411c6eeSJed Brown }
10241411c6eeSJed Brown 
10251411c6eeSJed Brown 
10261411c6eeSJed Brown #undef __FUNCT__
1027e727c939SJed Brown #define __FUNCT__ "DMCreateColoring_Composite"
1028e727c939SJed Brown PetscErrorCode  DMCreateColoring_Composite(DM dm,ISColoringType ctype,const MatType mtype,ISColoring *coloring)
102947c6ae99SBarry Smith {
103047c6ae99SBarry Smith   PetscErrorCode         ierr;
103147c6ae99SBarry Smith   PetscInt               n,i,cnt;
103247c6ae99SBarry Smith   ISColoringValue        *colors;
103347c6ae99SBarry Smith   PetscBool              dense = PETSC_FALSE;
103447c6ae99SBarry Smith   ISColoringValue        maxcol = 0;
103547c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
103647c6ae99SBarry Smith 
103747c6ae99SBarry Smith   PetscFunctionBegin;
103847c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
103947c6ae99SBarry Smith   if (ctype == IS_COLORING_GHOSTED) {
104047c6ae99SBarry Smith     SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"Currently you must use -dmmg_iscoloring_type global" );
104147c6ae99SBarry Smith   } else if (ctype == IS_COLORING_GLOBAL) {
104247c6ae99SBarry Smith     n = com->n;
104347c6ae99SBarry Smith   } else SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Unknown ISColoringType");
104447c6ae99SBarry Smith   ierr = PetscMalloc(n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr); /* freed in ISColoringDestroy() */
104547c6ae99SBarry Smith 
1046671f6225SBarry Smith   ierr = PetscOptionsGetBool(PETSC_NULL,"-dmcomposite_dense_jacobian",&dense,PETSC_NULL);CHKERRQ(ierr);
104747c6ae99SBarry Smith   if (dense) {
104847c6ae99SBarry Smith     for (i=0; i<n; i++) {
104947c6ae99SBarry Smith       colors[i] = (ISColoringValue)(com->rstart + i);
105047c6ae99SBarry Smith     }
105147c6ae99SBarry Smith     maxcol = com->N;
105247c6ae99SBarry Smith   } else {
105347c6ae99SBarry Smith     struct DMCompositeLink *next = com->next;
105447c6ae99SBarry Smith     PetscMPIInt            rank;
105547c6ae99SBarry Smith 
105647c6ae99SBarry Smith     ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr);
105747c6ae99SBarry Smith     cnt  = 0;
105847c6ae99SBarry Smith     while (next) {
105947c6ae99SBarry Smith       ISColoring     lcoloring;
106047c6ae99SBarry Smith 
1061e727c939SJed Brown       ierr = DMCreateColoring(next->dm,IS_COLORING_GLOBAL,mtype,&lcoloring);CHKERRQ(ierr);
106247c6ae99SBarry Smith       for (i=0; i<lcoloring->N; i++) {
106347c6ae99SBarry Smith         colors[cnt++] = maxcol + lcoloring->colors[i];
106447c6ae99SBarry Smith       }
106547c6ae99SBarry Smith       maxcol += lcoloring->n;
1066fcfd50ebSBarry Smith       ierr = ISColoringDestroy(&lcoloring);CHKERRQ(ierr);
106747c6ae99SBarry Smith       next = next->next;
106847c6ae99SBarry Smith     }
106947c6ae99SBarry Smith   }
107047c6ae99SBarry Smith   ierr = ISColoringCreate(((PetscObject)dm)->comm,maxcol,n,colors,coloring);CHKERRQ(ierr);
107147c6ae99SBarry Smith   PetscFunctionReturn(0);
107247c6ae99SBarry Smith }
107347c6ae99SBarry Smith 
107447c6ae99SBarry Smith #undef __FUNCT__
10750c010503SBarry Smith #define __FUNCT__ "DMGlobalToLocalBegin_Composite"
10767087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalBegin_Composite(DM dm,Vec gvec,InsertMode mode,Vec lvec)
107747c6ae99SBarry Smith {
107847c6ae99SBarry Smith   PetscErrorCode         ierr;
107947c6ae99SBarry Smith   struct DMCompositeLink *next;
108047c6ae99SBarry Smith   PetscInt               cnt = 3;
108147c6ae99SBarry Smith   PetscMPIInt            rank;
108247c6ae99SBarry Smith   PetscScalar            *garray,*larray;
108347c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
108447c6ae99SBarry Smith 
108547c6ae99SBarry Smith   PetscFunctionBegin;
108647c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
108747c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
108847c6ae99SBarry Smith   next = com->next;
108947c6ae99SBarry Smith   if (!com->setup) {
1090d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
109147c6ae99SBarry Smith   }
109247c6ae99SBarry Smith   ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr);
109347c6ae99SBarry Smith   ierr = VecGetArray(gvec,&garray);CHKERRQ(ierr);
109447c6ae99SBarry Smith   ierr = VecGetArray(lvec,&larray);CHKERRQ(ierr);
109547c6ae99SBarry Smith 
109647c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
109747c6ae99SBarry Smith   while (next) {
109847c6ae99SBarry Smith     Vec      local,global;
109947c6ae99SBarry Smith     PetscInt N;
110047c6ae99SBarry Smith 
110147c6ae99SBarry Smith     ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
110247c6ae99SBarry Smith     ierr = VecGetLocalSize(global,&N);CHKERRQ(ierr);
110347c6ae99SBarry Smith     ierr = VecPlaceArray(global,garray);CHKERRQ(ierr);
110447c6ae99SBarry Smith     ierr = DMGetLocalVector(next->dm,&local);CHKERRQ(ierr);
110547c6ae99SBarry Smith     ierr = VecPlaceArray(local,larray);CHKERRQ(ierr);
110647c6ae99SBarry Smith     ierr = DMGlobalToLocalBegin(next->dm,global,mode,local);CHKERRQ(ierr);
110747c6ae99SBarry Smith     ierr = DMGlobalToLocalEnd(next->dm,global,mode,local);CHKERRQ(ierr);
110847c6ae99SBarry Smith     ierr = VecResetArray(global);CHKERRQ(ierr);
110947c6ae99SBarry Smith     ierr = VecResetArray(local);CHKERRQ(ierr);
111047c6ae99SBarry Smith     ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
111147c6ae99SBarry Smith     ierr = DMRestoreGlobalVector(next->dm,&local);CHKERRQ(ierr);
111247c6ae99SBarry Smith     cnt++;
111306ebdd98SJed Brown     larray += next->nlocal;
111447c6ae99SBarry Smith     next    = next->next;
111547c6ae99SBarry Smith   }
111647c6ae99SBarry Smith 
111747c6ae99SBarry Smith   ierr = VecRestoreArray(gvec,PETSC_NULL);CHKERRQ(ierr);
111847c6ae99SBarry Smith   ierr = VecRestoreArray(lvec,PETSC_NULL);CHKERRQ(ierr);
111947c6ae99SBarry Smith   PetscFunctionReturn(0);
112047c6ae99SBarry Smith }
112147c6ae99SBarry Smith 
112247c6ae99SBarry Smith #undef __FUNCT__
11230c010503SBarry Smith #define __FUNCT__ "DMGlobalToLocalEnd_Composite"
11247087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalEnd_Composite(DM dm,Vec gvec,InsertMode mode,Vec lvec)
11250c010503SBarry Smith {
11260c010503SBarry Smith   PetscFunctionBegin;
11270c010503SBarry Smith   PetscFunctionReturn(0);
11280c010503SBarry Smith }
112947c6ae99SBarry Smith 
1130a4121054SBarry Smith EXTERN_C_BEGIN
1131a4121054SBarry Smith #undef __FUNCT__
1132a4121054SBarry Smith #define __FUNCT__ "DMCreate_Composite"
11337087cfbeSBarry Smith PetscErrorCode  DMCreate_Composite(DM p)
1134a4121054SBarry Smith {
1135a4121054SBarry Smith   PetscErrorCode ierr;
1136a4121054SBarry Smith   DM_Composite   *com;
1137a4121054SBarry Smith 
1138a4121054SBarry Smith   PetscFunctionBegin;
1139a4121054SBarry Smith   ierr = PetscNewLog(p,DM_Composite,&com);CHKERRQ(ierr);
1140a4121054SBarry Smith   p->data = com;
1141a4121054SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)p,"DMComposite");CHKERRQ(ierr);
1142a4121054SBarry Smith   com->n            = 0;
1143a4121054SBarry Smith   com->next         = PETSC_NULL;
1144a4121054SBarry Smith   com->nDM          = 0;
1145a4121054SBarry Smith 
1146a4121054SBarry Smith   p->ops->createglobalvector              = DMCreateGlobalVector_Composite;
1147a4121054SBarry Smith   p->ops->createlocalvector               = DMCreateLocalVector_Composite;
11481411c6eeSJed Brown   p->ops->createlocaltoglobalmapping      = DMCreateLocalToGlobalMapping_Composite;
11491411c6eeSJed Brown   p->ops->createlocaltoglobalmappingblock = 0;
1150*4d343eeaSMatthew G Knepley   p->ops->createfieldis                   = DMCreateFieldIS_Composite;
1151a4121054SBarry Smith   p->ops->refine                          = DMRefine_Composite;
115214354c39SJed Brown   p->ops->coarsen                         = DMCoarsen_Composite;
115325296bd5SBarry Smith   p->ops->createinterpolation                = DMCreateInterpolation_Composite;
115425296bd5SBarry Smith   p->ops->creatematrix                       = DMCreateMatrix_Composite;
1155e727c939SJed Brown   p->ops->getcoloring                     = DMCreateColoring_Composite;
1156a4121054SBarry Smith   p->ops->globaltolocalbegin              = DMGlobalToLocalBegin_Composite;
1157a4121054SBarry Smith   p->ops->globaltolocalend                = DMGlobalToLocalEnd_Composite;
1158a4121054SBarry Smith   p->ops->destroy                         = DMDestroy_Composite;
1159a4121054SBarry Smith   p->ops->view                            = DMView_Composite;
1160a4121054SBarry Smith   p->ops->setup                           = DMSetUp_Composite;
1161a4121054SBarry Smith   PetscFunctionReturn(0);
1162a4121054SBarry Smith }
1163a4121054SBarry Smith EXTERN_C_END
1164a4121054SBarry Smith 
11650c010503SBarry Smith #undef __FUNCT__
11660c010503SBarry Smith #define __FUNCT__ "DMCompositeCreate"
11670c010503SBarry Smith /*@C
11680c010503SBarry Smith     DMCompositeCreate - Creates a vector packer, used to generate "composite"
11690c010503SBarry Smith       vectors made up of several subvectors.
11700c010503SBarry Smith 
11710c010503SBarry Smith     Collective on MPI_Comm
117247c6ae99SBarry Smith 
117347c6ae99SBarry Smith     Input Parameter:
11740c010503SBarry Smith .   comm - the processors that will share the global vector
11750c010503SBarry Smith 
11760c010503SBarry Smith     Output Parameters:
11770c010503SBarry Smith .   packer - the packer object
117847c6ae99SBarry Smith 
117947c6ae99SBarry Smith     Level: advanced
118047c6ae99SBarry Smith 
11819ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCompositeScatter(),
11826eb61c8cSJed Brown          DMCompositeGather(), DMCreateGlobalVector(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess()
118347c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries()
118447c6ae99SBarry Smith 
118547c6ae99SBarry Smith @*/
11867087cfbeSBarry Smith PetscErrorCode  DMCompositeCreate(MPI_Comm comm,DM *packer)
118747c6ae99SBarry Smith {
11880c010503SBarry Smith   PetscErrorCode ierr;
11890c010503SBarry Smith 
119047c6ae99SBarry Smith   PetscFunctionBegin;
11910c010503SBarry Smith   PetscValidPointer(packer,2);
1192a4121054SBarry Smith   ierr = DMCreate(comm,packer);CHKERRQ(ierr);
1193a4121054SBarry Smith   ierr = DMSetType(*packer,DMCOMPOSITE);CHKERRQ(ierr);
119447c6ae99SBarry Smith   PetscFunctionReturn(0);
119547c6ae99SBarry Smith }
1196