Commits

Peter Brune committed 25a90ac

Fixed the behavior of left-pc SNESes preconditioning right-pc SNESes.

Comments (0)

Files changed (5)

src/snes/impls/ls/ls.c

   PetscBool           domainerror;
   SNESLineSearch      linesearch;
   SNESConvergedReason reason;
+  PCSide              npcside;
 
   PetscFunctionBegin;
   snes->numFailures            = 0;
   snes->norm = 0.0;
   ierr       = PetscObjectAMSGrantAccess((PetscObject)snes);CHKERRQ(ierr);
   ierr       = SNESGetSNESLineSearch(snes, &linesearch);CHKERRQ(ierr);
-  if (!snes->vec_func_init_set) {
+  if (!snes->vec_func_init_set || snes->pcside != PC_RIGHT) {
     ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr);
     ierr = SNESGetFunctionDomainError(snes, &domainerror);CHKERRQ(ierr);
     if (domainerror) {
     }
   } else snes->vec_func_init_set = PETSC_FALSE;
 
-  if (!snes->norm_init_set) {
+  if (!snes->norm_init_set || snes->pcside != PC_RIGHT) {
     ierr = VecNormBegin(F,NORM_2,&fnorm);CHKERRQ(ierr);        /* fnorm <- ||F||  */
     ierr = VecNormEnd(F,NORM_2,&fnorm);CHKERRQ(ierr);
     if (PetscIsInfOrNanReal(fnorm)) {
         snes->reason = SNES_DIVERGED_INNER;
         PetscFunctionReturn(0);
       }
-      ierr = SNESGetFunction(snes->pc, &FPC, NULL, NULL);CHKERRQ(ierr);
-      ierr = VecCopy(FPC, F);CHKERRQ(ierr);
-      ierr = SNESGetFunctionNorm(snes->pc, &fnorm);CHKERRQ(ierr);
+      ierr = SNESGetPCSide(snes->pc,&npcside);CHKERRQ(ierr);
+      if (npcside == PC_RIGHT) {
+        ierr = SNESGetFunction(snes->pc, &FPC, NULL, NULL);CHKERRQ(ierr);
+        ierr = VecCopy(FPC, F);CHKERRQ(ierr);
+        ierr = SNESGetFunctionNorm(snes->pc, &fnorm);CHKERRQ(ierr);
+      } else {
+        ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr);
+        ierr = VecNorm(F,NORM_2,&fnorm);CHKERRQ(ierr);
+      }
     }
 
     /* Solve J Y = F, where J is Jacobian matrix */

src/snes/impls/ncg/snesncg.c

   ierr       = PetscObjectAMSGrantAccess((PetscObject)snes);CHKERRQ(ierr);
 
   /* compute the initial function and preconditioned update dX */
-  if (!snes->vec_func_init_set) {
+  if (!snes->vec_func_init_set || snes->pcside != PC_RIGHT) {
     ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr);
     if (snes->domainerror) {
       snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN;
     }
   } else snes->vec_func_init_set = PETSC_FALSE;
 
-  if (!snes->norm_init_set) {
+  if (!snes->norm_init_set || snes->pcside != PC_RIGHT) {
     /* convergence test */
     ierr = VecNorm(F, NORM_2, &fnorm);CHKERRQ(ierr); /* fnorm <- ||F||  */
     if (PetscIsInfOrNanReal(fnorm)) {

src/snes/impls/ngmres/snesngmres.c

 
   SNESConvergedReason reason;
   PetscBool           lssucceed;
+  PCSide              npcside;
   PetscErrorCode      ierr;
 
   PetscFunctionBegin;
   /* initialization */
 
   /* r = F(x) */
-  if (!snes->vec_func_init_set) {
+  if (!snes->vec_func_init_set || snes->pcside != PC_RIGHT) {
     ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr);
     if (snes->domainerror) {
       snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN;
     }
   } else snes->vec_func_init_set = PETSC_FALSE;
 
-  if (!snes->norm_init_set) {
+  if (!snes->norm_init_set || snes->pcside != PC_RIGHT) {
     ierr = VecNorm(F,NORM_2,&fnorm);CHKERRQ(ierr);
     if (PetscIsInfOrNanReal(fnorm)) {
       snes->reason = SNES_DIVERGED_FNORM_NAN;
         snes->reason = SNES_DIVERGED_INNER;
         PetscFunctionReturn(0);
       }
-      ierr = SNESGetFunction(snes->pc,&FPC,NULL,NULL);CHKERRQ(ierr);
-      ierr = VecCopy(FPC,FM);CHKERRQ(ierr);
-      ierr = SNESGetFunctionNorm(snes->pc,&fMnorm);CHKERRQ(ierr);
+      ierr = SNESGetPCSide(snes->pc,&npcside);CHKERRQ(ierr);
+      if (npcside == PC_RIGHT) {
+        ierr = SNESGetFunction(snes->pc,&FPC,NULL,NULL);CHKERRQ(ierr);
+        ierr = VecCopy(FPC,FM);CHKERRQ(ierr);
+        ierr = SNESGetFunctionNorm(snes->pc,&fMnorm);CHKERRQ(ierr);
+      } else {
+        ierr = SNESComputeFunction(snes,XM,FM);CHKERRQ(ierr);
+        ierr = VecNorm(FM,NORM_2,&fMnorm);CHKERRQ(ierr);
+      }
     } else {
       /* no preconditioner -- just take gradient descent with line search */
       ierr = VecCopy(F,Y);CHKERRQ(ierr);

src/snes/impls/qn/qn.c

   PetscBool           lssucceed,powell,periodic;
   PetscScalar         DolddotD,DolddotDold,DdotD,YdotD;
   MatStructure        flg = DIFFERENT_NONZERO_PATTERN;
+  PCSide              npcside;
 
   /* basically just a regular newton's method except for the application of the jacobian */
 
   snes->iter = 0;
   snes->norm = 0.;
   ierr       = PetscObjectAMSGrantAccess((PetscObject)snes);CHKERRQ(ierr);
-  if (!snes->vec_func_init_set) {
+  if (!snes->vec_func_init_set || snes->pcside != PC_RIGHT) {
     ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr);
     if (snes->domainerror) {
       snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN;
     }
   } else snes->vec_func_init_set = PETSC_FALSE;
 
-  if (!snes->norm_init_set) {
+  if (!snes->norm_init_set || snes->pcside != PC_RIGHT) {
     ierr = VecNorm(F, NORM_2, &fnorm);CHKERRQ(ierr); /* fnorm <- ||F||  */
     if (PetscIsInfOrNanReal(fnorm)) {
       snes->reason = SNES_DIVERGED_FNORM_NAN;
       snes->reason = SNES_DIVERGED_INNER;
       PetscFunctionReturn(0);
     }
-    ierr = SNESGetFunction(snes->pc, &FPC, NULL, NULL);CHKERRQ(ierr);
-    ierr = VecCopy(FPC, F);CHKERRQ(ierr);
-    ierr = SNESGetFunctionNorm(snes->pc, &fnorm);CHKERRQ(ierr);
+    ierr = SNESGetPCSide(snes->pc,&npcside);CHKERRQ(ierr);
+    if (npcside == PC_RIGHT) {
+      ierr = SNESGetFunction(snes->pc, &FPC, NULL, NULL);CHKERRQ(ierr);
+      ierr = VecCopy(FPC, F);CHKERRQ(ierr);
+      ierr = SNESGetFunctionNorm(snes->pc, &fnorm);CHKERRQ(ierr);
+    } else {
+      ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr);
+      ierr = VecNorm(F,NORM_2,&fnorm);CHKERRQ(ierr);
+    }
     ierr = VecCopy(F, Y);CHKERRQ(ierr);
   } else {
     ierr = VecCopy(F, Y);CHKERRQ(ierr);
         snes->reason = SNES_DIVERGED_INNER;
         PetscFunctionReturn(0);
       }
-      ierr = SNESGetFunction(snes->pc, &FPC, NULL, NULL);CHKERRQ(ierr);
-      ierr = VecCopy(FPC, F);CHKERRQ(ierr);
-      ierr = SNESGetFunctionNorm(snes->pc, &fnorm);CHKERRQ(ierr);
+      ierr = SNESGetPCSide(snes->pc,&npcside);CHKERRQ(ierr);
+      if (npcside == PC_RIGHT) {
+        ierr = SNESGetFunction(snes->pc, &FPC, NULL, NULL);CHKERRQ(ierr);
+        ierr = VecCopy(FPC, F);CHKERRQ(ierr);
+        ierr = SNESGetFunctionNorm(snes->pc, &fnorm);CHKERRQ(ierr);
+      } else {
+        ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr);
+        ierr = VecNorm(F,NORM_2,&fnorm);CHKERRQ(ierr);
+      }
       ierr = VecCopy(F, D);CHKERRQ(ierr);
     } else {
       ierr = VecCopy(F, D);CHKERRQ(ierr);

src/snes/impls/richardson/snesrichardson.c

   snes->iter = 0;
   snes->norm = 0.;
   ierr       = PetscObjectAMSGrantAccess((PetscObject)snes);CHKERRQ(ierr);
-  if (!snes->vec_func_init_set) {
+  if (!snes->vec_func_init_set || snes->pcside != PC_RIGHT) {
     ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr);
     if (snes->domainerror) {
       snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN;
     }
   } else snes->vec_func_init_set = PETSC_FALSE;
 
-  if (!snes->norm_init_set) {
+  if (!snes->norm_init_set || snes->pcside != PC_RIGHT) {
     ierr = VecNorm(F,NORM_2,&fnorm);CHKERRQ(ierr); /* fnorm <- ||F||  */
     if (PetscIsInfOrNanReal(fnorm)) {
       snes->reason = SNES_DIVERGED_FNORM_NAN;
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.