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