1*fe1899a2SJed Brown #include <petscdmshell.h> /*I "petscdmshell.h" I*/ 2*fe1899a2SJed Brown #include <petscmat.h> /*I "petscmat.h" I*/ 3*fe1899a2SJed Brown #include <private/dmimpl.h> /*I "petscdm.h" I*/ 4*fe1899a2SJed Brown 5*fe1899a2SJed Brown typedef struct { 6*fe1899a2SJed Brown Vec Xglobal; 7*fe1899a2SJed Brown Mat A; 8*fe1899a2SJed Brown } DM_Shell; 9*fe1899a2SJed Brown 10*fe1899a2SJed Brown #undef __FUNCT__ 11*fe1899a2SJed Brown #define __FUNCT__ "DMCreateMatrix_Shell" 12*fe1899a2SJed Brown static PetscErrorCode DMCreateMatrix_Shell(DM dm,const MatType mtype,Mat *J) 13*fe1899a2SJed Brown { 14*fe1899a2SJed Brown PetscErrorCode ierr; 15*fe1899a2SJed Brown DM_Shell *shell = (DM_Shell*)dm->data; 16*fe1899a2SJed Brown Mat A; 17*fe1899a2SJed Brown 18*fe1899a2SJed Brown PetscFunctionBegin; 19*fe1899a2SJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 20*fe1899a2SJed Brown PetscValidPointer(J,3); 21*fe1899a2SJed Brown A = shell->A; 22*fe1899a2SJed Brown if (!A) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_USER,"Must call DMShellSetMatrix() or DMShellSetCreateMatrix()"); 23*fe1899a2SJed Brown if (mtype) { 24*fe1899a2SJed Brown PetscBool flg; 25*fe1899a2SJed Brown ierr = PetscTypeCompare((PetscObject)A,mtype,&flg);CHKERRQ(ierr); 26*fe1899a2SJed Brown if (!flg) SETERRQ2(((PetscObject)dm)->comm,PETSC_ERR_ARG_NOTSAMETYPE,"Requested matrix of type %s, but only %s available",mtype,((PetscObject)A)->type_name); 27*fe1899a2SJed Brown } 28*fe1899a2SJed Brown if (((PetscObject)A)->refct < 2) { /* We have an exclusive reference so we can give it out */ 29*fe1899a2SJed Brown ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 30*fe1899a2SJed Brown ierr = MatZeroEntries(A);CHKERRQ(ierr); 31*fe1899a2SJed Brown *J = A; 32*fe1899a2SJed Brown } else { /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */ 33*fe1899a2SJed Brown ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,J);CHKERRQ(ierr); 34*fe1899a2SJed Brown ierr = MatZeroEntries(*J);CHKERRQ(ierr); 35*fe1899a2SJed Brown } 36*fe1899a2SJed Brown PetscFunctionReturn(0); 37*fe1899a2SJed Brown } 38*fe1899a2SJed Brown 39*fe1899a2SJed Brown #undef __FUNCT__ 40*fe1899a2SJed Brown #define __FUNCT__ "DMCreateGlobalVector_Shell" 41*fe1899a2SJed Brown PetscErrorCode DMCreateGlobalVector_Shell(DM dm,Vec *gvec) 42*fe1899a2SJed Brown { 43*fe1899a2SJed Brown PetscErrorCode ierr; 44*fe1899a2SJed Brown DM_Shell *shell = (DM_Shell*)dm->data; 45*fe1899a2SJed Brown Vec X; 46*fe1899a2SJed Brown 47*fe1899a2SJed Brown PetscFunctionBegin; 48*fe1899a2SJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 49*fe1899a2SJed Brown PetscValidPointer(gvec,2); 50*fe1899a2SJed Brown *gvec = 0; 51*fe1899a2SJed Brown X = shell->Xglobal; 52*fe1899a2SJed Brown if (((PetscObject)X)->refct < 2) { /* We have an exclusive reference so we can give it out */ 53*fe1899a2SJed Brown ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr); 54*fe1899a2SJed Brown ierr = VecZeroEntries(X);CHKERRQ(ierr); 55*fe1899a2SJed Brown *gvec = X; 56*fe1899a2SJed Brown } else { /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */ 57*fe1899a2SJed Brown ierr = VecDuplicate(X,gvec);CHKERRQ(ierr); 58*fe1899a2SJed Brown ierr = VecZeroEntries(*gvec);CHKERRQ(ierr); 59*fe1899a2SJed Brown } 60*fe1899a2SJed Brown ierr = PetscObjectCompose((PetscObject)*gvec,"DM",(PetscObject)dm);CHKERRQ(ierr); 61*fe1899a2SJed Brown PetscFunctionReturn(0); 62*fe1899a2SJed Brown } 63*fe1899a2SJed Brown 64*fe1899a2SJed Brown #undef __FUNCT__ 65*fe1899a2SJed Brown #define __FUNCT__ "DMShellSetMatrix" 66*fe1899a2SJed Brown /*@ 67*fe1899a2SJed Brown DMShellSetMatrix - sets a template matrix associated with the DMShell 68*fe1899a2SJed Brown 69*fe1899a2SJed Brown Collective 70*fe1899a2SJed Brown 71*fe1899a2SJed Brown Input Arguments: 72*fe1899a2SJed Brown + dm - shell DM 73*fe1899a2SJed Brown - J - template matrix 74*fe1899a2SJed Brown 75*fe1899a2SJed Brown Level: advanced 76*fe1899a2SJed Brown 77*fe1899a2SJed Brown .seealso: DMCreateMatrix(), DMShellSetCreateMatrix() 78*fe1899a2SJed Brown @*/ 79*fe1899a2SJed Brown PetscErrorCode DMShellSetMatrix(DM dm,Mat J) 80*fe1899a2SJed Brown { 81*fe1899a2SJed Brown DM_Shell *shell = (DM_Shell*)dm->data; 82*fe1899a2SJed Brown PetscErrorCode ierr; 83*fe1899a2SJed Brown 84*fe1899a2SJed Brown PetscFunctionBegin; 85*fe1899a2SJed Brown ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr); 86*fe1899a2SJed Brown ierr = MatDestroy(&shell->A);CHKERRQ(ierr); 87*fe1899a2SJed Brown shell->A = J; 88*fe1899a2SJed Brown PetscFunctionReturn(0); 89*fe1899a2SJed Brown } 90*fe1899a2SJed Brown 91*fe1899a2SJed Brown #undef __FUNCT__ 92*fe1899a2SJed Brown #define __FUNCT__ "DMShellSetCreateMatrix" 93*fe1899a2SJed Brown /*@C 94*fe1899a2SJed Brown DMShellSetCreateMatrix - sets the routine to create a matrix associated with the shell DM 95*fe1899a2SJed Brown 96*fe1899a2SJed Brown Logically Collective on DM 97*fe1899a2SJed Brown 98*fe1899a2SJed Brown Input Arguments: 99*fe1899a2SJed Brown + dm - the shell DM 100*fe1899a2SJed Brown - func - the function to create a matrix 101*fe1899a2SJed Brown 102*fe1899a2SJed Brown Level: advanced 103*fe1899a2SJed Brown 104*fe1899a2SJed Brown .seealso: DMCreateMatrix(), DMShellSetMatrix() 105*fe1899a2SJed Brown @*/ 106*fe1899a2SJed Brown PetscErrorCode DMShellSetCreateMatrix(DM dm,PetscErrorCode (*func)(DM,const MatType,Mat*)) 107*fe1899a2SJed Brown { 108*fe1899a2SJed Brown 109*fe1899a2SJed Brown PetscFunctionBegin; 110*fe1899a2SJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 111*fe1899a2SJed Brown dm->ops->creatematrix = func; 112*fe1899a2SJed Brown PetscFunctionReturn(0); 113*fe1899a2SJed Brown } 114*fe1899a2SJed Brown 115*fe1899a2SJed Brown #undef __FUNCT__ 116*fe1899a2SJed Brown #define __FUNCT__ "DMShellSetGlobalVector" 117*fe1899a2SJed Brown /*@ 118*fe1899a2SJed Brown DMShellSetGlobalVector - sets a template global vector associated with the DMShell 119*fe1899a2SJed Brown 120*fe1899a2SJed Brown Logically Collective on DM 121*fe1899a2SJed Brown 122*fe1899a2SJed Brown Input Arguments: 123*fe1899a2SJed Brown + dm - shell DM 124*fe1899a2SJed Brown - X - template vector 125*fe1899a2SJed Brown 126*fe1899a2SJed Brown Level: advanced 127*fe1899a2SJed Brown 128*fe1899a2SJed Brown .seealso: DMCreateGlobalVector(), DMShellSetMatrix(), DMShellSetCreateGlobalVector() 129*fe1899a2SJed Brown @*/ 130*fe1899a2SJed Brown PetscErrorCode DMShellSetGlobalVector(DM dm,Vec X) 131*fe1899a2SJed Brown { 132*fe1899a2SJed Brown DM_Shell *shell = (DM_Shell*)dm->data; 133*fe1899a2SJed Brown PetscErrorCode ierr; 134*fe1899a2SJed Brown 135*fe1899a2SJed Brown PetscFunctionBegin; 136*fe1899a2SJed Brown ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr); 137*fe1899a2SJed Brown ierr = VecDestroy(&shell->Xglobal);CHKERRQ(ierr); 138*fe1899a2SJed Brown shell->Xglobal = X; 139*fe1899a2SJed Brown PetscFunctionReturn(0); 140*fe1899a2SJed Brown } 141*fe1899a2SJed Brown 142*fe1899a2SJed Brown #undef __FUNCT__ 143*fe1899a2SJed Brown #define __FUNCT__ "DMShellSetCreateGlobalVector" 144*fe1899a2SJed Brown /*@C 145*fe1899a2SJed Brown DMShellSetCreateGlobalVector - sets the routine to create a global vector associated with the shell DM 146*fe1899a2SJed Brown 147*fe1899a2SJed Brown Logically Collective 148*fe1899a2SJed Brown 149*fe1899a2SJed Brown Input Arguments: 150*fe1899a2SJed Brown + dm - the shell DM 151*fe1899a2SJed Brown - func - the creation routine 152*fe1899a2SJed Brown 153*fe1899a2SJed Brown Level: advanced 154*fe1899a2SJed Brown 155*fe1899a2SJed Brown .seealso: DMShellSetGlobalVector(), DMShellSetCreateMatrix() 156*fe1899a2SJed Brown @*/ 157*fe1899a2SJed Brown PetscErrorCode DMShellSetCreateGlobalVector(DM dm,PetscErrorCode (*func)(DM,Vec*)) 158*fe1899a2SJed Brown { 159*fe1899a2SJed Brown 160*fe1899a2SJed Brown PetscFunctionBegin; 161*fe1899a2SJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 162*fe1899a2SJed Brown dm->ops->createglobalvector = func; 163*fe1899a2SJed Brown PetscFunctionReturn(0); 164*fe1899a2SJed Brown } 165*fe1899a2SJed Brown 166*fe1899a2SJed Brown #undef __FUNCT__ 167*fe1899a2SJed Brown #define __FUNCT__ "DMDestroy_Shell" 168*fe1899a2SJed Brown static PetscErrorCode DMDestroy_Shell(DM dm) 169*fe1899a2SJed Brown { 170*fe1899a2SJed Brown PetscErrorCode ierr; 171*fe1899a2SJed Brown DM_Shell *shell = (DM_Shell*)dm->data; 172*fe1899a2SJed Brown 173*fe1899a2SJed Brown PetscFunctionBegin; 174*fe1899a2SJed Brown ierr = MatDestroy(&shell->A);CHKERRQ(ierr); 175*fe1899a2SJed Brown ierr = VecDestroy(&shell->Xglobal);CHKERRQ(ierr); 176*fe1899a2SJed Brown ierr = PetscFree(dm->data);CHKERRQ(ierr); 177*fe1899a2SJed Brown PetscFunctionReturn(0); 178*fe1899a2SJed Brown } 179*fe1899a2SJed Brown 180*fe1899a2SJed Brown 181*fe1899a2SJed Brown #undef __FUNCT__ 182*fe1899a2SJed Brown #define __FUNCT__ "DMCreate_Shell" 183*fe1899a2SJed Brown PETSC_EXTERN_C PetscErrorCode DMCreate_Shell(DM p) 184*fe1899a2SJed Brown { 185*fe1899a2SJed Brown PetscErrorCode ierr; 186*fe1899a2SJed Brown DM_Shell *shell; 187*fe1899a2SJed Brown 188*fe1899a2SJed Brown PetscFunctionBegin; 189*fe1899a2SJed Brown ierr = PetscNewLog(p,DM_Shell,&shell);CHKERRQ(ierr); 190*fe1899a2SJed Brown p->data = shell; 191*fe1899a2SJed Brown 192*fe1899a2SJed Brown ierr = PetscObjectChangeTypeName((PetscObject)p,DMSHELL);CHKERRQ(ierr); 193*fe1899a2SJed Brown p->ops->createglobalvector = DMCreateGlobalVector_Shell; 194*fe1899a2SJed Brown p->ops->creatematrix = DMCreateMatrix_Shell; 195*fe1899a2SJed Brown p->ops->destroy = DMDestroy_Shell; 196*fe1899a2SJed Brown PetscFunctionReturn(0); 197*fe1899a2SJed Brown } 198*fe1899a2SJed Brown 199*fe1899a2SJed Brown #undef __FUNCT__ 200*fe1899a2SJed Brown #define __FUNCT__ "DMShellCreate" 201*fe1899a2SJed Brown /*@ 202*fe1899a2SJed Brown DMShellCreate - Creates a shell DM object, used to manage user-defined problem data 203*fe1899a2SJed Brown 204*fe1899a2SJed Brown Collective on MPI_Comm 205*fe1899a2SJed Brown 206*fe1899a2SJed Brown Input Parameter: 207*fe1899a2SJed Brown . comm - the processors that will share the global vector 208*fe1899a2SJed Brown 209*fe1899a2SJed Brown Output Parameters: 210*fe1899a2SJed Brown . shell - the shell DM 211*fe1899a2SJed Brown 212*fe1899a2SJed Brown Level: advanced 213*fe1899a2SJed Brown 214*fe1899a2SJed Brown .seealso DMDestroy(), DMCreateGlobalVector() 215*fe1899a2SJed Brown @*/ 216*fe1899a2SJed Brown PetscErrorCode DMShellCreate(MPI_Comm comm,DM *dm) 217*fe1899a2SJed Brown { 218*fe1899a2SJed Brown PetscErrorCode ierr; 219*fe1899a2SJed Brown 220*fe1899a2SJed Brown PetscFunctionBegin; 221*fe1899a2SJed Brown PetscValidPointer(dm,2); 222*fe1899a2SJed Brown ierr = DMCreate(comm,dm);CHKERRQ(ierr); 223*fe1899a2SJed Brown ierr = DMSetType(*dm,DMSHELL);CHKERRQ(ierr); 224*fe1899a2SJed Brown PetscFunctionReturn(0); 225*fe1899a2SJed Brown } 226