1 #include <petsc-private/snesimpl.h> /*I "petscsnes.h" I*/ 2 #include <petsc-private/dmimpl.h> /*I "petscdm.h" I*/ 3 4 #undef __FUNCT__ 5 #define __FUNCT__ "DMSNESDestroy" 6 static PetscErrorCode DMSNESDestroy(DMSNES *kdm) 7 { 8 PetscErrorCode ierr; 9 10 PetscFunctionBegin; 11 if (!*kdm) PetscFunctionReturn(0); 12 PetscValidHeaderSpecific((*kdm),DMSNES_CLASSID,1); 13 if (--((PetscObject)(*kdm))->refct > 0) {*kdm = 0; PetscFunctionReturn(0);} 14 if ((*kdm)->ops->destroy) {ierr = ((*kdm)->ops->destroy)(*kdm);CHKERRQ(ierr);} 15 ierr = PetscHeaderDestroy(kdm);CHKERRQ(ierr); 16 PetscFunctionReturn(0); 17 } 18 19 #undef __FUNCT__ 20 #define __FUNCT__ "DMSNESLoad" 21 PetscErrorCode DMSNESLoad(DMSNES kdm,PetscViewer viewer) 22 { 23 PetscInt num = 1; 24 PetscErrorCode ierr; 25 26 PetscFunctionBegin; 27 ierr = PetscViewerBinaryRead(viewer,&kdm->ops->computefunction,&num,PETSC_FUNCTION);CHKERRQ(ierr); 28 ierr = PetscViewerBinaryRead(viewer,&kdm->ops->computejacobian,&num,PETSC_FUNCTION);CHKERRQ(ierr); 29 PetscFunctionReturn(0); 30 } 31 32 #undef __FUNCT__ 33 #define __FUNCT__ "DMSNESView" 34 PetscErrorCode DMSNESView(DMSNES kdm,PetscViewer viewer) 35 { 36 PetscErrorCode ierr; 37 PetscBool isascii,isbinary; 38 39 PetscFunctionBegin; 40 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 41 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 42 if (isascii) { 43 #if defined(PETSC_SERIALIZE_FUNCTIONS) 44 const char *fname; 45 46 ierr = PetscFPTFind(kdm->ops->computefunction,&fname);CHKERRQ(ierr); 47 if (fname) { 48 ierr = PetscViewerASCIIPrintf(viewer,"Function used by SNES: %s\n",fname);CHKERRQ(ierr); 49 } 50 ierr = PetscFPTFind(kdm->ops->computejacobian,&fname);CHKERRQ(ierr); 51 if (fname) { 52 ierr = PetscViewerASCIIPrintf(viewer,"Jacobian function used by SNES: %s\n",fname);CHKERRQ(ierr); 53 } 54 #endif 55 } else if (isbinary) { 56 struct { 57 PetscErrorCode (*func)(SNES,Vec,Vec,void*); 58 } funcstruct; 59 struct { 60 PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*); 61 } jacstruct; 62 funcstruct.func = kdm->ops->computefunction; 63 jacstruct.jac = kdm->ops->computejacobian; 64 ierr = PetscViewerBinaryWrite(viewer,&funcstruct,1,PETSC_FUNCTION,PETSC_FALSE);CHKERRQ(ierr); 65 ierr = PetscViewerBinaryWrite(viewer,&jacstruct,1,PETSC_FUNCTION,PETSC_FALSE);CHKERRQ(ierr); 66 } 67 PetscFunctionReturn(0); 68 } 69 70 #undef __FUNCT__ 71 #define __FUNCT__ "DMSNESCreate" 72 static PetscErrorCode DMSNESCreate(MPI_Comm comm,DMSNES *kdm) 73 { 74 PetscErrorCode ierr; 75 76 PetscFunctionBegin; 77 ierr = SNESInitializePackage();CHKERRQ(ierr); 78 ierr = PetscHeaderCreate(*kdm, _p_DMSNES, struct _DMSNESOps, DMSNES_CLASSID, "DMSNES", "DMSNES", "DMSNES", comm, DMSNESDestroy, DMSNESView);CHKERRQ(ierr); 79 ierr = PetscMemzero((*kdm)->ops, sizeof(struct _DMSNESOps));CHKERRQ(ierr); 80 PetscFunctionReturn(0); 81 } 82 83 #undef __FUNCT__ 84 #define __FUNCT__ "DMCoarsenHook_DMSNES" 85 /* Attaches the DMSNES to the coarse level. 86 * Under what conditions should we copy versus duplicate? 87 */ 88 static PetscErrorCode DMCoarsenHook_DMSNES(DM dm,DM dmc,void *ctx) 89 { 90 PetscErrorCode ierr; 91 92 PetscFunctionBegin; 93 ierr = DMCopyDMSNES(dm,dmc);CHKERRQ(ierr); 94 PetscFunctionReturn(0); 95 } 96 97 #undef __FUNCT__ 98 #define __FUNCT__ "DMRestrictHook_DMSNES" 99 /* This could restrict auxiliary information to the coarse level. 100 */ 101 static PetscErrorCode DMRestrictHook_DMSNES(DM dm,Mat Restrict,Vec rscale,Mat Inject,DM dmc,void *ctx) 102 { 103 104 PetscFunctionBegin; 105 PetscFunctionReturn(0); 106 } 107 108 #undef __FUNCT__ 109 #define __FUNCT__ "DMSubDomainHook_DMSNES" 110 /* Attaches the DMSNES to the subdomain. */ 111 static PetscErrorCode DMSubDomainHook_DMSNES(DM dm,DM subdm,void *ctx) 112 { 113 PetscErrorCode ierr; 114 115 PetscFunctionBegin; 116 ierr = DMCopyDMSNES(dm,subdm);CHKERRQ(ierr); 117 PetscFunctionReturn(0); 118 } 119 120 #undef __FUNCT__ 121 #define __FUNCT__ "DMSubDomainRestrictHook_DMSNES" 122 /* This could restrict auxiliary information to the coarse level. 123 */ 124 static PetscErrorCode DMSubDomainRestrictHook_DMSNES(DM dm,VecScatter gscat,VecScatter lscat,DM subdm,void *ctx) 125 { 126 127 PetscFunctionBegin; 128 PetscFunctionReturn(0); 129 } 130 131 #undef __FUNCT__ 132 #define __FUNCT__ "DMRefineHook_DMSNES" 133 static PetscErrorCode DMRefineHook_DMSNES(DM dm,DM dmf,void *ctx) 134 { 135 PetscErrorCode ierr; 136 137 PetscFunctionBegin; 138 ierr = DMCopyDMSNES(dm,dmf);CHKERRQ(ierr); 139 PetscFunctionReturn(0); 140 } 141 142 #undef __FUNCT__ 143 #define __FUNCT__ "DMInterpolateHook_DMSNES" 144 /* This could restrict auxiliary information to the coarse level. 145 */ 146 static PetscErrorCode DMInterpolateHook_DMSNES(DM dm,Mat Interp,DM dmf,void *ctx) 147 { 148 149 PetscFunctionBegin; 150 PetscFunctionReturn(0); 151 } 152 153 #undef __FUNCT__ 154 #define __FUNCT__ "DMSNESCopy" 155 /*@C 156 DMSNESCopy - copies the information in a DMSNES to another DMSNES 157 158 Not Collective 159 160 Input Argument: 161 + kdm - Original DMSNES 162 - nkdm - DMSNES to receive the data, should have been created with DMSNESCreate() 163 164 Level: developer 165 166 .seealso: DMSNESCreate(), DMSNESDestroy() 167 @*/ 168 PetscErrorCode DMSNESCopy(DMSNES kdm,DMSNES nkdm) 169 { 170 PetscErrorCode ierr; 171 172 PetscFunctionBegin; 173 PetscValidHeaderSpecific(kdm,DMSNES_CLASSID,1); 174 PetscValidHeaderSpecific(nkdm,DMSNES_CLASSID,2); 175 nkdm->ops->computefunction = kdm->ops->computefunction; 176 nkdm->ops->computejacobian = kdm->ops->computejacobian; 177 nkdm->ops->computegs = kdm->ops->computegs; 178 nkdm->ops->computeobjective = kdm->ops->computeobjective; 179 nkdm->ops->computepjacobian = kdm->ops->computepjacobian; 180 nkdm->ops->computepfunction = kdm->ops->computepfunction; 181 nkdm->ops->destroy = kdm->ops->destroy; 182 nkdm->ops->duplicate = kdm->ops->duplicate; 183 184 nkdm->functionctx = kdm->functionctx; 185 nkdm->gsctx = kdm->gsctx; 186 nkdm->pctx = kdm->pctx; 187 nkdm->jacobianctx = kdm->jacobianctx; 188 nkdm->objectivectx = kdm->objectivectx; 189 nkdm->data = kdm->data; 190 191 /* 192 nkdm->fortran_func_pointers[0] = kdm->fortran_func_pointers[0]; 193 nkdm->fortran_func_pointers[1] = kdm->fortran_func_pointers[1]; 194 nkdm->fortran_func_pointers[2] = kdm->fortran_func_pointers[2]; 195 */ 196 197 /* implementation specific copy hooks */ 198 if (kdm->ops->duplicate) {ierr = (*kdm->ops->duplicate)(kdm,nkdm);CHKERRQ(ierr);} 199 PetscFunctionReturn(0); 200 } 201 202 #undef __FUNCT__ 203 #define __FUNCT__ "DMGetDMSNES" 204 /*@C 205 DMGetDMSNES - get read-only private DMSNES context from a DM 206 207 Not Collective 208 209 Input Argument: 210 . dm - DM to be used with SNES 211 212 Output Argument: 213 . snesdm - private DMSNES context 214 215 Level: developer 216 217 Notes: 218 Use DMGetDMSNESWrite() if write access is needed. The DMSNESSetXXX API should be used wherever possible. 219 220 .seealso: DMGetDMSNESWrite() 221 @*/ 222 PetscErrorCode DMGetDMSNES(DM dm,DMSNES *snesdm) 223 { 224 PetscErrorCode ierr; 225 226 PetscFunctionBegin; 227 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 228 *snesdm = (DMSNES) dm->dmsnes; 229 if (!*snesdm) { 230 ierr = PetscInfo(dm,"Creating new DMSNES\n");CHKERRQ(ierr); 231 ierr = DMSNESCreate(PetscObjectComm((PetscObject)dm),snesdm);CHKERRQ(ierr); 232 233 dm->dmsnes = (PetscObject) *snesdm; 234 235 ierr = DMCoarsenHookAdd(dm,DMCoarsenHook_DMSNES,DMRestrictHook_DMSNES,NULL);CHKERRQ(ierr); 236 ierr = DMRefineHookAdd(dm,DMRefineHook_DMSNES,DMInterpolateHook_DMSNES,NULL);CHKERRQ(ierr); 237 ierr = DMSubDomainHookAdd(dm,DMSubDomainHook_DMSNES,DMSubDomainRestrictHook_DMSNES,NULL);CHKERRQ(ierr); 238 } 239 PetscFunctionReturn(0); 240 } 241 242 #undef __FUNCT__ 243 #define __FUNCT__ "DMGetDMSNESWrite" 244 /*@C 245 DMGetDMSNESWrite - get write access to private DMSNES context from a DM 246 247 Not Collective 248 249 Input Argument: 250 . dm - DM to be used with SNES 251 252 Output Argument: 253 . snesdm - private DMSNES context 254 255 Level: developer 256 257 .seealso: DMGetDMSNES() 258 @*/ 259 PetscErrorCode DMGetDMSNESWrite(DM dm,DMSNES *snesdm) 260 { 261 PetscErrorCode ierr; 262 DMSNES sdm; 263 264 PetscFunctionBegin; 265 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 266 ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 267 if (!sdm->originaldm) sdm->originaldm = dm; 268 if (sdm->originaldm != dm) { /* Copy on write */ 269 DMSNES oldsdm = sdm; 270 ierr = PetscInfo(dm,"Copying DMSNES due to write\n");CHKERRQ(ierr); 271 ierr = DMSNESCreate(PetscObjectComm((PetscObject)dm),&sdm);CHKERRQ(ierr); 272 ierr = DMSNESCopy(oldsdm,sdm);CHKERRQ(ierr); 273 ierr = DMSNESDestroy((DMSNES*)&dm->dmsnes);CHKERRQ(ierr); 274 dm->dmsnes = (PetscObject)sdm; 275 } 276 *snesdm = sdm; 277 PetscFunctionReturn(0); 278 } 279 280 #undef __FUNCT__ 281 #define __FUNCT__ "DMCopyDMSNES" 282 /*@C 283 DMCopyDMSNES - copies a DM context to a new DM 284 285 Logically Collective 286 287 Input Arguments: 288 + dmsrc - DM to obtain context from 289 - dmdest - DM to add context to 290 291 Level: developer 292 293 Note: 294 The context is copied by reference. This function does not ensure that a context exists. 295 296 .seealso: DMGetDMSNES(), SNESSetDM() 297 @*/ 298 PetscErrorCode DMCopyDMSNES(DM dmsrc,DM dmdest) 299 { 300 PetscErrorCode ierr; 301 302 PetscFunctionBegin; 303 PetscValidHeaderSpecific(dmsrc,DM_CLASSID,1); 304 PetscValidHeaderSpecific(dmdest,DM_CLASSID,2); 305 if (!dmdest->dmsnes) {ierr = DMSNESCreate(PetscObjectComm((PetscObject) dmdest), (DMSNES *) &dmdest->dmsnes);CHKERRQ(ierr);} 306 ierr = DMSNESCopy((DMSNES) dmsrc->dmsnes, (DMSNES) dmdest->dmsnes);CHKERRQ(ierr); 307 ierr = DMCoarsenHookAdd(dmdest,DMCoarsenHook_DMSNES,NULL,NULL);CHKERRQ(ierr); 308 ierr = DMRefineHookAdd(dmdest,DMRefineHook_DMSNES,NULL,NULL);CHKERRQ(ierr); 309 ierr = DMSubDomainHookAdd(dmdest,DMSubDomainHook_DMSNES,DMSubDomainRestrictHook_DMSNES,NULL);CHKERRQ(ierr); 310 PetscFunctionReturn(0); 311 } 312 313 #undef __FUNCT__ 314 #define __FUNCT__ "DMSNESSetFunction" 315 /*@C 316 DMSNESSetFunction - set SNES residual evaluation function 317 318 Not Collective 319 320 Input Arguments: 321 + dm - DM to be used with SNES 322 . f - residual evaluation function; see SNESFunction for details 323 - ctx - context for residual evaluation 324 325 Level: advanced 326 327 Note: 328 SNESSetFunction() is normally used, but it calls this function internally because the user context is actually 329 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 330 not. If DM took a more central role at some later date, this could become the primary method of setting the residual. 331 332 .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESSetJacobian(), SNESFunction 333 @*/ 334 PetscErrorCode DMSNESSetFunction(DM dm,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx) 335 { 336 PetscErrorCode ierr; 337 DMSNES sdm; 338 339 PetscFunctionBegin; 340 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 341 if (f || ctx) { 342 ierr = DMGetDMSNESWrite(dm,&sdm);CHKERRQ(ierr); 343 } 344 if (f) sdm->ops->computefunction = f; 345 if (ctx) sdm->functionctx = ctx; 346 PetscFunctionReturn(0); 347 } 348 349 #undef __FUNCT__ 350 #define __FUNCT__ "DMSNESGetFunction" 351 /*@C 352 DMSNESGetFunction - get SNES residual evaluation function 353 354 Not Collective 355 356 Input Argument: 357 . dm - DM to be used with SNES 358 359 Output Arguments: 360 + f - residual evaluation function; see SNESFunction for details 361 - ctx - context for residual evaluation 362 363 Level: advanced 364 365 Note: 366 SNESGetFunction() is normally used, but it calls this function internally because the user context is actually 367 associated with the DM. 368 369 .seealso: DMSNESSetContext(), DMSNESSetFunction(), SNESSetFunction(), SNESFunction 370 @*/ 371 PetscErrorCode DMSNESGetFunction(DM dm,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx) 372 { 373 PetscErrorCode ierr; 374 DMSNES sdm; 375 376 PetscFunctionBegin; 377 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 378 ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 379 if (f) *f = sdm->ops->computefunction; 380 if (ctx) *ctx = sdm->functionctx; 381 PetscFunctionReturn(0); 382 } 383 384 #undef __FUNCT__ 385 #define __FUNCT__ "DMSNESSetObjective" 386 /*@C 387 DMSNESSetObjective - set SNES objective evaluation function 388 389 Not Collective 390 391 Input Arguments: 392 + dm - DM to be used with SNES 393 . obj - objective evaluation function; see SNESObjectiveFunction for details 394 - ctx - context for residual evaluation 395 396 Level: advanced 397 398 .seealso: DMSNESSetContext(), SNESGetObjective(), DMSNESSetFunction() 399 @*/ 400 PetscErrorCode DMSNESSetObjective(DM dm,PetscErrorCode (*obj)(SNES,Vec,PetscReal*,void*),void *ctx) 401 { 402 PetscErrorCode ierr; 403 DMSNES sdm; 404 405 PetscFunctionBegin; 406 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 407 if (obj || ctx) { 408 ierr = DMGetDMSNESWrite(dm,&sdm);CHKERRQ(ierr); 409 } 410 if (obj) sdm->ops->computeobjective = obj; 411 if (ctx) sdm->objectivectx = ctx; 412 PetscFunctionReturn(0); 413 } 414 415 #undef __FUNCT__ 416 #define __FUNCT__ "DMSNESGetObjective" 417 /*@C 418 DMSNESGetObjective - get SNES objective evaluation function 419 420 Not Collective 421 422 Input Argument: 423 . dm - DM to be used with SNES 424 425 Output Arguments: 426 + obj- residual evaluation function; see SNESObjectiveFunction for details 427 - ctx - context for residual evaluation 428 429 Level: advanced 430 431 Note: 432 SNESGetFunction() is normally used, but it calls this function internally because the user context is actually 433 associated with the DM. 434 435 .seealso: DMSNESSetContext(), DMSNESSetObjective(), SNESSetFunction() 436 @*/ 437 PetscErrorCode DMSNESGetObjective(DM dm,PetscErrorCode (**obj)(SNES,Vec,PetscReal*,void*),void **ctx) 438 { 439 PetscErrorCode ierr; 440 DMSNES sdm; 441 442 PetscFunctionBegin; 443 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 444 ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 445 if (obj) *obj = sdm->ops->computeobjective; 446 if (ctx) *ctx = sdm->objectivectx; 447 PetscFunctionReturn(0); 448 } 449 450 #undef __FUNCT__ 451 #define __FUNCT__ "DMSNESSetNGS" 452 /*@C 453 DMSNESSetNGS - set SNES Gauss-Seidel relaxation function 454 455 Not Collective 456 457 Input Argument: 458 + dm - DM to be used with SNES 459 . f - relaxation function, see SNESGSFunction 460 - ctx - context for residual evaluation 461 462 Level: advanced 463 464 Note: 465 SNESSetNGS() is normally used, but it calls this function internally because the user context is actually 466 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 467 not. If DM took a more central role at some later date, this could become the primary method of setting the residual. 468 469 .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESSetJacobian(), DMSNESSetFunction(), SNESGSFunction 470 @*/ 471 PetscErrorCode DMSNESSetNGS(DM dm,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx) 472 { 473 PetscErrorCode ierr; 474 DMSNES sdm; 475 476 PetscFunctionBegin; 477 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 478 if (f || ctx) { 479 ierr = DMGetDMSNESWrite(dm,&sdm);CHKERRQ(ierr); 480 } 481 if (f) sdm->ops->computegs = f; 482 if (ctx) sdm->gsctx = ctx; 483 PetscFunctionReturn(0); 484 } 485 486 #undef __FUNCT__ 487 #define __FUNCT__ "DMSNESGetNGS" 488 /*@C 489 DMSNESGetNGS - get SNES Gauss-Seidel relaxation function 490 491 Not Collective 492 493 Input Argument: 494 . dm - DM to be used with SNES 495 496 Output Arguments: 497 + f - relaxation function which performs Gauss-Seidel sweeps, see SNESGSFunction 498 - ctx - context for residual evaluation 499 500 Level: advanced 501 502 Note: 503 SNESGetNGS() is normally used, but it calls this function internally because the user context is actually 504 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 505 not. If DM took a more central role at some later date, this could become the primary method of setting the residual. 506 507 .seealso: DMSNESSetContext(), SNESGetNGS(), DMSNESGetJacobian(), DMSNESGetFunction(), SNESNGSFunction 508 @*/ 509 PetscErrorCode DMSNESGetNGS(DM dm,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx) 510 { 511 PetscErrorCode ierr; 512 DMSNES sdm; 513 514 PetscFunctionBegin; 515 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 516 ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 517 if (f) *f = sdm->ops->computegs; 518 if (ctx) *ctx = sdm->gsctx; 519 PetscFunctionReturn(0); 520 } 521 522 #undef __FUNCT__ 523 #define __FUNCT__ "DMSNESSetJacobian" 524 /*@C 525 DMSNESSetJacobian - set SNES Jacobian evaluation function 526 527 Not Collective 528 529 Input Argument: 530 + dm - DM to be used with SNES 531 . J - Jacobian evaluation function 532 - ctx - context for residual evaluation 533 534 Level: advanced 535 536 Note: 537 SNESSetJacobian() is normally used, but it calls this function internally because the user context is actually 538 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 539 not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian. 540 541 .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESGetJacobian(), SNESSetJacobian(), SNESJacobianFunction 542 @*/ 543 PetscErrorCode DMSNESSetJacobian(DM dm,PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx) 544 { 545 PetscErrorCode ierr; 546 DMSNES sdm; 547 548 PetscFunctionBegin; 549 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 550 if (J || ctx) { 551 ierr = DMGetDMSNESWrite(dm,&sdm);CHKERRQ(ierr); 552 } 553 if (J) sdm->ops->computejacobian = J; 554 if (ctx) sdm->jacobianctx = ctx; 555 PetscFunctionReturn(0); 556 } 557 558 #undef __FUNCT__ 559 #define __FUNCT__ "DMSNESGetJacobian" 560 /*@C 561 DMSNESGetJacobian - get SNES Jacobian evaluation function 562 563 Not Collective 564 565 Input Argument: 566 . dm - DM to be used with SNES 567 568 Output Arguments: 569 + J - Jacobian evaluation function; see SNESJacobianFunction for all calling sequence 570 - ctx - context for residual evaluation 571 572 Level: advanced 573 574 Note: 575 SNESGetJacobian() is normally used, but it calls this function internally because the user context is actually 576 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 577 not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian. 578 579 .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESSetJacobian(), SNESJacobianFunction 580 @*/ 581 PetscErrorCode DMSNESGetJacobian(DM dm,PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx) 582 { 583 PetscErrorCode ierr; 584 DMSNES sdm; 585 586 PetscFunctionBegin; 587 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 588 ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 589 if (J) *J = sdm->ops->computejacobian; 590 if (ctx) *ctx = sdm->jacobianctx; 591 PetscFunctionReturn(0); 592 } 593 594 #undef __FUNCT__ 595 #define __FUNCT__ "DMSNESSetPicard" 596 /*@C 597 DMSNESSetPicard - set SNES Picard iteration matrix and RHS evaluation functions. 598 599 Not Collective 600 601 Input Argument: 602 + dm - DM to be used with SNES 603 . b - RHS evaluation function 604 . J - Picard matrix evaluation function 605 - ctx - context for residual evaluation 606 607 Level: advanced 608 609 .seealso: SNESSetPicard(), DMSNESSetFunction(), DMSNESSetJacobian() 610 @*/ 611 PetscErrorCode DMSNESSetPicard(DM dm,PetscErrorCode (*b)(SNES,Vec,Vec,void*),PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx) 612 { 613 PetscErrorCode ierr; 614 DMSNES sdm; 615 616 PetscFunctionBegin; 617 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 618 ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 619 if (b) sdm->ops->computepfunction = b; 620 if (J) sdm->ops->computepjacobian = J; 621 if (ctx) sdm->pctx = ctx; 622 PetscFunctionReturn(0); 623 } 624 625 #undef __FUNCT__ 626 #define __FUNCT__ "DMSNESGetPicard" 627 /*@C 628 DMSNESGetPicard - get SNES Picard iteration evaluation functions 629 630 Not Collective 631 632 Input Argument: 633 . dm - DM to be used with SNES 634 635 Output Arguments: 636 + b - RHS evaluation function; see SNESFunction for details 637 . J - RHS evaluation function; see SNESJacobianFunction for detailsa 638 - ctx - context for residual evaluation 639 640 Level: advanced 641 642 .seealso: DMSNESSetContext(), SNESSetFunction(), DMSNESSetJacobian() 643 @*/ 644 PetscErrorCode DMSNESGetPicard(DM dm,PetscErrorCode (**b)(SNES,Vec,Vec,void*),PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx) 645 { 646 PetscErrorCode ierr; 647 DMSNES sdm; 648 649 PetscFunctionBegin; 650 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 651 ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 652 if (b) *b = sdm->ops->computepfunction; 653 if (J) *J = sdm->ops->computepjacobian; 654 if (ctx) *ctx = sdm->pctx; 655 PetscFunctionReturn(0); 656 } 657