Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_ANP_HB.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_ANP_HB.C,v $
27 // Purpose : HB analysis functions.
28 // Special Notes :
29 // Creator : Todd Coffey, 1414, Ting Mei, 1437
30 // Creation Date : 07/23/08
31 //
32 // Revision Information:
33 // ---------------------
34 // Revision Number: $Revision: 1.60 $
35 // Revision Date : $Date: 2014/02/24 23:49:12 $
36 // Current Owner : $Author: tvrusso $
37 //-----------------------------------------------------------------------------
38 #include <Xyce_config.h>
39 
40 #include <N_ANP_AnalysisManager.h>
41 #include <N_ANP_HB.h>
42 #include <N_ANP_Transient.h>
43 #include <N_ANP_DCSweep.h>
44 #include <N_ANP_Report.h>
45 #include <N_MPDE_Manager.h>
46 #include <N_MPDE_Discretization.h>
47 
49 #include <N_TIA_DataStore.h>
50 
51 #include <N_LOA_HBLoader.h>
52 #include <N_LAS_HBBuilder.h>
53 #include <N_LAS_HBPrecondFactory.h>
54 #include <N_LAS_PrecondFactory.h>
55 #include <N_LAS_System.h>
56 #include <N_LAS_BlockSystemHelpers.h>
57 
58 #include <N_NLS_Manager.h>
59 
60 #include <N_IO_OutputMgr.h>
61 
62 #include <N_UTL_FFTInterface.hpp>
63 
64 #include <Teuchos_Utils.hpp>
65 
66 using Teuchos::rcp;
67 using Teuchos::RCP;
68 using Teuchos::rcp_dynamic_cast;
69 
70 namespace Xyce {
71 namespace Analysis {
72 
73 //-----------------------------------------------------------------------------
74 // Function : HB::HB( AnalysisManager * )
75 // Purpose :
76 // Special Notes :
77 // Scope : public
78 // Creator : Todd Coffey, SNL
79 // Creation Date : 09/18/2008
80 //-----------------------------------------------------------------------------
81 HB::HB( AnalysisManager * anaManagerPtr ) :
82  AnalysisBase(anaManagerPtr),
83  debugLevel(0),
84  isPaused(false),
85  startDCOPtime(0.0),
86  endTRANtime(0.0),
87  isTransient_(false),
88  isDCSweep_(false),
89  test_(false),
90  size_(21),
91  period_(1.0),
92  startUpPeriods_(0),
93  startUpPeriodsGiven_(false),
94  startUpPeriodsFinished_(false),
95  saveIcData_(false),
96  tiaParams_( anaManagerPtr->tiaParams ),
97  voltLimFlag_(1),
98  taHB_(1),
99  fastTimeDisc_(0),
100  fastTimeDiscOrder_(1),
101  hbTotalNumberSuccessfulStepsTaken_(0),
102  hbTotalNumberFailedStepsAttempted_(0),
103  hbTotalNumberJacobiansEvaluated_(0),
104  hbTotalNumberIterationMatrixFactorizations_(0),
105  hbTotalNumberLinearSolves_(0),
106  hbTotalNumberFailedLinearSolves_(0),
107  hbTotalNumberLinearIters_(0),
108  hbTotalNumberResidualEvaluations_(0),
109  hbTotalNonlinearConvergenceFailures_(0),
110  hbTotalResidualLoadTime_(0.0),
111  hbTotalJacobianLoadTime_(0.0),
112  hbTotalLinearSolutionTime_(0.0),
113  resetForStepCalledBefore_(false)
114 {
115  devInterfacePtr_ = anaManagerRCPtr_->devInterfacePtr;
116  topoMgrPtr_ = anaManagerRCPtr_->topoMgrPtr;
117  nonlinearEquationLoaderPtr_ = anaManagerRCPtr_->nonlinearEquationLoaderPtr;
118  appBuilderPtr_ = anaManagerRCPtr_->appBuilderPtr;
119  pdsMgrPtr_ = anaManagerRCPtr_->pdsMgrPtr;
120 }
121 
122 //-----------------------------------------------------------------------------
123 // Function : HB::getStepNumber()
124 // Purpose :
125 // Special Notes :
126 // Scope : public
127 // Creator : Heidi Thornquist
128 // Creation Date : 5/20/13
129 //-----------------------------------------------------------------------------
131 {
132  if ( !Teuchos::is_null( analysisObject_ ) )
133  {
134  return analysisObject_->getStepNumber();
135  }
136  return 0;
137 }
138 
139 //-----------------------------------------------------------------------------
140 // Function : HB::setStepNumber()
141 // Purpose :
142 // Special Notes :
143 // Scope : public
144 // Creator : Heidi Thornquist
145 // Creation Date : 5/20/13
146 //-----------------------------------------------------------------------------
147 void HB::setStepNumber (int step)
148 {
149  if ( !Teuchos::is_null( analysisObject_ ) )
150  {
151  analysisObject_->setStepNumber( step );
152  }
153 }
154 
155 //-----------------------------------------------------------------------------
156 // Function : HB::setBeginningIntegrationFlag()
157 // Purpose :
158 // Special Notes :
159 // Scope : public
160 // Creator : Heidi Thornquist
161 // Creation Date : 5/20/13
162 //-----------------------------------------------------------------------------
164 {
165  if ( !Teuchos::is_null( analysisObject_ ) )
166  {
167  analysisObject_->setBeginningIntegrationFlag( bif );
168  }
169 }
170 
171 //-----------------------------------------------------------------------------
172 // Function : HB::getBeginningIntegrationFlag()
173 // Purpose :
174 // Special Notes :
175 // Scope : public
176 // Creator : Heidi Thornquist
177 // Creation Date : 5/20/13
178 //-----------------------------------------------------------------------------
180 {
181  if ( !Teuchos::is_null( analysisObject_ ) )
182  {
183  return analysisObject_->getBeginningIntegrationFlag();
184  }
185  return true;
186 }
187 
188 //-----------------------------------------------------------------------------
189 // Function : HB::setIntegrationMethod
190 // Purpose :
191 // Special Notes :
192 // Scope : public
193 // Creator : Heidi Thornquist
194 // Creation Date : 5/20/13
195 //-----------------------------------------------------------------------------
197 {
198  if ( !Teuchos::is_null( analysisObject_ ) )
199  {
200  analysisObject_->setIntegrationMethod( im );
201  }
202 }
203 
204 //-----------------------------------------------------------------------------
205 // Function : HB::getIntegrationMethod
206 // Purpose :
207 // Special Notes :
208 // Scope : public
209 // Creator : Heidi Thornquist
210 // Creation Date : 5/20/13
211 //-----------------------------------------------------------------------------
213 {
214  if ( !Teuchos::is_null( analysisObject_ ) )
215  {
216  return analysisObject_->getIntegrationMethod ();
217  }
218  return TIAMethod_NONE;
219 }
220 
221 //-----------------------------------------------------------------------------
222 // Function : HB::run()
223 // Purpose :
224 // Special Notes :
225 // Scope : public
226 // Creator : Todd Coffey, SNL
227 // Creation Date : 09/18/2008
228 //-----------------------------------------------------------------------------
229 bool HB::run()
230 {
231 
232  // initializeAll_();
233  // get TIAParams from AnalysisInterface
234  // create HBBuilder
235  // generateMaps
236  // generateStateMaps
237  // create vectors for IC
238  //
239  // if (test_) {
240  // runTests_();
241  // } else {
242  //
243  // computeInitialCondition_();
244  // run startup periods
245  // integrate one period
246  // interpolate to evenly spaced points
247  // set this as IC for HB nonlinear problem
248  //
249  // setupHBProblem_();
250  //
251  // runHBProblem_();
252  //
253  // }
254 
255  bool bsuccess = true;
256 
257  bsuccess = bsuccess & init();
258  bsuccess = bsuccess & loopProcess();
259 
260  // if processing the loop failed,
261  // then skip finish step
262  if( bsuccess )
263  {
264  bsuccess = bsuccess & finish();
265  }
266 
267  return bsuccess;
268 }
269 
270 //-----------------------------------------------------------------------------
271 // Function : HB::init()
272 // Purpose :
273 // Special Notes :
274 // Scope : public
275 // Creator : Todd Coffey, SNL
276 // Creation Date : 09/18/2008
277 //-----------------------------------------------------------------------------
278 bool HB::init()
279 {
280  bool returnValue=true;
281 
282  Xyce::lout() << " ***** Running HB initial conditions....\n" << std::endl;
283 #ifdef Xyce_DEBUG_HB
284  Xyce::dout() << std::endl
285  << section_divider << std::endl
286  << " HB::init()" << std::endl;
287 #endif // Xyce_DEBUG_HB
288 
289  //Store copy of transient TIAParams for HB run
290  tiaParams_ = anaManagerRCPtr_->tiaParams;
291  //
292  // If it was requested, advance the solution a fixed number of startup periods
293  //
294  period_ = 1.0/tiaParams_.freqs[0];
295 
296 
297  if (taHB_ == 1)
298  {
299  bool retTol1 = runTol_(); returnValue = returnValue && retTol1;
300 
301  // Start up periods need to be run before the initial condition is computed, otherwise
302  // just used the solution from the tolerance calculation.
304  {
305  bool startupPeriodsSuccess = runStartupPeriods_();
306  if (!startupPeriodsSuccess)
307  {
308  std::string msg = "HB::init(). Failed to calculate the startup periods.\n";
309  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL_0,msg);
310  }
311  returnValue = returnValue && startupPeriodsSuccess;
312 
313  bool icSuccess = runTransientIC_();
314  if (!icSuccess)
315  {
316  std::string msg = "HB::init(). Initial HB Transient failed \n";
317  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL_0,msg);
318  }
319  returnValue = returnValue && icSuccess;
320  }
321 
322  interpolateIC_();
323 
324 
325  }
326  else
327  {
328 
329  double TimeStep = period_/static_cast<double>(size_);
330  timeSteps_.push_back( TimeStep );
331  fastTimes_.resize(size_+1);
332 
333  goodTimePoints_.resize(size_+1);
334  for( int i = 0; i <= size_; ++i )
335  {
336  fastTimes_[i] = tiaParams_.initialTime + static_cast<double>(i) * TimeStep;
337  }
339 
340  }
341 
342  freqPoints_.resize(size_);
343  // double fastStep = period_/static_cast<double>(size_);
344  int i=0;
345  for( i = 0; i < size_; ++i )
346  {
347  if (i < (size_-1)/2)
348  freqPoints_[i] = -static_cast<double>((size_-1)/2 - i) * tiaParams_.freqs[0];
349  else
350  freqPoints_[i] = static_cast<double>(i - (size_-1)/2) * tiaParams_.freqs[0];
351  }
352 
353 
354  // now that we have size_, continue with the initialization of objects for HB
355  mpdeDiscPtr_ = rcp(new N_MPDE_Discretization(
356  static_cast<N_MPDE_Discretization::Type>(fastTimeDisc_), fastTimeDiscOrder_ ));
357 
358  hbBuilderPtr_ = rcp(new N_LAS_HBBuilder( size_, mpdeDiscPtr_ ));
359 
360 #ifdef Xyce_DEBUG_HB
361  Xyce::dout() << "HB::init(): Generate Maps\n";
362 #endif // Xyce_DEBUG_HB
363  hbBuilderPtr_->generateMaps( rcp(pdsMgrPtr_->getParallelMap( "SOLUTION" ), false),
364  rcp(pdsMgrPtr_->getParallelMap( "SOLUTION_OVERLAP_GND" ), false) );
365  hbBuilderPtr_->generateStateMaps( rcp(pdsMgrPtr_->getParallelMap( "STATE" ),false) );
366  hbBuilderPtr_->generateStoreMaps( rcp(pdsMgrPtr_->getParallelMap( "STORE" ),false) );
367  hbBuilderPtr_->generateGraphs( *(pdsMgrPtr_->getMatrixGraph( "JACOBIAN" )) );
368 
369  HBICVectorPtr_ = hbBuilderPtr_->createTimeDomainBlockVector();
370  HBICStateVectorPtr_ = hbBuilderPtr_->createTimeDomainStateBlockVector();
371  HBICStoreVectorPtr_ = hbBuilderPtr_->createTimeDomainStoreBlockVector();
372  HBICQVectorPtr_ = hbBuilderPtr_->createTimeDomainBlockVector();
373 
374  HBICVectorFreqPtr_ = hbBuilderPtr_->createExpandedRealFormTransposeBlockVector();
375 
376 // HBICStateVectorFreqPtr_ = hbBuilderPtr_->createExpandedRealFormTransposeStateBlockVector();
377 // HBICQVectorFreqPtr_ = hbBuilderPtr_->createExpandedRealFormTransposeBlockVector();
378 // HBICStoreVectorFreqPtr_ = hbBuilderPtr_->createExpandedRealFormTransposeStoreBlockVector();
379 
381  anaManagerRCPtr_->registerTIAParams (tiaParams_);
382 
383  // set the fast source flag in the devices
384  std::vector<std::string> srcVec;
385  devInterfacePtr_->registerFastSources( srcVec );
386 
387  //anaManagerRCPtr_->anaIntPtr->getnlHBOptions(saved_nlHBOB_);
388  nlsMgrRCPtr_->getHBOptions(saved_nlHBOB_);
389 
390  // Create HB Loader.
391  hbLoaderPtr_ = rcp(new N_LOA_HBLoader( mpdeState_, mpdeDiscPtr_ ) );
392  hbLoaderPtr_->registerHBBuilder(hbBuilderPtr_);
393  hbLoaderPtr_->registerAppBuilder(appBuilderPtr_);
394 
395  if (taHB_==1)
396  {
397  // Pick up IC data from the initial transient.
398  for (int i=0 ; i<size_ ; ++i)
399  {
400 #ifdef Xyce_DEBUG_HB
401  if( debugLevel > 0 )
402  {
403  Xyce::dout() << "HB::init(): Loading initial condition data from time: fastTimes_["
404  << i << "] = " << fastTimes_[i] << std::endl;
405  }
406 #endif // Xyce_DEBUG_HB
407 
408  HBICVectorPtr_->block(i) = *(goodSolutionVec_[i]);
409  HBICStateVectorPtr_->block(i) = *(goodStateVec_[i]);
410  HBICQVectorPtr_->block(i) = *(goodQVec_[i]);
411  HBICStoreVectorPtr_->block(i) = *(goodStoreVec_[i]);
412  }
413 
415 
416  }
417 #ifdef Xyce_DEBUG_HB
418  if ( debugLevel > 1 )
419  {
420  Xyce::dout() << "HB Initial Condition Solution!\n";
421  HBICVectorPtr_->printPetraObject(std::cout);
422  Xyce::dout() << "HB Initial Condition State Vector!\n";
423  HBICStateVectorPtr_->printPetraObject(std::cout);
424  Xyce::dout() << "HB Initial Condition Store Vector!\n";
425  HBICStoreVectorPtr_->printPetraObject(std::cout);
426  }
427 #endif // Xyce_DEBUG_HB
428 
429  //Destroy Solvers, etc. from IC phase and prepare for HB
430  //-----------------------------------------
431 
432 // if ( voltLimFlag_ == 0 )
433 // devInterfacePtr_->setVoltageLimiterFlag (false);
434  devInterfacePtr_->setVoltageLimiterFlag (voltLimFlag_);
435 
436  devInterfacePtr_->setMPDEFlag( true );
437  anaManagerRCPtr_->resetAll();
438 
439  //-----------------------------------------
440 
441  //Finish setup of HB Loader
442  //-----------------------------------------
443  hbLoaderPtr_->registerAppLoader( loaderRCPtr_ );
444  hbLoaderPtr_->registerDeviceInterface( devInterfacePtr_ );
445  goodTimePoints_.resize(size_+1);
447 
448  for( int i = 0; i < size_; ++i )
449  {
451  }
452 
453  hbLoaderPtr_->setFastTimes(goodTimePoints_);
454 
455  //-----------------------------------------
456  //Construct Solvers, etc. for HB Phase
457  //-----------------------------------------
458  lasHBSysPtr_ = rcp(new N_LAS_System());
459  //-----------------------------------------
460 
461  anaManagerRCPtr_->registerTIAParams( tiaParams_ );
462  anaManagerRCPtr_->registerLinearSystem( &*lasHBSysPtr_ );
463  anaManagerRCPtr_->registerLoader( &*hbLoaderPtr_ );
464 
465  //hack needed by TIA initialization currently
466  hbBuilderPtr_->registerPDSManager( &*pdsMgrPtr_ );
467 
468  lasHBSysPtr_->registerANPInterface( (anaManagerRCPtr_->anaIntPtr).get() );
469  lasHBSysPtr_->registerPDSManager( &*pdsMgrPtr_ );
470  lasHBSysPtr_->registerBuilder( &*hbBuilderPtr_ );
471 
472  //need to cut out unnecessary stuff from this call for new dae
473  lasHBSysPtr_->initializeSystem();
474 
475  // Give NLS Manager the same old nonlinearEquationLoader as it just calls the TIA loader in newDAE
476  nlsMgrRCPtr_->registerLinearSystem( &*lasHBSysPtr_ );
477  nlsMgrRCPtr_->setLinSolOptions( saved_lsHBOB_ );
478  nlsMgrRCPtr_->setMatrixFreeFlag( true );
479 
480  // Let the HB loader know that the application of the operator is matrix free
481  hbLoaderPtr_->setMatrixFreeFlag( true );
482 
483  if (Teuchos::is_null( precFactory_ ))
484  {
485  // Generate the HB preconditioner factory.
486  precFactory_ = rcp( new N_LAS_HBPrecondFactory( saved_lsHBOB_ ) );
487  }
488 
489  // Register application loader with preconditioner factory
490  RCP<N_LAS_HBPrecondFactory> tmpPrecFactory
491  = rcp_dynamic_cast<N_LAS_HBPrecondFactory>( precFactory_ );
492 
493  tmpPrecFactory->registerAppBuilder( appBuilderPtr_ );
494  tmpPrecFactory->registerHBLoader( hbLoaderPtr_ );
495  tmpPrecFactory->registerHBBuilder( hbBuilderPtr_ );
496  tmpPrecFactory->setFastTimes( goodTimePoints_ );
497  tmpPrecFactory->setTimeSteps( timeSteps_ );
498 
499  nlsMgrRCPtr_->registerPrecondFactory( precFactory_ );
500  //-----------------------------------------
501 
502  //Initialization of Solvers, etc. for HB Phase
503  //-----------------------------------------
504  //Dummy call to setup time integrator for transient
505  anaManagerRCPtr_->resumeSimulation();
506  anaManagerRCPtr_->initializeAll();
507  anaManagerRCPtr_->setMPDEFlag( true );
508 
509  nlsMgrRCPtr_->initializeAll();
510  nlsMgrRCPtr_->setAnalysisMode(anpAnalysisModeToNLS(ANP_MODE_HB));
511 
512 #ifdef Xyce_DEBUG_HB
513  Xyce::dout() << section_divider << std::endl;
514 #endif // Xyce_DEBUG_HB
515 
516  return returnValue;
517 }
518 
519 //-----------------------------------------------------------------------------
520 // Function : HB::loopProcess()
521 // Purpose :
522 // Special Notes :
523 // Scope : public
524 // Creator : Todd Coffey, SNL
525 // Creation Date : 09/18/2008
526 //-----------------------------------------------------------------------------
528 {
529  bool returnValue = true;
530 
531  Xyce::lout() << " ***** Beginning full HB simulation....\n" << std::endl;
532 
533 #ifdef Xyce_DEBUG_HB
534  Xyce::dout() << std::endl
535  << section_divider << std::endl
536  << " HB::loopProcess" << std::endl;
537 #endif // Xyce_DEBUG_HB
538 
539  RCP<N_TIA_DataStore> dsPtr = anaManagerRCPtr_->getTIADataStore();
540  *(dsPtr->nextSolutionPtr) = *(HBICVectorFreqPtr_.get());
541  *(dsPtr->nextStatePtr) = *(HBICStateVectorPtr_.get());
542  *(dsPtr->nextStorePtr) = *(HBICStoreVectorPtr_.get());
543 
544  // try to run the problem
545  analysisObject_ = Teuchos::rcp(new DCSweep( anaManagerRCPtr_.get() ));
546  returnValue = analysisObject_->run();
547 
548  // Add in simulation times
550 
551  // print out analysis info
552  Xyce::lout() << " ***** Harmonic Balance Computation Summary *****" << std::endl;
553  analysisObject_->printLoopInfo( 0, 0 );
554 
555 #ifdef Xyce_DEBUG_HB
556  dout() << section_divider << std::endl;
557 #endif // Xyce_DEBUG_HB
558 
559  return returnValue;
560 }
561 
562 //-----------------------------------------------------------------------------
563 // Function : HB::processSuccessfulDCOP()
564 // Purpose :
565 // Special Notes :
566 // Scope : public
567 // Creator : Todd Coffey, SNL
568 // Creation Date : 09/18/2008
569 //-----------------------------------------------------------------------------
571 {
572  return false;
573 }
574 
575 //-----------------------------------------------------------------------------
576 // Function : HB::processSuccessfulStep()
577 // Purpose :
578 // Special Notes :
579 // Scope : public
580 // Creator : Todd Coffey, SNL
581 // Creation Date : 09/18/2008
582 //-----------------------------------------------------------------------------
584 {
585  return false;
586 }
587 
588 //-----------------------------------------------------------------------------
589 // Function : HB::processFailedStep
590 // Purpose :
591 // Special Notes :
592 // Scope : public
593 // Creator : Todd Coffey, SNL
594 // Creation Date : 09/18/2008
595 //-----------------------------------------------------------------------------
597 {
598  return false;
599 }
600 
601 //-----------------------------------------------------------------------------
602 // Function : HB::processFailedDCOP
603 // Purpose :
604 // Special Notes :
605 // Scope : public
606 // Creator : Todd Coffey, SNL
607 // Creation Date : 09/18/2008
608 //-----------------------------------------------------------------------------
610 {
611  return false;
612 }
613 
614 //-----------------------------------------------------------------------------
615 // Function : HB::finish
616 // Purpose :
617 // Special Notes :
618 // Scope : public
619 // Creator : Todd Coffey, SNL
620 // Creation Date : 09/18/2008
621 //-----------------------------------------------------------------------------
623 {
624  // Move statistics into common variable
637 
638  return true;
639 }
640 
642 {
643  return true;
644 }
645 
646 //-----------------------------------------------------------------------------
647 // Function : HB::resetForStepAnalysis()
648 // Purpose : When doing a .STEP sweep, some data must be reset to its
649 // initial state.
650 // Special Notes :
651 // Scope : public
652 // Creator : Todd Coffey, SNL
653 // Creation Date : 09/18/2008
654 //-----------------------------------------------------------------------------
656 {
658 
660  {
661  goodSolutionVec_.clear();
662  goodStateVec_.clear();
663  goodQVec_.clear();
664  goodStoreVec_.clear();
665 
666  secRCPtr_->resetAll();
667 
668  anaManagerRCPtr_->setNextOutputTime(0.0);
669  anaManagerRCPtr_->registerLinearSystem( &*lasSystemRCPtr_ );
670  anaManagerRCPtr_->registerLoader( loaderRCPtr_.get() );
671  anaManagerRCPtr_->resumeSimulation();
672 
673  nlsMgrRCPtr_->resetAll(DC_OP);
674  nlsMgrRCPtr_->setMatrixFreeFlag( false );
675  nlsMgrRCPtr_->registerLinearSystem( &*lasSystemRCPtr_ );
676  nlsMgrRCPtr_->registerLoader( nonlinearEquationLoaderPtr_.get() );
677  nlsMgrRCPtr_->setLinSolOptions( saved_lsOB_ );
678 
679  devInterfacePtr_->registerLinearSystem( &*lasSystemRCPtr_ );
680 
681  // un-set the fast source flag in the devices
682  std::vector<std::string> srcVec;
683  devInterfacePtr_->deRegisterFastSources( srcVec );
684 
685  anaManagerRCPtr_->initializeAll();
686 
687  devInterfacePtr_->resetForStepAnalysis();
688  devInterfacePtr_->initializeAll();
689  devInterfacePtr_->setMPDEFlag( false );
690 
691  nlsMgrRCPtr_->initializeAll();
692 
693  anaManagerRCPtr_->unset_resumeSimulation();
694 
695  // this would normally be allocated in the analysis manager::run function.
696  anaManagerRCPtr_->xyceTranTimerPtr_ = rcp(new N_UTL_Timer(*(pdsMgrPtr_->getPDSComm())));
697  }
698 
700 
701  return false;
702 }
703 
704 //-----------------------------------------------------------------------------
705 // Function : HB::finalVerboseOutput
706 // Purpose :
707 // Special Notes :
708 // Scope : public
709 // Creator : Todd Coffey, SNL
710 // Creation Date : 09/18/2008
711 //-----------------------------------------------------------------------------
713 {
714  return false;
715 }
716 
717 //-----------------------------------------------------------------------------
718 // Function : HB::setHBOptions
719 // Purpose :
720 // Special Notes :
721 // Scope : public
722 // Creator : Heidi Thornquist
723 // Creation Date : 05/13/13
724 //-----------------------------------------------------------------------------
725 bool HB::setHBOptions(const N_UTL_OptionBlock & OB)
726 {
727  std::list<N_UTL_Param>::const_iterator iterPL = OB.getParams().begin();
728  std::list<N_UTL_Param>::const_iterator endPL = OB.getParams().end();
729 
730  for( ; iterPL != endPL; ++iterPL )
731  {
732  ExtendedString tag = iterPL->tag();
733  tag.toUpper();
734 
735  if ( tag == "NUMFREQ" )
736  {
737  size_ = iterPL->getImmutableValue<int>();
738  }
739  else if ( tag == "STARTUPPERIODS" )
740  {
741  startUpPeriods_ = iterPL->getImmutableValue<int>();
742 
743  if (startUpPeriods_ > 0)
744  startUpPeriodsGiven_ = true;
745  }
746  else if( tag == "SAVEICDATA" )
747  {
748  saveIcData_ = true;
749  }
750  else if( tag == "TEST" )
751  {
752  test_ = static_cast<bool> (iterPL->getImmutableValue<int>());
753  }
754  else if (tag == "DEBUGLEVEL" )
755  {
756  debugLevel = iterPL->getImmutableValue<int>();
757  }
758  else if ( tag == "TAHB" )
759  {
760  taHB_ = iterPL->getImmutableValue<int>();
761  }
762  else if ( tag == "VOLTLIM" )
763  {
764  voltLimFlag_ = static_cast<bool> (iterPL->getImmutableValue<int>());
765  }
766  else
767  {
768  UserWarning(*this) << "Unrecognized HBINT option " << tag;
769  }
770  }
771 
772  return true;
773 }
774 
775 
776 //-----------------------------------------------------------------------------
777 // Function : HB::setLinSol
778 // Purpose : this is needed for .STEP to work with HB
779 // Special Notes :
780 // Scope : public
781 // Creator : Eric R. Keiter
782 // Creation Date : 7/12/2013
783 //-----------------------------------------------------------------------------
784 bool HB::setLinSol(const N_UTL_OptionBlock & OB)
785 {
786  // Save the non-HB linear solver option block
787  saved_lsOB_ = OB;
788 
789  return true;
790 }
791 
792 //-----------------------------------------------------------------------------
793 // Function : HB::setHBLinSol
794 // Purpose :
795 // Special Notes :
796 // Scope : public
797 // Creator : Heidi Thornquist
798 // Creation Date : 5/13/13
799 //-----------------------------------------------------------------------------
800 bool HB::setHBLinSol(const N_UTL_OptionBlock & OB)
801 {
802  // Save the HB linear solver option block
803  saved_lsHBOB_ = OB;
804 
805  // Generate the HB preconditioner factory.
806  precFactory_ = rcp( new N_LAS_HBPrecondFactory( OB ) );
807 
808  return true;
809 }
810 
811 //-----------------------------------------------------------------------------
812 // Function : HB::isAnalysis
813 // Purpose :
814 // Special Notes :
815 // Scope : public
816 // Creator : Heidi Thornquist
817 // Creation Date : 5/13/13
818 // Notes : Alternatively, we could try to cast the analysis object
819 // : However, this method is called a lot.
820 //-----------------------------------------------------------------------------
821 bool HB::isAnalysis( int analysis_type )
822 {
823  bool returnValue = false;
824 
825  if ( analysis_type == ANP_MODE_TRANSIENT )
826  {
827  returnValue = isTransient_;
828  }
829  if ( analysis_type == ANP_MODE_DC_SWEEP )
830  {
831  returnValue = isDCSweep_;
832  }
833  return returnValue;
834 }
835 
836 //-----------------------------------------------------------------------------
837 // Function : HB::prepareHBOutput
838 // Purpose :
839 // Special Notes :
840 // Scope : public
841 // Creator : Eric Keiter, 9233, Computational Sciences
842 // Creation Date : 08/20/07
843 //-----------------------------------------------------------------------------
845  N_LAS_Vector & solnVecPtr,
846  std::vector<double> & timePoints,
847  std::vector<double> & freqPoints,
848  RCP<N_LAS_BlockVector> & timeDomainSolnVec,
849  RCP<N_LAS_BlockVector> & freqDomainSolnVecReal,
850  RCP<N_LAS_BlockVector> & freqDomainSolnVecImag,
851  RCP<N_LAS_BlockVector> & timeDomainStoreVec,
852  RCP<N_LAS_BlockVector> & freqDomainStoreVecReal,
853  RCP<N_LAS_BlockVector> & freqDomainStoreVecImag
854  ) const
855 {
856  N_LAS_BlockVector & blockSolVecPtr = dynamic_cast<N_LAS_BlockVector &>(solnVecPtr);
857 
858  Teuchos::RCP<N_LAS_BlockVector> bStoreVecFreqPtr_ = hbLoaderPtr_->getStoreVecFreqPtr();
859 
860  timeDomainStoreVec = hbBuilderPtr_->createTimeDomainStoreBlockVector();
861 
862  if (bStoreVecFreqPtr_->blockCount() > 0 )
863  {
864  hbLoaderPtr_->permutedIFT(*bStoreVecFreqPtr_, &*timeDomainStoreVec);
865 // bStoreVecFreqPtr_->printPetraObject(std::cout);
866  }
867 
868  //TD solution
869  timeDomainSolnVec = hbBuilderPtr_->createTimeDomainBlockVector();
870  int blockCount = timeDomainSolnVec->blockCount();
871  int N = timeDomainSolnVec->block(0).globalLength();
872 
873  timePoints.resize(size_);
874 
875  for( int i = 0; i < size_; ++i )
876  {
877  timePoints[i] = fastTimes_[i] - tiaParams_.initialTime;
878  }
879 
880  freqPoints = freqPoints_;
881 
882  // Create individual block vectors to store the real and imaginary parts separately.
883  Teuchos::RCP<N_PDS_ParMap> baseMap = Teuchos::rcp_const_cast<N_PDS_ParMap>( hbBuilderPtr_->getBaseSolutionMap() );
884  Teuchos::RCP<N_PDS_ParMap> globalMap = createBlockParMap( blockCount, *baseMap );
885  freqDomainSolnVecReal = Teuchos::rcp( new N_LAS_BlockVector( blockCount, globalMap, baseMap ) );
886  freqDomainSolnVecImag = Teuchos::rcp( new N_LAS_BlockVector( blockCount, globalMap, baseMap ) );
887 
888  hbLoaderPtr_->permutedIFT(blockSolVecPtr, &*timeDomainSolnVec);
889 
890 // Xyce::dout() << "HB X Vector TD" << std::endl;
891 // timeDomainSolnVec->printPetraObject(std::cout);
892 
893 // Xyce::dout() << "HB Store Vector TD" << std::endl;
894 // timeDomainStoreVec->printPetraObject(std::cout);
895 
896  // Now copy over the frequency domain solution, real and imaginary parts separately, into the output vectors.
897  for (int j=0; j<N; j++)
898  {
899  // See if this time-domain solution variable is owned by the local processor.
900  // If so, this processor owns the entire j-th block of the blockSolVecPtr vector,
901  // and the j-th entry of every block in the freqDomainSolnVec[Real/Imag] vector.
902  int lid = baseMap->globalToLocalIndex( j );
903  N_LAS_Vector& solBlock = blockSolVecPtr.block( j );
904 
905  N_LAS_Vector& realVecRef = freqDomainSolnVecReal->block((blockCount-1)/2);
906  N_LAS_Vector& imagVecRef = freqDomainSolnVecImag->block((blockCount-1)/2);
907 
908  if (lid >= 0)
909  {
910  realVecRef[lid] = solBlock[0];
911  imagVecRef[lid] = solBlock[1];
912  }
913 
914  for (int i=1; i <= (blockCount-1)/2; ++i)
915  {
916  N_LAS_Vector& realVecRef_neg = freqDomainSolnVecReal->block((blockCount-1)/2 - i);
917  N_LAS_Vector& imagVecRef_neg = freqDomainSolnVecImag->block((blockCount-1)/2 - i);
918  N_LAS_Vector& realVecRef_pos = freqDomainSolnVecReal->block((blockCount-1)/2 + i);
919  N_LAS_Vector& imagVecRef_pos = freqDomainSolnVecImag->block((blockCount-1)/2 + i);
920 
921  if (lid >= 0)
922  {
923  realVecRef_neg[lid] = solBlock[ 2*(blockCount-i) ];
924  imagVecRef_neg[lid] = solBlock[ 2*(blockCount-i) + 1 ];
925  realVecRef_pos[lid] = solBlock[ 2*i ];
926  imagVecRef_pos[lid] = solBlock[ 2*i+1 ];
927  }
928  }
929  }
930 
931  // proceed to store variables
932  Teuchos::RCP<N_PDS_ParMap> baseStoreMap = Teuchos::rcp_const_cast<N_PDS_ParMap>( hbBuilderPtr_->getBaseStoreMap() );
933  Teuchos::RCP<N_PDS_ParMap> globalStoreMap = createBlockParMap( blockCount, *baseStoreMap );
934  freqDomainStoreVecReal = Teuchos::rcp( new N_LAS_BlockVector( blockCount, globalStoreMap, baseStoreMap ) );
935  freqDomainStoreVecImag = Teuchos::rcp( new N_LAS_BlockVector( blockCount, globalStoreMap, baseStoreMap ) );
936 
937 // hbLoaderPtr_->permutedIFT(blockSolVecPtr, &*timeDomainSolnVec);
938 
939  N = timeDomainStoreVec->block(0).globalLength();
940 
941  for (int j=0; j<N; j++)
942  {
943  // See if this time-domain solution variable is owned by the local processor.
944  // If so, this processor owns the entire j-th block of the blockSolVecPtr vector,
945  // and the j-th entry of every block in the freqDomainSolnVec[Real/Imag] vector.
946  int lid = baseStoreMap->globalToLocalIndex( j );
947  N_LAS_Vector& storeBlock = bStoreVecFreqPtr_->block( j );
948 
949  N_LAS_Vector& realVecRef = freqDomainStoreVecReal->block((blockCount-1)/2);
950  N_LAS_Vector& imagVecRef = freqDomainStoreVecImag->block((blockCount-1)/2);
951 
952  if (lid >= 0)
953  {
954  realVecRef[lid] = storeBlock[0];
955  imagVecRef[lid] = storeBlock[1];
956  }
957 
958  for (int i=1; i <= (blockCount-1)/2; ++i)
959  {
960  N_LAS_Vector& realVecRef_neg = freqDomainStoreVecReal->block((blockCount-1)/2 - i);
961  N_LAS_Vector& imagVecRef_neg = freqDomainStoreVecImag->block((blockCount-1)/2 - i);
962  N_LAS_Vector& realVecRef_pos = freqDomainStoreVecReal->block((blockCount-1)/2 + i);
963  N_LAS_Vector& imagVecRef_pos = freqDomainStoreVecImag->block((blockCount-1)/2 + i);
964 
965  if (lid >= 0)
966  {
967  realVecRef_neg[lid] = storeBlock[ 2*(blockCount-i) ];
968  imagVecRef_neg[lid] = storeBlock[ 2*(blockCount-i) + 1 ];
969  realVecRef_pos[lid] = storeBlock[ 2*i ];
970  imagVecRef_pos[lid] = storeBlock[ 2*i+1 ];
971  }
972  }
973  }
974 
975 // Xyce::dout() << "HB X Vector FD" << std::endl;
976 // freqDomainSolnVecReal->printPetraObject(std::cout);
977 // freqDomainSolnVecImag->printPetraObject(std::cout);
978 
979 // Xyce::dout() << "HB Store Vector FD" << std::endl;
980 
981 // freqDomainStoreVecReal->printPetraObject(std::cout);
982 // freqDomainStoreVecImag->printPetraObject(std::cout);
983 
984 }
985 
986 
987 //-----------------------------------------------------------------------------
988 // Function : HB::accumulateStatistics()
989 // Purpose : Add in the statistics from the current analysis object
990 // Special Notes :
991 // Scope : private
992 // Creator : Heidi Thornquist, 1355, Electrical Models & Simulation
993 // Creation Date : 05/29/13
994 //-----------------------------------------------------------------------------
996 {
997  hbTotalNumberSuccessfulStepsTaken_ += analysisObject_->totalNumberSuccessfulStepsTaken_;
998  hbTotalNumberFailedStepsAttempted_ += analysisObject_->totalNumberFailedStepsAttempted_;
999  hbTotalNumberJacobiansEvaluated_ += analysisObject_->totalNumberJacobiansEvaluated_;
1000  hbTotalNumberIterationMatrixFactorizations_ += analysisObject_->totalNumberIterationMatrixFactorizations_;
1001  hbTotalNumberLinearSolves_ += analysisObject_->totalNumberLinearSolves_;
1002  hbTotalNumberFailedLinearSolves_ += analysisObject_->totalNumberFailedLinearSolves_;
1003  hbTotalNumberLinearIters_ += analysisObject_->totalNumberLinearIters_;
1004  hbTotalNumberResidualEvaluations_ += analysisObject_->totalNumberResidualEvaluations_;
1005  hbTotalNonlinearConvergenceFailures_ += analysisObject_->totalNonlinearConvergenceFailures_;
1006  hbTotalResidualLoadTime_ += analysisObject_->totalResidualLoadTime_;
1007  hbTotalJacobianLoadTime_ += analysisObject_->totalJacobianLoadTime_;
1008  hbTotalLinearSolutionTime_ += analysisObject_->totalLinearSolutionTime_;
1009 }
1010 
1011 
1012 //-----------------------------------------------------------------------------
1013 // Function : HB::runTol_
1014 // Purpose : Conducts transient run to determine right tolerance
1015 // parameters for IC calculation
1016 // Special Notes :
1017 // Scope : private
1018 // Creator : T. Mei, 1437, Electrical and Micro Modeling
1019 // Creation Date : 02/23/09
1020 //-----------------------------------------------------------------------------
1022 {
1023  bool returnValue = true;
1024 
1025  Xyce::lout() << " ***** Computing tolerance parameters for HB IC calculation....\n" << std::endl;
1026 
1028  N_TIA_TIAParams tiaParamsSave = tiaParams;
1029 
1030  // now try the real thing
1031  tiaParams.initialTime = 0;
1032  tiaParams.finalTime = period_;
1033  tiaParams.pauseTime = tiaParams.finalTime;
1034  tiaParams.resume = false;
1035  tiaParams.maxOrder = 1;
1036 
1037  // If start up periods are not being run then we can use this transient to compute HB ICs.
1038  if (!startUpPeriodsGiven_)
1039  {
1040  tiaParams.saveTimeStepsFlag = true;
1041  }
1042 
1043  // register new tiaParams with time integrator
1044  anaManagerRCPtr_->registerTIAParams (tiaParams);
1045 
1046  // Create a transient analysis object for this section.
1047  isTransient_ = true;
1048  analysisObject_ = Teuchos::rcp( new Transient( anaManagerRCPtr_.get() ) );
1049  analysisObject_->setAnalysisParams( N_UTL_OptionBlock() );
1050  //analysisObject_->registerLoader( loaderRCPtr_.get() );
1051  Teuchos::rcp_dynamic_cast<Transient>(analysisObject_)->resetForHB();
1052  returnValue = analysisObject_->run();
1053 
1054  if (!returnValue)
1055  {
1056  std::string msg = "Calculation of tolerance parameters failed for relErrorTol = "
1057  + Teuchos::Utils::toString(tiaParams.relErrorTol) + ".\n";
1058  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL_0, msg );
1059  }
1060 
1061 
1062  int numPoints = anaManagerRCPtr_->getStepNumber();
1063 
1064  while((numPoints < (1.2*size_)) && (tiaParams.relErrorTol>= 1e-6))
1065  {
1066  std::string msg = "Tolerance parameters refined, re-running with relErrorTol = "
1067  + Teuchos::Utils::toString(tiaParams.relErrorTol/10) + ".\n";
1068  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::USR_WARNING_0, msg );
1069 
1070  if (!startUpPeriodsGiven_)
1071  {
1072  // Clear the fast time data storage before performing the next transient
1073  RCP<N_TIA_DataStore> dsPtr = anaManagerRCPtr_->getTIADataStore();
1074  dsPtr->resetFastTimeData();
1075  }
1076 
1077  tiaParams.relErrorTol = tiaParams.relErrorTol/10;
1078  anaManagerRCPtr_->registerTIAParams (tiaParams);
1079 
1080  // Create a transient analysis object for this section.
1081  analysisObject_ = Teuchos::rcp( new Transient( anaManagerRCPtr_.get() ) );
1082  analysisObject_->setAnalysisParams( N_UTL_OptionBlock() );
1083  //analysisObject_->registerLoader( loaderRCPtr_.get() );
1084  Teuchos::rcp_dynamic_cast<Transient>(analysisObject_)->resetForHB();
1085  bool retV = analysisObject_->run();
1086 
1087  if (!retV)
1088  {
1089  std::string msg = "Calculation of tolerance parameters failed for relErrorTol = "
1090  + Teuchos::Utils::toString(tiaParams.relErrorTol) + ".\n";
1091  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL_0, msg );
1092  }
1093  returnValue = retV && returnValue;
1094 
1095 
1096  numPoints = anaManagerRCPtr_->getStepNumber();
1097 
1098  }
1099 
1100  // Add in simulation times
1102 
1103  // Reset parameters
1104  tiaParamsSave.relErrorTol = tiaParams.relErrorTol;
1105  anaManagerRCPtr_->registerTIAParams (tiaParamsSave);
1106 
1107  // Reset transient flag before exiting.
1108  isTransient_ = false;
1109 
1110  return returnValue;
1111 }
1112 
1113 //-----------------------------------------------------------------------------
1114 // Function : HB::runStartupPeriods_()
1115 // Purpose : Runs normal transient problem through the requested
1116 // number of startup periods
1117 // Special Notes :
1118 // Scope : private
1119 // Creator : Richard Schiek, 1437, Electrical and Micro Modeling
1120 // Creation Date : 09/17/07
1121 //-----------------------------------------------------------------------------
1123 {
1124  bool returnValue = true;
1125 
1126  Xyce::lout() << " ***** Computing " << startUpPeriods_ << " start up periods for HB IC calculation...." << std::endl;
1127 
1128  // need to advance time by startUpPeriods_ * period_
1130  N_TIA_TIAParams tiaParamsSave = tiaParams;
1131 
1132  // set DAE initial time = 0.0
1133  tiaParams.initialTime = 0.0;
1134  tiaParams.finalTime = startUpPeriods_ * period_;
1135  tiaParams.pauseTime = tiaParams.finalTime;
1136 
1137 #ifdef Xyce_DEBUG_HB
1138  Xyce::dout() << "HB::runStartupPeriods_(): Advancing time through "
1139  << startUpPeriods_ << " startup periods"
1140  << " initialTime = " << tiaParams.initialTime
1141  << " finalTime = " << tiaParams.finalTime << std::endl;
1142 #endif // Xyce_DEBUG_HB
1143 
1144  // tell the output manager to save this data as netlist.cir.startup.prn
1145  // anaManagerRCPtr_->outMgrPtr->setOutputFilenameSuffix(".startup");
1146 
1147  {
1148  Xyce::IO::OutputMgr::ActiveOutput x(*anaManagerRCPtr_->outMgrPtr);
1149  x.add(Xyce::IO::PrintType::HB_STARTUP);
1150 
1151  // register new tiaParams with time integrator
1152  anaManagerRCPtr_->registerTIAParams (tiaParams);
1153 
1154  // Create a transient analysis object for this section.
1155  isTransient_ = true;
1156  analysisObject_ = Teuchos::rcp( new Transient( anaManagerRCPtr_.get() ) );
1157  analysisObject_->setAnalysisParams( N_UTL_OptionBlock() );
1158  Teuchos::rcp_dynamic_cast<Transient>(analysisObject_)->resetForHB();
1159  returnValue = analysisObject_->run();
1160  isTransient_ = false;
1161 
1162  // Add in simulation times
1164 
1165  anaManagerRCPtr_->outMgrPtr->finishOutput();
1166  }
1167 
1168  // reset the output filename suffix
1169  // anaManagerRCPtr_->outMgrPtr->setOutputFilenameSuffix("");
1170 
1171  // put the dsPtr->currentSolutionPtr into dcOpSol and State Vec so that it
1172  // is used as our initial condition for the pending fast time scale runs
1173  RCP<N_TIA_DataStore> dsPtr = anaManagerRCPtr_->getTIADataStore();
1174  dcOpSolVecPtr_ = rcp( new N_LAS_Vector( *(dsPtr->currSolutionPtr) ));
1175  dcOpStateVecPtr_ = rcp( new N_LAS_Vector( *(dsPtr->currStatePtr) ));
1176  dcOpQVecPtr_ = rcp( new N_LAS_Vector( *(dsPtr->daeQVectorPtr) ));
1177  dcOpStoreVecPtr_ = rcp( new N_LAS_Vector( *(dsPtr->currStorePtr) ));
1178 
1179  // tell HB to start after this startup period
1180  tiaParamsSave.initialTime = startUpPeriods_ * period_;
1182  anaManagerRCPtr_->registerTIAParams (tiaParamsSave);
1183  startUpPeriodsFinished_ = true;
1184 
1185  return returnValue;
1186 }
1187 
1188 //-----------------------------------------------------------------------------
1189 // Function : HB::runTransientIC_
1190 // Purpose : Conducts a regular transient run for HB initial conditions
1191 // Special Notes :
1192 // Scope : private
1193 // Creator : Ting Mei, SNL
1194 // Creation Date : 10/03/2008
1195 //-----------------------------------------------------------------------------
1197 {
1198  bool returnValue = true;
1199 
1200  Xyce::lout() << " ***** Running transient to compute HB initial condition....\n" << std::endl;
1201 
1202  // this prevents extra DC op data from being printed.
1203  devInterfacePtr_->setMPDEFlag( true );
1204 
1205  if(saveIcData_)
1206  {
1207  // Keep the initial condition data
1208  // anaManagerRCPtr_->outMgrPtr->setOutputFilenameSuffix( ".hb_ic" );
1209  }
1210 
1211  // use an initial transient run to create a set of time points for the fast time scale
1213  N_TIA_TIAParams tiaParamsSave = tiaParams;
1214 
1215  //tiaParams.initialTime = 0; // should be tiaParams_.initialTime;
1216  tiaParams.initialTime = tiaParams_.initialTime;
1217  //tiaParams.finalTime = period_; // should be tiaParams_.initialTime + period_;
1218  tiaParams.finalTime = tiaParams_.initialTime + period_;
1219  tiaParams.pauseTime = tiaParams.finalTime;
1220  tiaParams.saveTimeStepsFlag = true;
1221  tiaParams.maxOrder = 1;
1222 
1223 #ifdef Xyce_DEBUG_HB
1224  Xyce::dout() << "HB::runTransientIC_(): Advancing time from"
1225  << " initialTime = " << tiaParams.initialTime
1226  << " finalTime = " << tiaParams.finalTime << std::endl;
1227 #endif // Xyce_DEBUG_HB
1228 
1229  // Initial conditions will be set if startup periods were run.
1230  if ( startUpPeriodsGiven_ )
1231  {
1232  tiaParams.NOOP = true;
1233 
1234  RCP<N_TIA_DataStore> dsPtr = anaManagerRCPtr_->getTIADataStore();
1235  *(dsPtr->nextSolutionPtr) = *(dcOpSolVecPtr_.get());
1236  *(dsPtr->nextStatePtr) = *(dcOpStateVecPtr_.get());
1237  *(dsPtr->daeQVectorPtr) = *(dcOpQVecPtr_.get());
1238  *(dsPtr->nextStorePtr) = *(dcOpStoreVecPtr_.get());
1239  }
1240 
1241  // register new tiaParams with time integrator
1242  anaManagerRCPtr_->registerTIAParams (tiaParams);
1243 
1244  // Create a transient analysis object for this section.
1245  isTransient_ = true;
1246  analysisObject_ = Teuchos::rcp( new Transient( anaManagerRCPtr_.get() ) );
1247  analysisObject_->setAnalysisParams( N_UTL_OptionBlock() );
1248  Teuchos::rcp_dynamic_cast<Transient>(analysisObject_)->resetForHB();
1249  returnValue = analysisObject_->run();
1250  isTransient_ = false;
1251 
1252  // Add in simulation times
1254 
1255  if(saveIcData_)
1256  {
1257  // reset suffix
1258  // anaManagerRCPtr_->outMgrPtr->setOutputFilenameSuffix( "" );
1259  }
1260 
1261  // restore the saved copy of time integration parameters.
1262  anaManagerRCPtr_->registerLoader( loaderRCPtr_.get() );
1263 
1264  tiaParamsSave.initialTime += period_; // start HB problem after this transient init.
1265  anaManagerRCPtr_->registerTIAParams (tiaParamsSave);
1266  devInterfacePtr_->setMPDEFlag( false );
1267 
1268  return returnValue;
1269 }
1270 
1271 //-----------------------------------------------------------------------------
1272 // Function : HB::interpolateIC_()
1273 // Purpose : Tries to filter the fast time points from a transient run
1274 // so that points are not too close together
1275 // Special Notes :
1276 // Scope : private
1277 // Creator : Richard Schiek, 1437, Electrical and Micro Modeling
1278 // Creation Date : 09/17/07
1279 //-----------------------------------------------------------------------------
1281 {
1282  Xyce::lout() << " ***** Interpolating transient solution for IC calculation....\n" << std::endl;
1283 
1284  RCP<N_TIA_DataStore> dsPtr = anaManagerRCPtr_->getTIADataStore();
1285  int numPoints = dsPtr->timeSteps.size();
1286 
1287 #ifdef Xyce_DEBUG_HB
1288  Xyce::dout() << "HB::interpolateIC_(): Initial transient run produced " << numPoints << " points." << std::endl;
1289 #endif
1290 
1291  std::vector<int> goodIndicies;
1292  goodTimePoints_.resize(size_);
1293 
1294  double TimeStep = period_/static_cast<double>(size_);
1295  timeSteps_.push_back( TimeStep );
1296  for( int i = 0; i < size_; ++i )
1297  {
1298  goodTimePoints_[i] = tiaParams_.initialTime + static_cast<double>(i) * TimeStep;
1299  }
1301  fastTimes_.resize(size_+1);
1303 
1304  int breakpoints = 0; // need to keep track of how many breakpoints there are
1305  int startIndex = 0;
1306 
1307  // always keep first point
1308  goodIndicies.push_back(startIndex);
1309  int GoodTimePointIndex = startIndex + 1;
1310 
1311  for( int i=startIndex; i < numPoints - 1 ; i++ )
1312  {
1313  // count up breakpoints
1314  if( dsPtr->timeStepsBreakpointFlag[i] == true )
1315  {
1316  breakpoints++;
1317  }
1318 
1319 #ifdef Xyce_DEBUG_HB
1320  if( debugLevel > 0 )
1321  {
1322  Xyce::dout() << "\t\t timeStep[ " << i << " ] = " << dsPtr->timeSteps[i];
1323  if( dsPtr->timeStepsBreakpointFlag[i] == true )
1324  {
1325  Xyce::dout() << " Breakpoint";
1326  }
1327  Xyce::dout() << std::endl;
1328  }
1329 #endif
1330  while( ( GoodTimePointIndex < size_ ) && (dsPtr->timeSteps[i] <= goodTimePoints_[GoodTimePointIndex]) && (goodTimePoints_[GoodTimePointIndex] < dsPtr->timeSteps[i+1]))
1331  {
1332  // found a good point so save the index
1333  goodIndicies.push_back( i );
1334  GoodTimePointIndex = GoodTimePointIndex+1;
1335  }
1336  }
1337 
1338  for(int i=0; i<size_; i++ )
1339  {
1340  int currentIndex = goodIndicies[i];
1341  N_LAS_Vector * firstSolVecPtr = dsPtr->fastTimeSolutionVec[currentIndex];
1342  N_LAS_Vector * secondSolVecPtr = dsPtr->fastTimeSolutionVec[currentIndex+1];
1343 
1344  N_LAS_Vector * firstStateVecPtr = dsPtr->fastTimeStateVec[currentIndex];
1345  N_LAS_Vector * secondStateVecPtr = dsPtr->fastTimeStateVec[currentIndex+1];
1346 
1347  N_LAS_Vector * firstQVecPtr = dsPtr->fastTimeQVec[currentIndex];
1348  N_LAS_Vector * secondQVecPtr = dsPtr->fastTimeQVec[currentIndex+1];
1349 
1350  N_LAS_Vector * firstStoreVecPtr = dsPtr->fastTimeStoreVec[currentIndex];
1351  N_LAS_Vector * secondStoreVecPtr = dsPtr->fastTimeStoreVec[currentIndex+1];
1352 
1353  double fraction = (goodTimePoints_[i] - dsPtr->timeSteps[currentIndex])/(dsPtr->timeSteps[currentIndex+1] - dsPtr->timeSteps[currentIndex]);
1354 
1355  RCP<N_LAS_Vector> InterpICSolVecPtr = rcp( new N_LAS_Vector( *secondSolVecPtr ) );
1356  RCP<N_LAS_Vector> InterpICStateVecPtr = rcp( new N_LAS_Vector( *secondStateVecPtr ) );
1357  RCP<N_LAS_Vector> InterpICQVecPtr = rcp( new N_LAS_Vector( *secondQVecPtr ) );
1358  RCP<N_LAS_Vector> InterpICStoreVecPtr = rcp( new N_LAS_Vector( *secondStoreVecPtr ) );
1359 
1360  InterpICSolVecPtr->putScalar(0.0);
1361  InterpICStateVecPtr->putScalar(0.0);
1362  InterpICQVecPtr->putScalar(0.0);
1363  InterpICStoreVecPtr->putScalar(0.0);
1364 
1365  InterpICSolVecPtr->linearCombo(-1.0, *firstSolVecPtr, 1.0, *secondSolVecPtr );
1366  InterpICSolVecPtr->linearCombo(1.0, *firstSolVecPtr, fraction , *InterpICSolVecPtr);
1367 
1368  InterpICStateVecPtr->linearCombo(-1.0, *firstStateVecPtr, 1.0, *secondStateVecPtr );
1369  InterpICStateVecPtr->linearCombo(1.0, *firstStateVecPtr, fraction , *InterpICStateVecPtr);
1370 
1371  InterpICQVecPtr->linearCombo(-1.0, *firstQVecPtr, 1.0, *secondQVecPtr );
1372  InterpICQVecPtr->linearCombo(1.0, *firstQVecPtr, fraction , *InterpICQVecPtr);
1373 
1374  InterpICStoreVecPtr->linearCombo(-1.0, *firstStoreVecPtr, 1.0, *secondStoreVecPtr );
1375  InterpICStoreVecPtr->linearCombo(1.0, *firstStoreVecPtr, fraction , *InterpICStoreVecPtr);
1376 
1377  goodSolutionVec_.push_back(InterpICSolVecPtr);
1378  goodStateVec_.push_back(InterpICStateVecPtr);
1379  goodQVec_.push_back(InterpICQVecPtr);
1380  goodStoreVec_.push_back(InterpICStoreVecPtr);
1381  }
1382 
1383  // Clean up the fast time data since we are finished computing the initial condition.
1384  // The fast time data can take a considerable amount of memory for large problems.
1385  dsPtr->resetFastTimeData();
1386 
1387  return true;
1388 }
1389 
1390 } // namespace Analysis
1391 } // namespace Xyce
1392