xref: /petsc/src/dm/impls/composite/pack.c (revision c688c0463f6c25494d0d243b2a43b2b3454e025c)
147c6ae99SBarry Smith 
2ccd284c7SBarry Smith #include <../src/dm/impls/composite/packimpl.h>       /*I  "petscdmcomposite.h"  I*/
347c6ae99SBarry Smith 
447c6ae99SBarry Smith #undef __FUNCT__
547c6ae99SBarry Smith #define __FUNCT__ "DMCompositeSetCoupling"
647c6ae99SBarry Smith /*@C
747c6ae99SBarry Smith     DMCompositeSetCoupling - Sets user provided routines that compute the coupling between the
89ae5db72SJed Brown       seperate components (DMs) in a DMto build the correct matrix nonzero structure.
947c6ae99SBarry Smith 
1047c6ae99SBarry Smith 
1147c6ae99SBarry Smith     Logically Collective on MPI_Comm
1247c6ae99SBarry Smith 
1347c6ae99SBarry Smith     Input Parameter:
1447c6ae99SBarry Smith +   dm - the composite object
1547c6ae99SBarry Smith -   formcouplelocations - routine to set the nonzero locations in the matrix
1647c6ae99SBarry Smith 
1747c6ae99SBarry Smith     Level: advanced
1847c6ae99SBarry Smith 
191b2093e4SBarry Smith     Notes: See DMSetApplicationContext() and DMGetApplicationContext() for how to get user information into
2047c6ae99SBarry Smith         this routine
2147c6ae99SBarry Smith 
2247c6ae99SBarry Smith @*/
237087cfbeSBarry Smith PetscErrorCode  DMCompositeSetCoupling(DM dm,PetscErrorCode (*FormCoupleLocations)(DM,Mat,PetscInt*,PetscInt*,PetscInt,PetscInt,PetscInt,PetscInt))
2447c6ae99SBarry Smith {
2547c6ae99SBarry Smith   DM_Composite *com = (DM_Composite*)dm->data;
2647c6ae99SBarry Smith 
2747c6ae99SBarry Smith   PetscFunctionBegin;
2847c6ae99SBarry Smith   com->FormCoupleLocations = FormCoupleLocations;
2947c6ae99SBarry Smith   PetscFunctionReturn(0);
3047c6ae99SBarry Smith }
3147c6ae99SBarry Smith 
3247c6ae99SBarry Smith #undef __FUNCT__
330c010503SBarry Smith #define __FUNCT__ "DMDestroy_Composite"
346bf464f9SBarry Smith PetscErrorCode  DMDestroy_Composite(DM dm)
3547c6ae99SBarry Smith {
3647c6ae99SBarry Smith   PetscErrorCode         ierr;
3747c6ae99SBarry Smith   struct DMCompositeLink *next, *prev;
3847c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite *)dm->data;
3947c6ae99SBarry Smith 
4047c6ae99SBarry Smith   PetscFunctionBegin;
4147c6ae99SBarry Smith   next = com->next;
4247c6ae99SBarry Smith   while (next) {
4347c6ae99SBarry Smith     prev = next;
4447c6ae99SBarry Smith     next = next->next;
45fcfd50ebSBarry Smith     ierr = DMDestroy(&prev->dm);CHKERRQ(ierr);
4647c6ae99SBarry Smith     ierr = PetscFree(prev->grstarts);CHKERRQ(ierr);
4747c6ae99SBarry Smith     ierr = PetscFree(prev);CHKERRQ(ierr);
4847c6ae99SBarry Smith   }
49435a35e8SMatthew G Knepley   /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */
50435a35e8SMatthew G Knepley   ierr = PetscFree(com);CHKERRQ(ierr);
5147c6ae99SBarry Smith   PetscFunctionReturn(0);
5247c6ae99SBarry Smith }
5347c6ae99SBarry Smith 
5447c6ae99SBarry Smith #undef __FUNCT__
550c010503SBarry Smith #define __FUNCT__ "DMView_Composite"
567087cfbeSBarry Smith PetscErrorCode  DMView_Composite(DM dm,PetscViewer v)
5747c6ae99SBarry Smith {
5847c6ae99SBarry Smith   PetscErrorCode ierr;
5947c6ae99SBarry Smith   PetscBool      iascii;
6047c6ae99SBarry Smith   DM_Composite   *com = (DM_Composite *)dm->data;
6147c6ae99SBarry Smith 
6247c6ae99SBarry Smith   PetscFunctionBegin;
63251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
6447c6ae99SBarry Smith   if (iascii) {
6547c6ae99SBarry Smith     struct DMCompositeLink *lnk = com->next;
6647c6ae99SBarry Smith     PetscInt               i;
6747c6ae99SBarry Smith 
6847c6ae99SBarry Smith     ierr = PetscViewerASCIIPrintf(v,"DM (%s)\n",((PetscObject)dm)->prefix?((PetscObject)dm)->prefix:"no prefix");CHKERRQ(ierr);
699ae5db72SJed Brown     ierr = PetscViewerASCIIPrintf(v,"  contains %D DMs\n",com->nDM);CHKERRQ(ierr);
7047c6ae99SBarry Smith     ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr);
7147c6ae99SBarry Smith     for (i=0; lnk; lnk=lnk->next,i++) {
729ae5db72SJed Brown       ierr = PetscViewerASCIIPrintf(v,"Link %D: DM of type %s\n",i,((PetscObject)lnk->dm)->type_name);CHKERRQ(ierr);
7347c6ae99SBarry Smith       ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr);
7447c6ae99SBarry Smith       ierr = DMView(lnk->dm,v);CHKERRQ(ierr);
7547c6ae99SBarry Smith       ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr);
7647c6ae99SBarry Smith     }
7747c6ae99SBarry Smith     ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr);
7847c6ae99SBarry Smith   }
7947c6ae99SBarry Smith   PetscFunctionReturn(0);
8047c6ae99SBarry Smith }
8147c6ae99SBarry Smith 
8247c6ae99SBarry Smith /* --------------------------------------------------------------------------------------*/
8347c6ae99SBarry Smith #undef __FUNCT__
84d7bf68aeSBarry Smith #define __FUNCT__ "DMSetUp_Composite"
857087cfbeSBarry Smith PetscErrorCode  DMSetUp_Composite(DM dm)
8647c6ae99SBarry Smith {
8747c6ae99SBarry Smith   PetscErrorCode         ierr;
8847c6ae99SBarry Smith   PetscInt               nprev = 0;
8947c6ae99SBarry Smith   PetscMPIInt            rank,size;
9047c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
9147c6ae99SBarry Smith   struct DMCompositeLink *next = com->next;
9247c6ae99SBarry Smith   PetscLayout            map;
9347c6ae99SBarry Smith 
9447c6ae99SBarry Smith   PetscFunctionBegin;
9547c6ae99SBarry Smith   if (com->setup) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Packer has already been setup");
9647c6ae99SBarry Smith   ierr = PetscLayoutCreate(((PetscObject)dm)->comm,&map);CHKERRQ(ierr);
9747c6ae99SBarry Smith   ierr = PetscLayoutSetLocalSize(map,com->n);CHKERRQ(ierr);
9847c6ae99SBarry Smith   ierr = PetscLayoutSetSize(map,PETSC_DETERMINE);CHKERRQ(ierr);
9947c6ae99SBarry Smith   ierr = PetscLayoutSetBlockSize(map,1);CHKERRQ(ierr);
10047c6ae99SBarry Smith   ierr = PetscLayoutSetUp(map);CHKERRQ(ierr);
10147c6ae99SBarry Smith   ierr = PetscLayoutGetSize(map,&com->N);CHKERRQ(ierr);
10247c6ae99SBarry Smith   ierr = PetscLayoutGetRange(map,&com->rstart,PETSC_NULL);CHKERRQ(ierr);
103fcfd50ebSBarry Smith   ierr = PetscLayoutDestroy(&map);CHKERRQ(ierr);
10447c6ae99SBarry Smith 
1059ae5db72SJed Brown   /* now set the rstart for each linked vector */
10647c6ae99SBarry Smith   ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr);
10747c6ae99SBarry Smith   ierr = MPI_Comm_size(((PetscObject)dm)->comm,&size);CHKERRQ(ierr);
10847c6ae99SBarry Smith   while (next) {
10947c6ae99SBarry Smith     next->rstart = nprev;
11006ebdd98SJed Brown     nprev += next->n;
11147c6ae99SBarry Smith     next->grstart = com->rstart + next->rstart;
11247c6ae99SBarry Smith     ierr = PetscMalloc(size*sizeof(PetscInt),&next->grstarts);CHKERRQ(ierr);
11347c6ae99SBarry Smith     ierr = MPI_Allgather(&next->grstart,1,MPIU_INT,next->grstarts,1,MPIU_INT,((PetscObject)dm)->comm);CHKERRQ(ierr);
11447c6ae99SBarry Smith     next = next->next;
11547c6ae99SBarry Smith   }
11647c6ae99SBarry Smith   com->setup = PETSC_TRUE;
11747c6ae99SBarry Smith   PetscFunctionReturn(0);
11847c6ae99SBarry Smith }
11947c6ae99SBarry Smith 
12047c6ae99SBarry Smith /* ----------------------------------------------------------------------------------*/
12147c6ae99SBarry Smith 
12247c6ae99SBarry Smith #include <stdarg.h>
12347c6ae99SBarry Smith 
12447c6ae99SBarry Smith #undef __FUNCT__
12547c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetNumberDM"
12647c6ae99SBarry Smith /*@C
12747c6ae99SBarry Smith     DMCompositeGetNumberDM - Get's the number of DM objects in the DMComposite
12847c6ae99SBarry Smith        representation.
12947c6ae99SBarry Smith 
13047c6ae99SBarry Smith     Not Collective
13147c6ae99SBarry Smith 
13247c6ae99SBarry Smith     Input Parameter:
13347c6ae99SBarry Smith .    dm - the packer object
13447c6ae99SBarry Smith 
13547c6ae99SBarry Smith     Output Parameter:
13647c6ae99SBarry Smith .     nDM - the number of DMs
13747c6ae99SBarry Smith 
13847c6ae99SBarry Smith     Level: beginner
13947c6ae99SBarry Smith 
14047c6ae99SBarry Smith @*/
1417087cfbeSBarry Smith PetscErrorCode  DMCompositeGetNumberDM(DM dm,PetscInt *nDM)
14247c6ae99SBarry Smith {
14347c6ae99SBarry Smith   DM_Composite *com = (DM_Composite*)dm->data;
14447c6ae99SBarry Smith   PetscFunctionBegin;
14547c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
14647c6ae99SBarry Smith   *nDM = com->nDM;
14747c6ae99SBarry Smith   PetscFunctionReturn(0);
14847c6ae99SBarry Smith }
14947c6ae99SBarry Smith 
15047c6ae99SBarry Smith 
15147c6ae99SBarry Smith #undef __FUNCT__
15247c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetAccess"
15347c6ae99SBarry Smith /*@C
15447c6ae99SBarry Smith     DMCompositeGetAccess - Allows one to access the individual packed vectors in their global
15547c6ae99SBarry Smith        representation.
15647c6ae99SBarry Smith 
15747c6ae99SBarry Smith     Collective on DMComposite
15847c6ae99SBarry Smith 
1599ae5db72SJed Brown     Input Parameters:
16047c6ae99SBarry Smith +    dm - the packer object
1619ae5db72SJed Brown -    gvec - the global vector
1629ae5db72SJed Brown 
1639ae5db72SJed Brown     Output Parameters:
1649ae5db72SJed Brown .    Vec* ... - the packed parallel vectors, PETSC_NULL for those that are not needed
16547c6ae99SBarry Smith 
16647c6ae99SBarry Smith     Notes: Use DMCompositeRestoreAccess() to return the vectors when you no longer need them
16747c6ae99SBarry Smith 
16847c6ae99SBarry Smith     Level: advanced
16947c6ae99SBarry Smith 
17047c6ae99SBarry Smith @*/
1717087cfbeSBarry Smith PetscErrorCode  DMCompositeGetAccess(DM dm,Vec gvec,...)
17247c6ae99SBarry Smith {
17347c6ae99SBarry Smith   va_list                Argp;
17447c6ae99SBarry Smith   PetscErrorCode         ierr;
17547c6ae99SBarry Smith   struct DMCompositeLink *next;
17647c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
17747c6ae99SBarry Smith 
17847c6ae99SBarry Smith   PetscFunctionBegin;
17947c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
18047c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
18147c6ae99SBarry Smith   next = com->next;
18247c6ae99SBarry Smith   if (!com->setup) {
183d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
18447c6ae99SBarry Smith   }
18547c6ae99SBarry Smith 
18647c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
18747c6ae99SBarry Smith   va_start(Argp,gvec);
18847c6ae99SBarry Smith   while (next) {
18947c6ae99SBarry Smith     Vec *vec;
19047c6ae99SBarry Smith     vec = va_arg(Argp, Vec*);
1919ae5db72SJed Brown     if (vec) {
1929ae5db72SJed Brown       PetscScalar *array;
1939ae5db72SJed Brown       ierr = DMGetGlobalVector(next->dm,vec);CHKERRQ(ierr);
1949ae5db72SJed Brown       ierr = VecGetArray(gvec,&array);CHKERRQ(ierr);
1959ae5db72SJed Brown       ierr = VecPlaceArray(*vec,array+next->rstart);CHKERRQ(ierr);
1969ae5db72SJed Brown       ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr);
19747c6ae99SBarry Smith     }
19847c6ae99SBarry Smith     next = next->next;
19947c6ae99SBarry Smith   }
20047c6ae99SBarry Smith   va_end(Argp);
20147c6ae99SBarry Smith   PetscFunctionReturn(0);
20247c6ae99SBarry Smith }
20347c6ae99SBarry Smith 
20447c6ae99SBarry Smith #undef __FUNCT__
20547c6ae99SBarry Smith #define __FUNCT__ "DMCompositeRestoreAccess"
20647c6ae99SBarry Smith /*@C
207aa219208SBarry Smith     DMCompositeRestoreAccess - Returns the vectors obtained with DMCompositeGetAccess()
20847c6ae99SBarry Smith        representation.
20947c6ae99SBarry Smith 
21047c6ae99SBarry Smith     Collective on DMComposite
21147c6ae99SBarry Smith 
2129ae5db72SJed Brown     Input Parameters:
21347c6ae99SBarry Smith +    dm - the packer object
21447c6ae99SBarry Smith .    gvec - the global vector
2159ae5db72SJed Brown -    Vec* ... - the individual parallel vectors, PETSC_NULL for those that are not needed
21647c6ae99SBarry Smith 
21747c6ae99SBarry Smith     Level: advanced
21847c6ae99SBarry Smith 
2199ae5db72SJed Brown .seealso  DMCompositeAddDM(), DMCreateGlobalVector(),
2206eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeScatter(),
221aa219208SBarry Smith          DMCompositeRestoreAccess(), DMCompositeGetAccess()
22247c6ae99SBarry Smith 
22347c6ae99SBarry Smith @*/
2247087cfbeSBarry Smith PetscErrorCode  DMCompositeRestoreAccess(DM dm,Vec gvec,...)
22547c6ae99SBarry Smith {
22647c6ae99SBarry Smith   va_list                Argp;
22747c6ae99SBarry Smith   PetscErrorCode         ierr;
22847c6ae99SBarry Smith   struct DMCompositeLink *next;
22947c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
23047c6ae99SBarry Smith 
23147c6ae99SBarry Smith   PetscFunctionBegin;
23247c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
23347c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
23447c6ae99SBarry Smith   next = com->next;
23547c6ae99SBarry Smith   if (!com->setup) {
236d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
23747c6ae99SBarry Smith   }
23847c6ae99SBarry Smith 
23947c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
24047c6ae99SBarry Smith   va_start(Argp,gvec);
24147c6ae99SBarry Smith   while (next) {
24247c6ae99SBarry Smith     Vec *vec;
24347c6ae99SBarry Smith     vec = va_arg(Argp, Vec*);
2449ae5db72SJed Brown     if (vec) {
2459ae5db72SJed Brown       ierr = VecResetArray(*vec);CHKERRQ(ierr);
2469ae5db72SJed Brown       ierr = DMRestoreGlobalVector(next->dm,vec);CHKERRQ(ierr);
24747c6ae99SBarry Smith     }
24847c6ae99SBarry Smith     next = next->next;
24947c6ae99SBarry Smith   }
25047c6ae99SBarry Smith   va_end(Argp);
25147c6ae99SBarry Smith   PetscFunctionReturn(0);
25247c6ae99SBarry Smith }
25347c6ae99SBarry Smith 
25447c6ae99SBarry Smith #undef __FUNCT__
25547c6ae99SBarry Smith #define __FUNCT__ "DMCompositeScatter"
25647c6ae99SBarry Smith /*@C
25747c6ae99SBarry Smith     DMCompositeScatter - Scatters from a global packed vector into its individual local vectors
25847c6ae99SBarry Smith 
25947c6ae99SBarry Smith     Collective on DMComposite
26047c6ae99SBarry Smith 
2619ae5db72SJed Brown     Input Parameters:
26247c6ae99SBarry Smith +    dm - the packer object
26347c6ae99SBarry Smith .    gvec - the global vector
2649ae5db72SJed Brown -    Vec ... - the individual sequential vectors, PETSC_NULL for those that are not needed
26547c6ae99SBarry Smith 
26647c6ae99SBarry Smith     Level: advanced
26747c6ae99SBarry Smith 
2689ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
2696eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
27047c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries()
27147c6ae99SBarry Smith 
27247c6ae99SBarry Smith @*/
2737087cfbeSBarry Smith PetscErrorCode  DMCompositeScatter(DM dm,Vec gvec,...)
27447c6ae99SBarry Smith {
27547c6ae99SBarry Smith   va_list                Argp;
27647c6ae99SBarry Smith   PetscErrorCode         ierr;
27747c6ae99SBarry Smith   struct DMCompositeLink *next;
2788fd8f222SJed Brown   PetscInt               cnt;
27947c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
28047c6ae99SBarry Smith 
28147c6ae99SBarry Smith   PetscFunctionBegin;
28247c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
28347c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
28447c6ae99SBarry Smith   if (!com->setup) {
285d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
28647c6ae99SBarry Smith   }
28747c6ae99SBarry Smith 
28847c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
28947c6ae99SBarry Smith   va_start(Argp,gvec);
2908fd8f222SJed Brown   for (cnt=3,next=com->next; next; cnt++,next=next->next) {
2919ae5db72SJed Brown     Vec local;
2929ae5db72SJed Brown     local = va_arg(Argp, Vec);
2939ae5db72SJed Brown     if (local) {
2949ae5db72SJed Brown       Vec global;
29547c6ae99SBarry Smith       PetscScalar *array;
2969ae5db72SJed Brown       PetscValidHeaderSpecific(local,VEC_CLASSID,cnt);
2979ae5db72SJed Brown       ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
2989ae5db72SJed Brown       ierr = VecGetArray(gvec,&array);CHKERRQ(ierr);
2999ae5db72SJed Brown       ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr);
3009ae5db72SJed Brown       ierr = DMGlobalToLocalBegin(next->dm,global,INSERT_VALUES,local);CHKERRQ(ierr);
3019ae5db72SJed Brown       ierr = DMGlobalToLocalEnd(next->dm,global,INSERT_VALUES,local);CHKERRQ(ierr);
3029ae5db72SJed Brown       ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr);
3039ae5db72SJed Brown       ierr = VecResetArray(global);CHKERRQ(ierr);
3049ae5db72SJed Brown       ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
30547c6ae99SBarry Smith     }
30647c6ae99SBarry Smith   }
30747c6ae99SBarry Smith   va_end(Argp);
30847c6ae99SBarry Smith   PetscFunctionReturn(0);
30947c6ae99SBarry Smith }
31047c6ae99SBarry Smith 
31147c6ae99SBarry Smith #undef __FUNCT__
31247c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGather"
31347c6ae99SBarry Smith /*@C
31447c6ae99SBarry Smith     DMCompositeGather - Gathers into a global packed vector from its individual local vectors
31547c6ae99SBarry Smith 
31647c6ae99SBarry Smith     Collective on DMComposite
31747c6ae99SBarry Smith 
31847c6ae99SBarry Smith     Input Parameter:
31947c6ae99SBarry Smith +    dm - the packer object
32047c6ae99SBarry Smith .    gvec - the global vector
3219ae5db72SJed Brown -    Vec ... - the individual sequential vectors, PETSC_NULL for any that are not needed
32247c6ae99SBarry Smith 
32347c6ae99SBarry Smith     Level: advanced
32447c6ae99SBarry Smith 
3259ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
3266eb61c8cSJed Brown          DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
32747c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries()
32847c6ae99SBarry Smith 
32947c6ae99SBarry Smith @*/
3307087cfbeSBarry Smith PetscErrorCode  DMCompositeGather(DM dm,Vec gvec,InsertMode imode,...)
33147c6ae99SBarry Smith {
33247c6ae99SBarry Smith   va_list                Argp;
33347c6ae99SBarry Smith   PetscErrorCode         ierr;
33447c6ae99SBarry Smith   struct DMCompositeLink *next;
33547c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
3368fd8f222SJed Brown   PetscInt               cnt;
33747c6ae99SBarry Smith 
33847c6ae99SBarry Smith   PetscFunctionBegin;
33947c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
34047c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
34147c6ae99SBarry Smith   if (!com->setup) {
342d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
34347c6ae99SBarry Smith   }
34447c6ae99SBarry Smith 
34547c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
346df0c820aSJed Brown   va_start(Argp,imode);
3478fd8f222SJed Brown   for (cnt=3,next=com->next; next; cnt++,next=next->next) {
3489ae5db72SJed Brown     Vec local;
3499ae5db72SJed Brown     local = va_arg(Argp, Vec);
3509ae5db72SJed Brown     if (local) {
35147c6ae99SBarry Smith       PetscScalar    *array;
3529ae5db72SJed Brown       Vec            global;
3539ae5db72SJed Brown       PetscValidHeaderSpecific(local,VEC_CLASSID,cnt);
3549ae5db72SJed Brown       ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
3559ae5db72SJed Brown       ierr = VecGetArray(gvec,&array);CHKERRQ(ierr);
3569ae5db72SJed Brown       ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr);
3579ae5db72SJed Brown       ierr = DMLocalToGlobalBegin(next->dm,local,imode,global);CHKERRQ(ierr);
3589ae5db72SJed Brown       ierr = DMLocalToGlobalEnd(next->dm,local,imode,global);CHKERRQ(ierr);
3599ae5db72SJed Brown       ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr);
3609ae5db72SJed Brown       ierr = VecResetArray(global);CHKERRQ(ierr);
3619ae5db72SJed Brown       ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
36247c6ae99SBarry Smith     }
36347c6ae99SBarry Smith   }
36447c6ae99SBarry Smith   va_end(Argp);
36547c6ae99SBarry Smith   PetscFunctionReturn(0);
36647c6ae99SBarry Smith }
36747c6ae99SBarry Smith 
36847c6ae99SBarry Smith #undef __FUNCT__
36947c6ae99SBarry Smith #define __FUNCT__ "DMCompositeAddDM"
37047c6ae99SBarry Smith /*@C
371aa219208SBarry Smith     DMCompositeAddDM - adds a DM  vector to a DMComposite
37247c6ae99SBarry Smith 
37347c6ae99SBarry Smith     Collective on DMComposite
37447c6ae99SBarry Smith 
37547c6ae99SBarry Smith     Input Parameter:
37647c6ae99SBarry Smith +    dm - the packer object
37747c6ae99SBarry Smith -    dm - the DM object, if the DM is a da you will need to caste it with a (DM)
37847c6ae99SBarry Smith 
37947c6ae99SBarry Smith     Level: advanced
38047c6ae99SBarry Smith 
3810c010503SBarry Smith .seealso DMDestroy(), DMCompositeGather(), DMCompositeAddDM(), DMCreateGlobalVector(),
3826eb61c8cSJed Brown          DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
38347c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries()
38447c6ae99SBarry Smith 
38547c6ae99SBarry Smith @*/
3867087cfbeSBarry Smith PetscErrorCode  DMCompositeAddDM(DM dmc,DM dm)
38747c6ae99SBarry Smith {
38847c6ae99SBarry Smith   PetscErrorCode         ierr;
38906ebdd98SJed Brown   PetscInt               n,nlocal;
39047c6ae99SBarry Smith   struct DMCompositeLink *mine,*next;
39106ebdd98SJed Brown   Vec                    global,local;
39247c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dmc->data;
39347c6ae99SBarry Smith 
39447c6ae99SBarry Smith   PetscFunctionBegin;
39547c6ae99SBarry Smith   PetscValidHeaderSpecific(dmc,DM_CLASSID,1);
39647c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,2);
39747c6ae99SBarry Smith   next = com->next;
398aa219208SBarry Smith   if (com->setup) SETERRQ(((PetscObject)dmc)->comm,PETSC_ERR_ARG_WRONGSTATE,"Cannot add a DM once you have used the DMComposite");
39947c6ae99SBarry Smith 
40047c6ae99SBarry Smith   /* create new link */
40147c6ae99SBarry Smith   ierr = PetscNew(struct DMCompositeLink,&mine);CHKERRQ(ierr);
40247c6ae99SBarry Smith   ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);
40347c6ae99SBarry Smith   ierr = DMGetGlobalVector(dm,&global);CHKERRQ(ierr);
40447c6ae99SBarry Smith   ierr = VecGetLocalSize(global,&n);CHKERRQ(ierr);
40547c6ae99SBarry Smith   ierr = DMRestoreGlobalVector(dm,&global);CHKERRQ(ierr);
40606ebdd98SJed Brown   ierr = DMGetLocalVector(dm,&local);CHKERRQ(ierr);
40706ebdd98SJed Brown   ierr = VecGetSize(local,&nlocal);CHKERRQ(ierr);
40806ebdd98SJed Brown   ierr = DMRestoreLocalVector(dm,&local);CHKERRQ(ierr);
40947c6ae99SBarry Smith   mine->n      = n;
41006ebdd98SJed Brown   mine->nlocal = nlocal;
41147c6ae99SBarry Smith   mine->dm     = dm;
41247c6ae99SBarry Smith   mine->next   = PETSC_NULL;
41347c6ae99SBarry Smith   com->n       += n;
41447c6ae99SBarry Smith 
41547c6ae99SBarry Smith   /* add to end of list */
41647c6ae99SBarry Smith   if (!next) {
41747c6ae99SBarry Smith     com->next = mine;
41847c6ae99SBarry Smith   } else {
41947c6ae99SBarry Smith     while (next->next) next = next->next;
42047c6ae99SBarry Smith     next->next = mine;
42147c6ae99SBarry Smith   }
42247c6ae99SBarry Smith   com->nDM++;
42347c6ae99SBarry Smith   com->nmine++;
42447c6ae99SBarry Smith   PetscFunctionReturn(0);
42547c6ae99SBarry Smith }
42647c6ae99SBarry Smith 
4277087cfbeSBarry Smith extern PetscErrorCode  VecView_MPI(Vec,PetscViewer);
42847c6ae99SBarry Smith EXTERN_C_BEGIN
42947c6ae99SBarry Smith #undef __FUNCT__
43047c6ae99SBarry Smith #define __FUNCT__ "VecView_DMComposite"
4317087cfbeSBarry Smith PetscErrorCode  VecView_DMComposite(Vec gvec,PetscViewer viewer)
43247c6ae99SBarry Smith {
43347c6ae99SBarry Smith   DM                     dm;
43447c6ae99SBarry Smith   PetscErrorCode         ierr;
43547c6ae99SBarry Smith   struct DMCompositeLink *next;
43647c6ae99SBarry Smith   PetscBool              isdraw;
437cef07954SSatish Balay   DM_Composite           *com;
43847c6ae99SBarry Smith 
43947c6ae99SBarry Smith   PetscFunctionBegin;
440*c688c046SMatthew G Knepley   ierr = VecGetDM(gvec, &dm);CHKERRQ(ierr);
44147c6ae99SBarry Smith   if (!dm) SETERRQ(((PetscObject)gvec)->comm,PETSC_ERR_ARG_WRONG,"Vector not generated from a DMComposite");
44247c6ae99SBarry Smith   com = (DM_Composite*)dm->data;
44347c6ae99SBarry Smith   next = com->next;
44447c6ae99SBarry Smith 
445251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
44647c6ae99SBarry Smith   if (!isdraw) {
44747c6ae99SBarry Smith     /* do I really want to call this? */
44847c6ae99SBarry Smith     ierr = VecView_MPI(gvec,viewer);CHKERRQ(ierr);
44947c6ae99SBarry Smith   } else {
45047c6ae99SBarry Smith     PetscInt cnt = 0;
45147c6ae99SBarry Smith 
45247c6ae99SBarry Smith     /* loop over packed objects, handling one at at time */
45347c6ae99SBarry Smith     while (next) {
45447c6ae99SBarry Smith       Vec         vec;
4559ae5db72SJed Brown       PetscScalar *array;
45647c6ae99SBarry Smith       PetscInt    bs;
45747c6ae99SBarry Smith 
4589ae5db72SJed Brown       /* Should use VecGetSubVector() eventually, but would need to forward the DM for that to work */
4599ae5db72SJed Brown       ierr = DMGetGlobalVector(next->dm,&vec);CHKERRQ(ierr);
4609ae5db72SJed Brown       ierr = VecGetArray(gvec,&array);CHKERRQ(ierr);
4619ae5db72SJed Brown       ierr = VecPlaceArray(vec,array+next->rstart);CHKERRQ(ierr);
4629ae5db72SJed Brown       ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr);
46347c6ae99SBarry Smith       ierr = VecView(vec,viewer);CHKERRQ(ierr);
46447c6ae99SBarry Smith       ierr = VecGetBlockSize(vec,&bs);CHKERRQ(ierr);
4659ae5db72SJed Brown       ierr = VecResetArray(vec);CHKERRQ(ierr);
4669ae5db72SJed Brown       ierr = DMRestoreGlobalVector(next->dm,&vec);CHKERRQ(ierr);
46747c6ae99SBarry Smith       ierr = PetscViewerDrawBaseAdd(viewer,bs);CHKERRQ(ierr);
46847c6ae99SBarry Smith       cnt += bs;
46947c6ae99SBarry Smith       next = next->next;
47047c6ae99SBarry Smith     }
47147c6ae99SBarry Smith     ierr = PetscViewerDrawBaseAdd(viewer,-cnt);CHKERRQ(ierr);
47247c6ae99SBarry Smith   }
47347c6ae99SBarry Smith   PetscFunctionReturn(0);
47447c6ae99SBarry Smith }
47547c6ae99SBarry Smith EXTERN_C_END
47647c6ae99SBarry Smith 
47747c6ae99SBarry Smith 
47847c6ae99SBarry Smith #undef __FUNCT__
4790c010503SBarry Smith #define __FUNCT__ "DMCreateGlobalVector_Composite"
4807087cfbeSBarry Smith PetscErrorCode  DMCreateGlobalVector_Composite(DM dm,Vec *gvec)
48147c6ae99SBarry Smith {
48247c6ae99SBarry Smith   PetscErrorCode         ierr;
48347c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
48447c6ae99SBarry Smith 
48547c6ae99SBarry Smith   PetscFunctionBegin;
48647c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
487d7bf68aeSBarry Smith   ierr = DMSetUp(dm);CHKERRQ(ierr);
48847c6ae99SBarry Smith   ierr = VecCreateMPI(((PetscObject)dm)->comm,com->n,com->N,gvec);CHKERRQ(ierr);
489*c688c046SMatthew G Knepley   ierr = VecSetDM(*gvec, dm);CHKERRQ(ierr);
49047c6ae99SBarry Smith   ierr = VecSetOperation(*gvec,VECOP_VIEW,(void(*)(void))VecView_DMComposite);CHKERRQ(ierr);
49147c6ae99SBarry Smith   PetscFunctionReturn(0);
49247c6ae99SBarry Smith }
49347c6ae99SBarry Smith 
49447c6ae99SBarry Smith #undef __FUNCT__
4950c010503SBarry Smith #define __FUNCT__ "DMCreateLocalVector_Composite"
4967087cfbeSBarry Smith PetscErrorCode  DMCreateLocalVector_Composite(DM dm,Vec *lvec)
49747c6ae99SBarry Smith {
49847c6ae99SBarry Smith   PetscErrorCode         ierr;
49947c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
50047c6ae99SBarry Smith 
50147c6ae99SBarry Smith   PetscFunctionBegin;
50247c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
50347c6ae99SBarry Smith   if (!com->setup) {
504d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
50547c6ae99SBarry Smith   }
50647c6ae99SBarry Smith   ierr = VecCreateSeq(((PetscObject)dm)->comm,com->nghost,lvec);CHKERRQ(ierr);
507*c688c046SMatthew G Knepley   ierr = VecSetDM(*lvec, dm);CHKERRQ(ierr);
50847c6ae99SBarry Smith   PetscFunctionReturn(0);
50947c6ae99SBarry Smith }
51047c6ae99SBarry Smith 
51147c6ae99SBarry Smith #undef __FUNCT__
5126eb61c8cSJed Brown #define __FUNCT__ "DMCompositeGetISLocalToGlobalMappings"
51347c6ae99SBarry Smith /*@C
5149ae5db72SJed Brown     DMCompositeGetISLocalToGlobalMappings - gets an ISLocalToGlobalMapping for each DM in the DMComposite, maps to the composite global space
51547c6ae99SBarry Smith 
51606ebdd98SJed Brown     Collective on DM
51747c6ae99SBarry Smith 
51847c6ae99SBarry Smith     Input Parameter:
51947c6ae99SBarry Smith .    dm - the packer object
52047c6ae99SBarry Smith 
52147c6ae99SBarry Smith     Output Parameters:
5229ae5db72SJed Brown .    ltogs - the individual mappings for each packed vector. Note that this includes
5239ae5db72SJed Brown            all the ghost points that individual ghosted DMDA's may have.
52447c6ae99SBarry Smith 
52547c6ae99SBarry Smith     Level: advanced
52647c6ae99SBarry Smith 
52747c6ae99SBarry Smith     Notes:
5286eb61c8cSJed Brown        Each entry of ltogs should be destroyed with ISLocalToGlobalMappingDestroy(), the ltogs array should be freed with PetscFree().
52947c6ae99SBarry Smith 
5309ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
53147c6ae99SBarry Smith          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetAccess(), DMCompositeScatter(),
53247c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(),DMCompositeGetEntries()
53347c6ae99SBarry Smith 
53447c6ae99SBarry Smith @*/
5357087cfbeSBarry Smith PetscErrorCode  DMCompositeGetISLocalToGlobalMappings(DM dm,ISLocalToGlobalMapping **ltogs)
53647c6ae99SBarry Smith {
53747c6ae99SBarry Smith   PetscErrorCode         ierr;
53847c6ae99SBarry Smith   PetscInt               i,*idx,n,cnt;
53947c6ae99SBarry Smith   struct DMCompositeLink *next;
54047c6ae99SBarry Smith   PetscMPIInt            rank;
54147c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
54247c6ae99SBarry Smith 
54347c6ae99SBarry Smith   PetscFunctionBegin;
54447c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
545728e99d6SJed Brown   ierr = DMSetUp(dm);CHKERRQ(ierr);
5469ae5db72SJed Brown   ierr = PetscMalloc((com->nDM)*sizeof(ISLocalToGlobalMapping),ltogs);CHKERRQ(ierr);
54747c6ae99SBarry Smith   next = com->next;
54847c6ae99SBarry Smith   ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr);
54947c6ae99SBarry Smith 
55047c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
55147c6ae99SBarry Smith   cnt = 0;
55247c6ae99SBarry Smith   while (next) {
5536eb61c8cSJed Brown     ISLocalToGlobalMapping ltog;
5546eb61c8cSJed Brown     PetscMPIInt            size;
55586994e45SJed Brown     const PetscInt         *suboff,*indices;
5566eb61c8cSJed Brown     Vec                    global;
55747c6ae99SBarry Smith 
5586eb61c8cSJed Brown     /* Get sub-DM global indices for each local dof */
5591411c6eeSJed Brown     ierr = DMGetLocalToGlobalMapping(next->dm,&ltog);CHKERRQ(ierr);
5606eb61c8cSJed Brown     ierr = ISLocalToGlobalMappingGetSize(ltog,&n);CHKERRQ(ierr);
56186994e45SJed Brown     ierr = ISLocalToGlobalMappingGetIndices(ltog,&indices);CHKERRQ(ierr);
56247c6ae99SBarry Smith     ierr = PetscMalloc(n*sizeof(PetscInt),&idx);CHKERRQ(ierr);
56347c6ae99SBarry Smith 
5646eb61c8cSJed Brown     /* Get the offsets for the sub-DM global vector */
5656eb61c8cSJed Brown     ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
5666eb61c8cSJed Brown     ierr = VecGetOwnershipRanges(global,&suboff);CHKERRQ(ierr);
5676eb61c8cSJed Brown     ierr = MPI_Comm_size(((PetscObject)global)->comm,&size);CHKERRQ(ierr);
5686eb61c8cSJed Brown 
5696eb61c8cSJed Brown     /* Shift the sub-DM definition of the global space to the composite global space */
5706eb61c8cSJed Brown     for (i=0; i<n; i++) {
57186994e45SJed Brown       PetscInt subi = indices[i],lo = 0,hi = size,t;
5726eb61c8cSJed Brown       /* Binary search to find which rank owns subi */
5736eb61c8cSJed Brown       while (hi-lo > 1) {
5746eb61c8cSJed Brown         t = lo + (hi-lo)/2;
5756eb61c8cSJed Brown         if (suboff[t] > subi) hi = t;
5766eb61c8cSJed Brown         else                  lo = t;
5776eb61c8cSJed Brown       }
5786eb61c8cSJed Brown       idx[i] = subi - suboff[lo] + next->grstarts[lo];
5796eb61c8cSJed Brown     }
58086994e45SJed Brown     ierr = ISLocalToGlobalMappingRestoreIndices(ltog,&indices);CHKERRQ(ierr);
5816eb61c8cSJed Brown     ierr = ISLocalToGlobalMappingCreate(((PetscObject)dm)->comm,n,idx,PETSC_OWN_POINTER,&(*ltogs)[cnt]);CHKERRQ(ierr);
5826eb61c8cSJed Brown     ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
58347c6ae99SBarry Smith     next = next->next;
58447c6ae99SBarry Smith     cnt++;
58547c6ae99SBarry Smith   }
58647c6ae99SBarry Smith   PetscFunctionReturn(0);
58747c6ae99SBarry Smith }
58847c6ae99SBarry Smith 
58947c6ae99SBarry Smith #undef __FUNCT__
59087c85e80SJed Brown #define __FUNCT__ "DMCompositeGetLocalISs"
59187c85e80SJed Brown /*@C
5929ae5db72SJed Brown    DMCompositeGetLocalISs - Gets index sets for each component of a composite local vector
59387c85e80SJed Brown 
59487c85e80SJed Brown    Not Collective
59587c85e80SJed Brown 
59687c85e80SJed Brown    Input Arguments:
59787c85e80SJed Brown . dm - composite DM
59887c85e80SJed Brown 
59987c85e80SJed Brown    Output Arguments:
60087c85e80SJed Brown . is - array of serial index sets for each each component of the DMComposite
60187c85e80SJed Brown 
60287c85e80SJed Brown    Level: intermediate
60387c85e80SJed Brown 
60487c85e80SJed Brown    Notes:
60587c85e80SJed Brown    At present, a composite local vector does not normally exist.  This function is used to provide index sets for
60687c85e80SJed Brown    MatGetLocalSubMatrix().  In the future, the scatters for each entry in the DMComposite may be be merged into a single
6079ae5db72SJed Brown    scatter to a composite local vector.  The user should not typically need to know which is being done.
60887c85e80SJed Brown 
60987c85e80SJed Brown    To get the composite global indices at all local points (including ghosts), use DMCompositeGetISLocalToGlobalMappings().
61087c85e80SJed Brown 
61187c85e80SJed Brown    To get index sets for pieces of the composite global vector, use DMCompositeGetGlobalISs().
61287c85e80SJed Brown 
61387c85e80SJed Brown    Each returned IS should be destroyed with ISDestroy(), the array should be freed with PetscFree().
61487c85e80SJed Brown 
61587c85e80SJed Brown .seealso: DMCompositeGetGlobalISs(), DMCompositeGetISLocalToGlobalMappings(), MatGetLocalSubMatrix(), MatCreateLocalRef()
61687c85e80SJed Brown @*/
6177087cfbeSBarry Smith PetscErrorCode  DMCompositeGetLocalISs(DM dm,IS **is)
61887c85e80SJed Brown {
61987c85e80SJed Brown   PetscErrorCode         ierr;
62087c85e80SJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
62187c85e80SJed Brown   struct DMCompositeLink *link;
62287c85e80SJed Brown   PetscInt cnt,start;
62387c85e80SJed Brown 
62487c85e80SJed Brown   PetscFunctionBegin;
62587c85e80SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
62687c85e80SJed Brown   PetscValidPointer(is,2);
62787c85e80SJed Brown   ierr = PetscMalloc(com->nmine*sizeof(IS),is);CHKERRQ(ierr);
62806ebdd98SJed Brown   for (cnt=0,start=0,link=com->next; link; start+=link->nlocal,cnt++,link=link->next) {
629520db06cSJed Brown     PetscInt bs;
6309ae5db72SJed Brown     ierr = ISCreateStride(PETSC_COMM_SELF,link->nlocal,start,1,&(*is)[cnt]);CHKERRQ(ierr);
6311411c6eeSJed Brown     ierr = DMGetBlockSize(link->dm,&bs);CHKERRQ(ierr);
632520db06cSJed Brown     ierr = ISSetBlockSize((*is)[cnt],bs);CHKERRQ(ierr);
633520db06cSJed Brown   }
63487c85e80SJed Brown   PetscFunctionReturn(0);
63587c85e80SJed Brown }
63687c85e80SJed Brown 
63787c85e80SJed Brown #undef __FUNCT__
63847c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetGlobalISs"
63947c6ae99SBarry Smith /*@C
64047c6ae99SBarry Smith     DMCompositeGetGlobalISs - Gets the index sets for each composed object
64147c6ae99SBarry Smith 
64247c6ae99SBarry Smith     Collective on DMComposite
64347c6ae99SBarry Smith 
64447c6ae99SBarry Smith     Input Parameter:
64547c6ae99SBarry Smith .    dm - the packer object
64647c6ae99SBarry Smith 
64747c6ae99SBarry Smith     Output Parameters:
64847c6ae99SBarry Smith .    is - the array of index sets
64947c6ae99SBarry Smith 
65047c6ae99SBarry Smith     Level: advanced
65147c6ae99SBarry Smith 
65247c6ae99SBarry Smith     Notes:
65347c6ae99SBarry Smith        The is entries should be destroyed with ISDestroy(), the is array should be freed with PetscFree()
65447c6ae99SBarry Smith 
65547c6ae99SBarry Smith        These could be used to extract a subset of vector entries for a "multi-physics" preconditioner
65647c6ae99SBarry Smith 
6576eb61c8cSJed Brown        Use DMCompositeGetLocalISs() for index sets in the packed local numbering, and
6586eb61c8cSJed Brown        DMCompositeGetISLocalToGlobalMappings() for to map local sub-DM (including ghost) indices to packed global
6596eb61c8cSJed Brown        indices.
66047c6ae99SBarry Smith 
6619ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
66247c6ae99SBarry Smith          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetAccess(), DMCompositeScatter(),
66347c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(),DMCompositeGetEntries()
66447c6ae99SBarry Smith 
66547c6ae99SBarry Smith @*/
6666eb61c8cSJed Brown 
6677087cfbeSBarry Smith PetscErrorCode  DMCompositeGetGlobalISs(DM dm,IS *is[])
66847c6ae99SBarry Smith {
66947c6ae99SBarry Smith   PetscErrorCode         ierr;
67047c6ae99SBarry Smith   PetscInt               cnt = 0,*idx,i;
67147c6ae99SBarry Smith   struct DMCompositeLink *next;
67247c6ae99SBarry Smith   PetscMPIInt            rank;
67347c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
67447c6ae99SBarry Smith 
67547c6ae99SBarry Smith   PetscFunctionBegin;
67647c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6779ae5db72SJed Brown   ierr = PetscMalloc((com->nDM)*sizeof(IS),is);CHKERRQ(ierr);
67847c6ae99SBarry Smith   next = com->next;
67947c6ae99SBarry Smith   ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr);
68047c6ae99SBarry Smith 
68147c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
68247c6ae99SBarry Smith   while (next) {
68347c6ae99SBarry Smith     ierr = PetscMalloc(next->n*sizeof(PetscInt),&idx);CHKERRQ(ierr);
68447c6ae99SBarry Smith     for (i=0; i<next->n; i++) idx[i] = next->grstart + i;
68547c6ae99SBarry Smith     ierr = ISCreateGeneral(((PetscObject)dm)->comm,next->n,idx,PETSC_OWN_POINTER,&(*is)[cnt]);CHKERRQ(ierr);
68647c6ae99SBarry Smith     cnt++;
68747c6ae99SBarry Smith     next = next->next;
68847c6ae99SBarry Smith   }
68947c6ae99SBarry Smith   PetscFunctionReturn(0);
69047c6ae99SBarry Smith }
69147c6ae99SBarry Smith 
6924d343eeaSMatthew G Knepley #undef __FUNCT__
6934d343eeaSMatthew G Knepley #define __FUNCT__ "DMCreateFieldIS_Composite"
69421c9b008SJed Brown PetscErrorCode DMCreateFieldIS_Composite(DM dm, PetscInt *numFields,char ***fieldNames, IS **fields)
6954d343eeaSMatthew G Knepley {
6964d343eeaSMatthew G Knepley   PetscInt       nDM;
6974d343eeaSMatthew G Knepley   DM            *dms;
6984d343eeaSMatthew G Knepley   PetscInt       i;
6994d343eeaSMatthew G Knepley   PetscErrorCode ierr;
7004d343eeaSMatthew G Knepley 
7014d343eeaSMatthew G Knepley   PetscFunctionBegin;
7024d343eeaSMatthew G Knepley   ierr = DMCompositeGetNumberDM(dm, &nDM);CHKERRQ(ierr);
7034d343eeaSMatthew G Knepley   if (numFields) {*numFields = nDM;}
7044d343eeaSMatthew G Knepley   ierr = DMCompositeGetGlobalISs(dm, fields);CHKERRQ(ierr);
7054d343eeaSMatthew G Knepley   if (fieldNames) {
7064d343eeaSMatthew G Knepley     ierr = PetscMalloc(nDM*sizeof(DM), &dms);CHKERRQ(ierr);
7074d343eeaSMatthew G Knepley     ierr = PetscMalloc(nDM*sizeof(const char *), fieldNames);CHKERRQ(ierr);
7084d343eeaSMatthew G Knepley     ierr = DMCompositeGetEntriesArray(dm, dms);CHKERRQ(ierr);
7094d343eeaSMatthew G Knepley     for (i=0; i<nDM; i++) {
7104d343eeaSMatthew G Knepley       char buf[256];
7114d343eeaSMatthew G Knepley       const char *splitname;
7124d343eeaSMatthew G Knepley 
7134d343eeaSMatthew G Knepley       /* Split naming precedence: object name, prefix, number */
7144d343eeaSMatthew G Knepley       splitname = ((PetscObject) dm)->name;
7154d343eeaSMatthew G Knepley       if (!splitname) {
7164d343eeaSMatthew G Knepley         ierr = PetscObjectGetOptionsPrefix((PetscObject)dms[i],&splitname);CHKERRQ(ierr);
7174d343eeaSMatthew G Knepley         if (splitname) {
7184d343eeaSMatthew G Knepley           size_t len;
7198caf3d72SBarry Smith           ierr = PetscStrncpy(buf,splitname,sizeof(buf));CHKERRQ(ierr);
7208caf3d72SBarry Smith           buf[sizeof(buf) - 1] = 0;
7214d343eeaSMatthew G Knepley           ierr = PetscStrlen(buf,&len);CHKERRQ(ierr);
7224d343eeaSMatthew G Knepley           if (buf[len-1] == '_') buf[len-1] = 0; /* Remove trailing underscore if it was used */
7234d343eeaSMatthew G Knepley           splitname = buf;
7244d343eeaSMatthew G Knepley         }
7254d343eeaSMatthew G Knepley       }
7264d343eeaSMatthew G Knepley       if (!splitname) {
7278caf3d72SBarry Smith         ierr = PetscSNPrintf(buf,sizeof(buf),"%D",i);CHKERRQ(ierr);
7284d343eeaSMatthew G Knepley         splitname = buf;
7294d343eeaSMatthew G Knepley       }
73021c9b008SJed Brown       ierr = PetscStrallocpy(splitname,&(*fieldNames)[i]);CHKERRQ(ierr);
7314d343eeaSMatthew G Knepley     }
7324d343eeaSMatthew G Knepley     ierr = PetscFree(dms);CHKERRQ(ierr);
7334d343eeaSMatthew G Knepley   }
7344d343eeaSMatthew G Knepley   PetscFunctionReturn(0);
7354d343eeaSMatthew G Knepley }
7364d343eeaSMatthew G Knepley 
737e7c4fc90SDmitry Karpeev /*
738e7c4fc90SDmitry Karpeev  This could take over from DMCreateFieldIS(), as it is more general,
739e7c4fc90SDmitry Karpeev  making DMCreateFieldIS() a special case -- calling with dmlist == PETSC_NULL;
740e7c4fc90SDmitry Karpeev  At this point it's probably best to be less intrusive, however.
741e7c4fc90SDmitry Karpeev  */
742e7c4fc90SDmitry Karpeev #undef __FUNCT__
74316621825SDmitry Karpeev #define __FUNCT__ "DMCreateFieldDecomposition_Composite"
74416621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecomposition_Composite(DM dm, PetscInt *len,char ***namelist, IS **islist, DM** dmlist)
745e7c4fc90SDmitry Karpeev {
746e7c4fc90SDmitry Karpeev   PetscInt       nDM;
747e7c4fc90SDmitry Karpeev   PetscInt       i;
748e7c4fc90SDmitry Karpeev   PetscErrorCode ierr;
749e7c4fc90SDmitry Karpeev 
750e7c4fc90SDmitry Karpeev   PetscFunctionBegin;
751e7c4fc90SDmitry Karpeev   ierr = DMCreateFieldIS_Composite(dm, len, namelist, islist); CHKERRQ(ierr);
752e7c4fc90SDmitry Karpeev   if (dmlist) {
753e7c4fc90SDmitry Karpeev     ierr = DMCompositeGetNumberDM(dm, &nDM);    CHKERRQ(ierr);
754e7c4fc90SDmitry Karpeev     ierr = PetscMalloc(nDM*sizeof(DM), dmlist); CHKERRQ(ierr);
755e7c4fc90SDmitry Karpeev     ierr = DMCompositeGetEntriesArray(dm, *dmlist);CHKERRQ(ierr);
756e7c4fc90SDmitry Karpeev     for (i=0; i<nDM; i++) {
757e7c4fc90SDmitry Karpeev       ierr = PetscObjectReference((PetscObject)((*dmlist)[i])); CHKERRQ(ierr);
758e7c4fc90SDmitry Karpeev     }
759e7c4fc90SDmitry Karpeev   }
760e7c4fc90SDmitry Karpeev   PetscFunctionReturn(0);
761e7c4fc90SDmitry Karpeev }
762e7c4fc90SDmitry Karpeev 
763e7c4fc90SDmitry Karpeev 
764e7c4fc90SDmitry Karpeev 
76547c6ae99SBarry Smith /* -------------------------------------------------------------------------------------*/
76647c6ae99SBarry Smith #undef __FUNCT__
76747c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetLocalVectors"
76847c6ae99SBarry Smith /*@C
7699ae5db72SJed Brown     DMCompositeGetLocalVectors - Gets local vectors for each part of a DMComposite.
77047c6ae99SBarry Smith        Use DMCompositeRestoreLocalVectors() to return them.
77147c6ae99SBarry Smith 
77247c6ae99SBarry Smith     Not Collective
77347c6ae99SBarry Smith 
77447c6ae99SBarry Smith     Input Parameter:
77547c6ae99SBarry Smith .    dm - the packer object
77647c6ae99SBarry Smith 
77747c6ae99SBarry Smith     Output Parameter:
7789ae5db72SJed Brown .   Vec ... - the individual sequential Vecs
77947c6ae99SBarry Smith 
78047c6ae99SBarry Smith     Level: advanced
78147c6ae99SBarry Smith 
7829ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
7836eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
78447c6ae99SBarry Smith          DMCompositeRestoreLocalVectors(), DMCompositeScatter(), DMCompositeGetEntries()
78547c6ae99SBarry Smith 
78647c6ae99SBarry Smith @*/
7877087cfbeSBarry Smith PetscErrorCode  DMCompositeGetLocalVectors(DM dm,...)
78847c6ae99SBarry Smith {
78947c6ae99SBarry Smith   va_list                Argp;
79047c6ae99SBarry Smith   PetscErrorCode         ierr;
79147c6ae99SBarry Smith   struct DMCompositeLink *next;
79247c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
79347c6ae99SBarry Smith 
79447c6ae99SBarry Smith   PetscFunctionBegin;
79547c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
79647c6ae99SBarry Smith   next = com->next;
79747c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
79847c6ae99SBarry Smith   va_start(Argp,dm);
79947c6ae99SBarry Smith   while (next) {
80047c6ae99SBarry Smith     Vec *vec;
80147c6ae99SBarry Smith     vec = va_arg(Argp, Vec*);
80206930112SJed Brown     if (vec) {ierr = DMGetLocalVector(next->dm,vec);CHKERRQ(ierr);}
80347c6ae99SBarry Smith     next = next->next;
80447c6ae99SBarry Smith   }
80547c6ae99SBarry Smith   va_end(Argp);
80647c6ae99SBarry Smith   PetscFunctionReturn(0);
80747c6ae99SBarry Smith }
80847c6ae99SBarry Smith 
80947c6ae99SBarry Smith #undef __FUNCT__
81047c6ae99SBarry Smith #define __FUNCT__ "DMCompositeRestoreLocalVectors"
81147c6ae99SBarry Smith /*@C
8129ae5db72SJed Brown     DMCompositeRestoreLocalVectors - Restores local vectors for each part of a DMComposite.
81347c6ae99SBarry Smith 
81447c6ae99SBarry Smith     Not Collective
81547c6ae99SBarry Smith 
81647c6ae99SBarry Smith     Input Parameter:
81747c6ae99SBarry Smith .    dm - the packer object
81847c6ae99SBarry Smith 
81947c6ae99SBarry Smith     Output Parameter:
8209ae5db72SJed Brown .   Vec ... - the individual sequential Vecs
82147c6ae99SBarry Smith 
82247c6ae99SBarry Smith     Level: advanced
82347c6ae99SBarry Smith 
8249ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(),
8256eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
82647c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeScatter(), DMCompositeGetEntries()
82747c6ae99SBarry Smith 
82847c6ae99SBarry Smith @*/
8297087cfbeSBarry Smith PetscErrorCode  DMCompositeRestoreLocalVectors(DM dm,...)
83047c6ae99SBarry Smith {
83147c6ae99SBarry Smith   va_list                Argp;
83247c6ae99SBarry Smith   PetscErrorCode         ierr;
83347c6ae99SBarry Smith   struct DMCompositeLink *next;
83447c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
83547c6ae99SBarry Smith 
83647c6ae99SBarry Smith   PetscFunctionBegin;
83747c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
83847c6ae99SBarry Smith   next = com->next;
83947c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
84047c6ae99SBarry Smith   va_start(Argp,dm);
84147c6ae99SBarry Smith   while (next) {
84247c6ae99SBarry Smith     Vec *vec;
84347c6ae99SBarry Smith     vec = va_arg(Argp, Vec*);
84406930112SJed Brown     if (vec) {ierr = DMRestoreLocalVector(next->dm,vec);CHKERRQ(ierr);}
84547c6ae99SBarry Smith     next = next->next;
84647c6ae99SBarry Smith   }
84747c6ae99SBarry Smith   va_end(Argp);
84847c6ae99SBarry Smith   PetscFunctionReturn(0);
84947c6ae99SBarry Smith }
85047c6ae99SBarry Smith 
85147c6ae99SBarry Smith /* -------------------------------------------------------------------------------------*/
85247c6ae99SBarry Smith #undef __FUNCT__
85347c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetEntries"
85447c6ae99SBarry Smith /*@C
8559ae5db72SJed Brown     DMCompositeGetEntries - Gets the DM for each entry in a DMComposite.
85647c6ae99SBarry Smith 
85747c6ae99SBarry Smith     Not Collective
85847c6ae99SBarry Smith 
85947c6ae99SBarry Smith     Input Parameter:
86047c6ae99SBarry Smith .    dm - the packer object
86147c6ae99SBarry Smith 
86247c6ae99SBarry Smith     Output Parameter:
8639ae5db72SJed Brown .   DM ... - the individual entries (DMs)
86447c6ae99SBarry Smith 
86547c6ae99SBarry Smith     Level: advanced
86647c6ae99SBarry Smith 
8672fa5ba8aSJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), DMCompositeGetEntriesArray()
8686eb61c8cSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
86947c6ae99SBarry Smith          DMCompositeRestoreLocalVectors(), DMCompositeGetLocalVectors(),  DMCompositeScatter(),
87047c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors()
87147c6ae99SBarry Smith 
87247c6ae99SBarry Smith @*/
8737087cfbeSBarry Smith PetscErrorCode  DMCompositeGetEntries(DM dm,...)
87447c6ae99SBarry Smith {
87547c6ae99SBarry Smith   va_list                Argp;
87647c6ae99SBarry Smith   struct DMCompositeLink *next;
87747c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
87847c6ae99SBarry Smith 
87947c6ae99SBarry Smith   PetscFunctionBegin;
88047c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
88147c6ae99SBarry Smith   next = com->next;
88247c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
88347c6ae99SBarry Smith   va_start(Argp,dm);
88447c6ae99SBarry Smith   while (next) {
88547c6ae99SBarry Smith     DM *dmn;
88647c6ae99SBarry Smith     dmn = va_arg(Argp, DM*);
8879ae5db72SJed Brown     if (dmn) *dmn = next->dm;
88847c6ae99SBarry Smith     next = next->next;
88947c6ae99SBarry Smith   }
89047c6ae99SBarry Smith   va_end(Argp);
89147c6ae99SBarry Smith   PetscFunctionReturn(0);
89247c6ae99SBarry Smith }
89347c6ae99SBarry Smith 
89447c6ae99SBarry Smith #undef __FUNCT__
8952fa5ba8aSJed Brown #define __FUNCT__ "DMCompositeGetEntriesArray"
8962fa5ba8aSJed Brown /*@
8972fa5ba8aSJed Brown     DMCompositeGetEntriesArray - Gets the DM for each entry in a DMComposite.
8982fa5ba8aSJed Brown 
8992fa5ba8aSJed Brown     Not Collective
9002fa5ba8aSJed Brown 
9012fa5ba8aSJed Brown     Input Parameter:
9022fa5ba8aSJed Brown +    dm - the packer object
9032fa5ba8aSJed Brown -    dms - array of sufficient length (see DMCompositeGetNumberDM()), holds the DMs on output
9042fa5ba8aSJed Brown 
9052fa5ba8aSJed Brown     Level: advanced
9062fa5ba8aSJed Brown 
9072fa5ba8aSJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), DMCompositeGetEntries()
9082fa5ba8aSJed Brown          DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(),
9092fa5ba8aSJed Brown          DMCompositeRestoreLocalVectors(), DMCompositeGetLocalVectors(),  DMCompositeScatter(),
9102fa5ba8aSJed Brown          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors()
9112fa5ba8aSJed Brown 
9122fa5ba8aSJed Brown @*/
9132fa5ba8aSJed Brown PetscErrorCode DMCompositeGetEntriesArray(DM dm,DM dms[])
9142fa5ba8aSJed Brown {
9152fa5ba8aSJed Brown   struct DMCompositeLink *next;
9162fa5ba8aSJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
9172fa5ba8aSJed Brown   PetscInt               i;
9182fa5ba8aSJed Brown 
9192fa5ba8aSJed Brown   PetscFunctionBegin;
9202fa5ba8aSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
9212fa5ba8aSJed Brown   /* loop over packed objects, handling one at at time */
9222fa5ba8aSJed Brown   for (next=com->next,i=0; next; next=next->next,i++) dms[i] = next->dm;
9232fa5ba8aSJed Brown   PetscFunctionReturn(0);
9242fa5ba8aSJed Brown }
9252fa5ba8aSJed Brown 
9262fa5ba8aSJed Brown #undef __FUNCT__
9270c010503SBarry Smith #define __FUNCT__ "DMRefine_Composite"
9287087cfbeSBarry Smith PetscErrorCode  DMRefine_Composite(DM dmi,MPI_Comm comm,DM *fine)
92947c6ae99SBarry Smith {
93047c6ae99SBarry Smith   PetscErrorCode         ierr;
93147c6ae99SBarry Smith   struct DMCompositeLink *next;
93247c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dmi->data;
93347c6ae99SBarry Smith   DM                     dm;
93447c6ae99SBarry Smith 
93547c6ae99SBarry Smith   PetscFunctionBegin;
93647c6ae99SBarry Smith   PetscValidHeaderSpecific(dmi,DM_CLASSID,1);
9372ee06e3bSJed Brown   if (comm == MPI_COMM_NULL) comm = ((PetscObject)dmi)->comm;
9382ce3a92bSJed Brown   ierr = DMSetUp(dmi);CHKERRQ(ierr);
93947c6ae99SBarry Smith   next = com->next;
94047c6ae99SBarry Smith   ierr = DMCompositeCreate(comm,fine);CHKERRQ(ierr);
94147c6ae99SBarry Smith 
94247c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
94347c6ae99SBarry Smith   while (next) {
94447c6ae99SBarry Smith     ierr = DMRefine(next->dm,comm,&dm);CHKERRQ(ierr);
94547c6ae99SBarry Smith     ierr = DMCompositeAddDM(*fine,dm);CHKERRQ(ierr);
94647c6ae99SBarry Smith     ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr);
94747c6ae99SBarry Smith     next = next->next;
94847c6ae99SBarry Smith   }
94947c6ae99SBarry Smith   PetscFunctionReturn(0);
95047c6ae99SBarry Smith }
95147c6ae99SBarry Smith 
95214354c39SJed Brown #undef __FUNCT__
95314354c39SJed Brown #define __FUNCT__ "DMCoarsen_Composite"
95414354c39SJed Brown PetscErrorCode  DMCoarsen_Composite(DM dmi,MPI_Comm comm,DM *fine)
95514354c39SJed Brown {
95614354c39SJed Brown   PetscErrorCode         ierr;
95714354c39SJed Brown   struct DMCompositeLink *next;
95814354c39SJed Brown   DM_Composite           *com = (DM_Composite*)dmi->data;
95914354c39SJed Brown   DM                     dm;
96014354c39SJed Brown 
96114354c39SJed Brown   PetscFunctionBegin;
96214354c39SJed Brown   PetscValidHeaderSpecific(dmi,DM_CLASSID,1);
9632ce3a92bSJed Brown   ierr = DMSetUp(dmi);CHKERRQ(ierr);
9642ee06e3bSJed Brown   if (comm == MPI_COMM_NULL) {
96525296bd5SBarry Smith     ierr = PetscObjectGetComm((PetscObject)dmi,&comm);CHKERRQ(ierr);
96625296bd5SBarry Smith   }
96714354c39SJed Brown   next = com->next;
96814354c39SJed Brown   ierr = DMCompositeCreate(comm,fine);CHKERRQ(ierr);
96914354c39SJed Brown 
97014354c39SJed Brown   /* loop over packed objects, handling one at at time */
97114354c39SJed Brown   while (next) {
97214354c39SJed Brown     ierr = DMCoarsen(next->dm,comm,&dm);CHKERRQ(ierr);
97314354c39SJed Brown     ierr = DMCompositeAddDM(*fine,dm);CHKERRQ(ierr);
97414354c39SJed Brown     ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr);
97514354c39SJed Brown     next = next->next;
97614354c39SJed Brown   }
97714354c39SJed Brown   PetscFunctionReturn(0);
97814354c39SJed Brown }
97947c6ae99SBarry Smith 
98047c6ae99SBarry Smith #undef __FUNCT__
981e727c939SJed Brown #define __FUNCT__ "DMCreateInterpolation_Composite"
982e727c939SJed Brown PetscErrorCode  DMCreateInterpolation_Composite(DM coarse,DM fine,Mat *A,Vec *v)
98347c6ae99SBarry Smith {
98447c6ae99SBarry Smith   PetscErrorCode         ierr;
9859ae5db72SJed Brown   PetscInt               m,n,M,N,nDM,i;
98647c6ae99SBarry Smith   struct DMCompositeLink *nextc;
98747c6ae99SBarry Smith   struct DMCompositeLink *nextf;
98825296bd5SBarry Smith   Vec                    gcoarse,gfine,*vecs;
98947c6ae99SBarry Smith   DM_Composite           *comcoarse = (DM_Composite*)coarse->data;
99047c6ae99SBarry Smith   DM_Composite           *comfine = (DM_Composite*)fine->data;
9919ae5db72SJed Brown   Mat                    *mats;
99247c6ae99SBarry Smith 
99347c6ae99SBarry Smith   PetscFunctionBegin;
99447c6ae99SBarry Smith   PetscValidHeaderSpecific(coarse,DM_CLASSID,1);
99547c6ae99SBarry Smith   PetscValidHeaderSpecific(fine,DM_CLASSID,2);
996f692024eSJed Brown   ierr = DMSetUp(coarse);CHKERRQ(ierr);
997f692024eSJed Brown   ierr = DMSetUp(fine);CHKERRQ(ierr);
99847c6ae99SBarry Smith   /* use global vectors only for determining matrix layout */
9999ae5db72SJed Brown   ierr = DMGetGlobalVector(coarse,&gcoarse);CHKERRQ(ierr);
10009ae5db72SJed Brown   ierr = DMGetGlobalVector(fine,&gfine);CHKERRQ(ierr);
100147c6ae99SBarry Smith   ierr = VecGetLocalSize(gcoarse,&n);CHKERRQ(ierr);
100247c6ae99SBarry Smith   ierr = VecGetLocalSize(gfine,&m);CHKERRQ(ierr);
100347c6ae99SBarry Smith   ierr = VecGetSize(gcoarse,&N);CHKERRQ(ierr);
100447c6ae99SBarry Smith   ierr = VecGetSize(gfine,&M);CHKERRQ(ierr);
10059ae5db72SJed Brown   ierr = DMRestoreGlobalVector(coarse,&gcoarse);CHKERRQ(ierr);
10069ae5db72SJed Brown   ierr = DMRestoreGlobalVector(fine,&gfine);CHKERRQ(ierr);
100747c6ae99SBarry Smith 
10089ae5db72SJed Brown   nDM = comfine->nDM;
10099ae5db72SJed 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);
10109ae5db72SJed Brown   ierr = PetscMalloc(nDM*nDM*sizeof(Mat),&mats);CHKERRQ(ierr);
10119ae5db72SJed Brown   ierr = PetscMemzero(mats,nDM*nDM*sizeof(Mat));CHKERRQ(ierr);
101225296bd5SBarry Smith   if (v) {
101325296bd5SBarry Smith     ierr = PetscMalloc(nDM*sizeof(Vec),&vecs);CHKERRQ(ierr);
101425296bd5SBarry Smith     ierr = PetscMemzero(vecs,nDM*sizeof(Vec));CHKERRQ(ierr);
101525296bd5SBarry Smith   }
101647c6ae99SBarry Smith 
101747c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
10189ae5db72SJed Brown   for (nextc=comcoarse->next,nextf=comfine->next,i=0; nextc; nextc=nextc->next,nextf=nextf->next,i++) {
101925296bd5SBarry Smith     if (!v) {
1020e727c939SJed Brown       ierr = DMCreateInterpolation(nextc->dm,nextf->dm,&mats[i*nDM+i],PETSC_NULL);CHKERRQ(ierr);
102125296bd5SBarry Smith     } else {
102225296bd5SBarry Smith       ierr = DMCreateInterpolation(nextc->dm,nextf->dm,&mats[i*nDM+i],&vecs[i]);CHKERRQ(ierr);
102325296bd5SBarry Smith     }
102447c6ae99SBarry Smith   }
10259ae5db72SJed Brown   ierr = MatCreateNest(((PetscObject)fine)->comm,nDM,PETSC_NULL,nDM,PETSC_NULL,mats,A);CHKERRQ(ierr);
102625296bd5SBarry Smith   if (v) {
102725296bd5SBarry Smith     ierr = VecCreateNest(((PetscObject)fine)->comm,nDM,PETSC_NULL,vecs,v);CHKERRQ(ierr);
102825296bd5SBarry Smith   }
10299ae5db72SJed Brown   for (i=0; i<nDM*nDM; i++) {ierr = MatDestroy(&mats[i]);CHKERRQ(ierr);}
10309ae5db72SJed Brown   ierr = PetscFree(mats);CHKERRQ(ierr);
103125296bd5SBarry Smith   if (v) {
103225296bd5SBarry Smith     for (i=0; i<nDM; i++) {ierr = VecDestroy(&vecs[i]);CHKERRQ(ierr);}
103325296bd5SBarry Smith     ierr = PetscFree(vecs);CHKERRQ(ierr);
103425296bd5SBarry Smith   }
103547c6ae99SBarry Smith   PetscFunctionReturn(0);
103647c6ae99SBarry Smith }
103747c6ae99SBarry Smith 
103847c6ae99SBarry Smith #undef __FUNCT__
10391411c6eeSJed Brown #define __FUNCT__ "DMCreateLocalToGlobalMapping_Composite"
10401411c6eeSJed Brown static PetscErrorCode DMCreateLocalToGlobalMapping_Composite(DM dm)
10411411c6eeSJed Brown {
10421411c6eeSJed Brown   DM_Composite           *com = (DM_Composite*)dm->data;
10431411c6eeSJed Brown   ISLocalToGlobalMapping *ltogs;
1044f7efa3c7SJed Brown   PetscInt               i;
10451411c6eeSJed Brown   PetscErrorCode         ierr;
10461411c6eeSJed Brown 
10471411c6eeSJed Brown   PetscFunctionBegin;
10481411c6eeSJed Brown   /* Set the ISLocalToGlobalMapping on the new matrix */
10491411c6eeSJed Brown   ierr = DMCompositeGetISLocalToGlobalMappings(dm,&ltogs);CHKERRQ(ierr);
10509ae5db72SJed Brown   ierr = ISLocalToGlobalMappingConcatenate(((PetscObject)dm)->comm,com->nDM,ltogs,&dm->ltogmap);CHKERRQ(ierr);
10519ae5db72SJed Brown   for (i=0; i<com->nDM; i++) {ierr = ISLocalToGlobalMappingDestroy(&ltogs[i]);CHKERRQ(ierr);}
10521411c6eeSJed Brown   ierr = PetscFree(ltogs);CHKERRQ(ierr);
10531411c6eeSJed Brown   PetscFunctionReturn(0);
10541411c6eeSJed Brown }
10551411c6eeSJed Brown 
10561411c6eeSJed Brown 
10571411c6eeSJed Brown #undef __FUNCT__
1058e727c939SJed Brown #define __FUNCT__ "DMCreateColoring_Composite"
105919fd82e9SBarry Smith PetscErrorCode  DMCreateColoring_Composite(DM dm,ISColoringType ctype,MatType mtype,ISColoring *coloring)
106047c6ae99SBarry Smith {
106147c6ae99SBarry Smith   PetscErrorCode         ierr;
106247c6ae99SBarry Smith   PetscInt               n,i,cnt;
106347c6ae99SBarry Smith   ISColoringValue        *colors;
106447c6ae99SBarry Smith   PetscBool              dense = PETSC_FALSE;
106547c6ae99SBarry Smith   ISColoringValue        maxcol = 0;
106647c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
106747c6ae99SBarry Smith 
106847c6ae99SBarry Smith   PetscFunctionBegin;
106947c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
10709805c61eSBarry Smith   if (ctype == IS_COLORING_GHOSTED) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"Only global coloring supported" );
1071e3247f34SBarry Smith   else if (ctype == IS_COLORING_GLOBAL) {
107247c6ae99SBarry Smith     n = com->n;
107347c6ae99SBarry Smith   } else SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Unknown ISColoringType");
107447c6ae99SBarry Smith   ierr = PetscMalloc(n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr); /* freed in ISColoringDestroy() */
107547c6ae99SBarry Smith 
1076671f6225SBarry Smith   ierr = PetscOptionsGetBool(PETSC_NULL,"-dmcomposite_dense_jacobian",&dense,PETSC_NULL);CHKERRQ(ierr);
107747c6ae99SBarry Smith   if (dense) {
107847c6ae99SBarry Smith     for (i=0; i<n; i++) {
107947c6ae99SBarry Smith       colors[i] = (ISColoringValue)(com->rstart + i);
108047c6ae99SBarry Smith     }
108147c6ae99SBarry Smith     maxcol = com->N;
108247c6ae99SBarry Smith   } else {
108347c6ae99SBarry Smith     struct DMCompositeLink *next = com->next;
108447c6ae99SBarry Smith     PetscMPIInt            rank;
108547c6ae99SBarry Smith 
108647c6ae99SBarry Smith     ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr);
108747c6ae99SBarry Smith     cnt  = 0;
108847c6ae99SBarry Smith     while (next) {
108947c6ae99SBarry Smith       ISColoring     lcoloring;
109047c6ae99SBarry Smith 
1091e727c939SJed Brown       ierr = DMCreateColoring(next->dm,IS_COLORING_GLOBAL,mtype,&lcoloring);CHKERRQ(ierr);
109247c6ae99SBarry Smith       for (i=0; i<lcoloring->N; i++) {
109347c6ae99SBarry Smith         colors[cnt++] = maxcol + lcoloring->colors[i];
109447c6ae99SBarry Smith       }
109547c6ae99SBarry Smith       maxcol += lcoloring->n;
1096fcfd50ebSBarry Smith       ierr = ISColoringDestroy(&lcoloring);CHKERRQ(ierr);
109747c6ae99SBarry Smith       next = next->next;
109847c6ae99SBarry Smith     }
109947c6ae99SBarry Smith   }
110047c6ae99SBarry Smith   ierr = ISColoringCreate(((PetscObject)dm)->comm,maxcol,n,colors,coloring);CHKERRQ(ierr);
110147c6ae99SBarry Smith   PetscFunctionReturn(0);
110247c6ae99SBarry Smith }
110347c6ae99SBarry Smith 
110447c6ae99SBarry Smith #undef __FUNCT__
11050c010503SBarry Smith #define __FUNCT__ "DMGlobalToLocalBegin_Composite"
11067087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalBegin_Composite(DM dm,Vec gvec,InsertMode mode,Vec lvec)
110747c6ae99SBarry Smith {
110847c6ae99SBarry Smith   PetscErrorCode         ierr;
110947c6ae99SBarry Smith   struct DMCompositeLink *next;
111047c6ae99SBarry Smith   PetscInt               cnt = 3;
111147c6ae99SBarry Smith   PetscMPIInt            rank;
111247c6ae99SBarry Smith   PetscScalar            *garray,*larray;
111347c6ae99SBarry Smith   DM_Composite           *com = (DM_Composite*)dm->data;
111447c6ae99SBarry Smith 
111547c6ae99SBarry Smith   PetscFunctionBegin;
111647c6ae99SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
111747c6ae99SBarry Smith   PetscValidHeaderSpecific(gvec,VEC_CLASSID,2);
111847c6ae99SBarry Smith   next = com->next;
111947c6ae99SBarry Smith   if (!com->setup) {
1120d7bf68aeSBarry Smith     ierr = DMSetUp(dm);CHKERRQ(ierr);
112147c6ae99SBarry Smith   }
112247c6ae99SBarry Smith   ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr);
112347c6ae99SBarry Smith   ierr = VecGetArray(gvec,&garray);CHKERRQ(ierr);
112447c6ae99SBarry Smith   ierr = VecGetArray(lvec,&larray);CHKERRQ(ierr);
112547c6ae99SBarry Smith 
112647c6ae99SBarry Smith   /* loop over packed objects, handling one at at time */
112747c6ae99SBarry Smith   while (next) {
112847c6ae99SBarry Smith     Vec      local,global;
112947c6ae99SBarry Smith     PetscInt N;
113047c6ae99SBarry Smith 
113147c6ae99SBarry Smith     ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr);
113247c6ae99SBarry Smith     ierr = VecGetLocalSize(global,&N);CHKERRQ(ierr);
113347c6ae99SBarry Smith     ierr = VecPlaceArray(global,garray);CHKERRQ(ierr);
113447c6ae99SBarry Smith     ierr = DMGetLocalVector(next->dm,&local);CHKERRQ(ierr);
113547c6ae99SBarry Smith     ierr = VecPlaceArray(local,larray);CHKERRQ(ierr);
113647c6ae99SBarry Smith     ierr = DMGlobalToLocalBegin(next->dm,global,mode,local);CHKERRQ(ierr);
113747c6ae99SBarry Smith     ierr = DMGlobalToLocalEnd(next->dm,global,mode,local);CHKERRQ(ierr);
113847c6ae99SBarry Smith     ierr = VecResetArray(global);CHKERRQ(ierr);
113947c6ae99SBarry Smith     ierr = VecResetArray(local);CHKERRQ(ierr);
114047c6ae99SBarry Smith     ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr);
114147c6ae99SBarry Smith     ierr = DMRestoreGlobalVector(next->dm,&local);CHKERRQ(ierr);
114247c6ae99SBarry Smith     cnt++;
114306ebdd98SJed Brown     larray += next->nlocal;
114447c6ae99SBarry Smith     next    = next->next;
114547c6ae99SBarry Smith   }
114647c6ae99SBarry Smith 
114747c6ae99SBarry Smith   ierr = VecRestoreArray(gvec,PETSC_NULL);CHKERRQ(ierr);
114847c6ae99SBarry Smith   ierr = VecRestoreArray(lvec,PETSC_NULL);CHKERRQ(ierr);
114947c6ae99SBarry Smith   PetscFunctionReturn(0);
115047c6ae99SBarry Smith }
115147c6ae99SBarry Smith 
115247c6ae99SBarry Smith #undef __FUNCT__
11530c010503SBarry Smith #define __FUNCT__ "DMGlobalToLocalEnd_Composite"
11547087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalEnd_Composite(DM dm,Vec gvec,InsertMode mode,Vec lvec)
11550c010503SBarry Smith {
11560c010503SBarry Smith   PetscFunctionBegin;
11570c010503SBarry Smith   PetscFunctionReturn(0);
11580c010503SBarry Smith }
115947c6ae99SBarry Smith 
11606ae3a549SBarry Smith /*MC
11616ae3a549SBarry Smith    DMCOMPOSITE = "composite" - A DM object that is used to manage data for a collection of DMs
11626ae3a549SBarry Smith 
11636ae3a549SBarry Smith 
11646ae3a549SBarry Smith 
11656ae3a549SBarry Smith   Level: intermediate
11666ae3a549SBarry Smith 
11676ae3a549SBarry Smith .seealso: DMType, DMCOMPOSITE, DMDACreate(), DMCreate(), DMSetType(), DMCompositeCreate()
11686ae3a549SBarry Smith M*/
11696ae3a549SBarry Smith 
11706ae3a549SBarry Smith 
1171a4121054SBarry Smith EXTERN_C_BEGIN
1172a4121054SBarry Smith #undef __FUNCT__
1173a4121054SBarry Smith #define __FUNCT__ "DMCreate_Composite"
11747087cfbeSBarry Smith PetscErrorCode  DMCreate_Composite(DM p)
1175a4121054SBarry Smith {
1176a4121054SBarry Smith   PetscErrorCode ierr;
1177a4121054SBarry Smith   DM_Composite   *com;
1178a4121054SBarry Smith 
1179a4121054SBarry Smith   PetscFunctionBegin;
1180a4121054SBarry Smith   ierr = PetscNewLog(p,DM_Composite,&com);CHKERRQ(ierr);
1181a4121054SBarry Smith   p->data = com;
1182a4121054SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)p,"DMComposite");CHKERRQ(ierr);
1183a4121054SBarry Smith   com->n            = 0;
1184a4121054SBarry Smith   com->next         = PETSC_NULL;
1185a4121054SBarry Smith   com->nDM          = 0;
1186a4121054SBarry Smith 
1187a4121054SBarry Smith   p->ops->createglobalvector              = DMCreateGlobalVector_Composite;
1188a4121054SBarry Smith   p->ops->createlocalvector               = DMCreateLocalVector_Composite;
11891411c6eeSJed Brown   p->ops->createlocaltoglobalmapping      = DMCreateLocalToGlobalMapping_Composite;
11901411c6eeSJed Brown   p->ops->createlocaltoglobalmappingblock = 0;
11914d343eeaSMatthew G Knepley   p->ops->createfieldis                   = DMCreateFieldIS_Composite;
119216621825SDmitry Karpeev   p->ops->createfielddecomposition        = DMCreateFieldDecomposition_Composite;
1193a4121054SBarry Smith   p->ops->refine                          = DMRefine_Composite;
119414354c39SJed Brown   p->ops->coarsen                         = DMCoarsen_Composite;
119525296bd5SBarry Smith   p->ops->createinterpolation             = DMCreateInterpolation_Composite;
119625296bd5SBarry Smith   p->ops->creatematrix                    = DMCreateMatrix_Composite;
1197e727c939SJed Brown   p->ops->getcoloring                     = DMCreateColoring_Composite;
1198a4121054SBarry Smith   p->ops->globaltolocalbegin              = DMGlobalToLocalBegin_Composite;
1199a4121054SBarry Smith   p->ops->globaltolocalend                = DMGlobalToLocalEnd_Composite;
1200a4121054SBarry Smith   p->ops->destroy                         = DMDestroy_Composite;
1201a4121054SBarry Smith   p->ops->view                            = DMView_Composite;
1202a4121054SBarry Smith   p->ops->setup                           = DMSetUp_Composite;
1203a4121054SBarry Smith   PetscFunctionReturn(0);
1204a4121054SBarry Smith }
1205a4121054SBarry Smith EXTERN_C_END
1206a4121054SBarry Smith 
12070c010503SBarry Smith #undef __FUNCT__
12080c010503SBarry Smith #define __FUNCT__ "DMCompositeCreate"
12090c010503SBarry Smith /*@C
12100c010503SBarry Smith     DMCompositeCreate - Creates a vector packer, used to generate "composite"
12110c010503SBarry Smith       vectors made up of several subvectors.
12120c010503SBarry Smith 
12130c010503SBarry Smith     Collective on MPI_Comm
121447c6ae99SBarry Smith 
121547c6ae99SBarry Smith     Input Parameter:
12160c010503SBarry Smith .   comm - the processors that will share the global vector
12170c010503SBarry Smith 
12180c010503SBarry Smith     Output Parameters:
12190c010503SBarry Smith .   packer - the packer object
122047c6ae99SBarry Smith 
122147c6ae99SBarry Smith     Level: advanced
122247c6ae99SBarry Smith 
12239ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCompositeScatter(),
12246eb61c8cSJed Brown          DMCompositeGather(), DMCreateGlobalVector(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess()
122547c6ae99SBarry Smith          DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries()
122647c6ae99SBarry Smith 
122747c6ae99SBarry Smith @*/
12287087cfbeSBarry Smith PetscErrorCode  DMCompositeCreate(MPI_Comm comm,DM *packer)
122947c6ae99SBarry Smith {
12300c010503SBarry Smith   PetscErrorCode ierr;
12310c010503SBarry Smith 
123247c6ae99SBarry Smith   PetscFunctionBegin;
12330c010503SBarry Smith   PetscValidPointer(packer,2);
1234a4121054SBarry Smith   ierr = DMCreate(comm,packer);CHKERRQ(ierr);
1235a4121054SBarry Smith   ierr = DMSetType(*packer,DMCOMPOSITE);CHKERRQ(ierr);
123647c6ae99SBarry Smith   PetscFunctionReturn(0);
123747c6ae99SBarry Smith }
1238