Xyce  6.1
N_NLS_NOX_SharedSystem.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-2015 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_SharedSystem.C,v $
27 //
28 // Purpose : Interface to Xyce vectors for NOX.
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.41.2.1 $
40 //
41 // Revision Date : $Date: 2015/04/02 18:20:17 $
42 //
43 // Current Owner : $Author: tvrusso $
44 //-------------------------------------------------------------------------
45 
46 #include <Xyce_config.h>
47 
48 
49 // ---------- Standard Includes ----------
50 
51 // ---------- Xyce Includes ----------
52 
53 #include "N_NLS_NOX_SharedSystem.h"
54 #include "N_NLS_NOX_Interface.h"
55 #include "N_LAS_Vector.h"
56 #include "N_LAS_Matrix.h"
57 #include "N_LAS_System.h"
58 #include "N_LAS_Builder.h"
59 #include "N_ERH_ErrorMgr.h"
60 #include "Epetra_CrsMatrix.h"
61 #include "Ifpack_IlukGraph.h"
62 #include "Ifpack_CrsRiluk.h"
63 
64 // ---------- NOX Includes ----------
65 
66 // ---------- Namespaces ---------------
67 namespace Xyce {
68 namespace Nonlinear {
69 namespace N_NLS_NOX {
70 
71 //-----------------------------------------------------------------------------
72 // Function : SharedSystem::SharedSystem
73 // Purpose : Constructor. Creates a shared system containing
74 // the soln vector, the previous solution vector,
75 // the RHS vector, the Newton vector, the Jacobian
76 // matrix, and a reference to the interface used to
77 // call the evaluation functions.
78 // Special Notes :
79 // Scope : public
80 // Creator :
81 // Creation Date :
82 //-----------------------------------------------------------------------------
83 SharedSystem::SharedSystem(Linear::Vector& soln,
84  Linear::Vector& f,
85  Linear::Matrix& jacobian,
86  Linear::Vector& newton,
87  Linear::Vector& gradient,
88  Linear::System& lasSys,
89  Interface& interface) :
90 
91  xyceSolnPtr_(0),
92  xyceFPtr_(0),
93  xyceJacobianPtr_(0),
94  xyceNewtonPtr_(0),
95  xyceGradientPtr_(0),
96  xyceLasSysPtr_(0),
97  xyceInterfacePtr_(0),
98  matrixFreeFlag_(false),
99  ownerOfJacobian_(0),
100  ownerOfStateVectors_(0),
101  ifpackGraphPtr_(0),
102  ifpackPreconditionerPtr_(0)
103 {
104  reset(soln, f, jacobian, newton, gradient, lasSys, interface);
105 }
106 
107 //-----------------------------------------------------------------------------
108 // Function : SharedSystem::~SharedSystem
109 // Purpose : Destructor.
110 // Special Notes :
111 // Scope : public
112 // Creator :
113 // Creation Date :
114 //-----------------------------------------------------------------------------
116 {
118  delete xyceSolnPtr_;
119  delete xyceFPtr_;
120  delete xyceNewtonPtr_;
121  delete xyceGradientPtr_;
122 }
123 
124 //-----------------------------------------------------------------------------
125 // Function : SharedSystem::reset
126 // Purpose : reset the Xyce fill objects - pointers may have changed!
127 // Special Notes :
128 // Scope : public
129 // Creator :
130 // Creation Date :
131 //-----------------------------------------------------------------------------
132 void SharedSystem::reset(Linear::Vector& x,
133  Linear::Vector& f,
134  Linear::Matrix& jacobian,
135  Linear::Vector& newton,
136  Linear::Vector& gradient,
137  Linear::System& lasSys,
138  Interface& interface)
139 {
140  // Clear out old views
141  delete xyceSolnPtr_;
142  delete xyceFPtr_;
143  delete xyceNewtonPtr_;
144  delete xyceGradientPtr_;
145 
146  xyceJacobianPtr_ = &jacobian;
147  xyceLasSysPtr_ = &lasSys;
148  xyceInterfacePtr_ = &interface;
150 
151  // Create views of the data used for fills in xyce
152  xyceSolnPtr_ = new Vector(x, lasSys);
153  xyceFPtr_ = new Vector(f, lasSys);
154  xyceNewtonPtr_ = new Vector(newton, lasSys);
155  xyceGradientPtr_ = new Vector(gradient, lasSys);
156 
157  // Wipe the preconditioner clean
159 }
160 
161 //-----------------------------------------------------------------------------
162 // Function : SharedSystem::computeF
163 // Purpose : Compute the F corresponding to the current
164 // primary solution vector. Makes the primary
165 // solution vector owner in to the owner of the F.
166 // Special Notes :
167 // Scope : public
168 // Creator :
169 // Creation Date :
170 //-----------------------------------------------------------------------------
171 bool SharedSystem::computeF(const Vector& solution, Vector& F,
172  const Group* grp)
173 {
174  ownerOfStateVectors_ = grp;
175 
176 #ifdef Xyce_NOX_USE_VECTOR_COPY
177  *xyceSolnPtr_ = solution;
178  bool status = xyceInterfacePtr_->computeF();
179 #else
180  bool status = xyceInterfacePtr_->computeF(F, solution);
181 #endif
182 
183  if (status == false) {
184  const string message = "Error: SharedSystem::computeF() - compute F failed!";
185  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, message);
186  }
187 
188 #ifdef Xyce_NOX_USE_VECTOR_COPY
189  F = *xyceFPtr_;
190 #endif
191  return status;
192 }
193 
194 //-----------------------------------------------------------------------------
195 // Function : SharedSystem::computeJacobian
196 // Purpose : Compute the Jacobian corresponding to the current
197 // primary solution vector.
198 // Special Notes :
199 // Scope : public
200 // Creator :
201 // Creation Date :
202 //-----------------------------------------------------------------------------
204 {
205  ownerOfJacobian_ = grp;
206 
207 #ifdef Xyce_NOX_USE_VECTOR_COPY
208  *xyceSolnPtr_ = grp->getX();
209 #endif
210 
211  if (!areStateVectors(grp)) {
212 #ifdef Xyce_VERBOSE_NOX
213  if (1) { //RPP: Need to add priting utilities to group ctor
214  dout() << "Warning: SharedSystem::computeJacobian() - State "
215  << "Vectors are not valid wrt solution!" << std::endl;
216  dout() << "Calling computeResidual to fix this!" << std::endl;
217  }
218 #endif
219  // RPP: This line is not needed since we now call the group
220  //ownerOfStateVectors_ = grp;
221 
222  NOX::Abstract::Group::ReturnType status = grp->computeF();
223 
224  if (status != NOX::Abstract::Group::Ok) {
225  const string message = "SharedSystem::computeJacobian() - compute F failed!";
226  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, message);
227  }
228 
229  }
230 
231 #ifdef Xyce_NOX_USE_VECTOR_COPY
232  bool status = xyceInterfacePtr_->computeJacobian();
233 #else
234  bool status = xyceInterfacePtr_->computeJacobian
235  (dynamic_cast<const Vector &> (grp->getX()));
236 #endif
237 
238  if (status == false) {
239  const string message = "SharedSystem::computeJacobian() - compute Jac failed!";
240  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, message);
241  }
242 
243  return status;
244 }
245 
246 //-----------------------------------------------------------------------------
247 // Function : SharedSystem::computeNewton
248 // Purpose : Compute the Newton corresponding to the current
249 // primary solution vector.
250 // Special Notes :
251 // Scope : public
252 // Creator :
253 // Creation Date :
254 //-----------------------------------------------------------------------------
256  Teuchos::ParameterList& params)
257 {
258  *xyceFPtr_ = F;
259  // Zero out the Newton vector
260  xyceNewtonPtr_->scale(0.0);
261  bool status = xyceInterfacePtr_->computeNewton(params);
262  Newton = *xyceNewtonPtr_;
263 
264  return status;
265 }
266 
267 //-----------------------------------------------------------------------------
268 // Function : SharedSystem::computeGradient
269 // Purpose : Compute the Gradient corresponding to the current
270 // primary solution vector.
271 // Special Notes :
272 // Scope : public
273 // Creator :
274 // Creation Date :
275 //-----------------------------------------------------------------------------
276 bool SharedSystem::computeGradient(const Vector& F, Vector& Gradient)
277 {
278  *xyceFPtr_ = F;
279  xyceGradientPtr_->scale(0.0);
280  bool status = xyceInterfacePtr_->computeGradient();
281  Gradient = *xyceGradientPtr_;
282  return status;
283 }
284 
285 //-----------------------------------------------------------------------------
286 // Function : SharedSystem::applyJacobian
287 // Purpose :
288 // Special Notes :
289 // Scope : public
290 // Creator :
291 // Creation Date :
292 //-----------------------------------------------------------------------------
293 bool SharedSystem::applyJacobian(const Vector& input, Vector& result) const
294 {
295  if (!matrixFreeFlag_) {
296  bool NoTranspose = false;
297  xyceJacobianPtr_->matvec(NoTranspose, input.getNativeVectorRef(), result.getNativeVectorRef());
298  } else {
299  // tscoffe/tmei HB 07/29/08
300 #ifndef Xyce_NOX_USE_VECTOR_COPY
301  const string message = "SharedSystem::applyJacobian() - ERROR, Xyce_NOX_USE_VECTOR_COPY required";
302  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, message);
303 #endif
304  bool status = xyceInterfacePtr_->applyJacobian(input.getNativeVectorRef(), result.getNativeVectorRef());
305  if (status == false) {
306  const string message = "SharedSystem::applyJacobian() - apply Jac failed!";
307  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, message);
308  }
309  }
310  return true;
311 }
312 
313 //-----------------------------------------------------------------------------
314 // Function : SharedSystem::applyJacobianTranspose
315 // Purpose :
316 // Special Notes :
317 // Scope : public
318 // Creator :
319 // Creation Date :
320 //-----------------------------------------------------------------------------
321 bool SharedSystem::applyJacobianTranspose(const Vector& input, Vector& result) const
322 {
323  if (!matrixFreeFlag_) {
324  bool Transpose = true;
325  xyceJacobianPtr_->matvec(Transpose, input.getNativeVectorRef(), result.getNativeVectorRef());
326  } else {
327  const string message = "SharedSystem::applyJacobianTranspose() - Not Supported for Matrix Free Loads!";
328  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, message);
329  }
330  return true;
331 }
332 
333 //-----------------------------------------------------------------------------
334 // Function : SharedSystem::computePreconditioner
335 // Purpose :
336 // Special Notes :
337 // Scope : public
338 // Creator :
339 // Creation Date :
340 //-----------------------------------------------------------------------------
342 {
343  Epetra_CrsMatrix* crs = dynamic_cast<Epetra_CrsMatrix*>
344  (&(xyceJacobianPtr_->epetraObj()));
345 
346  if (crs == 0) {
347  dout() << "SharedSystem::computePreconditioner() - "
348  << "Dynamic cast to CRS Matrix failed!" << std::endl;
349  }
350 
352  ifpackGraphPtr_ = new Ifpack_IlukGraph(crs->Graph(),
353  1,
354  0);
355  ifpackGraphPtr_->ConstructFilledGraph();
356  ifpackPreconditionerPtr_ = new Ifpack_CrsRiluk(*ifpackGraphPtr_);
357  ifpackPreconditionerPtr_->InitValues(*crs);
358  ifpackPreconditionerPtr_->Factor();
359  return true;
360 }
361 
362 //-----------------------------------------------------------------------------
363 // Function : SharedSystem::deletePreconditioner
364 // Purpose :
365 // Special Notes :
366 // Scope : public
367 // Creator :
368 // Creation Date :
369 //-----------------------------------------------------------------------------
371 {
373  delete ifpackGraphPtr_;
375  ifpackGraphPtr_ = 0;
376  return true;
377 }
378 
379 //-----------------------------------------------------------------------------
380 // Function : SharedSystem::applyRightPreconditioning
381 // Purpose :
382 // Special Notes :
383 // Scope : public
384 // Creator :
385 // Creation Date :
386 //-----------------------------------------------------------------------------
388  Teuchos::ParameterList& params,
389  const Vector& input,
390  Vector& result)
391 {
392  if (ifpackPreconditionerPtr_ == 0) {
393  const string message = "SharedSystem::applyRightPreconditioning - Preconditioner is 0!";
394  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, message);
395  }
396 
397  if (useTranspose)
398  ifpackPreconditionerPtr_->SetUseTranspose(useTranspose);
399 
400  Linear::Vector& nonConstInput =
401  const_cast<Linear::Vector&>(input.getNativeVectorRef_());
402  Epetra_MultiVector& epVecInput =
403  const_cast<Epetra_MultiVector&>(nonConstInput.epetraObj());
404 
405  Linear::Vector& nonConstResult =
406  const_cast<Linear::Vector&>(result.getNativeVectorRef_());
407  Epetra_MultiVector& epVecResult =
408  const_cast<Epetra_MultiVector&>(nonConstResult.epetraObj());
409 
410  int errorCode = ifpackPreconditionerPtr_->
411  ApplyInverse(epVecInput, epVecResult);
412 
413  // Unset the transpose call
414  if (useTranspose)
415  ifpackPreconditionerPtr_->SetUseTranspose(false);
416 
417  return true;
418 }
419 
420 //-----------------------------------------------------------------------------
421 // Function : SharedSystem::getSolutionVector
422 // Purpose :
423 // Special Notes :
424 // Scope : public
425 // Creator :
426 // Creation Date :
427 //-----------------------------------------------------------------------------
429 {
430  return *xyceSolnPtr_;
431 }
432 
433 //-----------------------------------------------------------------------------
434 // Function : SharedSystem::getJacobian
435 // Purpose :
436 // Special Notes :
437 // Scope : public
438 // Creator :
439 // Creation Date :
440 //-----------------------------------------------------------------------------
441 const Linear::Matrix& SharedSystem::getJacobian() const
442 {
443  return *xyceJacobianPtr_;
444 }
445 
446 //-----------------------------------------------------------------------------
447 // Function : SharedSystem::getJacobian
448 // Purpose :
449 // Special Notes :
450 // Scope : public
451 // Creator :
452 // Creation Date :
453 //-----------------------------------------------------------------------------
454 Linear::Matrix& SharedSystem::getJacobian(const Group* grp)
455 {
456  ownerOfJacobian_ = grp;
457  return *xyceJacobianPtr_;
458 }
459 
460 //-----------------------------------------------------------------------------
461 // Function : SharedSystem::getStateVectors
462 // Purpose :
463 // Special Notes :
464 // Scope : public
465 // Creator :
466 // Creation Date :
467 //-----------------------------------------------------------------------------
469 {
470  ownerOfStateVectors_ = grp;
471 }
472 
473 //-----------------------------------------------------------------------------
474 // Function : SharedSystem::getLasSystem
475 // Purpose :
476 // Special Notes :
477 // Scope : public
478 // Creator :
479 // Creation Date :
480 //-----------------------------------------------------------------------------
481 Linear::System* SharedSystem::getLasSystem()
482 {
483  return xyceLasSysPtr_;
484 }
485 
486 //-----------------------------------------------------------------------------
487 // Function : SharedSystem::cloneSolutionVector
488 // Purpose :
489 // Special Notes :
490 // Scope : public
491 // Creator :
492 // Creation Date :
493 //-----------------------------------------------------------------------------
495 {
496  Vector* tmpVectorPtr = 0;
497  tmpVectorPtr =
498  dynamic_cast<Vector*>(xyceSolnPtr_->clone(NOX::DeepCopy).release().get());
499 
500  if (tmpVectorPtr == 0) {
501  const string message =
502  "SharedSystem::cloneSolutionVector() - dynamic cast/ memory allocation failure!";
503  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, message);
504  }
505 
506  return (tmpVectorPtr);
507 }
508 
509 //-----------------------------------------------------------------------------
510 // Function : SharedSystem:: getNewtonVector
511 // Purpose :
512 // Special Notes :
513 // Scope : public
514 // Creator :
515 // Creation Date :
516 //-----------------------------------------------------------------------------
518 {
519  return *xyceNewtonPtr_;
520 }
521 
522 //-----------------------------------------------------------------------------
523 // Function : SharedSystem::debugOutput1
524 // Purpose :
525 // Special Notes :
526 // Scope : public
527 // Creator :
528 // Creation Date :
529 //-----------------------------------------------------------------------------
531  (Linear::Matrix & jacobian, Linear::Vector & rhs)
532 {
533  xyceInterfacePtr_->debugOutput1(jacobian, rhs);
534 }
535 
536 //-----------------------------------------------------------------------------
537 // Function : SharedSystem::debugOutput3
538 // Purpose :
539 // Special Notes :
540 // Scope : public
541 // Creator :
542 // Creation Date :
543 //-----------------------------------------------------------------------------
545  (Linear::Vector & dxVector, Linear::Vector & xVector)
546 {
547  xyceInterfacePtr_->debugOutput3(dxVector, xVector);
548 }
549 
550 }}}
Teuchos::RCP< NOX::Abstract::Vector > clone(NOX::CopyType type=NOX::DeepCopy) const
bool areStateVectors(const Group *grp) const
bool applyJacobian(const Vector &input, Vector &result) const
void reset(Xyce::Linear::Vector &x, Xyce::Linear::Vector &f, Xyce::Linear::Matrix &jacobian, Xyce::Linear::Vector &newton, Xyce::Linear::Vector &gradient, Xyce::Linear::System &lasSys, Interface &interface)
const NOX::Abstract::Vector & getX() const
const Xyce::Linear::Vector & getNativeVectorRef_() const
bool computeNewton(const Vector &F, Vector &Newton, Teuchos::ParameterList &params)
Pure virtual class to augment a linear system.
bool applyJacobianTranspose(const Vector &input, Vector &result) const
NOX::Abstract::Group::ReturnType computeF()
const Xyce::Linear::Vector & getNativeVectorRef() const
bool computeNewton(Teuchos::ParameterList &p)
void debugOutput3(Xyce::Linear::Vector &dxVector, Xyce::Linear::Vector &xVector)
NOX::Abstract::Vector & scale(double gamma)
bool applyRightPreconditioning(bool useTranspose, Teuchos::ParameterList &params, const Vector &input, Vector &result)
SharedSystem(Xyce::Linear::Vector &x, Xyce::Linear::Vector &f, Xyce::Linear::Matrix &jacobian, Xyce::Linear::Vector &newton, Xyce::Linear::Vector &gradient, Xyce::Linear::System &lasSys, Interface &interface)
const Xyce::Linear::Matrix & getJacobian() const
bool applyJacobian(const Xyce::Linear::Vector &input, Xyce::Linear::Vector &result)
bool computeGradient(const Vector &F, Vector &Gradient)
bool computeF(const Vector &solution, Vector &F, const Group *grp)
void debugOutput1(Xyce::Linear::Matrix &jacobian, Xyce::Linear::Vector &rhs)