Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_NLS_NOX_Interface.C
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2 // Copyright Notice
3 //
4 // Copyright 2002 Sandia Corporation. Under the terms
5 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
6 // Government retains certain rights in this software.
7 //
8 // Xyce(TM) Parallel Electrical Simulator
9 // Copyright (C) 2002-2014 Sandia Corporation
10 //
11 // This program is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation, either version 3 of the License, or
14 // (at your option) any later version.
15 //
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 //-----------------------------------------------------------------------------
24 
25 //-------------------------------------------------------------------------
26 // Filename : $RCSfile: N_NLS_NOX_Interface.C,v $
27 //
28 // Purpose : Interface to Xyce vectors for NOX.
29 //
30 // Special Notes :
31 //
32 // Creator : Tammy Kolda, NLS, 8950
33 //
34 // Creation Date : 01/31/02
35 //
36 // Revision Information:
37 // ---------------------
38 //
39 // Revision Number: $Revision: 1.158 $
40 //
41 // Revision Date : $Date: 2014/02/24 23:49:25 $
42 //
43 // Current Owner : $Author: tvrusso $
44 //-------------------------------------------------------------------------
45 
46 #include <Xyce_config.h>
47 
48 
49 // ---------- Standard Includes ----------
50 
51 // ---------- Xyce Includes ----------
52 
53 #ifndef HAVE_CONFIG_H
54 #define HAVE_CONFIG_H
55 #endif
56 
57 #include <sstream>
58 
59 #include "N_NLS_NOX_Interface.h"
60 #include "N_NLS_NOX_SharedSystem.h"
61 #include "N_NLS_NOX_Group.h"
62 #include "N_NLS_LOCA_Group.h"
63 #include "LOCA_GlobalData.H"
64 #include "LOCA_StatusTest_Wrapper.H"
65 #include "NOX_Solver_Factory.H"
66 
69 
70 #include "N_NLS_NOX_XyceTests.h"
72 #include "N_LAS_Solver.h"
73 #include "N_LAS_Builder.h"
74 #include "N_LAS_System.h"
75 #include "N_LAS_QueryUtil.h"
76 #include "N_LOA_Loader.h"
77 #include "N_IO_CmdParse.h"
78 #include "N_IO_OutputMgr.h"
80 
81 #ifdef Xyce_PARALLEL_MPI
82 #include <N_PDS_ParComm.h>
83 #else
84 #include <N_PDS_SerialComm.h>
85 #endif
86 
87 
88 // ---------- NOX Includes ----------
89 #include "LOCA.H"
90 
91 // ----------- Forward declarations -------
92 using namespace N_NLS_NOX;
93 
94 //-----------------------------------------------------------------------------
95 // Function : N_NLS_NOX::Interface::Interface
96 // Purpose : constructor
97 // Special Notes :
98 // Scope : public
99 // Creator :
100 // Creation Date :
101 //-----------------------------------------------------------------------------
102 Interface::Interface(N_IO_CmdParse & cp) :
104  dcParams_(DC_OP),
105  transientParams_(TRANSIENT),
106  hbParams_(HB_MODE),
107  sharedSystemPtr_(0),
108  mode_(DC_OP),
109  lastParametersMode_(DC_OP),
110  parametersMode_(DC_OP),
111  usemode_(true),
112  copiedGroupFlag_(false),
113  DCOPused_(false),
114  ICspecified_(false),
115  NODESETspecified_(false),
116  isFirstContinuationParam_(true),
117  firstSolveComplete_(false),
118  iParam_(0)
119 {
120 }
121 
122 //-----------------------------------------------------------------------------
123 // Function : N_NLS_NOX::Interface::~Interface
124 // Purpose : destructor
125 // Special Notes :
126 // Scope : public
127 // Creator :
128 // Creation Date :
129 //-----------------------------------------------------------------------------
131 {
132  delete sharedSystemPtr_;
133  if (!Teuchos::is_null(globalDataPtr_))
134  {
135  LOCA::destroyGlobalData(globalDataPtr_);
136  }
137 }
138 
139 //-----------------------------------------------------------------------------
140 // Function : N_NLS_NOX::Interface::setOptions
141 // Purpose : Passes option block corresponding to "NONLIN" onto
142 // nonlinear solver. These parameters set convergence
143 // tolerances, the type of method used, and so on.
144 // Special Notes :
145 // Return Type : boolean
146 //
147 // See also : setTranOptions, setAnalysisMode
148 //
149 // - Input Arguments -
150 //
151 // OB : Option block containing options corresponding to
152 // "NONLIN" in the netlist.
153 // Scope : public
154 // Creator :
155 // Creation Date :
156 //-----------------------------------------------------------------------------
157 bool Interface::setOptions(const N_UTL_OptionBlock& OB)
158 {
159  return dcParams_.setOptions(OB);
160 }
161 
162 
163 //-----------------------------------------------------------------------------
164 // Function : N_NLS_NOX::Interface::setTranOptions
165 //
166 // Purpose : Passes option block corresponding to "NONLIN-TRAN" onto
167 // nonlinear solver. This affects the settings used when
168 // the mode is Transient.
169 //
170 // Special Notes :
171 // Return Type : boolean
172 //
173 // See also : setOptions, setAnalysisMode
174 //
175 // - Input Arguments -
176 // OB : Option block containing options corresponding to
177 // "NONLIN-TRAN" in the netlist.
178 // Scope : public
179 // Creator :
180 // Creation Date :
181 //-----------------------------------------------------------------------------
182 bool Interface::setTranOptions(const N_UTL_OptionBlock& OB)
183 {
184  return transientParams_.setOptions(OB);
185 }
186 
187 //-----------------------------------------------------------------------------
188 // Function : N_NLS_NOX::Interface::setHBOptions
189 // Purpose :
190 // Scope : public
191 // Creator :
192 // Creation Date :
193 //-----------------------------------------------------------------------------
194 bool Interface::setHBOptions(const N_UTL_OptionBlock& OB)
195 {
196  return hbParams_.setOptions(OB);
197 }
198 
199 
200 //-----------------------------------------------------------------------------
201 // Function : N_NLS_NOX::Interface::setLocaOptions
202 // Purpose :
203 // Special Notes :
204 // Scope : public
205 // Creator :
206 // Creation Date :
207 //-----------------------------------------------------------------------------
208 bool Interface::setLocaOptions(const N_UTL_OptionBlock& OB)
209 {
210  return dcParams_.setLocaOptions(OB);
211 }
212 
213 //-----------------------------------------------------------------------------
214 // Function : N_NLS_NOX::Interface::setDCOPRestartOptions
215 // Purpose :
216 // Special Notes :
217 // Scope : public
218 // Creator :
219 // Creation Date :
220 //-----------------------------------------------------------------------------
221 bool Interface::setDCOPRestartOptions(const N_UTL_OptionBlock& OB)
222 {
223  DCOPspecified_ = true;
224  return true;
225 }
226 
227 //-----------------------------------------------------------------------------
228 // Function : N_NLS_NOX::Interface::setICOptions
229 // Purpose :
230 // Special Notes :
231 // Scope : public
232 // Creator :
233 // Creation Date :
234 //-----------------------------------------------------------------------------
235 bool Interface::setICOptions(const N_UTL_OptionBlock& OB)
236 {
237  ICspecified_ = true;
238  return true;
239 }
240 
241 //-----------------------------------------------------------------------------
242 // Function : N_NLS_NOX::Interface::setNodeSetOptions
243 // Purpose :
244 // Special Notes :
245 // Scope : public
246 // Creator :
247 // Creation Date :
248 //-----------------------------------------------------------------------------
249 bool Interface::setNodeSetOptions(const N_UTL_OptionBlock& OB)
250 {
251  NODESETspecified_ = true;
252  return true;
253 }
254 
255 //-----------------------------------------------------------------------------
256 // Function : N_NLS_NOX::Interface::initializeAll
257 //
258 // Purpose : Called after all register and set functions.
259 // Once the various registrations have taken place,
260 // this function sets the remaining pointers.
261 //
262 // Special Notes :
263 // Derived Notes : This function also calls the base object initializeAll.
264 //
265 // Special Notes: This function obtains the solution, temporary solution and
266 // f vectors from the LAS system class.
267 //
268 // Return Type : boolean
269 // Scope : public
270 // Creator :
271 // Creation Date :
272 //-----------------------------------------------------------------------------
274 {
275  // Use the base class initialization
276  bool initok = N_NLS_NonLinearSolver::initializeAll();
277  if (!initok)
278  {
279  return false;
280  }
281 
282  // Set the processor ID for printing in the nonlinear solver
283  // For now, processor 0 will output information to the screen
284  //int myPID = ((**nextSolVectorPtrPtr_).epetraObj()).Comm().MyPID();
285  int myPID = pdsMgrPtr_->getPDSComm()->procID();
286  dcParams_.setOutputOptions(myPID, 0);
288 
289  // get var type list
290  std::vector<char> varTypeVec;
291 #if 0
292  topologyRcp_->returnVarTypeVec( varTypeVec );
293 #endif
294  hbParams_.setOutputOptions(myPID, 0);
295 
296  // Set up the status tests
297 #ifdef Xyce_NLS_MASKED_WRMS_NORMS
298  bool testsok =
300  lasSysPtr_->getNonTrivialDeviceMaskFlag(), lasSysPtr_->getDeviceMaskVector()) &&
302  lasSysPtr_->getNonTrivialDeviceMaskFlag(), lasSysPtr_->getDeviceMaskVector()) &&
304  lasSysPtr_->getNonTrivialDeviceMaskFlag(), lasSysPtr_->getDeviceMaskVector());
305 #else
306  bool testsok =
310 #endif
311 
312  if (!testsok)
313  return false;
314 
315  // Set up any linear solver options
316  // We only set the tolerance if adaptive forcing is being used.
317  setAZ_Tol_DC = false;
318  setAZ_Tol_Transient = false;
319  if (!(dcParams_.getNoxParams()->sublist("Direction").sublist("Newton")
320  .get("Forcing Term Method","Constant") == std::string("Constant")))
321  {
322  setAZ_Tol_DC = true;
323  //Xyce::dout() << "NOX is overriding DC LS tol." << std::endl;
324  }
325  if (!(transientParams_.getNoxParams()->sublist("Direction").sublist("Newton")
326  .get("Forcing Term Method", "Constant") == std::string("Constant")))
327  {
328  setAZ_Tol_Transient = true;
329  //Xyce::dout() << "NOX is overriding Transient LS tol." << std::endl;
330  }
331  if (!(hbParams_.getNoxParams()->sublist("Direction").sublist("Newton")
332  .get("Forcing Term Method", "Constant") == std::string("Constant")))
333  {
334  setAZ_Tol_Transient = true;
335  //Xyce::dout() << "NOX is overriding Transient LS tol." << std::endl;
336  }
337 
338  return true;
339 }
340 
341 //-----------------------------------------------------------------------------
342 // Function : N_NLS_NOX::Interface::solve
343 //
344 // Purpose : Reset all the counters and parameters and solve the
345 // nonlinear problem for this time step. The solution is
346 // stored in nextSolVector (obtained from the N_LAS_System
347 // registered above by registerLinearSystem).
348 //
349 // Special Notes : Should not be called until *after* initializeAll() has
350 // been called.
351 //
352 // Return Type : Integer - postive for sucess, negative for failure.
353 // Special Notes :
354 // Scope : public
355 // Creator : Roger Pawlowski, SNL 9233
356 // Creation Date :
357 //-----------------------------------------------------------------------------
359 {
360 
361  try
362  {
363 
364  // For base object
366 
367 #ifdef Xyce_DEBUG_NONLINEAR
368  N_NLS_NonLinearSolver::setDebugFlags ();
369 #endif
370 
371  // Setup the status tests
372  if (Teuchos::is_null(locaStatusTestPtr_))
373  {
375  Teuchos::rcp(new LOCA::StatusTest::Wrapper(dcParams_.getStatusTests()));
377  Teuchos::rcp(new LOCA::StatusTest::Wrapper(transientParams_.getStatusTests()));
379  Teuchos::rcp(new LOCA::StatusTest::Wrapper(hbParams_.getStatusTests()));
380 
381  }
382 
383  // Pick the parameter set to use.
384  ParameterSet* paramsPtr;
385  if ((usemode_) && (mode_ == TRANSIENT))
386  {
387  paramsPtr = &transientParams_;
391  }
392  else if ((usemode_) && (mode_ == HB_MODE))
393  {
394  paramsPtr = &hbParams_;
398  }
399  else
400  {
401  paramsPtr = &dcParams_;
405  }
406 
407  if (Teuchos::is_null(globalDataPtr_))
408  globalDataPtr_ = LOCA::createGlobalData(paramsPtr->getAllParams());
409 
410  // set the xyce return codes:
412 
413  // Set up the shared system (we have to redo this every time because
414  // the object pointed to by nextSolVectorPtrPtr may have changed.
415  //delete sharedSystemPtr_;
416  if (sharedSystemPtr_ == 0)
418  *rhsVectorPtr_,
422  *lasSysPtr_,
423  *this);
424  else
426  *rhsVectorPtr_,
430  *lasSysPtr_,
431  *this);
432 
433  //////////////////////////////////////////////////////////////////////////
434  // erkeite: Group handling required by 2-level Newton:
435  // Reset up the corresponding group as well
436  if (nlsTmpPtr==0)
437  {
438  if (Teuchos::is_null(groupPtr_))
439  {
440  groupPtr_ = Teuchos::rcp(new N_NLS_LOCA::Group(globalDataPtr_,
442  getLoader(),
443  *outMgrPtr_,
444  *anaIntPtr_)
445  );
446  }
447  else
448  {
450  groupPtr_->setX(tmpVec);
451  }
452  }
453  else
454  {
455  copiedGroupFlag_ = true;
456  Interface * nlsOtherPtr = dynamic_cast<Interface*>(nlsTmpPtr);
457  groupPtr_ = nlsOtherPtr->getSolutionGroup();
458  }
459  // End of block needed by 2-level Newton.
460  //////////////////////////////////////////////////////////////////////////
461 
462  int solverType = paramsPtr->getNoxSolverType();
463 
464  // Setting the nonContinuation flag is required to prevent incorrect
465  // N_DEV_DeviceMgr::setParam calls.
466  if (solverType==0)
467  {
468  groupPtr_->setNonContinuationFlag (true);
469  }
470  else
471  {
472  groupPtr_->setNonContinuationFlag (false);
473  }
474 
475 #ifdef Xyce_DEBUG_NONLINEAR
476  Xyce::dout() << "solverType is " << solverType << std::endl;
477 #endif
478 
479  // (0) Standard Newton Method Solve (includes line search and
480  // trust region based methods
481  if (solverType == 0)
482  {
483  bool usedIC=false;
484  bool usedNODESET=false;
485  bool usedOP=false;
486 
487  // RPP: needed for tensor method. DO NOT UNCOMMENT!
488  // This somehow breaks the one-shot test circuit.
489  // ERK: it breaks it (and probably many other circuits) b/c voltage
490  // limiting is fragile and cannot handle extra (unexpected)
491  // F-loads.
492  //groupPtr_->computeF();
493 
494  // Set up nox nonlinear solver. solverPtr is only needed for
495  // non-LOCA (i.e. just Newton's method, no continuation) solves.
496  if (Teuchos::is_null(solverPtr_))
497  {
498 #ifdef Xyce_DEBUG_NONLINEAR
499  Xyce::dout() << "Creating new NLS solver b/c it is 0." <<std::endl;
500 #endif
501  solverPtr_ = NOX::Solver::buildSolver(groupPtr_,
502  paramsPtr->getStatusTests(),
503  paramsPtr->getNoxParams());
504 
505  // If .IC, .NODESET or .OP have been specified, then set up the
506  // augmented linear systems
507  if ((usemode_) && (mode_ != TRANSIENT))
508  {
509  if (ICspecified_)
510  {
511  usedIC=icCont (paramsPtr);
512  }
513  else if (NODESETspecified_)
514  {
515  usedNODESET=nodesetCont0 (paramsPtr);
516  }
517  else
518  {
519  usedOP = opStartCont0 (paramsPtr);
520  }
521  }
522  }
523  else if ((usemode_) && (lastParametersMode_ != parametersMode_))
524  {
525 #ifdef Xyce_DEBUG_NONLINEAR
526  Xyce::dout() << "Creating new NLS solver b/c starting next phase, post-DC." <<std::endl;
527 #endif
528  // Create a new solver for the next phase of the simulation.
529  solverPtr_ = NOX::Solver::buildSolver(groupPtr_,
530  paramsPtr->getStatusTests(),
531  paramsPtr->getNoxParams());
532  }
533  else // solverPtr is not null, and the mode didn't change since last call.
534  {
535 #ifdef Xyce_DEBUG_NONLINEAR
536  Xyce::dout() << "NOT Creating new NLS solver, just resetting." <<std::endl;
537 #endif
538  solverPtr_->reset(groupPtr_->getX());
539  }
540 
541  NOX::StatusTest::StatusType status = solverPtr_->solve();
542  firstSolveComplete_ = true;
543 
544  if (usedIC)
545  {
546  Teuchos::RefCountPtr<N_NLS_NOX::AugmentLinSys> alsNull; // 0
547  groupPtr_->setAugmentLinearSystem(false, alsNull);
548  }
549  // Send back the correct return code
550 #ifdef Xyce_DEBUG_NONLINEAR
551  Xyce::dout() << "return code for transient params: " << transientParams_.getStatusTestReturnCode() <<std::endl;;
552  Xyce::dout() << "return code for hb params: " << hbParams_.getStatusTestReturnCode() << std::endl;
553  Xyce::dout() << "return code for dc params: " << dcParams_.getStatusTestReturnCode () <<std::endl;
554 #endif
555  return (paramsPtr->getStatusTestReturnCode());
556  }
557  // (1) Natural Parameter Continuation
558  else if (solverType == 1)
559  {
560  std::vector<std::string> pars;
561  std::string con;
562  int j, numParam = 0;
563  double value;
564  bool usedOP=false;
565  bool usedNODESET=false;
566  bool usedIC=false;
567 
568  if ((usemode_) && (mode_ != TRANSIENT))
569  {
570  if (ICspecified_)
571  {
572  usedIC=icCont (paramsPtr);
573  }
574  else if (NODESETspecified_)
575  {
576  usedNODESET=nodesetCont1 (paramsPtr);
577  }
578  else
579  {
580  usedOP = opStartCont1 (paramsPtr);
581  }
582  }
583 
584  Teuchos::RefCountPtr<Teuchos::ParameterList> locaList =
585  paramsPtr->getLocaParams();
586 
587  // Create Parameter Vector and get the stepper parameter list.
588  LOCA::ParameterVector locaPVec;
589  Teuchos::ParameterList& stepperList = locaList->sublist("Stepper");
590  Teuchos::ParameterList& stepSizeList = locaList->sublist("Step Size");
591 
592  while (paramsPtr->getVectorParam("CONPARAM", numParam, con))
593  {
594  pars.push_back(con);
595  numParam++;
596  }
597 
598  // Fail out if no parameters have been specified.
599  if ( numParam == 0 ) {
600  std::string message = "Using \"continuation=1\" requires a parameter to be set with the conparam keyword in the loca option block!";
601  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::USR_FATAL, message);
602  }
603 
604  Teuchos::RefCountPtr<N_NLS_NOX::AugmentLinSys> als;
605  Teuchos::RefCountPtr<N_NLS_NOX::AugmentLinSys> alsNull; // 0
606 
607  std::vector<double> minValue(numParam, 0.);
608  std::vector<double> maxValue(numParam, 0.);
609  std::vector<double> initialValue(numParam, 0.);
610  std::vector<double> initialStepSize(numParam, 0.);
611  std::vector<double> minStepSize(numParam, 0.);
612  std::vector<double> maxStepSize(numParam, 0.);
613  std::vector<double> aggressiveness(numParam, 0.);
614 
615  // Check the size of params to make sure users provided all required data
616  std::vector<std::string> paramNames(0);
617  paramNames.push_back("MINVALUE");
618  paramNames.push_back("MAXVALUE");
619  paramNames.push_back("INITIALVALUE");
620  paramNames.push_back("INITIALSTEPSIZE");
621  paramNames.push_back("MINSTEPSIZE");
622  paramNames.push_back("MAXSTEPSIZE");
623  paramNames.push_back("AGGRESSIVENESS");
624 
625  for (std::size_t p = 0 ; p < paramNames.size() ; ++p) {
626  if ( paramsPtr->getVectorParamSize(paramNames[p]) != numParam) {
627  std::string msg = "The parameter \"" +
628  paramNames[p] +
629  "\" must have a list of values with size equal to the numParamber of parameters specified in \"conparam\".";
630  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
631  }
632  }
633 
634  for (iParam_=0 ; iParam_<numParam ; ++iParam_)
635  {
636  paramsPtr->getVectorParam("MINVALUE", iParam_, value);
637  minValue[iParam_] = value;
638 
639  paramsPtr->getVectorParam("MAXVALUE", iParam_, value);
640  maxValue[iParam_] = value;
641 
642  paramsPtr->getVectorParam("INITIALVALUE", iParam_, value);
643  initialValue[iParam_] = value;
644 
645  paramsPtr->getVectorParam("INITIALSTEPSIZE", iParam_, value);
646  initialStepSize[iParam_] = value;
647 
648  paramsPtr->getVectorParam("MINSTEPSIZE", iParam_, value);
649  minStepSize[iParam_] = value;
650 
651  paramsPtr->getVectorParam("MAXSTEPSIZE", iParam_, value);
652  maxStepSize[iParam_] = value;
653 
654  paramsPtr->getVectorParam("AGGRESSIVENESS", iParam_, value);
655  aggressiveness[iParam_] = value;
656 
657  locaPVec.addParameter (pars[iParam_], initialValue[iParam_]);
658 
659  }
660 
661  if (usedOP || usedNODESET)
662  {
663  const N_NLS_LOCA::Group & conLocaGrp =
664  dynamic_cast<const N_NLS_LOCA::Group&>(solverPtr_->getSolutionGroup());
665  *groupPtr_ = const_cast<N_NLS_LOCA::Group&>(conLocaGrp);
666  solverPtr_ = Teuchos::null;
667  }
668 
669  groupPtr_->setParams(locaPVec);
670 
671  LOCA::Abstract::Iterator::IteratorStatus locaStatus;
672 
673  for (iParam_=0 ; iParam_<numParam ; ++iParam_)
674  {
675  // Copy out the solution and use it in the next run
676  if (iParam_ > 0)
677  {
678  groupPtr_->copy(*(stepperPtr_->getSolutionGroup()));
679  }
680 
681  stepperList.set("Continuation Parameter", pars[iParam_]);
682  stepperList.set("Initial Value", initialValue[iParam_]);
683  stepperList.set("Max Value", maxValue[iParam_]);
684  stepperList.set("Min Value", minValue[iParam_]);
685  stepSizeList.set("Initial Step Size", initialStepSize[iParam_]);
686  stepSizeList.set("Min Step Size", minStepSize[iParam_]);
687  stepSizeList.set("Max Step Size", maxStepSize[iParam_]);
688  stepSizeList.set("Aggressiveness", aggressiveness[iParam_]);
689 
690  for (j=0 ; j<iParam_ ; ++j)
691  {
692  locaPVec.setValue(pars[j], maxValue[j]);
693  }
694  for (j=iParam_ ; j<numParam ; ++j)
695  {
696  locaPVec.setValue(pars[j], initialValue[j]);
697  }
698  groupPtr_->setParams(locaPVec);
699 
700  if (iParam_==0)
701  {
702  if (!usedOP && !usedNODESET) // (usedOP and usedNODESET have already loaded F)
703  {
704  groupPtr_->computeF();
705  }
706  }
707 
708  // RPP 03/08/2006 If this is a special parameter used in voltage
709  // node resistance (Spice's GMIN stepping) then we need to
710  // intercept and handle the parameter in the solver (in the LOCA
711  // Group) - the device package does nothing for this parameter.
712  if (pars[iParam_] != "GSTEPPING")
713  {
714  // Do the continuation run
716  locaStatus = stepperPtr_->run();
717  if (usedIC || usedNODESET)
718  {
719  groupPtr_->setAugmentLinearSystem(false, alsNull);
720  }
721  }
722  else
723  {
724  if (iParam_ == 0 && DCOPused_)
725  {
726  std::string message = "'.dcop input=' and gstepping are incompatible";
727  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::USR_FATAL, message);
728  }
729  Teuchos::RefCountPtr<N_NLS_NOX::AugmentLinSys> als =
731  groupPtr_->setAugmentLinearSystem(true, als);
732 
733  // Do the continuation run
735  locaStatus = stepperPtr_->run();
736 
737  groupPtr_->setAugmentLinearSystem(false, alsNull);
738  }
739 
740  // Kick out if continuation failed
741  if (locaStatus != LOCA::Abstract::Iterator::Finished)
742  return (-1);
743 
744  // Increment Param Number Tracking
746  firstSolveComplete_ = true;
747  }
748  return (paramsPtr->getStatusTestReturnCode());
749  }
750  // (2) Mosfet specific continuation
751  else if (solverType == 2)
752  {
753  bool usedOP=false;
754  bool usedNODESET=false;
755  bool usedIC=false;
756  Teuchos::RefCountPtr<N_NLS_NOX::AugmentLinSys> alsNull; // 0
757 
758  if ((usemode_) && (mode_ != TRANSIENT))
759  {
760  if (ICspecified_)
761  {
762  usedIC=icCont (paramsPtr);
763  }
764  else if (NODESETspecified_)
765  {
766  usedNODESET=nodesetCont1 (paramsPtr);
767  }
768  else
769  {
770  usedOP = opStartCont1 (paramsPtr);
771  }
772  }
773 
774  // check if use specified vector params. If so, flag a warning.
775  std::vector<std::string> pars;
776  std::string con;
777  int numParam;
778  while (paramsPtr->getVectorParam("CONPARAM", numParam, con))
779  {
780  pars.push_back(con);
781  numParam++;
782  }
783 
784  if ( numParam > 1 ) {
785  std::string message = "WARNING: Using \"continuation=2\" currently does not support vectorized loca parameters. Only the first values in each list will be used.";
786  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::USR_WARNING, message);
787  }
788 
789  Teuchos::RefCountPtr<Teuchos::ParameterList> locaList = paramsPtr->getLocaParams();
790 
791  // Create the continuation parameter names
792  std::string gain = "mosfet:gainscale";
793  std::string nonlinear = "mosfet:nltermscale";
794 
795  // Create Parameter Vector and get the stepper parameter list.
796  LOCA::ParameterVector locaPVec;
797  Teuchos::ParameterList& stepperList = locaList->sublist("Stepper");
798  Teuchos::ParameterList& predictorList = locaList->sublist("Predictor");
799  Teuchos::ParameterList& stepSizeList = locaList->sublist("Step Size");
800 
801  // Continuation solve from alpha2 (gain) = 0.0 -> 1.0
802  // with alpha1 (nlterm) = 0.0 (constant)
803  locaPVec.addParameter(gain, 0.0);
804  locaPVec.addParameter(nonlinear, 0.0);
805  groupPtr_->setParams(locaPVec);
806  stepperList.set("Continuation Parameter", gain);
807 
808  stepperList.set("Initial Value", 0.0);
809  stepperList.set("Max Value", 1.0);
810  stepperList.set("Min Value",-1.0);
811 
812  stepSizeList.set("Initial Step Size", 0.2);
813  stepSizeList.set("Min Step Size", 1.0e-4);
814  stepSizeList.set("Max Step Size", 1.0);
815  stepSizeList.set("Aggressiveness", 1.0);
816 
817  // assert the user-specified defaults, if any.
819 
820  // Initialize parameters in xyce
821  if (!usedOP && !usedNODESET) // (usedOP and usedNODESET have already loaded F)
822  {
823  groupPtr_->computeF();
824  }
825 
826  // Do the continuation run
827  iParam_ = 0;
829  LOCA::Abstract::Iterator::IteratorStatus locaStatus = stepperPtr_->run();
830 
831  // Kick out if continuation failed
832  if (locaStatus != LOCA::Abstract::Iterator::Finished)
833  return (-1);
834 
835  // Increment Param Number Tracking
837  firstSolveComplete_ = true;
838 
839  // Copy out the solution and use it in the next run
840  groupPtr_->copy(*(stepperPtr_->getSolutionGroup()));
841 
842  // Continuation solve from alpha1 (nlterm) = 0.0 -> 1.0
843  // with alpha2 (gain) = 1.0 (constant)
844  stepperList.set("Continuation Parameter", nonlinear);
845 
846  stepperList.set("Initial Value", 0.0);
847  stepperList.set("Max Value", 1.0);
848  stepperList.set("Min Value",-1.0);
849 
850  stepSizeList.set("Initial Step Size", 0.2);
851  stepSizeList.set("Min Step Size", 1.0e-4);
852  stepSizeList.set("Max Step Size", 1.0);
853  stepSizeList.set("Aggressiveness", 1.0);
854 
855  // assert the user-specified defaults, if any.
857 
858  locaPVec.setValue(gain, 1.0);
859  locaPVec.setValue(nonlinear, 0.0);
860  groupPtr_->setParams(locaPVec);
861 
862  // Do the continuation run
863  iParam_ = 1;
865  locaStatus = stepperPtr_->run();
866 
867  if (usedIC)
868  {
869  groupPtr_->setAugmentLinearSystem(false, alsNull);
870  }
871 
872  // Return the solution status
873  if (locaStatus != LOCA::Abstract::Iterator::Finished)
874  return (-1);
875  else
876  return (paramsPtr->getStatusTestReturnCode());
877 
878  }
879  else if (solverType == 3) // GMIN stepping, simple specification
880  {
881 
882 
883  Teuchos::RefCountPtr<Teuchos::ParameterList> locaList = paramsPtr->getLocaParams();
884 
885  // Create the continuation parameter names
886  std::string gmin = "GSTEPPING";
887 
888  // Create Parameter Vector and get the stepper parameter list.
889  LOCA::ParameterVector locaPVec;
890  Teuchos::ParameterList& stepperList = locaList->sublist("Stepper");
891  Teuchos::ParameterList& predictorList = locaList->sublist("Predictor");
892  Teuchos::ParameterList& stepSizeList = locaList->sublist("Step Size");
893 
894  // Continuation solve using Gmin stepping.
895  locaPVec.addParameter(gmin, 0.0);
896  groupPtr_->setParams(locaPVec);
897  stepperList.set("Continuation Parameter", gmin);
898  stepperList.set("Continuation Method", "Natural");
899 
900  stepSizeList.set("Method", "Adaptive");
901  predictorList.set("Method", "Constant");
902 
903  stepperList.set("Initial Value", 4.0);
904  stepperList.set("Min Value", -4.0);
905  paramsPtr->set_gstepping_min_value (-4.0);
906  stepperList.set("Max Value", 4.0);
907 
908  stepSizeList.set("Initial Step Size", -2.0);
909  stepSizeList.set("Min Step Size", 1.0e-6);
910  stepSizeList.set("Max Step Size", 1.0e+12);
911  stepSizeList.set("Aggressiveness", 0.01);
912 
913  stepperList.set("Max Steps", 400);
914  stepperList.set("Max Nonlinear Iterations", 20);
915 
916  // the following set of if-statemtents call functions that
917  // allocate augmented linear systems for various scenarios.
918  // It is important that the augmented systems get allocated
919  // after the paramter (above) have been set.
920  bool usedOP=false;
921  bool usedNODESET=false;
922  bool usedIC=false;
923  Teuchos::RefCountPtr<N_NLS_NOX::AugmentLinSys> alsNull; // 0
924 
925  if ((usemode_) && (mode_ != TRANSIENT))
926  {
927  if (ICspecified_)
928  {
929  usedIC=icCont3 (paramsPtr);
930  }
931  else if (NODESETspecified_)
932  {
933  usedNODESET=nodesetCont1 (paramsPtr);
934  }
935  else
936  {
937  usedOP = opStartCont1 (paramsPtr);
938  }
939  }
940 
941  // Initialize parameters in xyce
942  if (!usedOP && !usedNODESET) // (usedOP and usedNODESET have already loaded F)
943  {
944  groupPtr_->computeF();
945  }
946 
947  // Do the continuation run
948  iParam_ = 0;
949  if (iParam_ == 0 && DCOPused_)
950  {
951  std::string message = "'.dcop input=' and gstepping are incompatible";
952  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::USR_FATAL, message);
953  }
954  if (!usedIC)
955  {
956  Teuchos::RefCountPtr<N_NLS_NOX::AugmentLinSys> als =
958  groupPtr_->setAugmentLinearSystem(true, als);
959  }
960 
961  // Do the continuation run
963  LOCA::Abstract::Iterator::IteratorStatus locaStatus = stepperPtr_->run();
964 
965  groupPtr_->setAugmentLinearSystem(false, alsNull);
966 
967  // Kick out if continuation failed
968  if (locaStatus != LOCA::Abstract::Iterator::Finished)
969  return (-1);
970  else
971  return (paramsPtr->getStatusTestReturnCode());
972  }
973  // (4) Mosfet specific continuation (ERK, new 2/21/2004)
974  else if (solverType == 4)
975  {
976 
977  Teuchos::RefCountPtr<Teuchos::ParameterList> locaList = paramsPtr->getLocaParams();
978 
979  // Create the continuation parameter names
980  std::string gain = "mosfet:gainscale";
981  std::string nonlinear = "mosfet:nltermscale";
982  std::string size = "mosfet:sizescale";
983 
984  // Create Parameter Vector and get the stepper parameter list.
985  LOCA::ParameterVector locaPVec;
986  Teuchos::ParameterList& stepperList = locaList->sublist("Stepper");
987 
988  // Continuation solve from alpha2 (gain) = 0.0 -> 1.0
989  // with alpha1 (nlterm) = 0.0 (constant)
990  // sizeScale = 0.0 (constant)
991  locaPVec.addParameter(gain, 0.0);
992  locaPVec.addParameter(nonlinear, 0.0);
993  locaPVec.addParameter(size, 0.0);
994  groupPtr_->setParams(locaPVec);
995  stepperList.set("Continuation Parameter", gain);
996  stepperList.set("Initial Value", 0.0);
997  stepperList.set("Max Value", 1.0);
998 
999  // Initialize parameters in xyce
1000  groupPtr_->computeF();
1001 
1002  // Do the continuation run
1004  LOCA::Abstract::Iterator::IteratorStatus locaStatus = stepperPtr_->run();
1005 
1006  // Kick out if continuation failed
1007  if (locaStatus != LOCA::Abstract::Iterator::Finished)
1008  return (-1);
1009 
1010  // Increment Param Number Tracking
1011  isFirstContinuationParam_ = false;
1012  firstSolveComplete_ = true;
1013 
1014  // Copy out the solution and use it in the next run
1015  groupPtr_->copy(*(stepperPtr_->getSolutionGroup()));
1016 
1017  // Continuation solve from alpha1 (nlterm) = 0.0 -> 1.0
1018  // with alpha2 (gain) = 1.0 (constant)
1019  // with size (scale) = 0.0 (constant)
1020  stepperList.set("Continuation Parameter", nonlinear);
1021  stepperList.set("Initial Value", 0.0);
1022  stepperList.set("Max Value", 1.0);
1023  locaPVec.setValue(gain, 1.0);
1024  locaPVec.setValue(nonlinear, 0.0);
1025  locaPVec.setValue(size, 0.0);
1026  groupPtr_->setParams(locaPVec);
1027 
1028  // Do the continuation run
1030  locaStatus = stepperPtr_->run();
1031 
1032  // Kick out if continuation failed
1033  if (locaStatus != LOCA::Abstract::Iterator::Finished)
1034  return (-1);
1035 
1036  // Copy out the solution and use it in the next run
1037  groupPtr_->copy(*(stepperPtr_->getSolutionGroup()));
1038 
1039  // Continuation solve from alpha1 (nlterm) = 1.0 -> 1.0
1040  // with alpha2 (gain) = 1.0 (constant)
1041  // with size (scale) = 0.0 -> 1.0
1042  stepperList.set("Continuation Parameter", size);
1043  stepperList.set("Initial Value", 0.0);
1044  stepperList.set("Max Value", 1.0);
1045  locaPVec.setValue(gain, 1.0);
1046  locaPVec.setValue(nonlinear, 1.0);
1047  locaPVec.setValue(size, 0.0);
1048  groupPtr_->setParams(locaPVec);
1049 
1050  // Do the continuation run
1052  locaStatus = stepperPtr_->run();
1053 
1054  // Return the solution status
1055  if (locaStatus != LOCA::Abstract::Iterator::Finished)
1056  return (-1);
1057  else
1058  return (paramsPtr->getStatusTestReturnCode());
1059 
1060  }
1061  // (5) Mosfet:BSIM3:Inverter specific continuation (RPP, new 2/25/2004)
1062  else if (solverType == 5)
1063  {
1064 
1065  Teuchos::RefCountPtr<Teuchos::ParameterList> locaList = paramsPtr->getLocaParams();
1066 
1067  // Create the continuation parameter names
1068  //std::string gain = "mosfet:gainscale";
1069  std::string nonlinear = "mosfet:nltermscale";
1070  std::string size = "mosfet:sizescale";
1071 
1072  // Create Parameter Vector and get the stepper parameter list.
1073  LOCA::ParameterVector locaPVec;
1074  Teuchos::ParameterList& stepperList = locaList->sublist("Stepper");
1075 
1076  // Continuation solve from alpha2 (gain) = 0.0 -> 1.0
1077  // with alpha1 (nlterm) = 0.0 (constant)
1078  // sizeScale = 0.0 (constant)
1079  //locaPVec.addParameter(gain, 0.0);
1080  locaPVec.addParameter(nonlinear, 0.0);
1081  locaPVec.addParameter(size, 0.0);
1082  groupPtr_->setParams(locaPVec);
1083  stepperList.set("Continuation Parameter", nonlinear);
1084  stepperList.set("Initial Value", 0.0);
1085  stepperList.set("Max Value", 1.0);
1086 
1087  // Initialize parameters in xyce
1088  groupPtr_->computeF();
1089 
1090  // Do the continuation run
1092  LOCA::Abstract::Iterator::IteratorStatus locaStatus = stepperPtr_->run();
1093 
1094  // Kick out if continuation failed
1095  if (locaStatus != LOCA::Abstract::Iterator::Finished)
1096  return (-1);
1097 
1098  // Increment Param Number Tracking
1099  isFirstContinuationParam_ = false;
1100  firstSolveComplete_ = true;
1101 
1102  // Copy out the solution and use it in the next run
1103  groupPtr_->copy(*(stepperPtr_->getSolutionGroup()));
1104 
1105  // Continuation solve from alpha1 (nlterm) = 0.0 -> 1.0
1106  // with alpha2 (gain) = 1.0 (constant)
1107  // with size (scale) = 0.0 (constant)
1108  stepperList.set("Continuation Parameter", size);
1109  stepperList.set("Initial Value", 0.0);
1110  stepperList.set("Max Value", 1.0);
1111  //locaPVec.setValue(gain, 1.0);
1112  locaPVec.setValue(nonlinear, 1.0);
1113  locaPVec.setValue(size, 0.0);
1114  groupPtr_->setParams(locaPVec);
1115 
1116  // Do the continuation run
1118  locaStatus = stepperPtr_->run();
1119 
1120  // Return the solution status
1121  if (locaStatus != LOCA::Abstract::Iterator::Finished)
1122  return (-1);
1123  else
1124  return (paramsPtr->getStatusTestReturnCode());
1125 
1126  }
1127  // (6) Mosfet:BSIM3:Inverter specific continuation (RPP, new 2/25/2004)
1128  else if (solverType == 6)
1129  {
1130 
1131  Teuchos::RefCountPtr<Teuchos::ParameterList> locaList = paramsPtr->getLocaParams();
1132 
1133  // Create the continuation parameter names
1134  std::string gain = "mosfet:gainscale";
1135  std::string nonlinear = "mosfet:nltermscale";
1136  std::string size = "mosfet:sizescale";
1137 
1138  // Create Parameter Vector and get the stepper parameter list.
1139  LOCA::ParameterVector locaPVec;
1140  Teuchos::ParameterList& stepperList = locaList->sublist("Stepper");
1141 
1142  // Continuation solve
1143  locaPVec.addParameter(gain, 1.0);
1144  locaPVec.addParameter(nonlinear, 1.0);
1145  locaPVec.addParameter(size, 0.0);
1146  groupPtr_->setParams(locaPVec);
1147  stepperList.set("Continuation Parameter", size);
1148  stepperList.set("Initial Value", 0.0);
1149  stepperList.set("Max Value", 1.0);
1150 
1151  // Initialize parameters in xyce
1152  groupPtr_->computeF();
1153 
1154  // Do the continuation run
1156  LOCA::Abstract::Iterator::IteratorStatus locaStatus = stepperPtr_->run();
1157 
1158  // Return the solution status
1159  if (locaStatus != LOCA::Abstract::Iterator::Finished)
1160  return (-1);
1161  else
1162  {
1163  firstSolveComplete_ = true;
1164  return (paramsPtr->getStatusTestReturnCode());
1165  }
1166 
1167  } // Block gainscale
1168  else if (solverType == 7)
1169  {
1170 
1171  // Get some initial objects
1172  Teuchos::RefCountPtr<Teuchos::ParameterList> locaList = paramsPtr->getLocaParams();
1173  Teuchos::ParameterList& stepperList = locaList->sublist("Stepper");
1174  LOCA::ParameterVector locaPVec;
1175 
1176  // Create storage for continuation objects
1177  int numGainBlocks = loaderPtr_->getHomotopyBlockSize();
1178  int numHomotopyContinuationRuns = 1 + numGainBlocks;
1179  std::vector<std::string> names(numHomotopyContinuationRuns);
1180  std::vector<double> initialVal(numHomotopyContinuationRuns);
1181  std::vector<double> finalVal(numHomotopyContinuationRuns);
1182  std::vector<double> minVal(numHomotopyContinuationRuns);
1183  std::vector<double> maxVal(numHomotopyContinuationRuns);
1184 
1185  // Set up continuation steps
1186  // ***************************************************
1187  // Changes vals below for continuation
1188  // ***************************************************
1189  for (int i = 0; i < numGainBlocks; ++i) {
1190  std::stringstream s;
1191  s << i;
1192  names[i] = "mosfet:gainscale_block_" + s.str();
1193  initialVal[i] = 0.0;
1194  finalVal[i] = 1.0;
1195  }
1196  names[numHomotopyContinuationRuns - 1] = "mosfet:nltermscale";
1197  initialVal[numHomotopyContinuationRuns - 1] = 0.0;
1198  finalVal[numHomotopyContinuationRuns - 1] = 1.0;
1199  // ***************************************************
1200  // ***************************************************
1201 
1202  // Ste up max/min bounds
1203  for (int i = 0; i < names.size(); ++i) {
1204  if (finalVal[i] > initialVal[i]) {
1205  minVal[i] = initialVal[i];
1206  maxVal[i] = finalVal[i];
1207  }
1208  else {
1209  minVal[i] = finalVal[i];
1210  maxVal[i] = initialVal[i];
1211  }
1212  }
1213 
1214  // Initialize loca parameter vector
1215  for (int i = 0; i < names.size(); ++i)
1216  locaPVec.addParameter(names[i], initialVal[i]);
1217 
1218  LOCA::Abstract::Iterator::IteratorStatus locaStatus;
1219 
1220  // Loop over the number of homotopy steps
1221  for (int hs = 0; hs < names.size(); ++hs) {
1222  for (int i = 0; i < names.size(); ++i) {
1223  if (i >= hs)
1224  locaPVec.setValue(names[i], initialVal[i]);
1225  else
1226  locaPVec.setValue(names[i], finalVal[i]);
1227  }
1228  groupPtr_->setParams(locaPVec);
1229  stepperList.set("Continuation Parameter", names[hs]);
1230  stepperList.set("Initial Value", initialVal[hs]);
1231  stepperList.set("Min Value", minVal[hs]);
1232  stepperList.set("Max Value", maxVal[hs]);
1233 
1234  // Initialize parameters in xyce
1235  groupPtr_->computeF();
1236 
1237  // Do the continuation run
1239  locaStatus = stepperPtr_->run();
1240 
1241  // Kick out if continuation failed
1242  if (locaStatus != LOCA::Abstract::Iterator::Finished)
1243  return (-1);
1244 
1245  // Increment Param Number Tracking
1246  isFirstContinuationParam_ = false;
1247  firstSolveComplete_ = true;
1248 
1249  // Copy out the solution and use it in the next run
1250  groupPtr_->copy(*(stepperPtr_->getSolutionGroup()));
1251  }
1252 
1253  // Return converged solver code
1254  return (paramsPtr->getStatusTestReturnCode());
1255 
1256  } // Test suite
1257  else if (solverType == 8)
1258  {
1259 
1260  // Get some initial objects
1261  Teuchos::RefCountPtr<Teuchos::ParameterList> locaList = paramsPtr->getLocaParams();
1262  Teuchos::ParameterList& stepperList = locaList->sublist("Stepper");
1263  LOCA::ParameterVector locaPVec;
1264 
1265  // Create storage for continuation objects
1266  int numHomotopyContinuationRuns = 1;
1267  std::vector<std::string> names(numHomotopyContinuationRuns);
1268  std::vector<double> initialVal(numHomotopyContinuationRuns);
1269  std::vector<double> finalVal(numHomotopyContinuationRuns);
1270  std::vector<double> minVal(numHomotopyContinuationRuns);
1271  std::vector<double> maxVal(numHomotopyContinuationRuns);
1272 
1273  // Set up continuation steps
1274  // ***************************************************
1275  // Changes vals below for continuation
1276  // ***************************************************
1277  names[0] = "mosfet:gainscale";
1278  //names[1] = "mosfet:nltermscale";
1279  //names[2] = "mosfet:sizescale";
1280  //names[2] = "mosfet:l";
1281  initialVal[0] = 0.0;
1282  //initialVal[1] = 0.0;
1283  //initialVal[2] = 0.0;
1284  finalVal[0] = 1.0;
1285  //finalVal[1] = 1.0;
1286  //finalVal[2] = 1.0;
1287  // ***************************************************
1288  std::string n1 = "mosfet:nltermscale";
1289  locaPVec.addParameter(n1, 0.0);
1290  //std::string n2 = "mosfet:sizescale";
1291  //locaPVec.addParameter(n2, 0.0);
1292  // ***************************************************
1293  // ***************************************************
1294 
1295  // Ste up max/min bounds
1296  for (int i = 0; i < names.size(); ++i) {
1297  if (finalVal[i] > initialVal[i]) {
1298  minVal[i] = initialVal[i];
1299  maxVal[i] = finalVal[i];
1300  }
1301  else {
1302  minVal[i] = finalVal[i];
1303  maxVal[i] = initialVal[i];
1304  }
1305  }
1306 
1307  // Initialize loca parameter vector
1308  for (int i = 0; i < names.size(); ++i)
1309  locaPVec.addParameter(names[i], initialVal[i]);
1310 
1311  LOCA::Abstract::Iterator::IteratorStatus locaStatus;
1312 
1313  LOCA::StatusTest::Wrapper test(paramsPtr->getStatusTests());
1314 
1315  // Loop over the number of homotopy steps
1316  for (int hs = 0; hs < names.size(); ++hs) {
1317  for (int i = 0; i < names.size(); ++i) {
1318  if (i >= hs)
1319  locaPVec.setValue(names[i], initialVal[i]);
1320  else
1321  locaPVec.setValue(names[i], finalVal[i]);
1322  }
1323  groupPtr_->setParams(locaPVec);
1324  stepperList.set("Continuation Parameter", names[hs]);
1325  stepperList.set("Initial Value", initialVal[hs]);
1326  stepperList.set("Min Value", minVal[hs]);
1327  stepperList.set("Max Value", maxVal[hs]);
1328 
1329  // Initialize parameters in xyce
1330  groupPtr_->computeF();
1331 
1332  // Do the continuation run
1334  locaStatus = stepperPtr_->run();
1335 
1336  // Kick out if continuation failed
1337  if (locaStatus != LOCA::Abstract::Iterator::Finished)
1338  return (-1);
1339 
1340  // Increment Param Number Tracking
1341  isFirstContinuationParam_ = false;
1342  firstSolveComplete_ = true;
1343 
1344  // Copy out the solution and use it in the next run
1345  groupPtr_->copy(*(stepperPtr_->getSolutionGroup()));
1346  }
1347 
1348  // Return converged solver code
1349  return (paramsPtr->getStatusTestReturnCode());
1350 
1351  } // Pseudo Transient
1352  else if (solverType == 9)
1353  {
1354  Teuchos::RefCountPtr<NOX::StatusTest::Combo> ctest =
1355  Teuchos::rcp(new NOX::StatusTest::Combo(NOX::StatusTest::Combo::OR));
1356 
1357  Teuchos::RefCountPtr<Teuchos::ParameterList> locaList =
1358  paramsPtr->getLocaParams();
1359  Teuchos::ParameterList& stepperList = locaList->sublist("Stepper");
1360  Teuchos::ParameterList& stepSizeList = locaList->sublist("Step Size");
1361  double initialStepSize =
1362  stepSizeList.get("Initial Step Size", 1.0e-3);
1363  double minStepSize = stepSizeList.get("Min Step Size", 1.0e-12);
1364  double maxStepSize = stepSizeList.get("Max Step Size", 1.0e4);
1365  Teuchos::RefCountPtr<Teuchos::ParameterList> noxList =
1366  paramsPtr->getNoxParams();
1367 
1368  // Create Pseudo Transient status tests.
1369  //paramsPtr->getStatusTests()
1370  Teuchos::RefCountPtr<NOX::StatusTest::MaxIters> mi =
1371  Teuchos::rcp(new NOX::StatusTest::MaxIters(stepperList.get("Max Steps", 200)));
1372  Teuchos::RefCountPtr<NOX::StatusTest::FiniteValue> fv =
1373  Teuchos::rcp(new NOX::StatusTest::FiniteValue);
1374  Teuchos::RefCountPtr<N_NLS_NOX::PseudoTransientTest> pt =
1375  Teuchos::rcp(new N_NLS_NOX::PseudoTransientTest(maxStepSize, 1.0e-8));
1376 
1377  ctest->addStatusTest(mi);
1378  ctest->addStatusTest(fv);
1379  ctest->addStatusTest(pt);
1380 
1381  // First solve - pseudo transient
1382 
1383  Teuchos::RefCountPtr<N_NLS_NOX::AugmentLinSys> als =
1385 
1386  solverPtr_ = Teuchos::rcp(new N_NLS_NOX::PseudoTransientBased(als,
1387  groupPtr_,
1388  ctest,
1389  noxList,
1390  initialStepSize,
1391  minStepSize,
1392  maxStepSize));
1393 
1394  NOX::StatusTest::StatusType status = solverPtr_->solve();
1395  firstSolveComplete_ = true;
1396 
1397  // RPP 3/7/2006: We don't care if pseudo transient solve fails the
1398  // solve() call above. This is just to get an inital guess for
1399  // the corrector step in the next solve. So we don't check the
1400  // status at this point.
1401 
1402  // Turn off pseudo transient in groups. (this is also done in the
1403  // pseudo transient solver, but just being safe - groups could be
1404  // different).
1405  Teuchos::RefCountPtr<N_NLS_NOX::AugmentLinSys> dummy;
1406  groupPtr_->setAugmentLinearSystem(false, dummy);
1407 
1408  // Second solve is the correct steady state solve
1409  solverPtr_ = NOX::Solver::buildSolver(groupPtr_,
1410  paramsPtr->getStatusTests(),
1411  paramsPtr->getNoxParams());
1412  status = solverPtr_->solve();
1413 
1414  // Send back the correct return code
1415  return (paramsPtr->getStatusTestReturnCode());
1416  } // continuation = 4 + power node
1417  else if (solverType == 10)
1418  {
1419 
1420  // Get some initial objects
1421  Teuchos::RefCountPtr<Teuchos::ParameterList> locaList = paramsPtr->getLocaParams();
1422  Teuchos::ParameterList& stepperList = locaList->sublist("Stepper");
1423  LOCA::ParameterVector locaPVec;
1424 
1425  // Create storage for continuation objects
1426  int numHomotopyContinuationRuns = 4;
1427  std::vector<std::string> names(numHomotopyContinuationRuns);
1428  std::vector<double> initialVal(numHomotopyContinuationRuns);
1429  std::vector<double> finalVal(numHomotopyContinuationRuns);
1430  std::vector<double> minVal(numHomotopyContinuationRuns);
1431  std::vector<double> maxVal(numHomotopyContinuationRuns);
1432 
1433  // Set up continuation steps
1434  // ***************************************************
1435  // Changes vals below for continuation
1436  // ***************************************************
1437  names[0] = stepperList.get("Power Node", "VA:V0");
1438  names[1] = "mosfet:gainscale";
1439  names[2] = "mosfet:nltermscale";
1440  names[3] = "mosfet:sizescale";
1441  initialVal[0] = 0.0;
1442  initialVal[1] = 0.0;
1443  initialVal[2] = 0.0;
1444  initialVal[3] = 0.0;
1445  finalVal[0] = 1.0;
1446  finalVal[1] = 1.0;
1447  finalVal[2] = 1.0;
1448  finalVal[3] = 1.0;
1449  // ***************************************************
1450  //std::string n1 = "mosfet:nltermscale";
1451  //locaPVec.addParameter(n1, 0.0);
1452  //std::string n2 = "mosfet:sizescale";
1453  //locaPVec.addParameter(n2, 0.0);
1454  // ***************************************************
1455  // ***************************************************
1456 
1457  // Ste up max/min bounds
1458  for (int i = 0; i < names.size(); ++i) {
1459  if (finalVal[i] > initialVal[i]) {
1460  minVal[i] = initialVal[i];
1461  maxVal[i] = finalVal[i];
1462  }
1463  else {
1464  minVal[i] = finalVal[i];
1465  maxVal[i] = initialVal[i];
1466  }
1467  }
1468 
1469  // Initialize loca parameter vector
1470  for (int i = 0; i < names.size(); ++i)
1471  locaPVec.addParameter(names[i], initialVal[i]);
1472 
1473  LOCA::Abstract::Iterator::IteratorStatus locaStatus;
1474 
1475  // Loop over the number of homotopy steps
1476  for (int hs = 0; hs < names.size(); ++hs) {
1477  for (int i = 0; i < names.size(); ++i) {
1478  if (i >= hs)
1479  locaPVec.setValue(names[i], initialVal[i]);
1480  else
1481  locaPVec.setValue(names[i], finalVal[i]);
1482  }
1483  groupPtr_->setParams(locaPVec);
1484  stepperList.set("Continuation Parameter", names[hs]);
1485  stepperList.set("Initial Value", initialVal[hs]);
1486  stepperList.set("Min Value", minVal[hs]);
1487  stepperList.set("Max Value", maxVal[hs]);
1488 
1489  // Initialize parameters in xyce
1490  groupPtr_->computeF();
1491 
1492  // Do the continuation run
1494  locaStatus = stepperPtr_->run();
1495 
1496  // Kick out if continuation failed
1497  if (locaStatus != LOCA::Abstract::Iterator::Finished)
1498  return (-1);
1499 
1500  firstSolveComplete_ = true;
1501 
1502  // Copy out the solution and use it in the next run
1503  groupPtr_->copy(*(stepperPtr_->getSolutionGroup()));
1504  }
1505 
1506  // Return converged solver code
1507  return (paramsPtr->getStatusTestReturnCode());
1508 
1509  }
1510  else if (solverType == 33) // artificial parameter
1511  {
1512 
1513 #ifdef Xyce_NOX_LOCA_ARTIFICIAL_HOMOTOPY_SUPPORT
1514  Teuchos::RefCountPtr<Teuchos::ParameterList> locaList = paramsPtr->getLocaParams();
1515  Teuchos::ParameterList& locaUtilsList = locaList->sublist("Utilities");
1516 
1517  Teuchos::RefCountPtr<LOCA::Homotopy::Group> hGrp =
1518  Teuchos::rcp(new LOCA::Homotopy::Group(*locaList, globalDataPtr_, groupPtr_, 1.0, 0.0));
1519 
1520  hGrp->computeF();
1521 
1522  locaList->sublist("Predictor").set("Secant", 0.999);
1523  locaList->sublist("Stepper").set("Max Value", 0.999);
1524 
1526 
1527  LOCA::Abstract::Iterator::IteratorStatus locaStatus = stepperPtr_->run();
1528  firstSolveComplete_ = true;
1529 
1530  Teuchos::RefCountPtr<LOCA::Homotopy::Group> hGrp2 =
1531  Teuchos::rcp(new LOCA::Homotopy::Group(*locaList, globalDataPtr_, groupPtr_, 0.1, 1.0));
1532 
1533  locaList->sublist("Predictor").set("Secant", 0.999);
1534  locaList->sublist("Stepper").set("Initial Value", 0.999);
1535  locaList->sublist("Stepper").set("Max Value", 1.0);
1536  locaList->sublist("Step Size").set("Method", "Constant");
1537  locaList->sublist("Step Size").set("Initial Step Size", 0.0001);
1538  locaList->sublist("Step Size").set("Min Step Size", 0.0001);
1539 
1541 
1542  locaStatus = stepperPtr_->run();
1543 
1544  // Return the solution status
1545  if (locaStatus != LOCA::Abstract::Iterator::Finished)
1546  return (-1);
1547  else
1548  return (paramsPtr->getStatusTestReturnCode());
1549 
1550 #else
1551  Xyce::Report::UserFatal0() << "Nonlinear Solver (NOX::Interface) Artificial parameter continuation requires "
1552  << "building xyce with the define: -DXyce_NOX_LOCA_ARTIFICIAL_HOMOTOPY_SUPPORT to "
1553  << "allow LOCA to augment the diagonal of Jacobian! Either rebuild Xyce or do not "
1554  << "run Xyce with \"continuation=33\"";
1555 #endif
1556  } // End of if (solverType == )
1557 
1558  } // try
1559  catch (const char* error_msg) {
1560  std::string nox_error = "NOX Error";
1561  std::string err_msg = std::string(error_msg);
1562  if (err_msg == nox_error) {
1563  const std::string message =
1564  "Caught a NOX Exception in N_NLS_NOX::Interface::solve()!";
1565  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, message);
1566  }
1567  else // Otherwise, rethrow...
1568  throw;
1569  }
1570 #ifndef Xyce_CHARON
1571  catch (const std::exception& e) {
1572  Xyce::dout() << e.what() << std::endl;
1573  const std::string message =
1574  "Caught std::exception in N_NLS_NOX::Interface::solve()!";
1575  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, message);
1576  }
1577  catch (...) {
1578  const std::string message =
1579  "Caught Unknown Exception in N_NLS_NOX::Interface::solve()!";
1580  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, message);
1581  }
1582 #endif
1583 
1584  // Should never get this far
1585  return -1;
1586 }
1587 
1588 
1589 //-----------------------------------------------------------------------------
1590 // Function : N_NLS_NOX::Interface::opStartCont0
1591 // Purpose :
1592 // Special Notes : returns true if DCOP restart is being used.
1593 //
1594 // The "found" variable indicates if any of the nodes specified
1595 // in the dcop start file were found in this circuit. If not,
1596 // then don't bother with this.
1597 //
1598 // Scope : public
1599 // Creator : Eric R. Keiter, SNL, Electrical and Microsystem Modeling
1600 // Creation Date : 09/15/07
1601 //-----------------------------------------------------------------------------
1603 {
1604  bool usedOP(false);
1605 
1606 #ifdef Xyce_DEBUG_OP_START
1607  Xyce::dout() << "NOX_Interface: Inside continuation=0 OP_START code (case 1)" << std::endl;
1608 #endif
1609  if (!DCOPused_)
1610  {
1611  int found = 0;
1612  std::string icType;
1613  Xyce::NodeNamePairMap & op = outMgrPtr_->getICData(found, icType);
1614  Xyce::NodeNamePairMap & allNodes = outMgrPtr_->getAllNodes( );
1615 #ifdef Xyce_PARALLEL_MPI
1616  N_PDS_Comm * pdsCommPtr = pdsMgrPtr_->getPDSComm();
1617 #endif
1618 
1619  if (found > 0 && icType == "DCOP_RESTART")
1620  {
1621  DCOPused_ = true;
1622  usedOP = true;
1623  Teuchos::RefCountPtr<N_NLS_NOX::AugmentLinSys> als =
1624 #ifdef Xyce_PARALLEL_MPI
1625  paramsPtr->createAugmentLinearSystem(lasSysPtr_, op, allNodes, pdsCommPtr);
1626 #else
1627  paramsPtr->createAugmentLinearSystem(lasSysPtr_, op, allNodes);
1628 #endif
1629  groupPtr_->setAugmentLinearSystem(true, als);
1630  NOX::StatusTest::StatusType status = solverPtr_->solve();
1631  // Create a new solver after performing the initial op_start solve.
1632  solverPtr_ = NOX::Solver::buildSolver(groupPtr_,
1633  paramsPtr->getStatusTests(),
1634  paramsPtr->getNoxParams());
1635  firstSolveComplete_ = true;
1636  groupPtr_->setAugmentLinearSystem(false, als);
1638 
1639 #ifdef Xyce_DEBUG_OP_START
1640  // DNS: Uncommenting this will set debug output of linear system for every step
1641 #ifdef Xyce_PARALLEL_MPI
1642  groupPtr_->setOutputLinear (&op, &allNodes, pdsCommPtr);
1643 #else
1644  groupPtr_->setOutputLinear (&op, &allNodes);
1645 #endif
1646 #endif // debug op start
1647 
1648  }
1649  }
1650  return usedOP;
1651 }
1652 
1653 //-----------------------------------------------------------------------------
1654 // Function : N_NLS_NOX::Interface::opStartCont1
1655 // Purpose :
1656 // Special Notes : returns true if DCOP restart is being used.
1657 //
1658 // The "found" variable indicates if any of the nodes specified
1659 // in the dcop start file were found in this circuit. If not,
1660 // then don't bother with this.
1661 //
1662 // Scope : public
1663 // Creator : Eric R. Keiter, SNL, Electrical and Microsystem Modeling
1664 // Creation Date : 09/15/07
1665 //-----------------------------------------------------------------------------
1667 {
1668  bool usedOP(false);
1669 
1670 #ifdef Xyce_DEBUG_OP_START
1671  Xyce::dout() << "NOX_Interface: Inside continuation=1 OP_START code (case 2)" << std::endl;
1672 #endif
1673  if (!DCOPused_)
1674  {
1675  int found = 0;
1676  std::string icType;
1677  Xyce::NodeNamePairMap & op = outMgrPtr_->getICData(found, icType);
1678  Xyce::NodeNamePairMap & allNodes = outMgrPtr_->getAllNodes( );
1679 #ifdef Xyce_PARALLEL_MPI
1680  N_PDS_Comm * pdsCommPtr = pdsMgrPtr_->getPDSComm();
1681 #endif
1682 
1683  if (found > 0 && icType == "DCOP_RESTART")
1684  {
1685  DCOPused_ = true;
1686  usedOP = true;
1687  // Set up nox nonlinear solver
1688  if (Teuchos::is_null(solverPtr_))
1689  {
1690  solverPtr_ = NOX::Solver::buildSolver(groupPtr_,
1691  paramsPtr->getStatusTests(),
1692  paramsPtr->getNoxParams());
1693  }
1694 
1695  Teuchos::RefCountPtr<N_NLS_NOX::AugmentLinSys> als =
1696 #ifdef Xyce_PARALLEL_MPI
1697  paramsPtr->createAugmentLinearSystem(lasSysPtr_, op, allNodes, pdsCommPtr);
1698 #else
1699  paramsPtr->createAugmentLinearSystem(lasSysPtr_, op, allNodes);
1700 #endif
1701  groupPtr_->setAugmentLinearSystem(true, als);
1702  NOX::StatusTest::StatusType status = solverPtr_->solve();
1703 
1704  firstSolveComplete_ = true;
1705  groupPtr_->setAugmentLinearSystem(false, als);
1707 
1708 #ifdef Xyce_DEBUG_OP_START
1709  // DNS: Uncommenting this will set debug output of linear system for every step
1710 #ifdef Xyce_PARALLEL_MPI
1711  groupPtr_->setOutputLinear (&op, &allNodes, pdsCommPtr);
1712 #else
1713  groupPtr_->setOutputLinear (&op, &allNodes);
1714 #endif
1715 #endif // debug op start
1716 
1717  }
1718  }
1719  return usedOP;
1720 }
1721 
1722 //-----------------------------------------------------------------------------
1723 // Function : N_NLS_NOX::Interface::icCont
1724 // Purpose :
1725 // Special Notes : returns true if IC is being used.
1726 //
1727 // The "found" variable indicates if any of the nodes specified
1728 // in the dcop start file were found in this circuit. If not,
1729 // then don't bother with this.
1730 //
1731 // Scope : public
1732 // Creator : Eric R. Keiter, SNL, Electrical and Microsystem Modeling
1733 // Creation Date : 09/15/07
1734 //-----------------------------------------------------------------------------
1736 {
1737  bool usedIC(false);
1738 
1739 #ifdef Xyce_DEBUG_IC
1740  Xyce::dout() << "NOX_Interface: Inside continuation=0 .IC code." << std::endl;
1741 #endif
1742  int found = 0;
1743  std::string icType;
1744  Xyce::NodeNamePairMap & op = outMgrPtr_->getICData(found, icType);
1745 
1746  usedIC = (icType=="IC" && found > 0);
1747  if (usedIC)
1748  {
1749  bool useGminStepping=false;
1750  Teuchos::RefCountPtr<N_NLS_NOX::AugmentLinSys> als =
1751  paramsPtr->createAugmentLinearSystem(lasSysPtr_, op, useGminStepping);
1752  groupPtr_->setAugmentLinearSystem(true, als);
1753  }
1754  return usedIC;
1755 }
1756 
1757 //-----------------------------------------------------------------------------
1758 // Function : N_NLS_NOX::Interface::icCont3
1759 // Purpose : IC with gmin stepping
1760 // Special Notes : returns true if IC is being used.
1761 //
1762 // The "found" variable indicates if any of the nodes specified
1763 // in the dcop start file were found in this circuit. If not,
1764 // then don't bother with this.
1765 //
1766 // Scope : public
1767 // Creator : Eric R. Keiter, SNL
1768 // Creation Date : 04/29/2012
1769 //-----------------------------------------------------------------------------
1771 {
1772  bool usedIC(false);
1773 
1774 #ifdef Xyce_DEBUG_IC
1775  Xyce::dout() << "NOX_Interface: Inside continuation=3 .IC code." << std::endl;
1776 #endif
1777  int found = 0;
1778  std::string icType = "";
1779  Xyce::NodeNamePairMap & op = outMgrPtr_->getICData(found, icType);
1780 
1781  usedIC = (icType=="IC" && found > 0);
1782  if (usedIC)
1783  {
1784  bool useGminStepping=true;
1785  Teuchos::RefCountPtr<N_NLS_NOX::AugmentLinSys> als =
1786  paramsPtr->createAugmentLinearSystem(lasSysPtr_, op, useGminStepping);
1787  groupPtr_->setAugmentLinearSystem(true, als);
1788  }
1789  return usedIC;
1790 }
1791 
1792 //-----------------------------------------------------------------------------
1793 // Function : N_NLS_NOX::Interface::nodesetCont0
1794 // Purpose :
1795 // Special Notes : returns true if is being used.
1796 // Scope : public
1797 // Creator : Eric R. Keiter, SNL, Electrical and Microsystem Modeling
1798 // Creation Date : 09/15/07
1799 //-----------------------------------------------------------------------------
1801 {
1802  bool usedNODESET(false);
1803 
1804 #ifdef Xyce_DEBUG_IC
1805  Xyce::dout() << "NOX_Interface: Inside continuation=0 .NODESET code (case 1)" << std::endl;
1806 #endif
1807  int found = 0;
1808  std::string icType;
1809  Xyce::NodeNamePairMap & op = outMgrPtr_->getICData(found, icType);
1810 #ifdef Xyce_PARALLEL_MPI
1811  N_PDS_Comm * pdsCommPtr = pdsMgrPtr_->getPDSComm();
1812 #endif
1813 
1814  usedNODESET = (icType=="NODESET" && found > 0);
1815  if (usedNODESET)
1816  {
1817  Teuchos::RefCountPtr<N_NLS_NOX::AugmentLinSys> als =
1818  paramsPtr->createAugmentLinearSystem(lasSysPtr_, op);
1819 
1820  groupPtr_->setAugmentLinearSystem(true, als);
1821  NOX::StatusTest::StatusType status = solverPtr_->solve();
1822 
1823  // Create a new solver after performing the initial nodeset solve.
1824  solverPtr_ = NOX::Solver::buildSolver(groupPtr_,
1825  paramsPtr->getStatusTests(),
1826  paramsPtr->getNoxParams());
1827  firstSolveComplete_ = true;
1828  groupPtr_->setAugmentLinearSystem(false, als);
1830  }
1831  return usedNODESET;
1832 }
1833 
1834 
1835 //-----------------------------------------------------------------------------
1836 // Function : N_NLS_NOX::Interface::nodesetCont1
1837 // Purpose :
1838 // Special Notes : returns true if .NODESET is being used.
1839 // Scope : public
1840 // Creator : Eric R. Keiter, SNL, Electrical and Microsystem Modeling
1841 // Creation Date : 09/15/07
1842 //-----------------------------------------------------------------------------
1844 {
1845  bool usedNODESET(false);
1846 
1847 #ifdef Xyce_DEBUG_IC
1848  Xyce::dout() << "NOX_Interface: Inside continuation=1 .NODESET code (case 2)" << std::endl;
1849 #endif
1850 
1851  int found = 0;
1852  std::string icType;
1853  Xyce::NodeNamePairMap & op = outMgrPtr_->getICData(found, icType);
1854 #ifdef Xyce_PARALLEL_MPI
1855  N_PDS_Comm * pdsCommPtr = pdsMgrPtr_->getPDSComm();
1856 #endif
1857 
1858  usedNODESET = (icType=="NODESET" && found > 0);
1859  if (usedNODESET)
1860  {
1861  // Set up nox nonlinear solver
1862  if (Teuchos::is_null(solverPtr_))
1863  {
1864  solverPtr_ = NOX::Solver::buildSolver(groupPtr_,
1865  paramsPtr->getStatusTests(),
1866  paramsPtr->getNoxParams());
1867  }
1868 
1869  Teuchos::RefCountPtr<N_NLS_NOX::AugmentLinSys> als =
1870  paramsPtr->createAugmentLinearSystem(lasSysPtr_, op);
1871 
1872  groupPtr_->setAugmentLinearSystem(true, als);
1873  NOX::StatusTest::StatusType status = solverPtr_->solve();
1874 
1875  firstSolveComplete_ = true;
1876  groupPtr_->setAugmentLinearSystem(false, als);
1878  }
1879  return usedNODESET;
1880 }
1881 
1882 //-----------------------------------------------------------------------------
1883 // Function : N_NLS_NOX::Interface::takeFirstSolveStep
1884 // Purpose : same as Interface::solve, except that solverPtr_->iterate is
1885 // called instead of solverPtr_->solve.
1886 // Special Notes :
1887 // Scope : public
1888 // Creator :
1889 // Creation Date :
1890 //-----------------------------------------------------------------------------
1892 {
1893  // For base object
1895 
1896  // Pick the parameter set to use.
1897  ParameterSet* paramsPtr;
1898  if ((usemode_) && (mode_ == TRANSIENT))
1899  paramsPtr = &transientParams_;
1900  else if ((usemode_) && (mode_ == HB_MODE))
1901  paramsPtr = &hbParams_;
1902  else
1903  paramsPtr = &dcParams_;
1904 
1905  // set the xyce return codes:
1906  paramsPtr->setStatusTestReturnCodes(retCodes_);
1907 
1908  if (Teuchos::is_null(globalDataPtr_))
1909  globalDataPtr_ = LOCA::createGlobalData(paramsPtr->getAllParams());
1910 
1911  // Set up the shared system (we have to redo this every time because
1912  // the object pointed to by nextSolVectorPtrPtr may have changed.
1913  delete sharedSystemPtr_;
1914  sharedSystemPtr_ = new SharedSystem(**nextSolVectorPtrPtr_,
1915  *rhsVectorPtr_,
1918  *gradVectorPtr_,
1919  *lasSysPtr_,
1920  *this);
1921 
1922  // Reset up the corresponding group as well
1923  //delete groupPtr_;
1924  if (nlsTmpPtr==0)
1925  {
1926  if (Teuchos::is_null(groupPtr_))
1927  {
1928  Xyce::dout() << "takeFirstSolveStep: allocating a new group!" << std::endl;
1929  groupPtr_ = Teuchos::rcp(new N_NLS_LOCA::Group(globalDataPtr_,
1930  *sharedSystemPtr_,
1931  getLoader(),
1932  *outMgrPtr_,
1933  *anaIntPtr_));
1934  }
1935  else
1936  {
1937  Xyce::dout() << "takeFirstSolveStep: using the old group!" << std::endl;
1939  groupPtr_->setX(tmpVec);
1940  }
1941  }
1942  else
1943  {
1944  Xyce::dout() << "takeFirstSolveStep: copying over the passed group!" << std::endl;
1945  copiedGroupFlag_ = true;
1946  Interface * nlsOtherPtr = dynamic_cast<Interface*>(nlsTmpPtr);
1947  groupPtr_ = nlsOtherPtr->getSolutionGroup();
1948  }
1949 
1950  // Set up solver
1951  if (Teuchos::is_null(solverPtr_))
1952  solverPtr_ = NOX::Solver::buildSolver(groupPtr_,
1953  paramsPtr->getStatusTests(),
1954  paramsPtr->getNoxParams());
1955  else
1956  solverPtr_->reset(groupPtr_->getX());
1957 
1958  // Solve
1959  NOX::StatusTest::StatusType status = solverPtr_->step();
1960 
1961  // Return the solution status
1962  return (status == NOX::StatusTest::Converged) ? 1 : -1;
1963 }
1964 
1965 //-----------------------------------------------------------------------------
1966 // Function : N_NLS_NOX::Interface::takeOneSolveStep
1967 // Purpose : same as Interface::takeFirstSolveStep, except that none of the
1968 // set up stuff (like allocating the solverPtr) is done here.
1969 // Special Notes :
1970 // Scope : public
1971 // Creator :
1972 // Creation Date :
1973 //-----------------------------------------------------------------------------
1975 {
1976  // Solve
1977  NOX::StatusTest::StatusType status = solverPtr_->step();
1978 
1979  // Return the solution status
1980  return (status == NOX::StatusTest::Converged) ? 1 : -1;
1981 }
1982 
1983 //-----------------------------------------------------------------------------
1984 // Function : N_NLS_NOX::Interface::getNumIterations
1985 // Purpose :
1986 // Special Notes :
1987 // Return Type : Integer (current number of nonlinear iterations)
1988 // Scope : public
1989 // Creator :
1990 // Creation Date :
1991 //-----------------------------------------------------------------------------
1993 {
1994  // Pick the parameter set to use.
1995  const ParameterSet* paramsPtr;
1996  if ((usemode_) && (mode_ == TRANSIENT))
1997  paramsPtr = &transientParams_;
1998  else if ((usemode_) && (mode_ == HB_MODE))
1999  paramsPtr = &hbParams_;
2000  else
2001  paramsPtr = &dcParams_;
2002 
2003  int solverType = paramsPtr->getNoxSolverType();
2004 
2005  if ((!Teuchos::is_null(solverPtr_)) && (solverType == 0))
2006  return solverPtr_->getNumIterations();
2007  else if ((!Teuchos::is_null(solverPtr_)) && (solverType == 1))
2008  return solverPtr_->getNumIterations();
2009  else if ((!Teuchos::is_null(solverPtr_)) && (solverType == 9))
2010  return solverPtr_->getNumIterations();
2011  else if ((!Teuchos::is_null(stepperPtr_)) && (solverType != 0))
2012  {
2013  return stepperPtr_->getSolver()->getNumIterations();
2014  }
2015 
2016  // Sometimes this is called before solve() itself, in which calse
2017  // the solverPtr_ has not yet been initialized, so we just return 0.
2018  return 0;
2019 }
2020 
2021 //-----------------------------------------------------------------------------
2022 // Function : N_NLS_NOX::Interface::getMaxNormF() const
2023 // Purpose :
2024 // Special Notes :
2025 // Return Type : double (norm of F)
2026 // Scope : public
2027 // Creator :
2028 // Creation Date :
2029 //-----------------------------------------------------------------------------
2031 {
2032  // Pick the parameter set to use.
2033  const ParameterSet* paramsPtr;
2034  if ((usemode_) && (mode_ == TRANSIENT))
2035  {
2036  paramsPtr = &transientParams_;
2037  }
2038  else if ((usemode_) && (mode_ == HB_MODE))
2039  {
2040  paramsPtr = &hbParams_;
2041  }
2042  else
2043  {
2044  paramsPtr = &dcParams_;
2045  }
2046 
2047  double maxNormF = paramsPtr->getMaxNormF();
2048  return maxNormF;
2049 }
2050 
2051 
2052 //-----------------------------------------------------------------------------
2053 // Function : N_NLS_NOX::Interface::getMaxNormFindex() const
2054 // Purpose :
2055 // Special Notes :
2056 // Return Type : int (vector index norm of F)
2057 // Scope : public
2058 // Creator :
2059 // Creation Date :
2060 //-----------------------------------------------------------------------------
2062 {
2063  // Pick the parameter set to use.
2064  const ParameterSet* paramsPtr;
2065  if ((usemode_) && (mode_ == TRANSIENT))
2066  {
2067  paramsPtr = &transientParams_;
2068  }
2069  else if ((usemode_) && (mode_ == HB_MODE))
2070  {
2071  paramsPtr = &hbParams_;
2072  }
2073  else
2074  {
2075  paramsPtr = &dcParams_;
2076  }
2077 
2078  int maxNormFindex = paramsPtr->getMaxNormFindex();
2079  return maxNormFindex;
2080 }
2081 
2082 //-----------------------------------------------------------------------------
2083 // Function : N_NLS_NOX::Interface::getDebugLevel
2084 // Purpose :
2085 // Special Notes :
2086 // Scope : public
2087 // Creator : Eric Keiter, SNL
2088 // Creation Date : 9/17/2007
2089 //-----------------------------------------------------------------------------
2091 {
2092  const ParameterSet* paramsPtr;
2093  if ((usemode_) && (mode_ == TRANSIENT))
2094  {
2095  paramsPtr = &transientParams_;
2096  }
2097  else if ((usemode_) && (mode_ == HB_MODE))
2098  {
2099  paramsPtr = &hbParams_;
2100  }
2101  else
2102  {
2103  paramsPtr = &dcParams_;
2104  }
2105 
2106  return (paramsPtr->getDebugLevel());
2107 }
2108 
2109 //-----------------------------------------------------------------------------
2110 // Function : N_NLS_NOX::Interface::getScreenOutputFlag
2111 // Purpose :
2112 // Special Notes :
2113 // Scope : public
2114 // Creator : Eric Keiter, SNL
2115 // Creation Date : 9/17/2007
2116 //-----------------------------------------------------------------------------
2118 {
2119  const ParameterSet* paramsPtr;
2120  if ((usemode_) && (mode_ == TRANSIENT))
2121  {
2122  paramsPtr = &transientParams_;
2123  }
2124  else if ((usemode_) && (mode_ == HB_MODE))
2125  {
2126  paramsPtr = &hbParams_;
2127  }
2128  else
2129  {
2130  paramsPtr = &dcParams_;
2131  }
2132 
2133  return (paramsPtr->getScreenOutputFlag());
2134 }
2135 
2136 //-----------------------------------------------------------------------------
2137 // Function : N_NLS_NOX::Interface::getDebugMinTime
2138 // Purpose :
2139 // Special Notes :
2140 // Scope : public
2141 // Creator : Eric Keiter, SNL
2142 // Creation Date : 9/17/2007
2143 //-----------------------------------------------------------------------------
2145 {
2146  const ParameterSet* paramsPtr;
2147  if ((usemode_) && (mode_ == TRANSIENT))
2148  {
2149  paramsPtr = &transientParams_;
2150  }
2151  else if ((usemode_) && (mode_ == HB_MODE))
2152  {
2153  paramsPtr = &hbParams_;
2154  }
2155  else
2156  {
2157  paramsPtr = &dcParams_;
2158  }
2159 
2160  return (paramsPtr->getDebugMinTime());
2161 }
2162 
2163 //-----------------------------------------------------------------------------
2164 // Function : N_NLS_NOX::Interface::getDebugMaxTime
2165 // Purpose :
2166 // Special Notes :
2167 // Scope : public
2168 // Creator : Eric Keiter, SNL
2169 // Creation Date : 9/17/2007
2170 //-----------------------------------------------------------------------------
2172 {
2173  const ParameterSet* paramsPtr;
2174  if ((usemode_) && (mode_ == TRANSIENT))
2175  {
2176  paramsPtr = &transientParams_;
2177  }
2178  else if ((usemode_) && (mode_ == HB_MODE))
2179  {
2180  paramsPtr = &hbParams_;
2181  }
2182  else
2183  {
2184  paramsPtr = &dcParams_;
2185  }
2186 
2187  return (paramsPtr->getDebugMaxTime());
2188 }
2189 
2190 //-----------------------------------------------------------------------------
2191 // Function : N_NLS_NOX::Interface::getDebugMinTimeStep
2192 // Purpose :
2193 // Special Notes :
2194 // Scope : public
2195 // Creator : Eric Keiter, SNL
2196 // Creation Date : 9/17/2007
2197 //-----------------------------------------------------------------------------
2199 {
2200  const ParameterSet* paramsPtr;
2201  if ((usemode_) && (mode_ == TRANSIENT))
2202  {
2203  paramsPtr = &transientParams_;
2204  }
2205  else if ((usemode_) && (mode_ == HB_MODE))
2206  {
2207  paramsPtr = &hbParams_;
2208  }
2209  else
2210  {
2211  paramsPtr = &dcParams_;
2212  }
2213 
2214  return (paramsPtr->getDebugMinTimeStep());
2215 }
2216 
2217 //-----------------------------------------------------------------------------
2218 // Function : N_NLS_NOX::Interface::getDebugMaxTimeStep
2219 // Purpose :
2220 // Special Notes :
2221 // Scope : public
2222 // Creator : Eric Keiter, SNL
2223 // Creation Date : 9/17/2007
2224 //-----------------------------------------------------------------------------
2226 {
2227  const ParameterSet* paramsPtr;
2228  if ((usemode_) && (mode_ == TRANSIENT))
2229  {
2230  paramsPtr = &transientParams_;
2231  }
2232  else if ((usemode_) && (mode_ == HB_MODE))
2233  {
2234  paramsPtr = &hbParams_;
2235  }
2236  else
2237  {
2238  paramsPtr = &dcParams_;
2239  }
2240 
2241  return (paramsPtr->getDebugMaxTimeStep());
2242 }
2243 
2244 //-----------------------------------------------------------------------------
2245 // Function : N_NLS_NOX::Interface::getMMFormat
2246 // Purpose :
2247 // Special Notes :
2248 // Scope : public
2249 // Creator : Eric Keiter, SNL
2250 // Creation Date : 3/2/2011
2251 //-----------------------------------------------------------------------------
2253 {
2254  return false;
2255 }
2256 
2257 //-----------------------------------------------------------------------------
2258 // Function : N_NLS_NOX::Interface::isFirstContinuationParam
2259 // Purpose :
2260 // Special Notes :
2261 // Scope : public
2262 // Creator :
2263 // Creation Date :
2264 //-----------------------------------------------------------------------------
2266 {
2268 }
2269 
2270 //-----------------------------------------------------------------------------
2271 // Function : N_NLS_NOX::Interface::isFirstSolveComplete
2272 // Purpose :
2273 // Special Notes :
2274 // Scope : public
2275 // Creator :
2276 // Creation Date :
2277 //-----------------------------------------------------------------------------
2279 {
2280  return firstSolveComplete_;
2281 }
2282 
2283 //-----------------------------------------------------------------------------
2284 // Function : N_NLS_NOX::Interface::getContinuationStep
2285 // Purpose :
2286 // Special Notes :
2287 // Scope : public
2288 // Creator :
2289 // Creation Date :
2290 //-----------------------------------------------------------------------------
2292 {
2293  if (!Teuchos::is_null(stepperPtr_))
2294  {
2295  return stepperPtr_->getStepNumber();
2296  }
2297  return 0;
2298 }
2299 
2300 //-----------------------------------------------------------------------------
2301 // Function : N_NLS_NOX::Interface::getContinuationStep
2302 // Purpose :
2303 // Special Notes :
2304 // Scope : public
2305 // Creator :
2306 // Creation Date :
2307 //-----------------------------------------------------------------------------
2309 {
2310  return iParam_;
2311 }
2312 
2313 //-----------------------------------------------------------------------------
2314 // Function : N_NLS_NOX::Interface::setAnalysisMode
2315 //
2316 // Purpose : Specify the analysis mode to be used by the nonlinear
2317 // solver in the next call to solve(). This *may* affect
2318 // the parameters used by the solver.
2319 //
2320 // See Also : setOptions, setTranOptions
2321 //
2322 // - Input Arguments -
2323 //
2324 // mode : Mode to be used in the next nonlinear solve.
2325 // Special Notes :
2326 // Scope : public
2327 // Creator :
2328 // Creation Date :
2329 //-----------------------------------------------------------------------------
2331 {
2332  mode_ = mode;
2333 }
2334 
2335 //-----------------------------------------------------------------------------
2336 // Function : N_NLS_NOX::Interface::resetAll
2337 // Purpose : This is used when Xyce is doing a STEP loop, and
2338 // needs to act like it is at the beginning of a transient
2339 // simulation again, for the next parameter in the STEP loop.
2340 // Special Notes :
2341 // Scope : public
2342 // Creator : Eric Keiter
2343 // Creation Date :
2344 //-----------------------------------------------------------------------------
2346 {
2347  setAnalysisMode(mode);
2348 }
2349 
2350 //-----------------------------------------------------------------------------
2351 // Function : N_NLS_NOX::Interface::copySolnVectors()
2352 //
2353 // Purpose : To be called at the beginning of each nonlinear
2354 // iteration. It equates the tmp and next vectors as
2355 // well as some special hidden vectors.
2356 //
2357 // See Also : setX0_
2358 // Special Notes :
2359 // Scope : public
2360 // Creator :
2361 // Creation Date :
2362 //-----------------------------------------------------------------------------
2364 {
2366  return true;
2367 }
2368 
2369 //-----------------------------------------------------------------------------
2370 // Function : N_NLS_NOX::Interface::getMatrixFreeFlag()
2371 //
2372 // Purpose :
2373 // See Also :
2374 // Special Notes :
2375 // Scope : public
2376 // Creator : Todd Coffey, Ting Mei
2377 // Creation Date : 07/29/08
2378 //-----------------------------------------------------------------------------
2380 {
2382 }
2383 
2384 //-----------------------------------------------------------------------------
2385 // Function : N_NLS_NOX::Interface::computeF()
2386 // Purpose :
2387 // Special Notes :
2388 // Scope : public
2389 // Creator :
2390 // Creation Date :
2391 //-----------------------------------------------------------------------------
2393 {
2394  return N_NLS_NonLinearSolver::rhs_();
2395 }
2396 
2397 //-----------------------------------------------------------------------------
2398 // Function : N_NLS_NOX::Interface::computeNewton
2399 // Purpose : Set up the parameters for the linear solver and then
2400 // call newton_()
2401 // Special Notes :
2402 // Scope : public
2403 // Creator :
2404 // Creation Date :
2405 //-----------------------------------------------------------------------------
2406 bool Interface::computeNewton(Teuchos::ParameterList& params)
2407 {
2408  if (mode_ == DC_OP && setAZ_Tol_DC)
2409  {
2410  lasSolverPtr_->setTolerance(params.get("Tolerance", 1.0e-12));
2411  }
2412  else if (mode_ == TRANSIENT && setAZ_Tol_Transient)
2413  {
2414  lasSolverPtr_->setTolerance(params.get("Tolerance", 1.0e-12));
2415  }
2416 
2418 }
2419 
2420 //-----------------------------------------------------------------------------
2421 // Function : N_NLS_NOX::Interface::computeJacobian()
2422 // Purpose :
2423 // Special Notes :
2424 // Scope : public
2425 // Creator :
2426 // Creation Date :
2427 //-----------------------------------------------------------------------------
2429 {
2430  bool status = N_NLS_NonLinearSolver::jacobian_();
2431  return status;
2432 }
2433 
2434 //-----------------------------------------------------------------------------
2435 // Function : N_NLS_NOX::Interface::applyJacobian(const N_LAS_Vector& input, N_LAS_Vector& result)
2436 // Purpose :
2437 // Special Notes :
2438 // Scope : public
2439 // Creator :
2440 // Creation Date :
2441 //-----------------------------------------------------------------------------
2442 bool Interface::applyJacobian(const N_LAS_Vector& input, N_LAS_Vector& result)
2443 {
2444  return N_NLS_NonLinearSolver::applyJacobian(input,result);
2445 }
2446 
2447 //-----------------------------------------------------------------------------
2448 // Function : N_NLS_NOX::Interface::computeGradient()
2449 // Purpose :
2450 // Special Notes :
2451 // Scope : public
2452 // Creator :
2453 // Creation Date :
2454 //-----------------------------------------------------------------------------
2456 {
2457  bool status = N_NLS_NonLinearSolver::gradient_();
2458  return status;
2459 }
2460 
2461 //-----------------------------------------------------------------------------
2462 // Function : N_NLS_NOX::Interface::getSolutionGroup
2463 // Purpose :
2464 // Special Notes :
2465 // Scope : public
2466 // Creator :
2467 // Creation Date :
2468 //-----------------------------------------------------------------------------
2469 Teuchos::RefCountPtr<N_NLS_LOCA::Group> Interface::getSolutionGroup ()
2470 {
2471  return groupPtr_;
2472 }
2473 
2474 //-----------------------------------------------------------------------------
2475 // Function : N_NLS_NOX::Interface::getLoader
2476 //
2477 // Purpose : LOCA needs access to loader to set parameters
2478 //
2479 // Special Notes :
2480 // Scope : public
2481 // Creator :
2482 // Creation Date :
2483 //-----------------------------------------------------------------------------
2484 N_LOA_Loader& Interface::getLoader() const
2485 {
2487 }
2488 
2489 //-----------------------------------------------------------------------------
2490 // Function : N_NLS_NOX::Interface::resetStepper
2491 // Purpose :
2492 // Special Notes :
2493 // Scope : public
2494 // Creator :
2495 // Creation Date :
2496 //-----------------------------------------------------------------------------
2497 void Interface::resetStepper(const Teuchos::RefCountPtr<LOCA::GlobalData>& gd,
2498  const Teuchos::RefCountPtr<LOCA::MultiContinuation::AbstractGroup>& initialGuess,
2499  const Teuchos::RefCountPtr<NOX::StatusTest::Generic>& test,
2500  const Teuchos::RefCountPtr<Teuchos::ParameterList>& p)
2501 {
2502  stepperPtr_ =
2503  Teuchos::rcp(new LOCA::Stepper(gd, initialGuess, test, p));
2504 }
2505 
2506 //-----------------------------------------------------------------------------
2507 // Function : N_NLS_NOX::Interface::getLocaFlag
2508 // Purpose :
2509 // Special Notes :
2510 // Scope : public
2511 // Creator :
2512 // Creation Date :
2513 //-----------------------------------------------------------------------------
2515 {
2516  // Pick the parameter set to use.
2517  const ParameterSet* paramsPtr;
2518  bool retCode;
2519 
2520  if ((usemode_) && (mode_ == TRANSIENT))
2521  {
2522  firstSolveComplete_ = false;
2523  paramsPtr = &transientParams_;
2524  int solverType = paramsPtr->getNoxSolverType();
2525  retCode = false;
2526  if (solverType != 0) retCode = true;
2527  }
2528  else
2529  {
2530  if ((usemode_) && (mode_ ==HB_MODE))
2531  {
2532  paramsPtr = &hbParams_;
2533  }
2534  else
2535  {
2536  paramsPtr = &dcParams_;
2537  }
2538 
2539  if (DCOPused_)
2540  {
2541  retCode = firstSolveComplete_;
2542  }
2543  else
2544  {
2545  int solverType = paramsPtr->getNoxSolverType();
2546  retCode=false;
2547  if (solverType != 0) retCode = true;
2548  }
2549  }
2550 
2551  return retCode;
2552 }
2553