1b79b07cfSJed Brown 2af0996ceSBarry Smith #include <petsc/private/snesimpl.h> 3b79b07cfSJed Brown 4b79b07cfSJed Brown #undef __FUNCT__ 5b79b07cfSJed Brown #define __FUNCT__ "SNESSolve_KSPONLY" 6b79b07cfSJed Brown static PetscErrorCode SNESSolve_KSPONLY(SNES snes) 7b79b07cfSJed Brown { 8b79b07cfSJed Brown PetscErrorCode ierr; 9b79b07cfSJed Brown PetscInt lits; 10b79b07cfSJed Brown Vec Y,X,F; 11b79b07cfSJed Brown KSPConvergedReason kspreason; 12b79b07cfSJed Brown 13b79b07cfSJed Brown PetscFunctionBegin; 14*c579b300SPatrick Farrell 15*c579b300SPatrick Farrell if (snes->xl || snes->xu || snes->ops->computevariablebounds) { 16*c579b300SPatrick Farrell SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONGSTATE, "SNES solver %s does not support bounds", ((PetscObject)snes)->type_name); 17*c579b300SPatrick Farrell } 18*c579b300SPatrick Farrell 19b79b07cfSJed Brown snes->numFailures = 0; 20b79b07cfSJed Brown snes->numLinearSolveFailures = 0; 21b79b07cfSJed Brown snes->reason = SNES_CONVERGED_ITERATING; 22b79b07cfSJed Brown snes->iter = 0; 23b79b07cfSJed Brown snes->norm = 0.0; 24b79b07cfSJed Brown 25b79b07cfSJed Brown X = snes->vec_sol; 26b79b07cfSJed Brown F = snes->vec_func; 27b79b07cfSJed Brown Y = snes->vec_sol_update; 28b79b07cfSJed Brown 29b79b07cfSJed Brown ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr); 30b79b07cfSJed Brown if (snes->domainerror) { 31b79b07cfSJed Brown snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 32b79b07cfSJed Brown PetscFunctionReturn(0); 33b79b07cfSJed Brown } 34a5eaddd9SBarry Smith if (snes->numbermonitors) { 35a5eaddd9SBarry Smith PetscReal fnorm; 36a5eaddd9SBarry Smith ierr = VecNorm(F,NORM_2,&fnorm);CHKERRQ(ierr); 37a5eaddd9SBarry Smith ierr = SNESMonitor(snes,0,fnorm);CHKERRQ(ierr); 38a5eaddd9SBarry Smith } 39b79b07cfSJed Brown 405341784dSBarry Smith /* Call general purpose update function */ 415341784dSBarry Smith if (snes->ops->update) { 425341784dSBarry Smith ierr = (*snes->ops->update)(snes, 0);CHKERRQ(ierr); 435341784dSBarry Smith } 445341784dSBarry Smith 45b79b07cfSJed Brown /* Solve J Y = F, where J is Jacobian matrix */ 46d1e9a80fSBarry Smith ierr = SNESComputeJacobian(snes,X,snes->jacobian,snes->jacobian_pre);CHKERRQ(ierr); 4723ee1639SBarry Smith ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre);CHKERRQ(ierr); 48b79b07cfSJed Brown ierr = KSPSolve(snes->ksp,F,Y);CHKERRQ(ierr); 49b79b07cfSJed Brown ierr = KSPGetConvergedReason(snes->ksp,&kspreason);CHKERRQ(ierr); 50b79b07cfSJed Brown if (kspreason < 0 && ++snes->numLinearSolveFailures >= snes->maxLinearSolveFailures) { 51b79b07cfSJed Brown ierr = PetscInfo2(snes,"iter=%D, number linear solve failures %D greater than current SNES allowed, stopping solve\n",snes->iter,snes->numLinearSolveFailures);CHKERRQ(ierr); 52b79b07cfSJed Brown snes->reason = SNES_DIVERGED_LINEAR_SOLVE; 531aa26658SKarl Rupp } else snes->reason = SNES_CONVERGED_ITS; 541aa26658SKarl Rupp 55b79b07cfSJed Brown ierr = KSPGetIterationNumber(snes->ksp,&lits);CHKERRQ(ierr); 56b79b07cfSJed Brown snes->linear_its += lits; 57b79b07cfSJed Brown ierr = PetscInfo2(snes,"iter=%D, linear solve iterations=%D\n",snes->iter,lits);CHKERRQ(ierr); 58b79b07cfSJed Brown snes->iter++; 59b79b07cfSJed Brown 60b79b07cfSJed Brown /* Take the computed step. */ 61b79b07cfSJed Brown ierr = VecAXPY(X,-1.0,Y);CHKERRQ(ierr); 62a5eaddd9SBarry Smith if (snes->numbermonitors) { 63a5eaddd9SBarry Smith PetscReal fnorm; 64a5eaddd9SBarry Smith ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr); 65a5eaddd9SBarry Smith ierr = VecNorm(F,NORM_2,&fnorm);CHKERRQ(ierr); 66a5eaddd9SBarry Smith ierr = SNESMonitor(snes,1,fnorm);CHKERRQ(ierr); 67a5eaddd9SBarry Smith } 68b79b07cfSJed Brown PetscFunctionReturn(0); 69b79b07cfSJed Brown } 70b79b07cfSJed Brown 71b79b07cfSJed Brown #undef __FUNCT__ 72b79b07cfSJed Brown #define __FUNCT__ "SNESSetUp_KSPONLY" 73b79b07cfSJed Brown static PetscErrorCode SNESSetUp_KSPONLY(SNES snes) 74b79b07cfSJed Brown { 756cab3a1bSJed Brown PetscErrorCode ierr; 76b79b07cfSJed Brown 77b79b07cfSJed Brown PetscFunctionBegin; 786cab3a1bSJed Brown ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 79b79b07cfSJed Brown PetscFunctionReturn(0); 80b79b07cfSJed Brown } 81b79b07cfSJed Brown 82b79b07cfSJed Brown #undef __FUNCT__ 83b79b07cfSJed Brown #define __FUNCT__ "SNESDestroy_KSPONLY" 84b79b07cfSJed Brown static PetscErrorCode SNESDestroy_KSPONLY(SNES snes) 85b79b07cfSJed Brown { 86b79b07cfSJed Brown 87b79b07cfSJed Brown PetscFunctionBegin; 88b79b07cfSJed Brown PetscFunctionReturn(0); 89b79b07cfSJed Brown } 90b79b07cfSJed Brown 91b79b07cfSJed Brown /* -------------------------------------------------------------------------- */ 92b79b07cfSJed Brown /*MC 93b79b07cfSJed Brown SNESKSPONLY - Nonlinear solver that only performs one Newton step and does not compute any norms. 94b79b07cfSJed Brown The main purpose of this solver is to solve linear problems using the SNES interface, without 95b79b07cfSJed Brown any additional overhead in the form of vector operations. 96b79b07cfSJed Brown 97b79b07cfSJed Brown Level: beginner 98b79b07cfSJed Brown 9904d7464bSBarry Smith .seealso: SNESCreate(), SNES, SNESSetType(), SNESNEWTONLS, SNESNEWTONTR 100b79b07cfSJed Brown M*/ 101b79b07cfSJed Brown #undef __FUNCT__ 102b79b07cfSJed Brown #define __FUNCT__ "SNESCreate_KSPONLY" 1038cc058d9SJed Brown PETSC_EXTERN PetscErrorCode SNESCreate_KSPONLY(SNES snes) 104b79b07cfSJed Brown { 105b79b07cfSJed Brown 106b79b07cfSJed Brown PetscFunctionBegin; 107b79b07cfSJed Brown snes->ops->setup = SNESSetUp_KSPONLY; 108b79b07cfSJed Brown snes->ops->solve = SNESSolve_KSPONLY; 109b79b07cfSJed Brown snes->ops->destroy = SNESDestroy_KSPONLY; 11037596af1SLisandro Dalcin snes->ops->setfromoptions = 0; 11137596af1SLisandro Dalcin snes->ops->view = 0; 11237596af1SLisandro Dalcin snes->ops->reset = 0; 113b79b07cfSJed Brown 11442f4f86dSBarry Smith snes->usesksp = PETSC_TRUE; 11542f4f86dSBarry Smith snes->usespc = PETSC_FALSE; 11642f4f86dSBarry Smith 117b79b07cfSJed Brown snes->data = 0; 118b79b07cfSJed Brown PetscFunctionReturn(0); 119b79b07cfSJed Brown } 120