xref: /petsc/src/snes/impls/vi/vi.c (revision 349187a76f6788aca31171b8126aac13961ee1c8)
1af0996ceSBarry Smith #include <petsc/private/snesimpl.h>  /*I "petscsnes.h" I*/
21e25c274SJed Brown #include <petscdm.h>
3d0af7cd3SBarry Smith 
4d0af7cd3SBarry Smith #undef __FUNCT__
52176524cSBarry Smith #define __FUNCT__ "SNESVISetComputeVariableBounds"
62176524cSBarry Smith /*@C
72176524cSBarry Smith    SNESVISetComputeVariableBounds - Sets a function that is called to compute the variable bounds
82176524cSBarry Smith 
92176524cSBarry Smith    Input parameter
102176524cSBarry Smith +  snes - the SNES context
112176524cSBarry Smith -  compute - computes the bounds
122176524cSBarry Smith 
132bd2b0e6SSatish Balay    Level: advanced
142176524cSBarry Smith 
15c1c3a0ecSBarry Smith .seealso:   SNESVISetVariableBounds()
16c1c3a0ecSBarry Smith 
17aab9d709SJed Brown @*/
1877cdaf69SJed Brown PetscErrorCode SNESVISetComputeVariableBounds(SNES snes, PetscErrorCode (*compute)(SNES,Vec,Vec))
192176524cSBarry Smith {
2061589011SJed Brown   PetscErrorCode ierr,(*f)(SNES,PetscErrorCode (*)(SNES,Vec,Vec));
212176524cSBarry Smith 
222176524cSBarry Smith   PetscFunctionBegin;
2361589011SJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
240005d66cSJed Brown   ierr = PetscObjectQueryFunction((PetscObject)snes,"SNESVISetComputeVariableBounds_C",&f);CHKERRQ(ierr);
2563cdc2bdSPatrick Farrell   if (!f) {
2663cdc2bdSPatrick Farrell     ierr = SNESVISetComputeVariableBounds_VI(snes,compute);CHKERRQ(ierr);
2763cdc2bdSPatrick Farrell   } else {
2861589011SJed Brown     ierr = PetscUseMethod(snes,"SNESVISetComputeVariableBounds_C",(SNES,PetscErrorCode (*)(SNES,Vec,Vec)),(snes,compute));CHKERRQ(ierr);
2963cdc2bdSPatrick Farrell   }
302176524cSBarry Smith   PetscFunctionReturn(0);
312176524cSBarry Smith }
322176524cSBarry Smith 
3361589011SJed Brown #undef __FUNCT__
3461589011SJed Brown #define __FUNCT__ "SNESVISetComputeVariableBounds_VI"
3561589011SJed Brown PetscErrorCode SNESVISetComputeVariableBounds_VI(SNES snes,SNESVIComputeVariableBoundsFunction compute)
3661589011SJed Brown {
3761589011SJed Brown   PetscFunctionBegin;
3861589011SJed Brown   snes->ops->computevariablebounds = compute;
3961589011SJed Brown   PetscFunctionReturn(0);
4061589011SJed Brown }
412176524cSBarry Smith 
423c0c59f3SBarry Smith /* --------------------------------------------------------------------------------------------------------*/
432b4ed282SShri Abhyankar 
449308c137SBarry Smith #undef __FUNCT__
45ffdf2a20SBarry Smith #define __FUNCT__ "SNESVIMonitorResidual"
46ffdf2a20SBarry Smith PetscErrorCode  SNESVIMonitorResidual(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
47ffdf2a20SBarry Smith {
48ffdf2a20SBarry Smith   PetscErrorCode ierr;
49ffdf2a20SBarry Smith   Vec            X, F, Finactive;
50ffdf2a20SBarry Smith   IS             isactive;
51ffdf2a20SBarry Smith   PetscViewer    viewer = (PetscViewer) dummy;
52ffdf2a20SBarry Smith 
53ffdf2a20SBarry Smith   PetscFunctionBegin;
54ffdf2a20SBarry Smith   ierr = SNESGetFunction(snes,&F,0,0);CHKERRQ(ierr);
55ffdf2a20SBarry Smith   ierr = SNESGetSolution(snes,&X);CHKERRQ(ierr);
5687e98922SBarry Smith   ierr = SNESVIGetActiveSetIS(snes,X,F,&isactive);CHKERRQ(ierr);
57ffdf2a20SBarry Smith   ierr = VecDuplicate(F,&Finactive);CHKERRQ(ierr);
58ffdf2a20SBarry Smith   ierr = VecCopy(F,Finactive);CHKERRQ(ierr);
5987e98922SBarry Smith   ierr = VecISSet(Finactive,isactive,0.0);CHKERRQ(ierr);
60de34d3e9SBarry Smith   ierr = ISDestroy(&isactive);CHKERRQ(ierr);
61ffdf2a20SBarry Smith   if (!viewer) {
62ffdf2a20SBarry Smith     viewer = PETSC_VIEWER_DRAW_(PetscObjectComm((PetscObject)snes));
63ffdf2a20SBarry Smith   }
6487e98922SBarry Smith   ierr = VecView(Finactive,viewer);CHKERRQ(ierr);
65ffdf2a20SBarry Smith   ierr = VecDestroy(&Finactive);CHKERRQ(ierr);
66ffdf2a20SBarry Smith   PetscFunctionReturn(0);
67ffdf2a20SBarry Smith }
68ffdf2a20SBarry Smith 
69ffdf2a20SBarry Smith #undef __FUNCT__
709308c137SBarry Smith #define __FUNCT__ "SNESMonitorVI"
717087cfbeSBarry Smith PetscErrorCode  SNESMonitorVI(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
729308c137SBarry Smith {
739308c137SBarry Smith   PetscErrorCode    ierr;
74ce94432eSBarry Smith   PetscViewer       viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes));
759308c137SBarry Smith   const PetscScalar *x,*xl,*xu,*f;
766fd67740SBarry Smith   PetscInt          i,n,act[2] = {0,0},fact[2],N;
776a9e2d46SJungho Lee   /* Number of components that actually hit the bounds (c.f. active variables) */
786a9e2d46SJungho Lee   PetscInt          act_bound[2] = {0,0},fact_bound[2];
79*349187a7SBarry Smith   PetscReal         rnorm,fnorm,zerotolerance = snes->vizerotolerance;
809d1809e2SSatish Balay   double            tmp;
819308c137SBarry Smith 
829308c137SBarry Smith   PetscFunctionBegin;
839308c137SBarry Smith   ierr = VecGetLocalSize(snes->vec_sol,&n);CHKERRQ(ierr);
846fd67740SBarry Smith   ierr = VecGetSize(snes->vec_sol,&N);CHKERRQ(ierr);
85c2fc9fa9SBarry Smith   ierr = VecGetArrayRead(snes->xl,&xl);CHKERRQ(ierr);
86c2fc9fa9SBarry Smith   ierr = VecGetArrayRead(snes->xu,&xu);CHKERRQ(ierr);
879308c137SBarry Smith   ierr = VecGetArrayRead(snes->vec_sol,&x);CHKERRQ(ierr);
883f731af5SBarry Smith   ierr = VecGetArrayRead(snes->vec_func,&f);CHKERRQ(ierr);
899308c137SBarry Smith 
909308c137SBarry Smith   rnorm = 0.0;
919308c137SBarry Smith   for (i=0; i<n; i++) {
92*349187a7SBarry Smith     if (((PetscRealPart(x[i]) > PetscRealPart(xl[i]) + zerotolerance || (PetscRealPart(f[i]) <= 0.0)) && ((PetscRealPart(x[i]) < PetscRealPart(xu[i]) - zerotolerance) || PetscRealPart(f[i]) >= 0.0))) rnorm += PetscRealPart(PetscConj(f[i])*f[i]);
93*349187a7SBarry Smith     else if (PetscRealPart(x[i]) <= PetscRealPart(xl[i]) + zerotolerance && PetscRealPart(f[i]) > 0.0) act[0]++;
94*349187a7SBarry Smith     else if (PetscRealPart(x[i]) >= PetscRealPart(xu[i]) - zerotolerance && PetscRealPart(f[i]) < 0.0) act[1]++;
95ce94432eSBarry Smith     else SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_PLIB,"Can never get here");
969308c137SBarry Smith   }
976a9e2d46SJungho Lee 
986a9e2d46SJungho Lee   for (i=0; i<n; i++) {
99*349187a7SBarry Smith     if (PetscRealPart(x[i]) <= PetscRealPart(xl[i]) + zerotolerance) act_bound[0]++;
100*349187a7SBarry Smith     else if (PetscRealPart(x[i]) >= PetscRealPart(xu[i]) - zerotolerance) act_bound[1]++;
1016a9e2d46SJungho Lee   }
1023f731af5SBarry Smith   ierr  = VecRestoreArrayRead(snes->vec_func,&f);CHKERRQ(ierr);
103c2fc9fa9SBarry Smith   ierr  = VecRestoreArrayRead(snes->xl,&xl);CHKERRQ(ierr);
104c2fc9fa9SBarry Smith   ierr  = VecRestoreArrayRead(snes->xu,&xu);CHKERRQ(ierr);
1059308c137SBarry Smith   ierr  = VecRestoreArrayRead(snes->vec_sol,&x);CHKERRQ(ierr);
106ce94432eSBarry Smith   ierr  = MPI_Allreduce(&rnorm,&fnorm,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)snes));CHKERRQ(ierr);
107ce94432eSBarry Smith   ierr  = MPI_Allreduce(act,fact,2,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)snes));CHKERRQ(ierr);
108ce94432eSBarry Smith   ierr  = MPI_Allreduce(act_bound,fact_bound,2,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)snes));CHKERRQ(ierr);
109f137e44dSBarry Smith   fnorm = PetscSqrtReal(fnorm);
1106fd67740SBarry Smith 
111649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
1129d1809e2SSatish Balay   if (snes->ntruebounds) tmp = ((double)(fact[0]+fact[1]))/((double)snes->ntruebounds);
1139d1809e2SSatish Balay   else tmp = 0.0;
1149d1809e2SSatish Balay   ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES VI Function norm %14.12e Active lower constraints %D/%D upper constraints %D/%D Percent of total %g Percent of bounded %g\n",its,(double)fnorm,fact[0],fact_bound[0],fact[1],fact_bound[1],((double)(fact[0]+fact[1]))/((double)N),tmp);CHKERRQ(ierr);
1156a9e2d46SJungho Lee 
116649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
1179308c137SBarry Smith   PetscFunctionReturn(0);
1189308c137SBarry Smith }
1199308c137SBarry Smith 
1202b4ed282SShri Abhyankar /*
1212b4ed282SShri Abhyankar      Checks if J^T F = 0 which implies we've found a local minimum of the norm of the function,
1222b4ed282SShri Abhyankar     || F(u) ||_2 but not a zero, F(u) = 0. In the case when one cannot compute J^T F we use the fact that
1232b4ed282SShri Abhyankar     0 = (J^T F)^T W = F^T J W iff W not in the null space of J. Thanks for Jorge More
1242b4ed282SShri Abhyankar     for this trick. One assumes that the probability that W is in the null space of J is very, very small.
1252b4ed282SShri Abhyankar */
1262b4ed282SShri Abhyankar #undef __FUNCT__
1272b4ed282SShri Abhyankar #define __FUNCT__ "SNESVICheckLocalMin_Private"
128ace3abfcSBarry Smith PetscErrorCode SNESVICheckLocalMin_Private(SNES snes,Mat A,Vec F,Vec W,PetscReal fnorm,PetscBool *ismin)
1292b4ed282SShri Abhyankar {
1302b4ed282SShri Abhyankar   PetscReal      a1;
1312b4ed282SShri Abhyankar   PetscErrorCode ierr;
132ace3abfcSBarry Smith   PetscBool      hastranspose;
1332b4ed282SShri Abhyankar 
1342b4ed282SShri Abhyankar   PetscFunctionBegin;
1352b4ed282SShri Abhyankar   *ismin = PETSC_FALSE;
1362b4ed282SShri Abhyankar   ierr   = MatHasOperation(A,MATOP_MULT_TRANSPOSE,&hastranspose);CHKERRQ(ierr);
1372b4ed282SShri Abhyankar   if (hastranspose) {
1382b4ed282SShri Abhyankar     /* Compute || J^T F|| */
1392b4ed282SShri Abhyankar     ierr = MatMultTranspose(A,F,W);CHKERRQ(ierr);
1402b4ed282SShri Abhyankar     ierr = VecNorm(W,NORM_2,&a1);CHKERRQ(ierr);
1414839bfe8SBarry Smith     ierr = PetscInfo1(snes,"|| J^T F|| %g near zero implies found a local minimum\n",(double)(a1/fnorm));CHKERRQ(ierr);
1422b4ed282SShri Abhyankar     if (a1/fnorm < 1.e-4) *ismin = PETSC_TRUE;
1432b4ed282SShri Abhyankar   } else {
1442b4ed282SShri Abhyankar     Vec         work;
1452b4ed282SShri Abhyankar     PetscScalar result;
1462b4ed282SShri Abhyankar     PetscReal   wnorm;
1472b4ed282SShri Abhyankar 
1480298fd71SBarry Smith     ierr = VecSetRandom(W,NULL);CHKERRQ(ierr);
1492b4ed282SShri Abhyankar     ierr = VecNorm(W,NORM_2,&wnorm);CHKERRQ(ierr);
1502b4ed282SShri Abhyankar     ierr = VecDuplicate(W,&work);CHKERRQ(ierr);
1512b4ed282SShri Abhyankar     ierr = MatMult(A,W,work);CHKERRQ(ierr);
1522b4ed282SShri Abhyankar     ierr = VecDot(F,work,&result);CHKERRQ(ierr);
1536bf464f9SBarry Smith     ierr = VecDestroy(&work);CHKERRQ(ierr);
1542b4ed282SShri Abhyankar     a1   = PetscAbsScalar(result)/(fnorm*wnorm);
1554839bfe8SBarry Smith     ierr = PetscInfo1(snes,"(F^T J random)/(|| F ||*||random|| %g near zero implies found a local minimum\n",(double)a1);CHKERRQ(ierr);
1562b4ed282SShri Abhyankar     if (a1 < 1.e-4) *ismin = PETSC_TRUE;
1572b4ed282SShri Abhyankar   }
1582b4ed282SShri Abhyankar   PetscFunctionReturn(0);
1592b4ed282SShri Abhyankar }
1602b4ed282SShri Abhyankar 
1612b4ed282SShri Abhyankar /*
1622b4ed282SShri Abhyankar      Checks if J^T(F - J*X) = 0
1632b4ed282SShri Abhyankar */
1642b4ed282SShri Abhyankar #undef __FUNCT__
1652b4ed282SShri Abhyankar #define __FUNCT__ "SNESVICheckResidual_Private"
1662b4ed282SShri Abhyankar PetscErrorCode SNESVICheckResidual_Private(SNES snes,Mat A,Vec F,Vec X,Vec W1,Vec W2)
1672b4ed282SShri Abhyankar {
1682b4ed282SShri Abhyankar   PetscReal      a1,a2;
1692b4ed282SShri Abhyankar   PetscErrorCode ierr;
170ace3abfcSBarry Smith   PetscBool      hastranspose;
1712b4ed282SShri Abhyankar 
1722b4ed282SShri Abhyankar   PetscFunctionBegin;
1732b4ed282SShri Abhyankar   ierr = MatHasOperation(A,MATOP_MULT_TRANSPOSE,&hastranspose);CHKERRQ(ierr);
1742b4ed282SShri Abhyankar   if (hastranspose) {
1752b4ed282SShri Abhyankar     ierr = MatMult(A,X,W1);CHKERRQ(ierr);
1762b4ed282SShri Abhyankar     ierr = VecAXPY(W1,-1.0,F);CHKERRQ(ierr);
1772b4ed282SShri Abhyankar 
1782b4ed282SShri Abhyankar     /* Compute || J^T W|| */
1792b4ed282SShri Abhyankar     ierr = MatMultTranspose(A,W1,W2);CHKERRQ(ierr);
1802b4ed282SShri Abhyankar     ierr = VecNorm(W1,NORM_2,&a1);CHKERRQ(ierr);
1812b4ed282SShri Abhyankar     ierr = VecNorm(W2,NORM_2,&a2);CHKERRQ(ierr);
1822b4ed282SShri Abhyankar     if (a1 != 0.0) {
1834839bfe8SBarry Smith       ierr = PetscInfo1(snes,"||J^T(F-Ax)||/||F-AX|| %g near zero implies inconsistent rhs\n",(double)(a2/a1));CHKERRQ(ierr);
1842b4ed282SShri Abhyankar     }
1852b4ed282SShri Abhyankar   }
1862b4ed282SShri Abhyankar   PetscFunctionReturn(0);
1872b4ed282SShri Abhyankar }
1882b4ed282SShri Abhyankar 
1892b4ed282SShri Abhyankar /*
1908d359177SBarry Smith   SNESConvergedDefault_VI - Checks the convergence of the semismooth newton algorithm.
1912b4ed282SShri Abhyankar 
1922b4ed282SShri Abhyankar   Notes:
1932b4ed282SShri Abhyankar   The convergence criterion currently implemented is
1942b4ed282SShri Abhyankar   merit < abstol
1952b4ed282SShri Abhyankar   merit < rtol*merit_initial
1962b4ed282SShri Abhyankar */
1972b4ed282SShri Abhyankar #undef __FUNCT__
1988d359177SBarry Smith #define __FUNCT__ "SNESConvergedDefault_VI"
1998d359177SBarry Smith PetscErrorCode SNESConvergedDefault_VI(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gradnorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
2002b4ed282SShri Abhyankar {
2012b4ed282SShri Abhyankar   PetscErrorCode ierr;
2022b4ed282SShri Abhyankar 
2032b4ed282SShri Abhyankar   PetscFunctionBegin;
2042b4ed282SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2052b4ed282SShri Abhyankar   PetscValidPointer(reason,6);
2062b4ed282SShri Abhyankar 
2072b4ed282SShri Abhyankar   *reason = SNES_CONVERGED_ITERATING;
2082b4ed282SShri Abhyankar 
2092b4ed282SShri Abhyankar   if (!it) {
2102b4ed282SShri Abhyankar     /* set parameter for default relative tolerance convergence test */
2117fe79bc4SShri Abhyankar     snes->ttol = fnorm*snes->rtol;
2122b4ed282SShri Abhyankar   }
2137fe79bc4SShri Abhyankar   if (fnorm != fnorm) {
2142b4ed282SShri Abhyankar     ierr    = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
2152b4ed282SShri Abhyankar     *reason = SNES_DIVERGED_FNORM_NAN;
2167fe79bc4SShri Abhyankar   } else if (fnorm < snes->abstol) {
2174839bfe8SBarry Smith     ierr    = PetscInfo2(snes,"Converged due to function norm %g < %g\n",(double)fnorm,(double)snes->abstol);CHKERRQ(ierr);
2182b4ed282SShri Abhyankar     *reason = SNES_CONVERGED_FNORM_ABS;
2192b4ed282SShri Abhyankar   } else if (snes->nfuncs >= snes->max_funcs) {
2202b4ed282SShri Abhyankar     ierr    = PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);CHKERRQ(ierr);
2212b4ed282SShri Abhyankar     *reason = SNES_DIVERGED_FUNCTION_COUNT;
2222b4ed282SShri Abhyankar   }
2232b4ed282SShri Abhyankar 
2242b4ed282SShri Abhyankar   if (it && !*reason) {
2257fe79bc4SShri Abhyankar     if (fnorm < snes->ttol) {
2264839bfe8SBarry Smith       ierr    = PetscInfo2(snes,"Converged due to function norm %g < %g (relative tolerance)\n",(double)fnorm,(double)snes->ttol);CHKERRQ(ierr);
2272b4ed282SShri Abhyankar       *reason = SNES_CONVERGED_FNORM_RELATIVE;
2282b4ed282SShri Abhyankar     }
2292b4ed282SShri Abhyankar   }
2302b4ed282SShri Abhyankar   PetscFunctionReturn(0);
2312b4ed282SShri Abhyankar }
2322b4ed282SShri Abhyankar 
233ee657d29SShri Abhyankar 
234c1a5e521SShri Abhyankar /* -------------------------------------------------------------------------- */
235c1a5e521SShri Abhyankar /*
236c1a5e521SShri Abhyankar    SNESVIProjectOntoBounds - Projects X onto the feasible region so that Xl[i] <= X[i] <= Xu[i] for i = 1...n.
237c1a5e521SShri Abhyankar 
238c1a5e521SShri Abhyankar    Input Parameters:
239c1a5e521SShri Abhyankar .  SNES - nonlinear solver context
240c1a5e521SShri Abhyankar 
241c1a5e521SShri Abhyankar    Output Parameters:
242c1a5e521SShri Abhyankar .  X - Bound projected X
243c1a5e521SShri Abhyankar 
244c1a5e521SShri Abhyankar */
245c1a5e521SShri Abhyankar 
246c1a5e521SShri Abhyankar #undef __FUNCT__
247c1a5e521SShri Abhyankar #define __FUNCT__ "SNESVIProjectOntoBounds"
248c1a5e521SShri Abhyankar PetscErrorCode SNESVIProjectOntoBounds(SNES snes,Vec X)
249c1a5e521SShri Abhyankar {
250c1a5e521SShri Abhyankar   PetscErrorCode    ierr;
251c1a5e521SShri Abhyankar   const PetscScalar *xl,*xu;
252c1a5e521SShri Abhyankar   PetscScalar       *x;
253c1a5e521SShri Abhyankar   PetscInt          i,n;
254c1a5e521SShri Abhyankar 
255c1a5e521SShri Abhyankar   PetscFunctionBegin;
256c1a5e521SShri Abhyankar   ierr = VecGetLocalSize(X,&n);CHKERRQ(ierr);
257c1a5e521SShri Abhyankar   ierr = VecGetArray(X,&x);CHKERRQ(ierr);
258c2fc9fa9SBarry Smith   ierr = VecGetArrayRead(snes->xl,&xl);CHKERRQ(ierr);
259c2fc9fa9SBarry Smith   ierr = VecGetArrayRead(snes->xu,&xu);CHKERRQ(ierr);
260c1a5e521SShri Abhyankar 
261c1a5e521SShri Abhyankar   for (i = 0; i<n; i++) {
26210f5ae6bSBarry Smith     if (PetscRealPart(x[i]) < PetscRealPart(xl[i])) x[i] = xl[i];
26310f5ae6bSBarry Smith     else if (PetscRealPart(x[i]) > PetscRealPart(xu[i])) x[i] = xu[i];
264c1a5e521SShri Abhyankar   }
265c1a5e521SShri Abhyankar   ierr = VecRestoreArray(X,&x);CHKERRQ(ierr);
266c2fc9fa9SBarry Smith   ierr = VecRestoreArrayRead(snes->xl,&xl);CHKERRQ(ierr);
267c2fc9fa9SBarry Smith   ierr = VecRestoreArrayRead(snes->xu,&xu);CHKERRQ(ierr);
268c1a5e521SShri Abhyankar   PetscFunctionReturn(0);
269c1a5e521SShri Abhyankar }
270c1a5e521SShri Abhyankar 
27169c03620SShri Abhyankar 
27269c03620SShri Abhyankar #undef __FUNCT__
273693ddf92SShri Abhyankar #define __FUNCT__ "SNESVIGetActiveSetIS"
274693ddf92SShri Abhyankar /*
275693ddf92SShri Abhyankar    SNESVIGetActiveSetIndices - Gets the global indices for the active set variables
276693ddf92SShri Abhyankar 
277693ddf92SShri Abhyankar    Input parameter
278693ddf92SShri Abhyankar .  snes - the SNES context
279693ddf92SShri Abhyankar .  X    - the snes solution vector
280693ddf92SShri Abhyankar .  F    - the nonlinear function vector
281693ddf92SShri Abhyankar 
282693ddf92SShri Abhyankar    Output parameter
283693ddf92SShri Abhyankar .  ISact - active set index set
284693ddf92SShri Abhyankar  */
285693ddf92SShri Abhyankar PetscErrorCode SNESVIGetActiveSetIS(SNES snes,Vec X,Vec F,IS *ISact)
286d950fb63SShri Abhyankar {
287d950fb63SShri Abhyankar   PetscErrorCode    ierr;
288c2fc9fa9SBarry Smith   Vec               Xl=snes->xl,Xu=snes->xu;
289693ddf92SShri Abhyankar   const PetscScalar *x,*f,*xl,*xu;
290693ddf92SShri Abhyankar   PetscInt          *idx_act,i,nlocal,nloc_isact=0,ilow,ihigh,i1=0;
291*349187a7SBarry Smith   PetscReal         zerotolerance = snes->vizerotolerance;
292d950fb63SShri Abhyankar 
293d950fb63SShri Abhyankar   PetscFunctionBegin;
294d950fb63SShri Abhyankar   ierr = VecGetLocalSize(X,&nlocal);CHKERRQ(ierr);
295d950fb63SShri Abhyankar   ierr = VecGetOwnershipRange(X,&ilow,&ihigh);CHKERRQ(ierr);
296fe835674SShri Abhyankar   ierr = VecGetArrayRead(X,&x);CHKERRQ(ierr);
297fe835674SShri Abhyankar   ierr = VecGetArrayRead(Xl,&xl);CHKERRQ(ierr);
298fe835674SShri Abhyankar   ierr = VecGetArrayRead(Xu,&xu);CHKERRQ(ierr);
299fe835674SShri Abhyankar   ierr = VecGetArrayRead(F,&f);CHKERRQ(ierr);
300693ddf92SShri Abhyankar   /* Compute active set size */
301d950fb63SShri Abhyankar   for (i=0; i < nlocal;i++) {
302*349187a7SBarry Smith     if (!((PetscRealPart(x[i]) > PetscRealPart(xl[i]) + zerotolerance || (PetscRealPart(f[i]) <= 0.0)) && ((PetscRealPart(x[i]) < PetscRealPart(xu[i]) - zerotolerance) || PetscRealPart(f[i]) >= 0.0))) nloc_isact++;
303d950fb63SShri Abhyankar   }
304693ddf92SShri Abhyankar 
305785e854fSJed Brown   ierr = PetscMalloc1(nloc_isact,&idx_act);CHKERRQ(ierr);
306d950fb63SShri Abhyankar 
307693ddf92SShri Abhyankar   /* Set active set indices */
308d950fb63SShri Abhyankar   for (i=0; i < nlocal; i++) {
309*349187a7SBarry Smith     if (!((PetscRealPart(x[i]) > PetscRealPart(xl[i]) + zerotolerance || (PetscRealPart(f[i]) <= 0.0)) && ((PetscRealPart(x[i]) < PetscRealPart(xu[i]) - zerotolerance) || PetscRealPart(f[i]) >= 0.0))) idx_act[i1++] = ilow+i;
310d950fb63SShri Abhyankar   }
311d950fb63SShri Abhyankar 
312693ddf92SShri Abhyankar   /* Create active set IS */
313ce94432eSBarry Smith   ierr = ISCreateGeneral(PetscObjectComm((PetscObject)snes),nloc_isact,idx_act,PETSC_OWN_POINTER,ISact);CHKERRQ(ierr);
314d950fb63SShri Abhyankar 
315fe835674SShri Abhyankar   ierr = VecRestoreArrayRead(X,&x);CHKERRQ(ierr);
316fe835674SShri Abhyankar   ierr = VecRestoreArrayRead(Xl,&xl);CHKERRQ(ierr);
317fe835674SShri Abhyankar   ierr = VecRestoreArrayRead(Xu,&xu);CHKERRQ(ierr);
318fe835674SShri Abhyankar   ierr = VecRestoreArrayRead(F,&f);CHKERRQ(ierr);
319d950fb63SShri Abhyankar   PetscFunctionReturn(0);
320d950fb63SShri Abhyankar }
321d950fb63SShri Abhyankar 
322693ddf92SShri Abhyankar #undef __FUNCT__
323693ddf92SShri Abhyankar #define __FUNCT__ "SNESVICreateIndexSets_RS"
324693ddf92SShri Abhyankar PetscErrorCode SNESVICreateIndexSets_RS(SNES snes,Vec X,Vec F,IS *ISact,IS *ISinact)
325693ddf92SShri Abhyankar {
326693ddf92SShri Abhyankar   PetscErrorCode ierr;
327077aedafSJed Brown   PetscInt       rstart,rend;
328693ddf92SShri Abhyankar 
329693ddf92SShri Abhyankar   PetscFunctionBegin;
330693ddf92SShri Abhyankar   ierr = SNESVIGetActiveSetIS(snes,X,F,ISact);CHKERRQ(ierr);
331077aedafSJed Brown   ierr = VecGetOwnershipRange(X,&rstart,&rend);CHKERRQ(ierr);
332077aedafSJed Brown   ierr = ISComplement(*ISact,rstart,rend,ISinact);CHKERRQ(ierr);
333693ddf92SShri Abhyankar   PetscFunctionReturn(0);
334693ddf92SShri Abhyankar }
335693ddf92SShri Abhyankar 
336fe835674SShri Abhyankar #undef __FUNCT__
337fe835674SShri Abhyankar #define __FUNCT__ "SNESVIComputeInactiveSetFnorm"
33810f5ae6bSBarry Smith PetscErrorCode SNESVIComputeInactiveSetFnorm(SNES snes,Vec F,Vec X, PetscReal *fnorm)
339fe835674SShri Abhyankar {
340fe835674SShri Abhyankar   PetscErrorCode    ierr;
341fe835674SShri Abhyankar   const PetscScalar *x,*xl,*xu,*f;
342fe835674SShri Abhyankar   PetscInt          i,n;
343*349187a7SBarry Smith   PetscReal         rnorm,zerotolerance = snes->vizerotolerance;;
344fe835674SShri Abhyankar 
345fe835674SShri Abhyankar   PetscFunctionBegin;
346fe835674SShri Abhyankar   ierr  = VecGetLocalSize(X,&n);CHKERRQ(ierr);
347c2fc9fa9SBarry Smith   ierr  = VecGetArrayRead(snes->xl,&xl);CHKERRQ(ierr);
348c2fc9fa9SBarry Smith   ierr  = VecGetArrayRead(snes->xu,&xu);CHKERRQ(ierr);
349fe835674SShri Abhyankar   ierr  = VecGetArrayRead(X,&x);CHKERRQ(ierr);
350fe835674SShri Abhyankar   ierr  = VecGetArrayRead(F,&f);CHKERRQ(ierr);
351fe835674SShri Abhyankar   rnorm = 0.0;
352fe835674SShri Abhyankar   for (i=0; i<n; i++) {
353*349187a7SBarry Smith     if (((PetscRealPart(x[i]) > PetscRealPart(xl[i]) + zerotolerance || (PetscRealPart(f[i]) <= 0.0)) && ((PetscRealPart(x[i]) < PetscRealPart(xu[i]) - zerotolerance) || PetscRealPart(f[i]) >= 0.0))) rnorm += PetscRealPart(PetscConj(f[i])*f[i]);
3548f918527SKarl Rupp   }
355fe835674SShri Abhyankar   ierr   = VecRestoreArrayRead(F,&f);CHKERRQ(ierr);
356c2fc9fa9SBarry Smith   ierr   = VecRestoreArrayRead(snes->xl,&xl);CHKERRQ(ierr);
357c2fc9fa9SBarry Smith   ierr   = VecRestoreArrayRead(snes->xu,&xu);CHKERRQ(ierr);
358fe835674SShri Abhyankar   ierr   = VecRestoreArrayRead(X,&x);CHKERRQ(ierr);
359ce94432eSBarry Smith   ierr   = MPI_Allreduce(&rnorm,fnorm,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)snes));CHKERRQ(ierr);
36062d1f40fSBarry Smith   *fnorm = PetscSqrtReal(*fnorm);
361fe835674SShri Abhyankar   PetscFunctionReturn(0);
362fe835674SShri Abhyankar }
363fe835674SShri Abhyankar 
36408da532bSDmitry Karpeev #undef __FUNCT__
36508da532bSDmitry Karpeev #define __FUNCT__ "SNESVIDMComputeVariableBounds"
36608da532bSDmitry Karpeev PetscErrorCode SNESVIDMComputeVariableBounds(SNES snes,Vec xl, Vec xu)
36708da532bSDmitry Karpeev {
36808da532bSDmitry Karpeev   PetscErrorCode ierr;
3696e111a19SKarl Rupp 
37008da532bSDmitry Karpeev   PetscFunctionBegin;
37108da532bSDmitry Karpeev   ierr = DMComputeVariableBounds(snes->dm, xl, xu);CHKERRQ(ierr);
37208da532bSDmitry Karpeev   PetscFunctionReturn(0);
37308da532bSDmitry Karpeev }
37408da532bSDmitry Karpeev 
3752f63a38cSShri Abhyankar 
3762b4ed282SShri Abhyankar /* -------------------------------------------------------------------------- */
3772b4ed282SShri Abhyankar /*
378c2fc9fa9SBarry Smith    SNESSetUp_VI - Does setup common to all VI solvers -- basically makes sure bounds have been properly set up
3792b4ed282SShri Abhyankar    of the SNESVI nonlinear solver.
3802b4ed282SShri Abhyankar 
3812b4ed282SShri Abhyankar    Input Parameter:
3822b4ed282SShri Abhyankar .  snes - the SNES context
3832b4ed282SShri Abhyankar 
3842b4ed282SShri Abhyankar    Application Interface Routine: SNESSetUp()
3852b4ed282SShri Abhyankar 
3862b4ed282SShri Abhyankar    Notes:
3872b4ed282SShri Abhyankar    For basic use of the SNES solvers, the user need not explicitly call
3882b4ed282SShri Abhyankar    SNESSetUp(), since these actions will automatically occur during
3892b4ed282SShri Abhyankar    the call to SNESSolve().
3902b4ed282SShri Abhyankar  */
3912b4ed282SShri Abhyankar #undef __FUNCT__
3922b4ed282SShri Abhyankar #define __FUNCT__ "SNESSetUp_VI"
3932b4ed282SShri Abhyankar PetscErrorCode SNESSetUp_VI(SNES snes)
3942b4ed282SShri Abhyankar {
3952b4ed282SShri Abhyankar   PetscErrorCode ierr;
3962b4ed282SShri Abhyankar   PetscInt       i_start[3],i_end[3];
3972b4ed282SShri Abhyankar 
3982b4ed282SShri Abhyankar   PetscFunctionBegin;
399fa0ddf94SBarry Smith   ierr = SNESSetWorkVecs(snes,1);CHKERRQ(ierr);
4006cab3a1bSJed Brown   ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr);
4012b4ed282SShri Abhyankar 
40208da532bSDmitry Karpeev   if (!snes->ops->computevariablebounds && snes->dm) {
403a201590fSDmitry Karpeev     PetscBool flag;
404a201590fSDmitry Karpeev     ierr = DMHasVariableBounds(snes->dm, &flag);CHKERRQ(ierr);
4051aa26658SKarl Rupp 
40608da532bSDmitry Karpeev     snes->ops->computevariablebounds = SNESVIDMComputeVariableBounds;
40708da532bSDmitry Karpeev   }
408a201590fSDmitry Karpeev   if (!snes->usersetbounds) {
409c2fc9fa9SBarry Smith     if (snes->ops->computevariablebounds) {
410c2fc9fa9SBarry Smith       if (!snes->xl) {ierr = VecDuplicate(snes->vec_sol,&snes->xl);CHKERRQ(ierr);}
411c2fc9fa9SBarry Smith       if (!snes->xu) {ierr = VecDuplicate(snes->vec_sol,&snes->xu);CHKERRQ(ierr);}
412c2fc9fa9SBarry Smith       ierr = (*snes->ops->computevariablebounds)(snes,snes->xl,snes->xu);CHKERRQ(ierr);
4131aa26658SKarl Rupp     } else if (!snes->xl && !snes->xu) {
4142176524cSBarry Smith       /* If the lower and upper bound on variables are not set, set it to -Inf and Inf */
415c2fc9fa9SBarry Smith       ierr = VecDuplicate(snes->vec_sol, &snes->xl);CHKERRQ(ierr);
416e270355aSBarry Smith       ierr = VecSet(snes->xl,PETSC_NINFINITY);CHKERRQ(ierr);
417c2fc9fa9SBarry Smith       ierr = VecDuplicate(snes->vec_sol, &snes->xu);CHKERRQ(ierr);
418e270355aSBarry Smith       ierr = VecSet(snes->xu,PETSC_INFINITY);CHKERRQ(ierr);
4192b4ed282SShri Abhyankar     } else {
4202b4ed282SShri Abhyankar       /* Check if lower bound, upper bound and solution vector distribution across the processors is identical */
4212b4ed282SShri Abhyankar       ierr = VecGetOwnershipRange(snes->vec_sol,i_start,i_end);CHKERRQ(ierr);
422c2fc9fa9SBarry Smith       ierr = VecGetOwnershipRange(snes->xl,i_start+1,i_end+1);CHKERRQ(ierr);
423c2fc9fa9SBarry Smith       ierr = VecGetOwnershipRange(snes->xu,i_start+2,i_end+2);CHKERRQ(ierr);
4242b4ed282SShri Abhyankar       if ((i_start[0] != i_start[1]) || (i_start[0] != i_start[2]) || (i_end[0] != i_end[1]) || (i_end[0] != i_end[2]))
4252b4ed282SShri Abhyankar         SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Distribution of lower bound, upper bound and the solution vector should be identical across all the processors.");
4262b4ed282SShri Abhyankar     }
427a201590fSDmitry Karpeev   }
4282b4ed282SShri Abhyankar   PetscFunctionReturn(0);
4292b4ed282SShri Abhyankar }
4302b4ed282SShri Abhyankar /* -------------------------------------------------------------------------- */
4312176524cSBarry Smith #undef __FUNCT__
4322176524cSBarry Smith #define __FUNCT__ "SNESReset_VI"
4332176524cSBarry Smith PetscErrorCode SNESReset_VI(SNES snes)
4342176524cSBarry Smith {
4352176524cSBarry Smith   PetscErrorCode ierr;
4362176524cSBarry Smith 
4372176524cSBarry Smith   PetscFunctionBegin;
438c2fc9fa9SBarry Smith   ierr                = VecDestroy(&snes->xl);CHKERRQ(ierr);
439c2fc9fa9SBarry Smith   ierr                = VecDestroy(&snes->xu);CHKERRQ(ierr);
4402d6615e8SDmitry Karpeev   snes->usersetbounds = PETSC_FALSE;
4412176524cSBarry Smith   PetscFunctionReturn(0);
4422176524cSBarry Smith }
4432176524cSBarry Smith 
4442b4ed282SShri Abhyankar /*
4452b4ed282SShri Abhyankar    SNESDestroy_VI - Destroys the private SNES_VI context that was created
4462b4ed282SShri Abhyankar    with SNESCreate_VI().
4472b4ed282SShri Abhyankar 
4482b4ed282SShri Abhyankar    Input Parameter:
4492b4ed282SShri Abhyankar .  snes - the SNES context
4502b4ed282SShri Abhyankar 
4512b4ed282SShri Abhyankar    Application Interface Routine: SNESDestroy()
4522b4ed282SShri Abhyankar  */
4532b4ed282SShri Abhyankar #undef __FUNCT__
4542b4ed282SShri Abhyankar #define __FUNCT__ "SNESDestroy_VI"
4552b4ed282SShri Abhyankar PetscErrorCode SNESDestroy_VI(SNES snes)
4562b4ed282SShri Abhyankar {
4572b4ed282SShri Abhyankar   PetscErrorCode ierr;
4582b4ed282SShri Abhyankar 
4592b4ed282SShri Abhyankar   PetscFunctionBegin;
4602b4ed282SShri Abhyankar   ierr = PetscFree(snes->data);CHKERRQ(ierr);
4612b4ed282SShri Abhyankar 
4622b4ed282SShri Abhyankar   /* clear composed functions */
463bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)snes,"SNESLineSearchSet_C",NULL);CHKERRQ(ierr);
464bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)snes,"SNESLineSearchSetMonitor_C",NULL);CHKERRQ(ierr);
4652b4ed282SShri Abhyankar   PetscFunctionReturn(0);
4662b4ed282SShri Abhyankar }
4677fe79bc4SShri Abhyankar 
4685559b345SBarry Smith #undef __FUNCT__
4695559b345SBarry Smith #define __FUNCT__ "SNESVISetVariableBounds"
4705559b345SBarry Smith /*@
4712b4ed282SShri Abhyankar    SNESVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu.
4722b4ed282SShri Abhyankar 
4732b4ed282SShri Abhyankar    Input Parameters:
4742b4ed282SShri Abhyankar .  snes - the SNES context.
4752b4ed282SShri Abhyankar .  xl   - lower bound.
4762b4ed282SShri Abhyankar .  xu   - upper bound.
4772b4ed282SShri Abhyankar 
4782b4ed282SShri Abhyankar    Notes:
4792b4ed282SShri Abhyankar    If this routine is not called then the lower and upper bounds are set to
48029eed3a4SBarry Smith    PETSC_NINFINITY and PETSC_INFINITY respectively during SNESSetUp().
48184c105d7SBarry Smith 
4822bd2b0e6SSatish Balay    Level: advanced
4832bd2b0e6SSatish Balay 
4845559b345SBarry Smith @*/
48569c03620SShri Abhyankar PetscErrorCode SNESVISetVariableBounds(SNES snes, Vec xl, Vec xu)
4862b4ed282SShri Abhyankar {
48761589011SJed Brown   PetscErrorCode ierr,(*f)(SNES,Vec,Vec);
4882b4ed282SShri Abhyankar 
4892b4ed282SShri Abhyankar   PetscFunctionBegin;
4902b4ed282SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4912b4ed282SShri Abhyankar   PetscValidHeaderSpecific(xl,VEC_CLASSID,2);
4922b4ed282SShri Abhyankar   PetscValidHeaderSpecific(xu,VEC_CLASSID,3);
4930005d66cSJed Brown   ierr = PetscObjectQueryFunction((PetscObject)snes,"SNESVISetVariableBounds_C",&f);CHKERRQ(ierr);
49456e5e3feSPatrick Farrell   if (!f) {
49556e5e3feSPatrick Farrell     ierr = SNESVISetVariableBounds_VI(snes, xl, xu);CHKERRQ(ierr);
49656e5e3feSPatrick Farrell   } else {
49761589011SJed Brown     ierr = PetscUseMethod(snes,"SNESVISetVariableBounds_C",(SNES,Vec,Vec),(snes,xl,xu));CHKERRQ(ierr);
49856e5e3feSPatrick Farrell   }
499a201590fSDmitry Karpeev   snes->usersetbounds = PETSC_TRUE;
50061589011SJed Brown   PetscFunctionReturn(0);
50161589011SJed Brown }
50261589011SJed Brown 
50361589011SJed Brown #undef __FUNCT__
50461589011SJed Brown #define __FUNCT__ "SNESVISetVariableBounds_VI"
50561589011SJed Brown PetscErrorCode SNESVISetVariableBounds_VI(SNES snes,Vec xl,Vec xu)
50661589011SJed Brown {
50761589011SJed Brown   PetscErrorCode    ierr;
50861589011SJed Brown   const PetscScalar *xxl,*xxu;
50961589011SJed Brown   PetscInt          i,n, cnt = 0;
51061589011SJed Brown 
51161589011SJed Brown   PetscFunctionBegin;
5120298fd71SBarry Smith   ierr = SNESGetFunction(snes,&snes->vec_func,NULL,NULL);CHKERRQ(ierr);
513a63bb30eSJed Brown   if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() or SNESSetDM() first");
514077aedafSJed Brown   {
515077aedafSJed Brown     PetscInt xlN,xuN,N;
516077aedafSJed Brown     ierr = VecGetSize(xl,&xlN);CHKERRQ(ierr);
517077aedafSJed Brown     ierr = VecGetSize(xu,&xuN);CHKERRQ(ierr);
518077aedafSJed Brown     ierr = VecGetSize(snes->vec_func,&N);CHKERRQ(ierr);
519077aedafSJed Brown     if (xlN != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Incompatible vector lengths lower bound = %D solution vector = %D",xlN,N);
520077aedafSJed Brown     if (xuN != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Incompatible vector lengths: upper bound = %D solution vector = %D",xuN,N);
521077aedafSJed Brown   }
5222176524cSBarry Smith   ierr     = PetscObjectReference((PetscObject)xl);CHKERRQ(ierr);
5232176524cSBarry Smith   ierr     = PetscObjectReference((PetscObject)xu);CHKERRQ(ierr);
524c2fc9fa9SBarry Smith   ierr     = VecDestroy(&snes->xl);CHKERRQ(ierr);
525c2fc9fa9SBarry Smith   ierr     = VecDestroy(&snes->xu);CHKERRQ(ierr);
526c2fc9fa9SBarry Smith   snes->xl = xl;
527c2fc9fa9SBarry Smith   snes->xu = xu;
5286fd67740SBarry Smith   ierr     = VecGetLocalSize(xl,&n);CHKERRQ(ierr);
5296fd67740SBarry Smith   ierr     = VecGetArrayRead(xl,&xxl);CHKERRQ(ierr);
5306fd67740SBarry Smith   ierr     = VecGetArrayRead(xu,&xxu);CHKERRQ(ierr);
531e270355aSBarry Smith   for (i=0; i<n; i++) cnt += ((xxl[i] != PETSC_NINFINITY) || (xxu[i] != PETSC_INFINITY));
5321aa26658SKarl Rupp 
533ce94432eSBarry Smith   ierr = MPI_Allreduce(&cnt,&snes->ntruebounds,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)snes));CHKERRQ(ierr);
5346fd67740SBarry Smith   ierr = VecRestoreArrayRead(xl,&xxl);CHKERRQ(ierr);
5356fd67740SBarry Smith   ierr = VecRestoreArrayRead(xu,&xxu);CHKERRQ(ierr);
5362b4ed282SShri Abhyankar   PetscFunctionReturn(0);
5372b4ed282SShri Abhyankar }
53892c02d66SPeter Brune 
5392b4ed282SShri Abhyankar #undef __FUNCT__
540c2fc9fa9SBarry Smith #define __FUNCT__ "SNESSetFromOptions_VI"
5418c34d3f5SBarry Smith PetscErrorCode SNESSetFromOptions_VI(PetscOptions *PetscOptionsObject,SNES snes)
5422b4ed282SShri Abhyankar {
5432b4ed282SShri Abhyankar   PetscErrorCode ierr;
5448afaa268SBarry Smith   PetscBool      flg = PETSC_FALSE;
545639ea3faSPeter Brune   SNESLineSearch linesearch;
5462b4ed282SShri Abhyankar 
5472b4ed282SShri Abhyankar   PetscFunctionBegin;
548e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SNES VI options");CHKERRQ(ierr);
549*349187a7SBarry Smith   ierr = PetscOptionsReal("-snes_vi_zero_tolerance","Tolerance for considering x[] value to be on a bound","None",snes->vizerotolerance,&snes->vizerotolerance,NULL);CHKERRQ(ierr);
550ffdf2a20SBarry Smith   ierr = PetscOptionsBool("-snes_vi_monitor","Monitor all non-active variables","SNESMonitorResidual",flg,&flg,NULL);CHKERRQ(ierr);
551c2fc9fa9SBarry Smith   if (flg) {
552c2fc9fa9SBarry Smith     ierr = SNESMonitorSet(snes,SNESMonitorVI,0,0);CHKERRQ(ierr);
5532b4ed282SShri Abhyankar   }
554de34d3e9SBarry Smith   flg = PETSC_FALSE;
555ffdf2a20SBarry Smith   ierr = PetscOptionsBool("-snes_vi_monitor_residual","Monitor residual all non-active variables; using zero for active constraints","SNESMonitorVIResidual",flg,&flg,NULL);CHKERRQ(ierr);
556ffdf2a20SBarry Smith   if (flg) {
557ffdf2a20SBarry Smith     ierr = SNESMonitorSet(snes,SNESVIMonitorResidual,PETSC_VIEWER_DRAW_(PetscObjectComm((PetscObject)snes)),NULL);CHKERRQ(ierr);
558ffdf2a20SBarry Smith   }
559639ea3faSPeter Brune   if (!snes->linesearch) {
5607601faf0SJed Brown     ierr = SNESGetLineSearch(snes, &linesearch);CHKERRQ(ierr);
561639ea3faSPeter Brune     ierr = SNESLineSearchSetType(linesearch, SNESLINESEARCHBT);CHKERRQ(ierr);
562639ea3faSPeter Brune     ierr = SNESLineSearchBTSetAlpha(linesearch, 0.0);CHKERRQ(ierr);
563639ea3faSPeter Brune   }
564c2fc9fa9SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
565ed70e96aSJungho Lee   PetscFunctionReturn(0);
566ed70e96aSJungho Lee }
567