Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_NLS_LOCA_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_LOCA_Group.C,v $
27 //
28 // Purpose : Interface to Xyce for LOCA continuation routines.
29 //
30 // Special Notes :
31 //
32 // Creator : Roger Pawlowski, SNL 9233
33 //
34 // Creation Date : 02/17/03
35 //
36 // Revision Information:
37 // ---------------------
38 //
39 // Revision Number: $Revision: 1.53 $
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 #include <N_UTL_Misc.h>
53 
54 #include <N_NLS_LOCA_Group.h>
55 #include <N_NLS_NOX_SharedSystem.h>
57 #include <N_LAS_Vector.h>
58 #include <N_LAS_Matrix.h>
59 #include <N_LAS_System.h>
60 #include <N_LAS_Builder.h>
61 #include <N_ERH_ErrorMgr.h>
62 #include <N_LOA_Loader.h>
63 #include <N_IO_OutputMgr.h>
64 #include <N_ANP_AnalysisManager.h>
65 
66 // ---------- NOX Includes ----------
67 #include <Teuchos_ParameterList.hpp>
68 #include <NOX_Abstract_Vector.H>
69 #include <LOCA_Parameter_Vector.H>
70 
71 using namespace N_NLS_NOX;
72 
73 namespace N_NLS_LOCA {
74 
75 //-----------------------------------------------------------------------------
76 // Function : Group::Group
77 // Purpose : constructor
78 // Special Notes :
79 // Scope : public
80 // Creator :
81 // Creation Date :
82 //-----------------------------------------------------------------------------
83 Group::Group(Teuchos::RefCountPtr<LOCA::GlobalData> gd,
84  N_NLS_NOX::SharedSystem& s, N_LOA_Loader& l,
85  N_IO_OutputMgr& o, N_ANP_AnalysisManager & t) :
86  N_NLS_NOX::Group(s),
87  LOCA::Abstract::Group(gd),
88  loader(l),
89  outputMgr(o),
90  anaInt(t),
91  derivUtils(gd),
92  tmpVectorPtr(0),
93  scalingVecPtr(0),
94  useAugmentLinSys_(false),
95  outputLinear_(false),
96  serialNumber_(0),
97  op_(0),
98  allNodes_(0),
99  pdsCommPtr_(0),
100  nonContinuationSolve_(true)
101 {
102  tmpVectorPtr = sharedSystemPtr_->getLasSystem()->builder().createVector();
103 }
104 
105 //-----------------------------------------------------------------------------
106 // Function : Group::Group
107 // Purpose : constructor
108 // Special Notes :
109 // Scope : public
110 // Creator :
111 // Creation Date :
112 //-----------------------------------------------------------------------------
113 Group::Group(const Group& source, NOX::CopyType type) :
114  N_NLS_NOX::Group(source, type),
115  LOCA::Abstract::Group(source, type),
116  loader(source.loader),
117  outputMgr(source.outputMgr),
118  anaInt(source.anaInt),
119  params(source.params),
120  derivUtils(source.derivUtils),
121  tmpVectorPtr(0),
122  scalingVecPtr(source.scalingVecPtr),
123  useAugmentLinSys_(source.useAugmentLinSys_),
124  outputLinear_(source.outputLinear_),
125  serialNumber_(source.serialNumber_),
126  oldSol_(source.oldSol_),
127  op_(source.op_),
128  allNodes_(source.allNodes_),
129 #ifdef Xyce_PARALLEL_MPI
130  pdsCommPtr_(source.pdsCommPtr_),
131 #endif
132  augmentLSStrategy_(source.augmentLSStrategy_),
133  nonContinuationSolve_(source.nonContinuationSolve_)
134 {
135  tmpVectorPtr = sharedSystemPtr_->getLasSystem()->builder().createVector();
136 }
137 
138 //-----------------------------------------------------------------------------
139 // Function : Group::~Group
140 // Purpose : destructor
141 // Special Notes :
142 // Scope : public
143 // Creator :
144 // Creation Date :
145 //-----------------------------------------------------------------------------
147 {
148  delete tmpVectorPtr;
149 }
150 
151 //-----------------------------------------------------------------------------
152 // Function : Group::operator=
153 // Purpose :
154 // Special Notes :
155 // Scope : public
156 // Creator :
157 // Creation Date :
158 //-----------------------------------------------------------------------------
159 NOX::Abstract::Group&
160 Group::operator=(const NOX::Abstract::Group& source)
161 {
162  return operator=(dynamic_cast<const Group&>(source));
163 }
164 
165 //-----------------------------------------------------------------------------
166 // Function : Group::operator=
167 // Purpose :
168 // Special Notes :
169 // Scope : public
170 // Creator :
171 // Creation Date :
172 //-----------------------------------------------------------------------------
175 {
176  return operator=(dynamic_cast<const Group&>(source));
177 }
178 
179 //-----------------------------------------------------------------------------
180 // Function : Group::operator=
181 // Purpose :
182 // Special Notes :
183 // Scope : public
184 // Creator :
185 // Creation Date :
186 //-----------------------------------------------------------------------------
187 LOCA::Abstract::Group&
188 Group::operator=(const LOCA::Abstract::Group& source)
189 {
190  return operator=(dynamic_cast<const Group&>(source));
191 }
192 
193 //-----------------------------------------------------------------------------
194 // Function : Group::operator=
195 // Purpose :
196 // Special Notes :
197 // Scope : public
198 // Creator :
199 // Creation Date :
200 //-----------------------------------------------------------------------------
201 Group&
202 Group::operator=(const Group& source)
203 {
205  params = source.params;
206  derivUtils = source.derivUtils;
207  if (source.scalingVecPtr != 0)
208  scalingVecPtr = source.scalingVecPtr;
211  return *this;
212 }
213 
214 //-----------------------------------------------------------------------------
215 // Function : Group::copy
216 // Purpose :
217 // Special Notes :
218 // Scope : public
219 // Creator :
220 // Creation Date :
221 //-----------------------------------------------------------------------------
222 void Group::copy(const NOX::Abstract::Group &source)
223 {
224  *this = source;
225 }
226 
227 //-----------------------------------------------------------------------------
228 // Function : Group::clone
229 // Purpose :
230 // Special Notes :
231 // Scope : public
232 // Creator :
233 // Creation Date :
234 //-----------------------------------------------------------------------------
235 Teuchos::RefCountPtr<NOX::Abstract::Group> Group::
236 clone(NOX::CopyType type) const
237 {
238  Teuchos::RefCountPtr<Group> ptr =
239  Teuchos::rcp(new Group(*this, type));
240  return ptr;
241 }
242 
243 //-----------------------------------------------------------------------------
244 // Function : Group::computeF()
245 // Purpose :
246 // Special Notes :
247 // Scope : public
248 // Creator :
249 // Creation Date :
250 //-----------------------------------------------------------------------------
251 NOX::Abstract::Group::ReturnType Group::computeF()
252 {
253  // Set continuation parameters, if neccessary
254  // Note: If the tranOP solve was a continuation, but the
255  // transient is traditional Newton, make SURE that the
256  // setParam calls are not happening for transient!
258  {
259  for (int i = 0; i < params.length(); ++i) {
260  std::string label = params.getLabel(i);
261  loader.setParam(label, params.getValue(i));
262 
263  if (label == "GSTEPPING" && useAugmentLinSys_)
264  augmentLSStrategy_->setProgressVariable(params.getValue(i));
265 
266  }
267  }
268 
269  NOX::Abstract::Group::ReturnType status = N_NLS_NOX::Group::computeF();
270 
271  if (useAugmentLinSys_)
272  augmentLSStrategy_->augmentResidual(xVec_.getNativeVectorPtr(),
274 
275  return status;
276 }
277 
278 //-----------------------------------------------------------------------------
279 // Function : Group::computeJacobian()
280 // Purpose :
281 // Special Notes :
282 // Scope : public
283 // Creator :
284 // Creation Date :
285 //-----------------------------------------------------------------------------
286 NOX::Abstract::Group::ReturnType Group::computeJacobian()
287 {
288  // Set continuation parameters, if neccessary
289  // Note: If the tranOP solve was a continuation, but the
290  // transient is traditional Newton, make SURE that the
291  // setParam calls are not happening for transient!
293  {
294  for (int i = 0; i < params.length(); ++i) {
295  std::string label = params.getLabel(i);
296  loader.setParam(label, params.getValue(i));
297 
298  if (label == "GSTEPPING" && useAugmentLinSys_)
299  augmentLSStrategy_->setProgressVariable(params.getValue(i));
300 
301  }
302  }
303 
304  NOX::Abstract::Group::ReturnType status =
306 
307  // Augment jacobian for pseudo transient if enabled
308  if (useAugmentLinSys_) {
309  N_LAS_Matrix& jacobian =
310  const_cast<N_LAS_Matrix&>(sharedSystemPtr_->getJacobian());
311  augmentLSStrategy_->augmentJacobian(&jacobian);
312  }
313 
314  if (outputLinear_)
315  {
316  N_LAS_Matrix& jacobian =
317  const_cast<N_LAS_Matrix&>(sharedSystemPtr_->getJacobian());
318  Xyce::dout() << "After computeJacobian, linear system is:" << std::endl;
321  }
322 
323 #ifdef Xyce_DEBUG_NONLINEAR
324  N_LAS_Matrix& jacobian =
325  const_cast<N_LAS_Matrix&>(sharedSystemPtr_->getJacobian());
326  sharedSystemPtr_->debugOutput1( jacobian,
327  (*(fVec_.getNativeVectorPtr())));
328 #endif
329 
330  return status;
331 }
332 
333 //-----------------------------------------------------------------------------
334 // Function : Group::setOutputLinear
335 // Purpose :
336 // Special Notes : for DCOP restart (debugging)
337 // Scope : public
338 // Creator : Dave Shirley
339 // Creation Date : 2006
340 //-----------------------------------------------------------------------------
341 void Group::setOutputLinear (Xyce::NodeNamePairMap * op,
342  Xyce::NodeNamePairMap * allNodes,
343  N_PDS_Comm * pdsCommPtr)
344 {
345  op_ = op;
346  allNodes_ = allNodes;
347  pdsCommPtr_ = pdsCommPtr;
348  outputLinear_ = true;
349  serialNumber_ = 0;
350 }
351 
352 //-----------------------------------------------------------------------------
353 // Function : Group::outputLinearSystem_
354 // Purpose :
355 // Special Notes : for DCOP restart (debugging)
356 // Scope : private
357 // Creator : Dave Shirly
358 // Creation Date : 2006
359 //-----------------------------------------------------------------------------
360 void Group::outputLinearSystem_ (N_LAS_Matrix* jacobian,
361  N_LAS_Vector* solPtr_,
362  N_LAS_Vector* resPtr_)
363 {
364  Xyce::NodeNamePairMap::iterator op_i;
365  Xyce::NodeNamePairMap::iterator op_end;
366  int i, row, global_row;
367  int num;
368  std::vector<int> col;
369  std::vector<double> val;
370  std::map<int,std::string> rowOut;
371  int rowLen, GID;
372 
373  if (!outputLinear_)
374  return;
375 
376 #ifdef Xyce_PARALLEL_MPI
377  N_PDS_ParMap * pmap_;
378  pmap_ = resPtr_->pmap();
379  int procID = pdsCommPtr_->procID();
380 #endif
381  op_i = allNodes_->begin();
382  op_end = allNodes_->end();
383  for ( ; op_i != op_end ; ++op_i)
384  {
385  std::ostringstream s;
386  row = (*op_i).second.first;
387 #ifdef Xyce_PARALLEL_MPI
388  global_row = pmap_->localToGlobalIndex(row);
389 #else
390  global_row = row;
391 #endif
392  s << "Global: " << global_row << " : " << (*op_i).first << " Row: " << global_row;
393  s << " Value: " << (*solPtr_)[row];
394  if (serialNumber_ > 0)
395  {
396  s << std::endl;
397  s << " Delta Value: " << (*solPtr_)[row] - oldSol_[row];
398  s << std::endl;
399  }
400  oldSol_[row] = (*solPtr_)[row];
401  s << " Residual: " << (*resPtr_)[row];
402 #ifdef Xyce_PARALLEL_MPI
403  s << " proc: " << procID;
404 #endif
405  s << std::endl;
406  rowLen = jacobian->getLocalRowLength(row);
407  col.resize(rowLen);
408  val.resize(rowLen);
409  jacobian->getRowCopy(global_row, rowLen, rowLen, &val[0], &col[0]);
410  for (i=0 ; i<rowLen ; i++)
411  {
412  if (i>1 && i%10 == 0)
413  s << std::endl;
414  GID = col[i];
415  s << " " << GID << "(" << val[i] << ")";
416  }
417  rowOut[global_row] = s.str();
418  }
419  serialNumber_++;
420  std::map<int,std::string>::iterator row_i;
421  std::map<int,std::string>::iterator row_end = rowOut.end();
422  row_i = rowOut.begin();
423  std::string str;
424 #ifdef Xyce_PARALLEL_MPI
425  int numG;
426  int pos, posG;
427  int len;
428  std::string buf;
429 #endif
430  int big=2000000000;
431  for ( ; ; ++row_i )
432  {
433  if (row_i == row_end)
434  {
435  str = "";
436  num = big;
437  }
438  else
439  {
440  str = (*row_i).second;
441  num = (*row_i).first;
442  }
443 #ifdef Xyce_PARALLEL_MPI
444  numG = -1;
445  while (numG != num)
446  {
447  pdsCommPtr_->minAll (&num, &numG, 1);
448  if (numG == big)
449  break;
450  if (num == numG)
451  pos = procID;
452  else
453  pos = 0;
454  pdsCommPtr_->sumAll (&pos, &posG, 1);
455  if (procID == 0)
456  {
457  if (posG != 0)
458  {
459  pdsCommPtr_->recv(&len, 1, posG);
460  buf.resize(len);
461  pdsCommPtr_->recv(&buf[0], len, posG);
462  Xyce::dout() << buf << std::endl;
463  }
464  else
465  Xyce::dout() << str << std::endl;
466  }
467  else if (procID == posG)
468  {
469  len = str.size();
470  pdsCommPtr_->send(&len, 1, 0);
471  pdsCommPtr_->send(str.c_str(), len, 0);
472  }
473  }
474  if (numG == big)
475  break;
476 #else
477  Xyce::dout() << str << std::endl;
478  if (num == big)
479  break;
480 #endif
481  }
482 }
483 
484 //-----------------------------------------------------------------------------
485 // Function : Group::setParams
486 // Purpose :
487 // Special Notes :
488 // Scope : public
489 // Creator :
490 // Creation Date :
491 //-----------------------------------------------------------------------------
492 void Group::setParams(const LOCA::ParameterVector& p)
493 {
495  params = p;
496  return;
497 }
498 
499 //-----------------------------------------------------------------------------
500 // Function : Group::getParams
501 // Purpose :
502 // Special Notes :
503 // Scope : public
504 // Creator :
505 // Creation Date :
506 //-----------------------------------------------------------------------------
507 const LOCA::ParameterVector& Group::getParams() const
508 {
509  return params;
510 }
511 
512 //-----------------------------------------------------------------------------
513 // Function : Group::setParam
514 // Purpose :
515 // Special Notes :
516 // Scope : public
517 // Creator :
518 // Creation Date :
519 //-----------------------------------------------------------------------------
520 void Group::setParam(int paramID, double value)
521 {
523  params.setValue(paramID, value);
524  return;
525 }
526 
527 //-----------------------------------------------------------------------------
528 // Function : Group::getParam
529 // Purpose :
530 // Special Notes :
531 // Scope : public
532 // Creator :
533 // Creation Date :
534 //-----------------------------------------------------------------------------
535 double Group::getParam(int paramID) const
536 {
537  return params.getValue(paramID);
538 }
539 
540 //-----------------------------------------------------------------------------
541 // Function : Group::setParam
542 // Purpose :
543 // Special Notes :
544 // Scope : public
545 // Creator :
546 // Creation Date :
547 //-----------------------------------------------------------------------------
548 void Group::setParam(std::string paramID, double value)
549 {
551  params.setValue(paramID, value);
552  return;
553 }
554 
555 //-----------------------------------------------------------------------------
556 // Function : Group::getParam
557 // Purpose :
558 // Special Notes :
559 // Scope : public
560 // Creator :
561 // Creation Date :
562 //-----------------------------------------------------------------------------
563 double Group::getParam(std::string paramID) const
564 {
565  return params.getValue(paramID);
566 }
567 
568 //-----------------------------------------------------------------------------
569 // Function : Group::setScaleVec
570 // Purpose :
571 // Special Notes :
572 // Scope : public
573 // Creator :
574 // Creation Date :
575 //-----------------------------------------------------------------------------
576 void Group::setScaleVec(const NOX::Abstract::Vector& s)
577 {
578  scalingVecPtr = &s;
579 }
580 
581 //-----------------------------------------------------------------------------
582 // Function : Group::getScaleVec()
583 // Purpose :
584 // Special Notes :
585 // Scope : public
586 // Creator :
587 // Creation Date :
588 //-----------------------------------------------------------------------------
589 const NOX::Abstract::Vector& Group::getScaleVec() const
590 {
591  if (scalingVecPtr == 0) {
592  const std::string message = "Group::getScaleVec() - scaling vector not set!";
593  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, message);
594  }
595 
596  return (*scalingVecPtr);
597 }
598 
599 //-----------------------------------------------------------------------------
600 // Function : Group::augmentJacobianForHomotopy
601 // Purpose :
602 // Special Notes :
603 // Scope : public
604 // Creator :
605 // Creation Date :
606 //-----------------------------------------------------------------------------
607 NOX::Abstract::Group::ReturnType
609 {
610 
611  N_LAS_Matrix& jacobian =
612  const_cast<N_LAS_Matrix&>(sharedSystemPtr_->getJacobian());
613 
614  //jacobian.printPetraObject();
615  jacobian.scale(conParamValue);
616  jacobian.getDiagonal(*tmpVectorPtr);
617  (*tmpVectorPtr).addScalar(1.0 - conParamValue);
618  jacobian.replaceDiagonal(*tmpVectorPtr);
619  //jacobian.printPetraObject();
620 
621  return NOX::Abstract::Group::Ok;
622 }
623 
624 //-----------------------------------------------------------------------------
625 // Function : Group::printSolution
626 // Purpose :
627 // Special Notes :
628 // Scope : public
629 // Creator :
630 // Creation Date :
631 //-----------------------------------------------------------------------------
632 void Group::printSolution (const double conParam) const
633 {
634  // ERK: This is a KLUDGE! I put it here because the "printSolution"
635  // functions were the only place in this class that were called
636  // only after a continuation step was successful.
637  //
638  // Note: homotopy output is now called from the time integrator,
639  // so it is this function still results in the the solution being
640  // printed.
641  //
642  // Note: This will be replaced by "stepSuccess" (see below), once
643  // stepSuccess completely works.
645  (params.getNamesVector(),
646  params.getValuesVector(),
648 
649  return;
650 }
651 
652 //-----------------------------------------------------------------------------
653 // Function : Group::printSolution
654 // Purpose :
655 // Special Notes :
656 // Scope : public
657 // Creator :
658 // Creation Date :
659 //-----------------------------------------------------------------------------
660 void Group::printSolution (const NOX::Abstract::Vector &x,
661  const double conParam) const
662 {
663  const N_NLS_NOX::Vector& noxVector =
664  dynamic_cast<const N_NLS_NOX::Vector&>(x);
665 
666  // ERK: This is a KLUDGE! I put it here because the "printSolution"
667  // functions were the only place in this class that were called
668  // only after a continuation step was successful.
669  //
670  // Note: homotopy output is now called from the time integrator,
671  // so it is this function still results in the the solution being
672  // printed.
673  //
674  // Note: This will be replaced by "stepSuccess" (see below), once
675  // stepSuccess completely works.
677  (params.getNamesVector(),
678  params.getValuesVector(),
680 
681  return;
682 }
683 
684 //-----------------------------------------------------------------------------
685 // Function : Group::stepFailed
686 // Purpose :
687 // Special Notes :
688 // Scope : public
689 // Creator :
690 // Creation Date :
691 //-----------------------------------------------------------------------------
693 {
694 #ifdef Xyce_DEBUG_NONLINEAR
695  Xyce::dout() << "In Group::stepFailed" << std::endl;
696 #endif
698 }
699 
700 //-----------------------------------------------------------------------------
701 // Function : Group::stepSucceeded
702 // Purpose :
703 // Special Notes :
704 // Scope : public
705 // Creator :
706 // Creation Date :
707 //-----------------------------------------------------------------------------
709 {
710 #ifdef Xyce_DEBUG_NONLINEAR
711  Xyce::dout() << "In Group::stepSucceeded" << std::endl;
712 #endif
713 #ifdef Xyce_UPDATED_LOCA
714  // Do nothing. Unfortunately, this function doesn't get called
715  // on the initial solve. (for continuation param = initial value)
716  // So, for now, still have to use the printSolution function, which
717  // is called every time.
718  const std::string message = "Group::stepSucceeded is not fully supported yet! Recompile without Xyce_UPDATED_LOCA defined\n";
719  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, message);
720 #endif
721 }
722 
723 //-----------------------------------------------------------------------------
724 // Function : Group::setAugmentLinearSystem
725 // Purpose :
726 // Special Notes :
727 // Scope : public
728 // Creator :
729 // Creation Date :
730 //-----------------------------------------------------------------------------
731 void Group::setAugmentLinearSystem(bool enable_value,
732  const Teuchos::RefCountPtr<N_NLS_NOX::AugmentLinSys>& ls)
733 {
734  useAugmentLinSys_ = enable_value;
735  augmentLSStrategy_ = ls;
736 }
737 
738 //-----------------------------------------------------------------------------
739 // Function : Group::setNonContinuationFlag
740 // Purpose :
741 // Special Notes :
742 // Scope : public
743 // Creator :
744 // Creation Date :
745 //-----------------------------------------------------------------------------
747 {
749 }
750 
751 //-----------------------------------------------------------------------------
752 // Function : Group::getNonContinuationFlag
753 // Purpose :
754 // Special Notes :
755 // Scope : public
756 // Creator :
757 // Creation Date :
758 //-----------------------------------------------------------------------------
760 {
761  return nonContinuationSolve_;
762 }
763 
764 } // namespace N_NLS_LOCA