xref: /petsc/src/dm/impls/redundant/dmredundant.c (revision b45d2f2cb7e031d9c0de5873eca80614ca7b863b)
1*b45d2f2cSJed Brown #include <petsc-private/dmimpl.h>     /*I      "petscdm.h"          I*/
28ac4e037SJed Brown #include <petscdmredundant.h>   /*I      "petscdmredundant.h" I*/
38ac4e037SJed Brown #include <petscmat.h>           /*I      "petscmat.h"         I*/
48ac4e037SJed Brown 
58ac4e037SJed Brown typedef struct  {
68ac4e037SJed Brown   PetscInt rank;                /* owner */
78ac4e037SJed Brown   PetscInt N;                   /* total number of dofs */
88ac4e037SJed Brown   PetscInt n;                   /* owned number of dofs, n=N on owner, n=0 on non-owners */
98ac4e037SJed Brown } DM_Redundant;
108ac4e037SJed Brown 
118ac4e037SJed Brown #undef __FUNCT__
12950540a4SJed Brown #define __FUNCT__ "DMCreateMatrix_Redundant"
13950540a4SJed Brown static PetscErrorCode DMCreateMatrix_Redundant(DM dm,const MatType mtype,Mat *J)
148ac4e037SJed Brown {
158ac4e037SJed Brown   DM_Redundant           *red = (DM_Redundant*)dm->data;
168ac4e037SJed Brown   PetscErrorCode         ierr;
178ac4e037SJed Brown   ISLocalToGlobalMapping ltog,ltogb;
18d2e2b695SJed Brown   PetscInt               i,rstart,rend,*cols;
19d2e2b695SJed Brown   PetscScalar            *vals;
208ac4e037SJed Brown 
218ac4e037SJed Brown   PetscFunctionBegin;
228ac4e037SJed Brown   ierr = MatCreate(((PetscObject)dm)->comm,J);CHKERRQ(ierr);
238ac4e037SJed Brown   ierr = MatSetSizes(*J,red->n,red->n,red->N,red->N);CHKERRQ(ierr);
248ac4e037SJed Brown   ierr = MatSetType(*J,mtype);CHKERRQ(ierr);
258ac4e037SJed Brown   ierr = MatSeqAIJSetPreallocation(*J,red->n,PETSC_NULL);CHKERRQ(ierr);
268ac4e037SJed Brown   ierr = MatSeqBAIJSetPreallocation(*J,1,red->n,PETSC_NULL);CHKERRQ(ierr);
278ac4e037SJed Brown   ierr = MatMPIAIJSetPreallocation(*J,red->n,PETSC_NULL,red->N-red->n,PETSC_NULL);CHKERRQ(ierr);
288ac4e037SJed Brown   ierr = MatMPIBAIJSetPreallocation(*J,1,red->n,PETSC_NULL,red->N-red->n,PETSC_NULL);CHKERRQ(ierr);
298ac4e037SJed Brown 
308ac4e037SJed Brown   ierr = DMGetLocalToGlobalMapping(dm,&ltog);CHKERRQ(ierr);
318ac4e037SJed Brown   ierr = DMGetLocalToGlobalMappingBlock(dm,&ltogb);CHKERRQ(ierr);
328ac4e037SJed Brown   ierr = MatSetLocalToGlobalMapping(*J,ltog,ltog);CHKERRQ(ierr);
338ac4e037SJed Brown   ierr = MatSetLocalToGlobalMappingBlock(*J,ltogb,ltogb);CHKERRQ(ierr);
34d2e2b695SJed Brown 
35d2e2b695SJed Brown   ierr = PetscMalloc2(red->N,PetscInt,&cols,red->N,PetscScalar,&vals);CHKERRQ(ierr);
36d2e2b695SJed Brown   for (i=0; i<red->N; i++) {
37d2e2b695SJed Brown     cols[i] = i;
38d2e2b695SJed Brown     vals[i] = 0.0;
39d2e2b695SJed Brown   }
40d2e2b695SJed Brown   ierr = MatGetOwnershipRange(*J,&rstart,&rend);CHKERRQ(ierr);
41d2e2b695SJed Brown   for (i=rstart; i<rend; i++) {
42d2e2b695SJed Brown     ierr = MatSetValues(*J,1,&i,red->N,cols,vals,INSERT_VALUES);CHKERRQ(ierr);
43d2e2b695SJed Brown   }
44d2e2b695SJed Brown   ierr = PetscFree2(cols,vals);CHKERRQ(ierr);
45d2e2b695SJed Brown   ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
46d2e2b695SJed Brown   ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
478ac4e037SJed Brown   PetscFunctionReturn(0);
488ac4e037SJed Brown }
498ac4e037SJed Brown 
508ac4e037SJed Brown #undef __FUNCT__
518ac4e037SJed Brown #define __FUNCT__ "DMDestroy_Redundant"
528ac4e037SJed Brown static PetscErrorCode DMDestroy_Redundant(DM dm)
538ac4e037SJed Brown {
548ac4e037SJed Brown   PetscErrorCode ierr;
558ac4e037SJed Brown 
568ac4e037SJed Brown   PetscFunctionBegin;
578ac4e037SJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)dm,"DMRedundantSetSize_C","",PETSC_NULL);CHKERRQ(ierr);
588ac4e037SJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)dm,"DMRedundantGetSize_C","",PETSC_NULL);CHKERRQ(ierr);
598ac4e037SJed Brown   PetscFunctionReturn(0);
608ac4e037SJed Brown }
618ac4e037SJed Brown 
628ac4e037SJed Brown #undef __FUNCT__
638ac4e037SJed Brown #define __FUNCT__ "DMCreateGlobalVector_Redundant"
648ac4e037SJed Brown static PetscErrorCode DMCreateGlobalVector_Redundant(DM dm,Vec *gvec)
658ac4e037SJed Brown {
668ac4e037SJed Brown   PetscErrorCode         ierr;
678ac4e037SJed Brown   DM_Redundant           *red = (DM_Redundant*)dm->data;
688ac4e037SJed Brown   ISLocalToGlobalMapping ltog,ltogb;
698ac4e037SJed Brown 
708ac4e037SJed Brown   PetscFunctionBegin;
718ac4e037SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
728ac4e037SJed Brown   PetscValidPointer(gvec,2);
738ac4e037SJed Brown   *gvec = 0;
748ac4e037SJed Brown   ierr = VecCreate(((PetscObject)dm)->comm,gvec);CHKERRQ(ierr);
758ac4e037SJed Brown   ierr = VecSetSizes(*gvec,red->n,red->N);CHKERRQ(ierr);
768ac4e037SJed Brown   ierr = VecSetType(*gvec,dm->vectype);CHKERRQ(ierr);
778ac4e037SJed Brown   ierr = DMGetLocalToGlobalMapping(dm,&ltog);CHKERRQ(ierr);
788ac4e037SJed Brown   ierr = DMGetLocalToGlobalMappingBlock(dm,&ltogb);CHKERRQ(ierr);
798ac4e037SJed Brown   ierr = VecSetLocalToGlobalMapping(*gvec,ltog);CHKERRQ(ierr);
808ac4e037SJed Brown   ierr = VecSetLocalToGlobalMappingBlock(*gvec,ltog);CHKERRQ(ierr);
818ac4e037SJed Brown   ierr = PetscObjectCompose((PetscObject)*gvec,"DM",(PetscObject)dm);CHKERRQ(ierr);
828ac4e037SJed Brown   PetscFunctionReturn(0);
838ac4e037SJed Brown }
848ac4e037SJed Brown 
858ac4e037SJed Brown #undef __FUNCT__
868ac4e037SJed Brown #define __FUNCT__ "DMCreateLocalVector_Redundant"
878ac4e037SJed Brown static PetscErrorCode DMCreateLocalVector_Redundant(DM dm,Vec *lvec)
888ac4e037SJed Brown {
898ac4e037SJed Brown   PetscErrorCode         ierr;
908ac4e037SJed Brown   DM_Redundant           *red = (DM_Redundant*)dm->data;
918ac4e037SJed Brown 
928ac4e037SJed Brown   PetscFunctionBegin;
938ac4e037SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
948ac4e037SJed Brown   PetscValidPointer(lvec,2);
958ac4e037SJed Brown   *lvec = 0;
968ac4e037SJed Brown   ierr = VecCreate(PETSC_COMM_SELF,lvec);CHKERRQ(ierr);
978ac4e037SJed Brown   ierr = VecSetSizes(*lvec,red->N,red->N);CHKERRQ(ierr);
988ac4e037SJed Brown   ierr = VecSetType(*lvec,dm->vectype);CHKERRQ(ierr);
998ac4e037SJed Brown   ierr = PetscObjectCompose((PetscObject)*lvec,"DM",(PetscObject)dm);CHKERRQ(ierr);
1008ac4e037SJed Brown   PetscFunctionReturn(0);
1018ac4e037SJed Brown }
1028ac4e037SJed Brown 
1038ac4e037SJed Brown #undef __FUNCT__
1048ac4e037SJed Brown #define __FUNCT__ "DMLocalToGlobalBegin_Redundant"
1058ac4e037SJed Brown static PetscErrorCode DMLocalToGlobalBegin_Redundant(DM dm,Vec l,InsertMode imode,Vec g)
1068ac4e037SJed Brown {
1078ac4e037SJed Brown   PetscErrorCode    ierr;
1088ac4e037SJed Brown   DM_Redundant      *red = (DM_Redundant*)dm->data;
1098ac4e037SJed Brown   const PetscScalar *lv;
1108ac4e037SJed Brown   PetscScalar       *gv;
1118ac4e037SJed Brown   PetscMPIInt       rank;
1128ac4e037SJed Brown 
1138ac4e037SJed Brown   PetscFunctionBegin;
1148ac4e037SJed Brown   ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr);
1158ac4e037SJed Brown   ierr = VecGetArrayRead(l,&lv);CHKERRQ(ierr);
1168ac4e037SJed Brown   ierr = VecGetArray(g,&gv);CHKERRQ(ierr);
1178ac4e037SJed Brown   switch (imode) {
1188ac4e037SJed Brown   case ADD_VALUES:
1198ac4e037SJed Brown   case MAX_VALUES:
1208ac4e037SJed Brown   {
1218ac4e037SJed Brown     void *source;
1228ac4e037SJed Brown     PetscScalar *buffer;
1238ac4e037SJed Brown     PetscInt i;
1248ac4e037SJed Brown     if (rank == red->rank) {
1258ac4e037SJed Brown #if defined (PETSC_HAVE_MPI_IN_PLACE)
1268ac4e037SJed Brown       buffer = gv;
1278ac4e037SJed Brown       source = MPI_IN_PLACE;
1288ac4e037SJed Brown #else
1298ac4e037SJed Brown       ierr = PetscMalloc(red->N*sizeof(PetscScalar),&buffer);CHKERRQ(ierr);
1308ac4e037SJed Brown       source = buffer;
1318ac4e037SJed Brown #endif
1328ac4e037SJed Brown       if (imode == ADD_VALUES) for (i=0; i<red->N; i++) buffer[i] = gv[i] + lv[i];
1338ac4e037SJed Brown #if !defined(PETSC_USE_COMPLEX)
1348ac4e037SJed Brown       if (imode == MAX_VALUES) for (i=0; i<red->N; i++) buffer[i] = PetscMax(gv[i],lv[i]);
1358ac4e037SJed Brown #endif
1368ac4e037SJed Brown     } else {
1378ac4e037SJed Brown       source = (void*)lv;
1388ac4e037SJed Brown     }
1398ac4e037SJed Brown     ierr = MPI_Reduce(source,gv,red->N,MPIU_SCALAR,(imode == ADD_VALUES)?MPI_SUM:MPI_MAX,red->rank,((PetscObject)dm)->comm);CHKERRQ(ierr);
1408ac4e037SJed Brown #if !defined(PETSC_HAVE_MPI_IN_PLACE)
14199839c1eSBarry Smith     if (rank == red->rank) {ierr = PetscFree(buffer);CHKERRQ(ierr);}
1428ac4e037SJed Brown #endif
1438ac4e037SJed Brown   } break;
1448ac4e037SJed Brown   case INSERT_VALUES:
1458ac4e037SJed Brown   ierr = PetscMemcpy(gv,lv,red->n*sizeof(PetscScalar));CHKERRQ(ierr);
1468ac4e037SJed Brown   break;
1478ac4e037SJed Brown   default: SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"InsertMode not supported");
1488ac4e037SJed Brown   }
1498ac4e037SJed Brown   ierr = VecRestoreArrayRead(l,&lv);CHKERRQ(ierr);
1508ac4e037SJed Brown   ierr = VecRestoreArray(g,&gv);CHKERRQ(ierr);
1518ac4e037SJed Brown   PetscFunctionReturn(0);
1528ac4e037SJed Brown }
1538ac4e037SJed Brown 
1548ac4e037SJed Brown #undef __FUNCT__
1558ac4e037SJed Brown #define __FUNCT__ "DMLocalToGlobalEnd_Redundant"
1568ac4e037SJed Brown static PetscErrorCode DMLocalToGlobalEnd_Redundant(DM dm,Vec l,InsertMode imode,Vec g)
1578ac4e037SJed Brown {
1588ac4e037SJed Brown   PetscFunctionBegin;
1598ac4e037SJed Brown   PetscFunctionReturn(0);
1608ac4e037SJed Brown }
1618ac4e037SJed Brown 
1628ac4e037SJed Brown #undef __FUNCT__
1638ac4e037SJed Brown #define __FUNCT__ "DMGlobalToLocalBegin_Redundant"
1648ac4e037SJed Brown static PetscErrorCode DMGlobalToLocalBegin_Redundant(DM dm,Vec g,InsertMode imode,Vec l)
1658ac4e037SJed Brown {
1668ac4e037SJed Brown   PetscErrorCode    ierr;
1678ac4e037SJed Brown   DM_Redundant      *red = (DM_Redundant*)dm->data;
1688ac4e037SJed Brown   const PetscScalar *gv;
1698ac4e037SJed Brown   PetscScalar       *lv;
1708ac4e037SJed Brown 
1718ac4e037SJed Brown   PetscFunctionBegin;
1728ac4e037SJed Brown   ierr = VecGetArrayRead(g,&gv);CHKERRQ(ierr);
1738ac4e037SJed Brown   ierr = VecGetArray(l,&lv);CHKERRQ(ierr);
1748ac4e037SJed Brown   switch (imode) {
1758ac4e037SJed Brown   case INSERT_VALUES:
1768ac4e037SJed Brown     if (red->n) {ierr = PetscMemcpy(lv,gv,red->n*sizeof(PetscScalar));CHKERRQ(ierr);}
1778ac4e037SJed Brown     ierr = MPI_Bcast(lv,red->N,MPIU_SCALAR,red->rank,((PetscObject)dm)->comm);CHKERRQ(ierr);
1788ac4e037SJed Brown     break;
1798ac4e037SJed Brown   default: SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"InsertMode not supported");
1808ac4e037SJed Brown   }
1818ac4e037SJed Brown   ierr = VecRestoreArrayRead(g,&gv);CHKERRQ(ierr);
1828ac4e037SJed Brown   ierr = VecRestoreArray(l,&lv);CHKERRQ(ierr);
1838ac4e037SJed Brown   PetscFunctionReturn(0);
1848ac4e037SJed Brown }
1858ac4e037SJed Brown 
1868ac4e037SJed Brown #undef __FUNCT__
1878ac4e037SJed Brown #define __FUNCT__ "DMGlobalToLocalEnd_Redundant"
1888ac4e037SJed Brown static PetscErrorCode DMGlobalToLocalEnd_Redundant(DM dm,Vec g,InsertMode imode,Vec l)
1898ac4e037SJed Brown {
1908ac4e037SJed Brown   PetscFunctionBegin;
1918ac4e037SJed Brown   PetscFunctionReturn(0);
1928ac4e037SJed Brown }
1938ac4e037SJed Brown 
1948ac4e037SJed Brown #undef __FUNCT__
1958ac4e037SJed Brown #define __FUNCT__ "DMSetUp_Redundant"
1968ac4e037SJed Brown static PetscErrorCode DMSetUp_Redundant(DM dm)
1978ac4e037SJed Brown {
1988ac4e037SJed Brown   PetscErrorCode ierr;
1998ac4e037SJed Brown   DM_Redundant   *red = (DM_Redundant*)dm->data;
2008ac4e037SJed Brown   PetscInt       i,*globals;
2018ac4e037SJed Brown 
2028ac4e037SJed Brown   PetscFunctionBegin;
2038ac4e037SJed Brown   ierr = PetscMalloc(red->N*sizeof(PetscInt),&globals);CHKERRQ(ierr);
2048ac4e037SJed Brown   for (i=0; i<red->N; i++) globals[i] = i;
2058ac4e037SJed Brown   ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,red->N,globals,PETSC_OWN_POINTER,&dm->ltogmap);CHKERRQ(ierr);
2068ac4e037SJed Brown   ierr = PetscObjectReference((PetscObject)dm->ltogmap);CHKERRQ(ierr);
2078ac4e037SJed Brown   dm->ltogmapb = dm->ltogmap;
2088ac4e037SJed Brown   PetscFunctionReturn(0);
2098ac4e037SJed Brown }
2108ac4e037SJed Brown 
2118ac4e037SJed Brown #undef __FUNCT__
2128ac4e037SJed Brown #define __FUNCT__ "DMView_Redundant"
2138ac4e037SJed Brown static PetscErrorCode DMView_Redundant(DM dm,PetscViewer viewer)
2148ac4e037SJed Brown {
2158ac4e037SJed Brown   PetscErrorCode ierr;
2168ac4e037SJed Brown   DM_Redundant   *red = (DM_Redundant*)dm->data;
2178ac4e037SJed Brown   PetscBool      iascii;
2188ac4e037SJed Brown 
2198ac4e037SJed Brown   PetscFunctionBegin;
2208ac4e037SJed Brown   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
2218ac4e037SJed Brown   if (iascii) {
2228ac4e037SJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"redundant: rank=%D N=%D\n",red->rank,red->N);CHKERRQ(ierr);
2238ac4e037SJed Brown   }
2248ac4e037SJed Brown   PetscFunctionReturn(0);
2258ac4e037SJed Brown }
2268ac4e037SJed Brown 
22769527181SJed Brown #undef __FUNCT__
228e727c939SJed Brown #define __FUNCT__ "DMCreateColoring_Redundant"
229e727c939SJed Brown static PetscErrorCode DMCreateColoring_Redundant(DM dm,ISColoringType ctype,const MatType mtype,ISColoring *coloring)
23069527181SJed Brown {
23169527181SJed Brown   DM_Redundant   *red = (DM_Redundant*)dm->data;
23269527181SJed Brown   PetscErrorCode ierr;
23369527181SJed Brown   PetscInt i,nloc;
23469527181SJed Brown   ISColoringValue *colors;
23569527181SJed Brown 
23669527181SJed Brown   PetscFunctionBegin;
23769527181SJed Brown   switch (ctype) {
23869527181SJed Brown   case IS_COLORING_GLOBAL:
23969527181SJed Brown     nloc = red->n;
24069527181SJed Brown     break;
24169527181SJed Brown   case IS_COLORING_GHOSTED:
24269527181SJed Brown     nloc = red->N;
24369527181SJed Brown     break;
24469527181SJed Brown   default: SETERRQ1(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONG,"Unknown ISColoringType %d",(int)ctype);
24569527181SJed Brown   }
24669527181SJed Brown   ierr = PetscMalloc(nloc*sizeof(ISColoringValue),&colors);CHKERRQ(ierr);
24769527181SJed Brown   for (i=0; i<nloc; i++) colors[i] = i;
24869527181SJed Brown   ierr = ISColoringCreate(((PetscObject)dm)->comm,red->N,nloc,colors,coloring);CHKERRQ(ierr);
24969527181SJed Brown   ierr = ISColoringSetType(*coloring,ctype);CHKERRQ(ierr);
25069527181SJed Brown   PetscFunctionReturn(0);
25169527181SJed Brown }
2528ac4e037SJed Brown 
2538ac4e037SJed Brown #undef __FUNCT__
2548ac4e037SJed Brown #define __FUNCT__ "DMRefine_Redundant"
2558ac4e037SJed Brown static PetscErrorCode DMRefine_Redundant(DM dmc,MPI_Comm comm,DM *dmf)
2568ac4e037SJed Brown {
2578ac4e037SJed Brown   PetscErrorCode ierr;
2588ac4e037SJed Brown   PetscMPIInt flag;
2598ac4e037SJed Brown   DM_Redundant *redc = (DM_Redundant*)dmc->data;
2608ac4e037SJed Brown 
2618ac4e037SJed Brown   PetscFunctionBegin;
2628ac4e037SJed Brown   ierr = MPI_Comm_compare(((PetscObject)dmc)->comm,comm,&flag); CHKERRQ(ierr);
2638ac4e037SJed Brown   if (flag != MPI_CONGRUENT && flag != MPI_IDENT) SETERRQ(((PetscObject)dmc)->comm,PETSC_ERR_SUP,"cannot change communicators");
2648ac4e037SJed Brown   ierr = DMRedundantCreate(comm,redc->rank,redc->N,dmf);CHKERRQ(ierr);
2658ac4e037SJed Brown   PetscFunctionReturn(0);
2668ac4e037SJed Brown }
2678ac4e037SJed Brown 
2688ac4e037SJed Brown #undef __FUNCT__
2698ac4e037SJed Brown #define __FUNCT__ "DMCoarsen_Redundant"
2708ac4e037SJed Brown static PetscErrorCode DMCoarsen_Redundant(DM dmf,MPI_Comm comm,DM *dmc)
2718ac4e037SJed Brown {
2728ac4e037SJed Brown   PetscErrorCode ierr;
2738ac4e037SJed Brown   PetscMPIInt flag;
2748ac4e037SJed Brown   DM_Redundant *redf = (DM_Redundant*)dmf->data;
2758ac4e037SJed Brown 
2768ac4e037SJed Brown   PetscFunctionBegin;
2778ac4e037SJed Brown   ierr = MPI_Comm_compare(((PetscObject)dmf)->comm,comm,&flag); CHKERRQ(ierr);
2788ac4e037SJed Brown   if (flag != MPI_CONGRUENT && flag != MPI_IDENT) SETERRQ(((PetscObject)dmf)->comm,PETSC_ERR_SUP,"cannot change communicators");
2798ac4e037SJed Brown   ierr = DMRedundantCreate(comm,redf->rank,redf->N,dmc);CHKERRQ(ierr);
2808ac4e037SJed Brown   PetscFunctionReturn(0);
2818ac4e037SJed Brown }
2828ac4e037SJed Brown 
2838ac4e037SJed Brown #undef __FUNCT__
284e727c939SJed Brown #define __FUNCT__ "DMCreateInterpolation_Redundant"
285e727c939SJed Brown static PetscErrorCode DMCreateInterpolation_Redundant(DM dmc,DM dmf,Mat *P,Vec *scale)
2868ac4e037SJed Brown {
2878ac4e037SJed Brown   PetscErrorCode ierr;
2888ac4e037SJed Brown   DM_Redundant   *redc = (DM_Redundant*)dmc->data;
2898ac4e037SJed Brown   DM_Redundant   *redf = (DM_Redundant*)dmf->data;
2908ac4e037SJed Brown   PetscMPIInt    flag;
2918ac4e037SJed Brown   PetscInt       i,rstart,rend;
2928ac4e037SJed Brown 
2938ac4e037SJed Brown   PetscFunctionBegin;
2948ac4e037SJed Brown   ierr = MPI_Comm_compare(((PetscObject)dmc)->comm,((PetscObject)dmf)->comm,&flag); CHKERRQ(ierr);
2958ac4e037SJed Brown   if (flag != MPI_CONGRUENT && flag != MPI_IDENT) SETERRQ(((PetscObject)dmf)->comm,PETSC_ERR_SUP,"cannot change communicators");
2968ac4e037SJed Brown   if (redc->rank != redf->rank) SETERRQ(((PetscObject)dmf)->comm,PETSC_ERR_ARG_INCOMP,"Owning rank does not match");
2978ac4e037SJed Brown   if (redc->N != redf->N) SETERRQ(((PetscObject)dmf)->comm,PETSC_ERR_ARG_INCOMP,"Global size does not match");
2988ac4e037SJed Brown   ierr = MatCreate(((PetscObject)dmc)->comm,P);CHKERRQ(ierr);
2998ac4e037SJed Brown   ierr = MatSetSizes(*P,redc->n,redc->n,redc->N,redc->N);CHKERRQ(ierr);
3008ac4e037SJed Brown   ierr = MatSetType(*P,MATAIJ);CHKERRQ(ierr);
3018ac4e037SJed Brown   ierr = MatSeqAIJSetPreallocation(*P,1,0);CHKERRQ(ierr);
3028ac4e037SJed Brown   ierr = MatMPIAIJSetPreallocation(*P,1,0,0,0);CHKERRQ(ierr);
3038ac4e037SJed Brown   ierr = MatGetOwnershipRange(*P,&rstart,&rend);CHKERRQ(ierr);
3048ac4e037SJed Brown   for (i=rstart; i<rend; i++) {ierr = MatSetValue(*P,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr);}
3058ac4e037SJed Brown   ierr = MatAssemblyBegin(*P,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3068ac4e037SJed Brown   ierr = MatAssemblyEnd(*P,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
307e727c939SJed Brown   if (scale) {ierr = DMCreateInterpolationScale(dmc,dmf,*P,scale);CHKERRQ(ierr);}
3088ac4e037SJed Brown   PetscFunctionReturn(0);
3098ac4e037SJed Brown }
3108ac4e037SJed Brown 
3118ac4e037SJed Brown #undef __FUNCT__
3128ac4e037SJed Brown #define __FUNCT__ "DMRedundantSetSize"
3138ac4e037SJed Brown /*@
3148ac4e037SJed Brown     DMRedundantSetSize - Sets the size of a densely coupled redundant object
3158ac4e037SJed Brown 
3168ac4e037SJed Brown     Collective on DM
3178ac4e037SJed Brown 
3188ac4e037SJed Brown     Input Parameter:
3198ac4e037SJed Brown +   dm - redundant DM
3208ac4e037SJed Brown .   rank - rank of process to own redundant degrees of freedom
3218ac4e037SJed Brown -   N - total number of redundant degrees of freedom
3228ac4e037SJed Brown 
3238ac4e037SJed Brown     Level: advanced
3248ac4e037SJed Brown 
3258ac4e037SJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMRedundantCreate(), DMRedundantGetSize()
3268ac4e037SJed Brown @*/
3278ac4e037SJed Brown PetscErrorCode DMRedundantSetSize(DM dm,PetscInt rank,PetscInt N)
3288ac4e037SJed Brown {
3298ac4e037SJed Brown   PetscErrorCode ierr;
3308ac4e037SJed Brown 
3318ac4e037SJed Brown   PetscFunctionBegin;
3328ac4e037SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3338ac4e037SJed Brown   PetscValidType(dm,1);
3348ac4e037SJed Brown   PetscValidLogicalCollectiveInt(dm,rank,2);
3358ac4e037SJed Brown   PetscValidLogicalCollectiveInt(dm,N,3);
3368ac4e037SJed Brown   ierr = PetscTryMethod(dm,"DMRedundantSetSize_C",(DM,PetscInt,PetscInt),(dm,rank,N));CHKERRQ(ierr);
3378ac4e037SJed Brown   PetscFunctionReturn(0);
3388ac4e037SJed Brown }
3398ac4e037SJed Brown 
3408ac4e037SJed Brown #undef __FUNCT__
3418ac4e037SJed Brown #define __FUNCT__ "DMRedundantGetSize"
3428ac4e037SJed Brown /*@
3438ac4e037SJed Brown     DMRedundantGetSize - Gets the size of a densely coupled redundant object
3448ac4e037SJed Brown 
3458ac4e037SJed Brown     Not Collective
3468ac4e037SJed Brown 
3478ac4e037SJed Brown     Input Parameter:
3488ac4e037SJed Brown +   dm - redundant DM
3498ac4e037SJed Brown 
3508ac4e037SJed Brown     Output Parameters:
3518ac4e037SJed Brown +   rank - rank of process to own redundant degrees of freedom (or PETSC_NULL)
3528ac4e037SJed Brown -   N - total number of redundant degrees of freedom (or PETSC_NULL)
3538ac4e037SJed Brown 
3548ac4e037SJed Brown     Level: advanced
3558ac4e037SJed Brown 
3568ac4e037SJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMRedundantCreate(), DMRedundantSetSize()
3578ac4e037SJed Brown @*/
3588ac4e037SJed Brown PetscErrorCode DMRedundantGetSize(DM dm,PetscInt *rank,PetscInt *N)
3598ac4e037SJed Brown {
3608ac4e037SJed Brown   PetscErrorCode ierr;
3618ac4e037SJed Brown 
3628ac4e037SJed Brown   PetscFunctionBegin;
3638ac4e037SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3648ac4e037SJed Brown   PetscValidType(dm,1);
3658ac4e037SJed Brown   ierr = PetscUseMethod(dm,"DMRedundantGetSize_C",(DM,PetscInt*,PetscInt*),(dm,rank,N));CHKERRQ(ierr);
3668ac4e037SJed Brown   PetscFunctionReturn(0);
3678ac4e037SJed Brown }
3688ac4e037SJed Brown 
3698ac4e037SJed Brown EXTERN_C_BEGIN
3708ac4e037SJed Brown #undef __FUNCT__
3718ac4e037SJed Brown #define __FUNCT__ "DMRedundantSetSize_Redundant"
3728ac4e037SJed Brown PetscErrorCode DMRedundantSetSize_Redundant(DM dm,PetscInt rank,PetscInt N)
3738ac4e037SJed Brown {
3748ac4e037SJed Brown   DM_Redundant   *red = (DM_Redundant*)dm->data;
3758ac4e037SJed Brown   PetscErrorCode ierr;
3768ac4e037SJed Brown   PetscMPIInt    myrank;
3778ac4e037SJed Brown 
3788ac4e037SJed Brown   PetscFunctionBegin;
3798ac4e037SJed Brown   ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&myrank);CHKERRQ(ierr);
3808ac4e037SJed Brown   red->rank = rank;
3818ac4e037SJed Brown   red->N = N;
3828ac4e037SJed Brown   red->n = (myrank == rank) ? N : 0;
3838ac4e037SJed Brown   PetscFunctionReturn(0);
3848ac4e037SJed Brown }
3858ac4e037SJed Brown 
3868ac4e037SJed Brown #undef __FUNCT__
3878ac4e037SJed Brown #define __FUNCT__ "DMRedundantGetSize_Redundant"
3888ac4e037SJed Brown PetscErrorCode DMRedundantGetSize_Redundant(DM dm,PetscInt *rank,PetscInt *N)
3898ac4e037SJed Brown {
3908ac4e037SJed Brown   DM_Redundant   *red = (DM_Redundant*)dm->data;
3918ac4e037SJed Brown 
3928ac4e037SJed Brown   PetscFunctionBegin;
3938ac4e037SJed Brown   if (rank) *rank = red->rank;
3948ac4e037SJed Brown   if (N)    *N = red->N;
3958ac4e037SJed Brown   PetscFunctionReturn(0);
3968ac4e037SJed Brown }
3978ac4e037SJed Brown EXTERN_C_END
3988ac4e037SJed Brown 
3998ac4e037SJed Brown EXTERN_C_BEGIN
4008ac4e037SJed Brown #undef __FUNCT__
4018ac4e037SJed Brown #define __FUNCT__ "DMCreate_Redundant"
4028ac4e037SJed Brown PetscErrorCode DMCreate_Redundant(DM dm)
4038ac4e037SJed Brown {
4048ac4e037SJed Brown   PetscErrorCode ierr;
4058ac4e037SJed Brown   DM_Redundant   *red;
4068ac4e037SJed Brown 
4078ac4e037SJed Brown   PetscFunctionBegin;
4088ac4e037SJed Brown   ierr = PetscNewLog(dm,DM_Redundant,&red);CHKERRQ(ierr);
4098ac4e037SJed Brown   dm->data = red;
4108ac4e037SJed Brown 
4118ac4e037SJed Brown   ierr = PetscObjectChangeTypeName((PetscObject)dm,DMREDUNDANT);CHKERRQ(ierr);
4128ac4e037SJed Brown   dm->ops->setup              = DMSetUp_Redundant;
4138ac4e037SJed Brown   dm->ops->view               = DMView_Redundant;
4148ac4e037SJed Brown   dm->ops->createglobalvector = DMCreateGlobalVector_Redundant;
4158ac4e037SJed Brown   dm->ops->createlocalvector  = DMCreateLocalVector_Redundant;
41625296bd5SBarry Smith   dm->ops->creatematrix          = DMCreateMatrix_Redundant;
4178ac4e037SJed Brown   dm->ops->destroy            = DMDestroy_Redundant;
4188ac4e037SJed Brown   dm->ops->globaltolocalbegin = DMGlobalToLocalBegin_Redundant;
4198ac4e037SJed Brown   dm->ops->globaltolocalend   = DMGlobalToLocalEnd_Redundant;
4208ac4e037SJed Brown   dm->ops->localtoglobalbegin = DMLocalToGlobalBegin_Redundant;
4218ac4e037SJed Brown   dm->ops->localtoglobalend   = DMLocalToGlobalEnd_Redundant;
4228ac4e037SJed Brown   dm->ops->refine             = DMRefine_Redundant;
4238ac4e037SJed Brown   dm->ops->coarsen            = DMCoarsen_Redundant;
42425296bd5SBarry Smith   dm->ops->createinterpolation   = DMCreateInterpolation_Redundant;
425e727c939SJed Brown   dm->ops->getcoloring        = DMCreateColoring_Redundant;
4268ac4e037SJed Brown   ierr = PetscStrallocpy(VECSTANDARD,&dm->vectype);CHKERRQ(ierr);
4278ac4e037SJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)dm,"DMRedundantSetSize_C","DMRedundantSetSize_Redundant",DMRedundantSetSize_Redundant);CHKERRQ(ierr);
4288ac4e037SJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)dm,"DMRedundantGetSize_C","DMRedundantGetSize_Redundant",DMRedundantGetSize_Redundant);CHKERRQ(ierr);
4298ac4e037SJed Brown   PetscFunctionReturn(0);
4308ac4e037SJed Brown }
4318ac4e037SJed Brown EXTERN_C_END
4328ac4e037SJed Brown 
4338ac4e037SJed Brown #undef __FUNCT__
4348ac4e037SJed Brown #define __FUNCT__ "DMRedundantCreate"
4358ac4e037SJed Brown /*@C
4368ac4e037SJed Brown     DMRedundantCreate - Creates a DM object, used to manage data for dense globally coupled variables
4378ac4e037SJed Brown 
4388ac4e037SJed Brown     Collective on MPI_Comm
4398ac4e037SJed Brown 
4408ac4e037SJed Brown     Input Parameter:
4418ac4e037SJed Brown +   comm - the processors that will share the global vector
4428ac4e037SJed Brown .   rank - rank to own the redundant values
4438ac4e037SJed Brown -   N - total number of degrees of freedom
4448ac4e037SJed Brown 
4458ac4e037SJed Brown     Output Parameters:
4468ac4e037SJed Brown .   red - the redundant DM
4478ac4e037SJed Brown 
4488ac4e037SJed Brown     Level: advanced
4498ac4e037SJed Brown 
450950540a4SJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateMatrix(), DMCompositeAddDM()
4518ac4e037SJed Brown 
4528ac4e037SJed Brown @*/
4538ac4e037SJed Brown PetscErrorCode DMRedundantCreate(MPI_Comm comm,PetscInt rank,PetscInt N,DM *dm)
4548ac4e037SJed Brown {
4558ac4e037SJed Brown   PetscErrorCode ierr;
4568ac4e037SJed Brown 
4578ac4e037SJed Brown   PetscFunctionBegin;
4588ac4e037SJed Brown   PetscValidPointer(dm,2);
4598ac4e037SJed Brown   ierr = DMCreate(comm,dm);CHKERRQ(ierr);
4608ac4e037SJed Brown   ierr = DMSetType(*dm,DMREDUNDANT);CHKERRQ(ierr);
4618ac4e037SJed Brown   ierr = DMRedundantSetSize(*dm,rank,N);CHKERRQ(ierr);
4628ac4e037SJed Brown   ierr = DMSetUp(*dm);CHKERRQ(ierr);
4638ac4e037SJed Brown   PetscFunctionReturn(0);
4648ac4e037SJed Brown }
465