~chaffra/+junk/trilinos

« back to all changes in this revision

Viewing changes to packages/nox/src/NOX_Direction_ModifiedNewton.C

  • Committer: Bazaar Package Importer
  • Author(s): Christophe Prud'homme, Christophe Prud'homme, Johannes Ring
  • Date: 2009-12-13 12:53:22 UTC
  • mfrom: (5.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20091213125322-in0nrdjc55deqsw9
Tags: 10.0.3.dfsg-1
[Christophe Prud'homme]
* New upstream release

[Johannes Ring]
* debian/patches/libname.patch: Add prefix 'libtrilinos_' to all
  libraries. 
* debian/patches/soname.patch: Add soversion to libraries.
* debian/watch: Update download URL.
* debian/control:
  - Remove python-numeric from Build-Depends (virtual package).
  - Remove automake and autotools from Build-Depends and add cmake to
    reflect switch to CMake.
  - Add python-support to Build-Depends.
* debian/rules: 
  - Cleanup and updates for switch to CMake.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// $Id$ 
 
2
// $Source$ 
 
3
 
 
4
//@HEADER
 
5
// ************************************************************************
 
6
// 
 
7
//            NOX: An Object-Oriented Nonlinear Solver Package
 
8
//                 Copyright (2002) Sandia Corporation
 
9
// 
 
10
//            LOCA: Library of Continuation Algorithms Package
 
11
//                 Copyright (2005) Sandia Corporation
 
12
// 
 
13
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
 
14
// license for use of this work by or on behalf of the U.S. Government.
 
15
// 
 
16
// This library is free software; you can redistribute it and/or modify
 
17
// it under the terms of the GNU Lesser General Public License as
 
18
// published by the Free Software Foundation; either version 2.1 of the
 
19
// License, or (at your option) any later version.
 
20
//  
 
21
// This library is distributed in the hope that it will be useful, but
 
22
// WITHOUT ANY WARRANTY; without even the implied warranty of
 
23
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
24
// Lesser General Public License for more details.
 
25
// 
 
26
// You should have received a copy of the GNU Lesser General Public
 
27
// License along with this library; if not, write to the Free Software
 
28
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 
29
// USA
 
30
// 
 
31
// Questions? Contact Roger Pawlowski (rppawlo@sandia.gov) or 
 
32
// Eric Phipps (etphipp@sandia.gov), Sandia National Laboratories.
 
33
// ************************************************************************
 
34
//  CVS Information
 
35
//  $Source$
 
36
//  $Author$
 
37
//  $Date$
 
38
//  $Revision$
 
39
// ************************************************************************
 
40
//@HEADER
 
41
 
 
42
#include "NOX_Common.H"
 
43
 
 
44
#ifdef WITH_PRERELEASE
 
45
 
 
46
#include "NOX_Direction_ModifiedNewton.H" // class definition
 
47
#include "NOX_Abstract_Vector.H"
 
48
#include "NOX_Abstract_Group.H"
 
49
#include "NOX_Solver_Generic.H"
 
50
#include "NOX_Utils.H"
 
51
#include "NOX_GlobalData.H"
 
52
 
 
53
NOX::Direction::ModifiedNewton::
 
54
ModifiedNewton(const Teuchos::RCP<NOX::GlobalData>& gd,
 
55
               Teuchos::ParameterList& p)
 
56
{
 
57
  reset(gd, p);
 
58
  ageOfJacobian = -1;
 
59
  if (p.sublist("Modified-Newton").get("Max Age of Jacobian", 10) < 0)
 
60
    p.sublist("Modified-Newton").set("Max Age of Jacobian", 0);
 
61
}
 
62
 
 
63
NOX::Direction::ModifiedNewton::~ModifiedNewton()
 
64
{
 
65
}
 
66
 
 
67
bool NOX::Direction::ModifiedNewton::
 
68
reset(const Teuchos::RCP<NOX::GlobalData>& gd,
 
69
      Teuchos::ParameterList& params)
 
70
{
 
71
  globalDataPtr = gd;
 
72
  utils = gd->getUtils();
 
73
  
 
74
  paramsPtr = &params;
 
75
 
 
76
  Teuchos::ParameterList& p = params.sublist("Modified-Newton");
 
77
 
 
78
  doRescue = p.get("Rescue Bad Newton Solve", true);
 
79
  if (!p.sublist("Linear Solver").isParameter("Tolerance"))
 
80
    p.sublist("Linear Solver").get("Tolerance", 1.0e-10);
 
81
  ageOfJacobian = -1;
 
82
  return true;
 
83
}
 
84
 
 
85
bool NOX::Direction::ModifiedNewton::
 
86
compute(NOX::Abstract::Vector& dir, 
 
87
        NOX::Abstract::Group& soln, 
 
88
        const NOX::Solver::Generic& solver)
 
89
{
 
90
  NOX::Abstract::Group::ReturnType status;
 
91
 
 
92
  // Compute F at current solution
 
93
  status = soln.computeF();
 
94
  if (status != NOX::Abstract::Group::Ok)
 
95
    throwError("compute", "Unable to compute F");
 
96
 
 
97
  maxAgeOfJacobian = paramsPtr->sublist("Modified-Newton").get("Max Age of Jacobian", 10);
 
98
 
 
99
  if (Teuchos::is_null(oldJacobianGrpPtr)) {
 
100
    oldJacobianGrpPtr = soln.clone(DeepCopy);
 
101
  }
 
102
  NOX::Abstract::Group& oldJacobianGrp = *oldJacobianGrpPtr;
 
103
  
 
104
  status = NOX::Abstract::Group::Failed;
 
105
  while (status != NOX::Abstract::Group::Ok) {
 
106
    // Conditionally compute Jacobian at current solution.
 
107
    if ( (ageOfJacobian == -1) || (ageOfJacobian == maxAgeOfJacobian) ) {
 
108
 
 
109
      if (ageOfJacobian > 0) 
 
110
        oldJacobianGrp = soln;
 
111
      status = oldJacobianGrp.computeJacobian();
 
112
      if (status != NOX::Abstract::Group::Ok) 
 
113
        throwError("compute", "Unable to compute Jacobian");
 
114
      ageOfJacobian = 1;
 
115
    } 
 
116
    else 
 
117
      ageOfJacobian++;
 
118
 
 
119
    // Compute the Modified Newton direction
 
120
    status = oldJacobianGrp.applyJacobianInverse(paramsPtr->sublist("Modified-Newton").sublist("Linear Solver"), soln.getF(), dir);
 
121
    dir.scale(-1.0);
 
122
 
 
123
    // It didn't converge, but maybe we can recover.
 
124
    if ((status != NOX::Abstract::Group::Ok) &&
 
125
        (doRescue == false)) {
 
126
      throwError("compute", "Unable to solve Newton system");
 
127
    }
 
128
    else if ((status != NOX::Abstract::Group::Ok) &&
 
129
             (doRescue == true)) {
 
130
      if (utils->isPrintType(NOX::Utils::Warning))
 
131
        utils->out() << "WARNING: NOX::Direction::ModifiedNewton::compute() - "
 
132
             << "Linear solve failed to achieve convergence - "
 
133
             << "using the step anyway since \"Rescue Bad Newton Solve\" "
 
134
             << "is true. Also, flagging recompute of Jacobian." << std::endl;
 
135
      ageOfJacobian = maxAgeOfJacobian;
 
136
      status = NOX::Abstract::Group::Ok;
 
137
    }
 
138
  }
 
139
 
 
140
  return true;
 
141
}
 
142
 
 
143
bool NOX::Direction::ModifiedNewton::compute(NOX::Abstract::Vector& dir, 
 
144
                                             NOX::Abstract::Group& soln, 
 
145
                                             const NOX::Solver::LineSearchBased& solver)
 
146
{
 
147
  return NOX::Direction::Generic::compute( dir, soln, solver );
 
148
}
 
149
 
 
150
bool  NOX::Direction::ModifiedNewton::rescueBadNewtonSolve(const NOX::Abstract::Group& grp) const
 
151
{
 
152
  //! Check if the "rescue" option has been selected
 
153
  if (!doRescue)
 
154
    return false;
 
155
 
 
156
  //! See if the group has compute the accuracy
 
157
  double accuracy;
 
158
  NOX::Abstract::Group::ReturnType status = oldJacobianGrpPtr->getNormLastLinearSolveResidual(accuracy);
 
159
    
 
160
  // If this functionality is not supported in the group, return false
 
161
  /* NOTE FROM TAMMY: We could later modify this to acutally caluclate
 
162
     the error itself if it's just a matter of the status being
 
163
     NotDefined. */
 
164
  if (status != NOX::Abstract::Group::Ok) 
 
165
    return false;
 
166
 
 
167
  // Check if there is any improvement in the relative residual
 
168
  double normF = grp.getNormF();
 
169
 
 
170
  // If we can't reduce the relative norm at all, we're not happy
 
171
  if (accuracy >= normF) 
 
172
    return false;
 
173
 
 
174
  // Otherwise, we just print a warning and keep going
 
175
  if (utils->isPrintType(NOX::Utils::Warning))
 
176
    utils->out() << "WARNING: NOX::Direction::ModifiedNewton::compute - Unable to achieve desired linear solve accuracy." << endl;
 
177
  return true;
 
178
 
 
179
}
 
180
 
 
181
void NOX::Direction::ModifiedNewton::throwError(const string& functionName, const string& errorMsg)
 
182
{
 
183
  if (utils->isPrintType(NOX::Utils::Error))
 
184
    utils->err() << "NOX::Direction::ModifiedNewton::" << functionName << " - " << errorMsg << endl;
 
185
  throw "NOX Error";
 
186
}
 
187
 
 
188
#endif // WITH_PRERELEASE
 
189
 
 
190
 
 
191