Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_NLS_NOX_WeightedUpdateTest.C
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2 // Copyright Notice
3 //
4 // Copyright 2002 Sandia Corporation. Under the terms
5 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
6 // Government retains certain rights in this software.
7 //
8 // Xyce(TM) Parallel Electrical Simulator
9 // Copyright (C) 2002-2014 Sandia Corporation
10 //
11 // This program is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation, either version 3 of the License, or
14 // (at your option) any later version.
15 //
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 //-----------------------------------------------------------------------------
24 
25 //-------------------------------------------------------------------------
26 // Filename : $RCSfile: N_NLS_NOX_WeightedUpdateTest.C,v $
27 //
28 // Purpose : Status test.
29 //
30 // Special Notes :
31 //
32 // Creator : Tammy Kolda, NLS, 8950
33 //
34 // Creation Date : 01/31/02
35 //
36 // Revision Information:
37 // ---------------------
38 //
39 // Revision Number: $Revision: 1.17 $
40 //
41 // Revision Date : $Date: 2014/02/24 23:49:25 $
42 //
43 // Current Owner : $Author: tvrusso $
44 //-------------------------------------------------------------------------
45 
46 #include <Xyce_config.h>
47 
48 
49 // ---------- Standard Includes ----------
50 
51 // ---------- Xyce Includes ----------
52 
54 #include "N_NLS_NOX_Vector.h"
55 #include "N_LAS_Vector.h"
56 #include "NOX.H"
57 #include "NOX_Solver_LineSearchBased.H"
58 
59 // ---------- Namespaces ----------
60 
61 using namespace N_NLS_NOX;
62 
63 // ---------- Code ----------
64 
65 WeightedUpdateTest::WeightedUpdateTest(N_LAS_Vector** currSolVectorPtrPtr,
66  double epsilon_a, double epsilon_r,
67  double tol, bool isTransient) :
68  epsilon_a_(epsilon_a),
69  epsilon_r_(epsilon_r),
70  tol_(tol),
71  isTransient_(isTransient)
72 {
73  result_ = 0.0;
74  status_ = NOX::StatusTest::Unconverged;
75  oldTimeStepVectorPtrPtr_ = currSolVectorPtrPtr;
77  updateVectorPtr_ = 0;
78  tmpVectorPtr_ = 0;
79 }
80 
82 {
83  if( weightsVectorPtr_ != 0 )
84  {
85  delete weightsVectorPtr_;
86  delete updateVectorPtr_;
87  delete tmpVectorPtr_;
88  }
89 }
90 
91 
92 NOX::StatusTest::StatusType WeightedUpdateTest::checkStatus(const NOX::Solver::Generic& problem)
93 {
94  status_ = NOX::StatusTest::Unconverged;
95 
96  int niters = problem.getNumIterations();
97 
98  // Copy into local reference
99  N_LAS_Vector& oldTimeStepX = **oldTimeStepVectorPtrPtr_;
100 
101  const N_LAS_Vector& x = dynamic_cast<const N_NLS_NOX::Vector&>
102  (problem.getSolutionGroup().getX()).getNativeVectorRef();
103  const N_LAS_Vector& oldX = dynamic_cast<const N_NLS_NOX::Vector&>
104  (problem.getPreviousSolutionGroup().getX()).getNativeVectorRef();
105 
106  // Allocate space if necessary
107  if (weightsVectorPtr_ == 0) {
108  weightsVectorPtr_ = new N_LAS_Vector(x);
109  updateVectorPtr_ = new N_LAS_Vector(x);
110  tmpVectorPtr_ = new N_LAS_Vector(x);
111  }
112 
113  // Local references
114  N_LAS_Vector& weights = *weightsVectorPtr_;
115  N_LAS_Vector& update = *updateVectorPtr_;
116  N_LAS_Vector& tmp = *tmpVectorPtr_;
117 
118  // Compute local portion of weights vector
119  // Weights are recomputed at each nonlinear iteration of a DC Op calc
120  // but only at the beginning of a transient nonlinear solve.
121  if ((!isTransient_) || (niters == 0)) {
122  int length = x.localLength();
123  for (int i = 0; i < length; ++i ) {
124  //update[i] = x[i] - oldX[i];
125  weights[i] =
126  epsilon_r_ * Xycemax(fabs(x[i]), fabs(oldTimeStepX[i])) +
127  epsilon_a_;
128  }
129  //weights.printPetraObject();
130  }
131 
132  if (niters < 1) {
133  result_ = 0.0;
134  return status_;
135  }
136 
137  // Next compute the update
138  update.update(1.0, x, -1.0, oldX, 0.0);
139 
140  // Compute final result
141 #ifdef Xyce_SPICE_NORMS
142  update.wMaxNorm(weights,tmp,&result_);
143 #else
144  update.wRMSNorm(weights,&result_);
145 #endif
146 
147  //cout.precision(12);
148  //cout << "\n ** WRMS = "<<result_<< "\n" <<endl;
149 
150  // RPP: If a line search is being used, we must account for any
151  // damping of the step length. Otherwise delta X could be small due
152  // the line search and not due to being close to a solution.
153  const NOX::Solver::LineSearchBased* test = 0;
154  test = dynamic_cast<const NOX::Solver::LineSearchBased*>(&problem);
155  if (test != 0) {
156  result_ = result_/(test->getStepSize());
157  }
158 
159  if (result_ < tol_)
160  status_ = NOX::StatusTest::Converged;
161 
162  return status_;
163 }
164 
165 std::ostream& WeightedUpdateTest::print(std::ostream& stream, int indent) const
166 {
167  for (int j = 0; j < indent; ++j )
168  stream << ' ';
169  stream << status_;
170  stream << "Weighted Update = " << NOX::Utils::sciformat(result_, 3) << " < " << NOX::Utils::sciformat(tol_, 3) << "\n";
171 
172  for (int j = 0; j < indent; ++j )
173  stream << ' ';
174  stream << std::setw(13) << " ";
175  stream << "(with e_r = " << NOX::Utils::sciformat(epsilon_r_, 3);
176  stream << " and e_a = " << NOX::Utils::sciformat(epsilon_a_, 3) << ")"; ;
177  stream << std::endl;
178  return stream;
179 }
180