1fe1899a2SJed Brown #include <petscdmshell.h> /*I "petscdmshell.h" I*/ 207475bc1SBarry Smith #include <petscmat.h> 307475bc1SBarry Smith #include <petsc-private/dmimpl.h> 4fe1899a2SJed Brown 5fe1899a2SJed Brown typedef struct { 6fe1899a2SJed Brown Vec Xglobal; 7dc43b69eSJed Brown Vec Xlocal; 8fe1899a2SJed Brown Mat A; 981634712SRichard Tran Mills VecScatter *gtol; 1081634712SRichard Tran Mills VecScatter *ltog; 11fe1899a2SJed Brown } DM_Shell; 12fe1899a2SJed Brown 13fe1899a2SJed Brown #undef __FUNCT__ 147a108d1dSBarry Smith #define __FUNCT__ "DMGlobalToLocalBeginDefaultShell" 157a108d1dSBarry Smith /*@ 167a108d1dSBarry Smith DMGlobalToLocalBeginDefaultShell - Uses the GlobalToLocal VecScatter context set by the user to begin a global to local scatter 178d359177SBarry Smith Collective 188d359177SBarry Smith 198d359177SBarry Smith Input Arguments: 208d359177SBarry Smith + dm - shell DM 218d359177SBarry Smith . g - global vector 228d359177SBarry Smith . mode - InsertMode 238d359177SBarry Smith - l - local vector 248d359177SBarry Smith 257a108d1dSBarry Smith Level: advanced 268d359177SBarry Smith 277a108d1dSBarry Smith Note: This is not normally called directly by user code, generally user code calls DMGlobalToLocalBegin() and DMGlobalToLocalEnd(). If the user provides their own custom routines to DMShellSetLocalToGlobal() then those routines might have reason to call this function. 287a108d1dSBarry Smith 297a108d1dSBarry Smith .seealso: DMGlobalToLocalEndDefaultShell() 308d359177SBarry Smith @*/ 317a108d1dSBarry Smith PetscErrorCode DMGlobalToLocalBeginDefaultShell(DM dm,Vec g,InsertMode mode,Vec l) 328d359177SBarry Smith { 338d359177SBarry Smith PetscErrorCode ierr; 348d359177SBarry Smith DM_Shell *shell = (DM_Shell*)dm->data; 358d359177SBarry Smith 368d359177SBarry Smith PetscFunctionBegin; 377a108d1dSBarry Smith if (!shell->gtol) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()"); 388d359177SBarry Smith ierr = VecScatterBegin(*(shell->gtol),g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr); 398d359177SBarry Smith PetscFunctionReturn(0); 408d359177SBarry Smith } 418d359177SBarry Smith 428d359177SBarry Smith #undef __FUNCT__ 437a108d1dSBarry Smith #define __FUNCT__ "DMGlobalToLocalEndDefaultShell" 447a108d1dSBarry Smith /*@ 457a108d1dSBarry Smith DMGlobalToLocalEndDefaultShell - Uses the GlobalToLocal VecScatter context set by the user to end a global to local scatter 468d359177SBarry Smith Collective 478d359177SBarry Smith 488d359177SBarry Smith Input Arguments: 498d359177SBarry Smith + dm - shell DM 508d359177SBarry Smith . g - global vector 518d359177SBarry Smith . mode - InsertMode 528d359177SBarry Smith - l - local vector 538d359177SBarry Smith 547a108d1dSBarry Smith Level: advanced 558d359177SBarry Smith 567a108d1dSBarry Smith .seealso: DMGlobalToLocalBeginDefaultShell() 578d359177SBarry Smith @*/ 587a108d1dSBarry Smith PetscErrorCode DMGlobalToLocalEndDefaultShell(DM dm,Vec g,InsertMode mode,Vec l) 598d359177SBarry Smith { 608d359177SBarry Smith PetscErrorCode ierr; 618d359177SBarry Smith DM_Shell *shell = (DM_Shell*)dm->data; 628d359177SBarry Smith 638d359177SBarry Smith PetscFunctionBegin; 647a108d1dSBarry Smith if (!shell->gtol) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()"); 657a108d1dSBarry Smith ierr = VecScatterEnd(*(shell->gtol),g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr); 668d359177SBarry Smith PetscFunctionReturn(0); 678d359177SBarry Smith } 688d359177SBarry Smith 698d359177SBarry Smith #undef __FUNCT__ 70c5076b69SRichard Tran Mills #define __FUNCT__ "DMLocalToGlobalBeginDefaultShell" 71c5076b69SRichard Tran Mills /*@ 72c5076b69SRichard Tran Mills DMLocalToGlobalBeginDefaultShell - Uses the LocalToGlobal VecScatter context set by the user to begin a local to global scatter 73c5076b69SRichard Tran Mills Collective 74c5076b69SRichard Tran Mills 75c5076b69SRichard Tran Mills Input Arguments: 76c5076b69SRichard Tran Mills + dm - shell DM 77c5076b69SRichard Tran Mills . l - local vector 78c5076b69SRichard Tran Mills . mode - InsertMode 79c5076b69SRichard Tran Mills - g - global vector 80c5076b69SRichard Tran Mills 81c5076b69SRichard Tran Mills Level: advanced 82c5076b69SRichard Tran Mills 83c5076b69SRichard Tran Mills Note: This is not normally called directly by user code, generally user code calls DMLocalToGlobalBegin() and DMLocalToGlobalEnd(). If the user provides their own custom routines to DMShellSetLocalToGlobal() then those routines might have reason to call this function. 84c5076b69SRichard Tran Mills 85c5076b69SRichard Tran Mills .seealso: DMLocalToGlobalEndDefaultShell() 86c5076b69SRichard Tran Mills @*/ 87c5076b69SRichard Tran Mills PetscErrorCode DMLocalToGlobalBeginDefaultShell(DM dm,Vec l,InsertMode mode,Vec g) 88c5076b69SRichard Tran Mills { 89c5076b69SRichard Tran Mills PetscErrorCode ierr; 90c5076b69SRichard Tran Mills DM_Shell *shell = (DM_Shell*)dm->data; 91c5076b69SRichard Tran Mills 92c5076b69SRichard Tran Mills PetscFunctionBegin; 93c5076b69SRichard Tran Mills if (!shell->ltog) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToGlobalVecScatter()"); 94c5076b69SRichard Tran Mills ierr = VecScatterBegin(*(shell->ltog),l,g,mode,SCATTER_FORWARD);CHKERRQ(ierr); 95c5076b69SRichard Tran Mills PetscFunctionReturn(0); 96c5076b69SRichard Tran Mills } 97c5076b69SRichard Tran Mills 98c5076b69SRichard Tran Mills #undef __FUNCT__ 99c5076b69SRichard Tran Mills #define __FUNCT__ "DMLocalToGlobalEndDefaultShell" 100c5076b69SRichard Tran Mills /*@ 101c5076b69SRichard Tran Mills DMLocalToGlobalEndDefaultShell - Uses the LocalToGlobal VecScatter context set by the user to end a local to global scatter 102c5076b69SRichard Tran Mills Collective 103c5076b69SRichard Tran Mills 104c5076b69SRichard Tran Mills Input Arguments: 105c5076b69SRichard Tran Mills + dm - shell DM 106c5076b69SRichard Tran Mills . l - local vector 107c5076b69SRichard Tran Mills . mode - InsertMode 108c5076b69SRichard Tran Mills - g - global vector 109c5076b69SRichard Tran Mills 110c5076b69SRichard Tran Mills Level: advanced 111c5076b69SRichard Tran Mills 112c5076b69SRichard Tran Mills .seealso: DMLocalToGlobalBeginDefaultShell() 113c5076b69SRichard Tran Mills @*/ 114c5076b69SRichard Tran Mills PetscErrorCode DMLocalToGlobalEndDefaultShell(DM dm,Vec l,InsertMode mode,Vec g) 115c5076b69SRichard Tran Mills { 116c5076b69SRichard Tran Mills PetscErrorCode ierr; 117c5076b69SRichard Tran Mills DM_Shell *shell = (DM_Shell*)dm->data; 118c5076b69SRichard Tran Mills 119c5076b69SRichard Tran Mills PetscFunctionBegin; 120c5076b69SRichard Tran Mills if (!shell->ltog) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToGlobalVecScatter()"); 121c5076b69SRichard Tran Mills ierr = VecScatterEnd(*(shell->ltog),l,g,mode,SCATTER_FORWARD);CHKERRQ(ierr); 122c5076b69SRichard Tran Mills PetscFunctionReturn(0); 123c5076b69SRichard Tran Mills } 124c5076b69SRichard Tran Mills 125c5076b69SRichard Tran Mills 126c5076b69SRichard Tran Mills #undef __FUNCT__ 127fe1899a2SJed Brown #define __FUNCT__ "DMCreateMatrix_Shell" 12819fd82e9SBarry Smith static PetscErrorCode DMCreateMatrix_Shell(DM dm,MatType mtype,Mat *J) 129fe1899a2SJed Brown { 130fe1899a2SJed Brown PetscErrorCode ierr; 131fe1899a2SJed Brown DM_Shell *shell = (DM_Shell*)dm->data; 132fe1899a2SJed Brown Mat A; 133fe1899a2SJed Brown 134fe1899a2SJed Brown PetscFunctionBegin; 135fe1899a2SJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 136fe1899a2SJed Brown PetscValidPointer(J,3); 1377bde9f88SJed Brown if (!shell->A) { 1387bde9f88SJed Brown if (shell->Xglobal) { 1397bde9f88SJed Brown PetscInt m,M; 1407bde9f88SJed Brown ierr = PetscInfo(dm,"Naively creating matrix using global vector distribution without preallocation");CHKERRQ(ierr); 1417bde9f88SJed Brown ierr = VecGetSize(shell->Xglobal,&M);CHKERRQ(ierr); 1427bde9f88SJed Brown ierr = VecGetLocalSize(shell->Xglobal,&m);CHKERRQ(ierr); 143ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)dm),&shell->A);CHKERRQ(ierr); 1447bde9f88SJed Brown ierr = MatSetSizes(shell->A,m,m,M,M);CHKERRQ(ierr); 1457bde9f88SJed Brown if (mtype) {ierr = MatSetType(shell->A,mtype);CHKERRQ(ierr);} 1467bde9f88SJed Brown ierr = MatSetUp(shell->A);CHKERRQ(ierr); 147ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetMatrix(), DMShellSetCreateMatrix(), or provide a vector"); 1487bde9f88SJed Brown } 149fe1899a2SJed Brown A = shell->A; 150ad6bc421SBarry Smith /* the check below is tacky and incomplete */ 151fe1899a2SJed Brown if (mtype) { 152ad6bc421SBarry Smith PetscBool flg,aij,seqaij,mpiaij; 153251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)A,mtype,&flg);CHKERRQ(ierr); 154ad6bc421SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&seqaij);CHKERRQ(ierr); 155ad6bc421SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&mpiaij);CHKERRQ(ierr); 156ad6bc421SBarry Smith ierr = PetscStrcmp(mtype,MATAIJ,&aij);CHKERRQ(ierr); 157ad6bc421SBarry Smith if (!flg) { 158ce94432eSBarry Smith if (!(aij & (seqaij || mpiaij))) SETERRQ2(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_NOTSAMETYPE,"Requested matrix of type %s, but only %s available",mtype,((PetscObject)A)->type_name); 159ad6bc421SBarry Smith } 160fe1899a2SJed Brown } 161fe1899a2SJed Brown if (((PetscObject)A)->refct < 2) { /* We have an exclusive reference so we can give it out */ 162fe1899a2SJed Brown ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 163fe1899a2SJed Brown ierr = MatZeroEntries(A);CHKERRQ(ierr); 164fe1899a2SJed Brown *J = A; 165fe1899a2SJed Brown } else { /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */ 166fe1899a2SJed Brown ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,J);CHKERRQ(ierr); 167fe1899a2SJed Brown ierr = MatZeroEntries(*J);CHKERRQ(ierr); 168fe1899a2SJed Brown } 169fe1899a2SJed Brown PetscFunctionReturn(0); 170fe1899a2SJed Brown } 171fe1899a2SJed Brown 172fe1899a2SJed Brown #undef __FUNCT__ 173fe1899a2SJed Brown #define __FUNCT__ "DMCreateGlobalVector_Shell" 174fe1899a2SJed Brown PetscErrorCode DMCreateGlobalVector_Shell(DM dm,Vec *gvec) 175fe1899a2SJed Brown { 176fe1899a2SJed Brown PetscErrorCode ierr; 177fe1899a2SJed Brown DM_Shell *shell = (DM_Shell*)dm->data; 178fe1899a2SJed Brown Vec X; 179fe1899a2SJed Brown 180fe1899a2SJed Brown PetscFunctionBegin; 181fe1899a2SJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 182fe1899a2SJed Brown PetscValidPointer(gvec,2); 183fe1899a2SJed Brown *gvec = 0; 184fe1899a2SJed Brown X = shell->Xglobal; 185ce94432eSBarry Smith if (!X) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetGlobalVector() or DMShellSetCreateGlobalVector()"); 186fe1899a2SJed Brown if (((PetscObject)X)->refct < 2) { /* We have an exclusive reference so we can give it out */ 187fe1899a2SJed Brown ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr); 188fe1899a2SJed Brown ierr = VecZeroEntries(X);CHKERRQ(ierr); 189fe1899a2SJed Brown *gvec = X; 190fe1899a2SJed Brown } else { /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */ 191fe1899a2SJed Brown ierr = VecDuplicate(X,gvec);CHKERRQ(ierr); 192fe1899a2SJed Brown ierr = VecZeroEntries(*gvec);CHKERRQ(ierr); 193fe1899a2SJed Brown } 194c688c046SMatthew G Knepley ierr = VecSetDM(*gvec,dm);CHKERRQ(ierr); 195fe1899a2SJed Brown PetscFunctionReturn(0); 196fe1899a2SJed Brown } 197fe1899a2SJed Brown 198fe1899a2SJed Brown #undef __FUNCT__ 199dc43b69eSJed Brown #define __FUNCT__ "DMCreateLocalVector_Shell" 200dc43b69eSJed Brown PetscErrorCode DMCreateLocalVector_Shell(DM dm,Vec *gvec) 201dc43b69eSJed Brown { 202dc43b69eSJed Brown PetscErrorCode ierr; 203dc43b69eSJed Brown DM_Shell *shell = (DM_Shell*)dm->data; 204dc43b69eSJed Brown Vec X; 205dc43b69eSJed Brown 206dc43b69eSJed Brown PetscFunctionBegin; 207dc43b69eSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 208dc43b69eSJed Brown PetscValidPointer(gvec,2); 209dc43b69eSJed Brown *gvec = 0; 210dc43b69eSJed Brown X = shell->Xlocal; 211ce94432eSBarry Smith if (!X) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetLocalVector() or DMShellSetCreateLocalVector()"); 212dc43b69eSJed Brown if (((PetscObject)X)->refct < 2) { /* We have an exclusive reference so we can give it out */ 213dc43b69eSJed Brown ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr); 214dc43b69eSJed Brown ierr = VecZeroEntries(X);CHKERRQ(ierr); 215dc43b69eSJed Brown *gvec = X; 216dc43b69eSJed Brown } else { /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */ 217dc43b69eSJed Brown ierr = VecDuplicate(X,gvec);CHKERRQ(ierr); 218dc43b69eSJed Brown ierr = VecZeroEntries(*gvec);CHKERRQ(ierr); 219dc43b69eSJed Brown } 2206e4cbd8bSMark F. Adams ierr = VecSetDM(*gvec,dm);CHKERRQ(ierr); 221dc43b69eSJed Brown PetscFunctionReturn(0); 222dc43b69eSJed Brown } 223dc43b69eSJed Brown 224dc43b69eSJed Brown #undef __FUNCT__ 225fe1899a2SJed Brown #define __FUNCT__ "DMShellSetMatrix" 226fe1899a2SJed Brown /*@ 227fe1899a2SJed Brown DMShellSetMatrix - sets a template matrix associated with the DMShell 228fe1899a2SJed Brown 229fe1899a2SJed Brown Collective 230fe1899a2SJed Brown 231fe1899a2SJed Brown Input Arguments: 232fe1899a2SJed Brown + dm - shell DM 233fe1899a2SJed Brown - J - template matrix 234fe1899a2SJed Brown 235fe1899a2SJed Brown Level: advanced 236fe1899a2SJed Brown 237fe1899a2SJed Brown .seealso: DMCreateMatrix(), DMShellSetCreateMatrix() 238fe1899a2SJed Brown @*/ 239fe1899a2SJed Brown PetscErrorCode DMShellSetMatrix(DM dm,Mat J) 240fe1899a2SJed Brown { 241fe1899a2SJed Brown DM_Shell *shell = (DM_Shell*)dm->data; 242fe1899a2SJed Brown PetscErrorCode ierr; 2438c87107bSJed Brown PetscBool isshell; 244fe1899a2SJed Brown 245fe1899a2SJed Brown PetscFunctionBegin; 2468c87107bSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2478c87107bSJed Brown PetscValidHeaderSpecific(J,MAT_CLASSID,2); 248251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr); 2498c87107bSJed Brown if (!isshell) PetscFunctionReturn(0); 250fe1899a2SJed Brown ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr); 251fe1899a2SJed Brown ierr = MatDestroy(&shell->A);CHKERRQ(ierr); 252fe1899a2SJed Brown shell->A = J; 253fe1899a2SJed Brown PetscFunctionReturn(0); 254fe1899a2SJed Brown } 255fe1899a2SJed Brown 256fe1899a2SJed Brown #undef __FUNCT__ 257fe1899a2SJed Brown #define __FUNCT__ "DMShellSetCreateMatrix" 258fe1899a2SJed Brown /*@C 259fe1899a2SJed Brown DMShellSetCreateMatrix - sets the routine to create a matrix associated with the shell DM 260fe1899a2SJed Brown 261fe1899a2SJed Brown Logically Collective on DM 262fe1899a2SJed Brown 263fe1899a2SJed Brown Input Arguments: 264fe1899a2SJed Brown + dm - the shell DM 265fe1899a2SJed Brown - func - the function to create a matrix 266fe1899a2SJed Brown 267fe1899a2SJed Brown Level: advanced 268fe1899a2SJed Brown 269fe1899a2SJed Brown .seealso: DMCreateMatrix(), DMShellSetMatrix() 270fe1899a2SJed Brown @*/ 27119fd82e9SBarry Smith PetscErrorCode DMShellSetCreateMatrix(DM dm,PetscErrorCode (*func)(DM,MatType,Mat*)) 272fe1899a2SJed Brown { 273fe1899a2SJed Brown 274fe1899a2SJed Brown PetscFunctionBegin; 275fe1899a2SJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 276fe1899a2SJed Brown dm->ops->creatematrix = func; 277fe1899a2SJed Brown PetscFunctionReturn(0); 278fe1899a2SJed Brown } 279fe1899a2SJed Brown 280fe1899a2SJed Brown #undef __FUNCT__ 281fe1899a2SJed Brown #define __FUNCT__ "DMShellSetGlobalVector" 282fe1899a2SJed Brown /*@ 283fe1899a2SJed Brown DMShellSetGlobalVector - sets a template global vector associated with the DMShell 284fe1899a2SJed Brown 285fe1899a2SJed Brown Logically Collective on DM 286fe1899a2SJed Brown 287fe1899a2SJed Brown Input Arguments: 288fe1899a2SJed Brown + dm - shell DM 289fe1899a2SJed Brown - X - template vector 290fe1899a2SJed Brown 291fe1899a2SJed Brown Level: advanced 292fe1899a2SJed Brown 293fe1899a2SJed Brown .seealso: DMCreateGlobalVector(), DMShellSetMatrix(), DMShellSetCreateGlobalVector() 294fe1899a2SJed Brown @*/ 295fe1899a2SJed Brown PetscErrorCode DMShellSetGlobalVector(DM dm,Vec X) 296fe1899a2SJed Brown { 297fe1899a2SJed Brown DM_Shell *shell = (DM_Shell*)dm->data; 298fe1899a2SJed Brown PetscErrorCode ierr; 2998c87107bSJed Brown PetscBool isshell; 300fe1899a2SJed Brown 301fe1899a2SJed Brown PetscFunctionBegin; 3028c87107bSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3038c87107bSJed Brown PetscValidHeaderSpecific(X,VEC_CLASSID,2); 304251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr); 3058c87107bSJed Brown if (!isshell) PetscFunctionReturn(0); 306fe1899a2SJed Brown ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr); 307fe1899a2SJed Brown ierr = VecDestroy(&shell->Xglobal);CHKERRQ(ierr); 308fe1899a2SJed Brown shell->Xglobal = X; 309fe1899a2SJed Brown PetscFunctionReturn(0); 310fe1899a2SJed Brown } 311fe1899a2SJed Brown 312fe1899a2SJed Brown #undef __FUNCT__ 313fe1899a2SJed Brown #define __FUNCT__ "DMShellSetCreateGlobalVector" 314fe1899a2SJed Brown /*@C 315fe1899a2SJed Brown DMShellSetCreateGlobalVector - sets the routine to create a global vector associated with the shell DM 316fe1899a2SJed Brown 317fe1899a2SJed Brown Logically Collective 318fe1899a2SJed Brown 319fe1899a2SJed Brown Input Arguments: 320fe1899a2SJed Brown + dm - the shell DM 321fe1899a2SJed Brown - func - the creation routine 322fe1899a2SJed Brown 323fe1899a2SJed Brown Level: advanced 324fe1899a2SJed Brown 325fe1899a2SJed Brown .seealso: DMShellSetGlobalVector(), DMShellSetCreateMatrix() 326fe1899a2SJed Brown @*/ 327fe1899a2SJed Brown PetscErrorCode DMShellSetCreateGlobalVector(DM dm,PetscErrorCode (*func)(DM,Vec*)) 328fe1899a2SJed Brown { 329fe1899a2SJed Brown 330fe1899a2SJed Brown PetscFunctionBegin; 331fe1899a2SJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 332fe1899a2SJed Brown dm->ops->createglobalvector = func; 333fe1899a2SJed Brown PetscFunctionReturn(0); 334fe1899a2SJed Brown } 335fe1899a2SJed Brown 336fe1899a2SJed Brown #undef __FUNCT__ 337dc43b69eSJed Brown #define __FUNCT__ "DMShellSetLocalVector" 338dc43b69eSJed Brown /*@ 339dc43b69eSJed Brown DMShellSetLocalVector - sets a template local vector associated with the DMShell 340dc43b69eSJed Brown 341dc43b69eSJed Brown Logically Collective on DM 342dc43b69eSJed Brown 343dc43b69eSJed Brown Input Arguments: 344dc43b69eSJed Brown + dm - shell DM 345dc43b69eSJed Brown - X - template vector 346dc43b69eSJed Brown 347dc43b69eSJed Brown Level: advanced 348dc43b69eSJed Brown 349dc43b69eSJed Brown .seealso: DMCreateLocalVector(), DMShellSetMatrix(), DMShellSetCreateLocalVector() 350dc43b69eSJed Brown @*/ 351dc43b69eSJed Brown PetscErrorCode DMShellSetLocalVector(DM dm,Vec X) 352dc43b69eSJed Brown { 353dc43b69eSJed Brown DM_Shell *shell = (DM_Shell*)dm->data; 354dc43b69eSJed Brown PetscErrorCode ierr; 355dc43b69eSJed Brown PetscBool isshell; 356dc43b69eSJed Brown 357dc43b69eSJed Brown PetscFunctionBegin; 358dc43b69eSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 359dc43b69eSJed Brown PetscValidHeaderSpecific(X,VEC_CLASSID,2); 360dc43b69eSJed Brown ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr); 361dc43b69eSJed Brown if (!isshell) PetscFunctionReturn(0); 362dc43b69eSJed Brown ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr); 363dc43b69eSJed Brown ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr); 364dc43b69eSJed Brown shell->Xlocal = X; 365dc43b69eSJed Brown PetscFunctionReturn(0); 366dc43b69eSJed Brown } 367dc43b69eSJed Brown 368dc43b69eSJed Brown #undef __FUNCT__ 369dc43b69eSJed Brown #define __FUNCT__ "DMShellSetCreateLocalVector" 370dc43b69eSJed Brown /*@C 371dc43b69eSJed Brown DMShellSetCreateLocalVector - sets the routine to create a local vector associated with the shell DM 372dc43b69eSJed Brown 373dc43b69eSJed Brown Logically Collective 374dc43b69eSJed Brown 375dc43b69eSJed Brown Input Arguments: 376dc43b69eSJed Brown + dm - the shell DM 377dc43b69eSJed Brown - func - the creation routine 378dc43b69eSJed Brown 379dc43b69eSJed Brown Level: advanced 380dc43b69eSJed Brown 381dc43b69eSJed Brown .seealso: DMShellSetLocalVector(), DMShellSetCreateMatrix() 382dc43b69eSJed Brown @*/ 383dc43b69eSJed Brown PetscErrorCode DMShellSetCreateLocalVector(DM dm,PetscErrorCode (*func)(DM,Vec*)) 384dc43b69eSJed Brown { 385dc43b69eSJed Brown 386dc43b69eSJed Brown PetscFunctionBegin; 387dc43b69eSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 388dc43b69eSJed Brown dm->ops->createlocalvector = func; 389dc43b69eSJed Brown PetscFunctionReturn(0); 390dc43b69eSJed Brown } 391dc43b69eSJed Brown 392dc43b69eSJed Brown #undef __FUNCT__ 3938339e6d0SRichard Tran Mills #define __FUNCT__ "DMShellSetGlobalToLocal" 3948339e6d0SRichard Tran Mills /*@C 3958339e6d0SRichard Tran Mills DMShellSetGlobalToLocal - Sets the routines used to perform a global to local scatter 3968339e6d0SRichard Tran Mills 3978339e6d0SRichard Tran Mills Logically Collective on DM 3988339e6d0SRichard Tran Mills 3998339e6d0SRichard Tran Mills Input Arguments 4008339e6d0SRichard Tran Mills + dm - the shell DM 4018339e6d0SRichard Tran Mills . begin - the routine that begins the global to local scatter 4028339e6d0SRichard Tran Mills - end - the routine that ends the global to local scatter 4038339e6d0SRichard Tran Mills 4047a108d1dSBarry Smith Notes: If these functions are not provided but DMShellSetGlobalToLocalVecScatter() is called then 4057a108d1dSBarry Smith DMGlobalToLocalBeginDefaultShell() are used to to perform the transfers DMGlobalToLocalEndDefaultShell() 4067a108d1dSBarry Smith 4078339e6d0SRichard Tran Mills Level: advanced 4088339e6d0SRichard Tran Mills 4097a108d1dSBarry Smith .seealso: DMShellSetLocalToGlobal(), DMGlobalToLocalBeginDefaultShell(), DMGlobalToLocalEndDefaultShell() 4108339e6d0SRichard Tran Mills @*/ 4118339e6d0SRichard Tran Mills PetscErrorCode DMShellSetGlobalToLocal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec)) { 4128339e6d0SRichard Tran Mills PetscFunctionBegin; 4138339e6d0SRichard Tran Mills dm->ops->globaltolocalbegin = begin; 4148339e6d0SRichard Tran Mills dm->ops->globaltolocalend = end; 4158339e6d0SRichard Tran Mills PetscFunctionReturn(0); 4168339e6d0SRichard Tran Mills } 4178339e6d0SRichard Tran Mills 4188339e6d0SRichard Tran Mills #undef __FUNCT__ 4198339e6d0SRichard Tran Mills #define __FUNCT__ "DMShellSetLocalToGlobal" 4208339e6d0SRichard Tran Mills /*@C 4218339e6d0SRichard Tran Mills DMShellSetLocalToGlobal - Sets the routines used to perform a local to global scatter 4228339e6d0SRichard Tran Mills 4238339e6d0SRichard Tran Mills Logically Collective on DM 4248339e6d0SRichard Tran Mills 4258339e6d0SRichard Tran Mills Input Arguments 4268339e6d0SRichard Tran Mills + dm - the shell DM 4278339e6d0SRichard Tran Mills . begin - the routine that begins the local to global scatter 4288339e6d0SRichard Tran Mills - end - the routine that ends the local to global scatter 4298339e6d0SRichard Tran Mills 4308339e6d0SRichard Tran Mills Level: advanced 4318339e6d0SRichard Tran Mills 4328339e6d0SRichard Tran Mills .seealso: DMShellSetGlobalToLocal() 4338339e6d0SRichard Tran Mills @*/ 4348339e6d0SRichard Tran Mills PetscErrorCode DMShellSetLocalToGlobal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec)) { 4358339e6d0SRichard Tran Mills PetscFunctionBegin; 4368339e6d0SRichard Tran Mills dm->ops->localtoglobalbegin = begin; 4378339e6d0SRichard Tran Mills dm->ops->localtoglobalend = end; 4388339e6d0SRichard Tran Mills PetscFunctionReturn(0); 4398339e6d0SRichard Tran Mills } 4408339e6d0SRichard Tran Mills 4418339e6d0SRichard Tran Mills #undef __FUNCT__ 44281634712SRichard Tran Mills #define __FUNCT__ "DMShellSetGlobalToLocalVecScatter" 44381634712SRichard Tran Mills /*@ 44481634712SRichard Tran Mills DMShellSetGlobalToLocalVecScatter - Sets a VecScatter context for global to local communication 44581634712SRichard Tran Mills 44681634712SRichard Tran Mills Logically Collective on DM 44781634712SRichard Tran Mills 44881634712SRichard Tran Mills Input Arguments 44981634712SRichard Tran Mills + dm - the shell DM 45081634712SRichard Tran Mills - gtol - the global to local VecScatter context 45181634712SRichard Tran Mills 45281634712SRichard Tran Mills Level: advanced 45381634712SRichard Tran Mills 45481634712SRichard Tran Mills .seealso: DMShellSetGlobalToLocal() 45581634712SRichard Tran Mills @*/ 45681634712SRichard Tran Mills PetscErrorCode DMShellSetGlobalToLocalVecScatter(DM dm, VecScatter *gtol) 45781634712SRichard Tran Mills { 45881634712SRichard Tran Mills DM_Shell *shell = (DM_Shell*)dm->data; 45981634712SRichard Tran Mills 460b300e4a8SRichard Tran Mills PetscFunctionBegin; 46181634712SRichard Tran Mills shell->gtol = gtol; 46281634712SRichard Tran Mills PetscFunctionReturn(0); 46381634712SRichard Tran Mills } 46481634712SRichard Tran Mills 46581634712SRichard Tran Mills #undef __FUNCT__ 466988ea7d6SRichard Tran Mills #define __FUNCT__ "DMShellSetLocalToGlobalVecScatter" 467988ea7d6SRichard Tran Mills /*@ 468988ea7d6SRichard Tran Mills DMShellSetLocalToGlobalVecScatter - Sets a VecScatter context for local to global communication 469988ea7d6SRichard Tran Mills 470988ea7d6SRichard Tran Mills Logically Collective on DM 471988ea7d6SRichard Tran Mills 472988ea7d6SRichard Tran Mills Input Arguments 473988ea7d6SRichard Tran Mills + dm - the shell DM 474988ea7d6SRichard Tran Mills - ltog - the local to global VecScatter context 475988ea7d6SRichard Tran Mills 476988ea7d6SRichard Tran Mills Level: advanced 477988ea7d6SRichard Tran Mills 478988ea7d6SRichard Tran Mills .seealso: DMShellSetLocalToGlobal() 479988ea7d6SRichard Tran Mills @*/ 480988ea7d6SRichard Tran Mills PetscErrorCode DMShellSetLocalToGlobalVecScatter(DM dm, VecScatter *ltog) 481988ea7d6SRichard Tran Mills { 482988ea7d6SRichard Tran Mills DM_Shell *shell = (DM_Shell*)dm->data; 483988ea7d6SRichard Tran Mills 484988ea7d6SRichard Tran Mills PetscFunctionBegin; 485988ea7d6SRichard Tran Mills shell->ltog = ltog; 486988ea7d6SRichard Tran Mills PetscFunctionReturn(0); 487988ea7d6SRichard Tran Mills } 488988ea7d6SRichard Tran Mills 489988ea7d6SRichard Tran Mills #undef __FUNCT__ 490fe1899a2SJed Brown #define __FUNCT__ "DMDestroy_Shell" 491fe1899a2SJed Brown static PetscErrorCode DMDestroy_Shell(DM dm) 492fe1899a2SJed Brown { 493fe1899a2SJed Brown PetscErrorCode ierr; 494fe1899a2SJed Brown DM_Shell *shell = (DM_Shell*)dm->data; 495fe1899a2SJed Brown 496fe1899a2SJed Brown PetscFunctionBegin; 497fe1899a2SJed Brown ierr = MatDestroy(&shell->A);CHKERRQ(ierr); 498fe1899a2SJed Brown ierr = VecDestroy(&shell->Xglobal);CHKERRQ(ierr); 499dc43b69eSJed Brown ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr); 5007b6ad80cSMatthew G Knepley /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */ 5017b6ad80cSMatthew G Knepley ierr = PetscFree(shell);CHKERRQ(ierr); 502fe1899a2SJed Brown PetscFunctionReturn(0); 503fe1899a2SJed Brown } 504fe1899a2SJed Brown 5052d53ad75SBarry Smith #undef __FUNCT__ 5062d53ad75SBarry Smith #define __FUNCT__ "DMView_Shell" 5072d53ad75SBarry Smith static PetscErrorCode DMView_Shell(DM dm,PetscViewer v) 5082d53ad75SBarry Smith { 5092d53ad75SBarry Smith PetscErrorCode ierr; 5102d53ad75SBarry Smith DM_Shell *shell = (DM_Shell*)dm->data; 5112d53ad75SBarry Smith 5122d53ad75SBarry Smith PetscFunctionBegin; 5132d53ad75SBarry Smith ierr = VecView(shell->Xglobal,v);CHKERRQ(ierr); 5142d53ad75SBarry Smith PetscFunctionReturn(0); 5152d53ad75SBarry Smith } 5162d53ad75SBarry Smith 5172d53ad75SBarry Smith #undef __FUNCT__ 5182d53ad75SBarry Smith #define __FUNCT__ "DMLoad_Shell" 5192d53ad75SBarry Smith static PetscErrorCode DMLoad_Shell(DM dm,PetscViewer v) 5202d53ad75SBarry Smith { 5212d53ad75SBarry Smith PetscErrorCode ierr; 5222d53ad75SBarry Smith DM_Shell *shell = (DM_Shell*)dm->data; 5232d53ad75SBarry Smith 5242d53ad75SBarry Smith PetscFunctionBegin; 525ce94432eSBarry Smith ierr = VecCreate(PetscObjectComm((PetscObject)dm),&shell->Xglobal);CHKERRQ(ierr); 5262d53ad75SBarry Smith ierr = VecLoad(shell->Xglobal,v);CHKERRQ(ierr); 5272d53ad75SBarry Smith PetscFunctionReturn(0); 5282d53ad75SBarry Smith } 529fe1899a2SJed Brown 530fe1899a2SJed Brown #undef __FUNCT__ 531fe1899a2SJed Brown #define __FUNCT__ "DMCreate_Shell" 5328cc058d9SJed Brown PETSC_EXTERN PetscErrorCode DMCreate_Shell(DM dm) 533fe1899a2SJed Brown { 534fe1899a2SJed Brown PetscErrorCode ierr; 535fe1899a2SJed Brown DM_Shell *shell; 536fe1899a2SJed Brown 537fe1899a2SJed Brown PetscFunctionBegin; 5388c87107bSJed Brown ierr = PetscNewLog(dm,DM_Shell,&shell);CHKERRQ(ierr); 5398c87107bSJed Brown dm->data = shell; 540fe1899a2SJed Brown 5418c87107bSJed Brown ierr = PetscObjectChangeTypeName((PetscObject)dm,DMSHELL);CHKERRQ(ierr); 5428865f1eaSKarl Rupp 5438c87107bSJed Brown dm->ops->destroy = DMDestroy_Shell; 5448c87107bSJed Brown dm->ops->createglobalvector = DMCreateGlobalVector_Shell; 545dc43b69eSJed Brown dm->ops->createlocalvector = DMCreateLocalVector_Shell; 5468c87107bSJed Brown dm->ops->creatematrix = DMCreateMatrix_Shell; 5472d53ad75SBarry Smith dm->ops->view = DMView_Shell; 5482d53ad75SBarry Smith dm->ops->load = DMLoad_Shell; 5497a108d1dSBarry Smith dm->ops->globaltolocalbegin = DMGlobalToLocalBeginDefaultShell; 5507a108d1dSBarry Smith dm->ops->globaltolocalend = DMGlobalToLocalEndDefaultShell; 551*55daaa54SRichard Tran Mills dm->ops->localtoglobalbegin = DMLocalToGlobalBeginDefaultShell; 552*55daaa54SRichard Tran Mills dm->ops->localtoglobalend = DMLocalToGlobalEndDefaultShell; 553fe1899a2SJed Brown PetscFunctionReturn(0); 554fe1899a2SJed Brown } 555fe1899a2SJed Brown 556fe1899a2SJed Brown #undef __FUNCT__ 557fe1899a2SJed Brown #define __FUNCT__ "DMShellCreate" 558fe1899a2SJed Brown /*@ 559fe1899a2SJed Brown DMShellCreate - Creates a shell DM object, used to manage user-defined problem data 560fe1899a2SJed Brown 561fe1899a2SJed Brown Collective on MPI_Comm 562fe1899a2SJed Brown 563fe1899a2SJed Brown Input Parameter: 564fe1899a2SJed Brown . comm - the processors that will share the global vector 565fe1899a2SJed Brown 566fe1899a2SJed Brown Output Parameters: 567fe1899a2SJed Brown . shell - the shell DM 568fe1899a2SJed Brown 569fe1899a2SJed Brown Level: advanced 570fe1899a2SJed Brown 571dc43b69eSJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateLocalVector() 572fe1899a2SJed Brown @*/ 573fe1899a2SJed Brown PetscErrorCode DMShellCreate(MPI_Comm comm,DM *dm) 574fe1899a2SJed Brown { 575fe1899a2SJed Brown PetscErrorCode ierr; 576fe1899a2SJed Brown 577fe1899a2SJed Brown PetscFunctionBegin; 578fe1899a2SJed Brown PetscValidPointer(dm,2); 579fe1899a2SJed Brown ierr = DMCreate(comm,dm);CHKERRQ(ierr); 580fe1899a2SJed Brown ierr = DMSetType(*dm,DMSHELL);CHKERRQ(ierr); 581fe1899a2SJed Brown PetscFunctionReturn(0); 582fe1899a2SJed Brown } 58381634712SRichard Tran Mills 584