Xyce  6.1
N_ANP_Step.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_Step.C,v $
27 // Purpose : .STEP 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.83 $
35 // Revision Date : $Date: 2015/07/02 13:00:10 $
36 // Current Owner : $Author: dgbaur $
37 //-----------------------------------------------------------------------------
38 #include <Xyce_config.h>
39 
40 #include <N_ANP_AnalysisManager.h>
41 #include <N_ANP_OutputMgrAdapter.h>
42 #include <N_ANP_SweepParam.h>
43 #include <N_ANP_Step.h>
44 #include <N_ANP_StepEvent.h>
45 #include <N_ERH_Message.h>
46 #include <N_IO_CircuitBlock.h>
47 #include <N_IO_CmdParse.h>
48 #include <N_IO_OptionBlock.h>
49 #include <N_IO_PkgOptionsMgr.h>
50 #include <N_IO_SpiceSeparatedFieldTool.h>
51 #include <N_PDS_Manager.h>
52 #include <N_TIA_StepErrorControl.h>
53 #include <N_TIA_DataStore.h>
54 #include <N_UTL_Diagnostic.h>
55 #include <N_UTL_ExtendedString.h>
56 #include <N_UTL_Factory.h>
57 #include <N_UTL_FeatureTest.h>
58 #include <N_UTL_OptionBlock.h>
59 #include <N_UTL_Timer.h>
60 
61 namespace Xyce {
62 namespace Analysis {
63 
64 //-----------------------------------------------------------------------------
65 // Function : Step::setAnalysisParams
66 // Purpose :
67 // Special Notes :
68 // Scope : public
69 // Creator : Eric R. Keiter, SNL
70 // Creation Date : 6/22/10
71 //-----------------------------------------------------------------------------
72 bool
73 Step::setAnalysisParams(const Util::OptionBlock & paramsBlock)
74 {
75  stepSweepVector_.push_back(parseSweepParams(paramsBlock.begin(), paramsBlock.end()));
77 
78  return true;
79 }
80 
81 const TimeIntg::TIAParams &
83 {
85 }
86 
89 {
91 }
92 
93 //-----------------------------------------------------------------------------
94 // Function : Step::getDCOPFlag()
95 // Purpose :
96 //
97 // Special Notes :
98 // Scope : public
99 // Creator : Eric Keiter, SNL
100 // Creation Date : 3/24/2014
101 //-----------------------------------------------------------------------------
102 bool Step::getDCOPFlag() const
103 {
104  return childAnalysis_.getDCOPFlag();
105 }
106 
107 //-----------------------------------------------------------------------------
108 // Function : Step::run()
109 // Purpose : This is the main controlling loop for Step analysis.
110 //
111 // Special Notes :
112 // Scope : public
113 // Creator : Eric Keiter, SNL
114 // Creation Date : 10/04/00
115 //-----------------------------------------------------------------------------
117 {
118  return doInit() && doLoopProcess() && doFinish();
119 }
120 
121 //-----------------------------------------------------------------------------
122 // Function : Step::init()
123 // Purpose :
124 // Special Notes :
125 // Scope : public
126 // Creator : Eric Keiter, SNL
127 // Creation Date : 03/10/06
128 //-----------------------------------------------------------------------------
130 {
131  if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
132  {
133  Xyce::dout() << std::endl << std::endl;
134  Xyce::dout() << section_divider << std::endl;
135  Xyce::dout() << "Step::init" << std::endl;
136  }
137 
139 
141 
142  return true;
143 }
144 
145 
146 //-----------------------------------------------------------------------------
147 // Function : Step::loopProcess()
148 // Purpose :
149 // Special Notes :
150 // Scope : public
151 // Creator : Eric Keiter, SNL
152 // Creation Date : 03/10/06
153 //-----------------------------------------------------------------------------
155 {
156  bool integration_status = true;
157 
158  for (int i = 0; i < stepLoopSize_; ++i)
159  {
160  // Tell the manager if any of our sweeps are being reset in this loop iteration.
161  bool reset = updateSweepParams(loader_, i, stepSweepVector_.begin(), stepSweepVector_.end(), false);
162 
164 
166 
167  if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
168  {
169  for (SweepVector::const_iterator it = stepSweepVector_.begin(), end = stepSweepVector_.end(); it != end; ++it)
170  {
171  Xyce::dout() << "Step Analysis # " << i<<"\t";
172  Xyce::dout() << (*it);
173  }
174  }
175 
177  Util::publish<StepEvent>(analysisManager_, step_event);
178 
179  // solve the loop.
180  integration_status = childAnalysis_.run();
181 
182  step_event.state_ = StepEvent::STEP_COMPLETED;
183  step_event.finalSimTime_ = getTIAParams().finalTime;
184  Util::publish<StepEvent>(analysisManager_, step_event);
185  }
186 
187  return integration_status;
188 }
189 
190 //-----------------------------------------------------------------------------
191 // Function : Step::processSuccessfulStep()
192 // Purpose :
193 // Special Notes :
194 // Scope : public
195 // Creator : Eric Keiter, SNL
196 // Creation Date : 03/10/06
197 //-----------------------------------------------------------------------------
199 {
200  return true;
201 }
202 
203 //-----------------------------------------------------------------------------
204 // Function : Step::processFailedStep()
205 // Purpose :
206 // Special Notes :
207 // Scope : public
208 // Creator : Eric Keiter, SNL
209 // Creation Date : 03/10/06
210 //-----------------------------------------------------------------------------
212 {
213  return true;
214 }
215 
216 
217 //-----------------------------------------------------------------------------
218 // Function : Step::doFinish()
219 // Purpose :
220 // Special Notes :
221 // Scope : public
222 // Creator : Eric Keiter, SNL
223 // Creation Date : 03/10/06
224 //-----------------------------------------------------------------------------
226 {
228 
229  return true;
230 }
231 
232 namespace {
233 
234 //-----------------------------------------------------------------------------
235 // Class : StepFactory
236 // Purpose :
237 // Special Notes :
238 // Scope : public
239 // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
240 // Creation Date : Thu Jan 29 12:53:02 2015
241 //-----------------------------------------------------------------------------
242 ///
243 /// Factory for parsing Step parameters from the netlist and creating Step analysis.
244 ///
245 class StepFactory : public Util::Factory<AnalysisBase, Step>
246 {
247 public:
248  //-----------------------------------------------------------------------------
249  // Function : StepFactory
250  // Purpose :
251  // Special Notes :
252  // Scope : public
253  // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
254  // Creation Date : Thu Jan 29 12:54:09 2015
255  //-----------------------------------------------------------------------------
256  ///
257  /// Constructs the Step analysis factory
258  ///
259  /// @invariant Stores the results of parsing. Multiple Step analysis options may be
260  /// applied and each generates and additional step.
261  ///
262  /// @invariant The existence of the parameters specified in the constructor cannot
263  /// change.
264  ///
265  /// @param analysis_manager
266  /// @param linear_system
267  /// @param nonlinear_manager
268  ///
269  StepFactory(
270  Analysis::AnalysisManager & analysis_manager,
271  Linear::System & linear_system,
272  Nonlinear::Manager & nonlinear_manager,
273  Loader::Loader & loader)
274  : Util::Factory<AnalysisBase, Step>(),
275  analysisManager_(analysis_manager),
276  linearSystem_(linear_system),
277  nonlinearManager_(nonlinear_manager),
278  loader_(loader)
279  {}
280 
281  virtual ~StepFactory()
282  {}
283 
284  //-----------------------------------------------------------------------------
285  // Function : create
286  // Purpose :
287  // Special Notes :
288  // Scope : public
289  // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
290  // Creation Date : Thu Jan 29 12:59:00 2015
291  //-----------------------------------------------------------------------------
292  ///
293  /// Create a new Step analysis and applies the analysis and time integrator option blocks.
294  ///
295  /// @return new Step analysis object
296  ///
297  Step *create() const
298  {
299  Step *step = new Step(analysisManager_, loader_, analysisManager_.getAnalysisObject());
300  for (std::vector<Util::OptionBlock>::const_iterator it = stepSweepAnalysisOptionBlock_.begin(), end = stepSweepAnalysisOptionBlock_.end(); it != end; ++it)
301  step->setAnalysisParams(*it);
302 
303  return step;
304  }
305 
306  //-----------------------------------------------------------------------------
307  // Function : setStepAnalysisOptionBlock
308  // Purpose :
309  // Special Notes :
310  // Scope : public
311  // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
312  // Creation Date : Thu Jan 29 13:00:14 2015
313  //-----------------------------------------------------------------------------
314  ///
315  /// Saves the analysis parsed options block in the factory.
316  ///
317  /// @invariant Appends to any previously specified analysis option block.
318  ///
319  /// @param option_block parsed option block
320  ///
321  void setStepAnalysisOptionBlock(const Util::OptionBlock &option_block)
322  {
323  for (std::vector<Util::OptionBlock>::iterator it = stepSweepAnalysisOptionBlock_.begin(), end = stepSweepAnalysisOptionBlock_.end(); it != end; ++it)
324  {
325  if (Util::compareParamLists(option_block, *it))
326  {
327  (*it) = option_block;
328  return;
329  }
330  }
331 
332  // save the new one.
333  stepSweepAnalysisOptionBlock_.push_back(option_block); // save a copy for later.
334  }
335 
336 public:
337  AnalysisManager & analysisManager_;
338  Linear::System & linearSystem_;
339  Nonlinear::Manager & nonlinearManager_;
340  Loader::Loader & loader_;
341 
342 private:
343  std::vector<Util::OptionBlock> stepSweepAnalysisOptionBlock_;
344 };
345 
346 // .STEP
347 struct StepAnalysisReg : public IO::PkgOptionsReg
348 {
349  StepAnalysisReg(
350  StepFactory & factory)
351  : factory_(factory)
352  {}
353 
354  bool operator()(const Util::OptionBlock &option_block)
355  {
356  factory_.setStepAnalysisOptionBlock(option_block);
357 
358  factory_.analysisManager_.addAnalysis(&factory_);
359 
360  return true;
361  }
362 
363  StepFactory & factory_;
364 };
365 
366 //-----------------------------------------------------------------------------
367 // Function : extractSTEPData
368 // Purpose : Extract the parameters from a netlist .STEP line held in
369 // parsed_line.
370 // Special Notes :
371 // Scope : public
372 // Creator : Eric R. Keiter, SNL
373 // Creation Date : 10/30/2003
374 //-----------------------------------------------------------------------------
375 bool
376 extractSTEPData(
377  IO::PkgOptionsMgr & options_manager,
378  IO::CircuitBlock & circuit_block,
379  const std::string & netlist_filename,
380  const IO::TokenVector & parsed_line)
381 {
382  Util::OptionBlock option_block("STEP", Util::OptionBlock::NO_EXPRESSIONS, netlist_filename, parsed_line[0].lineNumber_);
383 
384  int numFields = parsed_line.size();
385 
386  // First check if the type has been explicitly set.
387  // If not, set it to the default, LIN.
388  int pos1=1;
389 
390  bool typeExplicitSetLinDecOct = false;
391  bool typeExplicitSetList = false;
392  std::string type("LIN");
393  while ( pos1 < numFields )
394  {
395  ExtendedString stringVal ( parsed_line[pos1].string_ );
396  stringVal.toUpper ();
397  if (stringVal == "LIN" ||
398  stringVal == "DEC" ||
399  stringVal == "OCT")
400  {
401  typeExplicitSetLinDecOct = true;
402  type = stringVal;
403  }
404  else if (stringVal == "LIST")
405  {
406  typeExplicitSetList = true;
407  type = stringVal;
408  }
409 
410  ++pos1;
411  }
412 
413  // Check that the minimum required number of fields are on the line.
414  int offset = 1;
415  if (typeExplicitSetLinDecOct)
416  {
417  offset = 2;
418  }
419 
420  if (!typeExplicitSetList)// if this is a list, number of fields is arbitrary.
421  {
422  if ( (numFields-offset)%4 != 0 )
423  {
424  Report::UserError0().at(netlist_filename, parsed_line[0].lineNumber_)
425  << ".STEP line not formatted correctly.";
426  return false;
427  }
428  }
429 
430  int linePosition = 1; // Start of parameters on .param line.
431  Util::Param parameter("", "");
432 
433  // Add the type (which was determined above) to the parameter list.
434  parameter.setTag( "TYPE" );
435  parameter.setVal( type );
436  option_block.addParam( parameter );
437 
438  if (type=="LIN")
439  {
440  if (typeExplicitSetLinDecOct) linePosition=2;
441  while ( linePosition < numFields )
442  {
443  parameter.setTag( "PARAM" );
444  parameter.setVal(std::string(ExtendedString(parsed_line[linePosition].string_).toUpper()));
445  option_block.addParam( parameter );
446  ++linePosition; // Advance to next parameter.
447 
448  parameter.setTag( "START" );
449  parameter.setVal( parsed_line[linePosition].string_ );
450  option_block.addParam( parameter );
451  ++linePosition; // Advance to next parameter.
452 
453  parameter.setTag( "STOP" );
454  parameter.setVal( parsed_line[linePosition].string_ );
455  option_block.addParam( parameter );
456  ++linePosition; // Advance to next parameter.
457 
458  parameter.setTag( "STEP" );
459  parameter.setVal( parsed_line[linePosition].string_ );
460  option_block.addParam( parameter );
461  ++linePosition; // Advance to next parameter.
462  }
463  }
464  else if (type=="DEC")
465  {
466  if (typeExplicitSetLinDecOct) linePosition=2;
467 
468  while ( linePosition < numFields )
469  {
470  parameter.setTag( "PARAM" );
471  parameter.setVal(std::string(ExtendedString(parsed_line[linePosition].string_).toUpper()));
472  option_block.addParam( parameter );
473  ++linePosition; // Advance to next parameter.
474 
475  parameter.setTag( "START" );
476  parameter.setVal( parsed_line[linePosition].string_ );
477  option_block.addParam( parameter );
478  ++linePosition; // Advance to next parameter.
479 
480  parameter.setTag( "STOP" );
481  parameter.setVal( parsed_line[linePosition].string_ );
482  option_block.addParam( parameter );
483  ++linePosition; // Advance to next parameter.
484 
485  parameter.setTag( "NUMSTEPS" );
486  parameter.setVal( parsed_line[linePosition].string_ );
487  option_block.addParam( parameter );
488  ++linePosition; // Advance to next parameter.
489  }
490  }
491  else if (type=="OCT")
492  {
493  if (typeExplicitSetLinDecOct) linePosition=2;
494 
495  while ( linePosition < numFields )
496  {
497  parameter.setTag( "PARAM" );
498  parameter.setVal(std::string(ExtendedString(parsed_line[linePosition].string_).toUpper()));
499  option_block.addParam( parameter );
500  ++linePosition; // Advance to next parameter.
501 
502  parameter.setTag( "START" );
503  parameter.setVal( parsed_line[linePosition].string_ );
504  option_block.addParam( parameter );
505  ++linePosition; // Advance to next parameter.
506 
507  parameter.setTag( "STOP" );
508  parameter.setVal( parsed_line[linePosition].string_ );
509  option_block.addParam( parameter );
510  ++linePosition; // Advance to next parameter.
511 
512  parameter.setTag( "NUMSTEPS" );
513  parameter.setVal( parsed_line[linePosition].string_ );
514  option_block.addParam( parameter );
515  ++linePosition; // Advance to next parameter.
516  }
517  }
518 
519  else if (type=="LIST")
520  {
521  parameter.setTag( "PARAM" );
522  parameter.setVal(std::string(ExtendedString(parsed_line[1].string_).toUpper()));
523  option_block.addParam( parameter );
524 
525  int linePosition=3;
526  while (linePosition<numFields)
527  {
528  parameter.setTag( "VAL" );
529  parameter.setVal( parsed_line[linePosition].string_ );
530  option_block.addParam( parameter );
531  ++linePosition;
532  }
533  }
534 
535  else
536  {
537  Report::UserError0().at(netlist_filename, parsed_line[0].lineNumber_)
538  << ".STEP line contains an unrecognized type";
539  }
540 
541  circuit_block.addOptions(option_block);
542 
543  return true;
544 }
545 
546 } // namespace <unnamed>
547 
548 
549 bool
551  FactoryBlock & factory_block)
552 {
553  StepFactory *factory = new StepFactory(factory_block.analysisManager_, factory_block.linearSystem_, factory_block.nonlinearManager_, factory_block.loader_);
554 
555  addAnalysisFactory(factory_block, factory);
556 
557  factory_block.optionsManager_.addCommandParser(".STEP", extractSTEPData);
558 
559  factory_block.optionsManager_.addCommandProcessor("STEP", new StepAnalysisReg(*factory));
560 
561  return true;
562 }
563 
564 } // namespace Analysis
565 } // namespace Xyce
int setupSweepLoop(Parallel::Machine comm, Loader::Loader &loader, std::vector< SweepParam >::iterator begin, std::vector< SweepParam >::iterator end)
Loader::Loader & loader_
Definition: N_ANP_Step.C:340
virtual const TimeIntg::TIAParams & getTIAParams() const =0
virtual bool doProcessFailedStep()
Definition: N_ANP_Step.C:211
Pure virtual class to augment a linear system.
StepFactory & factory_
Definition: N_ANP_Step.C:363
AnalysisBase & childAnalysis_
Definition: N_ANP_Step.h:101
bool updateSweepParams(Loader::Loader &loader, int step_count, std::vector< SweepParam >::iterator begin, std::vector< SweepParam >::iterator end, bool overrideOriginal)
Nonlinear::Manager & nonlinearManager_
Definition: N_ANP_Step.C:339
double finalTime
End time for simulation.
Parallel::Machine getComm() const
SweepVector stepSweepVector_
Definition: N_ANP_Step.h:102
virtual bool doProcessSuccessfulStep()
Definition: N_ANP_Step.C:198
virtual bool doInit()
Definition: N_ANP_Step.C:129
void setStepSweepVector(const Analysis::SweepVector &sweep_vector)
virtual bool doFinish()
Definition: N_ANP_Step.C:225
virtual bool getDCOPFlag() const
Definition: N_ANP_Step.C:102
virtual bool getDCOPFlag() const =0
The FactoryBlock contains parameters needed by the analysis creation functions.
bool registerStepFactory(FactoryBlock &factory_block)
Definition: N_ANP_Step.C:550
std::vector< Util::OptionBlock > stepSweepAnalysisOptionBlock_
Definition: N_ANP_Step.C:343
Linear::System & linearSystem_
Definition: N_ANP_Step.C:338
SweepParam parseSweepParams(Util::ParamList::const_iterator first, Util::ParamList::const_iterator last)
Populate the sweep params from the parameter list.
bool setAnalysisParams(const Util::OptionBlock &paramsBlock)
Definition: N_ANP_Step.C:73
Nonlinear::Manager & nonlinearManager_
TimeIntegrationMethod *(* Factory)(const TIAParams &tia_params, StepErrorControl &step_error_control, DataStore &data_store)
AnalysisManager & analysisManager_
Definition: N_ANP_Step.h:98
void addAnalysisFactory(FactoryBlock &factory_block, Util::Factory< AnalysisBase, void > *factory)
Loader::Loader & loader_
Definition: N_ANP_Step.h:99
OutputMgrAdapter & outputManagerAdapter_
Definition: N_ANP_Step.h:100
virtual bool doLoopProcess()
Definition: N_ANP_Step.C:154
virtual bool doRun()
Definition: N_ANP_Step.C:116
AnalysisManager & analysisManager_
Definition: N_ANP_Step.C:337
const TimeIntg::TIAParams & getTIAParams() const
Definition: N_ANP_Step.C:82