1639ea3faSPeter Brune #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); 25f450aa47SBarry Smith if (!f) {ierr = SNESSetType(snes,SNESVINEWTONRSLS);CHKERRQ(ierr);} 2661589011SJed Brown ierr = PetscUseMethod(snes,"SNESVISetComputeVariableBounds_C",(SNES,PetscErrorCode (*)(SNES,Vec,Vec)),(snes,compute));CHKERRQ(ierr); 272176524cSBarry Smith PetscFunctionReturn(0); 282176524cSBarry Smith } 292176524cSBarry Smith 3061589011SJed Brown #undef __FUNCT__ 3161589011SJed Brown #define __FUNCT__ "SNESVISetComputeVariableBounds_VI" 3261589011SJed Brown PetscErrorCode SNESVISetComputeVariableBounds_VI(SNES snes,SNESVIComputeVariableBoundsFunction compute) 3361589011SJed Brown { 3461589011SJed Brown PetscFunctionBegin; 3561589011SJed Brown snes->ops->computevariablebounds = compute; 3661589011SJed Brown PetscFunctionReturn(0); 3761589011SJed Brown } 382176524cSBarry Smith 392176524cSBarry Smith #undef __FUNCT__ 40ed70e96aSJungho Lee #define __FUNCT__ "SNESVIComputeInactiveSetIS" 41d0af7cd3SBarry Smith /* 42ed70e96aSJungho Lee SNESVIComputeInactiveSetIS - Gets the global indices for the bogus inactive set variables 43d0af7cd3SBarry Smith 44d0af7cd3SBarry Smith Input parameter 45d0af7cd3SBarry Smith . snes - the SNES context 46d0af7cd3SBarry Smith . X - the snes solution vector 47d0af7cd3SBarry Smith 48d0af7cd3SBarry Smith Output parameter 49d0af7cd3SBarry Smith . ISact - active set index set 50d0af7cd3SBarry Smith 51d0af7cd3SBarry Smith */ 52ed70e96aSJungho Lee PetscErrorCode SNESVIComputeInactiveSetIS(Vec upper,Vec lower,Vec X,Vec F,IS *inact) 53d0af7cd3SBarry Smith { 54d0af7cd3SBarry Smith PetscErrorCode ierr; 55d0af7cd3SBarry Smith const PetscScalar *x,*xl,*xu,*f; 56d0af7cd3SBarry Smith PetscInt *idx_act,i,nlocal,nloc_isact=0,ilow,ihigh,i1=0; 57d0af7cd3SBarry Smith 58d0af7cd3SBarry Smith PetscFunctionBegin; 59d0af7cd3SBarry Smith ierr = VecGetLocalSize(X,&nlocal);CHKERRQ(ierr); 60d0af7cd3SBarry Smith ierr = VecGetOwnershipRange(X,&ilow,&ihigh);CHKERRQ(ierr); 61d0af7cd3SBarry Smith ierr = VecGetArrayRead(X,&x);CHKERRQ(ierr); 62d0af7cd3SBarry Smith ierr = VecGetArrayRead(lower,&xl);CHKERRQ(ierr); 63d0af7cd3SBarry Smith ierr = VecGetArrayRead(upper,&xu);CHKERRQ(ierr); 64d0af7cd3SBarry Smith ierr = VecGetArrayRead(F,&f);CHKERRQ(ierr); 65d0af7cd3SBarry Smith /* Compute inactive set size */ 66d0af7cd3SBarry Smith for (i=0; i < nlocal; i++) { 67d0af7cd3SBarry Smith if (((PetscRealPart(x[i]) > PetscRealPart(xl[i]) + 1.e-8 || (PetscRealPart(f[i]) < 0.0)) && ((PetscRealPart(x[i]) < PetscRealPart(xu[i]) - 1.e-8) || PetscRealPart(f[i]) > 0.0))) nloc_isact++; 68d0af7cd3SBarry Smith } 69d0af7cd3SBarry Smith 70785e854fSJed Brown ierr = PetscMalloc1(nloc_isact,&idx_act);CHKERRQ(ierr); 71d0af7cd3SBarry Smith 72d0af7cd3SBarry Smith /* Set inactive set indices */ 73d0af7cd3SBarry Smith for (i=0; i < nlocal; i++) { 74d0af7cd3SBarry Smith if (((PetscRealPart(x[i]) > PetscRealPart(xl[i]) + 1.e-8 || (PetscRealPart(f[i]) < 0.0)) && ((PetscRealPart(x[i]) < PetscRealPart(xu[i]) - 1.e-8) || PetscRealPart(f[i]) > 0.0))) idx_act[i1++] = ilow+i; 75d0af7cd3SBarry Smith } 76d0af7cd3SBarry Smith 77d0af7cd3SBarry Smith /* Create inactive set IS */ 78ce94432eSBarry Smith ierr = ISCreateGeneral(PetscObjectComm((PetscObject)upper),nloc_isact,idx_act,PETSC_OWN_POINTER,inact);CHKERRQ(ierr); 79d0af7cd3SBarry Smith 80d0af7cd3SBarry Smith ierr = VecRestoreArrayRead(X,&x);CHKERRQ(ierr); 81d0af7cd3SBarry Smith ierr = VecRestoreArrayRead(lower,&xl);CHKERRQ(ierr); 82d0af7cd3SBarry Smith ierr = VecRestoreArrayRead(upper,&xu);CHKERRQ(ierr); 83d0af7cd3SBarry Smith ierr = VecRestoreArrayRead(F,&f);CHKERRQ(ierr); 84d0af7cd3SBarry Smith PetscFunctionReturn(0); 85d0af7cd3SBarry Smith } 86d0af7cd3SBarry Smith 873c0c59f3SBarry Smith /* --------------------------------------------------------------------------------------------------------*/ 882b4ed282SShri Abhyankar 899308c137SBarry Smith #undef __FUNCT__ 90ffdf2a20SBarry Smith #define __FUNCT__ "SNESVIMonitorResidual" 91ffdf2a20SBarry Smith PetscErrorCode SNESVIMonitorResidual(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 92ffdf2a20SBarry Smith { 93ffdf2a20SBarry Smith PetscErrorCode ierr; 94ffdf2a20SBarry Smith Vec X, F, Finactive; 95ffdf2a20SBarry Smith IS isactive; 96ffdf2a20SBarry Smith PetscViewer viewer = (PetscViewer) dummy; 97ffdf2a20SBarry Smith 98ffdf2a20SBarry Smith PetscFunctionBegin; 99ffdf2a20SBarry Smith ierr = SNESGetFunction(snes,&F,0,0);CHKERRQ(ierr); 100ffdf2a20SBarry Smith ierr = SNESGetSolution(snes,&X);CHKERRQ(ierr); 10187e98922SBarry Smith ierr = SNESVIGetActiveSetIS(snes,X,F,&isactive);CHKERRQ(ierr); 102ffdf2a20SBarry Smith ierr = VecDuplicate(F,&Finactive);CHKERRQ(ierr); 103ffdf2a20SBarry Smith ierr = VecCopy(F,Finactive);CHKERRQ(ierr); 10487e98922SBarry Smith ierr = VecISSet(Finactive,isactive,0.0);CHKERRQ(ierr); 105*de34d3e9SBarry Smith ierr = ISDestroy(&isactive);CHKERRQ(ierr); 106ffdf2a20SBarry Smith if (!viewer) { 107ffdf2a20SBarry Smith viewer = PETSC_VIEWER_DRAW_(PetscObjectComm((PetscObject)snes)); 108ffdf2a20SBarry Smith } 10987e98922SBarry Smith ierr = VecView(Finactive,viewer);CHKERRQ(ierr); 110ffdf2a20SBarry Smith ierr = VecDestroy(&Finactive);CHKERRQ(ierr); 111ffdf2a20SBarry Smith PetscFunctionReturn(0); 112ffdf2a20SBarry Smith } 113ffdf2a20SBarry Smith 114ffdf2a20SBarry Smith #undef __FUNCT__ 1159308c137SBarry Smith #define __FUNCT__ "SNESMonitorVI" 1167087cfbeSBarry Smith PetscErrorCode SNESMonitorVI(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 1179308c137SBarry Smith { 1189308c137SBarry Smith PetscErrorCode ierr; 119ce94432eSBarry Smith PetscViewer viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)); 1209308c137SBarry Smith const PetscScalar *x,*xl,*xu,*f; 1216fd67740SBarry Smith PetscInt i,n,act[2] = {0,0},fact[2],N; 1226a9e2d46SJungho Lee /* Number of components that actually hit the bounds (c.f. active variables) */ 1236a9e2d46SJungho Lee PetscInt act_bound[2] = {0,0},fact_bound[2]; 1249308c137SBarry Smith PetscReal rnorm,fnorm; 1259d1809e2SSatish Balay double tmp; 1269308c137SBarry Smith 1279308c137SBarry Smith PetscFunctionBegin; 1289308c137SBarry Smith ierr = VecGetLocalSize(snes->vec_sol,&n);CHKERRQ(ierr); 1296fd67740SBarry Smith ierr = VecGetSize(snes->vec_sol,&N);CHKERRQ(ierr); 130c2fc9fa9SBarry Smith ierr = VecGetArrayRead(snes->xl,&xl);CHKERRQ(ierr); 131c2fc9fa9SBarry Smith ierr = VecGetArrayRead(snes->xu,&xu);CHKERRQ(ierr); 1329308c137SBarry Smith ierr = VecGetArrayRead(snes->vec_sol,&x);CHKERRQ(ierr); 1333f731af5SBarry Smith ierr = VecGetArrayRead(snes->vec_func,&f);CHKERRQ(ierr); 1349308c137SBarry Smith 1359308c137SBarry Smith rnorm = 0.0; 1369308c137SBarry Smith for (i=0; i<n; i++) { 13710f5ae6bSBarry Smith if (((PetscRealPart(x[i]) > PetscRealPart(xl[i]) + 1.e-8 || (PetscRealPart(f[i]) < 0.0)) && ((PetscRealPart(x[i]) < PetscRealPart(xu[i]) - 1.e-8) || PetscRealPart(f[i]) > 0.0))) rnorm += PetscRealPart(PetscConj(f[i])*f[i]); 138e400df7aSBarry Smith else if (PetscRealPart(x[i]) <= PetscRealPart(xl[i]) + 1.e-8 && PetscRealPart(f[i]) >= 0.0) act[0]++; 139e400df7aSBarry Smith else if (PetscRealPart(x[i]) >= PetscRealPart(xu[i]) - 1.e-8 && PetscRealPart(f[i]) <= 0.0) act[1]++; 140ce94432eSBarry Smith else SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_PLIB,"Can never get here"); 1419308c137SBarry Smith } 1426a9e2d46SJungho Lee 1436a9e2d46SJungho Lee for (i=0; i<n; i++) { 1446a9e2d46SJungho Lee if (PetscRealPart(x[i]) <= PetscRealPart(xl[i]) + 1.e-8) act_bound[0]++; 1456a9e2d46SJungho Lee else if (PetscRealPart(x[i]) >= PetscRealPart(xu[i]) - 1.e-8) act_bound[1]++; 1466a9e2d46SJungho Lee } 1473f731af5SBarry Smith ierr = VecRestoreArrayRead(snes->vec_func,&f);CHKERRQ(ierr); 148c2fc9fa9SBarry Smith ierr = VecRestoreArrayRead(snes->xl,&xl);CHKERRQ(ierr); 149c2fc9fa9SBarry Smith ierr = VecRestoreArrayRead(snes->xu,&xu);CHKERRQ(ierr); 1509308c137SBarry Smith ierr = VecRestoreArrayRead(snes->vec_sol,&x);CHKERRQ(ierr); 151ce94432eSBarry Smith ierr = MPI_Allreduce(&rnorm,&fnorm,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)snes));CHKERRQ(ierr); 152ce94432eSBarry Smith ierr = MPI_Allreduce(act,fact,2,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)snes));CHKERRQ(ierr); 153ce94432eSBarry Smith ierr = MPI_Allreduce(act_bound,fact_bound,2,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)snes));CHKERRQ(ierr); 154f137e44dSBarry Smith fnorm = PetscSqrtReal(fnorm); 1556fd67740SBarry Smith 156649052a6SBarry Smith ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 1579d1809e2SSatish Balay if (snes->ntruebounds) tmp = ((double)(fact[0]+fact[1]))/((double)snes->ntruebounds); 1589d1809e2SSatish Balay else tmp = 0.0; 1599d1809e2SSatish 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); 1606a9e2d46SJungho Lee 161649052a6SBarry Smith ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 1629308c137SBarry Smith PetscFunctionReturn(0); 1639308c137SBarry Smith } 1649308c137SBarry Smith 1652b4ed282SShri Abhyankar /* 1662b4ed282SShri Abhyankar Checks if J^T F = 0 which implies we've found a local minimum of the norm of the function, 1672b4ed282SShri 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 1682b4ed282SShri Abhyankar 0 = (J^T F)^T W = F^T J W iff W not in the null space of J. Thanks for Jorge More 1692b4ed282SShri Abhyankar for this trick. One assumes that the probability that W is in the null space of J is very, very small. 1702b4ed282SShri Abhyankar */ 1712b4ed282SShri Abhyankar #undef __FUNCT__ 1722b4ed282SShri Abhyankar #define __FUNCT__ "SNESVICheckLocalMin_Private" 173ace3abfcSBarry Smith PetscErrorCode SNESVICheckLocalMin_Private(SNES snes,Mat A,Vec F,Vec W,PetscReal fnorm,PetscBool *ismin) 1742b4ed282SShri Abhyankar { 1752b4ed282SShri Abhyankar PetscReal a1; 1762b4ed282SShri Abhyankar PetscErrorCode ierr; 177ace3abfcSBarry Smith PetscBool hastranspose; 1782b4ed282SShri Abhyankar 1792b4ed282SShri Abhyankar PetscFunctionBegin; 1802b4ed282SShri Abhyankar *ismin = PETSC_FALSE; 1812b4ed282SShri Abhyankar ierr = MatHasOperation(A,MATOP_MULT_TRANSPOSE,&hastranspose);CHKERRQ(ierr); 1822b4ed282SShri Abhyankar if (hastranspose) { 1832b4ed282SShri Abhyankar /* Compute || J^T F|| */ 1842b4ed282SShri Abhyankar ierr = MatMultTranspose(A,F,W);CHKERRQ(ierr); 1852b4ed282SShri Abhyankar ierr = VecNorm(W,NORM_2,&a1);CHKERRQ(ierr); 1864839bfe8SBarry Smith ierr = PetscInfo1(snes,"|| J^T F|| %g near zero implies found a local minimum\n",(double)(a1/fnorm));CHKERRQ(ierr); 1872b4ed282SShri Abhyankar if (a1/fnorm < 1.e-4) *ismin = PETSC_TRUE; 1882b4ed282SShri Abhyankar } else { 1892b4ed282SShri Abhyankar Vec work; 1902b4ed282SShri Abhyankar PetscScalar result; 1912b4ed282SShri Abhyankar PetscReal wnorm; 1922b4ed282SShri Abhyankar 1930298fd71SBarry Smith ierr = VecSetRandom(W,NULL);CHKERRQ(ierr); 1942b4ed282SShri Abhyankar ierr = VecNorm(W,NORM_2,&wnorm);CHKERRQ(ierr); 1952b4ed282SShri Abhyankar ierr = VecDuplicate(W,&work);CHKERRQ(ierr); 1962b4ed282SShri Abhyankar ierr = MatMult(A,W,work);CHKERRQ(ierr); 1972b4ed282SShri Abhyankar ierr = VecDot(F,work,&result);CHKERRQ(ierr); 1986bf464f9SBarry Smith ierr = VecDestroy(&work);CHKERRQ(ierr); 1992b4ed282SShri Abhyankar a1 = PetscAbsScalar(result)/(fnorm*wnorm); 2004839bfe8SBarry Smith ierr = PetscInfo1(snes,"(F^T J random)/(|| F ||*||random|| %g near zero implies found a local minimum\n",(double)a1);CHKERRQ(ierr); 2012b4ed282SShri Abhyankar if (a1 < 1.e-4) *ismin = PETSC_TRUE; 2022b4ed282SShri Abhyankar } 2032b4ed282SShri Abhyankar PetscFunctionReturn(0); 2042b4ed282SShri Abhyankar } 2052b4ed282SShri Abhyankar 2062b4ed282SShri Abhyankar /* 2072b4ed282SShri Abhyankar Checks if J^T(F - J*X) = 0 2082b4ed282SShri Abhyankar */ 2092b4ed282SShri Abhyankar #undef __FUNCT__ 2102b4ed282SShri Abhyankar #define __FUNCT__ "SNESVICheckResidual_Private" 2112b4ed282SShri Abhyankar PetscErrorCode SNESVICheckResidual_Private(SNES snes,Mat A,Vec F,Vec X,Vec W1,Vec W2) 2122b4ed282SShri Abhyankar { 2132b4ed282SShri Abhyankar PetscReal a1,a2; 2142b4ed282SShri Abhyankar PetscErrorCode ierr; 215ace3abfcSBarry Smith PetscBool hastranspose; 2162b4ed282SShri Abhyankar 2172b4ed282SShri Abhyankar PetscFunctionBegin; 2182b4ed282SShri Abhyankar ierr = MatHasOperation(A,MATOP_MULT_TRANSPOSE,&hastranspose);CHKERRQ(ierr); 2192b4ed282SShri Abhyankar if (hastranspose) { 2202b4ed282SShri Abhyankar ierr = MatMult(A,X,W1);CHKERRQ(ierr); 2212b4ed282SShri Abhyankar ierr = VecAXPY(W1,-1.0,F);CHKERRQ(ierr); 2222b4ed282SShri Abhyankar 2232b4ed282SShri Abhyankar /* Compute || J^T W|| */ 2242b4ed282SShri Abhyankar ierr = MatMultTranspose(A,W1,W2);CHKERRQ(ierr); 2252b4ed282SShri Abhyankar ierr = VecNorm(W1,NORM_2,&a1);CHKERRQ(ierr); 2262b4ed282SShri Abhyankar ierr = VecNorm(W2,NORM_2,&a2);CHKERRQ(ierr); 2272b4ed282SShri Abhyankar if (a1 != 0.0) { 2284839bfe8SBarry Smith ierr = PetscInfo1(snes,"||J^T(F-Ax)||/||F-AX|| %g near zero implies inconsistent rhs\n",(double)(a2/a1));CHKERRQ(ierr); 2292b4ed282SShri Abhyankar } 2302b4ed282SShri Abhyankar } 2312b4ed282SShri Abhyankar PetscFunctionReturn(0); 2322b4ed282SShri Abhyankar } 2332b4ed282SShri Abhyankar 2342b4ed282SShri Abhyankar /* 2358d359177SBarry Smith SNESConvergedDefault_VI - Checks the convergence of the semismooth newton algorithm. 2362b4ed282SShri Abhyankar 2372b4ed282SShri Abhyankar Notes: 2382b4ed282SShri Abhyankar The convergence criterion currently implemented is 2392b4ed282SShri Abhyankar merit < abstol 2402b4ed282SShri Abhyankar merit < rtol*merit_initial 2412b4ed282SShri Abhyankar */ 2422b4ed282SShri Abhyankar #undef __FUNCT__ 2438d359177SBarry Smith #define __FUNCT__ "SNESConvergedDefault_VI" 2448d359177SBarry Smith PetscErrorCode SNESConvergedDefault_VI(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gradnorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy) 2452b4ed282SShri Abhyankar { 2462b4ed282SShri Abhyankar PetscErrorCode ierr; 2472b4ed282SShri Abhyankar 2482b4ed282SShri Abhyankar PetscFunctionBegin; 2492b4ed282SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2502b4ed282SShri Abhyankar PetscValidPointer(reason,6); 2512b4ed282SShri Abhyankar 2522b4ed282SShri Abhyankar *reason = SNES_CONVERGED_ITERATING; 2532b4ed282SShri Abhyankar 2542b4ed282SShri Abhyankar if (!it) { 2552b4ed282SShri Abhyankar /* set parameter for default relative tolerance convergence test */ 2567fe79bc4SShri Abhyankar snes->ttol = fnorm*snes->rtol; 2572b4ed282SShri Abhyankar } 2587fe79bc4SShri Abhyankar if (fnorm != fnorm) { 2592b4ed282SShri Abhyankar ierr = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr); 2602b4ed282SShri Abhyankar *reason = SNES_DIVERGED_FNORM_NAN; 2617fe79bc4SShri Abhyankar } else if (fnorm < snes->abstol) { 2624839bfe8SBarry Smith ierr = PetscInfo2(snes,"Converged due to function norm %g < %g\n",(double)fnorm,(double)snes->abstol);CHKERRQ(ierr); 2632b4ed282SShri Abhyankar *reason = SNES_CONVERGED_FNORM_ABS; 2642b4ed282SShri Abhyankar } else if (snes->nfuncs >= snes->max_funcs) { 2652b4ed282SShri Abhyankar ierr = PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);CHKERRQ(ierr); 2662b4ed282SShri Abhyankar *reason = SNES_DIVERGED_FUNCTION_COUNT; 2672b4ed282SShri Abhyankar } 2682b4ed282SShri Abhyankar 2692b4ed282SShri Abhyankar if (it && !*reason) { 2707fe79bc4SShri Abhyankar if (fnorm < snes->ttol) { 2714839bfe8SBarry Smith ierr = PetscInfo2(snes,"Converged due to function norm %g < %g (relative tolerance)\n",(double)fnorm,(double)snes->ttol);CHKERRQ(ierr); 2722b4ed282SShri Abhyankar *reason = SNES_CONVERGED_FNORM_RELATIVE; 2732b4ed282SShri Abhyankar } 2742b4ed282SShri Abhyankar } 2752b4ed282SShri Abhyankar PetscFunctionReturn(0); 2762b4ed282SShri Abhyankar } 2772b4ed282SShri Abhyankar 278ee657d29SShri Abhyankar 279c1a5e521SShri Abhyankar /* -------------------------------------------------------------------------- */ 280c1a5e521SShri Abhyankar /* 281c1a5e521SShri Abhyankar SNESVIProjectOntoBounds - Projects X onto the feasible region so that Xl[i] <= X[i] <= Xu[i] for i = 1...n. 282c1a5e521SShri Abhyankar 283c1a5e521SShri Abhyankar Input Parameters: 284c1a5e521SShri Abhyankar . SNES - nonlinear solver context 285c1a5e521SShri Abhyankar 286c1a5e521SShri Abhyankar Output Parameters: 287c1a5e521SShri Abhyankar . X - Bound projected X 288c1a5e521SShri Abhyankar 289c1a5e521SShri Abhyankar */ 290c1a5e521SShri Abhyankar 291c1a5e521SShri Abhyankar #undef __FUNCT__ 292c1a5e521SShri Abhyankar #define __FUNCT__ "SNESVIProjectOntoBounds" 293c1a5e521SShri Abhyankar PetscErrorCode SNESVIProjectOntoBounds(SNES snes,Vec X) 294c1a5e521SShri Abhyankar { 295c1a5e521SShri Abhyankar PetscErrorCode ierr; 296c1a5e521SShri Abhyankar const PetscScalar *xl,*xu; 297c1a5e521SShri Abhyankar PetscScalar *x; 298c1a5e521SShri Abhyankar PetscInt i,n; 299c1a5e521SShri Abhyankar 300c1a5e521SShri Abhyankar PetscFunctionBegin; 301c1a5e521SShri Abhyankar ierr = VecGetLocalSize(X,&n);CHKERRQ(ierr); 302c1a5e521SShri Abhyankar ierr = VecGetArray(X,&x);CHKERRQ(ierr); 303c2fc9fa9SBarry Smith ierr = VecGetArrayRead(snes->xl,&xl);CHKERRQ(ierr); 304c2fc9fa9SBarry Smith ierr = VecGetArrayRead(snes->xu,&xu);CHKERRQ(ierr); 305c1a5e521SShri Abhyankar 306c1a5e521SShri Abhyankar for (i = 0; i<n; i++) { 30710f5ae6bSBarry Smith if (PetscRealPart(x[i]) < PetscRealPart(xl[i])) x[i] = xl[i]; 30810f5ae6bSBarry Smith else if (PetscRealPart(x[i]) > PetscRealPart(xu[i])) x[i] = xu[i]; 309c1a5e521SShri Abhyankar } 310c1a5e521SShri Abhyankar ierr = VecRestoreArray(X,&x);CHKERRQ(ierr); 311c2fc9fa9SBarry Smith ierr = VecRestoreArrayRead(snes->xl,&xl);CHKERRQ(ierr); 312c2fc9fa9SBarry Smith ierr = VecRestoreArrayRead(snes->xu,&xu);CHKERRQ(ierr); 313c1a5e521SShri Abhyankar PetscFunctionReturn(0); 314c1a5e521SShri Abhyankar } 315c1a5e521SShri Abhyankar 31669c03620SShri Abhyankar 31769c03620SShri Abhyankar #undef __FUNCT__ 318693ddf92SShri Abhyankar #define __FUNCT__ "SNESVIGetActiveSetIS" 319693ddf92SShri Abhyankar /* 320693ddf92SShri Abhyankar SNESVIGetActiveSetIndices - Gets the global indices for the active set variables 321693ddf92SShri Abhyankar 322693ddf92SShri Abhyankar Input parameter 323693ddf92SShri Abhyankar . snes - the SNES context 324693ddf92SShri Abhyankar . X - the snes solution vector 325693ddf92SShri Abhyankar . F - the nonlinear function vector 326693ddf92SShri Abhyankar 327693ddf92SShri Abhyankar Output parameter 328693ddf92SShri Abhyankar . ISact - active set index set 329693ddf92SShri Abhyankar */ 330693ddf92SShri Abhyankar PetscErrorCode SNESVIGetActiveSetIS(SNES snes,Vec X,Vec F,IS *ISact) 331d950fb63SShri Abhyankar { 332d950fb63SShri Abhyankar PetscErrorCode ierr; 333c2fc9fa9SBarry Smith Vec Xl=snes->xl,Xu=snes->xu; 334693ddf92SShri Abhyankar const PetscScalar *x,*f,*xl,*xu; 335693ddf92SShri Abhyankar PetscInt *idx_act,i,nlocal,nloc_isact=0,ilow,ihigh,i1=0; 336d950fb63SShri Abhyankar 337d950fb63SShri Abhyankar PetscFunctionBegin; 338d950fb63SShri Abhyankar ierr = VecGetLocalSize(X,&nlocal);CHKERRQ(ierr); 339d950fb63SShri Abhyankar ierr = VecGetOwnershipRange(X,&ilow,&ihigh);CHKERRQ(ierr); 340fe835674SShri Abhyankar ierr = VecGetArrayRead(X,&x);CHKERRQ(ierr); 341fe835674SShri Abhyankar ierr = VecGetArrayRead(Xl,&xl);CHKERRQ(ierr); 342fe835674SShri Abhyankar ierr = VecGetArrayRead(Xu,&xu);CHKERRQ(ierr); 343fe835674SShri Abhyankar ierr = VecGetArrayRead(F,&f);CHKERRQ(ierr); 344693ddf92SShri Abhyankar /* Compute active set size */ 345d950fb63SShri Abhyankar for (i=0; i < nlocal;i++) { 34610f5ae6bSBarry Smith if (!((PetscRealPart(x[i]) > PetscRealPart(xl[i]) + 1.e-8 || (PetscRealPart(f[i]) < 0.0)) && ((PetscRealPart(x[i]) < PetscRealPart(xu[i]) - 1.e-8) || PetscRealPart(f[i]) > 0.0))) nloc_isact++; 347d950fb63SShri Abhyankar } 348693ddf92SShri Abhyankar 349785e854fSJed Brown ierr = PetscMalloc1(nloc_isact,&idx_act);CHKERRQ(ierr); 350d950fb63SShri Abhyankar 351693ddf92SShri Abhyankar /* Set active set indices */ 352d950fb63SShri Abhyankar for (i=0; i < nlocal; i++) { 35310f5ae6bSBarry Smith if (!((PetscRealPart(x[i]) > PetscRealPart(xl[i]) + 1.e-8 || (PetscRealPart(f[i]) < 0.0)) && ((PetscRealPart(x[i]) < PetscRealPart(xu[i]) - 1.e-8) || PetscRealPart(f[i]) > 0.0))) idx_act[i1++] = ilow+i; 354d950fb63SShri Abhyankar } 355d950fb63SShri Abhyankar 356693ddf92SShri Abhyankar /* Create active set IS */ 357ce94432eSBarry Smith ierr = ISCreateGeneral(PetscObjectComm((PetscObject)snes),nloc_isact,idx_act,PETSC_OWN_POINTER,ISact);CHKERRQ(ierr); 358d950fb63SShri Abhyankar 359fe835674SShri Abhyankar ierr = VecRestoreArrayRead(X,&x);CHKERRQ(ierr); 360fe835674SShri Abhyankar ierr = VecRestoreArrayRead(Xl,&xl);CHKERRQ(ierr); 361fe835674SShri Abhyankar ierr = VecRestoreArrayRead(Xu,&xu);CHKERRQ(ierr); 362fe835674SShri Abhyankar ierr = VecRestoreArrayRead(F,&f);CHKERRQ(ierr); 363d950fb63SShri Abhyankar PetscFunctionReturn(0); 364d950fb63SShri Abhyankar } 365d950fb63SShri Abhyankar 366693ddf92SShri Abhyankar #undef __FUNCT__ 367693ddf92SShri Abhyankar #define __FUNCT__ "SNESVICreateIndexSets_RS" 368693ddf92SShri Abhyankar PetscErrorCode SNESVICreateIndexSets_RS(SNES snes,Vec X,Vec F,IS *ISact,IS *ISinact) 369693ddf92SShri Abhyankar { 370693ddf92SShri Abhyankar PetscErrorCode ierr; 371077aedafSJed Brown PetscInt rstart,rend; 372693ddf92SShri Abhyankar 373693ddf92SShri Abhyankar PetscFunctionBegin; 374693ddf92SShri Abhyankar ierr = SNESVIGetActiveSetIS(snes,X,F,ISact);CHKERRQ(ierr); 375077aedafSJed Brown ierr = VecGetOwnershipRange(X,&rstart,&rend);CHKERRQ(ierr); 376077aedafSJed Brown ierr = ISComplement(*ISact,rstart,rend,ISinact);CHKERRQ(ierr); 377693ddf92SShri Abhyankar PetscFunctionReturn(0); 378693ddf92SShri Abhyankar } 379693ddf92SShri Abhyankar 380fe835674SShri Abhyankar #undef __FUNCT__ 381fe835674SShri Abhyankar #define __FUNCT__ "SNESVIComputeInactiveSetFnorm" 38210f5ae6bSBarry Smith PetscErrorCode SNESVIComputeInactiveSetFnorm(SNES snes,Vec F,Vec X, PetscReal *fnorm) 383fe835674SShri Abhyankar { 384fe835674SShri Abhyankar PetscErrorCode ierr; 385fe835674SShri Abhyankar const PetscScalar *x,*xl,*xu,*f; 386fe835674SShri Abhyankar PetscInt i,n; 387fe835674SShri Abhyankar PetscReal rnorm; 388fe835674SShri Abhyankar 389fe835674SShri Abhyankar PetscFunctionBegin; 390fe835674SShri Abhyankar ierr = VecGetLocalSize(X,&n);CHKERRQ(ierr); 391c2fc9fa9SBarry Smith ierr = VecGetArrayRead(snes->xl,&xl);CHKERRQ(ierr); 392c2fc9fa9SBarry Smith ierr = VecGetArrayRead(snes->xu,&xu);CHKERRQ(ierr); 393fe835674SShri Abhyankar ierr = VecGetArrayRead(X,&x);CHKERRQ(ierr); 394fe835674SShri Abhyankar ierr = VecGetArrayRead(F,&f);CHKERRQ(ierr); 395fe835674SShri Abhyankar rnorm = 0.0; 396fe835674SShri Abhyankar for (i=0; i<n; i++) { 39710f5ae6bSBarry Smith if (((PetscRealPart(x[i]) > PetscRealPart(xl[i]) + 1.e-8 || (PetscRealPart(f[i]) < 0.0)) && ((PetscRealPart(x[i]) < PetscRealPart(xu[i]) - 1.e-8) || PetscRealPart(f[i]) > 0.0))) rnorm += PetscRealPart(PetscConj(f[i])*f[i]); 3988f918527SKarl Rupp } 399fe835674SShri Abhyankar ierr = VecRestoreArrayRead(F,&f);CHKERRQ(ierr); 400c2fc9fa9SBarry Smith ierr = VecRestoreArrayRead(snes->xl,&xl);CHKERRQ(ierr); 401c2fc9fa9SBarry Smith ierr = VecRestoreArrayRead(snes->xu,&xu);CHKERRQ(ierr); 402fe835674SShri Abhyankar ierr = VecRestoreArrayRead(X,&x);CHKERRQ(ierr); 403ce94432eSBarry Smith ierr = MPI_Allreduce(&rnorm,fnorm,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)snes));CHKERRQ(ierr); 40462d1f40fSBarry Smith *fnorm = PetscSqrtReal(*fnorm); 405fe835674SShri Abhyankar PetscFunctionReturn(0); 406fe835674SShri Abhyankar } 407fe835674SShri Abhyankar 40808da532bSDmitry Karpeev #undef __FUNCT__ 40908da532bSDmitry Karpeev #define __FUNCT__ "SNESVIDMComputeVariableBounds" 41008da532bSDmitry Karpeev PetscErrorCode SNESVIDMComputeVariableBounds(SNES snes,Vec xl, Vec xu) 41108da532bSDmitry Karpeev { 41208da532bSDmitry Karpeev PetscErrorCode ierr; 4136e111a19SKarl Rupp 41408da532bSDmitry Karpeev PetscFunctionBegin; 41508da532bSDmitry Karpeev ierr = DMComputeVariableBounds(snes->dm, xl, xu);CHKERRQ(ierr); 41608da532bSDmitry Karpeev PetscFunctionReturn(0); 41708da532bSDmitry Karpeev } 41808da532bSDmitry Karpeev 4192f63a38cSShri Abhyankar 4202b4ed282SShri Abhyankar /* -------------------------------------------------------------------------- */ 4212b4ed282SShri Abhyankar /* 422c2fc9fa9SBarry Smith SNESSetUp_VI - Does setup common to all VI solvers -- basically makes sure bounds have been properly set up 4232b4ed282SShri Abhyankar of the SNESVI nonlinear solver. 4242b4ed282SShri Abhyankar 4252b4ed282SShri Abhyankar Input Parameter: 4262b4ed282SShri Abhyankar . snes - the SNES context 4272b4ed282SShri Abhyankar . x - the solution vector 4282b4ed282SShri Abhyankar 4292b4ed282SShri Abhyankar Application Interface Routine: SNESSetUp() 4302b4ed282SShri Abhyankar 4312b4ed282SShri Abhyankar Notes: 4322b4ed282SShri Abhyankar For basic use of the SNES solvers, the user need not explicitly call 4332b4ed282SShri Abhyankar SNESSetUp(), since these actions will automatically occur during 4342b4ed282SShri Abhyankar the call to SNESSolve(). 4352b4ed282SShri Abhyankar */ 4362b4ed282SShri Abhyankar #undef __FUNCT__ 4372b4ed282SShri Abhyankar #define __FUNCT__ "SNESSetUp_VI" 4382b4ed282SShri Abhyankar PetscErrorCode SNESSetUp_VI(SNES snes) 4392b4ed282SShri Abhyankar { 4402b4ed282SShri Abhyankar PetscErrorCode ierr; 4412b4ed282SShri Abhyankar PetscInt i_start[3],i_end[3]; 4422b4ed282SShri Abhyankar 4432b4ed282SShri Abhyankar PetscFunctionBegin; 444fa0ddf94SBarry Smith ierr = SNESSetWorkVecs(snes,1);CHKERRQ(ierr); 4456cab3a1bSJed Brown ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 4462b4ed282SShri Abhyankar 44708da532bSDmitry Karpeev if (!snes->ops->computevariablebounds && snes->dm) { 448a201590fSDmitry Karpeev PetscBool flag; 449a201590fSDmitry Karpeev ierr = DMHasVariableBounds(snes->dm, &flag);CHKERRQ(ierr); 4501aa26658SKarl Rupp 45108da532bSDmitry Karpeev snes->ops->computevariablebounds = SNESVIDMComputeVariableBounds; 45208da532bSDmitry Karpeev } 453a201590fSDmitry Karpeev if (!snes->usersetbounds) { 454c2fc9fa9SBarry Smith if (snes->ops->computevariablebounds) { 455c2fc9fa9SBarry Smith if (!snes->xl) {ierr = VecDuplicate(snes->vec_sol,&snes->xl);CHKERRQ(ierr);} 456c2fc9fa9SBarry Smith if (!snes->xu) {ierr = VecDuplicate(snes->vec_sol,&snes->xu);CHKERRQ(ierr);} 457c2fc9fa9SBarry Smith ierr = (*snes->ops->computevariablebounds)(snes,snes->xl,snes->xu);CHKERRQ(ierr); 4581aa26658SKarl Rupp } else if (!snes->xl && !snes->xu) { 4592176524cSBarry Smith /* If the lower and upper bound on variables are not set, set it to -Inf and Inf */ 460c2fc9fa9SBarry Smith ierr = VecDuplicate(snes->vec_sol, &snes->xl);CHKERRQ(ierr); 461e270355aSBarry Smith ierr = VecSet(snes->xl,PETSC_NINFINITY);CHKERRQ(ierr); 462c2fc9fa9SBarry Smith ierr = VecDuplicate(snes->vec_sol, &snes->xu);CHKERRQ(ierr); 463e270355aSBarry Smith ierr = VecSet(snes->xu,PETSC_INFINITY);CHKERRQ(ierr); 4642b4ed282SShri Abhyankar } else { 4652b4ed282SShri Abhyankar /* Check if lower bound, upper bound and solution vector distribution across the processors is identical */ 4662b4ed282SShri Abhyankar ierr = VecGetOwnershipRange(snes->vec_sol,i_start,i_end);CHKERRQ(ierr); 467c2fc9fa9SBarry Smith ierr = VecGetOwnershipRange(snes->xl,i_start+1,i_end+1);CHKERRQ(ierr); 468c2fc9fa9SBarry Smith ierr = VecGetOwnershipRange(snes->xu,i_start+2,i_end+2);CHKERRQ(ierr); 4692b4ed282SShri 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])) 4702b4ed282SShri 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."); 4712b4ed282SShri Abhyankar } 472a201590fSDmitry Karpeev } 4732b4ed282SShri Abhyankar PetscFunctionReturn(0); 4742b4ed282SShri Abhyankar } 4752b4ed282SShri Abhyankar /* -------------------------------------------------------------------------- */ 4762176524cSBarry Smith #undef __FUNCT__ 4772176524cSBarry Smith #define __FUNCT__ "SNESReset_VI" 4782176524cSBarry Smith PetscErrorCode SNESReset_VI(SNES snes) 4792176524cSBarry Smith { 4802176524cSBarry Smith PetscErrorCode ierr; 4812176524cSBarry Smith 4822176524cSBarry Smith PetscFunctionBegin; 483c2fc9fa9SBarry Smith ierr = VecDestroy(&snes->xl);CHKERRQ(ierr); 484c2fc9fa9SBarry Smith ierr = VecDestroy(&snes->xu);CHKERRQ(ierr); 4852d6615e8SDmitry Karpeev snes->usersetbounds = PETSC_FALSE; 4862176524cSBarry Smith PetscFunctionReturn(0); 4872176524cSBarry Smith } 4882176524cSBarry Smith 4892b4ed282SShri Abhyankar /* 4902b4ed282SShri Abhyankar SNESDestroy_VI - Destroys the private SNES_VI context that was created 4912b4ed282SShri Abhyankar with SNESCreate_VI(). 4922b4ed282SShri Abhyankar 4932b4ed282SShri Abhyankar Input Parameter: 4942b4ed282SShri Abhyankar . snes - the SNES context 4952b4ed282SShri Abhyankar 4962b4ed282SShri Abhyankar Application Interface Routine: SNESDestroy() 4972b4ed282SShri Abhyankar */ 4982b4ed282SShri Abhyankar #undef __FUNCT__ 4992b4ed282SShri Abhyankar #define __FUNCT__ "SNESDestroy_VI" 5002b4ed282SShri Abhyankar PetscErrorCode SNESDestroy_VI(SNES snes) 5012b4ed282SShri Abhyankar { 5022b4ed282SShri Abhyankar PetscErrorCode ierr; 5032b4ed282SShri Abhyankar 5042b4ed282SShri Abhyankar PetscFunctionBegin; 5052b4ed282SShri Abhyankar ierr = PetscFree(snes->data);CHKERRQ(ierr); 5062b4ed282SShri Abhyankar 5072b4ed282SShri Abhyankar /* clear composed functions */ 508bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)snes,"SNESLineSearchSet_C",NULL);CHKERRQ(ierr); 509bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)snes,"SNESLineSearchSetMonitor_C",NULL);CHKERRQ(ierr); 5102b4ed282SShri Abhyankar PetscFunctionReturn(0); 5112b4ed282SShri Abhyankar } 5127fe79bc4SShri Abhyankar 5135559b345SBarry Smith #undef __FUNCT__ 5145559b345SBarry Smith #define __FUNCT__ "SNESVISetVariableBounds" 5155559b345SBarry Smith /*@ 5162b4ed282SShri Abhyankar SNESVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu. 5172b4ed282SShri Abhyankar 5182b4ed282SShri Abhyankar Input Parameters: 5192b4ed282SShri Abhyankar . snes - the SNES context. 5202b4ed282SShri Abhyankar . xl - lower bound. 5212b4ed282SShri Abhyankar . xu - upper bound. 5222b4ed282SShri Abhyankar 5232b4ed282SShri Abhyankar Notes: 5242b4ed282SShri Abhyankar If this routine is not called then the lower and upper bounds are set to 525e270355aSBarry Smith PETSC_INFINITY and PETSC_NINFINITY respectively during SNESSetUp(). 52684c105d7SBarry Smith 5272bd2b0e6SSatish Balay Level: advanced 5282bd2b0e6SSatish Balay 5295559b345SBarry Smith @*/ 53069c03620SShri Abhyankar PetscErrorCode SNESVISetVariableBounds(SNES snes, Vec xl, Vec xu) 5312b4ed282SShri Abhyankar { 53261589011SJed Brown PetscErrorCode ierr,(*f)(SNES,Vec,Vec); 5332b4ed282SShri Abhyankar 5342b4ed282SShri Abhyankar PetscFunctionBegin; 5352b4ed282SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5362b4ed282SShri Abhyankar PetscValidHeaderSpecific(xl,VEC_CLASSID,2); 5372b4ed282SShri Abhyankar PetscValidHeaderSpecific(xu,VEC_CLASSID,3); 5380005d66cSJed Brown ierr = PetscObjectQueryFunction((PetscObject)snes,"SNESVISetVariableBounds_C",&f);CHKERRQ(ierr); 539f450aa47SBarry Smith if (!f) {ierr = SNESSetType(snes,SNESVINEWTONRSLS);CHKERRQ(ierr);} 54061589011SJed Brown ierr = PetscUseMethod(snes,"SNESVISetVariableBounds_C",(SNES,Vec,Vec),(snes,xl,xu));CHKERRQ(ierr); 541a201590fSDmitry Karpeev snes->usersetbounds = PETSC_TRUE; 54261589011SJed Brown PetscFunctionReturn(0); 54361589011SJed Brown } 54461589011SJed Brown 54561589011SJed Brown #undef __FUNCT__ 54661589011SJed Brown #define __FUNCT__ "SNESVISetVariableBounds_VI" 54761589011SJed Brown PetscErrorCode SNESVISetVariableBounds_VI(SNES snes,Vec xl,Vec xu) 54861589011SJed Brown { 54961589011SJed Brown PetscErrorCode ierr; 55061589011SJed Brown const PetscScalar *xxl,*xxu; 55161589011SJed Brown PetscInt i,n, cnt = 0; 55261589011SJed Brown 55361589011SJed Brown PetscFunctionBegin; 5540298fd71SBarry Smith ierr = SNESGetFunction(snes,&snes->vec_func,NULL,NULL);CHKERRQ(ierr); 555a63bb30eSJed Brown if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() or SNESSetDM() first"); 556077aedafSJed Brown { 557077aedafSJed Brown PetscInt xlN,xuN,N; 558077aedafSJed Brown ierr = VecGetSize(xl,&xlN);CHKERRQ(ierr); 559077aedafSJed Brown ierr = VecGetSize(xu,&xuN);CHKERRQ(ierr); 560077aedafSJed Brown ierr = VecGetSize(snes->vec_func,&N);CHKERRQ(ierr); 561077aedafSJed Brown if (xlN != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Incompatible vector lengths lower bound = %D solution vector = %D",xlN,N); 562077aedafSJed Brown if (xuN != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Incompatible vector lengths: upper bound = %D solution vector = %D",xuN,N); 563077aedafSJed Brown } 5642176524cSBarry Smith ierr = PetscObjectReference((PetscObject)xl);CHKERRQ(ierr); 5652176524cSBarry Smith ierr = PetscObjectReference((PetscObject)xu);CHKERRQ(ierr); 566c2fc9fa9SBarry Smith ierr = VecDestroy(&snes->xl);CHKERRQ(ierr); 567c2fc9fa9SBarry Smith ierr = VecDestroy(&snes->xu);CHKERRQ(ierr); 568c2fc9fa9SBarry Smith snes->xl = xl; 569c2fc9fa9SBarry Smith snes->xu = xu; 5706fd67740SBarry Smith ierr = VecGetLocalSize(xl,&n);CHKERRQ(ierr); 5716fd67740SBarry Smith ierr = VecGetArrayRead(xl,&xxl);CHKERRQ(ierr); 5726fd67740SBarry Smith ierr = VecGetArrayRead(xu,&xxu);CHKERRQ(ierr); 573e270355aSBarry Smith for (i=0; i<n; i++) cnt += ((xxl[i] != PETSC_NINFINITY) || (xxu[i] != PETSC_INFINITY)); 5741aa26658SKarl Rupp 575ce94432eSBarry Smith ierr = MPI_Allreduce(&cnt,&snes->ntruebounds,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)snes));CHKERRQ(ierr); 5766fd67740SBarry Smith ierr = VecRestoreArrayRead(xl,&xxl);CHKERRQ(ierr); 5776fd67740SBarry Smith ierr = VecRestoreArrayRead(xu,&xxu);CHKERRQ(ierr); 5782b4ed282SShri Abhyankar PetscFunctionReturn(0); 5792b4ed282SShri Abhyankar } 58092c02d66SPeter Brune 5812b4ed282SShri Abhyankar #undef __FUNCT__ 582c2fc9fa9SBarry Smith #define __FUNCT__ "SNESSetFromOptions_VI" 5838c34d3f5SBarry Smith PetscErrorCode SNESSetFromOptions_VI(PetscOptions *PetscOptionsObject,SNES snes) 5842b4ed282SShri Abhyankar { 5852b4ed282SShri Abhyankar PetscErrorCode ierr; 5868afaa268SBarry Smith PetscBool flg = PETSC_FALSE; 587639ea3faSPeter Brune SNESLineSearch linesearch; 5882b4ed282SShri Abhyankar 5892b4ed282SShri Abhyankar PetscFunctionBegin; 590e55864a3SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"SNES VI options");CHKERRQ(ierr); 591ffdf2a20SBarry Smith ierr = PetscOptionsBool("-snes_vi_monitor","Monitor all non-active variables","SNESMonitorResidual",flg,&flg,NULL);CHKERRQ(ierr); 592c2fc9fa9SBarry Smith if (flg) { 593c2fc9fa9SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorVI,0,0);CHKERRQ(ierr); 5942b4ed282SShri Abhyankar } 595*de34d3e9SBarry Smith flg = PETSC_FALSE; 596ffdf2a20SBarry Smith ierr = PetscOptionsBool("-snes_vi_monitor_residual","Monitor residual all non-active variables; using zero for active constraints","SNESMonitorVIResidual",flg,&flg,NULL);CHKERRQ(ierr); 597ffdf2a20SBarry Smith if (flg) { 598ffdf2a20SBarry Smith ierr = SNESMonitorSet(snes,SNESVIMonitorResidual,PETSC_VIEWER_DRAW_(PetscObjectComm((PetscObject)snes)),NULL);CHKERRQ(ierr); 599ffdf2a20SBarry Smith } 600639ea3faSPeter Brune if (!snes->linesearch) { 6017601faf0SJed Brown ierr = SNESGetLineSearch(snes, &linesearch);CHKERRQ(ierr); 602639ea3faSPeter Brune ierr = SNESLineSearchSetType(linesearch, SNESLINESEARCHBT);CHKERRQ(ierr); 603639ea3faSPeter Brune ierr = SNESLineSearchBTSetAlpha(linesearch, 0.0);CHKERRQ(ierr); 604639ea3faSPeter Brune } 605c2fc9fa9SBarry Smith ierr = PetscOptionsTail();CHKERRQ(ierr); 606ed70e96aSJungho Lee PetscFunctionReturn(0); 607ed70e96aSJungho Lee } 608