xref: /petsc/src/dm/impls/redundant/dmredundant.c (revision ea78f98c112368f404cd6d4fff6d4dfe73e5a1e7)
1af0996ceSBarry Smith #include <petsc/private/dmimpl.h>
28ac4e037SJed Brown #include <petscdmredundant.h>   /*I      "petscdmredundant.h" I*/
38ac4e037SJed Brown 
48ac4e037SJed Brown typedef struct  {
5907376e6SBarry Smith   PetscMPIInt rank;                /* owner */
68ac4e037SJed Brown   PetscInt    N;                   /* total number of dofs */
78ac4e037SJed Brown   PetscInt    n;                   /* owned number of dofs, n=N on owner, n=0 on non-owners */
88ac4e037SJed Brown } DM_Redundant;
98ac4e037SJed Brown 
10b412c318SBarry Smith static PetscErrorCode DMCreateMatrix_Redundant(DM dm,Mat *J)
118ac4e037SJed Brown {
128ac4e037SJed Brown   DM_Redundant           *red = (DM_Redundant*)dm->data;
138ac4e037SJed Brown   PetscErrorCode         ierr;
1445b6f7e9SBarry Smith   ISLocalToGlobalMapping ltog;
15d2e2b695SJed Brown   PetscInt               i,rstart,rend,*cols;
16d2e2b695SJed Brown   PetscScalar            *vals;
178ac4e037SJed Brown 
188ac4e037SJed Brown   PetscFunctionBegin;
19ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)dm),J);CHKERRQ(ierr);
208ac4e037SJed Brown   ierr = MatSetSizes(*J,red->n,red->n,red->N,red->N);CHKERRQ(ierr);
21b412c318SBarry Smith   ierr = MatSetType(*J,dm->mattype);CHKERRQ(ierr);
220298fd71SBarry Smith   ierr = MatSeqAIJSetPreallocation(*J,red->n,NULL);CHKERRQ(ierr);
230298fd71SBarry Smith   ierr = MatSeqBAIJSetPreallocation(*J,1,red->n,NULL);CHKERRQ(ierr);
240298fd71SBarry Smith   ierr = MatMPIAIJSetPreallocation(*J,red->n,NULL,red->N-red->n,NULL);CHKERRQ(ierr);
250298fd71SBarry Smith   ierr = MatMPIBAIJSetPreallocation(*J,1,red->n,NULL,red->N-red->n,NULL);CHKERRQ(ierr);
268ac4e037SJed Brown 
278ac4e037SJed Brown   ierr = DMGetLocalToGlobalMapping(dm,&ltog);CHKERRQ(ierr);
288ac4e037SJed Brown   ierr = MatSetLocalToGlobalMapping(*J,ltog,ltog);CHKERRQ(ierr);
29c6b011d8SStefano Zampini   ierr = MatSetDM(*J,dm);CHKERRQ(ierr);
30d2e2b695SJed Brown 
31dcca6d9dSJed Brown   ierr = PetscMalloc2(red->N,&cols,red->N,&vals);CHKERRQ(ierr);
32d2e2b695SJed Brown   for (i=0; i<red->N; i++) {
33d2e2b695SJed Brown     cols[i] = i;
34d2e2b695SJed Brown     vals[i] = 0.0;
35d2e2b695SJed Brown   }
36d2e2b695SJed Brown   ierr = MatGetOwnershipRange(*J,&rstart,&rend);CHKERRQ(ierr);
37d2e2b695SJed Brown   for (i=rstart; i<rend; i++) {
38d2e2b695SJed Brown     ierr = MatSetValues(*J,1,&i,red->N,cols,vals,INSERT_VALUES);CHKERRQ(ierr);
39d2e2b695SJed Brown   }
40d2e2b695SJed Brown   ierr = PetscFree2(cols,vals);CHKERRQ(ierr);
41d2e2b695SJed Brown   ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
42d2e2b695SJed Brown   ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
438ac4e037SJed Brown   PetscFunctionReturn(0);
448ac4e037SJed Brown }
458ac4e037SJed Brown 
468ac4e037SJed Brown static PetscErrorCode DMDestroy_Redundant(DM dm)
478ac4e037SJed Brown {
488ac4e037SJed Brown   PetscErrorCode ierr;
498ac4e037SJed Brown 
508ac4e037SJed Brown   PetscFunctionBegin;
51bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)dm,"DMRedundantSetSize_C",NULL);CHKERRQ(ierr);
52bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)dm,"DMRedundantGetSize_C",NULL);CHKERRQ(ierr);
5336623e74SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)dm,"DMSetUpGLVisViewer_C",NULL);CHKERRQ(ierr);
54435a35e8SMatthew G Knepley   /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */
55435a35e8SMatthew G Knepley   ierr = PetscFree(dm->data);CHKERRQ(ierr);
568ac4e037SJed Brown   PetscFunctionReturn(0);
578ac4e037SJed Brown }
588ac4e037SJed Brown 
598ac4e037SJed Brown static PetscErrorCode DMCreateGlobalVector_Redundant(DM dm,Vec *gvec)
608ac4e037SJed Brown {
618ac4e037SJed Brown   PetscErrorCode         ierr;
628ac4e037SJed Brown   DM_Redundant           *red = (DM_Redundant*)dm->data;
6345b6f7e9SBarry Smith   ISLocalToGlobalMapping ltog;
648ac4e037SJed Brown 
658ac4e037SJed Brown   PetscFunctionBegin;
668ac4e037SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
678ac4e037SJed Brown   PetscValidPointer(gvec,2);
68*ea78f98cSLisandro Dalcin   *gvec = NULL;
69ce94432eSBarry Smith   ierr  = VecCreate(PetscObjectComm((PetscObject)dm),gvec);CHKERRQ(ierr);
708ac4e037SJed Brown   ierr  = VecSetSizes(*gvec,red->n,red->N);CHKERRQ(ierr);
718ac4e037SJed Brown   ierr  = VecSetType(*gvec,dm->vectype);CHKERRQ(ierr);
728ac4e037SJed Brown   ierr  = DMGetLocalToGlobalMapping(dm,&ltog);CHKERRQ(ierr);
738ac4e037SJed Brown   ierr  = VecSetLocalToGlobalMapping(*gvec,ltog);CHKERRQ(ierr);
74c688c046SMatthew G Knepley   ierr  = VecSetDM(*gvec,dm);CHKERRQ(ierr);
758ac4e037SJed Brown   PetscFunctionReturn(0);
768ac4e037SJed Brown }
778ac4e037SJed Brown 
788ac4e037SJed Brown static PetscErrorCode DMCreateLocalVector_Redundant(DM dm,Vec *lvec)
798ac4e037SJed Brown {
808ac4e037SJed Brown   PetscErrorCode ierr;
818ac4e037SJed Brown   DM_Redundant   *red = (DM_Redundant*)dm->data;
828ac4e037SJed Brown 
838ac4e037SJed Brown   PetscFunctionBegin;
848ac4e037SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
858ac4e037SJed Brown   PetscValidPointer(lvec,2);
86*ea78f98cSLisandro Dalcin   *lvec = NULL;
878ac4e037SJed Brown   ierr  = VecCreate(PETSC_COMM_SELF,lvec);CHKERRQ(ierr);
888ac4e037SJed Brown   ierr  = VecSetSizes(*lvec,red->N,red->N);CHKERRQ(ierr);
898ac4e037SJed Brown   ierr  = VecSetType(*lvec,dm->vectype);CHKERRQ(ierr);
90c688c046SMatthew G Knepley   ierr  = VecSetDM(*lvec,dm);CHKERRQ(ierr);
918ac4e037SJed Brown   PetscFunctionReturn(0);
928ac4e037SJed Brown }
938ac4e037SJed Brown 
948ac4e037SJed Brown static PetscErrorCode DMLocalToGlobalBegin_Redundant(DM dm,Vec l,InsertMode imode,Vec g)
958ac4e037SJed Brown {
968ac4e037SJed Brown   PetscErrorCode    ierr;
978ac4e037SJed Brown   DM_Redundant      *red = (DM_Redundant*)dm->data;
988ac4e037SJed Brown   const PetscScalar *lv;
998ac4e037SJed Brown   PetscScalar       *gv;
1008ac4e037SJed Brown   PetscMPIInt       rank;
1018ac4e037SJed Brown 
1028ac4e037SJed Brown   PetscFunctionBegin;
103ce94432eSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
1048ac4e037SJed Brown   ierr = VecGetArrayRead(l,&lv);CHKERRQ(ierr);
1058ac4e037SJed Brown   ierr = VecGetArray(g,&gv);CHKERRQ(ierr);
1068ac4e037SJed Brown   switch (imode) {
1078ac4e037SJed Brown   case ADD_VALUES:
1088ac4e037SJed Brown   case MAX_VALUES:
1098ac4e037SJed Brown   {
1108ac4e037SJed Brown     void        *source;
1118ac4e037SJed Brown     PetscScalar *buffer;
1128ac4e037SJed Brown     PetscInt    i;
1138ac4e037SJed Brown     if (rank == red->rank) {
1148ac4e037SJed Brown #if defined(PETSC_HAVE_MPI_IN_PLACE)
1158ac4e037SJed Brown       buffer = gv;
1168ac4e037SJed Brown       source = MPI_IN_PLACE;
1178ac4e037SJed Brown #else
118785e854fSJed Brown       ierr   = PetscMalloc1(red->N,&buffer);CHKERRQ(ierr);
1198ac4e037SJed Brown       source = buffer;
1208ac4e037SJed Brown #endif
1218ac4e037SJed Brown       if (imode == ADD_VALUES) for (i=0; i<red->N; i++) buffer[i] = gv[i] + lv[i];
1228ac4e037SJed Brown #if !defined(PETSC_USE_COMPLEX)
1238ac4e037SJed Brown       if (imode == MAX_VALUES) for (i=0; i<red->N; i++) buffer[i] = PetscMax(gv[i],lv[i]);
1248ac4e037SJed Brown #endif
1258865f1eaSKarl Rupp     } else source = (void*)lv;
1268fa295daSBarry Smith     ierr = MPI_Reduce(source,gv,red->N,MPIU_SCALAR,(imode == ADD_VALUES) ? MPIU_SUM : MPIU_MAX,red->rank,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
1278ac4e037SJed Brown #if !defined(PETSC_HAVE_MPI_IN_PLACE)
12899839c1eSBarry Smith     if (rank == red->rank) {ierr = PetscFree(buffer);CHKERRQ(ierr);}
1298ac4e037SJed Brown #endif
1308ac4e037SJed Brown   } break;
1318ac4e037SJed Brown   case INSERT_VALUES:
132580bdb30SBarry Smith     ierr = PetscArraycpy(gv,lv,red->n);CHKERRQ(ierr);
1338ac4e037SJed Brown     break;
134ce94432eSBarry Smith   default: SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"InsertMode not supported");
1358ac4e037SJed Brown   }
1368ac4e037SJed Brown   ierr = VecRestoreArrayRead(l,&lv);CHKERRQ(ierr);
1378ac4e037SJed Brown   ierr = VecRestoreArray(g,&gv);CHKERRQ(ierr);
1388ac4e037SJed Brown   PetscFunctionReturn(0);
1398ac4e037SJed Brown }
1408ac4e037SJed Brown 
1418ac4e037SJed Brown static PetscErrorCode DMLocalToGlobalEnd_Redundant(DM dm,Vec l,InsertMode imode,Vec g)
1428ac4e037SJed Brown {
1438ac4e037SJed Brown   PetscFunctionBegin;
1448ac4e037SJed Brown   PetscFunctionReturn(0);
1458ac4e037SJed Brown }
1468ac4e037SJed Brown 
1478ac4e037SJed Brown static PetscErrorCode DMGlobalToLocalBegin_Redundant(DM dm,Vec g,InsertMode imode,Vec l)
1488ac4e037SJed Brown {
1498ac4e037SJed Brown   PetscErrorCode    ierr;
1508ac4e037SJed Brown   DM_Redundant      *red = (DM_Redundant*)dm->data;
1518ac4e037SJed Brown   const PetscScalar *gv;
1528ac4e037SJed Brown   PetscScalar       *lv;
1538ac4e037SJed Brown 
1548ac4e037SJed Brown   PetscFunctionBegin;
1558ac4e037SJed Brown   ierr = VecGetArrayRead(g,&gv);CHKERRQ(ierr);
1568ac4e037SJed Brown   ierr = VecGetArray(l,&lv);CHKERRQ(ierr);
1578ac4e037SJed Brown   switch (imode) {
1588ac4e037SJed Brown   case INSERT_VALUES:
159580bdb30SBarry Smith     if (red->n) {ierr = PetscArraycpy(lv,gv,red->n);CHKERRQ(ierr);}
160ce94432eSBarry Smith     ierr = MPI_Bcast(lv,red->N,MPIU_SCALAR,red->rank,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
1618ac4e037SJed Brown     break;
162ce94432eSBarry Smith   default: SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"InsertMode not supported");
1638ac4e037SJed Brown   }
1648ac4e037SJed Brown   ierr = VecRestoreArrayRead(g,&gv);CHKERRQ(ierr);
1658ac4e037SJed Brown   ierr = VecRestoreArray(l,&lv);CHKERRQ(ierr);
1668ac4e037SJed Brown   PetscFunctionReturn(0);
1678ac4e037SJed Brown }
1688ac4e037SJed Brown 
1698ac4e037SJed Brown static PetscErrorCode DMGlobalToLocalEnd_Redundant(DM dm,Vec g,InsertMode imode,Vec l)
1708ac4e037SJed Brown {
1718ac4e037SJed Brown   PetscFunctionBegin;
1728ac4e037SJed Brown   PetscFunctionReturn(0);
1738ac4e037SJed Brown }
1748ac4e037SJed Brown 
1758ac4e037SJed Brown static PetscErrorCode DMSetUp_Redundant(DM dm)
1768ac4e037SJed Brown {
1778ac4e037SJed Brown   PetscFunctionBegin;
1788ac4e037SJed Brown   PetscFunctionReturn(0);
1798ac4e037SJed Brown }
1808ac4e037SJed Brown 
1818ac4e037SJed Brown static PetscErrorCode DMView_Redundant(DM dm,PetscViewer viewer)
1828ac4e037SJed Brown {
1838ac4e037SJed Brown   PetscErrorCode ierr;
1848ac4e037SJed Brown   DM_Redundant   *red = (DM_Redundant*)dm->data;
1858ac4e037SJed Brown   PetscBool      iascii;
1868ac4e037SJed Brown 
1878ac4e037SJed Brown   PetscFunctionBegin;
188251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1898ac4e037SJed Brown   if (iascii) {
1908ac4e037SJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"redundant: rank=%D N=%D\n",red->rank,red->N);CHKERRQ(ierr);
1918ac4e037SJed Brown   }
1928ac4e037SJed Brown   PetscFunctionReturn(0);
1938ac4e037SJed Brown }
1948ac4e037SJed Brown 
195b412c318SBarry Smith static PetscErrorCode DMCreateColoring_Redundant(DM dm,ISColoringType ctype,ISColoring *coloring)
19669527181SJed Brown {
19769527181SJed Brown   DM_Redundant    *red = (DM_Redundant*)dm->data;
19869527181SJed Brown   PetscErrorCode  ierr;
19969527181SJed Brown   PetscInt        i,nloc;
20069527181SJed Brown   ISColoringValue *colors;
20169527181SJed Brown 
20269527181SJed Brown   PetscFunctionBegin;
20369527181SJed Brown   switch (ctype) {
20469527181SJed Brown   case IS_COLORING_GLOBAL:
20569527181SJed Brown     nloc = red->n;
20669527181SJed Brown     break;
2075bdb020cSBarry Smith   case IS_COLORING_LOCAL:
20869527181SJed Brown     nloc = red->N;
20969527181SJed Brown     break;
210ce94432eSBarry Smith   default: SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONG,"Unknown ISColoringType %d",(int)ctype);
21169527181SJed Brown   }
212785e854fSJed Brown   ierr = PetscMalloc1(nloc,&colors);CHKERRQ(ierr);
21369527181SJed Brown   for (i=0; i<nloc; i++) colors[i] = i;
214aaf3ff59SMatthew G. Knepley   ierr = ISColoringCreate(PetscObjectComm((PetscObject)dm),red->N,nloc,colors,PETSC_OWN_POINTER,coloring);CHKERRQ(ierr);
21569527181SJed Brown   ierr = ISColoringSetType(*coloring,ctype);CHKERRQ(ierr);
21669527181SJed Brown   PetscFunctionReturn(0);
21769527181SJed Brown }
2188ac4e037SJed Brown 
2198ac4e037SJed Brown static PetscErrorCode DMRefine_Redundant(DM dmc,MPI_Comm comm,DM *dmf)
2208ac4e037SJed Brown {
2218ac4e037SJed Brown   PetscErrorCode ierr;
2228ac4e037SJed Brown   PetscMPIInt    flag;
2238ac4e037SJed Brown   DM_Redundant   *redc = (DM_Redundant*)dmc->data;
2248ac4e037SJed Brown 
2258ac4e037SJed Brown   PetscFunctionBegin;
226ce94432eSBarry Smith   if (comm == MPI_COMM_NULL) {
227ce94432eSBarry Smith     ierr = PetscObjectGetComm((PetscObject)dmc,&comm);CHKERRQ(ierr);
228ce94432eSBarry Smith   }
229ce94432eSBarry Smith   ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)dmc),comm,&flag);CHKERRQ(ierr);
230ce94432eSBarry Smith   if (flag != MPI_CONGRUENT && flag != MPI_IDENT) SETERRQ(PetscObjectComm((PetscObject)dmc),PETSC_ERR_SUP,"cannot change communicators");
2318ac4e037SJed Brown   ierr = DMRedundantCreate(comm,redc->rank,redc->N,dmf);CHKERRQ(ierr);
2328ac4e037SJed Brown   PetscFunctionReturn(0);
2338ac4e037SJed Brown }
2348ac4e037SJed Brown 
2358ac4e037SJed Brown static PetscErrorCode DMCoarsen_Redundant(DM dmf,MPI_Comm comm,DM *dmc)
2368ac4e037SJed Brown {
2378ac4e037SJed Brown   PetscErrorCode ierr;
2388ac4e037SJed Brown   PetscMPIInt    flag;
2398ac4e037SJed Brown   DM_Redundant   *redf = (DM_Redundant*)dmf->data;
2408ac4e037SJed Brown 
2418ac4e037SJed Brown   PetscFunctionBegin;
242ce94432eSBarry Smith   if (comm == MPI_COMM_NULL) {
243ce94432eSBarry Smith     ierr = PetscObjectGetComm((PetscObject)dmf,&comm);CHKERRQ(ierr);
244ce94432eSBarry Smith   }
245ce94432eSBarry Smith   ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)dmf),comm,&flag);CHKERRQ(ierr);
246ce94432eSBarry Smith   if (flag != MPI_CONGRUENT && flag != MPI_IDENT) SETERRQ(PetscObjectComm((PetscObject)dmf),PETSC_ERR_SUP,"cannot change communicators");
2478ac4e037SJed Brown   ierr = DMRedundantCreate(comm,redf->rank,redf->N,dmc);CHKERRQ(ierr);
2488ac4e037SJed Brown   PetscFunctionReturn(0);
2498ac4e037SJed Brown }
2508ac4e037SJed Brown 
251e727c939SJed Brown static PetscErrorCode DMCreateInterpolation_Redundant(DM dmc,DM dmf,Mat *P,Vec *scale)
2528ac4e037SJed Brown {
2538ac4e037SJed Brown   PetscErrorCode ierr;
2548ac4e037SJed Brown   DM_Redundant   *redc = (DM_Redundant*)dmc->data;
2558ac4e037SJed Brown   DM_Redundant   *redf = (DM_Redundant*)dmf->data;
2568ac4e037SJed Brown   PetscMPIInt    flag;
2578ac4e037SJed Brown   PetscInt       i,rstart,rend;
2588ac4e037SJed Brown 
2598ac4e037SJed Brown   PetscFunctionBegin;
260ce94432eSBarry Smith   ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)dmc),PetscObjectComm((PetscObject)dmf),&flag);CHKERRQ(ierr);
261ce94432eSBarry Smith   if (flag != MPI_CONGRUENT && flag != MPI_IDENT) SETERRQ(PetscObjectComm((PetscObject)dmf),PETSC_ERR_SUP,"cannot change communicators");
262ce94432eSBarry Smith   if (redc->rank != redf->rank) SETERRQ(PetscObjectComm((PetscObject)dmf),PETSC_ERR_ARG_INCOMP,"Owning rank does not match");
263ce94432eSBarry Smith   if (redc->N != redf->N) SETERRQ(PetscObjectComm((PetscObject)dmf),PETSC_ERR_ARG_INCOMP,"Global size does not match");
264ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)dmc),P);CHKERRQ(ierr);
2658ac4e037SJed Brown   ierr = MatSetSizes(*P,redc->n,redc->n,redc->N,redc->N);CHKERRQ(ierr);
2668ac4e037SJed Brown   ierr = MatSetType(*P,MATAIJ);CHKERRQ(ierr);
267*ea78f98cSLisandro Dalcin   ierr = MatSeqAIJSetPreallocation(*P,1,NULL);CHKERRQ(ierr);
268*ea78f98cSLisandro Dalcin   ierr = MatMPIAIJSetPreallocation(*P,1,NULL,0,NULL);CHKERRQ(ierr);
2698ac4e037SJed Brown   ierr = MatGetOwnershipRange(*P,&rstart,&rend);CHKERRQ(ierr);
2708ac4e037SJed Brown   for (i=rstart; i<rend; i++) {ierr = MatSetValue(*P,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr);}
2718ac4e037SJed Brown   ierr = MatAssemblyBegin(*P,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2728ac4e037SJed Brown   ierr = MatAssemblyEnd(*P,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
273e727c939SJed Brown   if (scale) {ierr = DMCreateInterpolationScale(dmc,dmf,*P,scale);CHKERRQ(ierr);}
2748ac4e037SJed Brown   PetscFunctionReturn(0);
2758ac4e037SJed Brown }
2768ac4e037SJed Brown 
2778ac4e037SJed Brown /*@
2788ac4e037SJed Brown     DMRedundantSetSize - Sets the size of a densely coupled redundant object
2798ac4e037SJed Brown 
280d083f849SBarry Smith     Collective on dm
2818ac4e037SJed Brown 
2828ac4e037SJed Brown     Input Parameter:
2838ac4e037SJed Brown +   dm - redundant DM
2848ac4e037SJed Brown .   rank - rank of process to own redundant degrees of freedom
2858ac4e037SJed Brown -   N - total number of redundant degrees of freedom
2868ac4e037SJed Brown 
2878ac4e037SJed Brown     Level: advanced
2888ac4e037SJed Brown 
2898ac4e037SJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMRedundantCreate(), DMRedundantGetSize()
2908ac4e037SJed Brown @*/
291907376e6SBarry Smith PetscErrorCode DMRedundantSetSize(DM dm,PetscMPIInt rank,PetscInt N)
2928ac4e037SJed Brown {
2938ac4e037SJed Brown   PetscErrorCode ierr;
2948ac4e037SJed Brown 
2958ac4e037SJed Brown   PetscFunctionBegin;
2968ac4e037SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2978ac4e037SJed Brown   PetscValidType(dm,1);
29869fbec6eSBarry Smith   PetscValidLogicalCollectiveMPIInt(dm,rank,2);
2998ac4e037SJed Brown   PetscValidLogicalCollectiveInt(dm,N,3);
30083515869SBarry Smith   ierr = PetscTryMethod(dm,"DMRedundantSetSize_C",(DM,PetscMPIInt,PetscInt),(dm,rank,N));CHKERRQ(ierr);
3018ac4e037SJed Brown   PetscFunctionReturn(0);
3028ac4e037SJed Brown }
3038ac4e037SJed Brown 
3048ac4e037SJed Brown /*@
3058ac4e037SJed Brown     DMRedundantGetSize - Gets the size of a densely coupled redundant object
3068ac4e037SJed Brown 
3078ac4e037SJed Brown     Not Collective
3088ac4e037SJed Brown 
3098ac4e037SJed Brown     Input Parameter:
310a2b725a8SWilliam Gropp .   dm - redundant DM
3118ac4e037SJed Brown 
3128ac4e037SJed Brown     Output Parameters:
3130298fd71SBarry Smith +   rank - rank of process to own redundant degrees of freedom (or NULL)
3140298fd71SBarry Smith -   N - total number of redundant degrees of freedom (or NULL)
3158ac4e037SJed Brown 
3168ac4e037SJed Brown     Level: advanced
3178ac4e037SJed Brown 
3188ac4e037SJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMRedundantCreate(), DMRedundantSetSize()
3198ac4e037SJed Brown @*/
320907376e6SBarry Smith PetscErrorCode DMRedundantGetSize(DM dm,PetscMPIInt *rank,PetscInt *N)
3218ac4e037SJed Brown {
3228ac4e037SJed Brown   PetscErrorCode ierr;
3238ac4e037SJed Brown 
3248ac4e037SJed Brown   PetscFunctionBegin;
3258ac4e037SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3268ac4e037SJed Brown   PetscValidType(dm,1);
32783515869SBarry Smith   ierr = PetscUseMethod(dm,"DMRedundantGetSize_C",(DM,PetscMPIInt*,PetscInt*),(dm,rank,N));CHKERRQ(ierr);
3288ac4e037SJed Brown   PetscFunctionReturn(0);
3298ac4e037SJed Brown }
3308ac4e037SJed Brown 
331907376e6SBarry Smith static PetscErrorCode DMRedundantSetSize_Redundant(DM dm,PetscMPIInt rank,PetscInt N)
3328ac4e037SJed Brown {
3338ac4e037SJed Brown   DM_Redundant   *red = (DM_Redundant*)dm->data;
3348ac4e037SJed Brown   PetscErrorCode ierr;
3358ac4e037SJed Brown   PetscMPIInt    myrank;
33673c9e547SStefano Zampini   PetscInt       i,*globals;
3378ac4e037SJed Brown 
3388ac4e037SJed Brown   PetscFunctionBegin;
339ce94432eSBarry Smith   ierr      = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&myrank);CHKERRQ(ierr);
3408ac4e037SJed Brown   red->rank = rank;
3418ac4e037SJed Brown   red->N    = N;
3428ac4e037SJed Brown   red->n    = (myrank == rank) ? N : 0;
34373c9e547SStefano Zampini 
34473c9e547SStefano Zampini   /* mapping is setup here */
34573c9e547SStefano Zampini   ierr = PetscMalloc1(red->N,&globals);CHKERRQ(ierr);
34673c9e547SStefano Zampini   for (i=0; i<red->N; i++) globals[i] = i;
34773c9e547SStefano Zampini   ierr = ISLocalToGlobalMappingDestroy(&dm->ltogmap);CHKERRQ(ierr);
34873c9e547SStefano Zampini   ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)dm),1,red->N,globals,PETSC_OWN_POINTER,&dm->ltogmap);CHKERRQ(ierr);
3498ac4e037SJed Brown   PetscFunctionReturn(0);
3508ac4e037SJed Brown }
3518ac4e037SJed Brown 
3521e6b0712SBarry Smith static PetscErrorCode DMRedundantGetSize_Redundant(DM dm,PetscInt *rank,PetscInt *N)
3538ac4e037SJed Brown {
3548ac4e037SJed Brown   DM_Redundant *red = (DM_Redundant*)dm->data;
3558ac4e037SJed Brown 
3568ac4e037SJed Brown   PetscFunctionBegin;
3578ac4e037SJed Brown   if (rank) *rank = red->rank;
3588ac4e037SJed Brown   if (N)    *N = red->N;
3598ac4e037SJed Brown   PetscFunctionReturn(0);
3608ac4e037SJed Brown }
3618ac4e037SJed Brown 
36236623e74SStefano Zampini static PetscErrorCode DMSetUpGLVisViewer_Redundant(PetscObject odm, PetscViewer viewer)
36336623e74SStefano Zampini {
36436623e74SStefano Zampini   PetscFunctionBegin;
36536623e74SStefano Zampini   PetscFunctionReturn(0);
36636623e74SStefano Zampini }
36736623e74SStefano Zampini 
3683efe6655SBarry Smith /*MC
3693efe6655SBarry Smith    DMREDUNDANT = "redundant" - A DM object that is used to manage data for a small set of dense globally coupled variables.
3703efe6655SBarry Smith          In the global representation of the vector the variables are all stored on a single MPI process (all the other MPI processes have
3713efe6655SBarry Smith          no variables) in the local representation all the variables are stored on ALL the MPI processes (because they are all needed for each
3723efe6655SBarry Smith          processes local computations).
3733efe6655SBarry Smith 
3743efe6655SBarry Smith          This DM is generally used inside a DMCOMPOSITE object. For example, it may be used to store continuation parameters for a bifurcation problem.
3753efe6655SBarry Smith 
3763efe6655SBarry Smith 
3773efe6655SBarry Smith   Level: intermediate
3783efe6655SBarry Smith 
3791abcec8cSBarry Smith .seealso: DMType, DMCOMPOSITE,  DMCreate(), DMRedundantSetSize(), DMRedundantGetSize()
3803efe6655SBarry Smith M*/
3813efe6655SBarry Smith 
3828cc058d9SJed Brown PETSC_EXTERN PetscErrorCode DMCreate_Redundant(DM dm)
3838ac4e037SJed Brown {
3848ac4e037SJed Brown   PetscErrorCode ierr;
3858ac4e037SJed Brown   DM_Redundant   *red;
3868ac4e037SJed Brown 
3878ac4e037SJed Brown   PetscFunctionBegin;
388b00a9115SJed Brown   ierr     = PetscNewLog(dm,&red);CHKERRQ(ierr);
3898ac4e037SJed Brown   dm->data = red;
3908ac4e037SJed Brown 
3918ac4e037SJed Brown   dm->ops->setup               = DMSetUp_Redundant;
3928ac4e037SJed Brown   dm->ops->view                = DMView_Redundant;
3938ac4e037SJed Brown   dm->ops->createglobalvector  = DMCreateGlobalVector_Redundant;
3948ac4e037SJed Brown   dm->ops->createlocalvector   = DMCreateLocalVector_Redundant;
39525296bd5SBarry Smith   dm->ops->creatematrix        = DMCreateMatrix_Redundant;
3968ac4e037SJed Brown   dm->ops->destroy             = DMDestroy_Redundant;
3978ac4e037SJed Brown   dm->ops->globaltolocalbegin  = DMGlobalToLocalBegin_Redundant;
3988ac4e037SJed Brown   dm->ops->globaltolocalend    = DMGlobalToLocalEnd_Redundant;
3998ac4e037SJed Brown   dm->ops->localtoglobalbegin  = DMLocalToGlobalBegin_Redundant;
4008ac4e037SJed Brown   dm->ops->localtoglobalend    = DMLocalToGlobalEnd_Redundant;
4018ac4e037SJed Brown   dm->ops->refine              = DMRefine_Redundant;
4028ac4e037SJed Brown   dm->ops->coarsen             = DMCoarsen_Redundant;
40325296bd5SBarry Smith   dm->ops->createinterpolation = DMCreateInterpolation_Redundant;
404e727c939SJed Brown   dm->ops->getcoloring         = DMCreateColoring_Redundant;
4058865f1eaSKarl Rupp 
406bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)dm,"DMRedundantSetSize_C",DMRedundantSetSize_Redundant);CHKERRQ(ierr);
407bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)dm,"DMRedundantGetSize_C",DMRedundantGetSize_Redundant);CHKERRQ(ierr);
40836623e74SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)dm,"DMSetUpGLVisViewer_C",DMSetUpGLVisViewer_Redundant);CHKERRQ(ierr);
4098ac4e037SJed Brown   PetscFunctionReturn(0);
4108ac4e037SJed Brown }
4118ac4e037SJed Brown 
4128ac4e037SJed Brown /*@C
4138ac4e037SJed Brown     DMRedundantCreate - Creates a DM object, used to manage data for dense globally coupled variables
4148ac4e037SJed Brown 
415d083f849SBarry Smith     Collective
4168ac4e037SJed Brown 
4178ac4e037SJed Brown     Input Parameter:
4188ac4e037SJed Brown +   comm - the processors that will share the global vector
4198ac4e037SJed Brown .   rank - rank to own the redundant values
4208ac4e037SJed Brown -   N - total number of degrees of freedom
4218ac4e037SJed Brown 
4228ac4e037SJed Brown     Output Parameters:
423907376e6SBarry Smith .   dm - the redundant DM
4248ac4e037SJed Brown 
4258ac4e037SJed Brown     Level: advanced
4268ac4e037SJed Brown 
4273efe6655SBarry Smith .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateMatrix(), DMCompositeAddDM(), DMREDUNDANT, DMSetType(), DMRedundantSetSize(), DMRedundantGetSize()
4288ac4e037SJed Brown 
4298ac4e037SJed Brown @*/
430907376e6SBarry Smith PetscErrorCode DMRedundantCreate(MPI_Comm comm,PetscMPIInt rank,PetscInt N,DM *dm)
4318ac4e037SJed Brown {
4328ac4e037SJed Brown   PetscErrorCode ierr;
4338ac4e037SJed Brown 
4348ac4e037SJed Brown   PetscFunctionBegin;
4358ac4e037SJed Brown   PetscValidPointer(dm,2);
4368ac4e037SJed Brown   ierr = DMCreate(comm,dm);CHKERRQ(ierr);
4378ac4e037SJed Brown   ierr = DMSetType(*dm,DMREDUNDANT);CHKERRQ(ierr);
4388ac4e037SJed Brown   ierr = DMRedundantSetSize(*dm,rank,N);CHKERRQ(ierr);
4398ac4e037SJed Brown   ierr = DMSetUp(*dm);CHKERRQ(ierr);
4408ac4e037SJed Brown   PetscFunctionReturn(0);
4418ac4e037SJed Brown }
442