Xyce  6.1
N_NLS_TwoLevelNewton.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_TwoLevelNewton.C,v $
27 //
28 // Purpose : Body for the two level Newton class.
29 //
30 // Special Notes :
31 //
32 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
33 //
34 // Creation Date : 10/20/02
35 //
36 // Revision Information:
37 // ---------------------
38 //
39 // Revision Number: $Revision: 1.162 $
40 //
41 // Revision Date : $Date $
42 //
43 // Current Owner : $Author: hkthorn $
44 //-------------------------------------------------------------------------
45 
46 #include <Xyce_config.h>
47 
48 
49 // ---------- Standard Includes ----------
50 #include <cstdio>
51 #include <string>
52 #include <list>
53 
54 // ---------- Xyce Includes ----------
55 #include <N_ANP_AnalysisManager.h>
56 #include <N_ERH_ErrorMgr.h>
57 #include <N_IO_OutputMgr.h>
58 #include <N_LAS_Builder.h>
59 #include <N_LAS_Matrix.h>
60 #include <N_LAS_System.h>
61 #include <N_LAS_Vector.h>
62 #include <N_LOA_Loader.h>
64 #include <N_NLS_DampedNewton.h>
65 #include <N_NLS_Manager.h>
66 #include <N_NLS_NOX_Interface.h>
67 #include <N_NLS_ReturnCodes.h>
68 #include <N_NLS_TwoLevelNewton.h>
69 #include <N_UTL_FeatureTest.h>
70 #include <N_UTL_OptionBlock.h>
71 #include <N_UTL_Param.h>
72 
73 // ---------- Static Declarations ----------
74 
75 namespace Xyce {
76 namespace Nonlinear {
77 
78 //-----------------------------------------------------------------------------
79 // Function : TwoLevelNewton::TwoLevelNewton
80 // Purpose : constructor
81 // Special Notes :
82 // Scope : public
83 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
84 // Creation Date : 10/20/02
85 //-----------------------------------------------------------------------------
87  bool noxFlag,
88  bool noxFlagInner,
89  const IO::CmdParse & cp)
90  : NonLinearSolver(cp),
91  twoLevelAlgorithm_(3),
92  twoLevelAlgorithmTran_(0),
93  maxOuterSteps_(20),
94  maxContSteps_(10),
95  contStep_(0),
96  setupOuterLoopParamsFlag_(false),
97  setupTranParamsFlag_(false),
98  externalAnalysisMode(DC_OP),
99  outerLoopActiveFlag_(true),
100  noxFlag_(noxFlag),
101  noxFlagInner_(noxFlagInner),//inner loop possibly different than outer loop.
102  numInterfaceNodesSetup_(false),
103  twoLevelCouplingMode_(FULL_PROBLEM),
104  savedRHSPtr_(0),
105  savedNextSolPtr_(0),
106  jdxpVectorPtr_(0),
107  numSubProblems_(0),
108  continuationType_(1),
109  innerLoopFailFatal_(true),
110  totalSolveFailFatal_(false),
111  doFullNewtonFinalEnforcement_(true),
112  nlsPassingPtr_(0),
113  increaseContScalar_(1.5),
114  decreaseContScalar_(0.2), // was 0.125
115  continuationCalledBefore_(false),
116  voltLimTol_(1.0e-6)
117 {
118  // allocate the "outer loop" and "inner loop" solvers.
119  if (noxFlag_)
120  {
122  }
123  else
124  {
126  }
127 
128  if (noxFlagInner_)
129  {
131  }
132  else
133  {
135  }
136 
139 
140 }
141 
142 //-----------------------------------------------------------------------------
143 // Function : TwoLevelNewton::~TwoLevelNewton
144 // Purpose : destructor
145 // Special Notes :
146 // Scope : public
147 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
148 // Creation Date : 10/20/02
149 //-----------------------------------------------------------------------------
151 {
152  delete nlsOuterPtr_;
153  delete nlsInnerPtr_;
154 
155  if (savedRHSPtr_!=0) delete savedRHSPtr_;
156  if (savedNextSolPtr_!=0) delete savedNextSolPtr_;
157 }
158 
159 //-----------------------------------------------------------------------------
160 // Function : TwoLevelNewton::registerAnalysisManager
161 // Purpose :
162 // Special Notes :
163 // Scope : public
164 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
165 // Creation Date : 10/20/02
166 //-----------------------------------------------------------------------------
168 {
169  bool bsuccess = true;
170  bool tmpBool = true;
171 
172  analysisManager_ = analysis_manager;
174  bsuccess = bsuccess && tmpBool;
175 
177  bsuccess = bsuccess && tmpBool;
178 
179  return bsuccess;
180 }
181 
182 //-----------------------------------------------------------------------------
183 // Function : TwoLevelNewton::registerTIADataStore
184 // Purpose :
185 // Special Notes :
186 // Scope : public
187 // Creator : Eric Keiter
188 // Creation Date :
189 //-----------------------------------------------------------------------------
191 {
192  bool bsuccess = true;
193  bool tmpBool = true;
194 
195  dsPtr_ = ptr;
196 
197  tmpBool = nlsOuterPtr_->registerTIADataStore(ptr);
198  bsuccess = bsuccess && tmpBool;
199 
200  tmpBool = nlsInnerPtr_->registerTIADataStore(ptr);
201  bsuccess = bsuccess && tmpBool;
202 
203  return bsuccess;
204 }
205 
206 
207 //-----------------------------------------------------------------------------
208 // Function : TwoLevelNewton::registerParallelMgr
209 // Purpose :
210 // Special Notes :
211 // Scope : public
212 // Creator : Eric Keiter
213 // Creation Date :
214 //-----------------------------------------------------------------------------
215 bool TwoLevelNewton::registerParallelMgr (N_PDS_Manager * ptr)
216 {
217  bool bsuccess = true;
218  bool tmpBool = true;
219 
220  pdsMgrPtr_ = ptr;
221 
222  tmpBool = nlsOuterPtr_->registerParallelMgr(ptr);
223  bsuccess = bsuccess && tmpBool;
224 
225  tmpBool = nlsInnerPtr_->registerParallelMgr(ptr);
226  bsuccess = bsuccess && tmpBool;
227 
228  return bsuccess;
229 }
230 
231 //-----------------------------------------------------------------------------
232 // Function : TwoLevelNewton::registerLinearSystem
233 // Purpose :
234 // Special Notes :
235 // Scope : public
236 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
237 // Creation Date : 10/20/02
238 //-----------------------------------------------------------------------------
239 bool TwoLevelNewton::registerLinearSystem (Linear::System * ptr)
240 {
241  bool bsuccess = true;
242  bool tmpBool = true;
243 
244  lasSysPtr_ = ptr;
245  tmpBool = nlsOuterPtr_->registerLinearSystem (ptr);
246  bsuccess = bsuccess && tmpBool;
247 
248  tmpBool = nlsInnerPtr_->registerLinearSystem (ptr);
249  bsuccess = bsuccess && tmpBool;
250 
251  return bsuccess;
252 }
253 
254 //-----------------------------------------------------------------------------
255 // Function : TwoLevelNewton::registerNonlinearEquationLoader
256 // Purpose :
257 // Special Notes :
258 // Scope : public
259 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
260 // Creation Date : 10/20/02
261 //-----------------------------------------------------------------------------
263 {
264  bool bsuccess = true;
265  bool tmpBool = true;
266 
267  nonlinearEquationLoader_ = loaderPtr_tmp;
268  tmpBool = nlsOuterPtr_->registerNonlinearEquationLoader(loaderPtr_tmp);
269  bsuccess = bsuccess && tmpBool;
270 
271  tmpBool = nlsInnerPtr_->registerNonlinearEquationLoader(loaderPtr_tmp);
272  bsuccess = bsuccess && tmpBool;
273 
274  return bsuccess;
275 }
276 
277 //-----------------------------------------------------------------------------
278 // Function : TwoLevelNewton::registerOutputMgr
279 // Purpose :
280 // Special Notes :
281 // Scope : public
282 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
283 // Creation Date : 9/23/03
284 //-----------------------------------------------------------------------------
285 bool TwoLevelNewton::registerOutputMgr (IO::OutputMgr * ptr)
286 {
287  bool bsuccess = true;
288  bool tmpBool = true;
289 
290  outMgrPtr_ = ptr;
291  tmpBool = nlsOuterPtr_->registerOutputMgr (ptr);
292  bsuccess = bsuccess && tmpBool;
293 
294  tmpBool = nlsInnerPtr_->registerOutputMgr (ptr);
295  bsuccess = bsuccess && tmpBool;
296 
297  return bsuccess;
298 }
299 
300 
301 //-----------------------------------------------------------------------------
302 // Function : TwoLevelNewton::getCouplingMode
303 // Purpose :
304 // Special Notes :
305 // Scope : public
306 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
307 // Creation Date : 12/05/02
308 //-----------------------------------------------------------------------------
310 {
311  return twoLevelCouplingMode_;
312 }
313 
314 //-----------------------------------------------------------------------------
315 // Function : TwoLevelNewton::getNumResidualLoads
316 // Purpose :
317 // Special Notes :
318 // Scope : public
319 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
320 // Creation Date : 10/20/02
321 //-----------------------------------------------------------------------------
323 {
324  int numResLoads = 0;
325  numResLoads += nlsOuterPtr_->getNumResidualLoads ();
326  numResLoads += numResidualLoads_;
327  return numResLoads;
328 }
329 
330 //-----------------------------------------------------------------------------
331 // Function : TwoLevelNewton::getNumJacobianLoads
332 // Purpose :
333 // Special Notes :
334 // Scope : public
335 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
336 // Creation Date : 10/20/02
337 //-----------------------------------------------------------------------------
339 {
340  int numJacLoads = 0;
341  numJacLoads += nlsOuterPtr_->getNumJacobianLoads ();
342  numJacLoads += numJacobianLoads_;
343  return numJacLoads;
344 }
345 
346 //-----------------------------------------------------------------------------
347 // Function : TwoLevelNewton::getNumLinearSolves
348 // Purpose :
349 // Special Notes :
350 // Scope : public
351 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
352 // Creation Date : 10/20/02
353 //-----------------------------------------------------------------------------
355 {
356  int numLinSolves = 0;
357  numLinSolves += nlsOuterPtr_->getNumLinearSolves ();
358  numLinSolves += numLinearSolves_;
359  return numLinSolves;
360 }
361 
362 //-----------------------------------------------------------------------------
363 // Function : TwoLevelNewton::getNumFailedLinearSolves
364 // Purpose :
365 // Special Notes :
366 // Scope : public
367 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
368 // Creation Date : 10/20/02
369 //-----------------------------------------------------------------------------
371 {
372  int numFLinSolves = 0;
373  numFLinSolves += nlsOuterPtr_->getNumFailedLinearSolves ();
374  numFLinSolves += numFailedLinearSolves_;
375  return numFLinSolves;
376 }
377 
378 //-----------------------------------------------------------------------------
379 // Function : TwoLevelNewton::getNumJacobianFactorizations
380 // Purpose :
381 // Special Notes :
382 // Scope : public
383 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
384 // Creation Date : 10/20/02
385 //-----------------------------------------------------------------------------
387 {
388  int numJacFact = 0;
389  numJacFact += nlsOuterPtr_->getNumJacobianFactorizations ();
390  numJacFact += numJacobianFactorizations_;
391  return numJacFact;
392 }
393 
394 //-----------------------------------------------------------------------------
395 // Function : TwoLevelNewton::getTotalNumLinearIters
396 // Purpose :
397 // Special Notes :
398 // Scope : public
399 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
400 // Creation Date : 10/20/02
401 //-----------------------------------------------------------------------------
403 {
404  int numLinIters = 0;
405  numLinIters += nlsOuterPtr_->getTotalNumLinearIters ();
406  numLinIters += totalNumLinearIters_;
407  return numLinIters ;
408 }
409 
410 //-----------------------------------------------------------------------------
411 // Function : TwoLevelNewton::getTotalLinearSolveTime
412 // Purpose :
413 // Special Notes :
414 // Scope : public
415 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
416 // Creation Date : 10/20/02
417 //-----------------------------------------------------------------------------
419 {
420  double totalLinSolveTime = 0.0;
421  totalLinSolveTime += nlsOuterPtr_->getTotalLinearSolveTime();
422  totalLinSolveTime += totalLinearSolveTime_;
423  return totalLinSolveTime;
424 }
425 
426 //-----------------------------------------------------------------------------
427 // Function : TwoLevelNewton::getTotalResidualLoadTime
428 // Purpose :
429 // Special Notes :
430 // Scope : public
431 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
432 // Creation Date : 10/20/02
433 //-----------------------------------------------------------------------------
435 {
436  double totalResLoadTime = 0.0;
437  totalResLoadTime += nlsOuterPtr_-> getTotalResidualLoadTime();
438  totalResLoadTime += totalResidualLoadTime_;
439  return totalResLoadTime;
440 }
441 
442 //-----------------------------------------------------------------------------
443 // Function : TwoLevelNewton::getTotalJacobianLoadTime
444 // Purpose :
445 // Special Notes :
446 // Scope : public
447 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
448 // Creation Date : 10/20/02
449 //-----------------------------------------------------------------------------
451 {
452  double totalJacLoadTime = 0.0;
453  totalJacLoadTime += nlsOuterPtr_->getTotalJacobianLoadTime();
454  totalJacLoadTime += totalJacobianLoadTime_;
455  return totalJacLoadTime;
456 }
457 
458 //-----------------------------------------------------------------------------
459 // Function : TwoLevelNewton::getNumIterations
460 // Purpose : Returns the current number of nonlinear iterations, for
461 // the solver currently being used (for two-level more than
462 // one solver is usually being invoked).
463 // Special Notes :
464 // Scope : private
465 // Creator : Eric R. Keiter, SNL, Compuational Sciences
466 // Creation Date : 10/24/02
467 //-----------------------------------------------------------------------------
469 {
470  int numIters = 0;
472  {
473  numIters = nlsOuterPtr_->getNumIterations ();
474  }
475  else
476  {
477  numIters = nlsInnerPtr_->getNumIterations ();
478  }
479 
480  return numIters;
481 }
482 
483 //-----------------------------------------------------------------------------
484 // Function : TwoLevelNewton::getMaxNormF
485 // Purpose :
486 // Special Notes :
487 // Scope : public
488 // Creator : Rich Schiek, Electrical and Memes Modeling
489 // Creation Date : 9/27/2009
490 //-----------------------------------------------------------------------------
492 {
493  double result = nlsInnerPtr_->getMaxNormF() + nlsOuterPtr_->getMaxNormF();
494  return result;
495 }
496 
497 //-----------------------------------------------------------------------------
498 // Function : TwoLevelNewton::getMaxNormFindex
499 // Purpose :
500 // Special Notes :
501 // Scope : public
502 // Creator : Rich Schiek, Electrical and Memes Modeling
503 // Creation Date : 9/27/2009
504 //-----------------------------------------------------------------------------
506 {
507  int indexInner = nlsInnerPtr_->getMaxNormFindex();
508  int indexOuter = nlsOuterPtr_->getMaxNormFindex();
509 
510  return indexInner; // usually the inner will be the one you want,
511  // but there should be more of a detailed comparison
512  // here just in case. FIX THIS
513 }
514 
515 
516 //-----------------------------------------------------------------------------
517 // Function : TwoLevelNewton::initializeAll
518 //
519 // Purpose : This serves the same purpose as the initializeAll
520 // function in the other solvers.
521 //
522 // Special Notes : Each of the solvers (inner, outer, and this one) will
523 // ultimately call the base class initialize all function,
524 // meaning that there are potentially 3 of each linear
525 // solver (3 iterative, 3 direct). This sort of makes
526 // sense for the inner and outer, as they may want
527 // different linear solvers. But, for the wrapper class,
528 // TwoLevelNewton, I'm only doing this so that it is
529 // possible to pass a solver pointer to Sensitivity,
530 // if needed.
531 //
532 // In the future, it may make sense to clean this up a
533 // litte.
534 //
535 // Scope : public
536 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
537 // Creation Date : 10/20/02
538 //-----------------------------------------------------------------------------
540 {
541  bool bsuccess = true;
542  bool tmpBool = true;
543 
544  tmpBool = nlsInnerPtr_->initializeAll ();
545  bsuccess = bsuccess && tmpBool;
546 
547  tmpBool= nlsOuterPtr_->initializeAll ();
548  bsuccess = bsuccess && tmpBool;
549 
550  tmpBool = NonLinearSolver::initializeAll();
551  bsuccess = bsuccess && tmpBool;
552 
553  savedRHSPtr_ = lasSysPtr_->builder().createVector ();
554  savedNextSolPtr_ = lasSysPtr_->builder().createVector ();
555  jdxpVectorPtr_ = lasSysPtr_->getJDXPVector ();
556 
557  // set up the return codes so that the "inner" solver is subject to
558  // greater restrictions than the outter solver.
559  ReturnCodes retCode;
560  retCode.nearConvergence = -3;
561  nlsInnerPtr_->setReturnCodes (retCode);
562 
563  return bsuccess;
564 }
565 
566 //-----------------------------------------------------------------------------
567 // Function : TwoLevelNewton::setOptions
568 //
569 // Purpose : This function processes the options set in the
570 // ".options NONLIN" line of the netlist.
571 //
572 // Special Notes : Mostly, these options are just passed on through to the
573 // "outer" nonlinear solver. However, since the outer
574 // solver is incremented one Newton step at a time, and
575 // the actual outer control loop sits here in the two level
576 // class, a few of the parameters are needed. In
577 // particular, the maximum number of Newton steps.
578 //
579 // Scope : public
580 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
581 // Creation Date : 10/20/02
582 //-----------------------------------------------------------------------------
583 bool TwoLevelNewton::setOptions(const Util::OptionBlock & OB)
584 {
585  Util::ParamList::const_iterator it_tpL = OB.begin();
586  Util::ParamList::const_iterator end_tpL = OB.end();
587  for ( ; it_tpL != end_tpL; ++it_tpL)
588  {
589  if (it_tpL->uTag() == "MAXSTEP")
590  {
591  maxOuterSteps_ = static_cast<int>(it_tpL->getImmutableValue<int>());
592  }
593  }
594 
595  return nlsOuterPtr_->setOptions(OB);
596 }
597 
598 //-----------------------------------------------------------------------------
599 // Function : TwoLevelNewton::setTranOptions
600 // Purpose :
601 // Special Notes :
602 // Scope : public
603 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
604 // Creation Date : 10/20/02
605 //-----------------------------------------------------------------------------
606 bool TwoLevelNewton::setTranOptions(const Util::OptionBlock & OB)
607 {
608  return nlsOuterPtr_->setTranOptions(OB);
609 }
610 
611 //-----------------------------------------------------------------------------
612 // Function : TwoLevelNewton::setHBOptions
613 // Purpose :
614 // Special Notes :
615 // Scope : public
616 // Creator :
617 // Creation Date : 04/07/2015
618 //-----------------------------------------------------------------------------
619 bool TwoLevelNewton::setHBOptions(const Util::OptionBlock & OB)
620 {
621  return true;
622 }
623 
624 //-----------------------------------------------------------------------------
625 // Function : TwoLevelNewton::setNLPOptions
626 // Purpose :
627 // Special Notes :
628 // Scope : public
629 // Creator : Eric Keiter, SNL
630 // Creation Date : 04/07/2015
631 //-----------------------------------------------------------------------------
632 bool TwoLevelNewton::setNLPOptions(const Util::OptionBlock & OB)
633 {
634  return true;
635 }
636 
637 
638 //-----------------------------------------------------------------------------
639 // Function : TwoLevelNewton::setLocaOptions
640 // Purpose :
641 // Special Notes :
642 // Scope : public
643 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
644 // Creation Date : 09/10/03
645 //-----------------------------------------------------------------------------
646 bool TwoLevelNewton::setLocaOptions (const Util::OptionBlock & OB)
647 {
648  outerLocaOptions_ = OB;
649  return nlsOuterPtr_->setLocaOptions(OB);
650 }
651 
652 //-----------------------------------------------------------------------------
653 // Function : TwoLevelNewton::setTwoLevelLocaOptions
654 // Purpose :
655 // Special Notes :
656 // Scope : public
657 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
658 // Creation Date : 09/10/03
659 //-----------------------------------------------------------------------------
660 bool TwoLevelNewton::setTwoLevelLocaOptions (const Util::OptionBlock & OB)
661 {
662  innerLocaOptions_ = OB;
663  return nlsInnerPtr_->setLocaOptions(OB);
664 }
665 
666 
667 //-----------------------------------------------------------------------------
668 // Function : TwoLevelNewton::setTwoLevelOptions
669 // Purpose :
670 // Special Notes :
671 // Scope : public
672 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
673 // Creation Date : 10/20/02
674 //-----------------------------------------------------------------------------
675 bool TwoLevelNewton::setTwoLevelOptions(const Util::OptionBlock & OB)
676 {
677  Util::OptionBlock OBtmp;
678 
679  Util::ParamList::const_iterator it_tpL = OB.begin();
680  Util::ParamList::const_iterator end_tpL = OB.end();
681  for ( ; it_tpL != end_tpL; ++it_tpL)
682  {
683  if (it_tpL->uTag() == "ALGORITHM")
684  {
685  twoLevelAlgorithm_ = static_cast<int>(it_tpL->getImmutableValue<int>());
686  }
687  else if (it_tpL->uTag() == "NOX")
688  {
689  noxFlagInner_ = it_tpL->getImmutableValue<int>();
690  }
691  else if (it_tpL->uTag() == "MAXCONTSTEPS")
692  {
693  maxContSteps_ = static_cast<int>(it_tpL->getImmutableValue<int>());
694  }
695  else if (it_tpL->uTag() == "CONTINUATIONFLAG")
696  {
697  int tmp = static_cast<int>(it_tpL->getImmutableValue<int>());
698  continuationType_ = tmp;
699  }
700  else if (it_tpL->uTag() == "INNERFAIL")
701  {
702  int tmp = static_cast<int>(it_tpL->getImmutableValue<int>());
703  innerLoopFailFatal_ = (tmp!=0);
704  }
705  else if (it_tpL->uTag() == "EXITWITHFAILURE")
706  {
707  int tmp = static_cast<int>(it_tpL->getImmutableValue<int>());
708  totalSolveFailFatal_ = (tmp!=0);
709  }
710  else if (it_tpL->uTag() == "FULLNEWTONENFORCE")
711  {
712  int tmp = static_cast<int>(it_tpL->getImmutableValue<int>());
714  }
715  else if (it_tpL->uTag() == "CONPARAM")
716  {
717  paramNameList.push_back(it_tpL->stringValue());
718  }
719  else if (it_tpL->uTag() == "VOLTLIMTOL")
720  {
721  voltLimTol_ = static_cast<double>(it_tpL->getImmutableValue<double>());
722  }
723  else // anything that is not a "special" two-level param, push
724  // back on the the tmp param list.
725  {
726  OBtmp.addParam(*it_tpL);
727  }
728  }
729 
730  innerSolverOptions_ = OBtmp; // keep a copy of these.
731 
732  nlsInnerPtr_->setOptions(OBtmp);
733 
734  if (twoLevelAlgorithm_ < 0 || twoLevelAlgorithm_ > 5)
735  {
736  Report::UserWarning0() << "Now the only algorithms 0 to 5 are two-level algorithm. Resetting to 0";
737 
738  twoLevelAlgorithm_ = 0;
739  }
740 
741  if (VERBOSE_NONLINEAR)
742  {
743  Xyce::dout() << "\n" << std::endl
744  << Xyce::section_divider << std::endl
745  << "\n***** 2-level Inner Loop Nonlinear solver options:\n" << std::endl
746  << "\talgorithm:\t\t\t" << twoLevelAlgorithm_ << std::endl
747  << "\toutersteps:\t\t\t" << maxOuterSteps_ << std::endl
748  << "\tmaxContSteps:\t\t\t" << maxContSteps_ << std::endl;
749 
750  Xyce::dout() << "\n***** Done printing Inner Loop Params:\n" << std::endl
751  << Xyce::section_divider << std::endl
752  << "\n" << std::endl;
753  }
754 
755  // Now that the loop is done allocate the param val array:
756  paramFinalVal.resize(paramNameList.size(),0.0);
757  paramCurrentVal.resize(paramNameList.size(),0.0);
758 
759  return true;
760 }
761 
762 //-----------------------------------------------------------------------------
763 // Function : TwoLevelNewton::setTwoLevelTranOptions
764 // Purpose :
765 // Special Notes :
766 // Scope : public
767 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
768 // Creation Date : 10/20/02
769 //-----------------------------------------------------------------------------
770 bool TwoLevelNewton::setTwoLevelTranOptions(const Util::OptionBlock & OB)
771 {
772  setupTranParamsFlag_ = true;
773  if (VERBOSE_NONLINEAR)
774  Xyce::dout() << "In TwoLevelNewton::setTwoLevelTranOptions" << std::endl;
775 
776  Util::OptionBlock OBtmp;
777 
778  Util::ParamList::const_iterator it_tpL = OB.begin();
779  Util::ParamList::const_iterator end_tpL = OB.end();
780  for ( ; it_tpL != end_tpL; ++it_tpL)
781  {
782  if (it_tpL->uTag() == "ALGORITHM")
783  {
784  twoLevelAlgorithmTran_ = static_cast<int>(it_tpL->getImmutableValue<int>());
785  }
786  else if ( it_tpL->uTag() == "MAXCONTSTEPS" )
787  {
788  maxContStepsTran_ = static_cast<int>(it_tpL->getImmutableValue<int>());
789  }
790  else // anything that is not a "special" two-level param, push
791  // back on the the tmp param list.
792  {
793  OBtmp.addParam(*it_tpL);
794  }
795  }
796 
798 
799  if (twoLevelAlgorithmTran_ < 0 || twoLevelAlgorithmTran_ > 3)
800  {
801  Report::UserWarning0() << "Now the only algorithms 0 to 3 are two-level algorithm. Resetting to 0";
802 
804  }
805 
806  return true;
807 }
808 
809 
810 //-----------------------------------------------------------------------------
811 // Function : TwoLevelNewton::setAnalysisMode
812 // Purpose : This function is slightly different than the
813 // function of the same name in NLParams.
814 //
815 // Special Notes :
816 // Scope : public
817 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
818 // Creation Date : 10/21/02
819 //-----------------------------------------------------------------------------
821 {
822  // this should be 0,1 or 2 (DC_OP, DC_SWEEP, or TRANSIENT)
823  if (VERBOSE_NONLINEAR)
824  Xyce::dout() << std::endl
825  << "Setting the externalAnalysisMode = " << mode << std::endl;
826 
827  externalAnalysisMode = mode;
828 
831 }
832 
833 //-----------------------------------------------------------------------------
834 // Function : TwoLevelNewton::setLinsolOptions
835 // Purpose : see header file
836 // Special Notes : see header file
837 // Scope : public
838 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
839 // Creation Date : 11/9/00
840 //-----------------------------------------------------------------------------
841 
842 bool TwoLevelNewton::setLinsolOptions(const Util::OptionBlock & OB)
843 {
844  bool bsuccess = true;
845  bool tmpBool = true;
846  tmpBool = nlsOuterPtr_->setLinsolOptions(OB);
847  bsuccess = bsuccess && tmpBool;
848 
849  tmpBool = nlsInnerPtr_->setLinsolOptions(OB);
850  bsuccess = bsuccess && tmpBool;
851 
852  tmpBool = NonLinearSolver::setLinsolOptions(OB);
853  bsuccess = bsuccess && tmpBool;
854 
855  return bsuccess;
856 }
857 
858 
859 //-----------------------------------------------------------------------------
860 // Function : TwoLevelNewton::printStepInfo_
861 // Purpose : Print out 2-level Newton step information.
862 // Special Notes :
863 // Scope : public
864 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
865 // Creation Date : 10/21/02
866 //-----------------------------------------------------------------------------
868 (int step, int success, TwoLevelNewtonMode solveType)
869 {
870  char tmpChar[128];
871  if (solveType==FULL_PROBLEM)
872  {
873  Xyce::lout() << "---------- 2LNiter: " << step << "\t" << success << "\tFULL PROBLEM --------------------------------" << std::endl;
874  }
875  else if (solveType==INNER_PROBLEM)
876  {
877  Xyce::lout() << "---------- 2LNiter: " << step << "\t" << success << "\tINNER PROBLEM ----------------------------" << std::endl;
878  }
879  else
880  {
881  Xyce::lout() << "---------- 2LNiter: " << step << "\t" << success << "\tOUTER PROBLEM ----------------------------" << std::endl;
882  }
883 }
884 
885 //-----------------------------------------------------------------------------
886 // Function : TwoLevelNewton::zeroInnerLoopStatistics_
887 // Purpose :
888 // Special Notes :
889 // Scope : public
890 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
891 // Creation Date : 10/21/02
892 //-----------------------------------------------------------------------------
894 {
895  numResidualLoads_ = 0;
896  numJacobianLoads_ = 0;
897  numLinearSolves_ = 0;
901  totalLinearSolveTime_ = 0.0;
904 }
905 
906 //-----------------------------------------------------------------------------
907 // Function : TwoLevelNewton::calcInnerLoopStatistics_
908 // Purpose :
909 // Special Notes :
910 // Scope : public
911 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
912 // Creation Date : 10/21/02
913 //-----------------------------------------------------------------------------
915 {
925 }
926 
927 //-----------------------------------------------------------------------------
928 // Function : TwoLevelNewton::calcOuterLoopStatistics_
929 // Purpose :
930 // Special Notes :
931 // Scope : public
932 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
933 // Creation Date : 10/21/02
934 //-----------------------------------------------------------------------------
936 {
946 }
947 
948 
949 //-----------------------------------------------------------------------------
950 // Function : TwoLevelNewton::algorithm0_
951 // Purpose : This algorithm is the full newton algorithm.
952 //
953 // Special Notes : The main thing that is different about running this
954 // function, rather than just not using the 2-level class
955 // at all, is that here the conductance and capacitance
956 // calculations are performed at the end of the solve.
957 //
958 // Scope : private
959 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
960 // Creation Date : 05/07/03
961 //-----------------------------------------------------------------------------
962 int
964  bool nl_poisson_dcop)
965 {
966  int status = -1;
967 
968  if (VERBOSE_NONLINEAR)
969  Xyce::dout() << std::endl << "Running algorithm 0:" << std::endl;
970 
971  // set up the local algorithm variable:
972  int algorithm = twoLevelAlgorithm_;
973  if ( externalAnalysisMode ==2) algorithm = twoLevelAlgorithmTran_;
974 
975  // This step is neccessary in case we've just switched algorithms.
976  if ( algorithm == 0) twoLevelCouplingMode_=FULL_PROBLEM;
977 
978  status = nlsOuterPtr_->solve ();
979 
980  // Now do conductance/capacitance extractions, if it makes sense.
981  if (!nl_poisson_dcop)
982  {
984  }
985 
986  // Do this so that I can test the ConductanceExtractor class.
989 
990  return status;
991 }
992 
993 //-----------------------------------------------------------------------------
994 // Function : TwoLevelNewton::algorithm1_
995 // Purpose : This is the first two-level algorithm implemented.
996 // The idea is to have nested Newton solves.
997 //
998 // Inner loop = PDE-device only
999 // Outer loop = Full Newton.
1000 //
1001 // Special Notes : Doesn't work with NOX yet...
1002 //
1003 // This will exit immediately if the inner loop fails.
1004 // The reason for this is that the point of 2-level
1005 // Newton is to solve problems that are difficult
1006 // as a result of two very different problem types
1007 // being coupled together.
1008 //
1009 // Ideally, for the two-level Newton, you have a
1010 // circuit problem that can be easily solved on its
1011 // own, and a PDE-device problem that can easily be
1012 // solved on its own, and the only problem is that
1013 // they can't easily be solved together. Two level
1014 // Newton separates them, and applies different
1015 // (hopefully ideal) solver settings to each.
1016 //
1017 // If the PDE problem
1018 // (the inner loop) can't be solved with its
1019 // current settings, even in stand-alone mode, 2-level
1020 // Newton won't help.
1021 //
1022 // Scope : private
1023 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1024 // Creation Date : 10/22/02
1025 //-----------------------------------------------------------------------------
1027 {
1028  int status = -1;
1029 
1030  if (VERBOSE_NONLINEAR)
1031  Xyce::dout() << std::endl << "Running algorithm 1:" << std::endl;
1032 
1033  bool firstOuterStepTaken = false;
1034  nlsPassingPtr_ = 0;
1035 
1036  if (status < 0)
1037  {
1038  int twoLevelStep;
1039  for (twoLevelStep=0;twoLevelStep<maxOuterSteps_; ++twoLevelStep)
1040  {
1041  // Device Only:
1043  outerLoopActiveFlag_= false;
1044  int statInner = nlsInnerPtr_->solve (nlsPassingPtr_);
1045  nlsPassingPtr_ = 0;
1047 
1048  // Output the nonlinear solver step information:
1049  if (VERBOSE_NONLINEAR)
1050  printStepInfo_(twoLevelStep+1,statInner, twoLevelCouplingMode_);
1051 
1052  // If we can't even get the inner loop to converge,
1053  // just give up.
1054  if (statInner < 0)
1055  {
1056  break;
1057  }
1058 
1059  // Full Problem:
1061  outerLoopActiveFlag_= true;
1062  if (firstOuterStepTaken)
1063  {
1064  status = nlsOuterPtr_->takeOneSolveStep ();
1065  }
1066  else
1067  {
1068  firstOuterStepTaken = true;
1070  }
1071 
1073 
1074  // Output the nonlinear solver step information:
1075  if (VERBOSE_NONLINEAR)
1076  printStepInfo_(twoLevelStep+1,status, twoLevelCouplingMode_);
1077 
1078  // exit?
1079  // Use the total "full Newton" error to evaluate this step.
1080  if (status >= 0)
1081  {
1082  break;
1083  }
1084 
1085  } // end of for loop
1086  } // end of status if statement
1087 
1088  if (VERBOSE_NONLINEAR && status >=0)
1089  Xyce::dout() << "TWO LEVEL Newton succeeded!" << std::endl;
1090 
1091  return status;
1092 }
1093 
1094 //-----------------------------------------------------------------------------
1095 // Function : TwoLevelNewton::algorithm2_
1096 // Purpose : Similar to algorithm1, but this one allows for the
1097 // inner PDE Newton solve to be gradually stepped up to
1098 // the circuit imposed boundary conditions. Essentially,
1099 // the inner loop Newton solve is a continuation method.
1100 //
1101 // This could almost be called a "3-level" Newton, as there
1102 // are now 3 nested loops.
1103 //
1104 // Special Notes : not finished yet...
1105 //
1106 // Scope : private
1107 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1108 // Creation Date : 10/22/02
1109 //-----------------------------------------------------------------------------
1111 {
1112  int status = -1;
1113  int statInner = 0;
1114  bool statusFull = false;
1115  bool firstOuterStepTaken = false;
1116 
1117  if (VERBOSE_NONLINEAR)
1118  Xyce::dout() << std::endl << "Running algorithm 2:" << std::endl;
1119 
1120  // Start out with a single step of the full problem:
1121  // Full Problem:
1123  firstOuterStepTaken = true;
1124  outerLoopActiveFlag_= true;
1126 
1127  // Output the nonlinear solver step information:
1128  if (VERBOSE_NONLINEAR)
1130 
1131  nlsPassingPtr_ = 0;
1132  if (status <= 0)
1133  {
1134  int twoLevelStep;
1135  for (twoLevelStep=0;twoLevelStep<maxOuterSteps_; ++twoLevelStep)
1136  {
1137  // Device Only:
1139  outerLoopActiveFlag_= false;
1140 
1141  if (continuationType_ == 1)
1142  {
1143  statInner = continuationLoop_ ();
1144  }
1145  else if (continuationType_ == 2)
1146  {
1147  statInner = locaLoop_ ();
1148  }
1149  else
1150  {
1151  statInner = nlsInnerPtr_->solve (nlsPassingPtr_);
1152  nlsPassingPtr_ = 0;
1154  }
1155 
1156  // Output the nonlinear solver step information:
1157  if (VERBOSE_NONLINEAR)
1158  printStepInfo_(twoLevelStep+1,statInner,twoLevelCouplingMode_);
1159 
1160  if (innerLoopFailFatal_)
1161  {
1162  // If we can't even get the inner loop to converge,
1163  // just give up.
1164  if (statInner <= 0)
1165  {
1166  break;
1167  }
1168  }
1169 
1170  // Full Problem:
1172  outerLoopActiveFlag_= true;
1173 
1174  if (firstOuterStepTaken)
1175  {
1176  status = nlsOuterPtr_->takeOneSolveStep ();
1177  }
1178  else
1179  {
1180  firstOuterStepTaken = true;
1182  }
1184 
1185  // Output the nonlinear solver step information:
1186  if (VERBOSE_NONLINEAR)
1187  printStepInfo_(twoLevelStep+1,status,twoLevelCouplingMode_);
1188 
1189  // exit?
1190  // Use the total "full Newton" error to evaluate this step.
1191  // If the ckt considers itself converged at this point, do a
1192  // final reality check by taking a full Newton step.
1193  statusFull = false;
1194 
1195  if (status > 0 && statInner>0) statusFull = true;
1196 
1197  if (statusFull) break;
1198 
1199  } // end of for loop
1200  } // end of status if statement
1201 
1202  if (VERBOSE_NONLINEAR && status >0 && statInner > 0)
1203  Xyce::dout() << "TWO LEVEL Newton succeeded!" << std::endl;
1204 
1205  return status;
1206 }
1207 
1208 //-----------------------------------------------------------------------------
1209 // Function : TwoLevelNewton::algorithm3_
1210 //
1211 // Purpose : This is another 2-level algorithm. For this
1212 // algorithm, the de-coupling is greater than for
1213 // algorithms 1 and 2.
1214 //
1215 // The circuit Newton steps do *not* include any
1216 // PDE device elements, and never do. The PDE
1217 // devices are replaced by approximated conductances.
1218 //
1219 // Special Notes : This is the best algorithm.
1220 //
1221 // Scope : private
1222 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1223 // Creation Date : 10/25/02
1224 //-----------------------------------------------------------------------------
1226 {
1227  int status = -1;
1228  int statInner = 0;
1229  bool statusFull = false;
1230  bool firstOuterStepTaken = false;
1231 
1232  if (VERBOSE_NONLINEAR)
1233  Xyce::dout() << std::endl << "Running algorithm 3:" << std::endl;
1234 
1235  nlsPassingPtr_ = 0;
1236 
1237  int twoLevelStep;
1238  if (status <= 0)
1239  {
1240  for (twoLevelStep=0;twoLevelStep<maxOuterSteps_; ++twoLevelStep)
1241  {
1242  // Device Only:
1243  // Solve device problem with continuation:
1245  outerLoopActiveFlag_= false;
1246  statInner = 0;
1247 
1248  if (continuationType_ == 1)
1249  {
1250  statInner = continuationLoop_ ();
1251  }
1252  else if (continuationType_ == 2)
1253  {
1254  statInner = locaLoop_ ();
1255  }
1256  else
1257  {
1258  statInner = nlsInnerPtr_->solve (nlsPassingPtr_);
1259  nlsPassingPtr_ = 0;
1261  }
1262 
1263  // Output the nonlinear solver step information:
1264  if (VERBOSE_NONLINEAR)
1265  printStepInfo_(twoLevelStep+1,statInner,twoLevelCouplingMode_);
1266 
1267  if (innerLoopFailFatal_)
1268  {
1269  // If we can't even get the inner loop to converge,
1270  // just give up.
1271  if (statInner <= 0)
1272  {
1273  break;
1274  }
1275  }
1276 
1277  // Now do all the conductance extractions:
1278  calcCouplingTerms_ ();
1279 
1280  // ckt-only problem:
1282  outerLoopActiveFlag_= true;
1283  if (firstOuterStepTaken)
1284  {
1285  status = nlsOuterPtr_->takeOneSolveStep ();
1286  }
1287  else
1288  {
1289  firstOuterStepTaken = true;
1291  }
1292 
1293  if (noxFlag_)
1294  {
1296  }
1297 
1298  // Output the nonlinear solver step information:
1299  if (VERBOSE_NONLINEAR)
1300  printStepInfo_(twoLevelStep+1,status,twoLevelCouplingMode_);
1301 
1302  // check if voltage limiting is still active by getting the norm of the
1303  // jdxp vector:
1304  double twoNormJDXP_ = 0.0;
1305  jdxpVectorPtr_->lpNorm(2, &twoNormJDXP_);
1306 
1307  bool voltLimStat = (twoNormJDXP_ <= voltLimTol_);
1308 
1309  if (VERBOSE_NONLINEAR)
1310  Xyce::dout() << std::endl
1311  << " 2-norm of voltage limiting vector: " << twoNormJDXP_ << std::endl;
1312 
1313  // exit?
1314  statusFull = false;
1315  if (status > 0 && statInner>0 && voltLimStat) statusFull = true;
1316 
1317  if (statusFull) break;
1318 
1319  } // end of outer steps "for" loop
1320 
1321  } // end of status if statement
1322 
1323  // Do a final few "full Newton" steps, to get a final consistency between
1324  // the two solvers.
1325  int statFinal = 2;
1326  if (doFullNewtonFinalEnforcement_ && statusFull)
1327  {
1329  statFinal = nlsOuterPtr_->solve ();
1330 
1331  // Output the nonlinear solver step information:
1332  if (VERBOSE_NONLINEAR)
1333  {
1334  ++twoLevelStep;
1335  printStepInfo_(twoLevelStep+1,status,twoLevelCouplingMode_);
1336  }
1337  }
1338 
1339  // Do one final conductance/capacitance extraction:
1340  calcCouplingTerms_ ();
1341 
1342  if (VERBOSE_NONLINEAR && status >0 && statInner > 0 && statFinal > 0)
1343  Xyce::dout() << "TWO LEVEL Newton succeeded!" << std::endl;
1344 
1345  return status;
1346 }
1347 
1348 //-----------------------------------------------------------------------------
1349 // Function : TwoLevelNewton::algorithm4_
1350 //
1351 // Purpose : This is mostly a test algorithm.
1352 //
1353 // This is not a two-level class algorithm, but rather a
1354 // continuation algorithm to test out
1355 // some of the new continuation capabilities.
1356 //
1357 // Mostly, I'm putting this here to test out the new
1358 // "setParam" function in the device package, which is
1359 // needed by LOCA.
1360 //
1361 // Special Notes :
1362 // Scope : private
1363 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1364 // Creation Date : 07/26/03
1365 //-----------------------------------------------------------------------------
1367 {
1368  int status = -1;
1369  int statNL;
1370  nlsPassingPtr_ = 0;
1371  bool continuationLoop = false;
1372  bool successBool;
1373  int contMaxTmp = 100; // this is just a guess for number of steps.
1374  int stepsLeft = contMaxTmp;
1375 
1376  if (VERBOSE_NONLINEAR)
1377  Xyce::dout() << std::endl << "Running algorithm 4:" << std::endl
1378  << std::endl << "Initial continuation steps: "
1379  << contMaxTmp << std::endl;
1380 
1381  // The solves should be FULL newton solves.
1383 
1384  // These values assume that any parameter will start at zero and ramp up
1385  // to a final value. The final value is the value that is set for this
1386  // parameter in the netlist. So, for example, if a voltage source is set
1387  // to 5.0 volts in the netlist:
1388  //
1389  // vid 4 0 5.00
1390  //
1391  // and one of the continuation parameters is vid:v0, then the final value
1392  // for vid:v0 is 5.00.
1393 
1394  double initVal = 0.0;
1395  double currVal = initVal;
1396  double prevVal = initVal;
1397  double stepSizeEst;
1398 
1399  std::vector<std::string>::iterator iter;
1400  std::vector<std::string>::iterator begin = paramNameList.begin ();
1401  std::vector<std::string>::iterator end = paramNameList.end ();
1402 
1403  std::vector<double>::iterator iterFinalVal;
1404  std::vector<double>::iterator beginFinalVal = paramFinalVal.begin ();
1405  std::vector<double>::iterator endFinalVal = paramFinalVal.end ();
1406 
1407  std::vector<double>::iterator iterCurrentVal;
1408  std::vector<double>::iterator beginCurrentVal = paramCurrentVal.begin ();
1409  std::vector<double>::iterator endCurrentVal = paramCurrentVal.end ();
1410 
1411  // Get the final values for each param., then set each to zero.
1412  for (iter=begin, iterFinalVal=beginFinalVal, iterCurrentVal=beginCurrentVal;
1413  iter!=end;
1414  ++iter, ++iterFinalVal, ++iterCurrentVal)
1415  {
1416  //*iterFinalVal = nonlinearEquationLoader_->getParam(*iter);
1417  *iterFinalVal = 1.0;
1418  nonlinearEquationLoader_->setParam(*iter, 0.0);
1419  }
1420 
1421  // now, loop over each parameter, and do a continuation loop for each.
1422  // For each param, the loop will adjust the param from 0.0 to the final
1423  // value. Once each parameter has achieved a final value, the solve is
1424  // finished.
1425  for (iter=begin, iterFinalVal=beginFinalVal;
1426  iter!=end;
1427  ++iter, ++iterFinalVal)
1428  {
1429  // get the initial stepsize:
1430  stepSizeEst = (*iterFinalVal-0.0)/(static_cast<double>(contMaxTmp));
1431  currVal = 0.0;
1432  prevVal = 0.0;
1433  contStep_=1;
1434 
1435  if (VERBOSE_NONLINEAR)
1436  Xyce::dout() << "Parameter = " << *iter
1437  << " finalVal = " << *iterFinalVal << std::endl;
1438 
1439  // begin continuation Loop for the current parameter, *iter:
1440  bool continuationLoopFinished = false;
1441  int numTotalFailures = 0;
1442  while (!continuationLoopFinished)
1443  {
1444  bool stepFinished = false;
1445  int numFailures = 0;
1446 
1447  while(!stepFinished)
1448  {
1449  if (stepSizeEst != 0.0)
1450  {
1451  stepsLeft = static_cast<int>((*iterFinalVal-currVal)/stepSizeEst) + 1;
1452  }
1453  else
1454  {
1455  stepsLeft = 1;
1456  }
1457 
1458  if (VERBOSE_NONLINEAR)
1459  Xyce::dout() << std::endl << "Continuation Step: " << contStep_
1460  << " Estimated Remaining Steps: " << stepsLeft
1461  << " " << *iter
1462  << std::endl
1463  << "currVal= " << currVal
1464  << " prevVal= " << prevVal
1465  << " step= " << stepSizeEst
1466  << std::endl;
1467 
1468  if (stepsLeft < 0)
1469  {
1470  std::string tmp = "Continuation step estimate broken. Exiting\n";
1471  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::USR_FATAL_0, tmp);
1472  }
1473 
1474  // save a copy of solution:
1475  (*savedNextSolPtr_) = (**nextSolVectorPtrPtr_);
1476 
1477  // set the continuation-parameter:
1478  nonlinearEquationLoader_->setParam (*iter, currVal);
1479  *iterCurrentVal = currVal;
1480 
1481  // perform the nonlinear solve:
1482  statNL = nlsOuterPtr_->solve (nlsPassingPtr_);
1483 
1484  int stepsTaken = nlsOuterPtr_->getNumIterations ();
1485  int stepsNotTaken = abs(maxOuterSteps_ - stepsTaken);
1486 
1487  nlsPassingPtr_ = 0;
1488 
1489  // Add to the stats:
1491 
1492  // Earlier (in initializeAll), return codes should have been set,
1493  // hopefully correctly...
1494  successBool = (statNL > 0);
1495 
1496  if (successBool) // success!
1497  {
1498  stepFinished = true;
1499 
1500  //if (numFailures <= 0 && stepsNotTaken > 7)
1501  if (numFailures <= 0)
1502  {
1503  stepSizeEst *= increaseContScalar_;
1504  }
1505 
1506  --numFailures;
1507  if (numFailures < 0) numFailures = 0;
1508 
1509  prevVal = currVal;
1510  currVal += stepSizeEst;
1511 
1512  if ( (*iterFinalVal >= 0 && currVal > *iterFinalVal) ||
1513  (*iterFinalVal < 0 && currVal < *iterFinalVal) )
1514  {
1515  currVal = *iterFinalVal;
1516  stepSizeEst = currVal - prevVal;
1517  }
1518 
1519  if (DEBUG_NONLINEAR)
1520  {
1521  Xyce::dout() << "\nRight before outputHOMOTOPY:" << std::endl;
1522  for (int ieric=0;ieric<paramNameList.size();++ieric)
1523  {
1524  Xyce::dout() << paramNameList[ieric] << "\t";
1525  Xyce::dout() << paramCurrentVal[ieric] << std::endl;
1526  }
1527  }
1528 
1529 
1530  outMgrPtr_->outputHomotopy(pdsMgrPtr_->getPDSComm()->comm(), paramNameList, paramCurrentVal, **nextSolVectorPtrPtr_);
1531  }
1532  else // failure!
1533  {
1534  stepSizeEst *= decreaseContScalar_;
1535 
1536  // restore the solution:
1537  **nextSolVectorPtrPtr_ = (*savedNextSolPtr_);
1538 
1539  ++numFailures;
1540  ++numTotalFailures;
1541 
1542  currVal = prevVal + stepSizeEst;
1543  }
1544  } // end of stepFinished while loop
1545 
1546  if (!successBool) // failure...
1547  {
1548  break;
1549  }
1550 
1551  ++contStep_;
1552 
1553  continuationLoopFinished =
1554  ( (*iterFinalVal >= 0 && prevVal >= *iterFinalVal) ||
1555  (*iterFinalVal < 0 && prevVal <= *iterFinalVal) );
1556 
1557  } // end of continuation loop.
1558 
1559  if (VERBOSE_NONLINEAR)
1560  Xyce::dout() << "currVal= " << currVal
1561  << " prevVal= " << prevVal
1562  << std::endl
1563  << std::endl
1564  << "Total number of failures = " << numTotalFailures << std::endl
1565  << "Number of actual steps = " << contStep_-1
1566  << std::endl;
1567 
1568  } // end of parameter loop.
1569 
1570  status = statNL;
1571 
1572  return status;
1573 }
1574 
1575 //-----------------------------------------------------------------------------
1576 // Function : TwoLevelNewton::algorithm5_
1577 //
1578 // Purpose : Same as algorithm0, but calls the inner solver rather
1579 // than the outer.
1580 //
1581 // Special Notes : This is best used if you want to use LOCA most of the
1582 // time, but not on the nonlinear poisson solve
1583 // (firstDCOPstep).
1584 //
1585 // Scope : private
1586 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1587 // Creation Date : 05/07/03
1588 //-----------------------------------------------------------------------------
1590 {
1591  int status = -1;
1592 
1593  if (VERBOSE_NONLINEAR)
1594  Xyce::dout() << std::endl << "Running algorithm 5:" << std::endl;
1595 
1596  // set up the local algorithm variable:
1597  int algorithm = twoLevelAlgorithm_;
1598  if ( externalAnalysisMode ==2) algorithm = twoLevelAlgorithmTran_;
1599 
1601 
1602  status = nlsInnerPtr_->solve ();
1603 
1604  // Now do conductance/capacitance extractions, if it makes sense.
1605  // if (!nl_poisson_dcop)
1606  // {
1607  // calcCouplingTerms_ ();
1608  // }
1609 
1610  return status;
1611 }
1612 
1613 
1614 //-----------------------------------------------------------------------------
1615 // Function : TwoLevelNewton::solve
1616 // Purpose :
1617 // Special Notes : Doesn't work with NOX yet...
1618 // Scope : public
1619 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1620 // Creation Date : 10/20/02
1621 //-----------------------------------------------------------------------------
1622 int
1624  NonLinearSolver * nlsTmpPtr)
1625 {
1626  int status = -1;
1627 
1628  bool nl_poisson_dcop = analysisManager_->getDCOPSolve() == Analysis::NL_POISSON;
1629 
1631 
1632  // set up the local algorithm variable:
1633  int algorithm = twoLevelAlgorithm_;
1634  if ( externalAnalysisMode ==2) algorithm = twoLevelAlgorithmTran_;
1635 
1636  // Some intitial setup:
1638  {
1639  numInterfaceNodesSetup_ = true;
1642 
1643  if (VERBOSE_NONLINEAR)
1644  Xyce::dout() << std::endl
1645  << "numSubProblems_ = " << numSubProblems_ << std::endl;
1646  }
1647 
1648  // Algorithm 0:
1649  // Full Newton, same as if two level was never called.
1650  if (algorithm == 0 || nl_poisson_dcop)
1651  {
1652  status = algorithm0_(nl_poisson_dcop);
1653  }
1654  // else if algorithm 1:
1655  // outter loop is full Newton, inner loop PDE device only.
1656  else if (algorithm == 1)
1657  {
1658  status = algorithm1_ ();
1659  }
1660  // same as algorithm 1, but with continuation applied to the inner loop.
1661  else if (algorithm == 2)
1662  {
1663  status = algorithm2_ ();
1664  }
1665  // outter loop is circuit only, inner loop PDE device only, with
1666  // continuation.
1667  else if (algorithm == 3)
1668  {
1669  status = algorithm3_ ();
1670  }
1671  else if (algorithm == 4)
1672  {
1673  status = algorithm4_ ();
1674  }
1675  else if (algorithm == 5)
1676  {
1677  status = algorithm5_ ();
1678  }
1679  else
1680  {
1681  std::string tmp =
1682  "Two-Level Newton Algorithm set to invalid number.\n";
1683  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::USR_FATAL_0, tmp);
1684  }
1685 
1686  // Sometimes, when trying to debug, you want the code to exit the first
1687  // time the solver bombs. The totalSolveFailFlag gives that option.
1688  // Right before exiting, however, it instructs the device package to
1689  // output all its stuff. (tecplot files, text files, etc.)
1690  if (totalSolveFailFatal_ && status<=0)
1691  {
1692 #ifndef Xyce_PARALLEL_MPI
1694 #endif
1695 
1696  std::string tmp =
1697  "Two-Level Newton Algorithm failed to converge. Exiting.\n";
1698  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::USR_FATAL_0, tmp);
1699  }
1700 
1701  return status;
1702 }
1703 
1704 //-----------------------------------------------------------------------------
1705 // Function : TwoLevelNewton::calcCouplingTerms_
1706 //
1707 // Purpose : The purpose of this function is to manage the extraction
1708 // of conductances (coupling terms) from each PDE device.
1709 // These conductances may be neccessary if the outter Newton
1710 // loop is to be a ckt-only loop. In that case, the
1711 // PDE devices are replaced by much smaller conductance
1712 // based models.
1713 //
1714 // Special Notes : Performing a conductance calculation on a PDE device
1715 // requires a chain rule calculation, which includes several
1716 // linear solves of the Jacobian. It is because of the
1717 // required linear solve that some of the work is done
1718 // up here in the nonlinear solver, instead of having all
1719 // of it be done by the individual PDE devices.
1720 //
1721 // There may be a better solution later, but for the time
1722 // being I didn't want linear solves to be performed down
1723 // in the device package.
1724 //
1725 // Scope : public
1726 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1727 // Creation Date : 12/03/02
1728 //-----------------------------------------------------------------------------
1730 {
1731  bool bsuccess = true;
1732  bool tmpBool = true;
1733 
1734  char filename1[256];
1735 
1736  for (int ich = 0; ich < 256; ++ich)
1737  { filename1[ich] = 0; }
1738 
1739  // If the current mode is not "INNER_PROBLEM", then we need to re-load
1740  // the matrix, as the ckt part of the matrix needs to be kept out of
1741  // this calculation. Also, re-load Jacobian to make sure it is
1742  // completely up-to-date with the current solution.
1745  {
1747  }
1749 
1750  sprintf(filename1,"%s","tmpJac.txt");
1751  Linear::Matrix *A = lasSysPtr_->getJacobianMatrix();
1752  A->writeToFile(filename1);
1753 
1754  // save a copy of the RHS, as it is going to get mangled.
1755  Linear::Vector *rhsVecPtr = lasSysPtr_->getRHSVector();
1756  Linear::Vector *newtVecPtr = nlsOuterPtr_->NewtonVectorPtr_;
1757  *savedRHSPtr_ = *rhsVecPtr;
1758 
1759  // Loop over each sub-problem (PDE device).
1760  // Within each sub-problem, loop over each coupling term. (electrode)
1761  for (int iSubProblem=0; iSubProblem<numSubProblems_; ++iSubProblem)
1762  {
1763  int iCouple;
1764  int numCoupleTerms = numInterfaceNodes_[iSubProblem];
1765 
1766  if (VERBOSE_NONLINEAR)
1767  Xyce::dout() << "\n numCoupleTerms = " << numCoupleTerms << std::endl;
1768 
1769  for (iCouple=0;iCouple<numCoupleTerms;++iCouple)
1770  {
1771  // first zero out the RHS vector
1772  rhsVecPtr->putScalar(0.0);
1773 
1774  // load RHS vector with dFdV.
1775  tmpBool = nonlinearEquationLoader_->loadCouplingRHS (iSubProblem, iCouple, rhsVecPtr );
1776  bsuccess = bsuccess && tmpBool;
1777 
1778  sprintf(filename1,"dfdv%02d.txt", iCouple);
1779  rhsVecPtr->writeToFile(filename1);
1780 
1781  // solve linear system to get dVdX.
1782  tmpBool = nlsOuterPtr_->newton_();
1783  bsuccess = bsuccess && tmpBool;
1784  numLinearSolves_ += 1;
1785 
1786  sprintf(filename1,"dvdx%02d.txt", iCouple);
1787  newtVecPtr->writeToFile(filename1);
1788 
1789  // copy the newton vector (result of linear solve) into the
1790  // RHSvector. Doing this b/c device package knows about rhs, but
1791  // doesn't know about newton.
1792  *rhsVecPtr = *newtVecPtr;
1793 
1794  // instruct each PDE device to finish the conductance calc.
1795  tmpBool = nonlinearEquationLoader_->calcCouplingTerms (iSubProblem, iCouple, rhsVecPtr);
1796  bsuccess = bsuccess && tmpBool;
1797  }
1798  }
1799 
1800  // now restore everything, just in case:
1801  *rhsVecPtr = *savedRHSPtr_;
1802  twoLevelCouplingMode_ = savedMode;
1803 
1804  return bsuccess;
1805 }
1806 
1807 //-----------------------------------------------------------------------------
1808 // Function : TwoLevelNewton::continuationLoop_
1809 //
1810 // Purpose : Boundary condition continuation loop:
1811 //
1812 // Special Notes : This continuation loop allows for variable step size.
1813 //
1814 // Scope : public
1815 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1816 // Creation Date : 12/06/02
1817 //-----------------------------------------------------------------------------
1819 {
1820  int statInner;
1821  bool successBool;
1822  int contMaxTmp;
1823 
1824  // Instruct the PDE devices to set up the incremental
1825  // boundary conditions
1826  int suggestedSteps = 10; // this is a guess to the number of steps.
1827  suggestedSteps = nonlinearEquationLoader_->enablePDEContinuation ();
1828 
1829  if (suggestedSteps < 1) suggestedSteps = 1;
1830  contMaxTmp = suggestedSteps;
1831 
1832  double stepSizeEst = 1.0/(static_cast<double>(contMaxTmp));
1833  double currentAlpha = 0.0;
1834  double previousAlpha = 0.0;
1835  int stepsLeft = contMaxTmp;
1836 
1837  // If the continuation loop has never been called before, then leave the
1838  // initial alpha at zero, because we have no solution to start from,
1839  // probably. If it has been called before, go ahead and take the first
1840  // step, as it should just be one step beyond an already obtained
1841  // solution.
1843  {
1844  currentAlpha = stepSizeEst;
1845  }
1847 
1848  contStep_=1;
1849  bool continuationLoopFinished = false;
1850 
1851  int numTotalFailures = 0;
1852 
1853  while (!continuationLoopFinished)
1854  {
1855  bool stepFinished = false;
1856  int numFailures = 0;
1857 
1858  while(!stepFinished)
1859  {
1860 
1861  stepsLeft = static_cast<int>((1.0-currentAlpha)/stepSizeEst) + 1;
1862 
1863  if (VERBOSE_NONLINEAR)
1864  Xyce::dout() << std::endl << "Continuation Step: " << contStep_
1865  << " Estimated Remaining Steps: " << stepsLeft
1866  << std::endl
1867  << "current alpha = " << currentAlpha
1868  << " prev. alpha = " << previousAlpha
1869  << " step = " << stepSizeEst
1870  << std::endl;
1871 
1872  if (stepsLeft < 0)
1873  {
1874  std::string tmp = "Continuation step estimate broken. Exiting\n";
1875  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::USR_FATAL_0, tmp);
1876  }
1877 
1878  // save a copy of solution:
1879  (*savedNextSolPtr_) = (**nextSolVectorPtrPtr_);
1880 
1881  std::string paramName = "pdealpha";
1882  nonlinearEquationLoader_->setParam (paramName, currentAlpha);
1883 
1884  // perform the nonlinear solve:
1885  statInner = nlsInnerPtr_->solve (nlsPassingPtr_);
1886  nlsPassingPtr_ = 0;
1888 
1889  // Earlier (in initializeAll), return codes for the inner solver
1890  // should have been set so that "nearConvergence" is not considered
1891  // an adequate success. In other words, it returns a negative
1892  // number, not positive.
1893 
1894  if (DEBUG_NONLINEAR)
1895  Xyce::dout() << "Status of inner loop solve: " << statInner << std::endl;
1896 
1897  successBool = (statInner > 0);
1898 
1899  if (successBool) // success!
1900  {
1901  stepFinished = true;
1902 
1903  if (numFailures <= 0)
1904  {
1905  stepSizeEst *= increaseContScalar_;
1906  }
1907 
1908  --numFailures;
1909  if (numFailures < 0) numFailures = 0;
1910 
1911  previousAlpha = currentAlpha;
1912  currentAlpha += stepSizeEst;
1913 
1914  if (currentAlpha > 1.0)
1915  {
1916  currentAlpha = 1.0;
1917  stepSizeEst = currentAlpha - previousAlpha;
1918  }
1919  }
1920  else // failure!
1921  {
1922  stepSizeEst *= decreaseContScalar_;
1923 
1924  // restore the solution:
1925  (**nextSolVectorPtrPtr_) = (*savedNextSolPtr_);
1926 
1927  ++numFailures;
1928  ++numTotalFailures;
1929 
1930  currentAlpha = previousAlpha + stepSizeEst;
1931  }
1932  } // end of stepFinished while loop
1933 
1934  if (!successBool) // failure...
1935  {
1936  break;
1937  }
1938 
1939  ++contStep_;
1940  continuationLoopFinished = (previousAlpha >= 1.0);
1941 
1942  } // end of continuation loop.
1943 
1944  if (VERBOSE_NONLINEAR)
1945  Xyce::dout() << "current alpha = " << currentAlpha
1946  << " previous alpha = " << previousAlpha
1947  << std::endl
1948  << std::endl
1949  << "Total number of failures = " << numTotalFailures << std::endl
1950  << "Number of actual steps = " << contStep_-1
1951  << std::endl;
1952 
1954  contStep_=0;
1955 
1956  return statInner;
1957 }
1958 
1959 //-----------------------------------------------------------------------------
1960 // Function : TwoLevelNewton::locaLoop_
1961 //
1962 // Purpose : Boundary condition continuation (using LOCA) loop:
1963 //
1964 // Special Notes : This continuation loop allows for variable step size.
1965 //
1966 // Scope : public
1967 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1968 // Creation Date : 2/26/04
1969 //-----------------------------------------------------------------------------
1971 {
1972  int statInner;
1973 
1974  int suggestedSteps = nonlinearEquationLoader_->enablePDEContinuation ();
1975 
1976  // this ifdef'd block of code was an attempt to adjust loca parameters
1977  // in-situ. If the voltage change is really, really small, then there
1978  // isn't much point in doing a continuation, so I wanted to have to
1979  // option to on-the-fly switch to straight Newton.
1980  //
1981  // Unfortunately, it doesn't work at the moment - the second time it gets
1982  // called, everything goes haywire. ERK 2/25/04.
1983 #if 0
1984  Xyce::dout() << "suggested steps are: " << suggestedSteps << std::endl;
1985 
1986  Util::ParamList::const_iterator it_tpL;
1987  for (it_tpL = innerSolverOptions_.params.begin();
1988  it_tpL != innerSolverOptions_.params.end();
1989  ++it_tpL)
1990  {
1991  ExtendedString tmpTag = it_tpL->tag ();
1992  tmpTag.toUpper ();
1993 
1994  Xyce::dout() << "tmpTag = " << tmpTag << std::endl;
1995 
1996  if (tmpTag == "CONTINUATION")
1997  {
1998  if (suggestedSteps <= 1) // then just do one newton step.
1999  {
2000  Xyce::dout() << "Setting the solver type to 0" << std::endl;
2001  suggestedSteps = 1;
2002  it_tpL->setVal(0);
2003  }
2004  else
2005  {
2006  it_tpL->setVal(1);
2007  }
2008  }
2009  }
2010 
2013 #endif
2014  statInner = nlsInnerPtr_->solve (nlsPassingPtr_);
2015 
2016  nlsPassingPtr_ = 0;
2018 
2020 
2021  return statInner;
2022 }
2023 
2024 //-----------------------------------------------------------------------------
2025 // Function : TwoLevelNewton::enableSensitivity
2026 //
2027 // Purpose : This re-sets the code for a sensitivity calculation.
2028 // Mainly, it loads the jacobian and rhs vectors in FULL
2029 // newton mode, if neccessary.
2030 //
2031 // Special Notes : Since the implementation of the "fullNewtonEnforce"
2032 // parameter, this has become less crucial. When this option
2033 // is enabled (the default), then the last loads prior to this
2034 // function being called were full newton loads, so there is
2035 // no need to re-do them.
2036 //
2037 // Scope : public
2038 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
2039 // Creation Date : 04/21/03
2040 //-----------------------------------------------------------------------------
2042 {
2043  if (VERBOSE_NONLINEAR)
2044  Xyce::dout() << std::endl
2045  << Xyce::section_divider << std::endl
2046  << "TwoLevelNewton::enableSensitivity " << std::endl;
2047 
2048  bool bsuccess = true;
2049  bool tmpBool = true;
2050 
2052  tmpBool = NonLinearSolver::rhs_ (); bsuccess = bsuccess && tmpBool;
2053  tmpBool = NonLinearSolver::jacobian_ (); bsuccess = bsuccess && tmpBool;
2054 
2055  if (VERBOSE_NONLINEAR) {
2056  // print out the norm info for this "full newton" residual:
2057  double maxNormRHS_=0, twoNormRHS_ = 0.0;
2058  rhsVectorPtr_->infNorm(&maxNormRHS_);
2059  rhsVectorPtr_->lpNorm(2, &twoNormRHS_);
2060  Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
2061  Xyce::dout() << std::endl;
2062  Xyce::dout() << "Max. norm of full Newton RHS: " << maxNormRHS_ << std::endl;
2063  Xyce::dout() << " 2-norm of full Newton RHS: " << twoNormRHS_ << std::endl;
2064  Xyce::dout() << Xyce::section_divider << std::endl;
2065  }
2066 
2067  if (DEBUG_NONLINEAR)
2068  {
2069 
2070  static int callsSens = 0;
2071  char filename1[256]; for (int ich = 0; ich < 256; ++ich) filename1[ich] = 0;
2072  char filename2[256]; for (int ich = 0; ich < 256; ++ich) filename2[ich] = 0;
2073 
2074  sprintf(filename1, "matrixTmp%d.txt",callsSens);
2075  Linear::Matrix *A = lasSysPtr_->getJacobianMatrix();
2076  A->writeToFile(filename1);
2077 
2078 
2079  Linear::Vector *b = lasSysPtr_->getRHSVector();
2080  sprintf(filename2, "rhsTmp%d.txt", callsSens);
2081  int size, i;
2082  FILE *fp1;
2083 
2084 #ifndef Xyce_PARALLEL_MPI
2085  fp1 = fopen(filename2,"w");
2086  size = lasSysPtr_->getSolutionSize();
2087  for (i=0;i<size;++i)
2088  {
2089  double output = b->getElementByGlobalIndex(i);
2090  fprintf(fp1,"%25.18e\n",output);
2091  }
2092  fclose(fp1);
2093 #endif
2094 
2095  Linear::Vector *x = (*nextSolVectorPtrPtr_);
2096  sprintf(filename2, "solTmp%d.txt", callsSens);
2097 
2098 #ifndef Xyce_PARALLEL_MPI
2099  fp1 = fopen(filename2,"w");
2100  size = lasSysPtr_->getSolutionSize();
2101  for (i=0;i<size;++i)
2102  {
2103  double output = x->getElementByGlobalIndex(i);
2104  fprintf(fp1,"%25.18e\n",output);
2105  }
2106  fclose(fp1);
2107 #endif
2108 
2109  ++callsSens;
2110  }
2111  return bsuccess;
2112 }
2113 
2114 //-----------------------------------------------------------------------------
2115 // Dummy function since homotopy doesn't work with 2-level. (for the outer loop)
2116 //-----------------------------------------------------------------------------
2118 {
2119  return true;
2120 }
2121 
2122 //-----------------------------------------------------------------------------
2123 // Dummy function ... for now. This probably needs to get revamped.
2124 //-----------------------------------------------------------------------------
2126 {
2127  return 0;
2128 }
2129 
2130 //-----------------------------------------------------------------------------
2131 // Dummy function ... for now. This probably needs to get revamped.
2132 //-----------------------------------------------------------------------------
2134 {
2135  return 0;
2136 }
2137 
2138 } // namespace Nonlinear
2139 } // namespace Xyce
virtual int getMaxNormFindex() const =0
std::vector< std::string > paramNameList
bool setTwoLevelTranOptions(const Util::OptionBlock &OB)
bool loadCouplingRHS(int iSubProblem, int iCouple, Linear::Vector *dfdvPtr)
void setAnalysisMode(AnalysisMode mode)
virtual int solve(NonLinearSolver *nlsTmpPtr=NULL)=0
bool registerLinearSystem(Linear::System *ptr)
virtual bool setTranOptions(const Util::OptionBlock &OB)=0
virtual int takeFirstSolveStep(NonLinearSolver *nlsTmpPtr=NULL)
bool registerNonlinearEquationLoader(Loader::NonlinearEquationLoader *ptr)
Pure virtual class to augment a linear system.
bool setTranOptions(const Util::OptionBlock &OB)
virtual bool outputPlotFiles() const
Definition: N_LOA_Loader.h:261
bool setTwoLevelLocaOptions(const Util::OptionBlock &OB)
bool setLinsolOptions(const Util::OptionBlock &OB)
virtual double getMaxNormF() const =0
bool setTwoLevelOptions(const Util::OptionBlock &OB)
Analysis::AnalysisManager * analysisManager_
virtual void setReturnCodes(const ReturnCodes &retCodesTmp)
bool setLocaOptions(const Util::OptionBlock &OB)
bool registerAnalysisManager(Analysis::AnalysisManager *analysis_manager)
bool setHBOptions(const Util::OptionBlock &OB)
int solve(NonLinearSolver *nlsTmpPtr=NULL)
bool setParam(std::string &name, double val, bool overrideOriginal=false)
bool setOptions(const Util::OptionBlock &OB)
bool calcCouplingTerms(int iSubProblem, int iCouple, const Linear::Vector *dxdvPtr)
bool registerTwoLevelSolver(TwoLevelNewton *ptr)
virtual unsigned int getTotalNumLinearIters()
virtual unsigned int getTotalNumLinearIters()
bool registerTIADataStore(TimeIntg::DataStore *ptr)
Loader::NonlinearEquationLoader * nonlinearEquationLoader_
virtual bool registerTIADataStore(TimeIntg::DataStore *ptr)
virtual bool registerLinearSystem(Linear::System *ptr)
virtual bool setLinsolOptions(const Util::OptionBlock &OB)
int algorithm0_(bool nl_poisson_dcop)
virtual bool registerParallelMgr(N_PDS_Manager *ptr)
virtual bool registerAnalysisManager(Analysis::AnalysisManager *tmp_anaIntPtr)
void getNumInterfaceNodes(std::vector< int > &numINodes)
virtual void setAnalysisMode(AnalysisMode mode)=0
bool registerOutputMgr(IO::OutputMgr *ptr)
bool setNLPOptions(const Util::OptionBlock &OB)
bool registerOutputMgr(IO::OutputMgr *outPtr)
void printStepInfo_(int step, int success, TwoLevelNewtonMode solveType)
virtual bool setOptions(const Util::OptionBlock &OB)=0
virtual int getNumIterations() const =0
virtual bool registerNonlinearEquationLoader(Loader::NonlinearEquationLoader *ptr)
bool registerParallelMgr(N_PDS_Manager *ptr)
virtual bool setLocaOptions(const Util::OptionBlock &OB)