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.44 $
40 //
41 // Revision Date : $Date: 2015/07/11 23:40:30 $
42 //
43 // Current Owner : $Author: erkeite $
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 std::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 std::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 std::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 std::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 std::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 std::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::computeDfDpMulti
335 // Purpose :
336 // Special Notes :
337 // Scope : public
338 // Creator : Eric Keiter
339 // Creation Date :
340 //-----------------------------------------------------------------------------
342  (const std::vector< int > & paramIDs,
343  NOX::Abstract::MultiVector & dfdp,
344  bool isValidF)
345 {
346  bool status = xyceInterfacePtr_->computeDfDpMulti
347  (paramIDs, dfdp, isValidF);
348 
349  return status;
350 }
351 
352 //-----------------------------------------------------------------------------
353 // Function : SharedSystem::computePreconditioner
354 // Purpose :
355 // Special Notes :
356 // Scope : public
357 // Creator :
358 // Creation Date :
359 //-----------------------------------------------------------------------------
361 {
362  Epetra_CrsMatrix* crs = dynamic_cast<Epetra_CrsMatrix*>
363  (&(xyceJacobianPtr_->epetraObj()));
364 
365  if (crs == 0) {
366  dout() << "SharedSystem::computePreconditioner() - "
367  << "Dynamic cast to CRS Matrix failed!" << std::endl;
368  }
369 
371  ifpackGraphPtr_ = new Ifpack_IlukGraph(crs->Graph(),
372  1,
373  0);
374  ifpackGraphPtr_->ConstructFilledGraph();
375  ifpackPreconditionerPtr_ = new Ifpack_CrsRiluk(*ifpackGraphPtr_);
376  ifpackPreconditionerPtr_->InitValues(*crs);
377  ifpackPreconditionerPtr_->Factor();
378  return true;
379 }
380 
381 //-----------------------------------------------------------------------------
382 // Function : SharedSystem::deletePreconditioner
383 // Purpose :
384 // Special Notes :
385 // Scope : public
386 // Creator :
387 // Creation Date :
388 //-----------------------------------------------------------------------------
390 {
392  delete ifpackGraphPtr_;
394  ifpackGraphPtr_ = 0;
395  return true;
396 }
397 
398 //-----------------------------------------------------------------------------
399 // Function : SharedSystem::applyRightPreconditioning
400 // Purpose :
401 // Special Notes :
402 // Scope : public
403 // Creator :
404 // Creation Date :
405 //-----------------------------------------------------------------------------
407  Teuchos::ParameterList& params,
408  const Vector& input,
409  Vector& result)
410 {
411  if (ifpackPreconditionerPtr_ == 0) {
412  const std::string message = "SharedSystem::applyRightPreconditioning - Preconditioner is 0!";
413  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, message);
414  }
415 
416  if (useTranspose)
417  ifpackPreconditionerPtr_->SetUseTranspose(useTranspose);
418 
419  Linear::Vector& nonConstInput =
420  const_cast<Linear::Vector&>(input.getNativeVectorRef_());
421  Epetra_MultiVector& epVecInput =
422  const_cast<Epetra_MultiVector&>(nonConstInput.epetraObj());
423 
424  Linear::Vector& nonConstResult =
425  const_cast<Linear::Vector&>(result.getNativeVectorRef_());
426  Epetra_MultiVector& epVecResult =
427  const_cast<Epetra_MultiVector&>(nonConstResult.epetraObj());
428 
429  int errorCode = ifpackPreconditionerPtr_->
430  ApplyInverse(epVecInput, epVecResult);
431 
432  // Unset the transpose call
433  if (useTranspose)
434  ifpackPreconditionerPtr_->SetUseTranspose(false);
435 
436  return true;
437 }
438 
439 //-----------------------------------------------------------------------------
440 // Function : SharedSystem::getSolutionVector
441 // Purpose :
442 // Special Notes :
443 // Scope : public
444 // Creator :
445 // Creation Date :
446 //-----------------------------------------------------------------------------
448 {
449  return *xyceSolnPtr_;
450 }
451 
452 //-----------------------------------------------------------------------------
453 // Function : SharedSystem::getJacobian
454 // Purpose :
455 // Special Notes :
456 // Scope : public
457 // Creator :
458 // Creation Date :
459 //-----------------------------------------------------------------------------
460 const Linear::Matrix& SharedSystem::getJacobian() const
461 {
462  return *xyceJacobianPtr_;
463 }
464 
465 //-----------------------------------------------------------------------------
466 // Function : SharedSystem::getJacobian
467 // Purpose :
468 // Special Notes :
469 // Scope : public
470 // Creator :
471 // Creation Date :
472 //-----------------------------------------------------------------------------
473 Linear::Matrix& SharedSystem::getJacobian(const Group* grp)
474 {
475  ownerOfJacobian_ = grp;
476  return *xyceJacobianPtr_;
477 }
478 
479 //-----------------------------------------------------------------------------
480 // Function : SharedSystem::getStateVectors
481 // Purpose :
482 // Special Notes :
483 // Scope : public
484 // Creator :
485 // Creation Date :
486 //-----------------------------------------------------------------------------
488 {
489  ownerOfStateVectors_ = grp;
490 }
491 
492 //-----------------------------------------------------------------------------
493 // Function : SharedSystem::getLasSystem
494 // Purpose :
495 // Special Notes :
496 // Scope : public
497 // Creator :
498 // Creation Date :
499 //-----------------------------------------------------------------------------
500 Linear::System* SharedSystem::getLasSystem()
501 {
502  return xyceLasSysPtr_;
503 }
504 
505 //-----------------------------------------------------------------------------
506 // Function : SharedSystem::cloneSolutionVector
507 // Purpose :
508 // Special Notes :
509 // Scope : public
510 // Creator :
511 // Creation Date :
512 //-----------------------------------------------------------------------------
514 {
515  Vector* tmpVectorPtr = 0;
516  tmpVectorPtr =
517  dynamic_cast<Vector*>(xyceSolnPtr_->clone(NOX::DeepCopy).release().get());
518 
519  if (tmpVectorPtr == 0) {
520  const std::string message =
521  "SharedSystem::cloneSolutionVector() - dynamic cast/ memory allocation failure!";
522  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, message);
523  }
524 
525  return (tmpVectorPtr);
526 }
527 
528 //-----------------------------------------------------------------------------
529 // Function : SharedSystem:: getNewtonVector
530 // Purpose :
531 // Special Notes :
532 // Scope : public
533 // Creator :
534 // Creation Date :
535 //-----------------------------------------------------------------------------
537 {
538  return *xyceNewtonPtr_;
539 }
540 
541 //-----------------------------------------------------------------------------
542 // Function : SharedSystem::debugOutput1
543 // Purpose :
544 // Special Notes :
545 // Scope : public
546 // Creator :
547 // Creation Date :
548 //-----------------------------------------------------------------------------
550  (Linear::Matrix & jacobian, Linear::Vector & rhs)
551 {
552  xyceInterfacePtr_->debugOutput1(jacobian, rhs);
553 }
554 
555 //-----------------------------------------------------------------------------
556 // Function : SharedSystem::debugOutput3
557 // Purpose :
558 // Special Notes :
559 // Scope : public
560 // Creator :
561 // Creation Date :
562 //-----------------------------------------------------------------------------
564  (Linear::Vector & dxVector, Linear::Vector & xVector)
565 {
566  xyceInterfacePtr_->debugOutput3(dxVector, xVector);
567 }
568 
569 }}}
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)
bool computeDfDpMulti(const std::vector< int > &paramIDs, NOX::Abstract::MultiVector &dfdp, bool isValidF)