Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_NLS_NOX_ParameterSet.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_ParameterSet.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.104 $
40 //
41 // Revision Date : $Date: 2014/08/07 23:08:54 $
42 //
43 // Current Owner : $Author: dgbaur $
44 //-------------------------------------------------------------------------
45 
46 #include <Xyce_config.h>
47 
48 
49 
50 // ---------- Standard Includes ----------
51 
52 #include <N_UTL_Misc.h>
53 
54 #include<list>
55 
56 // ---------- Xyce Includes ----------
57 
58 #ifndef HAVE_CONFIG_H
59 #define HAVE_CONFIG_H
60 #endif
61 
62 #include <N_NLS_fwd.h>
63 #include "N_NLS_NOX_Interface.h"
64 #include "N_NLS_NOX_XyceTests.h"
65 #include "N_NLS_NOX_FastTests.h"
71 #include "N_ERH_ErrorMgr.h"
72 #include "N_ERH_Message.h"
73 #include "N_UTL_Param.h"
74 #include "N_PDS_fwd.h"
75 #include "N_UTL_OptionBlock.h"
76 #include "LOCA.H"
77 #include "N_NLS_ReturnCodes.h"
78 #include "N_LOA_Loader.h"
79 
80 // The following are needed to build AugmentLinSys strategies
87 #include "N_LAS_Builder.h"
88 #include "N_LAS_System.h"
89 #include "N_LAS_QueryUtil.h"
90 #include "Epetra_MapColoring.h"
91 
92 namespace N_NLS_NOX {
93 
94 //-----------------------------------------------------------------------------
95 // Function : ParameterSet::ParameterSet
96 // Purpose : constructor
97 // Special Notes :
98 // Scope : public
99 // Creator :
100 // Creation Date :
101 //-----------------------------------------------------------------------------
103  allParams_(Teuchos::rcp(new Teuchos::ParameterList)),
104  noxParams_(allParams_->sublist("NOX")),
105  locaParams_(allParams_->sublist("LOCA")),
106  debugParams_(allParams_->sublist("DEBUG")),
107  comboPtr_(Teuchos::rcp(new NOX::StatusTest::Combo(NOX::StatusTest::Combo::OR))),
108  isParamsSet_(false),
109  isStatusTestsSet_(false),
110  continuationSpecified_(false),
111  mode_(mode),
112  noxSolver(0),
113  voltageListType_(VLT_None),
114  gstepping_minimum_conductance_(0.0),
115  savedLocaOptions_(false),
116  debugLevel_(0),
117  debugMinTimeStep_(0),
118  debugMaxTimeStep_(N_UTL_MachineDependentParams::IntMax()),
119  debugMinTime_(0.0),
120  debugMaxTime_(N_UTL_MachineDependentParams::DoubleMax()),
121  screenOutputFlag_(false),
122  voltageScaleFactor_(1.0)
123 {
124  // Add the main status test to the list of tests to delete in dtor
125  tests_.push_back(comboPtr_);
126 
127  // Default printing options
128 #ifdef Xyce_VERBOSE_NOX
129  noxParams_.sublist("Printing")
130  .set("Output Information",
131  NOX::Utils::Error +
132  NOX::Utils::Warning +
133  NOX::Utils::OuterIteration +
134  NOX::Utils::OuterIterationStatusTest +
135  NOX::Utils::InnerIteration +
136  NOX::Utils::Details +
137  NOX::Utils::StepperIteration +
138  NOX::Utils::StepperDetails +
139  NOX::Utils::Parameters
140  );
141 
142 #else
143 #ifdef Xyce_VERBOSE_NONLINEAR
144  noxParams_.sublist("Printing")
145  .set("Output Information",
146  NOX::Utils::Error+
147  NOX::Utils::Warning +
148  NOX::Utils::OuterIteration +
149  NOX::Utils::StepperIteration
150  );
151 #else
152  noxParams_.sublist("Printing")
153  .set("Output Information", NOX::Utils::Error);
154 #endif
155 #endif
156 
157  // Defaults that are mode dependent
158  switch (mode_)
159  {
161  // These values correspond to N_NLS_DampedNewton.C; see the constructor
162  statusTestParams_.set("ABSTOL", 1.0e-6);
163  statusTestParams_.set("RELTOL", 1.0e-2);
164  statusTestParams_.set("DELTAXTOL", 0.33);
165  statusTestParams_.set("RHSTOL", 1.0e-2);
166  statusTestParams_.set("MAXSTEP", 20);
167  noxParams_.set("Nonlinear Solver", "Line Search Based");
168  noxParams_.sublist("Line Search").set("Method", "Full Step");
169  //noxParams_.sublist("Line Search").set("Method", "Polynomial");
170  //noxParams_.sublist("Line Search").sublist("Polynomial")
171  // .set("Max Iters", 2);
172  //noxParams_.sublist("Line Search").sublist("Polynomial")
173  // .set("Interpolation Type", "Quadratic");
174  //noxParams_.sublist("Direction").sublist("Newton")
175  //.sublist("Linear Solver").set("Tolerance", 1.0e-9);
176  break;
178  // These values correspond to N_NLS_DampedNewton.C; see the constructor
179  statusTestParams_.set("ABSTOL", 1.0e-9);
180  statusTestParams_.set("RELTOL", 1.0e-3);
181  statusTestParams_.set("DELTAXTOL", 1.0);
182  statusTestParams_.set("RHSTOL", 1.0e-4);
183  statusTestParams_.set("MAXSTEP", 200);
184  noxParams_.set("Nonlinear Solver", "Line Search Based");
185  noxParams_.sublist("Line Search").set("Method", "Full Step");
186  //noxParams_.sublist("Line Search").set("Method", "Polynomial");
187  //noxParams_.sublist("Line Search").sublist("Polynomial")
188  // .set("Max Iters", 2);
189  //noxParams_.sublist("Line Search").sublist("Polynomial")
190  // .set("Interpolation Type", "Quadratic");
191  //noxParams_.sublist("Direction").sublist("Newton")
192  //.sublist("Linear Solver").set("Tolerance", 1.0e-9);
193  break;
194  default:
195  statusTestParams_.set("ABSTOL", 1.0e-12);
196  statusTestParams_.set("RELTOL", 1.0e-3);
197  statusTestParams_.set("DELTAXTOL", 1.0);
198  statusTestParams_.set("RHSTOL", 1.0e-6);
199  statusTestParams_.set("MAXSTEP", 200);
200  noxParams_.set("Nonlinear Solver", "Line Search Based");
201  noxParams_.sublist("Line Search").set("Method", "Full Step");
202  noxParams_.sublist("Direction").sublist("Newton")
203  .sublist("Linear Solver").set("Tolerance", 1.0e-12);
204  break;
205  }
206 
207  // Parameters that should always be set
208  noxParams_.sublist("Line Search").sublist("Polynomial")
209  .set("Recovery Step Type", "Last Computed Step");
210 
211 
212  // Set default loca options in case this is a loca run.
213  Teuchos::ParameterList& stepperList = locaParams_.sublist("Stepper");
214  Teuchos::ParameterList& predictorList = locaParams_.sublist("Predictor");
215  Teuchos::ParameterList& stepSizeList = locaParams_.sublist("Step Size");
216 
217  stepperList.set("Continuation Method", "Natural");
218  stepperList.set("Skip df/dp", true);
219  predictorList.set("Method", "Tangent");
220 }
221 
222 //-----------------------------------------------------------------------------
223 // Function : ParameterSet::~ParameterSet
224 // Purpose :
225 // Special Notes :
226 // Scope : public
227 // Creator :
228 // Creation Date :
229 //-----------------------------------------------------------------------------
231 {
232 }
233 
234 //-----------------------------------------------------------------------------
235 // Function : ParameterSet::setOptions
236 // Purpose :
237 // Special Notes :
238 // Scope : public
239 // Creator :
240 // Creation Date :
241 //-----------------------------------------------------------------------------
242 bool ParameterSet::setOptions(const N_UTL_OptionBlock& OB)
243 {
244  // Parse the option block
245  bool parseok = parseOptionBlock_(OB);
246  if (!parseok)
247  {
248  return false;
249  }
250 
251  isParamsSet_ = true;
252  return true;
253 }
254 
255 //-----------------------------------------------------------------------------
256 // Function : ParameterSet::setOutputOptions
257 // Purpose : Set output for parallel runs
258 // Special Notes :
259 // Scope : public
260 // Creator :
261 // Creation Date :
262 //-----------------------------------------------------------------------------
263 bool ParameterSet::setOutputOptions(int myPID, int outputProcess)
264 {
265  noxParams_.sublist("Printing").set("MyPID", myPID);
266  noxParams_.sublist("Printing").set("Output Processor",
267  outputProcess);
268  locaParams_.sublist("Utilities").set("MyPID", myPID);
269  locaParams_.sublist("Utilities").set("Output Processor",
270  outputProcess);
271  return true;
272 }
273 
274 //-----------------------------------------------------------------------------
275 // Function : ParameterSet::createStatusTests
276 // Purpose :
277 // Special Notes :
278 // Scope : public
279 // Creator :
280 // Creation Date :
281 //-----------------------------------------------------------------------------
282 bool ParameterSet::createStatusTests(N_LAS_Vector** currSolVectorPtrPtr,
283  N_LOA_Loader& loader, std::vector<char> & varTypeVec
284 #ifdef Xyce_NLS_MASKED_WRMS_NORMS
285  , bool nonTrivialDeviceMaskFlag, N_LAS_Vector * maskVectorPtr)
286 #else
287  )
288 #endif
289 
290 {
291  /*
292  // Test 1 - Make sure the residual isn't too small, hardwired tolerances
293 
294  // Test 1a - Max Norm F is less than machine precision
295  NOX::StatusTest::NormF* test1a =
296  new NOX::StatusTest::NormF(N_UTL_MachineDependentParams::MachineEpsilon(),
297  NOX::Abstract::Vector::MaxNorm,
298  NOX::StatusTest::NormF::Unscaled);
299  tests_.push_back(test1a);
300 
301  // Test 1b - Max Norm F is less than requested tolerance
302  NOX::StatusTest::NormF* test1b =
303  new NOX::StatusTest::NormF(statusTestParams_.get("RHSTOL", 1.0e-6),
304  NOX::Abstract::Vector::MaxNorm,
305  NOX::StatusTest::NormF::Unscaled);
306  tests_.push_back(test1b);
307 
308  NOX::StatusTest::Combo* test1 =
309  new NOX::StatusTest::Combo(NOX::StatusTest::Combo::AND, *test1a, *test1b);
310  tests_.push_back(test1);
311  comboPtr_->addStatusTest(*test1);
312 
313 
314  // Test 2 - Normal convergence based on rhs residual (2a) and
315  // update norm (2b).
316 
317  // Test 2a - Max Residual
318  NOX::StatusTest::NormF* test2a =
319  new NOX::StatusTest::NormF(statusTestParams_.get("RHSTOL", 1.0e-6),
320  NOX::Abstract::Vector::MaxNorm,
321  NOX::StatusTest::NormF::Unscaled);
322  tests_.push_back(test2a);
323 
324  // Test 2b - weighted update
325  bool isTransient = false;
326  if (mode_ == TRANSIENT)
327  isTransient = true;
328  */
329  /*
330  N_NLS_NOX::WeightedUpdateTest* test2b =
331  new N_NLS_NOX::WeightedUpdateTest(currSolVectorPtrPtr,
332  statusTestParams_.get("ABSTOL", 1.0e-12),
333  statusTestParams_.get("RELTOL", 1.0e-3),
334  statusTestParams_.get("DELTAXTOL", 1.0),
335  isTransient);
336  tests_.push_back(test2b);
337  */
338  /*
339  //RPP Hack for test2b to get Homotopy to work
340  NOX::StatusTest::NormF* test2b =
341  new NOX::StatusTest::NormF(statusTestParams_.get("RHSTOL", 1.0e-6),
342  NOX::Abstract::Vector::MaxNorm,
343  NOX::StatusTest::NormF::Unscaled);
344  tests_.push_back(test2b);
345 
346 
347  NOX::StatusTest::Combo* test2 =
348  new NOX::StatusTest::Combo(NOX::StatusTest::Combo::AND, *test2a, *test2b);
349  tests_.push_back(test2);
350  comboPtr_->addStatusTest(*test2);
351 
352  // Test 3 - Near Convergence - Hit max iterations but residual
353  // and convergence rate indicate we may be near a converged solution.
354  // Therefore, let the time stepper decide whether or not the step is ok.
355  // Transient mode ONLY!
356  NOX::StatusTest::Generic* test3 = 0;
357  if (mode_ == TRANSIENT)
358  {
359  test3 = new N_NLS_NOX::NearConvergenceTest(statusTestParams_.get("MAXSTEP", 200), 1.0);
360  tests_.push_back(test3);
361  comboPtr_->addStatusTest(*test3);
362  }
363  */
364  /*
365  // Test 4 - Update is too small
366  N_NLS_NOX::UpdateTooSmallTest* test4 =
367  new N_NLS_NOX::UpdateTooSmallTest(*test2b, 1.0e-6);
368  tests_.push_back(test4);
369  comboPtr_->addStatusTest(*test4);
370  */
371  /*
372  // Test 5 - Max nonlinear iterations (if transient, this will be checked
373  // in the NearConvergence test (#3)
374  if (mode_ != TRANSIENT)
375  {
376  NOX::StatusTest::MaxIters* test5 =
377  new NOX::StatusTest::MaxIters(statusTestParams_.get("MAXSTEP", 200));
378  tests_.push_back(test5);
379  comboPtr_->addStatusTest(*test5);
380  }
381 
382  // Test 6 - update is too big
383  N_NLS_NOX::LargeUpdateTest* test6 =
384  new N_NLS_NOX::LargeUpdateTest(0.5*N_UTL_MachineDependentParams::DoubleMax());
385  tests_.push_back(test6);
386  comboPtr_->addStatusTest(*test6);
387 
388  // Test 7 - Stall in the convergence rate. Transient mode ONLY!
389  if (mode_ == TRANSIENT)
390  {
391  N_NLS_NOX::Stagnation* test7 = new N_NLS_NOX::Stagnation(50);
392  tests_.push_back(test7);
393  comboPtr_->addStatusTest(*test7);
394  }
395 
396  */
397 
398  // RPP: moving inside allTests so we don't have to dynamic cast
399  // NaN/Inf check on the residual vector 2-norm
400  //NOX::StatusTest::FiniteValue* fvTest = new NOX::StatusTest::FiniteValue;
401  //tests_.push_back(fvTest);
402  //comboPtr_->addStatusTest(*fvTest);
403 
404  // Tests All - replaces tests 1-7
405  bool isTransient = false;
406  if (mode_ == Xyce::Nonlinear::TRANSIENT)
407  {
408  isTransient = true;
409  }
410 
411  // make the correct testing object
412  Teuchos::RefCountPtr<N_NLS_NOX::XyceTests> allTests;
413  if( statusTestParams_.get("FASTTESTS",false) )
414  {
415  // make the FastTests object
416  allTests = Teuchos::rcp(new N_NLS_NOX::FastTests(isTransient,
417  statusTestParams_.get("RHSTOL", 1.0e-6),
418  N_UTL_MachineDependentParams::MachineEpsilon(),
419  currSolVectorPtrPtr,
420  statusTestParams_.get("ABSTOL", 1.0e-12),
421  statusTestParams_.get("RELTOL", 1.0e-3),
422  statusTestParams_.get("DELTAXTOL", 1.0),
423  statusTestParams_.get("MAXSTEP", 200),
424  0.9,
425  1.0,
426  0.5*N_UTL_MachineDependentParams::DoubleMax(),
427  1.0e-3,
428  5,
429  statusTestParams_.get("ENFORCEDEVICECONV", 1),
430  statusTestParams_.get("SMALLUPDATETOL", 1.0e-6),
431  &loader,
432  varTypeVec,
433  statusTestParams_.get("VOLTZEROTOL", 1.0e-6),
434  statusTestParams_.get("CURRZEROTOL", 1.0e-6)
435  #ifdef Xyce_NLS_MASKED_WRMS_NORMS
436  , nonTrivialDeviceMaskFlag, maskVectorPtr
437  #endif
438  ));
439  }
440  else
441  {
442  // here we make the default XyceTests object
443  allTests = Teuchos::rcp(new N_NLS_NOX::XyceTests(isTransient,
444  statusTestParams_.get("RHSTOL", 1.0e-6),
445  N_UTL_MachineDependentParams::MachineEpsilon(),
446  currSolVectorPtrPtr,
447  statusTestParams_.get("ABSTOL", 1.0e-12),
448  statusTestParams_.get("RELTOL", 1.0e-3),
449  statusTestParams_.get("DELTAXTOL", 1.0),
450  statusTestParams_.get("MAXSTEP", 200),
451  0.9,
452  1.0,
453  0.5*N_UTL_MachineDependentParams::DoubleMax(),
454  1.0e-3,
455  5,
456  statusTestParams_.get("ENFORCEDEVICECONV", 1),
457  statusTestParams_.get("SMALLUPDATETOL", 1.0e-6),
458  &loader
459  #ifdef Xyce_NLS_MASKED_WRMS_NORMS
460  , nonTrivialDeviceMaskFlag, maskVectorPtr
461  #endif
462  ));
463  }
464  tests_.push_back(allTests);
465  comboPtr_->addStatusTest(allTests);
466  isStatusTestsSet_ = true;
467  return true;
468 }
469 
470 //-----------------------------------------------------------------------------
471 // Function : ParameterSet::getStatusTests
472 // Purpose :
473 // Special Notes :
474 // Scope : public
475 // Creator :
476 // Creation Date :
477 //-----------------------------------------------------------------------------
478 Teuchos::RefCountPtr<NOX::StatusTest::Generic> ParameterSet::getStatusTests()
479 {
480  if (!isStatusTestsSet_)
481  {
482  const std::string message = "Error: N_NLS::NOX::ParameterSet::getStatusTests() - Status tests are not set!";
483  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, message);
484  }
485 
486  return comboPtr_;
487 }
488 
489 //-----------------------------------------------------------------------------
490 // Function : ParameterSet::getAllParams
491 // Purpose :
492 // Special Notes :
493 // Scope : public
494 // Creator :
495 // Creation Date :
496 //-----------------------------------------------------------------------------
497 Teuchos::RefCountPtr<Teuchos::ParameterList> ParameterSet::getAllParams()
498 {
499  return allParams_;
500 }
501 
502 //-----------------------------------------------------------------------------
503 // Function : ParameterSet::getNoxParams
504 // Purpose :
505 // Special Notes :
506 // Scope : public
507 // Creator :
508 // Creation Date :
509 //-----------------------------------------------------------------------------
510 Teuchos::RefCountPtr<Teuchos::ParameterList> ParameterSet::getNoxParams()
511 {
512  return Teuchos::rcp(&noxParams_, false);
513 }
514 
515 //-----------------------------------------------------------------------------
516 // Function : ParameterSet::getLocaParams
517 // Purpose :
518 // Special Notes :
519 // Scope : public
520 // Creator :
521 // Creation Date :
522 //-----------------------------------------------------------------------------
523 Teuchos::RefCountPtr<Teuchos::ParameterList> ParameterSet::getLocaParams()
524 {
525  return Teuchos::rcp(&locaParams_, false);
526 }
527 
528 //-----------------------------------------------------------------------------
529 // Function : ParameterSet::getDebugParams
530 // Purpose :
531 // Special Notes :
532 // Scope : public
533 // Creator :
534 // Creation Date :
535 //-----------------------------------------------------------------------------
536 Teuchos::RefCountPtr<Teuchos::ParameterList> ParameterSet::getDebugParams()
537 {
538  return Teuchos::rcp(&debugParams_, false);
539 }
540 
541 //-----------------------------------------------------------------------------
542 // Function : ParameterSet::unsupportedOption_
543 // Purpose :
544 // Special Notes :
545 // Scope : public
546 // Creator :
547 // Creation Date :
548 //-----------------------------------------------------------------------------
549 void ParameterSet::unsupportedOption_(const std::string& tag)
550 {
551  const std::string warning =
552  "Tag \"" + tag + "\" is unsupported by the NOX interface at this time.\n";
553  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::USR_WARNING_0, warning);
554 }
555 
556 //-----------------------------------------------------------------------------
557 // Function : ParameterSet::parseOptionBlock_
558 // Purpose :
559 // Special Notes :
560 // Scope : public
561 // Creator :
562 // Creation Date :
563 //-----------------------------------------------------------------------------
564 bool ParameterSet::parseOptionBlock_(const N_UTL_OptionBlock& OB)
565 {
566  // RPP: Some parameters can't be immediately set in the nox
567  // parameter list because they are in a sublist dependent upon
568  // another parameter being set first. We have to store these
569  // parameters until the entire option block is parsed and then set
570  // them in the correct sublist. These parameters are listed below.
571  int maxSearchStep = 2;
572  int in_Forcing = 0;
573  double AZ_tol = 1.0e-12;
574  int recoveryStepType = 0;
575  double recoveryStep = 1.0;
576  int memory = 400;
577 
578 
579  // Loop over all parameters in the option block
580  for (std::list<N_UTL_Param>::const_iterator it_tpL = OB.getParams().begin();
581  it_tpL != OB.getParams().end(); ++ it_tpL)
582  {
583  const std::string tag = it_tpL->uTag();
584 
585 
586  // Parameters for nonlinear convergence tests
587  if (tag == "ABSTOL")
588  {
589  statusTestParams_.set("ABSTOL", it_tpL->getImmutableValue<double>());
590  }
591  else if (tag == "RELTOL")
592  {
593  statusTestParams_.set("RELTOL", it_tpL->getImmutableValue<double>());
594  }
595  else if (tag == "DELTAXTOL")
596  {
597  statusTestParams_.set("DELTAXTOL", it_tpL->getImmutableValue<double>());
598  }
599  else if (tag == "RHSTOL")
600  {
601  statusTestParams_.set("RHSTOL", it_tpL->getImmutableValue<double>());
602  }
603  else if (tag == "MAXSTEP")
604  {
605  statusTestParams_.set("MAXSTEP", it_tpL->getImmutableValue<int>());
606  }
607  else if (tag == "SMALLUPDATETOL")
608  {
609  statusTestParams_.set("SMALLUPDATETOL", it_tpL->getImmutableValue<double>());
610  }
611 
612  // Check devices for convergence (by calls to cktloader)
613  else if (tag == "ENFORCEDEVICECONV")
614  {
615  statusTestParams_.set("ENFORCEDEVICECONV", it_tpL->getImmutableValue<int>());
616  }
617  else if (tag == "FASTTESTS")
618  {
619  statusTestParams_.set("FASTTESTS", it_tpL->getImmutableValue<bool>());
620  }
621  else if (tag == "VOLTZEROTOL")
622  {
623  statusTestParams_.set("VOLTZEROTOL", it_tpL->getImmutableValue<double>());
624  }
625  else if (tag == "ABSZEROTOL")
626  {
627  statusTestParams_.set("ABSZEROTOL", it_tpL->getImmutableValue<double>());
628  }
629 
630  // Unsupported options
631  else if (tag == "LINOPT")
632  {
633  unsupportedOption_(tag);
634  }
635  else if (tag == "CONSTRAINTBT")
636  {
637  unsupportedOption_(tag);
638  }
639  else if (tag == "CONSTRAINTMAX")
640  {
641  unsupportedOption_(tag);
642  }
643  else if (tag == "CONSTRAINTMIN")
644  {
645  unsupportedOption_(tag);
646  }
647  else if (tag == "CONSTRAINTCHANGE")
648  {
649  unsupportedOption_(tag);
650  }
651  else if (tag == "NORMLVL")
652  {
653  if (it_tpL->getImmutableValue<int>() != 2)
654  unsupportedOption_(tag);
655  }
656  else if (tag == "DEBUGLEVEL")
657  {
658  debugLevel_ = it_tpL->getImmutableValue<int>();
659  }
660  else if (tag == "SCREENOUTPUT")
661  {
662  screenOutputFlag_ = it_tpL->getImmutableValue<bool>();
663  }
664  else if (tag == "DEBUGMINTIMESTEP")
665  {
666  debugMinTimeStep_ = it_tpL->getImmutableValue<int>();
667  }
668  else if (tag == "DEBUGMAXTIMESTEP")
669  {
670  debugMaxTimeStep_ = it_tpL->getImmutableValue<int>();
671  }
672  else if (tag == "DEBUGMINTIME")
673  {
674  debugMinTime_ = it_tpL->getImmutableValue<double>();
675  }
676  else if (tag == "DEBUGMAXTIME")
677  {
678  debugMaxTime_ = it_tpL->getImmutableValue<double>();
679  }
680  else if (tag == "DLSDEBUG")
681  unsupportedOption_(tag);
682 
683  // Nonlinear Strategy
684  else if (tag == "NLSTRATEGY")
685  {
686  int val = it_tpL->getImmutableValue<int>();
687  if (val == 0) // Newton
688  {
689  noxParams_.set("Nonlinear Solver", "Line Search Based");
690  noxParams_.sublist("Direction").set("Method", "Newton");
691  }
692  else if (val == 1) // Steepest descent
693  {
694  noxParams_.set("Nonlinear Solver", "Line Search Based");
695  noxParams_.sublist("Direction")
696  .set("Method", "Steepest Descent");
697  }
698  else if (val == 2) // Trust Region
699  {
700  noxParams_.set("Nonlinear Solver", "Trust Region Based");
701  }
702  else if (val == 3) // Modified Newton
703  {
704  noxParams_.set("Nonlinear Solver", "Line Search Based");
705  noxParams_.sublist("Direction")
706  .set("Method", "Modified-Newton");
707  }
708  else if (val == 4) // BFGS
709  {
710  noxParams_.set("Nonlinear Solver", "Line Search Based");
711  noxParams_.sublist("Direction").set("Method", "Quasi-Newton");
712  }
713  else if (val == 5) // Broyden
714  {
715  noxParams_.set("Nonlinear Solver", "Line Search Based");
716  noxParams_.sublist("Direction").set("Method", "Broyden");
717  }
718  else if (val == 6) // Tensor
719  {
720  noxParams_.set("Nonlinear Solver", "Tensor Based");
721  noxParams_.sublist("Direction").set("Method", "Tensor");
722  noxParams_.sublist("Direction").sublist("Tensor")
723  .sublist("Linear Solver").set("Compute Step", "Newton");
724  noxParams_.sublist("Direction").sublist("Tensor")
725  .sublist("Linear Solver").set("Reorthogonalize", "Always");
726  noxParams_.sublist("Line Search").set("Method", "Tensor");
727  noxParams_.sublist("Line Search").sublist("Tensor")
728  .set("Submethod", "Full Step");
729  }
730  else if (val == 7) // Fast Newton Direction
731  {
732  // RPP: No longer supported
733  const std::string warning =
734  "NLStrategy = 7 is no longer supported.\n";
735  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::USR_WARNING_0, warning);
736  }
737  else if (val == 8) // Newton/Steepest Descent Combo Direction
738  {
739  // RPP: No longer supported
740  const std::string warning =
741  "NLStrategy = 8 is no longer supported.\n";
742  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::USR_WARNING_0, warning);
743  }
744  else
745  {
746  const std::string warning =
747  "NLStrategy is not found!\n";
748  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::USR_WARNING_0, warning);
749  }
750  }
751 
752  // Line search method
753  else if (tag == "SEARCHMETHOD")
754  {
755  int val = it_tpL->getImmutableValue<int>();
756  if (val == 0)
757  {
758  noxParams_.sublist("Line Search").set("Method", "Full Step");
759  }
760  else if (val == 1)
761  {
762  noxParams_.sublist("Line Search").set("Method", "Backtrack");
763  }
764  else if (val == 2)
765  {
766  noxParams_.sublist("Line Search").set("Method", "Polynomial");
767  noxParams_.sublist("Line Search").sublist("Polynomial")
768  .set("Interpolation Type", "Quadratic");
769  }
770  else if (val == 3)
771  {
772  noxParams_.sublist("Line Search").set("Method", "Polynomial");
773  noxParams_.sublist("Line Search").sublist("Polynomial")
774  .set("Interpolation Type", "Cubic");
775  }
776  else if (val == 4)
777  {
778  noxParams_.sublist("Line Search")
779  .set("Method", "More'-Thuente");
780  }
781  else
782  {
783  std::ostringstream ost;
784  ost << "N_NLS_NOX::ParameterSet::parseOptionBlock_ - "
785  << "SEARCHMETHOD = " << val
786  << " not supported by Xyce at this time." << std::endl;
787  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::USR_WARNING_0, ost.str());
788  }
789  }
790 
791  // Trust Region auxiliary parameters
792  else if (tag == "TRMINRADIUS")
793  {
794  noxParams_.sublist("Trust Region")
795  .set("Minimum Trust Region Radius", it_tpL->getImmutableValue<double>());
796  }
797  else if (tag == "TRMAXRADIUS")
798  {
799  noxParams_.sublist("Trust Region")
800  .set("Maximum Trust Region Radius", it_tpL->getImmutableValue<double>());
801  }
802  else if (tag == "TRMINIMPROVEMENTRATIO")
803  {
804  noxParams_.sublist("Trust Region")
805  .set("Minimum Improvement Ratio", it_tpL->getImmutableValue<double>());
806  }
807  else if (tag == "TRCONTRACTIONRATIO")
808  {
809  noxParams_.sublist("Trust Region")
810  .set("Contraction Trigger Ratio", it_tpL->getImmutableValue<double>());
811  }
812  else if (tag == "TRCONTRACTIONFACTOR")
813  {
814  noxParams_.sublist("Trust Region")
815  .set("Contraction Factor", it_tpL->getImmutableValue<double>());
816  }
817  else if (tag == "TREXPANSIONRATIO")
818  {
819  noxParams_.sublist("Trust Region")
820  .set("Expansion Trigger Ratio", it_tpL->getImmutableValue<double>());
821  }
822  else if (tag == "TREXPANSIONFACTOR")
823  {
824  noxParams_.sublist("Trust Region")
825  .set("Expansion Factor", it_tpL->getImmutableValue<double>());
826  }
827  else if (tag == "TRRECOVERYSTEP")
828  {
829  noxParams_.sublist("Trust Region")
830  .set("Recovery Step", it_tpL->getImmutableValue<double>());
831  }
832 
833  // RPP: Why this is here???
834  else if (tag == "NOX")
835  {
836  // do nothing (this option is handled in the manager)
837  }
838 
839  // LOCA Continuation control
840  // 0 = Nox solve (no continuation)
841  // 1 = Natural Parameter Continuation
842  // 2 = Mosfet Specific Dual Parameter Continuation
843  // 3 = gmin stepping.
844  // 33 = Artificial Parameter Continuation
845  else if (tag == "CONTINUATION")
846  {
848  if (it_tpL->isNumeric())
849  {
850  noxSolver = it_tpL->getImmutableValue<int>();
851  }
852  else
853  {
854  ExtendedString p(it_tpL->stringValue());
855  p.toUpper();
856  if (p.substr(0,4) == "STAN")
857  {
858  noxSolver = 0;
859  }
860  else if (p.substr(0,3) == "NAT")
861  {
862  noxSolver = 1;
863  }
864  else if (p.substr(0,3) == "MOS")
865  {
866  noxSolver = 2;
867  }
868  else if (p.substr(0,4) == "GMIN")
869  {
870  noxSolver = 3;
871  }
872  else if (p.substr(0,6) == "NEWMOS")
873  {
874  noxSolver = 4;
875  }
876  else if (p.substr(0,9) == "BSIM3INV1")
877  {
878  noxSolver = 5;
879  }
880  else if (p.substr(0,9) == "BSIM3INV2")
881  {
882  noxSolver = 6;
883  }
884  else if (p.substr(0,9) == "BLOCKGAIN")
885  {
886  noxSolver = 7;
887  }
888  else if (p.substr(0,4) == "TEST")
889  {
890  noxSolver = 8;
891  }
892  else if (p.substr(0,6) == "PSEUDO")
893  {
894  noxSolver = 9;
895  }
896  else if (p.substr(0,5) == "POWER")
897  {
898  noxSolver = 10;
899  }
900  else if (p.substr(0,3) == "ART")
901  {
902  noxSolver = 33;
903  }
904  else
905  {
906  std::string message = "Unknown specification in .options for 'continuation': ";
907  message += it_tpL->stringValue();
908  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, message);
909  }
910 
911  // Bail out if option 33 (artif. homotopy) is chosen but
912  // required support is not built in.
913 #ifndef Xyce_NOX_LOCA_ARTIFICIAL_HOMOTOPY_SUPPORT
914  if (noxSolver == 33)
915  {
916  Xyce::Report::UserFatal0() << "Nonlinear Solver (NOX::Interface) Artificial parameter continuation requires "
917  << "building xyce with the define: -DXyce_NOX_LOCA_ARTIFICIAL_HOMOTOPY_SUPPORT to "
918  << "allow LOCA to augment the diagonal of Jacobian! Either rebuild Xyce or do not "
919  << "run Xyce with \"continuation=33\"";
920  }
921 #endif
922  }
923  }
924 
925  // Parameters that can't be set in the list until all options
926  // have been parsed
927  else if (tag == "MAXSEARCHSTEP")
928  {
929  maxSearchStep = it_tpL->getImmutableValue<int>();
930  }
931  else if (tag == "IN_FORCING")
932  {
933  in_Forcing = it_tpL->getImmutableValue<int>();
934  }
935  else if (tag == "AZ_TOL")
936  {
937  AZ_tol = it_tpL->getImmutableValue<double>();
938  }
939  else if (tag == "RECOVERYSTEPTYPE")
940  {
941  recoveryStepType = it_tpL->getImmutableValue<int>();
942  }
943  else if (tag == "RECOVERYSTEP")
944  {
945  recoveryStep = it_tpL->getImmutableValue<double>();
946  }
947  else if (tag == "MEMORY")
948  {
949  memory = it_tpL->getImmutableValue<int>();
950  }
951 
952  // Parameters that can't be set in the list until all options
953  // have been parsed
954  else if (tag == "MAXSEARCHSTEP")
955  {
956  maxSearchStep = it_tpL->getImmutableValue<int>();
957  }
958  else if (tag == "IN_FORCING")
959  {
960  in_Forcing = it_tpL->getImmutableValue<int>();
961  }
962  else if (tag == "AZ_TOL")
963  {
964  AZ_tol = it_tpL->getImmutableValue<double>();
965  }
966  else if (tag == "RECOVERYSTEPTYPE")
967  {
968  recoveryStepType = it_tpL->getImmutableValue<int>();
969  }
970  else if (tag == "RECOVERYSTEP")
971  {
972  recoveryStep = it_tpL->getImmutableValue<double>();
973  }
974  else if (tag == "MEMORY")
975  {
976  memory = it_tpL->getImmutableValue<int>();
977  }
978 
979  // Warn user about unrecognized solver option
980  else
981  {
982  Xyce::Report::UserWarning() << tag << " is not a recognized nonlinear solver option.\n" << std::endl;
983  }
984 
985  } // end loop over all options in block
986 
987 
988  /*
989  Set parameters that are dependent upon other parameters
990 
991  RPP: Some parameters can't be immediately set in the nox
992  parameter list because they are in a sublist dependent upon
993  another parameter being set first. We have to store these
994  parameters until the entire option block is parsed and then set
995  them in the correct sublist.
996  */
997  std::string directionMethod =
998  noxParams_.sublist("Direction").get("Method", "Newton");
999 
1000  std::string lineSearchMethod =
1001  noxParams_.sublist("Line Search").get("Method", "Full Step");
1002 
1003  // MAXSEARCHSTEP
1004  noxParams_.sublist("Line Search").sublist(lineSearchMethod)
1005  .set("Max Iters", maxSearchStep);
1006 
1007  // In_FORCING
1008  if (in_Forcing == 0)
1009  {
1010  noxParams_.sublist("Direction").sublist(directionMethod)
1011  .set("Forcing Term Method", "Constant");
1012  }
1013  else if (in_Forcing == 1)
1014  {
1015  noxParams_.sublist("Direction").sublist(directionMethod)
1016  .set("Forcing Term Method", "Type 1");
1017  noxParams_.sublist("Direction").sublist("Newton")
1018  .set("Forcing Term Minimum Tolerance", AZ_tol);
1019  }
1020  else
1021  {
1022  noxParams_.sublist("Direction").sublist(directionMethod)
1023  .set("Forcing Term Method", "Type 2");
1024  noxParams_.sublist("Direction").sublist("Newton")
1025  .set("Forcing Term Minimum Tolerance", AZ_tol);
1026  }
1027 
1028  // RECOVERYSTEPTYPE
1029  if (recoveryStepType == 1)
1030  {
1031  // Recovery the NOX way
1032  noxParams_.sublist("Line Search").sublist(lineSearchMethod)
1033  .set("Recovery Step Type", "Constant");
1034  }
1035  else
1036  {
1037  // Recovery the Xyce way
1038  noxParams_.sublist("Line Search").sublist(lineSearchMethod)
1039  .set("Recovery Step Type", "Last Computed Step");
1040  }
1041 
1042  // RECOVERYSTEP
1043  noxParams_.sublist("Line Search").sublist(lineSearchMethod)
1044  .set("Recovery Step", recoveryStep);
1045 
1046  // MEMORY
1047  if ((directionMethod == "Quasi-Newton") ||
1048  (directionMethod == "Broyden"))
1049  noxParams_.sublist("Direction").sublist(directionMethod)
1050  .set("Memory", memory);
1051 
1052 
1053  return true;
1054 }
1055 
1056 //-----------------------------------------------------------------------------
1057 // Function : ParameterSet::setLocaOptions
1058 // Purpose :
1059 // Special Notes :
1060 // Scope : public
1061 // Creator :
1062 // Creation Date :
1063 //-----------------------------------------------------------------------------
1064 bool ParameterSet::setLocaOptions(const N_UTL_OptionBlock& OB, bool saveCopy)
1065 {
1066  Teuchos::ParameterList& stepperList = locaParams_.sublist("Stepper");
1067  Teuchos::ParameterList& predictorList = locaParams_.sublist("Predictor");
1068  Teuchos::ParameterList& stepSizeList = locaParams_.sublist("Step Size");
1069 
1070  bool stepperGiven=false;
1071  bool predictorGiven=false;
1072 
1073  if (saveCopy)
1074  {
1075  savedLocaOptions_ = true;
1076  savedLocaOB_ = OB; // save a copy to re-assert defaults later, if needed.
1077  }
1078 
1079  for (std::list<N_UTL_Param>::const_iterator it_tpL = OB.getParams().begin();
1080  it_tpL != OB.getParams().end(); ++ it_tpL)
1081  {
1082  const std::string tag = it_tpL->uTag();
1083  std::string baseTag=tag.substr(0,8);
1084  bool isVectorParam=false;
1085  if (baseTag == "CONPARAM" ||
1086  baseTag == "MINVALUE" ||
1087  baseTag == "MAXVALUE" ||
1088  baseTag == "INITIALV" ||
1089  baseTag == "INITIALS" ||
1090  baseTag == "MINSTEPS" ||
1091  (baseTag == "MAXSTEPS" && tag.substr(0,11)=="MAXSTEPSIZE")||
1092  baseTag == "AGGRESSI")
1093  {
1094  if (baseTag == "INITIALV")
1095  {
1096  baseTag = "INITIALVALUE";
1097  }
1098  else if (baseTag == "INITIALS")
1099  {
1100  baseTag = "INITIALSTEPSIZE";
1101  }
1102  else if (baseTag == "MINSTEPS")
1103  {
1104  baseTag = "MINSTEPSIZE";
1105  }
1106  else if (baseTag == "MAXSTEPS")
1107  {
1108  baseTag = "MAXSTEPSIZE";
1109  }
1110  else if (baseTag == "AGGRESSI")
1111  {
1112  baseTag = "AGGRESSIVENESS";
1113  }
1114 
1115  std::string num=tag.substr(baseTag.size(),tag.size()-baseTag.size());
1116  int index=ExtendedString(num).Ival();
1117  vectorParams[baseTag].push_back(*it_tpL);
1118  isVectorParam=true;
1119  }
1120  if (tag == "STEPPER")
1121  {
1122  stepperGiven=true;
1123  if (it_tpL->isNumeric())
1124  {
1125  int iType = it_tpL->getImmutableValue<int>();
1126  if (iType == 1)
1127  {
1128  stepperList.set("Continuation Method", "Arc Length");
1129  stepperList.set("Skip df/dp", false);
1130  }
1131  else
1132  {
1133  stepperList.set("Continuation Method", "Natural");
1134  stepperList.set("Skip df/dp", true);
1135  }
1136  }
1137  else
1138  {
1139  ExtendedString p(it_tpL->stringValue());
1140  p.toUpper();
1141  if (p.substr(0,3) == "ARC")
1142  {
1143  stepperList.set("Continuation Method", "Arc Length");
1144  stepperList.set("Skip df/dp", false);
1145  }
1146  else if (p.substr(0,3) == "NAT")
1147  {
1148  stepperList.set("Continuation Method", "Natural");
1149  stepperList.set("Skip df/dp", true);
1150  }
1151  else
1152  {
1153  std::string message = "Unknown specification in .options for 'stepper': ";
1154  message += it_tpL->stringValue();
1155  message += ". Legal choices are ARCLENGTH or NATURAL, which may be abbreviated to three characters.";
1156  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, message);
1157  }
1158  }
1159  }
1160  else if (tag == "PREDICTOR")
1161  {
1162  predictorGiven=true;
1163  if (it_tpL->isNumeric())
1164  {
1165  int iType = it_tpL->getImmutableValue<int>();
1166  if (iType == 1)
1167  {
1168  predictorList.set("Method", "Tangent");
1169  }
1170  else if (iType == 2)
1171  {
1172  predictorList.set("Method", "Secant");
1173  }
1174  else if (iType == 3)
1175  {
1176  predictorList.set("Method", "Random");
1177  }
1178  else
1179  {
1180  predictorList.set("Method", "Constant");
1181  }
1182  }
1183  else
1184  {
1185  ExtendedString p(it_tpL->stringValue());
1186  p.toUpper();
1187  if (p.substr(0,3) == "TAN")
1188  {
1189  predictorList.set("Method", "Tangent");
1190  }
1191  else if (p.substr(0,3) == "SEC")
1192  {
1193  predictorList.set("Method", "Secant");
1194  }
1195  else if (p.substr(0,3) == "RAN")
1196  {
1197  predictorList.set("Method", "Random");
1198  }
1199  else if (p.substr(0,3) == "CON")
1200  {
1201  predictorList.set("Method", "Constant");
1202  }
1203  else
1204  {
1205  std::string message = "Unknown specification in .options for 'predictor': ";
1206  message += it_tpL->stringValue();
1207  message += ". Legal choices are TANGENT, SECANT, RANDOM, CONSTANT, which may be abbreviated to three characters.";
1208  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, message);
1209  }
1210  }
1211  }
1212  // if we're the very first instance of one of these vector params,
1213  // then set our stepperList (this is the old behavior from the
1214  // "alternate" vector handling
1215  else if (tag == "CONPARAM1") // continuation parameter
1216  {
1217  stepperList.set("Continuation Parameter", it_tpL->stringValue());
1218  }
1219  else if (tag == "INITIALVALUE1")
1220  {
1221  stepperList.set("Initial Value", it_tpL->getImmutableValue<double>());
1222  }
1223  else if (tag == "MINVALUE1")
1224  {
1225  gstepping_min_value_ = it_tpL->getImmutableValue<double>();
1226  stepperList.set("Min Value", it_tpL->getImmutableValue<double>());
1227  }
1228  else if (tag == "RESIDUALCONDUCTANCE")
1229  {
1230  gstepping_minimum_conductance_ = it_tpL->getImmutableValue<double>();
1232  {
1233  Xyce::Report::UserWarning0() << "A non-zero value for the GMIN Stepping residual conductance has been specified (RESIDUALCONDUCTANCE= " << it_tpL->stringValue() << ")." << std::endl
1234  << "This option should never be used unless absolutely necessary to obtain an initial condition for transient runs with ill-posed DC operating points. The operating point obtained by GMIN Stepping will not be a valid steady state condition for the circuit as defined in the netlist, but might possibly produce a reasonable initial condition for transient runs.";
1235  }
1236  }
1237  else if (tag == "INITIALSTEPSIZE1")
1238  {
1239  stepSizeList.set("Initial Step Size", it_tpL->getImmutableValue<double>());
1240  }
1241  else if (tag == "MINSTEPSIZE1")
1242  {
1243  stepSizeList.set("Min Step Size", it_tpL->getImmutableValue<double>());
1244  }
1245  else if (tag == "MAXSTEPSIZE1")
1246  {
1247  stepSizeList.set("Max Step Size", it_tpL->getImmutableValue<double>());
1248  }
1249  else if (tag == "AGGRESSIVENESS1")
1250  {
1251  stepSizeList.set("Aggressiveness", it_tpL->getImmutableValue<double>());
1252  }
1253  else if (tag == "MAXVALUE1")
1254  {
1255  stepperList.set("Max Value", it_tpL->getImmutableValue<double>());
1256  }
1257  else if (tag == "BIFPARAM") // bifurcation parameter
1258  {
1259  stepperList.set("Bifurcation Parameter", it_tpL->stringValue());
1260  }
1261  else if (tag == "MAXSTEPS")
1262  {
1263  stepperList.set("Max Steps", it_tpL->getImmutableValue<int>());
1264  }
1265  else if (tag == "MAXNLITERS")
1266  {
1267  stepperList.set("Max Nonlinear Iterations", it_tpL->getImmutableValue<int>());
1268  }
1269  else if (tag == "STEPCONTROL")
1270  {
1271  if (it_tpL->isNumeric())
1272  {
1273  int iType = it_tpL->getImmutableValue<int>();
1274  if (iType == 1)
1275  stepSizeList.set("Method", "Adaptive");
1276  else
1277  stepSizeList.set("Method", "Constant");
1278  }
1279  else
1280  {
1281  ExtendedString p(it_tpL->stringValue());
1282  p.toUpper();
1283  if (p.substr(0,3) == "ADA")
1284  {
1285  stepSizeList.set("Method", "Adaptive");
1286  }
1287  else if (p.substr(0,3) == "CON")
1288  {
1289  stepSizeList.set("Method", "Constant");
1290  }
1291  else
1292  {
1293  std::string message = "Unknown specification in .options for 'stepcontrol': ";
1294  message += it_tpL->stringValue();
1295  message += ". Legal choices are ADAPTIVE or CONSTANT, which may be abbreviated to three characters.";
1296  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, message);
1297  }
1298  }
1299  }
1300  else if (tag == "POWERNODE") // continuation parameter
1301  {
1302  stepperList.set("Power Node", it_tpL->stringValue());
1303  }
1304  else if (tag == "VOLTAGELIST")
1305  {
1306  ExtendedString p(it_tpL->stringValue());
1307  p.toUpper();
1308  if (p.substr(0,3) == "DOF") // DOFS - degrees of freedom
1309  {
1311  }
1312  else if (p.substr(0,3) == "NOD") // NODES - voltage nodes
1313  {
1315  }
1316  else
1317  {
1318  std::string message = "Unknown specification in .options loca for 'voltagelist': ";
1319  message += it_tpL->stringValue();
1320  message += ". Legal choices are DOFS or NODES, which may be abbreviated to three characters.";
1321  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, message);
1322  }
1323  }
1324  else if(tag == "VOLTAGESCALEFACTOR")
1325  {
1326  voltageScaleFactor_ = it_tpL->getImmutableValue<double>();
1327  }
1328  // Start of the new parameter section
1329  else if (std::string(tag,0,10) == "PARAMLIST")
1330  {
1331  // don't know what to do yet.
1332  Xyce::dout() << "tag = " << tag << std::endl;
1333  }
1334  else
1335  {
1336  // if "isVectorParam" we've already handled this at the beginning
1337  // of the loop. Otherwise it's an unrecognized parameter.
1338  if (!isVectorParam)
1339  {
1340  std::string tmp =tag + " is not a recognized loca option.\n";
1341  N_ERH_ErrorMgr::report (N_ERH_ErrorMgr::USR_WARNING_0, tmp);
1342  }
1343  }
1344  }
1345 
1346  // Insure that the correct defaults are set. Sometimes the LOCA
1347  // defaults change in the LOCA library from release to release. However
1348  // Xyce's defaults should not necessarily change in that case.
1349  if (!stepperGiven)
1350  {
1351  stepperList.set("Continuation Method", "Natural");
1352  stepperList.set("Skip df/dp", true);
1353  }
1354 
1355  if (!predictorGiven)
1356  {
1357  predictorList.set("Method", "Tangent");
1358  }
1359 
1360  return true;
1361 }
1362 
1363 //-----------------------------------------------------------------------------
1364 // Function : ParameterSet::getVectorParam
1365 // Purpose : Obtain a parameter specified in the option line in vector syntax
1366 // Special Notes :
1367 // Scope : public
1368 // Creator : Dave Shirley, PSSI
1369 // Creation Date : 02/02/06
1370 //-----------------------------------------------------------------------------
1371 bool ParameterSet::getVectorParam (const std::string & tag, int index, double & value)
1372 {
1373  if (vectorParams.find(tag) != vectorParams.end() &&
1374  vectorParams[tag].size() > index)
1375  {
1376  value = vectorParams[tag][index].getImmutableValue<double>();
1377  return true;
1378  }
1379  else
1380  {
1381  return false;
1382  }
1383 }
1384 
1385 //-----------------------------------------------------------------------------
1386 // Function : ParameterSet::getVectorParam
1387 // Purpose : Obtain a parameter specified in the option line in vector syntax
1388 // Special Notes :
1389 // Scope : public
1390 // Creator : Dave Shirley, PSSI
1391 // Creation Date : 02/02/06
1392 //-----------------------------------------------------------------------------
1393 bool ParameterSet::getVectorParam (const std::string & tag, int index, std::string & value)
1394 {
1395  if (vectorParams.find(tag) != vectorParams.end() &&
1396  vectorParams[tag].size() > index)
1397  {
1398  value = vectorParams[tag][index].stringValue();
1399  return true;
1400  }
1401  else
1402  {
1403  return false;
1404  }
1405 }
1406 
1407 //-----------------------------------------------------------------------------
1408 // Function : ParameterSet::getVectorParamSize
1409 // Purpose :
1410 // Special Notes :
1411 // Scope : public
1412 // Creator :
1413 // Creation Date :
1414 //-----------------------------------------------------------------------------
1415 int ParameterSet::getVectorParamSize(const std::string& tag)
1416 {
1417  if (vectorParams.find(tag) != vectorParams.end())
1418  {
1419  return static_cast<int>(vectorParams[tag].size());
1420  }
1421  else
1422  {
1423  std::string msg = "N_NLS_NOX::ParameterSet::getVectorParam - ";
1424  msg += "the parameter \"";
1425  msg += tag;
1426  msg += "\" is required for parameter continuation!";
1427  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
1428  }
1429 
1430  return -1;
1431 }
1432 
1433 //-----------------------------------------------------------------------------
1434 // Function : ParameterSet::getStatusTestReturnCode
1435 // Purpose :
1436 // Special Notes :
1437 // Scope : public
1438 // Creator :
1439 // Creation Date :
1440 //-----------------------------------------------------------------------------
1442 {
1443  // Get the main Xyce Test
1444  Teuchos::RefCountPtr<N_NLS_NOX::XyceTests> testPtr =
1445  Teuchos::rcp_dynamic_cast<N_NLS_NOX::XyceTests>(tests_[1]);
1446  if (Teuchos::is_null(testPtr))
1447  {
1448  const std::string message = "N_NLS_NOX::getStatusTestReturnCode - Dynamic cast on Xyce Tests check failed.";
1449  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, message);
1450  }
1451 
1452  return testPtr->getXyceReturnCode();
1453 }
1454 
1455 //-----------------------------------------------------------------------------
1456 // Function : ParameterSet::setStatusTestReturnCode
1457 // Purpose :
1458 // Special Notes :
1459 // Scope : public
1460 // Creator :
1461 // Creation Date :
1462 //-----------------------------------------------------------------------------
1464  (const N_NLS_ReturnCodes & retCodesTmp)
1465 {
1466  // Get the main Xyce Test
1467  Teuchos::RefCountPtr<N_NLS_NOX::XyceTests> testPtr =
1468  Teuchos::rcp_dynamic_cast<N_NLS_NOX::XyceTests>(tests_[1]);
1469  if (Teuchos::is_null(testPtr))
1470  {
1471  const std::string message = "N_NLS_NOX::setStatusTestReturnCode - Dynamic cast on Xyce Tests check failed.";
1472  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, message);
1473  }
1474 
1475  return testPtr->setReturnCodes (retCodesTmp);
1476 }
1477 
1478 //-----------------------------------------------------------------------------
1479 // Function : ParameterSet::getMaxNormF
1480 // Purpose :
1481 // Special Notes :
1482 // Scope : public
1483 // Creator :
1484 // Creation Date :
1485 //-----------------------------------------------------------------------------
1487 {
1488  // Get the main Xyce Test
1489  Teuchos::RefCountPtr<N_NLS_NOX::XyceTests> testPtr =
1490  Teuchos::rcp_dynamic_cast<N_NLS_NOX::XyceTests>(tests_[1]);
1491  if (Teuchos::is_null(testPtr))
1492  {
1493  const std::string message = "N_NLS_NOX::getMaxNormF - Dynamic cast on Xyce Tests check failed.";
1494  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, message);
1495  }
1496 
1497  return testPtr->getMaxNormF();
1498 }
1499 
1500 //-----------------------------------------------------------------------------
1501 // Function : ParameterSet::getMaxNormFindex
1502 // Purpose :
1503 // Special Notes :
1504 // Scope : public
1505 // Creator :
1506 // Creation Date :
1507 //-----------------------------------------------------------------------------
1509 {
1510  // Get the main Xyce Test
1511  Teuchos::RefCountPtr<N_NLS_NOX::XyceTests> testPtr =
1512  Teuchos::rcp_dynamic_cast<N_NLS_NOX::XyceTests>(tests_[1]);
1513  if (Teuchos::is_null(testPtr))
1514  {
1515  const std::string message = "N_NLS_NOX::getMaxNormFindex - Dynamic cast on Xyce Tests check failed.";
1516  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, message);
1517  }
1518 
1519  return testPtr->getMaxNormFindex ();
1520 }
1521 
1522 //-----------------------------------------------------------------------------
1523 // Function : ParameterSet::getNoxSolverType
1524 // Purpose :
1525 // Special Notes :
1526 // Scope : public
1527 // Creator :
1528 // Creation Date :
1529 //-----------------------------------------------------------------------------
1531 {
1532  return noxSolver;
1533 }
1534 
1536 {
1537  noxSolver = type;
1538 }
1539 
1540 //-----------------------------------------------------------------------------
1541 // Function : ParameterSet::createAugmentLinearSystem
1542 // Purpose : creates an AugmentLinSys strategy object.
1543 // Special Notes :
1544 // Scope : public
1545 // Creator : Roger Pawlowski, SNL 1416
1546 // Creation Date : 03/08/06
1547 //-----------------------------------------------------------------------------
1548 Teuchos::RefCountPtr<N_NLS_NOX::AugmentLinSys>
1550 {
1551  Teuchos::RefCountPtr<N_NLS_NOX::AugmentLinSys> als;
1552 
1553  if (noxSolver == 9)
1554  {
1555  Teuchos::RefCountPtr<Epetra_MapColoring> color_map =
1556  Teuchos::rcp(ls->builder().createSolnColoring());
1557 
1558  if (voltageScaleFactor_ == 1.0)
1559  {
1560  als = Teuchos::rcp( new N_NLS_NOX::
1561  AugmentLinSysPseudoTransient(color_map,
1562  ls->getRHSVector()) );
1563  }
1564  else
1565  {
1566  als = Teuchos::rcp( new N_NLS_NOX::
1567  AugmentLinSysPseudoTransient(color_map,
1568  ls->getRHSVector(),
1569  true,
1571  }
1572 
1573  }
1574  else if(noxSolver == 1 || noxSolver == 3)
1575  {
1576  if (voltageListType_ == VLT_DOFS)
1577  {
1578  Teuchos::RefCountPtr<Epetra_MapColoring> color_map =
1579  Teuchos::rcp(ls->builder().createSolnColoring());
1580 
1581  als = Teuchos::rcp( new N_NLS_NOX::GStepping(color_map,
1582  ls->getRHSVector(),
1585  }
1586  else
1587  {
1588  als = Teuchos::rcp( new N_NLS_NOX::
1589  GStepping(ls->getQueryUtil()->vnodeGIDVec(),
1590  ls->getRHSVector(),
1593  }
1594  }
1595  else
1596  {
1597  std::string message = "N_NLS_NOX::createAugmentLinearSystem - The \'continuation\' ";
1598  message += "parameter in the .options nox list must be set to PSEUDO or NATURAL for ";
1599  message += "this function to be called!";
1600  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, message);
1601  }
1602 
1603  return als;
1604 }
1605 
1606 //-----------------------------------------------------------------------------
1607 // Function : ParameterSet::createAugmentLinearSystem
1608 // Purpose : creates an AugmentLinSys strategy object.
1609 // Special Notes :
1610 // Scope : public
1611 // Creator : Dave Shirley, PSSI
1612 // Creation Date : 05/08/06
1613 //-----------------------------------------------------------------------------
1614 Teuchos::RefCountPtr<N_NLS_NOX::AugmentLinSys>
1615 ParameterSet::createAugmentLinearSystem(N_LAS_System* ls, Xyce::NodeNamePairMap & op,
1616 #ifdef Xyce_PARALLEL_MPI
1617  const Xyce::NodeNamePairMap & allNodes, N_PDS_Comm * pdsCommPtr
1618 #else
1619  const Xyce::NodeNamePairMap & allNodes
1620 #endif
1621  ) const
1622 {
1623  Teuchos::RefCountPtr<N_NLS_NOX::AugmentLinSys> als;
1624 
1625 #ifdef Xyce_PARALLEL_MPI
1626  als = Teuchos::rcp( new N_NLS_NOX::AugmentLinSysOPStart(op, allNodes, pdsCommPtr) );
1627 #else
1628  als = Teuchos::rcp( new N_NLS_NOX::AugmentLinSysOPStart(op, allNodes) );
1629 #endif
1630 
1631  return als;
1632 }
1633 
1634 //-----------------------------------------------------------------------------
1635 // Function : ParameterSet::createAugmentLinearSystem
1636 // Purpose : creates an AugmentLinSys strategy object for .IC with
1637 // or without gmin stepping
1638 // Special Notes :
1639 // Scope : public
1640 // Creator : Eric Keiter, SNL
1641 // Creation Date : 03/08/07
1642 //-----------------------------------------------------------------------------
1643 Teuchos::RefCountPtr<N_NLS_NOX::AugmentLinSys>
1644 ParameterSet::createAugmentLinearSystem(N_LAS_System* ls, Xyce::NodeNamePairMap & op,
1645  bool gminStepping) const
1646 {
1647  Teuchos::RefCountPtr<N_NLS_NOX::AugmentLinSys> als;
1648 
1649  Teuchos::RefCountPtr<Epetra_MapColoring> ICcolor_map =
1650  Teuchos::rcp(ls->builder().createInitialConditionColoring());
1651 
1652  if (gminStepping==false)
1653  {
1654  als = Teuchos::rcp( new N_NLS_NOX::AugmentLinSysIC(op, ICcolor_map, ls->getRHSVector() ) );
1655  }
1656  else
1657  {
1658  if (voltageListType_ == VLT_DOFS)
1659  {
1660  Teuchos::RefCountPtr<Epetra_MapColoring> GMINcolor_map =
1661  Teuchos::rcp(ls->builder().createSolnColoring());
1662 
1663  als = Teuchos::rcp( new N_NLS_NOX::AugmentLinSysIC_Gmin(
1664  op,
1665  ICcolor_map,
1666  GMINcolor_map,
1667  ls->getRHSVector(),
1670  }
1671  else
1672  {
1673  als = Teuchos::rcp( new N_NLS_NOX::AugmentLinSysIC_Gmin(
1674  op,
1675  ICcolor_map,
1676  //AugmentLinSysIC_Gmin(ls->getQueryUtil()->vnodeGIDVec()),
1677  ls->getQueryUtil()->vnodeGIDVec(),
1678  ls->getRHSVector(),
1681  }
1682  }
1683 
1684  return als;
1685 }
1686 
1687 } // namespace N_NLS_NOX