Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_NLS_NOX_Group.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_Group.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.32 $
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 
53 #include "N_NLS_NOX_Group.h"
54 #include "N_NLS_NOX.h"
55 #include "N_NLS_NOX_Vector.h"
56 #include "N_NLS_NOX_SharedSystem.h"
57 #include "N_LAS_Vector.h"
58 #include "N_ERH_ErrorMgr.h"
59 
60 // ---------- NOX Includes ----------
61 #include "NOX_Abstract_Vector.H"
62 
63 using namespace N_NLS_NOX;
64 
65 //-----------------------------------------------------------------------------
66 // Function : N_NLS_LOCA::Group::Group
67 // Purpose :
68 // Special Notes :
69 // Scope : public
70 // Creator :
71 // Creation Date :
72 //-----------------------------------------------------------------------------
74  sharedSystemPtr_(&s),
75  xVecPtr_(Teuchos::rcp(dynamic_cast<N_NLS_NOX::Vector*>(s.cloneSolutionVector()))),
76  xVec_(*xVecPtr_),
77  fVecPtr_(Teuchos::rcp_dynamic_cast<N_NLS_NOX::Vector>(xVec_.clone(NOX::ShapeCopy))),
78  fVec_(*fVecPtr_),
79  normF_(0.0),
80  haveSolverFactors_(false)
81 {
82  resetIsValid_();
83 }
84 
85 //-----------------------------------------------------------------------------
86 // Function : N_NLS_LOCA::Group::Group
87 // Purpose :
88 // Special Notes :
89 // Scope : public
90 // Creator :
91 // Creation Date :
92 //-----------------------------------------------------------------------------
93 Group::Group(const Group& source, NOX::CopyType type) :
94  sharedSystemPtr_(source.sharedSystemPtr_),
95  xVecPtr_(Teuchos::rcp_dynamic_cast<N_NLS_NOX::Vector>(source.getX().clone(type))),
96  xVec_(*xVecPtr_),
97  fVecPtr_(Teuchos::rcp_dynamic_cast<N_NLS_NOX::Vector>(xVec_.clone(NOX::ShapeCopy))),
98  fVec_(*fVecPtr_),
99  normF_(0.0),
100  haveSolverFactors_(false)
101 {
102  // Default the is valid flags to "false"
103  resetIsValid_();
104 
105  switch(type)
106  {
107  case NOX::DeepCopy:
108 
109  // Copy F
110  if (source.isF()) {
111  isValidF_ = true;
112  fVec_ = source.fVec_;
113  normF_ = source.normF_;
114  if (sharedSystemPtr_->areStateVectors(&source))
116  }
117 
118  // Take ownership of the Jacobian.
119  if (source.isJacobian()) {
120  //isValidJacobian_ = false;
121  isValidJacobian_ = true;
124  }
125 
126  // Copy Gradient Vector
127  if (source.isGradient()) {
128 
129  if (Teuchos::is_null(gradVecPtr_)) {
130  gradVecPtr_ = Teuchos::rcp_dynamic_cast<N_NLS_NOX::Vector>
131  (source.gradVecPtr_->clone(NOX::DeepCopy));
132  }
133  else
134  *gradVecPtr_ = *(source.gradVecPtr_);
135 
136  isValidGradient_ = true;
137  }
138 
139  // Copy Newton Vector
140  if (source.isNewton()) {
141 
142  if (Teuchos::is_null(newtonVecPtr_)) {
143  newtonVecPtr_ = Teuchos::rcp_dynamic_cast<N_NLS_NOX::Vector>
144  (source.newtonVecPtr_->clone(NOX::DeepCopy));
145  }
146  else
147  *newtonVecPtr_ = *(source.newtonVecPtr_);
148 
149  isValidNewton_ = true;
150  }
151 
152  break;
153 
154  case NOX::ShapeCopy:
155  resetIsValid_();
156  break;
157 
158  default:
159  const std::string message = "N_NLS::NOX::Group::Group() - Invalid ConstructorType for group copy constructor";
160  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, message);
161  }
162 }
163 
164 //-----------------------------------------------------------------------------
165 // Function : N_NLS_LOCA::Group::~Group
166 // Purpose :
167 // Special Notes :
168 // Scope : public
169 // Creator :
170 // Creation Date :
171 //-----------------------------------------------------------------------------
173 {
174 }
175 
176 //-----------------------------------------------------------------------------
177 // Function : N_NLS_LOCA::Group::operator=
178 // Purpose :
179 // Special Notes :
180 // Scope : public
181 // Creator :
182 // Creation Date :
183 //-----------------------------------------------------------------------------
184 NOX::Abstract::Group& Group::operator=(const NOX::Abstract::Group& source)
185 {
186  return operator=(dynamic_cast<const Group&>(source));
187 }
188 
189 //-----------------------------------------------------------------------------
190 // Function : N_NLS_LOCA::Group::operator=
191 // Purpose :
192 // Special Notes :
193 // Scope : public
194 // Creator :
195 // Creation Date :
196 //-----------------------------------------------------------------------------
197 NOX::Abstract::Group& Group::operator=(const Group& source)
198 {
199  resetIsValid_();
200 
201  // Copy solution vector
202  xVec_ = source.xVec_;
203 
204  // Copy residual vector and take ownership of state vectors
205  if (source.isF()) {
206  isValidF_ = true;
207  fVec_ = source.fVec_;
208  normF_ = source.normF_;
209  if (source.sharedSystemPtr_->areStateVectors(&source))
211  }
212 
213  // Copy the Jacobian by taking ownership of the shared system
214  if (source.isJacobian()) {
215  isValidJacobian_ = true;
218  }
219 
220  // Copy Gradient Vector
221  if ( source.isGradient() ) {
222 
223  if (Teuchos::is_null(gradVecPtr_)) {
224  gradVecPtr_ = Teuchos::rcp_dynamic_cast<N_NLS_NOX::Vector>
225  (source.gradVecPtr_->clone(NOX::DeepCopy));
226  }
227  else
228  *gradVecPtr_ = *(source.gradVecPtr_);
229 
230  isValidGradient_ = true;
231  }
232 
233  // Copy Newton Vector
234  if (source.isNewton()) {
235  if (Teuchos::is_null(newtonVecPtr_)) {
236  newtonVecPtr_ = Teuchos::rcp_dynamic_cast<N_NLS_NOX::Vector>
237  (source.newtonVecPtr_->clone(NOX::DeepCopy));
238  }
239  else
240  *newtonVecPtr_ = *(source.newtonVecPtr_);
241 
242  isValidNewton_ = true;
243  }
244 
245  return *this;
246 }
247 
248 //-----------------------------------------------------------------------------
249 // Function : N_NLS_LOCA::Group::setX
250 // Purpose :
251 // Special Notes :
252 // Scope : public
253 // Creator :
254 // Creation Date :
255 //-----------------------------------------------------------------------------
256 void Group::setX(const NOX::Abstract::Vector& input)
257 {
258  setX(dynamic_cast<const Vector&>(input));
259 }
260 
261 //-----------------------------------------------------------------------------
262 // Function : N_NLS_LOCA::Group::setX
263 // Purpose :
264 // Special Notes :
265 // Scope : public
266 // Creator :
267 // Creation Date :
268 //-----------------------------------------------------------------------------
269 void Group::setX(const Vector& input)
270 {
271  resetIsValid_();
272  xVec_ = input;
273 }
274 
275 
276 //-----------------------------------------------------------------------------
277 // Function : N_NLS_LOCA::Group::computeX
278 // Purpose :
279 // Special Notes :
280 // Scope : public
281 // Creator :
282 // Creation Date :
283 //-----------------------------------------------------------------------------
284 void Group::computeX(const NOX::Abstract::Group& grp,
285  const NOX::Abstract::Vector& d,
286  double step)
287 {
288  computeX(dynamic_cast<const Group&>(grp), dynamic_cast<const Vector&>(d),
289  step);
290 }
291 
292 //-----------------------------------------------------------------------------
293 // Function : N_NLS_LOCA::Group::computeX
294 // Purpose :
295 // Special Notes :
296 // Scope : public
297 // Creator :
298 // Creation Date :
299 //-----------------------------------------------------------------------------
300 void Group::computeX(const Group& grp, const Vector& d, double step)
301 {
302  resetIsValid_();
303  xVec_.update(step, d, 1.0, grp.getX(), 0.0);
304 }
305 
306 //-----------------------------------------------------------------------------
307 // Function : N_NLS_LOCA::Group::computeF
308 // Purpose :
309 // Special Notes :
310 // Scope : public
311 // Creator :
312 // Creation Date :
313 //-----------------------------------------------------------------------------
314 NOX::Abstract::Group::ReturnType Group::computeF()
315 {
316  if( isF() ) return Ok;
317 
319 
320  // Xyce computes "-f" for efficiency of Newton solve:
321  // "Js = f" instead of "Js = -f" We need the real F!
322  fVec_.scale(-1.0);
323 
324  normF_ = fVec_.norm();
325 
326  return (isF()?Ok:Failed);
327 }
328 
329 //-----------------------------------------------------------------------------
330 // Function : N_NLS_LOCA::Group::computeJacobian
331 // Purpose :
332 // Special Notes :
333 // Scope : public
334 // Creator :
335 // Creation Date :
336 //-----------------------------------------------------------------------------
337 NOX::Abstract::Group::ReturnType Group::computeJacobian()
338 {
339  if (isJacobian()) return Ok;
340 
342 
343  haveSolverFactors_ = false;
344 
345  return (isJacobian()?Ok:Failed);
346 }
347 
348 //-----------------------------------------------------------------------------
349 // Function : N_NLS_LOCA::Group::computeGradient
350 // Purpose :
351 // Special Notes :
352 // Scope : public
353 // Creator :
354 // Creation Date :
355 //-----------------------------------------------------------------------------
356 NOX::Abstract::Group::ReturnType Group::computeGradient()
357 {
358  if (isGradient()) return Ok;
359 
360  if (!isF())
361  throwError("computeGradient", "F is not Valid!");
362 
363  if (!isJacobian())
364  throwError("computeGradient", "Jacobian is not Valid!");
365 
366  if (Teuchos::is_null(gradVecPtr_))
367  gradVecPtr_ = Teuchos::rcp_dynamic_cast<N_NLS_NOX::Vector>
368  (fVec_.clone(NOX::ShapeCopy));
369 
370  NOX::Abstract::Group::ReturnType status =
372 
373  //isValidGradient_ = sharedSystemPtr_->computeGradient(fVec_, *gradVecPtr_);
374  if (status == Ok)
375  isValidGradient_ = true;
376  else
377  isValidGradient_ = false;
378 
379  return (isGradient()?Ok:Failed);
380 }
381 
382 //-----------------------------------------------------------------------------
383 // Function : N_NLS_LOCA::Group::computeNewton
384 // Purpose :
385 // Special Notes :
386 // Scope : public
387 // Creator :
388 // Creation Date :
389 //-----------------------------------------------------------------------------
390 NOX::Abstract::Group::ReturnType Group::computeNewton(Teuchos::ParameterList& params)
391 {
392  if (isNewton()) return Ok;
393 
394  if (!isF())
395  throwError("computeNewton", "F is not Valid!");
396 
397  if (!isJacobian())
398  throwError("computeNewton", "Jacobian is not Valid!");
399 
400  if (Teuchos::is_null(newtonVecPtr_))
401  newtonVecPtr_ = Teuchos::rcp_dynamic_cast<N_NLS_NOX::Vector>
402  (fVec_.clone(NOX::ShapeCopy));
403 
405 
406  haveSolverFactors_ = true;
407 
408  newtonVecPtr_->scale(-1.0);
409 
410  return (isNewton()?Ok:Failed);
411 }
412 
413 //-----------------------------------------------------------------------------
414 // Function : N_NLS_LOCA::Group::applyJacobian
415 // Purpose :
416 // Special Notes :
417 // Scope : public
418 // Creator :
419 // Creation Date :
420 //-----------------------------------------------------------------------------
421 NOX::Abstract::Group::ReturnType Group::applyJacobian(const NOX::Abstract::Vector& input, NOX::Abstract::Vector& result) const
422 {
423  return applyJacobian(dynamic_cast<const Vector&>(input), dynamic_cast<Vector&>(result));
424 }
425 
426 //-----------------------------------------------------------------------------
427 // Function : N_NLS_LOCA::Group::applyJacobian
428 // Purpose :
429 // Special Notes :
430 // Scope : public
431 // Creator :
432 // Creation Date :
433 //-----------------------------------------------------------------------------
434 NOX::Abstract::Group::ReturnType Group::applyJacobian(const Vector& input, Vector& result) const
435 {
436  if (!isJacobian()) {
437  throwError("applyJacobian", "Jacobian is not Valid!");
438 
439  //RPP Hack to get Homotopy working!!
440  //cout << "RPP: Inefficient Jacobian computation!!" << endl;
441  //(const_cast<N_NLS_NOX::Group*>(this))->computeF();
442  //(const_cast<N_NLS_NOX::Group*>(this))->computeJacobian();
443  }
444 
445  return (sharedSystemPtr_->applyJacobian(input, result)?Ok:Failed);
446 }
447 
448 //-----------------------------------------------------------------------------
449 // Function : N_NLS_LOCA::Group::applyJacobianTranspose
450 // Purpose :
451 // Special Notes :
452 // Scope : public
453 // Creator :
454 // Creation Date :
455 //-----------------------------------------------------------------------------
456 NOX::Abstract::Group::ReturnType Group::applyJacobianTranspose(const NOX::Abstract::Vector& input,
457  NOX::Abstract::Vector& result) const
458 {
459  return applyJacobianTranspose(dynamic_cast<const Vector&>(input),
460  dynamic_cast<Vector&>(result));
461 }
462 
463 //-----------------------------------------------------------------------------
464 // Function : N_NLS_LOCA::Group::applyJacobianTranspose
465 // Purpose :
466 // Special Notes :
467 // Scope : public
468 // Creator :
469 // Creation Date :
470 //-----------------------------------------------------------------------------
471 NOX::Abstract::Group::ReturnType Group::applyJacobianTranspose(const Vector& input, Vector& result) const
472 {
473  if (!isJacobian())
474  throwError("applyJacobianTranspose", "Jacobian is not Valid!");
475 
476  return (sharedSystemPtr_->applyJacobianTranspose(input, result)?Ok:Failed);
477 }
478 
479 //-----------------------------------------------------------------------------
480 // Function : N_NLS_LOCA::Group::applyJacobianInverse
481 // Purpose :
482 // Special Notes :
483 // Scope : public
484 // Creator :
485 // Creation Date :
486 //-----------------------------------------------------------------------------
487 NOX::Abstract::Group::ReturnType
488 Group::applyJacobianInverse(Teuchos::ParameterList& params,
489  const NOX::Abstract::Vector& input,
490  NOX::Abstract::Vector& result) const
491 {
492  return applyJacobianInverse(params, dynamic_cast<const Vector&>(input),
493  dynamic_cast<Vector&>(result));
494 }
495 
496 //-----------------------------------------------------------------------------
497 // Function : N_NLS_LOCA::Group::applyJacobianInverse
498 // Purpose :
499 // Special Notes :
500 // Scope : public
501 // Creator :
502 // Creation Date :
503 //-----------------------------------------------------------------------------
504 NOX::Abstract::Group::ReturnType
505 Group::applyJacobianInverse(Teuchos::ParameterList& params,
506  const Vector& input, Vector& result) const
507 {
508  if (!isJacobian())
509  throwError("applyJacobianInverse", "Jacobian is not Valid!");
510 
511  bool status = sharedSystemPtr_->computeNewton(input, result, params);
512 
513  haveSolverFactors_ = true;
514 
515  return (status ? Ok : Failed);
516 }
517 
518 //-----------------------------------------------------------------------------
519 // Function : N_NLS_LOCA::Group::applyRightPreconditioning
520 // Purpose :
521 // Special Notes :
522 // Scope : public
523 // Creator :
524 // Creation Date :
525 //-----------------------------------------------------------------------------
526 NOX::Abstract::Group::ReturnType
528  Teuchos::ParameterList& params,
529  const NOX::Abstract::Vector& input,
530  NOX::Abstract::Vector& result) const
531 {
532  return applyRightPreconditioning(useTranspose, params,
533  dynamic_cast<const Vector&>(input),
534  dynamic_cast<Vector&> (result));
535 }
536 
537 //-----------------------------------------------------------------------------
538 // Function : N_NLS_LOCA::Group::applyRightPreconditioning
539 // Purpose :
540 // Special Notes :
541 // Scope : public
542 // Creator :
543 // Creation Date :
544 //-----------------------------------------------------------------------------
545 NOX::Abstract::Group::ReturnType
547  Teuchos::ParameterList& params,
548  const Vector& input,
549  Vector& result) const
550 {
551  if (!isJacobian()) {
552  // throw error - Jacobian is not owned by this group
553  }
554 
555  if (!isValidPreconditioner_) {
557  isValidPreconditioner_ = true;
558  }
559  sharedSystemPtr_->applyRightPreconditioning(useTranspose, params,
560  input, result);
561 
562  return NOX::Abstract::Group::Ok;
563 }
564 
565 //-----------------------------------------------------------------------------
566 // Function : N_NLS_LOCA::Group::isF
567 // Purpose :
568 // Special Notes :
569 // Scope : public
570 // Creator :
571 // Creation Date :
572 //-----------------------------------------------------------------------------
573 bool Group::isF() const
574 {
575  return isValidF_;
576 }
577 
578 //-----------------------------------------------------------------------------
579 // Function : N_NLS_LOCA::Group::isJacobian
580 // Purpose :
581 // Special Notes :
582 // Scope : public
583 // Creator :
584 // Creation Date :
585 //-----------------------------------------------------------------------------
586 bool Group::isJacobian() const
587 {
589 }
590 
591 //-----------------------------------------------------------------------------
592 // Function : N_NLS_LOCA::Group::isGradient
593 // Purpose :
594 // Special Notes :
595 // Scope : public
596 // Creator :
597 // Creation Date :
598 //-----------------------------------------------------------------------------
599 bool Group::isGradient() const
600 {
601  return isValidGradient_;
602 }
603 
604 //-----------------------------------------------------------------------------
605 // Function : N_NLS_LOCA::Group::isNewton
606 // Purpose :
607 // Special Notes :
608 // Scope : public
609 // Creator :
610 // Creation Date :
611 //-----------------------------------------------------------------------------
612 bool Group::isNewton() const
613 {
614  return isValidNewton_;
615 }
616 
617 //-----------------------------------------------------------------------------
618 // Function : N_NLS_LOCA::Group::getX
619 // Purpose :
620 // Special Notes :
621 // Scope : public
622 // Creator :
623 // Creation Date :
624 //-----------------------------------------------------------------------------
625 const NOX::Abstract::Vector& Group::getX() const
626 {
627  return xVec_;
628 }
629 
630 //-----------------------------------------------------------------------------
631 // Function : N_NLS_LOCA::Group::getF
632 // Purpose :
633 // Special Notes :
634 // Scope : public
635 // Creator :
636 // Creation Date :
637 //-----------------------------------------------------------------------------
638 const NOX::Abstract::Vector& Group::getF() const
639 {
640  if (!isF()) {
641  throwError("getF",
642  "F is not current with respect to the solution vector!");
643  }
644 
645  return fVec_;
646 }
647 
648 //-----------------------------------------------------------------------------
649 // Function : N_NLS_LOCA::Group::getNormF
650 // Purpose :
651 // Special Notes :
652 // Scope : public
653 // Creator :
654 // Creation Date :
655 //-----------------------------------------------------------------------------
656 double Group::getNormF() const
657 {
658  if (!isF()) {
659  //cout << "N_NLS_NOX::Group::getNormF() - F is not current "
660  // << "with respect to the solution vector!" << endl;
661  //throw "NOX Error";
662  (const_cast<N_NLS_NOX::Group*>(this))->computeF();
663  }
664 
665  return normF_;
666 }
667 
668 //-----------------------------------------------------------------------------
669 // Function : N_NLS_LOCA::Group::getGradient
670 // Purpose :
671 // Special Notes :
672 // Scope : public
673 // Creator :
674 // Creation Date :
675 //-----------------------------------------------------------------------------
676 const NOX::Abstract::Vector& Group::getGradient() const
677 {
678  if (Teuchos::is_null(gradVecPtr_))
679  throwError("getGradient", "gradVecPtr_ is 0!");
680 
681  return *gradVecPtr_;
682 }
683 
684 //-----------------------------------------------------------------------------
685 // Function : N_NLS_LOCA::Group::getNewton
686 // Purpose :
687 // Special Notes :
688 // Scope : public
689 // Creator :
690 // Creation Date :
691 //-----------------------------------------------------------------------------
692 const NOX::Abstract::Vector& Group::getNewton() const
693 {
694  if (Teuchos::is_null(newtonVecPtr_))
695  {
696  throwError("getNewton", "newtonVecPtr_ is 0!");
697  }
698  return *newtonVecPtr_;
699 }
700 
701 //-----------------------------------------------------------------------------
702 // Function : N_NLS_LOCA::Group::clone
703 // Purpose :
704 // Special Notes :
705 // Scope : public
706 // Creator :
707 // Creation Date :
708 //-----------------------------------------------------------------------------
709 Teuchos::RefCountPtr<NOX::Abstract::Group>
710 Group::clone(NOX::CopyType type) const
711 {
712  Teuchos::RefCountPtr<Group> ptr = Teuchos::rcp(new Group(*this, type));
713  return ptr;
714 }
715 
716 //-----------------------------------------------------------------------------
717 // Function : N_NLS_LOCA::Group::resetIsValid
718 // Purpose :
719 // Special Notes :
720 // Scope : public
721 // Creator :
722 // Creation Date :
723 //-----------------------------------------------------------------------------
724 // resets the isValid flags to false
726 {
727  isValidF_ = false;
728  isValidGradient_ = false;
729  isValidJacobian_ = false;
730  isValidNewton_ = false;
731  isValidPreconditioner_ = false;
732 }
733 
734 //-----------------------------------------------------------------------------
735 // Function : N_NLS_LOCA::Group::throwError
736 // Purpose :
737 // Special Notes :
738 // Scope : public
739 // Creator :
740 // Creation Date :
741 //-----------------------------------------------------------------------------
742 void Group::throwError(std::string method, std::string message) const
743 {
744  const std::string leader = "N_NLS::NOX::Group::";
745  const std::string fcn = "() - ";
746 
747  std::string error = leader + method + fcn + message;
748 
749  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, error);
750 }
751 
752