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,<og);CHKERRQ(ierr); 288ac4e037SJed Brown ierr = MatSetLocalToGlobalMapping(*J,ltog,ltog);CHKERRQ(ierr); 29d2e2b695SJed Brown 30dcca6d9dSJed Brown ierr = PetscMalloc2(red->N,&cols,red->N,&vals);CHKERRQ(ierr); 31d2e2b695SJed Brown for (i=0; i<red->N; i++) { 32d2e2b695SJed Brown cols[i] = i; 33d2e2b695SJed Brown vals[i] = 0.0; 34d2e2b695SJed Brown } 35d2e2b695SJed Brown ierr = MatGetOwnershipRange(*J,&rstart,&rend);CHKERRQ(ierr); 36d2e2b695SJed Brown for (i=rstart; i<rend; i++) { 37d2e2b695SJed Brown ierr = MatSetValues(*J,1,&i,red->N,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 38d2e2b695SJed Brown } 39d2e2b695SJed Brown ierr = PetscFree2(cols,vals);CHKERRQ(ierr); 40d2e2b695SJed Brown ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 41d2e2b695SJed Brown ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 428ac4e037SJed Brown PetscFunctionReturn(0); 438ac4e037SJed Brown } 448ac4e037SJed Brown 458ac4e037SJed Brown static PetscErrorCode DMDestroy_Redundant(DM dm) 468ac4e037SJed Brown { 478ac4e037SJed Brown PetscErrorCode ierr; 488ac4e037SJed Brown 498ac4e037SJed Brown PetscFunctionBegin; 50bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)dm,"DMRedundantSetSize_C",NULL);CHKERRQ(ierr); 51bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)dm,"DMRedundantGetSize_C",NULL);CHKERRQ(ierr); 5236623e74SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)dm,"DMSetUpGLVisViewer_C",NULL);CHKERRQ(ierr); 53435a35e8SMatthew G Knepley /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */ 54435a35e8SMatthew G Knepley ierr = PetscFree(dm->data);CHKERRQ(ierr); 558ac4e037SJed Brown PetscFunctionReturn(0); 568ac4e037SJed Brown } 578ac4e037SJed Brown 588ac4e037SJed Brown static PetscErrorCode DMCreateGlobalVector_Redundant(DM dm,Vec *gvec) 598ac4e037SJed Brown { 608ac4e037SJed Brown PetscErrorCode ierr; 618ac4e037SJed Brown DM_Redundant *red = (DM_Redundant*)dm->data; 6245b6f7e9SBarry Smith ISLocalToGlobalMapping ltog; 638ac4e037SJed Brown 648ac4e037SJed Brown PetscFunctionBegin; 658ac4e037SJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 668ac4e037SJed Brown PetscValidPointer(gvec,2); 678ac4e037SJed Brown *gvec = 0; 68ce94432eSBarry Smith ierr = VecCreate(PetscObjectComm((PetscObject)dm),gvec);CHKERRQ(ierr); 698ac4e037SJed Brown ierr = VecSetSizes(*gvec,red->n,red->N);CHKERRQ(ierr); 708ac4e037SJed Brown ierr = VecSetType(*gvec,dm->vectype);CHKERRQ(ierr); 718ac4e037SJed Brown ierr = DMGetLocalToGlobalMapping(dm,<og);CHKERRQ(ierr); 728ac4e037SJed Brown ierr = VecSetLocalToGlobalMapping(*gvec,ltog);CHKERRQ(ierr); 73c688c046SMatthew G Knepley ierr = VecSetDM(*gvec,dm);CHKERRQ(ierr); 748ac4e037SJed Brown PetscFunctionReturn(0); 758ac4e037SJed Brown } 768ac4e037SJed Brown 778ac4e037SJed Brown static PetscErrorCode DMCreateLocalVector_Redundant(DM dm,Vec *lvec) 788ac4e037SJed Brown { 798ac4e037SJed Brown PetscErrorCode ierr; 808ac4e037SJed Brown DM_Redundant *red = (DM_Redundant*)dm->data; 818ac4e037SJed Brown 828ac4e037SJed Brown PetscFunctionBegin; 838ac4e037SJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 848ac4e037SJed Brown PetscValidPointer(lvec,2); 858ac4e037SJed Brown *lvec = 0; 868ac4e037SJed Brown ierr = VecCreate(PETSC_COMM_SELF,lvec);CHKERRQ(ierr); 878ac4e037SJed Brown ierr = VecSetSizes(*lvec,red->N,red->N);CHKERRQ(ierr); 888ac4e037SJed Brown ierr = VecSetType(*lvec,dm->vectype);CHKERRQ(ierr); 89c688c046SMatthew G Knepley ierr = VecSetDM(*lvec,dm);CHKERRQ(ierr); 908ac4e037SJed Brown PetscFunctionReturn(0); 918ac4e037SJed Brown } 928ac4e037SJed Brown 938ac4e037SJed Brown static PetscErrorCode DMLocalToGlobalBegin_Redundant(DM dm,Vec l,InsertMode imode,Vec g) 948ac4e037SJed Brown { 958ac4e037SJed Brown PetscErrorCode ierr; 968ac4e037SJed Brown DM_Redundant *red = (DM_Redundant*)dm->data; 978ac4e037SJed Brown const PetscScalar *lv; 988ac4e037SJed Brown PetscScalar *gv; 998ac4e037SJed Brown PetscMPIInt rank; 1008ac4e037SJed Brown 1018ac4e037SJed Brown PetscFunctionBegin; 102ce94432eSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr); 1038ac4e037SJed Brown ierr = VecGetArrayRead(l,&lv);CHKERRQ(ierr); 1048ac4e037SJed Brown ierr = VecGetArray(g,&gv);CHKERRQ(ierr); 1058ac4e037SJed Brown switch (imode) { 1068ac4e037SJed Brown case ADD_VALUES: 1078ac4e037SJed Brown case MAX_VALUES: 1088ac4e037SJed Brown { 1098ac4e037SJed Brown void *source; 1108ac4e037SJed Brown PetscScalar *buffer; 1118ac4e037SJed Brown PetscInt i; 1128ac4e037SJed Brown if (rank == red->rank) { 1138ac4e037SJed Brown #if defined(PETSC_HAVE_MPI_IN_PLACE) 1148ac4e037SJed Brown buffer = gv; 1158ac4e037SJed Brown source = MPI_IN_PLACE; 1168ac4e037SJed Brown #else 117785e854fSJed Brown ierr = PetscMalloc1(red->N,&buffer);CHKERRQ(ierr); 1188ac4e037SJed Brown source = buffer; 1198ac4e037SJed Brown #endif 1208ac4e037SJed Brown if (imode == ADD_VALUES) for (i=0; i<red->N; i++) buffer[i] = gv[i] + lv[i]; 1218ac4e037SJed Brown #if !defined(PETSC_USE_COMPLEX) 1228ac4e037SJed Brown if (imode == MAX_VALUES) for (i=0; i<red->N; i++) buffer[i] = PetscMax(gv[i],lv[i]); 1238ac4e037SJed Brown #endif 1248865f1eaSKarl Rupp } else source = (void*)lv; 1258fa295daSBarry Smith ierr = MPI_Reduce(source,gv,red->N,MPIU_SCALAR,(imode == ADD_VALUES) ? MPIU_SUM : MPIU_MAX,red->rank,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 1268ac4e037SJed Brown #if !defined(PETSC_HAVE_MPI_IN_PLACE) 12799839c1eSBarry Smith if (rank == red->rank) {ierr = PetscFree(buffer);CHKERRQ(ierr);} 1288ac4e037SJed Brown #endif 1298ac4e037SJed Brown } break; 1308ac4e037SJed Brown case INSERT_VALUES: 1318ac4e037SJed Brown ierr = PetscMemcpy(gv,lv,red->n*sizeof(PetscScalar));CHKERRQ(ierr); 1328ac4e037SJed Brown break; 133ce94432eSBarry Smith default: SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"InsertMode not supported"); 1348ac4e037SJed Brown } 1358ac4e037SJed Brown ierr = VecRestoreArrayRead(l,&lv);CHKERRQ(ierr); 1368ac4e037SJed Brown ierr = VecRestoreArray(g,&gv);CHKERRQ(ierr); 1378ac4e037SJed Brown PetscFunctionReturn(0); 1388ac4e037SJed Brown } 1398ac4e037SJed Brown 1408ac4e037SJed Brown static PetscErrorCode DMLocalToGlobalEnd_Redundant(DM dm,Vec l,InsertMode imode,Vec g) 1418ac4e037SJed Brown { 1428ac4e037SJed Brown PetscFunctionBegin; 1438ac4e037SJed Brown PetscFunctionReturn(0); 1448ac4e037SJed Brown } 1458ac4e037SJed Brown 1468ac4e037SJed Brown static PetscErrorCode DMGlobalToLocalBegin_Redundant(DM dm,Vec g,InsertMode imode,Vec l) 1478ac4e037SJed Brown { 1488ac4e037SJed Brown PetscErrorCode ierr; 1498ac4e037SJed Brown DM_Redundant *red = (DM_Redundant*)dm->data; 1508ac4e037SJed Brown const PetscScalar *gv; 1518ac4e037SJed Brown PetscScalar *lv; 1528ac4e037SJed Brown 1538ac4e037SJed Brown PetscFunctionBegin; 1548ac4e037SJed Brown ierr = VecGetArrayRead(g,&gv);CHKERRQ(ierr); 1558ac4e037SJed Brown ierr = VecGetArray(l,&lv);CHKERRQ(ierr); 1568ac4e037SJed Brown switch (imode) { 1578ac4e037SJed Brown case INSERT_VALUES: 1588ac4e037SJed Brown if (red->n) {ierr = PetscMemcpy(lv,gv,red->n*sizeof(PetscScalar));CHKERRQ(ierr);} 159ce94432eSBarry Smith ierr = MPI_Bcast(lv,red->N,MPIU_SCALAR,red->rank,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 1608ac4e037SJed Brown break; 161ce94432eSBarry Smith default: SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"InsertMode not supported"); 1628ac4e037SJed Brown } 1638ac4e037SJed Brown ierr = VecRestoreArrayRead(g,&gv);CHKERRQ(ierr); 1648ac4e037SJed Brown ierr = VecRestoreArray(l,&lv);CHKERRQ(ierr); 1658ac4e037SJed Brown PetscFunctionReturn(0); 1668ac4e037SJed Brown } 1678ac4e037SJed Brown 1688ac4e037SJed Brown static PetscErrorCode DMGlobalToLocalEnd_Redundant(DM dm,Vec g,InsertMode imode,Vec l) 1698ac4e037SJed Brown { 1708ac4e037SJed Brown PetscFunctionBegin; 1718ac4e037SJed Brown PetscFunctionReturn(0); 1728ac4e037SJed Brown } 1738ac4e037SJed Brown 1748ac4e037SJed Brown static PetscErrorCode DMSetUp_Redundant(DM dm) 1758ac4e037SJed Brown { 1768ac4e037SJed Brown PetscErrorCode ierr; 1778ac4e037SJed Brown DM_Redundant *red = (DM_Redundant*)dm->data; 1788ac4e037SJed Brown PetscInt i,*globals; 1798ac4e037SJed Brown 1808ac4e037SJed Brown PetscFunctionBegin; 181785e854fSJed Brown ierr = PetscMalloc1(red->N,&globals);CHKERRQ(ierr); 1828ac4e037SJed Brown for (i=0; i<red->N; i++) globals[i] = i; 183f0413b6fSBarry Smith ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,red->N,globals,PETSC_OWN_POINTER,&dm->ltogmap);CHKERRQ(ierr); 1848ac4e037SJed Brown PetscFunctionReturn(0); 1858ac4e037SJed Brown } 1868ac4e037SJed Brown 1878ac4e037SJed Brown static PetscErrorCode DMView_Redundant(DM dm,PetscViewer viewer) 1888ac4e037SJed Brown { 1898ac4e037SJed Brown PetscErrorCode ierr; 1908ac4e037SJed Brown DM_Redundant *red = (DM_Redundant*)dm->data; 1918ac4e037SJed Brown PetscBool iascii; 1928ac4e037SJed Brown 1938ac4e037SJed Brown PetscFunctionBegin; 194251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1958ac4e037SJed Brown if (iascii) { 1968ac4e037SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"redundant: rank=%D N=%D\n",red->rank,red->N);CHKERRQ(ierr); 1978ac4e037SJed Brown } 1988ac4e037SJed Brown PetscFunctionReturn(0); 1998ac4e037SJed Brown } 2008ac4e037SJed Brown 201b412c318SBarry Smith static PetscErrorCode DMCreateColoring_Redundant(DM dm,ISColoringType ctype,ISColoring *coloring) 20269527181SJed Brown { 20369527181SJed Brown DM_Redundant *red = (DM_Redundant*)dm->data; 20469527181SJed Brown PetscErrorCode ierr; 20569527181SJed Brown PetscInt i,nloc; 20669527181SJed Brown ISColoringValue *colors; 20769527181SJed Brown 20869527181SJed Brown PetscFunctionBegin; 20969527181SJed Brown switch (ctype) { 21069527181SJed Brown case IS_COLORING_GLOBAL: 21169527181SJed Brown nloc = red->n; 21269527181SJed Brown break; 2135bdb020cSBarry Smith case IS_COLORING_LOCAL: 21469527181SJed Brown nloc = red->N; 21569527181SJed Brown break; 216ce94432eSBarry Smith default: SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONG,"Unknown ISColoringType %d",(int)ctype); 21769527181SJed Brown } 218785e854fSJed Brown ierr = PetscMalloc1(nloc,&colors);CHKERRQ(ierr); 21969527181SJed Brown for (i=0; i<nloc; i++) colors[i] = i; 220aaf3ff59SMatthew G. Knepley ierr = ISColoringCreate(PetscObjectComm((PetscObject)dm),red->N,nloc,colors,PETSC_OWN_POINTER,coloring);CHKERRQ(ierr); 22169527181SJed Brown ierr = ISColoringSetType(*coloring,ctype);CHKERRQ(ierr); 22269527181SJed Brown PetscFunctionReturn(0); 22369527181SJed Brown } 2248ac4e037SJed Brown 2258ac4e037SJed Brown static PetscErrorCode DMRefine_Redundant(DM dmc,MPI_Comm comm,DM *dmf) 2268ac4e037SJed Brown { 2278ac4e037SJed Brown PetscErrorCode ierr; 2288ac4e037SJed Brown PetscMPIInt flag; 2298ac4e037SJed Brown DM_Redundant *redc = (DM_Redundant*)dmc->data; 2308ac4e037SJed Brown 2318ac4e037SJed Brown PetscFunctionBegin; 232ce94432eSBarry Smith if (comm == MPI_COMM_NULL) { 233ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)dmc,&comm);CHKERRQ(ierr); 234ce94432eSBarry Smith } 235ce94432eSBarry Smith ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)dmc),comm,&flag);CHKERRQ(ierr); 236ce94432eSBarry Smith if (flag != MPI_CONGRUENT && flag != MPI_IDENT) SETERRQ(PetscObjectComm((PetscObject)dmc),PETSC_ERR_SUP,"cannot change communicators"); 2378ac4e037SJed Brown ierr = DMRedundantCreate(comm,redc->rank,redc->N,dmf);CHKERRQ(ierr); 2388ac4e037SJed Brown PetscFunctionReturn(0); 2398ac4e037SJed Brown } 2408ac4e037SJed Brown 2418ac4e037SJed Brown static PetscErrorCode DMCoarsen_Redundant(DM dmf,MPI_Comm comm,DM *dmc) 2428ac4e037SJed Brown { 2438ac4e037SJed Brown PetscErrorCode ierr; 2448ac4e037SJed Brown PetscMPIInt flag; 2458ac4e037SJed Brown DM_Redundant *redf = (DM_Redundant*)dmf->data; 2468ac4e037SJed Brown 2478ac4e037SJed Brown PetscFunctionBegin; 248ce94432eSBarry Smith if (comm == MPI_COMM_NULL) { 249ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)dmf,&comm);CHKERRQ(ierr); 250ce94432eSBarry Smith } 251ce94432eSBarry Smith ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)dmf),comm,&flag);CHKERRQ(ierr); 252ce94432eSBarry Smith if (flag != MPI_CONGRUENT && flag != MPI_IDENT) SETERRQ(PetscObjectComm((PetscObject)dmf),PETSC_ERR_SUP,"cannot change communicators"); 2538ac4e037SJed Brown ierr = DMRedundantCreate(comm,redf->rank,redf->N,dmc);CHKERRQ(ierr); 2548ac4e037SJed Brown PetscFunctionReturn(0); 2558ac4e037SJed Brown } 2568ac4e037SJed Brown 257e727c939SJed Brown static PetscErrorCode DMCreateInterpolation_Redundant(DM dmc,DM dmf,Mat *P,Vec *scale) 2588ac4e037SJed Brown { 2598ac4e037SJed Brown PetscErrorCode ierr; 2608ac4e037SJed Brown DM_Redundant *redc = (DM_Redundant*)dmc->data; 2618ac4e037SJed Brown DM_Redundant *redf = (DM_Redundant*)dmf->data; 2628ac4e037SJed Brown PetscMPIInt flag; 2638ac4e037SJed Brown PetscInt i,rstart,rend; 2648ac4e037SJed Brown 2658ac4e037SJed Brown PetscFunctionBegin; 266ce94432eSBarry Smith ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)dmc),PetscObjectComm((PetscObject)dmf),&flag);CHKERRQ(ierr); 267ce94432eSBarry Smith if (flag != MPI_CONGRUENT && flag != MPI_IDENT) SETERRQ(PetscObjectComm((PetscObject)dmf),PETSC_ERR_SUP,"cannot change communicators"); 268ce94432eSBarry Smith if (redc->rank != redf->rank) SETERRQ(PetscObjectComm((PetscObject)dmf),PETSC_ERR_ARG_INCOMP,"Owning rank does not match"); 269ce94432eSBarry Smith if (redc->N != redf->N) SETERRQ(PetscObjectComm((PetscObject)dmf),PETSC_ERR_ARG_INCOMP,"Global size does not match"); 270ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)dmc),P);CHKERRQ(ierr); 2718ac4e037SJed Brown ierr = MatSetSizes(*P,redc->n,redc->n,redc->N,redc->N);CHKERRQ(ierr); 2728ac4e037SJed Brown ierr = MatSetType(*P,MATAIJ);CHKERRQ(ierr); 2738ac4e037SJed Brown ierr = MatSeqAIJSetPreallocation(*P,1,0);CHKERRQ(ierr); 2748ac4e037SJed Brown ierr = MatMPIAIJSetPreallocation(*P,1,0,0,0);CHKERRQ(ierr); 2758ac4e037SJed Brown ierr = MatGetOwnershipRange(*P,&rstart,&rend);CHKERRQ(ierr); 2768ac4e037SJed Brown for (i=rstart; i<rend; i++) {ierr = MatSetValue(*P,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr);} 2778ac4e037SJed Brown ierr = MatAssemblyBegin(*P,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2788ac4e037SJed Brown ierr = MatAssemblyEnd(*P,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 279e727c939SJed Brown if (scale) {ierr = DMCreateInterpolationScale(dmc,dmf,*P,scale);CHKERRQ(ierr);} 2808ac4e037SJed Brown PetscFunctionReturn(0); 2818ac4e037SJed Brown } 2828ac4e037SJed Brown 2838ac4e037SJed Brown /*@ 2848ac4e037SJed Brown DMRedundantSetSize - Sets the size of a densely coupled redundant object 2858ac4e037SJed Brown 2868ac4e037SJed Brown Collective on DM 2878ac4e037SJed Brown 2888ac4e037SJed Brown Input Parameter: 2898ac4e037SJed Brown + dm - redundant DM 2908ac4e037SJed Brown . rank - rank of process to own redundant degrees of freedom 2918ac4e037SJed Brown - N - total number of redundant degrees of freedom 2928ac4e037SJed Brown 2938ac4e037SJed Brown Level: advanced 2948ac4e037SJed Brown 2958ac4e037SJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMRedundantCreate(), DMRedundantGetSize() 2968ac4e037SJed Brown @*/ 297907376e6SBarry Smith PetscErrorCode DMRedundantSetSize(DM dm,PetscMPIInt rank,PetscInt N) 2988ac4e037SJed Brown { 2998ac4e037SJed Brown PetscErrorCode ierr; 3008ac4e037SJed Brown 3018ac4e037SJed Brown PetscFunctionBegin; 3028ac4e037SJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3038ac4e037SJed Brown PetscValidType(dm,1); 30469fbec6eSBarry Smith PetscValidLogicalCollectiveMPIInt(dm,rank,2); 3058ac4e037SJed Brown PetscValidLogicalCollectiveInt(dm,N,3); 30683515869SBarry Smith ierr = PetscTryMethod(dm,"DMRedundantSetSize_C",(DM,PetscMPIInt,PetscInt),(dm,rank,N));CHKERRQ(ierr); 3078ac4e037SJed Brown PetscFunctionReturn(0); 3088ac4e037SJed Brown } 3098ac4e037SJed Brown 3108ac4e037SJed Brown /*@ 3118ac4e037SJed Brown DMRedundantGetSize - Gets the size of a densely coupled redundant object 3128ac4e037SJed Brown 3138ac4e037SJed Brown Not Collective 3148ac4e037SJed Brown 3158ac4e037SJed Brown Input Parameter: 316*a2b725a8SWilliam Gropp . dm - redundant DM 3178ac4e037SJed Brown 3188ac4e037SJed Brown Output Parameters: 3190298fd71SBarry Smith + rank - rank of process to own redundant degrees of freedom (or NULL) 3200298fd71SBarry Smith - N - total number of redundant degrees of freedom (or NULL) 3218ac4e037SJed Brown 3228ac4e037SJed Brown Level: advanced 3238ac4e037SJed Brown 3248ac4e037SJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMRedundantCreate(), DMRedundantSetSize() 3258ac4e037SJed Brown @*/ 326907376e6SBarry Smith PetscErrorCode DMRedundantGetSize(DM dm,PetscMPIInt *rank,PetscInt *N) 3278ac4e037SJed Brown { 3288ac4e037SJed Brown PetscErrorCode ierr; 3298ac4e037SJed Brown 3308ac4e037SJed Brown PetscFunctionBegin; 3318ac4e037SJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3328ac4e037SJed Brown PetscValidType(dm,1); 33383515869SBarry Smith ierr = PetscUseMethod(dm,"DMRedundantGetSize_C",(DM,PetscMPIInt*,PetscInt*),(dm,rank,N));CHKERRQ(ierr); 3348ac4e037SJed Brown PetscFunctionReturn(0); 3358ac4e037SJed Brown } 3368ac4e037SJed Brown 337907376e6SBarry Smith static PetscErrorCode DMRedundantSetSize_Redundant(DM dm,PetscMPIInt rank,PetscInt N) 3388ac4e037SJed Brown { 3398ac4e037SJed Brown DM_Redundant *red = (DM_Redundant*)dm->data; 3408ac4e037SJed Brown PetscErrorCode ierr; 3418ac4e037SJed Brown PetscMPIInt myrank; 3428ac4e037SJed Brown 3438ac4e037SJed Brown PetscFunctionBegin; 344ce94432eSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&myrank);CHKERRQ(ierr); 3458ac4e037SJed Brown red->rank = rank; 3468ac4e037SJed Brown red->N = N; 3478ac4e037SJed Brown red->n = (myrank == rank) ? N : 0; 3488ac4e037SJed Brown PetscFunctionReturn(0); 3498ac4e037SJed Brown } 3508ac4e037SJed Brown 3511e6b0712SBarry Smith static PetscErrorCode DMRedundantGetSize_Redundant(DM dm,PetscInt *rank,PetscInt *N) 3528ac4e037SJed Brown { 3538ac4e037SJed Brown DM_Redundant *red = (DM_Redundant*)dm->data; 3548ac4e037SJed Brown 3558ac4e037SJed Brown PetscFunctionBegin; 3568ac4e037SJed Brown if (rank) *rank = red->rank; 3578ac4e037SJed Brown if (N) *N = red->N; 3588ac4e037SJed Brown PetscFunctionReturn(0); 3598ac4e037SJed Brown } 3608ac4e037SJed Brown 36136623e74SStefano Zampini static PetscErrorCode DMSetUpGLVisViewer_Redundant(PetscObject odm, PetscViewer viewer) 36236623e74SStefano Zampini { 36336623e74SStefano Zampini PetscFunctionBegin; 36436623e74SStefano Zampini PetscFunctionReturn(0); 36536623e74SStefano Zampini } 36636623e74SStefano Zampini 3673efe6655SBarry Smith /*MC 3683efe6655SBarry Smith DMREDUNDANT = "redundant" - A DM object that is used to manage data for a small set of dense globally coupled variables. 3693efe6655SBarry Smith In the global representation of the vector the variables are all stored on a single MPI process (all the other MPI processes have 3703efe6655SBarry Smith no variables) in the local representation all the variables are stored on ALL the MPI processes (because they are all needed for each 3713efe6655SBarry Smith processes local computations). 3723efe6655SBarry Smith 3733efe6655SBarry Smith This DM is generally used inside a DMCOMPOSITE object. For example, it may be used to store continuation parameters for a bifurcation problem. 3743efe6655SBarry Smith 3753efe6655SBarry Smith 3763efe6655SBarry Smith Level: intermediate 3773efe6655SBarry Smith 3781abcec8cSBarry Smith .seealso: DMType, DMCOMPOSITE, DMCreate(), DMRedundantSetSize(), DMRedundantGetSize() 3793efe6655SBarry Smith M*/ 3803efe6655SBarry Smith 3818cc058d9SJed Brown PETSC_EXTERN PetscErrorCode DMCreate_Redundant(DM dm) 3828ac4e037SJed Brown { 3838ac4e037SJed Brown PetscErrorCode ierr; 3848ac4e037SJed Brown DM_Redundant *red; 3858ac4e037SJed Brown 3868ac4e037SJed Brown PetscFunctionBegin; 387b00a9115SJed Brown ierr = PetscNewLog(dm,&red);CHKERRQ(ierr); 3888ac4e037SJed Brown dm->data = red; 3898ac4e037SJed Brown 3908ac4e037SJed Brown ierr = PetscObjectChangeTypeName((PetscObject)dm,DMREDUNDANT);CHKERRQ(ierr); 3918865f1eaSKarl Rupp 3928ac4e037SJed Brown dm->ops->setup = DMSetUp_Redundant; 3938ac4e037SJed Brown dm->ops->view = DMView_Redundant; 3948ac4e037SJed Brown dm->ops->createglobalvector = DMCreateGlobalVector_Redundant; 3958ac4e037SJed Brown dm->ops->createlocalvector = DMCreateLocalVector_Redundant; 39625296bd5SBarry Smith dm->ops->creatematrix = DMCreateMatrix_Redundant; 3978ac4e037SJed Brown dm->ops->destroy = DMDestroy_Redundant; 3988ac4e037SJed Brown dm->ops->globaltolocalbegin = DMGlobalToLocalBegin_Redundant; 3998ac4e037SJed Brown dm->ops->globaltolocalend = DMGlobalToLocalEnd_Redundant; 4008ac4e037SJed Brown dm->ops->localtoglobalbegin = DMLocalToGlobalBegin_Redundant; 4018ac4e037SJed Brown dm->ops->localtoglobalend = DMLocalToGlobalEnd_Redundant; 4028ac4e037SJed Brown dm->ops->refine = DMRefine_Redundant; 4038ac4e037SJed Brown dm->ops->coarsen = DMCoarsen_Redundant; 40425296bd5SBarry Smith dm->ops->createinterpolation = DMCreateInterpolation_Redundant; 405e727c939SJed Brown dm->ops->getcoloring = DMCreateColoring_Redundant; 4068865f1eaSKarl Rupp 407bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)dm,"DMRedundantSetSize_C",DMRedundantSetSize_Redundant);CHKERRQ(ierr); 408bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)dm,"DMRedundantGetSize_C",DMRedundantGetSize_Redundant);CHKERRQ(ierr); 40936623e74SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)dm,"DMSetUpGLVisViewer_C",DMSetUpGLVisViewer_Redundant);CHKERRQ(ierr); 4108ac4e037SJed Brown PetscFunctionReturn(0); 4118ac4e037SJed Brown } 4128ac4e037SJed Brown 4138ac4e037SJed Brown /*@C 4148ac4e037SJed Brown DMRedundantCreate - Creates a DM object, used to manage data for dense globally coupled variables 4158ac4e037SJed Brown 4168ac4e037SJed Brown Collective on MPI_Comm 4178ac4e037SJed Brown 4188ac4e037SJed Brown Input Parameter: 4198ac4e037SJed Brown + comm - the processors that will share the global vector 4208ac4e037SJed Brown . rank - rank to own the redundant values 4218ac4e037SJed Brown - N - total number of degrees of freedom 4228ac4e037SJed Brown 4238ac4e037SJed Brown Output Parameters: 424907376e6SBarry Smith . dm - the redundant DM 4258ac4e037SJed Brown 4268ac4e037SJed Brown Level: advanced 4278ac4e037SJed Brown 4283efe6655SBarry Smith .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateMatrix(), DMCompositeAddDM(), DMREDUNDANT, DMSetType(), DMRedundantSetSize(), DMRedundantGetSize() 4298ac4e037SJed Brown 4308ac4e037SJed Brown @*/ 431907376e6SBarry Smith PetscErrorCode DMRedundantCreate(MPI_Comm comm,PetscMPIInt rank,PetscInt N,DM *dm) 4328ac4e037SJed Brown { 4338ac4e037SJed Brown PetscErrorCode ierr; 4348ac4e037SJed Brown 4358ac4e037SJed Brown PetscFunctionBegin; 4368ac4e037SJed Brown PetscValidPointer(dm,2); 4378ac4e037SJed Brown ierr = DMCreate(comm,dm);CHKERRQ(ierr); 4388ac4e037SJed Brown ierr = DMSetType(*dm,DMREDUNDANT);CHKERRQ(ierr); 4398ac4e037SJed Brown ierr = DMRedundantSetSize(*dm,rank,N);CHKERRQ(ierr); 4408ac4e037SJed Brown ierr = DMSetUp(*dm);CHKERRQ(ierr); 4418ac4e037SJed Brown PetscFunctionReturn(0); 4428ac4e037SJed Brown } 443