Xyce  6.1
N_ANP_DCSweep.C
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2 // Copyright Notice
3 //
4 // Copyright 2002 Sandia Corporation. Under the terms
5 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
6 // Government retains certain rights in this software.
7 //
8 // Xyce(TM) Parallel Electrical Simulator
9 // Copyright (C) 2002-2015 Sandia Corporation
10 //
11 // This program is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation, either version 3 of the License, or
14 // (at your option) any later version.
15 //
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 //-----------------------------------------------------------------------------
24 
25 //-----------------------------------------------------------------------------
26 // Filename : $RCSfile: N_ANP_DCSweep.C,v $
27 // Purpose : DC Sweep class analysis functions.
28 // Special Notes :
29 // Creator : Richard Schiek, SNL, Electrical and Microsystem Modeling
30 // Creation Date : 01/24/08
31 //
32 // Revision Information:
33 // ---------------------
34 // Revision Number: $Revision: 1.146 $
35 // Revision Date : $Date: 2015/09/03 22:11:39 $
36 // Current Owner : $Author: rlschie $
37 //-----------------------------------------------------------------------------
38 #include <Xyce_config.h>
39 
40 // ---------- Standard Includes ----------
41 #include <iostream>
42 
43 // ---------- Xyce Includes ----------
44 #include <N_ANP_AnalysisManager.h>
45 #include <N_ANP_DCSweep.h>
46 #include <N_ANP_HB.h>
47 #include <N_ANP_OutputMgrAdapter.h>
48 #include <N_ANP_SweepParam.h>
49 #include <N_IO_CircuitBlock.h>
50 #include <N_IO_CmdParse.h>
51 #include <N_IO_InitialConditions.h>
52 #include <N_IO_OptionBlock.h>
53 #include <N_IO_PkgOptionsMgr.h>
54 #include <N_IO_SpiceSeparatedFieldTool.h>
55 #include <N_LOA_Loader.h>
56 #include <N_NLS_Manager.h>
57 #include <N_NLS_fwd.h>
58 #include <N_TIA_DataStore.h>
60 #include <N_TIA_StepErrorControl.h>
62 #include <N_TOP_Topology.h>
63 #include <N_UTL_Diagnostic.h>
64 #include <N_UTL_ExtendedString.h>
65 #include <N_UTL_Factory.h>
66 #include <N_UTL_FeatureTest.h>
67 #include <N_UTL_OptionBlock.h>
68 #include <N_ERH_Message.h>
69 
70 #include <Teuchos_RCP.hpp>
71 
72 namespace Xyce {
73 namespace Analysis {
74 
75 //-----------------------------------------------------------------------------
76 // Function :
77 // Purpose :
78 // Special Notes :
79 // Scope :
80 // Creator : Eric R. Keiter
81 // Creation Date :
82 //-----------------------------------------------------------------------------
84  AnalysisManager & analysis_manager,
85  Nonlinear::Manager & nonlinear_manager,
86  Loader::Loader & loader,
87  Topo::Topology & topology,
88  IO::InitialConditionsManager & initial_conditions_manager,
89  HB * hb_analysis)
90  : AnalysisBase(analysis_manager, "DC Sweep"),
91  analysisManager_(analysis_manager),
92  loader_(loader),
93  nonlinearManager_(nonlinear_manager),
94  topology_(topology),
95  initialConditionsManager_(initial_conditions_manager),
96  outputManagerAdapter_(analysis_manager.getOutputManagerAdapter()),
97  tiaParams_(),
98  hbAnalysis_(hb_analysis),
99  sensFlag_(analysis_manager.getSensFlag()),
100  dcLoopInitialized_(false),
101  dcLoopSize_(0)
102 {}
103 
104 //-----------------------------------------------------------------------------
105 // Function :
106 // Purpose :
107 // Special Notes :
108 // Scope :
109 // Creator : Eric R. Keiter
110 // Creation Date :
111 //-----------------------------------------------------------------------------
113 {}
114 
115 //-----------------------------------------------------------------------------
116 // Function : AnalysisManager::setTranOptions
117 // Purpose :
118 // Special Notes : These are from '.options timeint'
119 // Scope : public
120 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
121 // Creation Date : 04/18/02
122 //-----------------------------------------------------------------------------
124  const Util::OptionBlock & option_block)
125 {
126  for (Util::ParamList::const_iterator it = option_block.begin(), end = option_block.end(); it != end; ++it)
127  {
128  const Util::Param &param = (*it);
129 
130  if (param.uTag() == "DAESTATEDERIV")
131  analysisManager_.setDAEStateDerivFlag(static_cast<bool> (param.getImmutableValue<int>()));
132  else if (param.uTag() == "DEBUGLEVEL")
133  IO::setTimeIntegratorDebugLevel(analysisManager_.getCommandLine(), param.getImmutableValue<int>());
134  else if (nonlinearManager_.setReturnCodeOption(param))
135  ;
136  else if (tiaParams_.setTimeIntegratorOption(param))
137  ;
138  else if (setDCOPOption(param))
139  ;
140  else if (param.uTag() == "METHOD")
141  ;
142  else
143  Report::UserError() << param.uTag() << " is not a recognized time integration option";
144  }
145 
146  return true;
147 }
148 
149 
150 //-----------------------------------------------------------------------------
151 // Function : DCSweep::setAnalysisParams
152 // Purpose :
153 // Special Notes :
154 // Scope : public
155 // Creator : Eric R. Keiter, SNL
156 // Creation Date : 6/22/10
157 //-----------------------------------------------------------------------------
158 bool DCSweep::setAnalysisParams(const Util::OptionBlock & paramsBlock)
159 {
160  dcSweepVector_.push_back(parseSweepParams(paramsBlock.begin(), paramsBlock.end()));
161 
162  return true;
163 }
164 
165 //-----------------------------------------------------------------------------
166 // Function : DCSweep::outputFailureStats
167 // Purpose :
168 // Special Notes :
169 // Scope : public
170 // Creator : Eric Keiter, SNL
171 // Creation Date : 6/21/2010
172 //-----------------------------------------------------------------------------
173 bool DCSweep::outputFailureStats(std::ostream &os)
174 {
175  if (!(dcSweepFailures_.empty()))
176  {
177  os << "\tFailed DC sweep steps:\t\t" << std::endl;
178 
179  for (std::vector<int>::iterator iter = dcSweepFailures_.begin(); iter != dcSweepFailures_.end(); ++iter)
180  {
181  os << "\t\tDC Step # " << *iter << std::endl;
182  }
183  }
184  return true;
185 }
186 
187 //-----------------------------------------------------------------------------
188 // Function : DCSweep::run()
189 // Purpose : This is the main controlling loop for DC sweep analysis.
190 // This loop calls a series of operating point calculations
191 // (ie calculations in which there is no time integration,
192 // and the time integration method is always set to "none").
193 // Special Notes :
194 // Scope : public
195 // Creator : Richard Schiek, SNL, Electrical and Microsystem Modeling
196 // Creation Date : 1/28/08
197 //-----------------------------------------------------------------------------
199 {
200  return doInit() && doLoopProcess() && doFinish();
201 }
202 
203 //-----------------------------------------------------------------------------
204 // Function : DCSweep::init()
205 // Purpose :
206 // Special Notes :
207 // Scope : public
208 // Creator : Richard Schiek, SNL, Electrical and Microsystem Modeling
209 // Creation Date : 1/28/08
210 //-----------------------------------------------------------------------------
212 {
213  bool bsuccess = true;
214 
215  if (sensFlag_)
216  {
217  Stats::StatTop _sensitivityStat("Sensitivity");
218 
220  }
221 
222  // set up the various sweep variables
223  // the following should only happen once, but must be isolated to
224  // prevent a step loop outside of this dc sweep from causing to
225  // occur more often
226  if( !dcLoopInitialized_ )
227  {
228  if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
229  {
230  Xyce::dout() << std::endl << std::endl
231  << Xyce::subsection_divider << std::endl
232  << "DCSweep::run()" << std::endl;
233  }
234 
236 
239 
240  dcLoopInitialized_ = true;
241  }
242 
243  //setup for operating pt calculation
246 
247  stepNumber = 0;
249  if (getDoubleDCOPEnabled() && getDoubleDCOPStep() == 0)
250  {
252  }
253 
255 
256  return bsuccess;
257 }
258 
259 //-----------------------------------------------------------------------------
260 // Function : DCSweep::initializeSolution()
261 // Purpose : Move solution-initialization steps to separate routine so
262 // the process may be repeated cleanly when necessary.
263 // Special Notes :
264 // Scope : public
265 // Creator : Tom Russo, SNL, Electrical and Microsystem Modeling
266 // Creation Date : 2/17/2010
267 //-----------------------------------------------------------------------------
269 {
270  // set initial guess, if there is one to be set.
271  // this setInitialGuess call is to up an initial guess in the
272  // devices that have them (usually PDE devices). This is different than
273  // the "intializeProblem" call, which sets IC's. (initial conditions are
274  // different than initial guesses.
276 
277  // If available, set initial solution (.IC, .NODESET, etc).
278  // setInputOPFlag(
279  // outputManagerAdapter_.setupInitialConditions(
280  // *analysisManager_.getDataStore()->nextSolutionPtr,
281  // *analysisManager_.getDataStore()->flagSolutionPtr));
284  topology_.getSolutionNodeNameMap(),
287 
288  // Set a constant history for operating point calculation
292 }
293 
294 //-----------------------------------------------------------------------------
295 // Function : DCSweep::loopProcess()
296 // Purpose :
297 // Special Notes :
298 // Scope : public
299 // Creator : Richard Schiek, SNL, Electrical and Microsystem Modeling
300 // Creation Date : 1/28/08
301 //-----------------------------------------------------------------------------
303 {
304  static_cast<Xyce::Util::Notifier<AnalysisEvent> &>(analysisManager_).publish(AnalysisEvent(AnalysisEvent::INITIALIZE, AnalysisEvent::DC));
305 
306  int currentStep = 0;
307  int finalStep = dcLoopSize_;
308  while (currentStep < finalStep)
309  {
311 
312  if (VERBOSE_TIME)
313  {
314  printStepHeader(Xyce::dout());
316  }
317 
318  bool reset = updateSweepParams(loader_, currentStep, dcSweepVector_.begin(), dcSweepVector_.end(), true);
319 
320  // Tell the manager if any of our sweeps are being reset in this loop iteration.
322 
324 
325  if (currentStep != 0 && reset)
326  {
329  }
330 
331  // Perform the step:
332  static_cast<Xyce::Util::Notifier<AnalysisEvent> &>(analysisManager_).publish(AnalysisEvent(AnalysisEvent::STEP_STARTED, AnalysisEvent::DC, 0.0, currentStep));
333 
334 #if 0
335  Xyce::dout() << "Current Solution\n";
336  analysisManager_.getDataStore()->currSolutionPtr->printPetraObject(Xyce::dout());
337  Xyce::dout() << "Next Solution\n";
338  analysisManager_.getDataStore()->nextSolutionPtr->printPetraObject(Xyce::dout());
339 #endif
340  takeStep_();
341 
342  // Set things up for the next time step, based on if this one was
343  // successful.
345  {
346  static_cast<Xyce::Util::Notifier<AnalysisEvent> &>(analysisManager_).publish(AnalysisEvent(AnalysisEvent::STEP_SUCCESSFUL, AnalysisEvent::DC, 0.0, currentStep));
348  }
349  else // stepAttemptStatus (ie do this if the step FAILED)
350  {
351  static_cast<Xyce::Util::Notifier<AnalysisEvent> &>(analysisManager_).publish(AnalysisEvent(AnalysisEvent::STEP_FAILED, AnalysisEvent::DC, 0.0, currentStep));
353  }
354 
355  // we don't really control the loop counter here. processSuccessfulStep
356  // and processFailedStep do that work. This needs to be cleaned up. RLS
357  currentStep = stepNumber;
358  } // end of sweep loop
359 
360  static_cast<Xyce::Util::Notifier<AnalysisEvent> &>(analysisManager_).publish(AnalysisEvent(AnalysisEvent::FINISH, AnalysisEvent::DC));
361 
362  return true;
363 }
364 
365 //-----------------------------------------------------------------------------
366 // Function : DCSweep::processSuccessfulStep()
367 //
368 // Purpose : Used by both function dcSweepLoop and 2-level solve
369 // function calls to process successful DC steps.
370 // Special Notes :
371 // Scope : public
372 // Creator : Richard Schiek, SNL, Electrical and Microsystem Modeling
373 // Creation Date : 1/28/08
374 //-----------------------------------------------------------------------------
376 {
377  Stats::StatTop _processSuccessfulStepStat("Successful Step");
378  Stats::TimeBlock _processSuccessfulStepTimer(_processSuccessfulStepStat);
379 
380  loader_.stepSuccess(TWO_LEVEL_MODE_DC_SWEEP); // analysisManager_.getTwoLevelMode());
381 
382  // This output call is for device-specific output, such as .OP,
383  // or internal plot output from PDE(TCAD) devices.
385 
386  if (sensFlag_ && !firstDoubleDCOPStep() )
387  {
389  }
390 
391  // Do some statistics, as long as this isn't the first "double"
392  // DCOP step. (that one doesn't count)
393  if ( !firstDoubleDCOPStep() )
394  {
395  stepNumber += 1;
398  }
399 
400  // update the data arrays, output:
402 
403  if (DEBUG_ANALYSIS & DEBUG_TIME && isActive(Diag::TIME_DUMP_SOLUTION_ARRAYS))
405 
406  dcSweepOutput();
407 
408  // now that output has been called, update the doubleDCOP step
409  // if neccessary. (pde-only)
410  nextDCOPStep();
412 
413  return true;
414 }
415 
416 //-----------------------------------------------------------------------------
417 // Function : DCSweep::processFailedStep()
418 // Purpose :
419 // Special Notes :
420 // Scope : public
421 // Creator : Richard Schiek, SNL, Electrical and Microsystem Modeling
422 // Creation Date : 1/28/08
423 //-----------------------------------------------------------------------------
425 {
426  Stats::StatTop _processFailedStat("Failed Steps");
427  Stats::TimeBlock _processFailedTimer(_processFailedStat);
428 
430 
431  stepNumber += 1;
432  dcSweepFailures_.push_back(stepNumber);
435 
436  return true;
437 }
438 
439 //-----------------------------------------------------------------------------
440 // Function : DCSweep::doFinish()
441 // Purpose :
442 // Special Notes :
443 // Scope : public
444 // Creator : Richard Schiek, SNL, Electrical and Microsystem Modeling
445 // Creation Date : 1/28/08
446 //-----------------------------------------------------------------------------
448 {
449  bool bsuccess = true;
450 
451  if (DEBUG_ANALYSIS)
452  Xyce::dout() << "Calling DCSweep::doFinish() outputs!" << std::endl;
453 
455  if (!(dcSweepFailures_.empty()))
456  {
457  bsuccess = false;
458  }
459  return bsuccess;
460 }
461 
462 
463 //-----------------------------------------------------------------------------
464 // Function : DCSweep::doHandlePredictor
465 // Purpose :
466 // Special Notes :
467 // Scope : private
468 // Creator : Eric Keiter, SNL
469 // Creation Date : 06/24/2013
470 //-----------------------------------------------------------------------------
472 {
476 
477  // In case this is the upper level of a 2-level sim, tell the
478  // inner solve to do its prediction:
479  bool beginIntegrationFlag = analysisManager_.getBeginningIntegrationFlag(); // system_state.beginIntegrationFlag;
480  double nextTimeStep = analysisManager_.getStepErrorControl().currentTimeStep; // system_state.nextTimeStep;
481  double nextTime = analysisManager_.getStepErrorControl().nextTime; // system_state.nextTime;
482  int currentOrder = analysisManager_.getWorkingIntegrationMethod().getOrder(); // system_state.currentOrder;
483 
484  loader_.startTimeStep(beginIntegrationFlag, nextTimeStep, nextTime, currentOrder);
485 
486  return true;
487 }
488 
489 //-----------------------------------------------------------------------------
490 // Function : DCSweep::takeStep_
491 // Purpose : Take a DC Sweep integration step.
492 // Special Notes :
493 // Scope : private
494 // Creator : Richard Schiek, SNL, Electrical and Microsystem Modeling
495 // Creation Date : 01/24/08
496 //-----------------------------------------------------------------------------
498 {
499  { // Integration step predictor
500  Stats::StatTop _predictorStat("Predictor");
501  Stats::TimeBlock _predictorTimer(_predictorStat);
502 
504  }
505 
506  { // Load B/V source devices with time data
507  Stats::StatTop _updateDeviceSourceStat("Update Device Sources");
508  Stats::TimeBlock _updateDeviceSourceTimer(_updateDeviceSourceStat);
509 
511  }
512 
513  { // Nonlinear solve
514  Stats::StatTop _nonlinearSolveStat("Solve");
515  Stats::TimeBlock _nonlinearSolveTimer(_nonlinearSolveStat);
516 
518  }
519 
520  { // Add change to solution
521  Stats::StatTop _errorStat("Error Estimation");
522  Stats::TimeBlock _errorTimer(_errorStat);
523 
525 
527 
529  }
530 }
531 
532 //-----------------------------------------------------------------------------
533 // Function : DCSweep::twoLevelStep
534 //
535 // Purpose : Used by 2-level Newton solves to execute a single DC sweep
536 // step.
537 //
538 // Special Notes : This is mostly what happens on the inner loop of
539 // dcSweepLoop, except that DC parameters are not updated,
540 // and success/failure of the step is not determined.
541 //
542 // Scope : public
543 // Creator : Eric Keiter, SNL
544 // Creation Date : 03/10/06
545 //-----------------------------------------------------------------------------
547 {
553 
555 }
556 
557 //-----------------------------------------------------------------------------
558 // Function : DCSweep::dcSweepOutput
559 // Purpose :
560 // Special Notes :
561 // Scope : public
562 // Creator : Richard Schiek, SNL, Electrical and Microsystem Modeling
563 // Creation Date : 1/31/08
564 //-----------------------------------------------------------------------------
566 {
567  if (hbAnalysis_)
568  {
569  std::vector<double> timePoints, freqPoints;
570  Teuchos::RCP<Linear::BlockVector> timeDomainSolnVec;
571  Teuchos::RCP<Linear::BlockVector> freqDomainSolnVecReal;
572  Teuchos::RCP<Linear::BlockVector> freqDomainSolnVecImaginary;
573  Teuchos::RCP<Linear::BlockVector> timeDomainStoreVec;
574  Teuchos::RCP<Linear::BlockVector> freqDomainStoreVecReal;
575  Teuchos::RCP<Linear::BlockVector> freqDomainStoreVecImaginary;
576  Teuchos::RCP<Linear::BlockVector> timeDomainLeadCurrentVec;
577  Teuchos::RCP<Linear::BlockVector> freqDomainLeadCurrentVecReal;
578  Teuchos::RCP<Linear::BlockVector> freqDomainLeadCurrentVecImaginary;
579  Teuchos::RCP<Linear::BlockVector> timeDomainJunctionVoltageVec;
580  Teuchos::RCP<Linear::BlockVector> freqDomainJunctionVoltageVecReal;
581  Teuchos::RCP<Linear::BlockVector> freqDomainJunctionVoltageVecImaginary;
582 
583  // RLS Todo: Need to update HB call here
584  // for leadcurrent and junctionvoltage vector
585 
586 
589  timePoints,
590  freqPoints,
591  timeDomainSolnVec,
592  freqDomainSolnVecReal,
593  freqDomainSolnVecImaginary,
594  timeDomainStoreVec,
595  freqDomainStoreVecReal,
596  freqDomainStoreVecImaginary,
597  timeDomainLeadCurrentVec,
598  freqDomainLeadCurrentVecReal,
599  freqDomainLeadCurrentVecImaginary,
600  timeDomainJunctionVoltageVec,
601  freqDomainJunctionVoltageVecReal,
602  freqDomainJunctionVoltageVecImaginary);
603 
605  timePoints,
606  freqPoints,
607  *timeDomainSolnVec,
608  *freqDomainSolnVecReal,
609  *freqDomainSolnVecImaginary,
610  *timeDomainStoreVec,
611  *freqDomainStoreVecReal,
612  *freqDomainStoreVecImaginary,
613  *timeDomainLeadCurrentVec,
614  *freqDomainLeadCurrentVecReal,
615  *freqDomainLeadCurrentVecImaginary,
616  *timeDomainJunctionVoltageVec,
617  *freqDomainJunctionVoltageVecReal,
618  *freqDomainJunctionVoltageVecImaginary);
619  }
620 
621  // Make sure this isn't the NL_POISSON step of a PDE DCOP.
622  else if (!firstDoubleDCOPStep())
623  {
624  // conventional .PRINT output
626  stepNumber,
635 
636  // output for DCOP restart
637  // outputManagerAdapter_.outputDCOP(*analysisManager_.getDataStore()->currSolutionPtr);
639  }
640 
641 }
642 
643 //-----------------------------------------------------------------------------
644 // Function : DCSweep::printStepHeader()
645 // Purpose : Prints out time step information.
646 // Special Notes :
647 // Scope : public
648 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
649 // Creation Date : 6/26/00
650 //-----------------------------------------------------------------------------
651 void DCSweep::printStepHeader(std::ostream &os)
652 {
653  if (VERBOSE_TIME)
654  dout() << std::endl << std::endl
655  << "***** "<< (DEBUG_ANALYSIS ? analysisManager_.getNetlistFilename() : "")
656  << " Start of DCOP STEP # " << stepNumber+1
657  << std::endl << std::endl;
658 }
659 
660 //-----------------------------------------------------------------------------
661 // Function : DCSweep::printLoopInfo
662 // Purpose :
663 // Scope : public
664 // Creator : Eric Keiter
665 // Creation Date : 12/14/2010
666 //-----------------------------------------------------------------------------
667 bool DCSweep::printLoopInfo(int start, int finish)
668 {
669  bool bsuccess = AnalysisBase::printLoopInfo(start, finish);
670  if (start == 0 && finish == 0)
671  {
672  outputFailureStats(Xyce::lout());
673  }
674  return bsuccess;
675 }
676 
677 namespace {
678 
679 typedef Util::Factory<AnalysisBase, DCSweep> DCSweepFactoryBase;
680 
681 //-----------------------------------------------------------------------------
682 // Class : DCSweepFactory
683 // Purpose :
684 // Special Notes :
685 // Scope : public
686 // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
687 // Creation Date : Thu Jan 29 12:53:02 2015
688 //-----------------------------------------------------------------------------
689 ///
690 /// Factory for parsing DCSweep parameters from the netlist and creating DCSweep analysis.
691 ///
692 class DCSweepFactory : public DCSweepFactoryBase
693 {
694 public:
695  //-----------------------------------------------------------------------------
696  // Function : DCSweepFactory
697  // Purpose :
698  // Special Notes :
699  // Scope : public
700  // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
701  // Creation Date : Thu Jan 29 12:54:09 2015
702  //-----------------------------------------------------------------------------
703  ///
704  /// Constructs the DCSweep analysis factory
705  ///
706  /// @invariant Stores the results of parsing. Multiple DCSweep analysis options may be
707  /// applied and each generates and additional dcsweep.
708  ///
709  /// @invariant The existence of the parameters specified in the constructor cannot
710  /// change.
711  ///
712  /// @param analysis_manager
713  /// @param linear_system
714  /// @param nonlinear_manager
715  /// @param topology
716  ///
717  DCSweepFactory(
718  Analysis::AnalysisManager & analysis_manager,
719  Linear::System & linear_system,
720  Nonlinear::Manager & nonlinear_manager,
721  Loader::Loader & loader,
722  Topo::Topology & topology,
723  IO::InitialConditionsManager & initial_conditions_manager)
724  : DCSweepFactoryBase(),
725  analysisManager_(analysis_manager),
726  linearSystem_(linear_system),
727  nonlinearManager_(nonlinear_manager),
728  loader_(loader),
729  topology_(topology),
730  initialConditionsManager_(initial_conditions_manager),
733  {}
734 
735  virtual ~DCSweepFactory()
736  {}
737 
738  //-----------------------------------------------------------------------------
739  // Function : create
740  // Purpose :
741  // Special Notes :
742  // Scope : public
743  // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
744  // Creation Date : Thu Jan 29 12:59:00 2015
745  //-----------------------------------------------------------------------------
746  ///
747  /// Create a new DCSweep analysis and applies the analysis and time integrator option blocks.
748  ///
749  /// @return new DCSweep analysis object
750  ///
751  ///
752  DCSweep *create() const
753  {
754  analysisManager_.setAnalysisMode(ANP_MODE_DC_SWEEP);
756  for (std::vector<Util::OptionBlock>::const_iterator it = dcSweepAnalysisOptionBlock_.begin(), end = dcSweepAnalysisOptionBlock_.end(); it != end; ++it)
757  dc_sweep->setAnalysisParams(*it);
758  dc_sweep->setTimeIntegratorOptions(timeIntegratorOptionBlock_);
759 
760  return dc_sweep;
761  }
762 
763  //-----------------------------------------------------------------------------
764  // Function : setDCSweepAnalysisOptionBlock
765  // Purpose :
766  // Special Notes :
767  // Scope : public
768  // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
769  // Creation Date : Thu Jan 29 13:00:14 2015
770  //-----------------------------------------------------------------------------
771  ///
772  /// Saves the analysis parsed options block in the factory.
773  ///
774  /// @invariant Appends to any previously specified analysis option block.
775  ///
776  /// @param option_block parsed option block
777  ///
778  void setDCSweepAnalysisOptionBlock(const Util::OptionBlock &option_block)
779  {
780  for (std::vector<Util::OptionBlock>::iterator it = dcSweepAnalysisOptionBlock_.begin(), end = dcSweepAnalysisOptionBlock_.end(); it != end; ++it)
781  {
782  if (Util::compareParamLists(option_block, *it))
783  {
784  (*it) = option_block;
785  return;
786  }
787  }
788 
789  // save the new one.
790  dcSweepAnalysisOptionBlock_.push_back(option_block); // save a copy for later.
791  }
792 
793  //-----------------------------------------------------------------------------
794  // Function : setTimeIntegratorOptionBlock
795  // Purpose :
796  // Special Notes :
797  // Scope : public
798  // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
799  // Creation Date : Thu Jan 29 13:01:27 2015
800  //-----------------------------------------------------------------------------
801  ///
802  /// Saves the time integrator parsed option block.
803  ///
804  /// @invariant Overwrites any previously specified time integrator option block.
805  ///
806  /// @param option_block parsed option block
807  ///
808  bool setTimeIntegratorOptionBlock(const Util::OptionBlock &option_block)
809  {
810  timeIntegratorOptionBlock_ = option_block;
811 
812  return true;
813  }
814 
815 public:
816  AnalysisManager & analysisManager_;
817  Linear::System & linearSystem_;
818  Nonlinear::Manager & nonlinearManager_;
819  Loader::Loader & loader_;
820  Topo::Topology & topology_;
821  IO::InitialConditionsManager & initialConditionsManager_;
822 
823 private:
824  std::vector<Util::OptionBlock> dcSweepAnalysisOptionBlock_;
825  Util::OptionBlock timeIntegratorOptionBlock_;
826 };
827 
828 
829 // .DC
830 struct DCSweepAnalysisReg : public IO::PkgOptionsReg
831 {
832  DCSweepAnalysisReg(
833  DCSweepFactory & factory)
834  : factory_(factory)
835  {}
836 
837  bool operator()(const Util::OptionBlock &option_block)
838  {
839  factory_.setDCSweepAnalysisOptionBlock(option_block);
840 
841  factory_.analysisManager_.addAnalysis(&factory_);
842 
843  return true;
844  }
845 
846  DCSweepFactory & factory_;
847 };
848 
849 //-----------------------------------------------------------------------------
850 // Function : extractDCData
851 // Purpose : Determine number of sweep variables on this DC line
852 // : and create option blocks for each, storing the blocks
853 // : in the referenced vector.
854 //-----------------------------------------------------------------------------
855 bool
856 extractDCData(
857  IO::PkgOptionsMgr & options_manager,
858  IO::CircuitBlock & circuit_block,
859  const std::string & netlist_filename,
860  const IO::TokenVector & parsed_line)
861 {
862  // length of the original .DC line
863  int numFields = parsed_line.size();
864 
865  // number of sweep sources on this line, and index to current source
866  int sourcesFound = 0;
867 
868  // start of parameters (skip over the ".DC")
869  int linePosition = 1;
870 
871  // line can be variable in length, with muliple sources to a line
872  while( linePosition < numFields )
873  {
874  Util::OptionBlock option_block("DC", Util::OptionBlock::ALLOW_EXPRESSIONS, netlist_filename, parsed_line[linePosition].lineNumber_);
875 
876  if (linePosition + 1 == numFields) {
877  Report::UserError0().at(netlist_filename, parsed_line[linePosition].lineNumber_) << "Extraneous values on .DC line";
878  break;
879  }
880 
881  std::string stringVal = parsed_line[linePosition + 1].string_;
882  Util::toUpper(stringVal);
883 
884  std::string curr = parsed_line[linePosition].string_;
885  Util::toUpper(curr);
886 
887  if ("LIST" == stringVal || "LIST" == curr)
888  {
889  // sweep type is LIST, get sweep variable name and move to just before beginning of list
890  option_block.addParam(Util::Param("TYPE", "LIST"));
891  option_block.addParam(Util::Param("PARAM", curr == "LIST" ? stringVal : curr));
892  ++linePosition;
893 
894  // collect values in this list until next sweep variable name is found
895  while (++linePosition < numFields && Util::isValue(parsed_line[linePosition].string_))
896  option_block.addParam(Util::Param("VAL", parsed_line[linePosition].string_));
897  }
898  else
899  {
900  std::string sweepStepTag;
901 
902  // check for non-LIST default (LINear sweep)
903  if (Util::isValue(stringVal))
904  {
905  sweepStepTag = "STEP";
906  stringVal = "LIN";
907  }
908 
909  // non-LIST sweep type is given
910  else
911  {
912  // get sweep type name and move to sweep variable name
913  stringVal = parsed_line[linePosition++].string_;
914  Util::toUpper(stringVal);
915 
916  // change sweep step tag
917  sweepStepTag = "NUMSTEPS";
918  }
919 
920  // Add the type (which was determined above) to the parameter list.
921  option_block.addParam(Util::Param("TYPE", stringVal));
922 
923  // simple check for expected four items; semantic errors pass through
924  if( numFields <= linePosition + 3 )
925  {
926  Report::UserError0().at(netlist_filename, parsed_line[0].lineNumber_)
927  << ".DC line not formatted correctly, found unexpected number of fields";
928  linePosition = numFields;
929  }
930  else {
931  option_block.addParam(Util::Param("PARAM", parsed_line[linePosition++].string_));
932  option_block.addParam(Util::Param("START", parsed_line[linePosition++].string_));
933  option_block.addParam(Util::Param("STOP", parsed_line[linePosition++].string_));
934  option_block.addParam(Util::Param(sweepStepTag, parsed_line[linePosition++].string_));
935  }
936  }
937 
938  circuit_block.addOptions(option_block);
939 
940  // record this source (and move on to the next)
941  ++sourcesFound;
942  }
943 
944  return sourcesFound;
945 }
946 
947 //-----------------------------------------------------------------------------
948 // Function : extractOPData
949 // Purpose : Extract the parameters from a netlist .OP line held in
950 // parsed_line.
951 // Special Notes :
952 // Scope : public
953 // Creator : Lon Waters, SNL
954 // Creation Date : 10/05/2001
955 //-----------------------------------------------------------------------------
956 bool
957 extractOPData(
958  IO::PkgOptionsMgr & options_manager,
959  IO::CircuitBlock & circuit_block,
960  const std::string & netlist_filename,
961  const IO::TokenVector & parsed_line)
962 {
963  Util::OptionBlock option_block("OP", Util::OptionBlock::NO_EXPRESSIONS, netlist_filename, parsed_line[0].lineNumber_);
964 
965  int numFields = parsed_line.size();
966 
967  // Check that the minimum required number of fields are on the line.
968  if ( numFields > 1 )
969  {
970  Report::UserWarning0().at(netlist_filename, parsed_line[0].lineNumber_) << "Ignoring extra fields on .OP line";
971  }
972 
973  circuit_block.addOptions(option_block);
974 
975  return true;
976 }
977 
978 } // namespace <unnamed>
979 
980 bool
982  FactoryBlock & factory_block)
983 {
984  DCSweepFactory *factory = new DCSweepFactory(factory_block.analysisManager_, factory_block.linearSystem_, factory_block.nonlinearManager_, factory_block.loader_, factory_block.topology_, factory_block.initialConditionsManager_);
985 
986  addAnalysisFactory(factory_block, factory);
987 
988  factory_block.optionsManager_.addCommandParser(".DC", extractDCData);
989  factory_block.optionsManager_.addCommandParser(".OP", extractOPData);
990 
991  factory_block.optionsManager_.addCommandProcessor("DC", new DCSweepAnalysisReg(*factory));
992 
993  factory_block.optionsManager_.addOptionsProcessor("TIMEINT", IO::createRegistrationOptions(*factory, &DCSweepFactory::setTimeIntegratorOptionBlock));
994 
995  return true;
996 }
997 
998 } // namespace Analysis
999 } // namespace Xyce
bool enableSensitivity(TimeIntg::DataStore &data_store, Parallel::Manager &parallel_manager, Topo::Topology &topology)
int setupSweepLoop(Parallel::Machine comm, Loader::Loader &loader, std::vector< SweepParam >::iterator begin, std::vector< SweepParam >::iterator end)
unsigned int successfulStepsTaken_
Number of consecutive successful time-integration steps.
virtual bool setInitialGuess(Linear::Vector *solVectorPtr)
Definition: N_LOA_Loader.h:232
bool setTimeIntegratorOption(const Util::Param &param)
bool printLoopInfo(int start, int finish)
bool calcSensitivity(std::vector< double > &objectiveVec, std::vector< double > &dOdpVec, std::vector< double > &dOdpAdjVec, std::vector< double > &scaled_dOdpVec, std::vector< double > &scaled_dOdpAdjVec)
AnalysisManager & analysisManager_
void evaluateStepError(const Loader::Loader &loader, const TIAParams &tia_params)
std::vector< double > objectiveVec_
Pure virtual class to augment a linear system.
virtual void stepFailure(Analysis::TwoLevelMode analysis)
Definition: N_LOA_Loader.h:287
virtual bool outputPlotFiles() const
Definition: N_LOA_Loader.h:261
std::vector< double > dOdpVec_
unsigned int stepNumber
Time-integration step number counter.
void outputSolDataArrays(std::ostream &os)
Linear::Vector * currStorePtr
IO::InitialConditionsManager & initialConditionsManager_
DCSweep(AnalysisManager &analysis_manager, Nonlinear::Manager &nonlinear_manager, Loader::Loader &loader, Topo::Topology &topology, IO::InitialConditionsManager &initial_conditions_manager, HB *hb_analysis=0)
Definition: N_ANP_DCSweep.C:83
bool updateSweepParams(Loader::Loader &loader, int step_count, std::vector< SweepParam >::iterator begin, std::vector< SweepParam >::iterator end, bool overrideOriginal)
void gatherStepStatistics(StatCounts &stats, Nonlinear::NonLinearSolver &nonlinear_solver, int newton_convergence_status)
OutputMgrAdapter & outputManagerAdapter_
void createTimeIntegratorMethod(const TimeIntg::TIAParams &tia_params, const unsigned int integration_method)
virtual int getDoubleDCOPStep() const
Parallel::Machine getComm() const
void setAnalysisMode(AnalysisMode mode)
Linear::Vector * currStatePtr
unsigned int failedStepsAttempted_
Total number of failed time-integration steps.
Parallel::Manager * getPDSManager() const
Topo::Topology & topology_
bool setDCOPOption(const Util::Param &param)
TimeIntg::StepErrorControl & getStepErrorControl()
const std::string & getNetlistFilename() const
std::vector< int > dcSweepFailures_
bool outputFailureStats(std::ostream &os)
NonLinearSolver & getNonlinearSolver()
std::vector< double > dOdpAdjVec_
void prepareHBOutput(Linear::Vector &solnVecPtr, std::vector< double > &timePoints, std::vector< double > &freqPoints, Teuchos::RCP< Linear::BlockVector > &timeDomainSolnVec, Teuchos::RCP< Linear::BlockVector > &freqDomainSolnVecReal, Teuchos::RCP< Linear::BlockVector > &freqDomainSolnVecImaginary, Teuchos::RCP< Linear::BlockVector > &timeDomainStoreVec, Teuchos::RCP< Linear::BlockVector > &freqDomainStoreVecReal, Teuchos::RCP< Linear::BlockVector > &freqDomainStoreVecImaginary, Teuchos::RCP< Linear::BlockVector > &timeDomainLeadCurrentVec, Teuchos::RCP< Linear::BlockVector > &freqDomainLeadCurrentVecReal, Teuchos::RCP< Linear::BlockVector > &freqDomainLeadCurrentVecImaginary, Teuchos::RCP< Linear::BlockVector > &timeDomainJunctionVoltageVec, Teuchos::RCP< Linear::BlockVector > &freqDomainJunctionVoltageVecReal, Teuchos::RCP< Linear::BlockVector > &freqDomainJunctionVoltageVecImaginary)
Definition: N_ANP_HB.C:825
std::vector< double > scaled_dOdpAdjVec_
bool setTimeIntegratorOptions(const Util::OptionBlock &option_block)
Nonlinear::Manager & nonlinearManager_
virtual bool startTimeStep(bool beginIntegrationFlag, double nextTimeStep, double nextTime, int currentOrder)
Definition: N_LOA_Loader.h:305
void setErrorWtVector(const TIAParams &tia_params)
Nonlinear::Manager & nonlinearManager_
virtual bool isPDESystem() const
Definition: N_LOA_Loader.h:256
The FactoryBlock contains parameters needed by the analysis creation functions.
Loader::Loader & loader_
IO::InitialConditionsManager & initialConditionsManager_
Util::OptionBlock timeIntegratorOptionBlock_
Nonlinear::AnalysisMode nonlinearAnalysisMode(Mode mode)
Returns the nonlinear analysis mode given the analysis mode.
void setDCSweepVector(const Analysis::SweepVector &sweep_vector)
DCSweepFactory & factory_
virtual bool updateSources()
Definition: N_LOA_Loader.h:244
Linear::Vector * currLeadCurrentQDerivPtr
void printStepHeader(std::ostream &os)
virtual bool printLoopInfo(int start, int finish)
SweepParam parseSweepParams(Util::ParamList::const_iterator first, Util::ParamList::const_iterator last)
Populate the sweep params from the parameter list.
Linear::Vector * currLeadDeltaVPtr
void setDoubleDCOPEnabled(bool enable)
Nonlinear::Manager & nonlinearManager_
std::vector< double > scaled_dOdpVec_
AnalysisManager & analysisManager_
Linear::Vector * nextSolutionPtr
void dcOutput(int dcStepNumber, Linear::Vector &currSolutionPtr, Linear::Vector &stateVecPtr, Linear::Vector &storeVecPtr, Linear::Vector &lead_current_vector, Linear::Vector &junction_voltage_vector, Linear::Vector &lead_current_dqdt_vector, std::vector< double > &objectiveVec_, std::vector< double > &dOdpVec_, std::vector< double > &dOdpAdjVec_, std::vector< double > &scaled_dOdpVec_, std::vector< double > &scaled_dOdpAdjVec_)
TimeIntg::TIAParams tiaParams_
void addAnalysisFactory(FactoryBlock &factory_block, Util::Factory< AnalysisBase, void > *factory)
Linear::Vector * currLeadCurrentPtr
void setInputOPFlag(bool initial_conditions_loaded)
TimeIntg::WorkingIntegrationMethod & getWorkingIntegrationMethod()
const IO::CmdParse & getCommandLine() const
Linear::Vector * currSolutionPtr
TimeIntg::DataStore * getDataStore()
unsigned int baseIntegrationMethod_
Current time-integration method flag.
Linear::System & linearSystem_
bool registerDCSweepFactory(FactoryBlock &factory_block)
virtual void stepSuccess(Analysis::TwoLevelMode analysis)
Definition: N_LOA_Loader.h:284
void outputHB(const std::vector< double > &timePoints, const std::vector< double > &freqPoints, const Linear::BlockVector &timeDomainSolnVec, const Linear::BlockVector &freqDomainSolnVecReal, const Linear::BlockVector &freqDomainSolnVecImaginary, const Linear::BlockVector &timeDomainStoreVec, const Linear::BlockVector &freqDomainStoreVecReal, const Linear::BlockVector &freqDomainStoreVecImaginary, const Linear::BlockVector &timeDomainLeadCurrentVec, const Linear::BlockVector &freqDomainLeadCurrentVecReal, const Linear::BlockVector &freqDomainLeadCurrentVecImaginary, const Linear::BlockVector &timeDomainJunctionVoltageVec, const Linear::BlockVector &freqDomainJunctionVoltageVecReal, const Linear::BlockVector &freqDomainJunctionVoltageVecImaginary)
std::vector< Util::OptionBlock > dcSweepAnalysisOptionBlock_
Linear::Vector * flagSolutionPtr
bool setAnalysisParams(const Util::OptionBlock &paramsBlock)
Loader::Loader & loader_
bool setReturnCodeOption(const Util::Param &param)
IO::InitialConditionsManager & initialConditionsManager_
Topo::Topology & topology_