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; 9a94b16f6SRichard Tran Mills VecScatter gtol; 10a94b16f6SRichard Tran Mills VecScatter ltog; 11*f089877aSRichard Tran Mills VecScatter ltol; 12fe1899a2SJed Brown } DM_Shell; 13fe1899a2SJed Brown 14fe1899a2SJed Brown #undef __FUNCT__ 157a108d1dSBarry Smith #define __FUNCT__ "DMGlobalToLocalBeginDefaultShell" 167a108d1dSBarry Smith /*@ 177a108d1dSBarry Smith DMGlobalToLocalBeginDefaultShell - Uses the GlobalToLocal VecScatter context set by the user to begin a global to local scatter 188d359177SBarry Smith Collective 198d359177SBarry Smith 208d359177SBarry Smith Input Arguments: 218d359177SBarry Smith + dm - shell DM 228d359177SBarry Smith . g - global vector 238d359177SBarry Smith . mode - InsertMode 248d359177SBarry Smith - l - local vector 258d359177SBarry Smith 267a108d1dSBarry Smith Level: advanced 278d359177SBarry Smith 287a108d1dSBarry 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. 297a108d1dSBarry Smith 307a108d1dSBarry Smith .seealso: DMGlobalToLocalEndDefaultShell() 318d359177SBarry Smith @*/ 327a108d1dSBarry Smith PetscErrorCode DMGlobalToLocalBeginDefaultShell(DM dm,Vec g,InsertMode mode,Vec l) 338d359177SBarry Smith { 348d359177SBarry Smith PetscErrorCode ierr; 358d359177SBarry Smith DM_Shell *shell = (DM_Shell*)dm->data; 368d359177SBarry Smith 378d359177SBarry Smith PetscFunctionBegin; 387a108d1dSBarry Smith if (!shell->gtol) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()"); 39a94b16f6SRichard Tran Mills ierr = VecScatterBegin(shell->gtol,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr); 408d359177SBarry Smith PetscFunctionReturn(0); 418d359177SBarry Smith } 428d359177SBarry Smith 438d359177SBarry Smith #undef __FUNCT__ 447a108d1dSBarry Smith #define __FUNCT__ "DMGlobalToLocalEndDefaultShell" 457a108d1dSBarry Smith /*@ 467a108d1dSBarry Smith DMGlobalToLocalEndDefaultShell - Uses the GlobalToLocal VecScatter context set by the user to end a global to local scatter 478d359177SBarry Smith Collective 488d359177SBarry Smith 498d359177SBarry Smith Input Arguments: 508d359177SBarry Smith + dm - shell DM 518d359177SBarry Smith . g - global vector 528d359177SBarry Smith . mode - InsertMode 538d359177SBarry Smith - l - local vector 548d359177SBarry Smith 557a108d1dSBarry Smith Level: advanced 568d359177SBarry Smith 577a108d1dSBarry Smith .seealso: DMGlobalToLocalBeginDefaultShell() 588d359177SBarry Smith @*/ 597a108d1dSBarry Smith PetscErrorCode DMGlobalToLocalEndDefaultShell(DM dm,Vec g,InsertMode mode,Vec l) 608d359177SBarry Smith { 618d359177SBarry Smith PetscErrorCode ierr; 628d359177SBarry Smith DM_Shell *shell = (DM_Shell*)dm->data; 638d359177SBarry Smith 648d359177SBarry Smith PetscFunctionBegin; 657a108d1dSBarry Smith if (!shell->gtol) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()"); 66a94b16f6SRichard Tran Mills ierr = VecScatterEnd(shell->gtol,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr); 678d359177SBarry Smith PetscFunctionReturn(0); 688d359177SBarry Smith } 698d359177SBarry Smith 708d359177SBarry Smith #undef __FUNCT__ 71c5076b69SRichard Tran Mills #define __FUNCT__ "DMLocalToGlobalBeginDefaultShell" 72c5076b69SRichard Tran Mills /*@ 73c5076b69SRichard Tran Mills DMLocalToGlobalBeginDefaultShell - Uses the LocalToGlobal VecScatter context set by the user to begin a local to global scatter 74c5076b69SRichard Tran Mills Collective 75c5076b69SRichard Tran Mills 76c5076b69SRichard Tran Mills Input Arguments: 77c5076b69SRichard Tran Mills + dm - shell DM 78c5076b69SRichard Tran Mills . l - local vector 79c5076b69SRichard Tran Mills . mode - InsertMode 80c5076b69SRichard Tran Mills - g - global vector 81c5076b69SRichard Tran Mills 82c5076b69SRichard Tran Mills Level: advanced 83c5076b69SRichard Tran Mills 84c5076b69SRichard 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. 85c5076b69SRichard Tran Mills 86c5076b69SRichard Tran Mills .seealso: DMLocalToGlobalEndDefaultShell() 87c5076b69SRichard Tran Mills @*/ 88c5076b69SRichard Tran Mills PetscErrorCode DMLocalToGlobalBeginDefaultShell(DM dm,Vec l,InsertMode mode,Vec g) 89c5076b69SRichard Tran Mills { 90c5076b69SRichard Tran Mills PetscErrorCode ierr; 91c5076b69SRichard Tran Mills DM_Shell *shell = (DM_Shell*)dm->data; 92c5076b69SRichard Tran Mills 93c5076b69SRichard Tran Mills PetscFunctionBegin; 94c5076b69SRichard Tran Mills if (!shell->ltog) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToGlobalVecScatter()"); 95a94b16f6SRichard Tran Mills ierr = VecScatterBegin(shell->ltog,l,g,mode,SCATTER_FORWARD);CHKERRQ(ierr); 96c5076b69SRichard Tran Mills PetscFunctionReturn(0); 97c5076b69SRichard Tran Mills } 98c5076b69SRichard Tran Mills 99c5076b69SRichard Tran Mills #undef __FUNCT__ 100c5076b69SRichard Tran Mills #define __FUNCT__ "DMLocalToGlobalEndDefaultShell" 101c5076b69SRichard Tran Mills /*@ 102c5076b69SRichard Tran Mills DMLocalToGlobalEndDefaultShell - Uses the LocalToGlobal VecScatter context set by the user to end a local to global scatter 103c5076b69SRichard Tran Mills Collective 104c5076b69SRichard Tran Mills 105c5076b69SRichard Tran Mills Input Arguments: 106c5076b69SRichard Tran Mills + dm - shell DM 107c5076b69SRichard Tran Mills . l - local vector 108c5076b69SRichard Tran Mills . mode - InsertMode 109c5076b69SRichard Tran Mills - g - global vector 110c5076b69SRichard Tran Mills 111c5076b69SRichard Tran Mills Level: advanced 112c5076b69SRichard Tran Mills 113c5076b69SRichard Tran Mills .seealso: DMLocalToGlobalBeginDefaultShell() 114c5076b69SRichard Tran Mills @*/ 115c5076b69SRichard Tran Mills PetscErrorCode DMLocalToGlobalEndDefaultShell(DM dm,Vec l,InsertMode mode,Vec g) 116c5076b69SRichard Tran Mills { 117c5076b69SRichard Tran Mills PetscErrorCode ierr; 118c5076b69SRichard Tran Mills DM_Shell *shell = (DM_Shell*)dm->data; 119c5076b69SRichard Tran Mills 120c5076b69SRichard Tran Mills PetscFunctionBegin; 121c5076b69SRichard Tran Mills if (!shell->ltog) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToGlobalVecScatter()"); 122a94b16f6SRichard Tran Mills ierr = VecScatterEnd(shell->ltog,l,g,mode,SCATTER_FORWARD);CHKERRQ(ierr); 123c5076b69SRichard Tran Mills PetscFunctionReturn(0); 124c5076b69SRichard Tran Mills } 125c5076b69SRichard Tran Mills 126c5076b69SRichard Tran Mills 127c5076b69SRichard Tran Mills #undef __FUNCT__ 128fe1899a2SJed Brown #define __FUNCT__ "DMCreateMatrix_Shell" 12919fd82e9SBarry Smith static PetscErrorCode DMCreateMatrix_Shell(DM dm,MatType mtype,Mat *J) 130fe1899a2SJed Brown { 131fe1899a2SJed Brown PetscErrorCode ierr; 132fe1899a2SJed Brown DM_Shell *shell = (DM_Shell*)dm->data; 133fe1899a2SJed Brown Mat A; 134fe1899a2SJed Brown 135fe1899a2SJed Brown PetscFunctionBegin; 136fe1899a2SJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 137fe1899a2SJed Brown PetscValidPointer(J,3); 1387bde9f88SJed Brown if (!shell->A) { 1397bde9f88SJed Brown if (shell->Xglobal) { 1407bde9f88SJed Brown PetscInt m,M; 1417bde9f88SJed Brown ierr = PetscInfo(dm,"Naively creating matrix using global vector distribution without preallocation");CHKERRQ(ierr); 1427bde9f88SJed Brown ierr = VecGetSize(shell->Xglobal,&M);CHKERRQ(ierr); 1437bde9f88SJed Brown ierr = VecGetLocalSize(shell->Xglobal,&m);CHKERRQ(ierr); 144ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)dm),&shell->A);CHKERRQ(ierr); 1457bde9f88SJed Brown ierr = MatSetSizes(shell->A,m,m,M,M);CHKERRQ(ierr); 1467bde9f88SJed Brown if (mtype) {ierr = MatSetType(shell->A,mtype);CHKERRQ(ierr);} 1477bde9f88SJed Brown ierr = MatSetUp(shell->A);CHKERRQ(ierr); 148ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetMatrix(), DMShellSetCreateMatrix(), or provide a vector"); 1497bde9f88SJed Brown } 150fe1899a2SJed Brown A = shell->A; 151ad6bc421SBarry Smith /* the check below is tacky and incomplete */ 152fe1899a2SJed Brown if (mtype) { 153ad6bc421SBarry Smith PetscBool flg,aij,seqaij,mpiaij; 154251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)A,mtype,&flg);CHKERRQ(ierr); 155ad6bc421SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&seqaij);CHKERRQ(ierr); 156ad6bc421SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&mpiaij);CHKERRQ(ierr); 157ad6bc421SBarry Smith ierr = PetscStrcmp(mtype,MATAIJ,&aij);CHKERRQ(ierr); 158ad6bc421SBarry Smith if (!flg) { 159b4640e9aSSatish Balay 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); 160ad6bc421SBarry Smith } 161fe1899a2SJed Brown } 162fe1899a2SJed Brown if (((PetscObject)A)->refct < 2) { /* We have an exclusive reference so we can give it out */ 163fe1899a2SJed Brown ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 164fe1899a2SJed Brown ierr = MatZeroEntries(A);CHKERRQ(ierr); 165fe1899a2SJed Brown *J = A; 166fe1899a2SJed Brown } else { /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */ 167fe1899a2SJed Brown ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,J);CHKERRQ(ierr); 168fe1899a2SJed Brown ierr = MatZeroEntries(*J);CHKERRQ(ierr); 169fe1899a2SJed Brown } 170fe1899a2SJed Brown PetscFunctionReturn(0); 171fe1899a2SJed Brown } 172fe1899a2SJed Brown 173fe1899a2SJed Brown #undef __FUNCT__ 174fe1899a2SJed Brown #define __FUNCT__ "DMCreateGlobalVector_Shell" 175fe1899a2SJed Brown PetscErrorCode DMCreateGlobalVector_Shell(DM dm,Vec *gvec) 176fe1899a2SJed Brown { 177fe1899a2SJed Brown PetscErrorCode ierr; 178fe1899a2SJed Brown DM_Shell *shell = (DM_Shell*)dm->data; 179fe1899a2SJed Brown Vec X; 180fe1899a2SJed Brown 181fe1899a2SJed Brown PetscFunctionBegin; 182fe1899a2SJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 183fe1899a2SJed Brown PetscValidPointer(gvec,2); 184fe1899a2SJed Brown *gvec = 0; 185fe1899a2SJed Brown X = shell->Xglobal; 186ce94432eSBarry Smith if (!X) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetGlobalVector() or DMShellSetCreateGlobalVector()"); 187fe1899a2SJed Brown if (((PetscObject)X)->refct < 2) { /* We have an exclusive reference so we can give it out */ 188fe1899a2SJed Brown ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr); 189fe1899a2SJed Brown ierr = VecZeroEntries(X);CHKERRQ(ierr); 190fe1899a2SJed Brown *gvec = X; 191fe1899a2SJed Brown } else { /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */ 192fe1899a2SJed Brown ierr = VecDuplicate(X,gvec);CHKERRQ(ierr); 193fe1899a2SJed Brown ierr = VecZeroEntries(*gvec);CHKERRQ(ierr); 194fe1899a2SJed Brown } 195c688c046SMatthew G Knepley ierr = VecSetDM(*gvec,dm);CHKERRQ(ierr); 196fe1899a2SJed Brown PetscFunctionReturn(0); 197fe1899a2SJed Brown } 198fe1899a2SJed Brown 199fe1899a2SJed Brown #undef __FUNCT__ 200dc43b69eSJed Brown #define __FUNCT__ "DMCreateLocalVector_Shell" 201dc43b69eSJed Brown PetscErrorCode DMCreateLocalVector_Shell(DM dm,Vec *gvec) 202dc43b69eSJed Brown { 203dc43b69eSJed Brown PetscErrorCode ierr; 204dc43b69eSJed Brown DM_Shell *shell = (DM_Shell*)dm->data; 205dc43b69eSJed Brown Vec X; 206dc43b69eSJed Brown 207dc43b69eSJed Brown PetscFunctionBegin; 208dc43b69eSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 209dc43b69eSJed Brown PetscValidPointer(gvec,2); 210dc43b69eSJed Brown *gvec = 0; 211dc43b69eSJed Brown X = shell->Xlocal; 212ce94432eSBarry Smith if (!X) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetLocalVector() or DMShellSetCreateLocalVector()"); 213dc43b69eSJed Brown if (((PetscObject)X)->refct < 2) { /* We have an exclusive reference so we can give it out */ 214dc43b69eSJed Brown ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr); 215dc43b69eSJed Brown ierr = VecZeroEntries(X);CHKERRQ(ierr); 216dc43b69eSJed Brown *gvec = X; 217dc43b69eSJed Brown } else { /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */ 218dc43b69eSJed Brown ierr = VecDuplicate(X,gvec);CHKERRQ(ierr); 219dc43b69eSJed Brown ierr = VecZeroEntries(*gvec);CHKERRQ(ierr); 220dc43b69eSJed Brown } 2216e4cbd8bSMark F. Adams ierr = VecSetDM(*gvec,dm);CHKERRQ(ierr); 222dc43b69eSJed Brown PetscFunctionReturn(0); 223dc43b69eSJed Brown } 224dc43b69eSJed Brown 225dc43b69eSJed Brown #undef __FUNCT__ 226fe1899a2SJed Brown #define __FUNCT__ "DMShellSetMatrix" 227fe1899a2SJed Brown /*@ 228fe1899a2SJed Brown DMShellSetMatrix - sets a template matrix associated with the DMShell 229fe1899a2SJed Brown 230fe1899a2SJed Brown Collective 231fe1899a2SJed Brown 232fe1899a2SJed Brown Input Arguments: 233fe1899a2SJed Brown + dm - shell DM 234fe1899a2SJed Brown - J - template matrix 235fe1899a2SJed Brown 236fe1899a2SJed Brown Level: advanced 237fe1899a2SJed Brown 238fe1899a2SJed Brown .seealso: DMCreateMatrix(), DMShellSetCreateMatrix() 239fe1899a2SJed Brown @*/ 240fe1899a2SJed Brown PetscErrorCode DMShellSetMatrix(DM dm,Mat J) 241fe1899a2SJed Brown { 242fe1899a2SJed Brown DM_Shell *shell = (DM_Shell*)dm->data; 243fe1899a2SJed Brown PetscErrorCode ierr; 2448c87107bSJed Brown PetscBool isshell; 245fe1899a2SJed Brown 246fe1899a2SJed Brown PetscFunctionBegin; 2478c87107bSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2488c87107bSJed Brown PetscValidHeaderSpecific(J,MAT_CLASSID,2); 249251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr); 2508c87107bSJed Brown if (!isshell) PetscFunctionReturn(0); 251fe1899a2SJed Brown ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr); 252fe1899a2SJed Brown ierr = MatDestroy(&shell->A);CHKERRQ(ierr); 253fe1899a2SJed Brown shell->A = J; 254fe1899a2SJed Brown PetscFunctionReturn(0); 255fe1899a2SJed Brown } 256fe1899a2SJed Brown 257fe1899a2SJed Brown #undef __FUNCT__ 258fe1899a2SJed Brown #define __FUNCT__ "DMShellSetCreateMatrix" 259fe1899a2SJed Brown /*@C 260fe1899a2SJed Brown DMShellSetCreateMatrix - sets the routine to create a matrix associated with the shell DM 261fe1899a2SJed Brown 262fe1899a2SJed Brown Logically Collective on DM 263fe1899a2SJed Brown 264fe1899a2SJed Brown Input Arguments: 265fe1899a2SJed Brown + dm - the shell DM 266fe1899a2SJed Brown - func - the function to create a matrix 267fe1899a2SJed Brown 268fe1899a2SJed Brown Level: advanced 269fe1899a2SJed Brown 270fe1899a2SJed Brown .seealso: DMCreateMatrix(), DMShellSetMatrix() 271fe1899a2SJed Brown @*/ 27219fd82e9SBarry Smith PetscErrorCode DMShellSetCreateMatrix(DM dm,PetscErrorCode (*func)(DM,MatType,Mat*)) 273fe1899a2SJed Brown { 274fe1899a2SJed Brown 275fe1899a2SJed Brown PetscFunctionBegin; 276fe1899a2SJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 277fe1899a2SJed Brown dm->ops->creatematrix = func; 278fe1899a2SJed Brown PetscFunctionReturn(0); 279fe1899a2SJed Brown } 280fe1899a2SJed Brown 281fe1899a2SJed Brown #undef __FUNCT__ 282fe1899a2SJed Brown #define __FUNCT__ "DMShellSetGlobalVector" 283fe1899a2SJed Brown /*@ 284fe1899a2SJed Brown DMShellSetGlobalVector - sets a template global vector associated with the DMShell 285fe1899a2SJed Brown 286fe1899a2SJed Brown Logically Collective on DM 287fe1899a2SJed Brown 288fe1899a2SJed Brown Input Arguments: 289fe1899a2SJed Brown + dm - shell DM 290fe1899a2SJed Brown - X - template vector 291fe1899a2SJed Brown 292fe1899a2SJed Brown Level: advanced 293fe1899a2SJed Brown 294fe1899a2SJed Brown .seealso: DMCreateGlobalVector(), DMShellSetMatrix(), DMShellSetCreateGlobalVector() 295fe1899a2SJed Brown @*/ 296fe1899a2SJed Brown PetscErrorCode DMShellSetGlobalVector(DM dm,Vec X) 297fe1899a2SJed Brown { 298fe1899a2SJed Brown DM_Shell *shell = (DM_Shell*)dm->data; 299fe1899a2SJed Brown PetscErrorCode ierr; 3008c87107bSJed Brown PetscBool isshell; 301fe1899a2SJed Brown 302fe1899a2SJed Brown PetscFunctionBegin; 3038c87107bSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3048c87107bSJed Brown PetscValidHeaderSpecific(X,VEC_CLASSID,2); 305251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr); 3068c87107bSJed Brown if (!isshell) PetscFunctionReturn(0); 307fe1899a2SJed Brown ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr); 308fe1899a2SJed Brown ierr = VecDestroy(&shell->Xglobal);CHKERRQ(ierr); 309fe1899a2SJed Brown shell->Xglobal = X; 310fe1899a2SJed Brown PetscFunctionReturn(0); 311fe1899a2SJed Brown } 312fe1899a2SJed Brown 313fe1899a2SJed Brown #undef __FUNCT__ 314fe1899a2SJed Brown #define __FUNCT__ "DMShellSetCreateGlobalVector" 315fe1899a2SJed Brown /*@C 316fe1899a2SJed Brown DMShellSetCreateGlobalVector - sets the routine to create a global vector associated with the shell DM 317fe1899a2SJed Brown 318fe1899a2SJed Brown Logically Collective 319fe1899a2SJed Brown 320fe1899a2SJed Brown Input Arguments: 321fe1899a2SJed Brown + dm - the shell DM 322fe1899a2SJed Brown - func - the creation routine 323fe1899a2SJed Brown 324fe1899a2SJed Brown Level: advanced 325fe1899a2SJed Brown 326fe1899a2SJed Brown .seealso: DMShellSetGlobalVector(), DMShellSetCreateMatrix() 327fe1899a2SJed Brown @*/ 328fe1899a2SJed Brown PetscErrorCode DMShellSetCreateGlobalVector(DM dm,PetscErrorCode (*func)(DM,Vec*)) 329fe1899a2SJed Brown { 330fe1899a2SJed Brown 331fe1899a2SJed Brown PetscFunctionBegin; 332fe1899a2SJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 333fe1899a2SJed Brown dm->ops->createglobalvector = func; 334fe1899a2SJed Brown PetscFunctionReturn(0); 335fe1899a2SJed Brown } 336fe1899a2SJed Brown 337fe1899a2SJed Brown #undef __FUNCT__ 338dc43b69eSJed Brown #define __FUNCT__ "DMShellSetLocalVector" 339dc43b69eSJed Brown /*@ 340dc43b69eSJed Brown DMShellSetLocalVector - sets a template local vector associated with the DMShell 341dc43b69eSJed Brown 342dc43b69eSJed Brown Logically Collective on DM 343dc43b69eSJed Brown 344dc43b69eSJed Brown Input Arguments: 345dc43b69eSJed Brown + dm - shell DM 346dc43b69eSJed Brown - X - template vector 347dc43b69eSJed Brown 348dc43b69eSJed Brown Level: advanced 349dc43b69eSJed Brown 350dc43b69eSJed Brown .seealso: DMCreateLocalVector(), DMShellSetMatrix(), DMShellSetCreateLocalVector() 351dc43b69eSJed Brown @*/ 352dc43b69eSJed Brown PetscErrorCode DMShellSetLocalVector(DM dm,Vec X) 353dc43b69eSJed Brown { 354dc43b69eSJed Brown DM_Shell *shell = (DM_Shell*)dm->data; 355dc43b69eSJed Brown PetscErrorCode ierr; 356dc43b69eSJed Brown PetscBool isshell; 357dc43b69eSJed Brown 358dc43b69eSJed Brown PetscFunctionBegin; 359dc43b69eSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 360dc43b69eSJed Brown PetscValidHeaderSpecific(X,VEC_CLASSID,2); 361dc43b69eSJed Brown ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr); 362dc43b69eSJed Brown if (!isshell) PetscFunctionReturn(0); 363dc43b69eSJed Brown ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr); 364dc43b69eSJed Brown ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr); 365dc43b69eSJed Brown shell->Xlocal = X; 366dc43b69eSJed Brown PetscFunctionReturn(0); 367dc43b69eSJed Brown } 368dc43b69eSJed Brown 369dc43b69eSJed Brown #undef __FUNCT__ 370dc43b69eSJed Brown #define __FUNCT__ "DMShellSetCreateLocalVector" 371dc43b69eSJed Brown /*@C 372dc43b69eSJed Brown DMShellSetCreateLocalVector - sets the routine to create a local vector associated with the shell DM 373dc43b69eSJed Brown 374dc43b69eSJed Brown Logically Collective 375dc43b69eSJed Brown 376dc43b69eSJed Brown Input Arguments: 377dc43b69eSJed Brown + dm - the shell DM 378dc43b69eSJed Brown - func - the creation routine 379dc43b69eSJed Brown 380dc43b69eSJed Brown Level: advanced 381dc43b69eSJed Brown 382dc43b69eSJed Brown .seealso: DMShellSetLocalVector(), DMShellSetCreateMatrix() 383dc43b69eSJed Brown @*/ 384dc43b69eSJed Brown PetscErrorCode DMShellSetCreateLocalVector(DM dm,PetscErrorCode (*func)(DM,Vec*)) 385dc43b69eSJed Brown { 386dc43b69eSJed Brown 387dc43b69eSJed Brown PetscFunctionBegin; 388dc43b69eSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 389dc43b69eSJed Brown dm->ops->createlocalvector = func; 390dc43b69eSJed Brown PetscFunctionReturn(0); 391dc43b69eSJed Brown } 392dc43b69eSJed Brown 393dc43b69eSJed Brown #undef __FUNCT__ 3948339e6d0SRichard Tran Mills #define __FUNCT__ "DMShellSetGlobalToLocal" 3958339e6d0SRichard Tran Mills /*@C 3968339e6d0SRichard Tran Mills DMShellSetGlobalToLocal - Sets the routines used to perform a global to local scatter 3978339e6d0SRichard Tran Mills 3988339e6d0SRichard Tran Mills Logically Collective on DM 3998339e6d0SRichard Tran Mills 4008339e6d0SRichard Tran Mills Input Arguments 4018339e6d0SRichard Tran Mills + dm - the shell DM 4028339e6d0SRichard Tran Mills . begin - the routine that begins the global to local scatter 4038339e6d0SRichard Tran Mills - end - the routine that ends the global to local scatter 4048339e6d0SRichard Tran Mills 4057a108d1dSBarry Smith Notes: If these functions are not provided but DMShellSetGlobalToLocalVecScatter() is called then 4067a108d1dSBarry Smith DMGlobalToLocalBeginDefaultShell() are used to to perform the transfers DMGlobalToLocalEndDefaultShell() 4077a108d1dSBarry Smith 4088339e6d0SRichard Tran Mills Level: advanced 4098339e6d0SRichard Tran Mills 4107a108d1dSBarry Smith .seealso: DMShellSetLocalToGlobal(), DMGlobalToLocalBeginDefaultShell(), DMGlobalToLocalEndDefaultShell() 4118339e6d0SRichard Tran Mills @*/ 4128339e6d0SRichard Tran Mills PetscErrorCode DMShellSetGlobalToLocal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec)) { 4138339e6d0SRichard Tran Mills PetscFunctionBegin; 4148339e6d0SRichard Tran Mills dm->ops->globaltolocalbegin = begin; 4158339e6d0SRichard Tran Mills dm->ops->globaltolocalend = end; 4168339e6d0SRichard Tran Mills PetscFunctionReturn(0); 4178339e6d0SRichard Tran Mills } 4188339e6d0SRichard Tran Mills 4198339e6d0SRichard Tran Mills #undef __FUNCT__ 4208339e6d0SRichard Tran Mills #define __FUNCT__ "DMShellSetLocalToGlobal" 4218339e6d0SRichard Tran Mills /*@C 4228339e6d0SRichard Tran Mills DMShellSetLocalToGlobal - Sets the routines used to perform a local to global scatter 4238339e6d0SRichard Tran Mills 4248339e6d0SRichard Tran Mills Logically Collective on DM 4258339e6d0SRichard Tran Mills 4268339e6d0SRichard Tran Mills Input Arguments 4278339e6d0SRichard Tran Mills + dm - the shell DM 4288339e6d0SRichard Tran Mills . begin - the routine that begins the local to global scatter 4298339e6d0SRichard Tran Mills - end - the routine that ends the local to global scatter 4308339e6d0SRichard Tran Mills 4318339e6d0SRichard Tran Mills Level: advanced 4328339e6d0SRichard Tran Mills 4338339e6d0SRichard Tran Mills .seealso: DMShellSetGlobalToLocal() 4348339e6d0SRichard Tran Mills @*/ 4358339e6d0SRichard Tran Mills PetscErrorCode DMShellSetLocalToGlobal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec)) { 4368339e6d0SRichard Tran Mills PetscFunctionBegin; 4378339e6d0SRichard Tran Mills dm->ops->localtoglobalbegin = begin; 4388339e6d0SRichard Tran Mills dm->ops->localtoglobalend = end; 4398339e6d0SRichard Tran Mills PetscFunctionReturn(0); 4408339e6d0SRichard Tran Mills } 4418339e6d0SRichard Tran Mills 4428339e6d0SRichard Tran Mills #undef __FUNCT__ 44381634712SRichard Tran Mills #define __FUNCT__ "DMShellSetGlobalToLocalVecScatter" 44481634712SRichard Tran Mills /*@ 44581634712SRichard Tran Mills DMShellSetGlobalToLocalVecScatter - Sets a VecScatter context for global to local communication 44681634712SRichard Tran Mills 44781634712SRichard Tran Mills Logically Collective on DM 44881634712SRichard Tran Mills 44981634712SRichard Tran Mills Input Arguments 45081634712SRichard Tran Mills + dm - the shell DM 45181634712SRichard Tran Mills - gtol - the global to local VecScatter context 45281634712SRichard Tran Mills 45381634712SRichard Tran Mills Level: advanced 45481634712SRichard Tran Mills 45581634712SRichard Tran Mills .seealso: DMShellSetGlobalToLocal() 45681634712SRichard Tran Mills @*/ 457a94b16f6SRichard Tran Mills PetscErrorCode DMShellSetGlobalToLocalVecScatter(DM dm, VecScatter gtol) 45881634712SRichard Tran Mills { 45981634712SRichard Tran Mills DM_Shell *shell = (DM_Shell*)dm->data; 460d885d199SRichard Tran Mills PetscErrorCode ierr; 46181634712SRichard Tran Mills 462b300e4a8SRichard Tran Mills PetscFunctionBegin; 463d885d199SRichard Tran Mills ierr = PetscObjectReference((PetscObject)gtol);CHKERRQ(ierr); 464d885d199SRichard Tran Mills /* Call VecScatterDestroy() to avoid a memory leak in case of re-setting. */ 465d885d199SRichard Tran Mills ierr = VecScatterDestroy(&shell->gtol);CHKERRQ(ierr); 46681634712SRichard Tran Mills shell->gtol = gtol; 46781634712SRichard Tran Mills PetscFunctionReturn(0); 46881634712SRichard Tran Mills } 46981634712SRichard Tran Mills 47081634712SRichard Tran Mills #undef __FUNCT__ 471988ea7d6SRichard Tran Mills #define __FUNCT__ "DMShellSetLocalToGlobalVecScatter" 472988ea7d6SRichard Tran Mills /*@ 473988ea7d6SRichard Tran Mills DMShellSetLocalToGlobalVecScatter - Sets a VecScatter context for local to global communication 474988ea7d6SRichard Tran Mills 475988ea7d6SRichard Tran Mills Logically Collective on DM 476988ea7d6SRichard Tran Mills 477988ea7d6SRichard Tran Mills Input Arguments 478988ea7d6SRichard Tran Mills + dm - the shell DM 479988ea7d6SRichard Tran Mills - ltog - the local to global VecScatter context 480988ea7d6SRichard Tran Mills 481988ea7d6SRichard Tran Mills Level: advanced 482988ea7d6SRichard Tran Mills 483988ea7d6SRichard Tran Mills .seealso: DMShellSetLocalToGlobal() 484988ea7d6SRichard Tran Mills @*/ 485a94b16f6SRichard Tran Mills PetscErrorCode DMShellSetLocalToGlobalVecScatter(DM dm, VecScatter ltog) 486988ea7d6SRichard Tran Mills { 487988ea7d6SRichard Tran Mills DM_Shell *shell = (DM_Shell*)dm->data; 488d885d199SRichard Tran Mills PetscErrorCode ierr; 489988ea7d6SRichard Tran Mills 490988ea7d6SRichard Tran Mills PetscFunctionBegin; 491d885d199SRichard Tran Mills ierr = PetscObjectReference((PetscObject)ltog);CHKERRQ(ierr); 492d885d199SRichard Tran Mills /* Call VecScatterDestroy() to avoid a memory leak in case of re-setting. */ 493d885d199SRichard Tran Mills ierr = VecScatterDestroy(&shell->ltog);CHKERRQ(ierr); 494988ea7d6SRichard Tran Mills shell->ltog = ltog; 495988ea7d6SRichard Tran Mills PetscFunctionReturn(0); 496988ea7d6SRichard Tran Mills } 497988ea7d6SRichard Tran Mills 498988ea7d6SRichard Tran Mills #undef __FUNCT__ 499fe1899a2SJed Brown #define __FUNCT__ "DMDestroy_Shell" 500fe1899a2SJed Brown static PetscErrorCode DMDestroy_Shell(DM dm) 501fe1899a2SJed Brown { 502fe1899a2SJed Brown PetscErrorCode ierr; 503fe1899a2SJed Brown DM_Shell *shell = (DM_Shell*)dm->data; 504fe1899a2SJed Brown 505fe1899a2SJed Brown PetscFunctionBegin; 506fe1899a2SJed Brown ierr = MatDestroy(&shell->A);CHKERRQ(ierr); 507fe1899a2SJed Brown ierr = VecDestroy(&shell->Xglobal);CHKERRQ(ierr); 508dc43b69eSJed Brown ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr); 509a94b16f6SRichard Tran Mills ierr = VecScatterDestroy(&shell->gtol);CHKERRQ(ierr); 510a94b16f6SRichard Tran Mills ierr = VecScatterDestroy(&shell->ltog);CHKERRQ(ierr); 5117b6ad80cSMatthew G Knepley /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */ 5127b6ad80cSMatthew G Knepley ierr = PetscFree(shell);CHKERRQ(ierr); 513fe1899a2SJed Brown PetscFunctionReturn(0); 514fe1899a2SJed Brown } 515fe1899a2SJed Brown 5162d53ad75SBarry Smith #undef __FUNCT__ 5172d53ad75SBarry Smith #define __FUNCT__ "DMView_Shell" 5182d53ad75SBarry Smith static PetscErrorCode DMView_Shell(DM dm,PetscViewer v) 5192d53ad75SBarry Smith { 5202d53ad75SBarry Smith PetscErrorCode ierr; 5212d53ad75SBarry Smith DM_Shell *shell = (DM_Shell*)dm->data; 5222d53ad75SBarry Smith 5232d53ad75SBarry Smith PetscFunctionBegin; 5242d53ad75SBarry Smith ierr = VecView(shell->Xglobal,v);CHKERRQ(ierr); 5252d53ad75SBarry Smith PetscFunctionReturn(0); 5262d53ad75SBarry Smith } 5272d53ad75SBarry Smith 5282d53ad75SBarry Smith #undef __FUNCT__ 5292d53ad75SBarry Smith #define __FUNCT__ "DMLoad_Shell" 5302d53ad75SBarry Smith static PetscErrorCode DMLoad_Shell(DM dm,PetscViewer v) 5312d53ad75SBarry Smith { 5322d53ad75SBarry Smith PetscErrorCode ierr; 5332d53ad75SBarry Smith DM_Shell *shell = (DM_Shell*)dm->data; 5342d53ad75SBarry Smith 5352d53ad75SBarry Smith PetscFunctionBegin; 536ce94432eSBarry Smith ierr = VecCreate(PetscObjectComm((PetscObject)dm),&shell->Xglobal);CHKERRQ(ierr); 5372d53ad75SBarry Smith ierr = VecLoad(shell->Xglobal,v);CHKERRQ(ierr); 5382d53ad75SBarry Smith PetscFunctionReturn(0); 5392d53ad75SBarry Smith } 540fe1899a2SJed Brown 541fe1899a2SJed Brown #undef __FUNCT__ 542fe1899a2SJed Brown #define __FUNCT__ "DMCreate_Shell" 5438cc058d9SJed Brown PETSC_EXTERN PetscErrorCode DMCreate_Shell(DM dm) 544fe1899a2SJed Brown { 545fe1899a2SJed Brown PetscErrorCode ierr; 546fe1899a2SJed Brown DM_Shell *shell; 547fe1899a2SJed Brown 548fe1899a2SJed Brown PetscFunctionBegin; 5498c87107bSJed Brown ierr = PetscNewLog(dm,DM_Shell,&shell);CHKERRQ(ierr); 5508c87107bSJed Brown dm->data = shell; 551fe1899a2SJed Brown 5528c87107bSJed Brown ierr = PetscObjectChangeTypeName((PetscObject)dm,DMSHELL);CHKERRQ(ierr); 5538865f1eaSKarl Rupp 5548c87107bSJed Brown dm->ops->destroy = DMDestroy_Shell; 5558c87107bSJed Brown dm->ops->createglobalvector = DMCreateGlobalVector_Shell; 556dc43b69eSJed Brown dm->ops->createlocalvector = DMCreateLocalVector_Shell; 5578c87107bSJed Brown dm->ops->creatematrix = DMCreateMatrix_Shell; 5582d53ad75SBarry Smith dm->ops->view = DMView_Shell; 5592d53ad75SBarry Smith dm->ops->load = DMLoad_Shell; 5607a108d1dSBarry Smith dm->ops->globaltolocalbegin = DMGlobalToLocalBeginDefaultShell; 5617a108d1dSBarry Smith dm->ops->globaltolocalend = DMGlobalToLocalEndDefaultShell; 56255daaa54SRichard Tran Mills dm->ops->localtoglobalbegin = DMLocalToGlobalBeginDefaultShell; 56355daaa54SRichard Tran Mills dm->ops->localtoglobalend = DMLocalToGlobalEndDefaultShell; 564fe1899a2SJed Brown PetscFunctionReturn(0); 565fe1899a2SJed Brown } 566fe1899a2SJed Brown 567fe1899a2SJed Brown #undef __FUNCT__ 568fe1899a2SJed Brown #define __FUNCT__ "DMShellCreate" 569fe1899a2SJed Brown /*@ 570fe1899a2SJed Brown DMShellCreate - Creates a shell DM object, used to manage user-defined problem data 571fe1899a2SJed Brown 572fe1899a2SJed Brown Collective on MPI_Comm 573fe1899a2SJed Brown 574fe1899a2SJed Brown Input Parameter: 575fe1899a2SJed Brown . comm - the processors that will share the global vector 576fe1899a2SJed Brown 577fe1899a2SJed Brown Output Parameters: 578fe1899a2SJed Brown . shell - the shell DM 579fe1899a2SJed Brown 580fe1899a2SJed Brown Level: advanced 581fe1899a2SJed Brown 582dc43b69eSJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateLocalVector() 583fe1899a2SJed Brown @*/ 584fe1899a2SJed Brown PetscErrorCode DMShellCreate(MPI_Comm comm,DM *dm) 585fe1899a2SJed Brown { 586fe1899a2SJed Brown PetscErrorCode ierr; 587fe1899a2SJed Brown 588fe1899a2SJed Brown PetscFunctionBegin; 589fe1899a2SJed Brown PetscValidPointer(dm,2); 590fe1899a2SJed Brown ierr = DMCreate(comm,dm);CHKERRQ(ierr); 591fe1899a2SJed Brown ierr = DMSetType(*dm,DMSHELL);CHKERRQ(ierr); 592fe1899a2SJed Brown PetscFunctionReturn(0); 593fe1899a2SJed Brown } 59481634712SRichard Tran Mills 595