xref: /petsc/src/snes/interface/snespc.c (revision b7281c8a8dad9307a4edc7c93ebc34ff865e909f) !
1 
2 #include <petsc-private/snesimpl.h>      /*I "petscsnes.h"  I*/
3 #include <petscdmshell.h>
4 
5 
6 #undef __FUNCT__
7 #define __FUNCT__ "SNESApplyPC"
8 /*@
9    SNESApplyPC - Calls the function that has been set with SNESSetFunction().
10 
11    Collective on SNES
12 
13    Input Parameters:
14 +  snes - the SNES context
15 -  x - input vector
16 
17    Output Parameter:
18 .  y - function vector, as set by SNESSetFunction()
19 
20    Notes:
21    SNESComputeFunction() should be called on X before SNESApplyPC() is called, as it is
22    with SNESComuteJacobian().
23 
24    Level: developer
25 
26 .keywords: SNES, nonlinear, compute, function
27 
28 .seealso: SNESGetPC(),SNESSetPC(),SNESComputeFunction()
29 @*/
30 PetscErrorCode  SNESApplyPC(SNES snes,Vec x,Vec f,PetscReal *fnorm,Vec y)
31 {
32   PetscErrorCode ierr;
33 
34   PetscFunctionBegin;
35   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
37   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
38   PetscCheckSameComm(snes,1,x,2);
39   PetscCheckSameComm(snes,1,y,3);
40   ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);
41   if (snes->pc) {
42     if (f) {
43       ierr = SNESSetInitialFunction(snes->pc,f);CHKERRQ(ierr);
44     }
45     if (fnorm) {
46       ierr = SNESSetInitialFunctionNorm(snes->pc,*fnorm);CHKERRQ(ierr);
47     }
48     ierr = VecCopy(x,y);CHKERRQ(ierr);
49     ierr = PetscLogEventBegin(SNES_NPCSolve,snes->pc,x,y,0);CHKERRQ(ierr);
50     ierr = SNESSolve(snes->pc,snes->vec_rhs,y);CHKERRQ(ierr);
51     ierr = PetscLogEventEnd(SNES_NPCSolve,snes->pc,x,y,0);CHKERRQ(ierr);
52     ierr = VecAYPX(y,-1.0,x);CHKERRQ(ierr);
53     ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);
54     PetscFunctionReturn(0);
55   }
56   ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);
57   PetscFunctionReturn(0);
58 }
59 
60 #undef __FUNCT__
61 #define __FUNCT__ "SNESComputeFunctionDefaultPC"
62 PetscErrorCode SNESComputeFunctionDefaultPC(SNES snes,Vec X,Vec F) {
63 /* This is to be used as an argument to SNESMF -- NOT as a "function" */
64   SNESConvergedReason reason;
65   PetscErrorCode      ierr;
66 
67   PetscFunctionBegin;
68   if (snes->pc) {
69     ierr = SNESApplyPC(snes,X,PETSC_NULL,PETSC_NULL,F);CHKERRQ(ierr);
70     ierr = SNESGetConvergedReason(snes->pc,&reason);CHKERRQ(ierr);
71     if (reason < 0  && reason != SNES_DIVERGED_MAX_IT) {
72       ierr = SNESSetFunctionDomainError(snes);CHKERRQ(ierr);
73     }
74   } else {
75     ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr);
76   }
77 PetscFunctionReturn(0);
78 }
79