Xyce  6.1
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-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_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.167.2.1 $
35 // Revision Date : $Date: 2015/04/02 18:20:07 $
36 // Current Owner : $Author: tvrusso $
37 //-----------------------------------------------------------------------------
38 #include <Xyce_config.h>
39 
40 #include <N_ANP_AnalysisManager.h>
41 #include <N_ANP_DCSweep.h>
42 #include <N_ANP_HB.h>
43 #include <N_ANP_OutputMgrAdapter.h>
44 #include <N_ANP_Report.h>
45 #include <N_ANP_Transient.h>
46 #include <N_DEV_DeviceMgr.h>
47 #include <N_IO_ActiveOutput.h>
48 #include <N_IO_CmdParse.h>
49 #include <N_IO_PkgOptionsMgr.h>
50 #include <N_LAS_BlockSystemHelpers.h>
51 #include <N_LAS_BlockVector.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_LOA_HBLoader.h>
58 #include <N_NLS_Manager.h>
59 #include <N_PDS_ParMap.h>
60 #include <N_TIA_DataStore.h>
62 #include <N_TIA_StepErrorControl.h>
64 #include <N_UTL_APFT.h>
65 #include <N_UTL_Diagnostic.h>
66 #include <N_UTL_ExtendedString.h>
67 #include <N_UTL_FFTInterface.hpp>
68 #include <N_UTL_FeatureTest.h>
69 #include <N_UTL_MachDepParams.h>
70 #include <N_UTL_Math.h>
71 #include <N_UTL_Timer.h>
72 
73 #include <Teuchos_BLAS.hpp>
74 #include <Teuchos_Utils.hpp>
75 #include <Teuchos_ScalarTraits.hpp>
76 #include <Teuchos_SerialDenseMatrix.hpp>
77 #include <Teuchos_SerialDenseVector.hpp>
78 #include <Teuchos_SerialDenseHelpers.hpp>
79 #include <Teuchos_SerialDenseSolver.hpp>
80 
81 #include <N_PDS_Comm.h>
82 
83 using Teuchos::rcp;
84 using Teuchos::RCP;
85 using Teuchos::rcp_dynamic_cast;
86 
87 namespace Xyce {
88 namespace Analysis {
89 
90 //-----------------------------------------------------------------------------
91 // Function : HB::HB( AnalysisManager * )
92 // Purpose :
93 // Special Notes :
94 // Scope : public
95 // Creator : Todd Coffey, SNL
96 // Creation Date : 09/18/2008
97 //-----------------------------------------------------------------------------
99  AnalysisManager & analysis_manager,
100  Linear::System & linear_system,
101  Nonlinear::Manager & nonlinear_manager,
102  Device::DeviceMgr & device_manager,
103  Linear::Builder & builder,
104  Topo::Topology & topology)
105  : AnalysisBase(analysis_manager, "HB"),
106  StepEventListener(&analysis_manager),
107  analysisManager_(analysis_manager),
108  loader_(analysis_manager.getLoader()),
109  linearSystem_(linear_system),
110  nonlinearManager_(nonlinear_manager),
111  deviceManager_(device_manager),
112  builder_(builder),
113  topology_(topology),
114  hbLoaderPtr_(0),
115  hbBuilderPtr_(),
116  hbLinearSystem_(0),
117  isPaused(false),
118  startDCOPtime(0.0),
119  endTRANtime(0.0),
120  isTransient_(false),
121  test_(false),
122  size_(21),
123  freqs_(),
124  freqsGiven_(false),
125  period_(1.0),
126  startUpPeriods_(0),
127  startUpPeriodsGiven_(false),
128  saveIcData_(false),
129  precFactory_(0),
130  taHB_(1),
131  voltLimFlag_(1),
132  intmodMax_(0),
133  method_("APFT"),
134  intmodMaxGiven_(false),
135  fastTimeDisc_(N_MPDE_Discretization::Backward),
136  fastTimeDiscOrder_(1),
137  resetForStepCalledBefore_(false)
138 {
140 }
141 
142 //-----------------------------------------------------------------------------
143 // Function : HB::~HB
144 // Purpose :
145 // Special Notes :
146 // Scope : public
147 // Creator :
148 // Creation Date :
149 //-----------------------------------------------------------------------------
151 {
152  delete hbLoaderPtr_;
153  delete hbLinearSystem_;
154  delete precFactory_;
155 }
156 
157 //-----------------------------------------------------------------------------
158 // Function : HB::notify
159 // Purpose :
160 // Special Notes :
161 // Scope : public
162 // Creator : Dave Baur
163 // Creation Date :
164 //-----------------------------------------------------------------------------
165 void HB::notify(const StepEvent &event)
166 {
167  if (event.state_ == StepEvent::STEP_STARTED)
168  {
170 
172  {
173  goodSolutionVec_.clear();
174  goodStateVec_.clear();
175  goodQVec_.clear();
176  goodStoreVec_.clear();
177 
179 
183 
184  // un-set the fast source flag in the devices
185  std::vector<std::string> srcVec;
188 
190 
192  deviceManager_.setMPDEFlag( false );
193 
202  topology_);
203 
206 
207  analysisManager_.getXyceTranTimer().resetStartTime();
208  }
209 
211  }
212 }
213 
214 //-----------------------------------------------------------------------------
215 // Function : HB::getDoubleDCOPStep
216 // Purpose :
217 // Special Notes :
218 // Scope : public
219 // Creator : Eric Keiter
220 // Creation Date : 3/24/2014
221 //-----------------------------------------------------------------------------
223 {
226  else
227  return 0;
228 }
229 
230 //-----------------------------------------------------------------------------
231 // Function : HB::getDCOPFlag
232 // Purpose :
233 // Special Notes :
234 // Scope : public
235 // Creator : Eric Keiter
236 // Creation Date : 3/24/2014
237 //-----------------------------------------------------------------------------
238 bool HB::getDCOPFlag() const
239 {
242 
243  // DCSweep is a special case in the HB analysis type. The HB calculation is
244  // performed through a DC analysis object. However, this function (getDCOPFlag)
245  // is called (ultimately) from the device package to determine a bunch of
246  // state-dependent load decisions. For an HB calculation, it should NOT
247  // do a DCOP load. It needs to do a full transient load.
248  else
249  return false;
250 }
251 
252 //-----------------------------------------------------------------------------
253 // Function : HB::run()
254 // Purpose :
255 // Special Notes :
256 // Scope : public
257 // Creator : Todd Coffey, SNL
258 // Creation Date : 09/18/2008
259 //-----------------------------------------------------------------------------
260 bool HB::doRun()
261 {
262  return doInit() && doLoopProcess() && doFinish();
263 }
264 
265 //-----------------------------------------------------------------------------
266 // Function : HB::init()
267 // Purpose :
268 // Special Notes :
269 // Scope : public
270 // Creator : Todd Coffey, SNL
271 // Creation Date : 09/18/2008
272 //-----------------------------------------------------------------------------
274 {
275  Xyce::lout() << " ***** Running HB initial conditions....\n" << std::endl;
276 
277  if (DEBUG_HB)
278  Xyce::dout() << std::endl
279  << section_divider << std::endl
280  << " HB::init()" << std::endl;
281 
283 
284  setFreqPoints_();
285 
286  period_ = 1.0/freqPoints_[(size_ - 1)/2 + 1];
287 
288  if (DEBUG_HB)
289  Xyce::dout() << "HB period =" << period_ << std::endl;
290 
291  fastTimes_.resize(size_);
292 
293  goodTimePoints_.resize(size_);
294 
295  if (freqs_.size() == 1)
296  {
297  double TimeStep = period_/size_;
298  timeSteps_.push_back( TimeStep );
299 
300  for( int i = 0; i < size_; ++i )
301  {
302  fastTimes_[i] = i*TimeStep;
303  }
304  }
305  else
306  {
307  setTimePoints_();
308  }
309 
311 
312  setInitialGuess();
313 
315 
316  // now that we have size_, continue with the initialization of objects for HB
317  mpdeDiscPtr_ = rcp(new N_MPDE_Discretization(fastTimeDisc_, fastTimeDiscOrder_));
318  hbBuilderPtr_ = rcp(new Linear::HBBuilder(size_, mpdeDiscPtr_));
319 
320  if (DEBUG_HB)
321  Xyce::dout() << "HB::init(): Generate Maps\n";
322 
323  hbBuilderPtr_->generateMaps( rcp(pdsMgrPtr_->getParallelMap( Parallel::SOLUTION ), false),
324  rcp(pdsMgrPtr_->getParallelMap( Parallel::SOLUTION_OVERLAP_GND ), false) );
325  hbBuilderPtr_->generateStateMaps( rcp(pdsMgrPtr_->getParallelMap( Parallel::STATE ),false) );
326  hbBuilderPtr_->generateStoreMaps( rcp(pdsMgrPtr_->getParallelMap( Parallel::STORE ),false) );
327  hbBuilderPtr_->generateLeadCurrentMaps( rcp(pdsMgrPtr_->getParallelMap( Parallel::LEADCURRENT ),false) );
328  hbBuilderPtr_->generateGraphs( *pdsMgrPtr_->getMatrixGraph( Parallel::JACOBIAN ));
329 
330  HBICVectorPtr_ = hbBuilderPtr_->createTimeDomainBlockVector();
331  HBICStateVectorPtr_ = hbBuilderPtr_->createTimeDomainStateBlockVector();
332  HBICStoreVectorPtr_ = hbBuilderPtr_->createTimeDomainStoreBlockVector();
333  HBICQVectorPtr_ = hbBuilderPtr_->createTimeDomainBlockVector();
334 
335  HBICVectorFreqPtr_ = hbBuilderPtr_->createExpandedRealFormTransposeBlockVector();
336 
337  // set the fast source flag in the devices
338  std::vector<std::string> srcVec;
339  deviceManager_.registerFastSources(pdsMgrPtr_->getPDSComm()->comm(), srcVec );
340 
341  //nonlinearManager_.getHBOptions(saved_nlHBOB_);
342 
343  // Create HB Loader.
344  delete hbLoaderPtr_;
347  hbLoaderPtr_->registerAppLoader( rcp(&loader_, false) );
348 
349  // Create DFT for HB Loader
350  // NOTE: For single-tone HB the DFT will probably be a FFT, for multi-tone a specialized
351  // implementation of the Util::DFTInterfaceDecl will need to be made and registered with
352  // the HB loader.
353 
354  ftInData_.resize( size_ );
355  ftOutData_.resize( size_ +1 );
356  iftInData_.resize( size_ +1 );
357  iftOutData_.resize( size_ );
358  if (freqs_.size() == 1)
359  {
360  if (ftInterface_ == Teuchos::null)
361  {
362  ftInterface_ = Teuchos::rcp( new N_UTL_FFTInterface<std::vector<double> >( size_ ) );
363  ftInterface_->registerVectors( ftInData_, &ftOutData_, iftInData_, &iftOutData_ );
364  }
365  else if (ftInterface_->getFFTInterface()->getSignalLength() != size_)
366  {
367  ftInterface_ = Teuchos::rcp( new N_UTL_FFTInterface<std::vector<double> >( size_ ) );
368  ftInterface_->registerVectors( ftInData_, &ftOutData_, iftInData_, &iftOutData_ );
369  }
370  hbLoaderPtr_->registerDFTInterface( ftInterface_->getFFTInterface() );
371  }
372  else
373  {
374  createFT_();
375 
376  dftInterface_ = Teuchos::rcp( new N_UTL_APFT<std::vector<double> >( idftMatrix_, dftMatrix_ ) );
377  dftInterface_->registerVectors( Teuchos::rcp( &ftInData_, false ), Teuchos::rcp( &ftOutData_, false ), Teuchos::rcp( &iftInData_, false ), Teuchos::rcp( &iftOutData_, false ) );
379  }
380 
381  if (taHB_==1)
382  {
383  // Pick up IC data from the initial transient.
384  for (int i=0 ; i<size_ ; ++i)
385  {
386  if (DEBUG_HB && isActive(Diag::HB_FAST_TIMES))
387  Xyce::dout() << "HB::init(): Loading initial condition data from time: fastTimes_["
388  << i << "] = " << fastTimes_[i] << std::endl;
389 
390  HBICVectorPtr_->block(i) = *(goodSolutionVec_[i]);
391  HBICStateVectorPtr_->block(i) = *(goodStateVec_[i]);
392  HBICQVectorPtr_->block(i) = *(goodQVec_[i]);
393  HBICStoreVectorPtr_->block(i) = *(goodStoreVec_[i]);
394  }
395 
397 
398  }
399 
400  if (DEBUG_HB && isActive(Diag::HB_PRINT_VECTORS))
401  {
402  Xyce::dout() << "HB Initial Condition Solution!\n";
403  HBICVectorPtr_->printPetraObject(std::cout);
404  Xyce::dout() << "HB Initial Condition State Vector!\n";
405  HBICStateVectorPtr_->printPetraObject(std::cout);
406  Xyce::dout() << "HB Initial Condition Store Vector!\n";
407  HBICStoreVectorPtr_->printPetraObject(std::cout);
408  }
409 
410  //Destroy Solvers, etc. from IC phase and prepare for HB
411  //-----------------------------------------
412 
414 
415  deviceManager_.setMPDEFlag( true );
417 
418  //-----------------------------------------
419 
420  //Finish setup of HB Loader
421  //-----------------------------------------
422  goodTimePoints_.resize(size_+1);
424 
425 
427 
429 
430  //-----------------------------------------
431  //Construct Solvers, etc. for HB Phase
432  //-----------------------------------------
433  delete hbLinearSystem_;
434  hbLinearSystem_ = new Linear::System();
435  //-----------------------------------------
436 
437  //hack needed by TIA initialization currently
438  hbBuilderPtr_->registerPDSManager( pdsMgrPtr_ );
439  hbLinearSystem_->registerPDSManager( pdsMgrPtr_ );
440  hbLinearSystem_->registerBuilder( &*hbBuilderPtr_ );
441 
442  hbLinearSystem_->initializeSystem();
443 
444  // Give NLS Manager the same old nonlinearEquationLoader as it just calls the TIA loader in newDAE
445  // nonlinearManager_.registerLinearSystem( hbLinearSystem_ );
448 
449  // Let the HB loader know that the application of the operator is matrix free
451 
452  if (!precFactory_)
453  {
454  // Generate the HB preconditioner factory.
455  precFactory_ = new Linear::HBPrecondFactory(saved_lsHBOB_, builder_);
456  }
457 
458  // Register application loader with preconditioner factory
459  precFactory_->registerHBLoader( rcp(hbLoaderPtr_, false) );
460  precFactory_->registerHBBuilder( hbBuilderPtr_ );
461  precFactory_->setFastTimes( goodTimePoints_ );
462  precFactory_->setTimeSteps( timeSteps_ );
463  precFactory_->setHBFreqs( freqPoints_ );
464 
466  //-----------------------------------------
467 
468  //Initialization of Solvers, etc. for HB Phase
469  //-----------------------------------------
470  //Dummy call to setup time integrator for transient
472 
474 
476 
478 
481 
482  if (DEBUG_HB)
483  {
484  Xyce::dout() << section_divider << std::endl;
485  }
486 
487  return true;
488 
489 }
490 
491 //-----------------------------------------------------------------------------
492 // Function : HB::loopProcess()
493 // Purpose :
494 // Special Notes :
495 // Scope : public
496 // Creator : Todd Coffey, SNL
497 // Creation Date : 09/18/2008
498 //-----------------------------------------------------------------------------
500 {
501  bool returnValue = true;
502 
503  Xyce::lout() << " ***** Beginning full HB simulation....\n" << std::endl;
504 
505  if (DEBUG_HB)
506  {
507  Xyce::dout() << std::endl
508  << section_divider << std::endl
509  << " HB::loopProcess" << std::endl;
510  }
511 
513  *(dsPtr->nextSolutionPtr) = *(HBICVectorFreqPtr_.get());
514  *(dsPtr->nextStatePtr) = *(HBICStateVectorPtr_.get());
515  *(dsPtr->nextStorePtr) = *(HBICStoreVectorPtr_.get());
516 
517  // try to run the problem
518  {
520  currentAnalysisObject_ = &dc_sweep;
522  returnValue = dc_sweep.doRun();
523 
524  // Add in simulation times
525  accumulateStatistics_(dc_sweep);
526 
527  // print out analysis info
528  Xyce::lout() << " ***** Harmonic Balance Computation Summary *****" << std::endl;
529  dc_sweep.printLoopInfo( 0, 0 );
530 
532 
534  }
535 
536  if (DEBUG_HB)
537  {
538  dout() << section_divider << std::endl;
539  }
540 
541  return returnValue;
542 }
543 
544 //-----------------------------------------------------------------------------
545 // Function : HB::processSuccessfulDCOP()
546 // Purpose :
547 // Special Notes :
548 // Scope : public
549 // Creator : Todd Coffey, SNL
550 // Creation Date : 09/18/2008
551 //-----------------------------------------------------------------------------
553 {
554  return false;
555 }
556 
557 //-----------------------------------------------------------------------------
558 // Function : HB::processSuccessfulStep()
559 // Purpose :
560 // Special Notes :
561 // Scope : public
562 // Creator : Todd Coffey, SNL
563 // Creation Date : 09/18/2008
564 //-----------------------------------------------------------------------------
566 {
567  return false;
568 }
569 
570 //-----------------------------------------------------------------------------
571 // Function : HB::processFailedStep
572 // Purpose :
573 // Special Notes :
574 // Scope : public
575 // Creator : Todd Coffey, SNL
576 // Creation Date : 09/18/2008
577 //-----------------------------------------------------------------------------
579 {
580  return false;
581 }
582 
583 //-----------------------------------------------------------------------------
584 // Function : HB::processFailedDCOP
585 // Purpose :
586 // Special Notes :
587 // Scope : public
588 // Creator : Todd Coffey, SNL
589 // Creation Date : 09/18/2008
590 //-----------------------------------------------------------------------------
592 {
593  return false;
594 }
595 
596 //-----------------------------------------------------------------------------
597 // Function : HB::finish
598 // Purpose :
599 // Special Notes :
600 // Scope : public
601 // Creator : Todd Coffey, SNL
602 // Creation Date : 09/18/2008
603 //-----------------------------------------------------------------------------
605 {
607 
608  return true;
609 }
610 
612 {
613  return true;
614 }
615 
616 //-----------------------------------------------------------------------------
617 // Function : HB::finalVerboseOutput
618 // Purpose :
619 // Special Notes :
620 // Scope : public
621 // Creator : Todd Coffey, SNL
622 // Creation Date : 09/18/2008
623 //-----------------------------------------------------------------------------
625 {
626  return false;
627 }
628 
629 //-----------------------------------------------------------------------------
630 // Function : AnalysisManager::setHBAnalysisParams
631 // Purpose : Sets the HB sweep calculation parameters (from .HB)
632 // Special Notes :
633 // Scope : public
634 // Creator : Todd Coffey, Ting Mei
635 // Creation Date : 7/30/08
636 //-----------------------------------------------------------------------------
637 bool
639  const Util::OptionBlock & option_block)
640 {
641  for (Util::ParamList::const_iterator it = option_block.begin(), end = option_block.end(); it != end; ++it)
642  {
643  if ((*it).uTag() == "FREQ")
644  {
645  freqs_ = (*it).getValue<std::vector<double> >();
646  freqsGiven_ = true;
647  }
648  }
649 
650  if (freqs_[0] <= 0.0 )
651  {
652  Report::UserError() << "Frequency of oscillation " << freqs_[0] << " is less than or equal to zero, invalid .HB specification";
653  }
654 
655  if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
656  {
657  dout() << section_divider << std::endl
658  << "HB transient simulation parameters"
659  //<< Util::push << std::endl
660  << std::endl
661  << "HB frequency = " << freqs_[0] << std::endl
662  //<< Util::pop << std::endl;
663  << std::endl;
664  }
665 
666  return true;
667 }
668 
669 
670 //-----------------------------------------------------------------------------
671 // Function : HB::setHBIntParams
672 // Purpose :
673 // Special Notes :
674 // Scope : public
675 // Creator : Heidi Thornquist
676 // Creation Date : 05/13/13
677 //-----------------------------------------------------------------------------
678 bool HB::setHBIntParams(const Util::OptionBlock & OB)
679 {
680  for(Util::ParamList::const_iterator iterPL = OB.begin(), endPL = OB.end(); iterPL != endPL; ++iterPL )
681  {
682  ExtendedString tag = iterPL->tag();
683  tag.toUpper();
684 
685  if (std::string(tag,0,7) == "NUMFREQ" )
686  {
687 
688  size_ = iterPL->getImmutableValue<int>() *2 + 1;
689 
690  numFreqs_.push_back(size_);
691  }
692  else if ( tag == "STARTUPPERIODS" )
693  {
694  startUpPeriods_ = iterPL->getImmutableValue<int>();
695 
696  if (startUpPeriods_ > 0)
697  startUpPeriodsGiven_ = true;
698  }
699  else if( tag == "SAVEICDATA" )
700  {
701  saveIcData_ = true;
702  }
703  else if( tag == "TEST" )
704  {
705  test_ = static_cast<bool> (iterPL->getImmutableValue<int>());
706  }
707  else if (tag == "DEBUGLEVEL" )
708  {
709  setHBDebugLevel(iterPL->getImmutableValue<int>());
710  }
711  else if ( tag == "TAHB" )
712  {
713  taHB_ = iterPL->getImmutableValue<int>();
714  }
715  else if ( tag == "VOLTLIM" )
716  {
717  voltLimFlag_ = static_cast<bool> (iterPL->getImmutableValue<int>());
718  }
719  else if ( tag == "INTMODMAX" )
720  {
721  intmodMax_ = iterPL->getImmutableValue<int>();
722 
723  if ( intmodMax_ > 0)
724  intmodMaxGiven_ = true;
725  }
726  else if ( tag == "METHOD" )
727  {
728  ExtendedString stringVal ( iterPL->stringValue() );
729  stringVal.toUpper();
730  method_ = stringVal;
731  }
732  else
733  {
734  UserWarning(*this) << "Unrecognized HBINT option " << tag;
735  }
736  }
737 
738  if (numFreqs_.size() != 0 && numFreqs_.size() != freqs_.size() )
739  {
740  Report::UserError() << "The size of numFreq does not match the number of tones in .hb!";
741  }
742 
743 
744  if (numFreqs_.size() == 0 )
745  {
746 
747  numFreqs_.resize( freqs_.size() ) ;
748  for (int i=0; i < freqs_.size(); i++ )
749  {
750  numFreqs_[i] = size_;
751  }
752 
753  }
754 
755  return true;
756 }
757 
758 //-----------------------------------------------------------------------------
759 // Function : HB::setLinSol
760 // Purpose : this is needed for .STEP to work with HB
761 // Special Notes :
762 // Scope : public
763 // Creator : Eric R. Keiter
764 // Creation Date : 7/12/2013
765 //-----------------------------------------------------------------------------
766 bool HB::setLinSol(const Util::OptionBlock & OB)
767 {
768  // Save the non-HB linear solver option block
769  saved_lsOB_ = OB;
770 
771  return true;
772 }
773 
774 //-----------------------------------------------------------------------------
775 // Function : HB::setHBLinSol
776 // Purpose :
777 // Special Notes :
778 // Scope : public
779 // Creator : Heidi Thornquist
780 // Creation Date : 5/13/13
781 //-----------------------------------------------------------------------------
782 bool HB::setHBLinSol(const Util::OptionBlock & OB, Linear::Builder &builder)
783 {
784  // Save the HB linear solver option block
785  saved_lsHBOB_ = OB;
786 
787  // Generate the HB preconditioner factory.
788  precFactory_ = new Linear::HBPrecondFactory(OB, builder);
789 
790  return true;
791 }
792 
793 //-----------------------------------------------------------------------------
794 // Function : HB::isAnalysis
795 // Purpose :
796 // Special Notes :
797 // Scope : public
798 // Creator : Heidi Thornquist
799 // Creation Date : 5/13/13
800 // Notes : Alternatively, we could try to cast the analysis object
801 // : However, this method is called a lot.
802 //-----------------------------------------------------------------------------
803 bool HB::isAnalysis( int analysis_type ) const
804 {
805  return analysis_type == ANP_MODE_TRANSIENT && isTransient_;
806 }
807 
808 //-----------------------------------------------------------------------------
809 // Function : HB::prepareHBOutput
810 // Purpose :
811 // Special Notes :
812 // Scope : public
813 // Creator : Eric Keiter, 9233, Computational Sciences
814 // Creation Date : 08/20/07
815 //-----------------------------------------------------------------------------
817  Linear::Vector & solnVecPtr,
818  std::vector<double> & timePoints,
819  std::vector<double> & freqPoints,
820  RCP<Linear::BlockVector> & timeDomainSolnVec,
821  RCP<Linear::BlockVector> & freqDomainSolnVecReal,
822  RCP<Linear::BlockVector> & freqDomainSolnVecImag,
823  RCP<Linear::BlockVector> & timeDomainStoreVec,
824  RCP<Linear::BlockVector> & freqDomainStoreVecReal,
825  RCP<Linear::BlockVector> & freqDomainStoreVecImag,
826  RCP<Linear::BlockVector> & timeDomainLeadCurrentVec,
827  RCP<Linear::BlockVector> & freqDomainLeadCurrentVecReal,
828  RCP<Linear::BlockVector> & freqDomainLeadCurrentVecImaginary,
829  RCP<Linear::BlockVector> & timeDomainJunctionVoltageVec,
830  RCP<Linear::BlockVector> & freqDomainJunctionVoltageVecReal,
831  RCP<Linear::BlockVector> & freqDomainJunctionVoltageVecImaginary
832  ) const
833 {
834  Linear::BlockVector & blockSolVecPtr = dynamic_cast<Linear::BlockVector &>(solnVecPtr);
835 
836  Teuchos::RCP<Linear::BlockVector> bStoreVecFreqPtr_ = hbLoaderPtr_->getStoreVecFreqPtr();
837  Teuchos::RCP<Linear::BlockVector> bLeadCurrentVecFreqPtr_ = hbLoaderPtr_->getLeadCurrentVecFreqPtr();
838  timeDomainStoreVec = hbBuilderPtr_->createTimeDomainStoreBlockVector();
839  timeDomainLeadCurrentVec = hbBuilderPtr_->createTimeDomainLeadCurrentBlockVector();
840  timeDomainJunctionVoltageVec = hbBuilderPtr_->createTimeDomainLeadCurrentBlockVector();
841  if (bStoreVecFreqPtr_->blockCount() > 0 )
842  {
843  hbLoaderPtr_->permutedIFT(*bStoreVecFreqPtr_, &*timeDomainStoreVec);
844  }
845 
846  if (bLeadCurrentVecFreqPtr_->blockCount() > 0 )
847  {
848  hbLoaderPtr_->permutedIFT(*bLeadCurrentVecFreqPtr_, &*timeDomainLeadCurrentVec);
849  }
850 
851  //TD solution
852  timeDomainSolnVec = hbBuilderPtr_->createTimeDomainBlockVector();
853  int blockCount = timeDomainSolnVec->blockCount();
854  int N = timeDomainSolnVec->block(0).globalLength();
855  timePoints.resize(size_);
856  timePoints = fastTimes_;
857 
858  freqPoints = freqPoints_;
859 
860  // Create individual block vectors to store the real and imaginary parts separately.
861  Teuchos::RCP<N_PDS_ParMap> baseMap = Teuchos::rcp_const_cast<N_PDS_ParMap>( hbBuilderPtr_->getBaseSolutionMap() );
862  Teuchos::RCP<N_PDS_ParMap> globalMap = Linear::createBlockParMap( blockCount, *baseMap );
863  freqDomainSolnVecReal = Teuchos::rcp( new Linear::BlockVector( blockCount, globalMap, baseMap ) );
864  freqDomainSolnVecImag = Teuchos::rcp( new Linear::BlockVector( blockCount, globalMap, baseMap ) );
865 
866  hbLoaderPtr_->permutedIFT(blockSolVecPtr, &*timeDomainSolnVec);
867 
868  // Now copy over the frequency domain solution, real and imaginary parts separately, into the output vectors.
869  for (int j=0; j<N; j++)
870  {
871  // See if this time-domain solution variable is owned by the local processor.
872  // If so, this processor owns the entire j-th block of the blockSolVecPtr vector,
873  // and the j-th entry of every block in the freqDomainSo
874  // lnVec[Real/Imag] vector.
875  int lid = baseMap->globalToLocalIndex( j );
876  Linear::Vector& solBlock = blockSolVecPtr.block( j );
877 
878  Linear::Vector& realVecRef = freqDomainSolnVecReal->block((blockCount-1)/2);
879  Linear::Vector& imagVecRef = freqDomainSolnVecImag->block((blockCount-1)/2);
880 
881  if (lid >= 0)
882  {
883  realVecRef[lid] = solBlock[0];
884  imagVecRef[lid] = solBlock[1];
885  }
886 
887  for (int i=1; i <= (blockCount-1)/2; ++i)
888  {
889  Linear::Vector& realVecRef_neg = freqDomainSolnVecReal->block((blockCount-1)/2 - i);
890  Linear::Vector& imagVecRef_neg = freqDomainSolnVecImag->block((blockCount-1)/2 - i);
891  Linear::Vector& realVecRef_pos = freqDomainSolnVecReal->block((blockCount-1)/2 + i);
892  Linear::Vector& imagVecRef_pos = freqDomainSolnVecImag->block((blockCount-1)/2 + i);
893 
894  if (lid >= 0)
895  {
896  realVecRef_neg[lid] = solBlock[ 2*(blockCount-i) ];
897  imagVecRef_neg[lid] = solBlock[ 2*(blockCount-i) + 1 ];
898  realVecRef_pos[lid] = solBlock[ 2*i ];
899  imagVecRef_pos[lid] = solBlock[ 2*i+1 ];
900  }
901  }
902  }
903 
904  // proceed to store variables
905  Teuchos::RCP<N_PDS_ParMap> baseStoreMap = Teuchos::rcp_const_cast<N_PDS_ParMap>( hbBuilderPtr_->getBaseStoreMap() );
906  Teuchos::RCP<N_PDS_ParMap> globalStoreMap = Linear::createBlockParMap( blockCount, *baseStoreMap );
907  freqDomainStoreVecReal = Teuchos::rcp( new Linear::BlockVector( blockCount, globalStoreMap, baseStoreMap ) );
908  freqDomainStoreVecImag = Teuchos::rcp( new Linear::BlockVector( blockCount, globalStoreMap, baseStoreMap ) );
909 
910  N = timeDomainStoreVec->block(0).globalLength();
911 
912  for (int j=0; j<N; j++)
913  {
914  // See if this time-domain solution variable is owned by the local processor.
915  // If so, this processor owns the entire j-th block of the blockSolVecPtr vector,
916  // and the j-th entry of every block in the freqDomainSolnVec[Real/Imag] vector.
917  int lid = baseStoreMap->globalToLocalIndex( j );
918  Linear::Vector& storeBlock = bStoreVecFreqPtr_->block( j );
919 
920  Linear::Vector& realVecRef = freqDomainStoreVecReal->block((blockCount-1)/2);
921  Linear::Vector& imagVecRef = freqDomainStoreVecImag->block((blockCount-1)/2);
922 
923  if (lid >= 0)
924  {
925  realVecRef[lid] = storeBlock[0];
926  imagVecRef[lid] = storeBlock[1];
927  }
928 
929  for (int i=1; i <= (blockCount-1)/2; ++i)
930  {
931  Linear::Vector& realVecRef_neg = freqDomainStoreVecReal->block((blockCount-1)/2 - i);
932  Linear::Vector& imagVecRef_neg = freqDomainStoreVecImag->block((blockCount-1)/2 - i);
933  Linear::Vector& realVecRef_pos = freqDomainStoreVecReal->block((blockCount-1)/2 + i);
934  Linear::Vector& imagVecRef_pos = freqDomainStoreVecImag->block((blockCount-1)/2 + i);
935 
936  if (lid >= 0)
937  {
938  realVecRef_neg[lid] = storeBlock[ 2*(blockCount-i) ];
939  imagVecRef_neg[lid] = storeBlock[ 2*(blockCount-i) + 1 ];
940  realVecRef_pos[lid] = storeBlock[ 2*i ];
941  imagVecRef_pos[lid] = storeBlock[ 2*i+1 ];
942  }
943  }
944  }
945 
946  // lead current vector
947  Teuchos::RCP<N_PDS_ParMap> baseLeadCurrentMap = Teuchos::rcp_const_cast<N_PDS_ParMap>( hbBuilderPtr_->getBaseLeadCurrentMap() );
948  Teuchos::RCP<N_PDS_ParMap> globalLeadCurrentMap = Linear::createBlockParMap( blockCount, *baseLeadCurrentMap );
949  freqDomainLeadCurrentVecReal = Teuchos::rcp( new Linear::BlockVector( blockCount, globalLeadCurrentMap, baseLeadCurrentMap ) );
950  freqDomainLeadCurrentVecImaginary = Teuchos::rcp( new Linear::BlockVector( blockCount, globalLeadCurrentMap, baseLeadCurrentMap ) );
951  freqDomainJunctionVoltageVecReal = Teuchos::rcp( new Linear::BlockVector( blockCount, globalLeadCurrentMap, baseLeadCurrentMap ) );
952  freqDomainJunctionVoltageVecImaginary = Teuchos::rcp( new Linear::BlockVector( blockCount, globalLeadCurrentMap, baseLeadCurrentMap ) );
953 
954  N = timeDomainLeadCurrentVec->block(0).globalLength();
955  for (int j=0; j<N; j++)
956  {
957  // See if this time-domain solution variable is owned by the local processor.
958  // If so, this processor owns the entire j-th block of the blockSolVecPtr vector,
959  // and the j-th entry of every block in the freqDomainSolnVec[Real/Imag] vector.
960  int lid = baseLeadCurrentMap->globalToLocalIndex( j );
961  Linear::Vector& leadCurrentBlock = bLeadCurrentVecFreqPtr_->block( j );
962 
963  Linear::Vector& realVecRef1 = freqDomainLeadCurrentVecReal->block((blockCount-1)/2);
964  Linear::Vector& imagVecRef1 = freqDomainLeadCurrentVecImaginary->block((blockCount-1)/2);
965  Linear::Vector& realVecRef2 = freqDomainJunctionVoltageVecReal->block((blockCount-1)/2);
966  Linear::Vector& imagVecRef2 = freqDomainJunctionVoltageVecImaginary->block((blockCount-1)/2);
967 
968  if (lid >= 0)
969  {
970  realVecRef1[lid] = leadCurrentBlock[0];
971  imagVecRef1[lid] = leadCurrentBlock[1];
972  realVecRef2[lid] = leadCurrentBlock[0];
973  imagVecRef2[lid] = leadCurrentBlock[1];
974  }
975 
976  for (int i=1; i <= (blockCount-1)/2; ++i)
977  {
978  Linear::Vector& realVecRef_neg1 = freqDomainLeadCurrentVecReal->block((blockCount-1)/2 - i);
979  Linear::Vector& imagVecRef_neg1 = freqDomainLeadCurrentVecImaginary->block((blockCount-1)/2 - i);
980  Linear::Vector& realVecRef_pos2 = freqDomainLeadCurrentVecReal->block((blockCount-1)/2 + i);
981  Linear::Vector& imagVecRef_pos2 = freqDomainLeadCurrentVecImaginary->block((blockCount-1)/2 + i);
982 
983  Linear::Vector& realVecRef_neg3 = freqDomainJunctionVoltageVecReal->block((blockCount-1)/2 - i);
984  Linear::Vector& imagVecRef_neg3 = freqDomainJunctionVoltageVecImaginary->block((blockCount-1)/2 - i);
985  Linear::Vector& realVecRef_pos4 = freqDomainJunctionVoltageVecReal->block((blockCount-1)/2 + i);
986  Linear::Vector& imagVecRef_pos4 = freqDomainJunctionVoltageVecImaginary->block((blockCount-1)/2 + i);
987 
988  if (lid >= 0)
989  {
990  realVecRef_neg1[lid] = leadCurrentBlock[ 2*(blockCount-i) ];
991  imagVecRef_neg1[lid] = leadCurrentBlock[ 2*(blockCount-i) + 1 ];
992  realVecRef_pos2[lid] = leadCurrentBlock[ 2*i ];
993  imagVecRef_pos2[lid] = leadCurrentBlock[ 2*i+1 ];
994  realVecRef_neg3[lid] = leadCurrentBlock[ 2*(blockCount-i) ];
995  imagVecRef_neg3[lid] = leadCurrentBlock[ 2*(blockCount-i) + 1 ];
996  realVecRef_pos4[lid] = leadCurrentBlock[ 2*i ];
997  imagVecRef_pos4[lid] = leadCurrentBlock[ 2*i+1 ];
998  }
999  }
1000  }
1001 
1002  if (DEBUG_HB)
1003  {
1004  freqDomainSolnVecReal->printPetraObject(std::cout);
1005  freqDomainSolnVecImag->printPetraObject(std::cout);
1006 
1007  Xyce::dout() << "HB Store Vector FD" << std::endl;
1008 
1009  freqDomainStoreVecReal->printPetraObject(std::cout);
1010  freqDomainStoreVecImag->printPetraObject(std::cout);
1011  }
1012 }
1013 
1014 
1015 //-----------------------------------------------------------------------------
1016 // Function : HB::accumulateStatistics()
1017 // Purpose : Add in the statistics from the current analysis object
1018 // Special Notes :
1019 // Scope : private
1020 // Creator : Heidi Thornquist, 1355, Electrical Models & Simulation
1021 // Creation Date : 05/29/13
1022 //-----------------------------------------------------------------------------
1024 {
1025  hbStatCounts_ += analysis.stats_;
1026 }
1027 
1028 //-----------------------------------------------------------------------------
1029 // Function : HB::setFreqPoints_
1030 // Purpose : Set frequency spectrum for HB analysis.
1031 // Special Notes :
1032 // Scope : private
1033 // Creator : Ting Mei, SNL
1034 // Creation Date : 03/03/2014
1035 //-----------------------------------------------------------------------------
1037 {
1038  if ( !intmodMaxGiven_)
1039  {
1040  int maxValue = 0;
1041  if (numFreqs_.size() != 0 )
1042  // find the max of numFreqs
1043  {
1044  maxValue = (numFreqs_[0] - 1)/2;
1045  for (int i=1; i<numFreqs_.size(); ++i)
1046  {
1047  if ((numFreqs_[i] - 1)/2 > maxValue)
1048  maxValue = (numFreqs_[i] - 1)/2 ;
1049  }
1050  }
1051  else
1052  {
1053  maxValue = (size_ - 1)/2;
1054  }
1055  intmodMax_ = maxValue;
1056  }
1057 
1058  std::vector<int> k;
1059 
1060  int numAnalysisFreqs = freqs_.size();
1061 
1062  numPosFreqs.resize(numAnalysisFreqs);
1063 
1064  k.resize(numAnalysisFreqs);
1065 
1066  k[0] = 1;
1067 
1068  if (numFreqs_.size() != 0 )
1069  numPosFreqs[0] = (numFreqs_[0] - 1)/2;
1070  else
1071  numPosFreqs[0]= (size_ - 1)/2;
1072 
1073  int numTotalFrequencies;
1074 
1075  int numExtraFreqs = 0;
1076 
1077  if (numPosFreqs[0] > intmodMax_)
1078  {
1079  numExtraFreqs += ( numPosFreqs[0] - intmodMax_ );
1080  numFreqs_[0] = (intmodMax_*2 + 1);
1081  }
1082 
1083  numTotalFrequencies = numFreqs_[0];
1084 
1085  for (int i=1; i < numAnalysisFreqs; i++)
1086  {
1087  numPosFreqs[i] = (numFreqs_[i] - 1)/2;
1088 
1089  if (numPosFreqs[i] > intmodMax_)
1090  {
1091  numExtraFreqs += ( numPosFreqs[i] - intmodMax_ );
1092  numFreqs_[i] = (intmodMax_*2 + 1);
1093  }
1094 
1095  k[i] = k[i-1] * numFreqs_[i -1 ];
1096 
1097  numTotalFrequencies *= numFreqs_[i];
1098  }
1099 
1100  if (DEBUG_HB)
1101  {
1102  for (int i=0; i< numAnalysisFreqs; i++)
1103  {
1104  Xyce::dout() << "HB index " << i << std::endl;
1105  Xyce::dout() << "HB numPosFreqs =" << numPosFreqs[i] << std::endl;
1106  Xyce::dout() << "HB k =" << k[i] << std::endl;
1107  }
1108  Xyce::dout() << "HB numTotalFrequencies =" << numTotalFrequencies<< std::endl;
1109  Xyce::dout() << "HB numextrafreqs =" << numExtraFreqs << std::endl;
1110  }
1111 
1112  int numIndex = numTotalFrequencies;
1113 
1114  Teuchos::SerialDenseMatrix<int,double> indexMatrix(numAnalysisFreqs, numTotalFrequencies);
1115 
1116  if (DEBUG_HB)
1117  {
1118  Xyce::dout() << "HB intmodMax =" << intmodMax_ << std::endl;
1119  }
1120 
1121  int nextIndex;
1122 
1123  int idxMod, idxValues;
1124  int sumIndex;
1125 
1126  std::vector<int> goodIndex;
1127  for (int i=0; i < numIndex; i++) // column
1128  {
1129  nextIndex = i;
1130  sumIndex = 0;
1131 
1132  for (int j= (numAnalysisFreqs - 1); j >= 0; j-- ) // row
1133  {
1134  idxMod = nextIndex%k[j];
1135  idxValues = (nextIndex - idxMod)/k[j];
1136 
1137  indexMatrix (j, i) = static_cast<double>(idxValues - (numFreqs_[j] - 1)/2 );
1138  nextIndex = idxMod;
1139  sumIndex += abs(idxValues - (numFreqs_[j] - 1)/2 );
1140 
1141  }
1142 
1143  if( sumIndex <= intmodMax_)
1144  goodIndex.push_back(i);
1145  }
1146 
1147  int diaindexSize = goodIndex.size();
1148 
1149  Teuchos::SerialDenseMatrix<int,double> diaindexMatrix( numAnalysisFreqs, (diaindexSize + numExtraFreqs) );
1150  diaindexMatrix.putScalar(0.0);
1151 
1152  for (int i=0; i < diaindexSize; i++)
1153  {
1154  for (int j= (numAnalysisFreqs - 1); j >= 0; j-- )
1155  diaindexMatrix (j, i) = indexMatrix (j, goodIndex[i]);
1156  }
1157 
1158  if (DEBUG_HB)
1159  {
1160  for (int i=0; i< diaindexSize; i++)
1161  {
1162  dout() << "good index i = " << i << goodIndex[i] << std::endl;
1163  }
1164  dout() << " checking diamond indexMatrix" << std::endl;
1165  diaindexMatrix.print(dout());
1166 
1167  dout() << " checking indexMatrix" << std::endl;
1168  indexMatrix.print(dout());
1169  }
1170 
1171 
1172  int extraIndexPos = diaindexSize;
1173  for (int i=0; i < numAnalysisFreqs ; i++) // column
1174  {
1175 
1176  if (numPosFreqs[i] > intmodMax_)
1177  {
1178 
1179  for (int j=0; j < (numPosFreqs[i] - intmodMax_ ) ; j++)
1180  diaindexMatrix (i, extraIndexPos + j ) = static_cast<double>(intmodMax_ + j + 1 );
1181 
1182  extraIndexPos += (numPosFreqs[i] - intmodMax_ );
1183  }
1184  }
1185 
1186 
1187  if (DEBUG_HB)
1188  {
1189  dout() << " checking diamond indexMatrix after axis" << std::endl;
1190  diaindexMatrix.print(dout());
1191  }
1192 
1193 // get the positive frequencies
1194 
1195  std::vector<double> posfreqPoints_;
1196 
1197  int posindexSize = (diaindexSize - 1)/2;
1198  posfreqPoints_.resize(posindexSize + numExtraFreqs);
1199 
1200  Teuchos::SerialDenseMatrix<int,double> currindexMatrix( Teuchos::View, diaindexMatrix, numAnalysisFreqs, (posindexSize + numExtraFreqs), 0, posindexSize+1 );
1201  Teuchos::SerialDenseVector<int,double> currfreqPoints( Teuchos::View, &posfreqPoints_[0], (posindexSize + numExtraFreqs ) );
1202 
1203  Teuchos::SerialDenseVector<int,double> hbFreqs( Teuchos::View, &freqs_[0], numAnalysisFreqs);
1204 // Teuchos::SerialDenseVector<int,double> currWeightVector( Teuchos::View, &weightVector[i], oversampleRate*size_-(i+1) );
1205  currfreqPoints.multiply( Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, currindexMatrix, hbFreqs, 0.0 );
1206 
1207 
1208  if (DEBUG_HB)
1209  {
1210  dout() << "checking positive frequencies" << std::endl;
1211  currindexMatrix.print(dout());
1212  hbFreqs.print(dout());
1213  currfreqPoints.print(dout());
1214  }
1215 
1216  for (int i=0; i < posindexSize; i++)
1217  {
1218  if (posfreqPoints_[i] < 0.0)
1219  posfreqPoints_[i] = fabs( posfreqPoints_[i]);
1220  }
1221 
1222  std::sort(posfreqPoints_.begin(), posfreqPoints_.end() );
1223 
1224 
1225  if (DEBUG_HB)
1226  {
1227  for (int i=0; i< posfreqPoints_.size(); i++)
1228  dout() << "pos frequency point " << posfreqPoints_[i] << std::endl;
1229  }
1230 
1231  posfreqPoints_.erase(std::unique(posfreqPoints_.begin(), posfreqPoints_.end() ), posfreqPoints_.end() );
1232 
1233 
1234  if (abs( posfreqPoints_[0]) < 2.0*Util::MachineDependentParams::MachinePrecision() )
1235  posfreqPoints_.erase( posfreqPoints_.begin());
1236 
1237  size_ = ( posfreqPoints_.size() ) *2 + 1;
1238 
1239  if (DEBUG_HB)
1240  {
1241  for (int i=0; i<posfreqPoints_.size(); i++)
1242  {
1243  dout() << "pos frequency point after " << posfreqPoints_[i] << std::endl;
1244  }
1245 
1246  Xyce::dout() << "HB size =" << size_ << std::endl;
1247  }
1248 
1249  int i=0;
1250  freqPoints_.resize(size_);
1251 
1252  for( i = 0; i < size_; ++i )
1253  {
1254  if (i < (size_-1)/2)
1255  freqPoints_[i] = - posfreqPoints_[ (size_-1)/2 - i - 1 ];
1256  else if (i > (size_-1)/2)
1257  freqPoints_[i] = posfreqPoints_[ i - (size_-1)/2 - 1 ];
1258  else
1259  freqPoints_[i] = 0.0;
1260  }
1261 
1262  if (DEBUG_HB)
1263  {
1264  for (int i=0; i<freqPoints_.size(); i++)
1265  {
1266  dout() << " frequency point " << freqPoints_[i] << std::endl;
1267  }
1268  }
1269 
1270  return true;
1271 }
1272 
1273 //-----------------------------------------------------------------------------
1274 // Function : HB::setTimePoints_
1275 // Purpose : Set time points for multi-tone HB analysis.
1276 // Special Notes :
1277 // Scope : private
1278 // Creator : Heidi Thornquist and Ting Mei, SNL
1279 // Creation Date : 03/05/2014
1280 //-----------------------------------------------------------------------------
1282 {
1283  // NOTE: Need to make this parallel safe.
1284 
1285  // Resize fastTimes_ vector to be ready to receive from root processor.
1286  fastTimes_.resize (size_);
1287 
1288  int posFreq = (size_-1)/2;
1289  int oversampleRate = 5;
1290 // int periodSampleMultiplier = 3;
1291  int periodSampleMultiplier = 1;
1292 
1293  Teuchos::BLAS<int,double> blas;
1294  std::vector<double> testPoints(oversampleRate*size_);
1295 
1296  int myPID = pdsMgrPtr_->getPDSComm()->procID();
1297 
1298  if (myPID == 0)
1299  {
1300 
1301  for (int i=0; i<oversampleRate*size_; ++i)
1302  {
1303  testPoints[i] = periodSampleMultiplier*period_*((Teuchos::ScalarTraits<double>::random()+1)/2);
1304  }
1305 
1306  Teuchos::SerialDenseMatrix<int,double> testMatrix(size_,oversampleRate*size_);
1307  // NOTE: i represents frequency, j represents sample time
1308  // Set DC values first.
1309  for (int j=0; j<oversampleRate*size_; ++j)
1310  {
1311  testMatrix(0,j) = 1.0;
1312  }
1313  // Set rest of frequency values
1314  for (int i=1; i<=posFreq; i++)
1315  {
1316 // for (int j=0; j<oversampleRate*size_; j+2)
1317  for (int j=0; j<oversampleRate*size_; j++)
1318  {
1319  testMatrix(2*i-1,j) = cos(2*M_PI*freqPoints_[posFreq+i]*testPoints[j]);
1320  testMatrix(2*i,j) = sin(2*M_PI*freqPoints_[posFreq+i]*testPoints[j]);
1321  }
1322  }
1323 
1324  // Now for orthogonalization (yipeee)
1325  std::vector<double> weightVector(oversampleRate*size_);
1326  for (int i=0; i<size_; ++i)
1327  {
1328  // Find column with largest norm, choose as next vector for orthogonalization
1329  int maxIndex = 0;
1330  double maxValue = 0.0;
1331  for (int j=i; j<oversampleRate*size_; ++j)
1332  {
1333  Teuchos::SerialDenseMatrix<int,double> tempVector( Teuchos::View, testMatrix, size_, 1, 0, j );
1334  weightVector[j] = tempVector.normFrobenius();
1335 
1336  if (weightVector[j] > maxValue)
1337  {
1338  maxIndex = j;
1339  maxValue = weightVector[j];
1340  }
1341  }
1342 
1343 
1344  // Swap time and vector.
1345  std::swap( testPoints[i], testPoints[maxIndex] );
1346  Teuchos::SerialDenseVector<int,double> newSwapVector2 = Teuchos::getCol<int,double>( Teuchos::Copy, testMatrix, maxIndex );
1347  Teuchos::SerialDenseVector<int,double> newSwapVector = Teuchos::getCol<int,double>( Teuchos::View, testMatrix, i );
1348  Teuchos::setCol<int,double>( newSwapVector, maxIndex, testMatrix );
1349  Teuchos::setCol<int,double>( newSwapVector2, i, testMatrix );
1350 
1351 // dout() << "Checking testMatrix for i= " << i << std::endl;
1352 // testMatrix.print(dout());
1353 
1354  // Compute inner product with vector from last time point with rest of time points
1355  Teuchos::SerialDenseMatrix<int,double> currTestMatrix( Teuchos::View, testMatrix, size_, oversampleRate*size_-(i+1), 0, i+1 );
1356  Teuchos::SerialDenseVector<int,double> currWeightVector( Teuchos::View, &weightVector[i+1], oversampleRate*size_-(i+1) );
1357 // Teuchos::SerialDenseVector<int,double> currWeightVector( Teuchos::View, &weightVector[i], oversampleRate*size_-(i+1) );
1358  currWeightVector.multiply( Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, currTestMatrix, newSwapVector, 0.0 );
1359 
1360 // dout() << "The current norm is" << std::endl;
1361 // currWeightVector.print(dout());
1362 
1363  // Subtract off scaled vector from rest of time points.
1364  // NOTE: maxValue is the norm of the last time point.
1365  for (int j=i+1; j<oversampleRate*size_; ++j)
1366  {
1367  Teuchos::SerialDenseMatrix<int,double> currVector( Teuchos::View, testMatrix, size_, 1, 0, j );
1368  blas.AXPY( size_, -(currWeightVector[j-(i+1)]/(maxValue*maxValue) ), newSwapVector.values(), 1, currVector.values(), 1 );
1369  }
1370 
1371 
1372  }
1373 // dout() << "Checking testMatrix after orthogonalization." << std::endl;
1374 // testMatrix.print(dout());
1375 
1376  // Sort the chosen test points and then copy them into the fastTimes_ vector.
1377  std::sort( testPoints.begin(), testPoints.begin()+size_ );
1378 
1379  for (int i=0; i<size_; ++i)
1380  {
1381  fastTimes_[i] = testPoints[i];
1382  }
1383  }
1384 
1385  // Communicate testPoints to all processors (broadcast)
1386  pdsMgrPtr_->getPDSComm()->bcast( &fastTimes_[0], size_, 0 );
1387 
1388 
1389  return true;
1390 }
1391 
1392 //-----------------------------------------------------------------------------
1393 // Function : HB::createFT_
1394 // Purpose : Create the DFT and IFT matrices using the time points for multi-tone HB analysis.
1395 // Special Notes :
1396 // Scope : private
1397 // Creator : Heidi Thornquist and Ting Mei, SNL
1398 // Creation Date : 03/05/2014
1399 //-----------------------------------------------------------------------------
1401 {
1402  int posFreq = (size_-1)/2;
1403  idftMatrix_.reshape(size_,size_);
1404 
1405  // NOTE: i represents frequency, j represents sample time
1406  // Set DC values first.
1407  for (int i=0; i<size_; ++i)
1408  {
1409  idftMatrix_(i,0) = 1.0;
1410  }
1411 
1412  // Set rest of frequency values
1413  for (int i=0; i<size_; i++)
1414  {
1415  for (int j=1; j<=posFreq; j++)
1416  {
1417  idftMatrix_(i,2*j-1) = cos(2*M_PI*freqPoints_[posFreq+j]*fastTimes_[i]);
1418  idftMatrix_(i,2*j) = sin(2*M_PI*freqPoints_[posFreq+j]*fastTimes_[i]);
1419  }
1420 
1421  }
1422 
1423  // Compute DFT matrix.
1425  Teuchos::SerialDenseSolver<int,double> ftSolver;
1426  ftSolver.setMatrix( Teuchos::rcp( &dftMatrix_, false ) );
1427  ftSolver.invert();
1428 
1429  return true;
1430 }
1431 
1432 //-----------------------------------------------------------------------------
1433 // Function : HB::setInitialGuess_
1434 // Purpose : Set initial guess for HB analysis.
1435 // Special Notes :
1436 // Scope : private
1437 // Creator : Ting Mei, SNL
1438 // Creation Date : 03/03/2014
1439 //-----------------------------------------------------------------------------
1441 {
1442  bool success = true;
1443 
1444  if (taHB_ == 1)
1445  {
1446  TimeIntg::TIAParams tia_params;
1447 
1448  tia_params.initialTime = 0;
1449  tia_params.finalTime = 1.0/freqs_[0];
1451  tia_params.maxOrder = 1;
1452 
1453  bool retTol1 = runTol(tia_params);
1454  success = success && retTol1;
1455 
1456  // Start up periods need to be run before the initial condition is computed, otherwise
1457  // just used the solution from the tolerance calculation.
1459  {
1460  // set DAE initial time = 0.0
1461  tia_params.initialTime = 0.0;
1462  tia_params.finalTime = startUpPeriods_/freqs_[0];
1463  tia_params.maxOrder = 5;
1465 
1466  bool startupPeriodsSuccess = runStartupPeriods(tia_params);
1467  if (!startupPeriodsSuccess)
1468  {
1469  Report::UserError() << "Failed to calculate the startup periods";
1470  return false;
1471  }
1472 
1473  success = success && startupPeriodsSuccess;
1474 
1475  tia_params.initialTime = startUpPeriods_/freqs_[0]; ;
1476  tia_params.finalTime = tia_params.initialTime + 1.0/freqs_[0];
1478  tia_params.maxOrder = 1;
1479 
1480  bool icSuccess = runTransientIC(tia_params);
1481  if (!icSuccess)
1482  {
1483  Report::UserError() << "Initial HB Transient failed";
1484  return false;
1485  }
1486  success = success && icSuccess;
1487 
1488  deviceManager_.setMPDEFlag( false );
1489  }
1490 
1491  interpolateIC(tia_params.initialTime);
1492  }
1493 
1494  return success;
1495 }
1496 
1497 //-----------------------------------------------------------------------------
1498 // Function : HB::runTol
1499 // Purpose : Conducts transient run to determine right tolerance
1500 // parameters for IC calculation
1501 // Special Notes :
1502 // Scope : private
1503 // Creator : T. Mei, 1437, Electrical and Micro Modeling
1504 // Creation Date : 02/23/09
1505 //-----------------------------------------------------------------------------
1506 bool
1508  TimeIntg::TIAParams & tia_params)
1509 {
1510  Xyce::lout() << " ***** Computing tolerance parameters for HB IC calculation....\n" << std::endl;
1511 
1512  // Create a transient analysis object for this section.
1513  int numPoints = 0;
1514  {
1515  isTransient_ = true;
1517  currentAnalysisObject_ = &transient;
1518  analysisManager_.pushActiveAnalysis(&transient);
1519  transient.setTIAParams(tia_params);
1520  transient.setAnalysisParams(Util::OptionBlock());
1521  transient.setSaveTimeSteps(!startUpPeriodsGiven_);
1522  transient.resetForHB();
1523  nonlinearManager_.resetAll(Nonlinear::DC_OP);
1524  analysisManager_.getStepErrorControl().resetAll(tia_params);
1525  analysisManager_.getDataStore()->resetAll(tia_params.absErrorTol, tia_params.relErrorTol);
1526  analysisManager_.setNextOutputTime(0.0);
1527 
1528  {
1529  if (!transient.run())
1530  {
1531  Report::UserError() << "Calculation of tolerance parameters failed for relErrorTol = " << tia_params.relErrorTol;
1532  return false;
1533  }
1534  }
1535 
1536  numPoints = transient.getStepNumber();
1537 
1538  // Add in simulation times
1539  accumulateStatistics_(transient);
1540 
1541  analysisManager_.popActiveAnalysis();
1542  currentAnalysisObject_ = 0;
1543  isTransient_ = false;
1544  }
1545 
1546  while ((numPoints < (1.2*size_)) && (tia_params.relErrorTol >= 1e-6))
1547  {
1548  {
1549  Report::UserWarning() << "Tolerance parameters refined, re-running with relErrorTol = " << tia_params.relErrorTol/10;
1550  }
1551 
1552  if (!startUpPeriodsGiven_)
1553  {
1554  // Clear the fast time data storage before performing the next transient
1556  }
1557 
1558  tia_params.relErrorTol = tia_params.relErrorTol/10;
1559 
1560  // Create a transient analysis object for this section.
1561  {
1562  isTransient_ = false;
1564  currentAnalysisObject_ = &transient;
1565  analysisManager_.pushActiveAnalysis(&transient);
1567  transient.setTIAParams(tia_params);
1568  transient.setAnalysisParams(Util::OptionBlock());
1569  transient.resetForHB();
1570  nonlinearManager_.resetAll(Nonlinear::DC_OP);
1571  analysisManager_.getStepErrorControl().resetAll(tia_params);
1572  analysisManager_.getDataStore()->resetAll(tia_params.absErrorTol, tia_params.relErrorTol);
1573  analysisManager_.setNextOutputTime(0.0);
1574 
1575  {
1576  if (!transient.run())
1577  {
1578  Report::UserError() << "Calculation of tolerance parameters failed for relErrorTol = " << tia_params.relErrorTol;
1579  return false;
1580  }
1581  }
1582 
1583  numPoints = transient.getStepNumber();
1584 
1585  // Add in simulation times
1586  accumulateStatistics_(transient);
1587 
1588  analysisManager_.popActiveAnalysis();
1589  currentAnalysisObject_ = 0;
1590  isTransient_ = false;
1591  }
1592  }
1593 
1594  return true;
1595 }
1596 
1597 //-----------------------------------------------------------------------------
1598 // Function : HB::runStartupPeriods_()
1599 // Purpose : Runs normal transient problem through the requested
1600 // number of startup periods
1601 // Special Notes :
1602 // Scope : private
1603 // Creator : Richard Schiek, 1437, Electrical and Micro Modeling
1604 // Creation Date : 09/17/07
1605 //-----------------------------------------------------------------------------
1606 bool
1608  const TimeIntg::TIAParams & tia_params)
1609 {
1610  bool returnValue = true;
1611 
1612  Xyce::lout() << " ***** Computing " << startUpPeriods_ << " start up periods for HB IC calculation...." << std::endl;
1613 
1614  if (DEBUG_HB)
1615  Xyce::dout() << "HB::runStartupPeriods_(): Advancing time through "
1616  << startUpPeriods_ << " startup periods"
1617  << " initialTime = " << tia_params.initialTime
1618  << " finalTime = " << tia_params.finalTime << std::endl;
1619 
1620 
1621  // << "HB::runStartupPeriods_(): Double DCOP tia_params:"
1622  // << " doubleDCOPStep = " << tia_params.doubleDCOPStep
1623  // << " firstDCOPStep = " << tia_params.firstDCOPStep
1624  // << " lastDCOPStep = " << tia_params.lastDCOPStep << std::endl
1625 
1626  // << "HB::runStartupPeriods_(): Double DCOP tiaParamsSave:"
1627  // << " doubleDCOPStep = " << tiaParamsSave.doubleDCOPStep
1628  // << " firstDCOPStep = " << tiaParamsSave.firstDCOPStep
1629  // << " lastDCOPStep = " << tiaParamsSave.lastDCOPStep << std::endl;
1630 
1631  {
1632  Xyce::IO::ActiveOutput x(analysisManager_.getOutputManagerAdapter().getOutputManager());
1633  x.add(Xyce::IO::PrintType::HB_STARTUP, ANP_MODE_HB);
1634 
1635  // Create a transient analysis object for this section.
1636  {
1637  isTransient_ = true;
1639  analysisManager_.pushActiveAnalysis(&transient);
1640  currentAnalysisObject_ = &transient;
1641  transient.setTIAParams(tia_params);
1642  transient.setAnalysisParams(Util::OptionBlock());
1643  transient.resetForHB();
1644  nonlinearManager_.resetAll(Nonlinear::DC_OP);
1645  analysisManager_.getStepErrorControl().resetAll(tia_params);
1646  analysisManager_.getDataStore()->resetAll(tia_params.absErrorTol, tia_params.relErrorTol);
1647  analysisManager_.setNextOutputTime(0.0);
1648 
1649  {
1650  returnValue = transient.run();
1651  }
1652 
1653  isTransient_ = false;
1654 
1655  // Add in simulation times
1656  accumulateStatistics_(transient);
1657 
1658  analysisManager_.getOutputManagerAdapter().finishOutput();
1659 
1660  analysisManager_.popActiveAnalysis();
1662  }
1663  }
1664 
1665  // reset the output filename suffix
1666  // analysisManager_.outMgrPtr->setOutputFilenameSuffix("");
1667 
1668  // put the dsPtr->currentSolutionPtr into dcOpSol and State Vec so that it
1669  // is used as our initial condition for the pending fast time scale runs
1671  dcOpSolVecPtr_ = rcp( new Linear::Vector( *(dsPtr->currSolutionPtr) ));
1672  dcOpStateVecPtr_ = rcp( new Linear::Vector( *(dsPtr->currStatePtr) ));
1673  dcOpQVecPtr_ = rcp( new Linear::Vector( *(dsPtr->daeQVectorPtr) ));
1674  dcOpStoreVecPtr_ = rcp( new Linear::Vector( *(dsPtr->currStorePtr) ));
1675 
1676  return returnValue;
1677 }
1678 
1679 //-----------------------------------------------------------------------------
1680 // Function : HB::runTransientIC_
1681 // Purpose : Conducts a regular transient run for HB initial conditions
1682 // Special Notes :
1683 // Scope : private
1684 // Creator : Ting Mei, SNL
1685 // Creation Date : 10/03/2008
1686 //-----------------------------------------------------------------------------
1687 bool
1689  const TimeIntg::TIAParams & tia_params)
1690 {
1691  bool returnValue = true;
1692 
1693  Xyce::lout() << " ***** Running transient to compute HB initial condition....\n" << std::endl;
1694 
1695  // this prevents extra DC op data from being printed.
1696  deviceManager_.setMPDEFlag( true );
1697 
1698  if(saveIcData_)
1699  {
1700  // Keep the initial condition data
1701  // analysisManager_.outMgrPtr->setOutputFilenameSuffix( ".hb_ic" );
1702  }
1703 
1704  if (DEBUG_HB)
1705  Xyce::dout() << "HB::runTransientIC_(): Advancing time from"
1706  << " initialTime = " << tia_params.initialTime
1707  << " finalTime = " << tia_params.finalTime << std::endl;
1708 
1709  // Initial conditions will be set if startup periods were run.
1710  if ( startUpPeriodsGiven_ )
1711  {
1713  *(dsPtr->nextSolutionPtr) = *(dcOpSolVecPtr_.get());
1714  *(dsPtr->nextStatePtr) = *(dcOpStateVecPtr_.get());
1715  *(dsPtr->daeQVectorPtr) = *(dcOpQVecPtr_.get());
1716  *(dsPtr->nextStorePtr) = *(dcOpStoreVecPtr_.get());
1717  }
1718 
1719  // Create a transient analysis object for this section.
1720  {
1721  isTransient_ = true;
1723  transient.setNOOP(true);
1724  transient.setSaveTimeSteps(true);
1725  currentAnalysisObject_ = &transient;
1726  analysisManager_.pushActiveAnalysis(&transient);
1727  transient.setTIAParams(tia_params);
1728  transient.setAnalysisParams(Util::OptionBlock());
1729  transient.resetForHB();
1730  nonlinearManager_.resetAll(Nonlinear::DC_OP);
1731  analysisManager_.getStepErrorControl().resetAll(tia_params);
1732  analysisManager_.getDataStore()->resetAll(tia_params.absErrorTol, tia_params.relErrorTol);
1733  analysisManager_.setNextOutputTime(0.0);
1734 
1735  {
1736  returnValue = transient.run();
1737  }
1738 
1739  isTransient_ = false;
1740 
1741  // Add in simulation times
1742  accumulateStatistics_(transient);
1743 
1744  analysisManager_.popActiveAnalysis();
1746  }
1747 
1748  if (saveIcData_)
1749  {
1750  // reset suffix
1751  }
1752 
1753  return returnValue;
1754 }
1755 
1756 //-----------------------------------------------------------------------------
1757 // Function : HB::interpolateIC()
1758 // Purpose : Tries to filter the fast time points from a transient run
1759 // so that points are not too close together
1760 // Special Notes :
1761 // Scope : private
1762 // Creator : Richard Schiek, 1437, Electrical and Micro Modeling
1763 // Creation Date : 09/17/07
1764 //-----------------------------------------------------------------------------
1765 bool
1767  double initial_time)
1768 {
1769  Xyce::lout() << " ***** Interpolating transient solution for IC calculation....\n" << std::endl;
1770 
1772  int numPoints = dsPtr->timeSteps.size();
1773 
1774  if (DEBUG_HB)
1775  Xyce::dout() << "HB::interpolateIC_(): Initial transient run produced " << numPoints << " points." << std::endl;
1776 
1777  std::vector<int> goodIndicies;
1778  for( int i = 0; i < size_; ++i )
1779  {
1780  goodTimePoints_[i] = initial_time + goodTimePoints_[i];
1781  }
1782 
1783  bool sortedTimesFlag = true;
1784 
1785  if (freqs_.size() > 1)
1786  sortedTimesFlag = false;
1787 
1788  int breakpoints = 0; // need to keep track of how many breakpoints there are
1789  int startIndex = 0;
1790 
1791  if (sortedTimesFlag)
1792  {
1793  goodIndicies.push_back(startIndex);
1794  int GoodTimePointIndex = startIndex + 1;
1795 
1796  for( int i=startIndex; i < numPoints - 1 ; i++ )
1797  {
1798  // count up breakpoints
1799 
1800  if( dsPtr->timeStepsBreakpointFlag[i] == true )
1801  {
1802  breakpoints++;
1803  }
1804 
1805  if (DEBUG_HB && isActive(Diag::HB_TIMESTEP))
1806  {
1807  Xyce::dout() << "\t\t timeStep[ " << i << " ] = " << dsPtr->timeSteps[i];
1808  if( dsPtr->timeStepsBreakpointFlag[i] == true )
1809  {
1810  Xyce::dout() << " Breakpoint";
1811  }
1812  Xyce::dout() << std::endl;
1813  }
1814 
1815  while( ( GoodTimePointIndex < size_ ) && (dsPtr->timeSteps[i] <= goodTimePoints_[GoodTimePointIndex]) && (goodTimePoints_[GoodTimePointIndex] < dsPtr->timeSteps[i+1]))
1816  {
1817  // found a good point so save the index
1818  goodIndicies.push_back( i );
1819  GoodTimePointIndex = GoodTimePointIndex+1;
1820  }
1821  }
1822  }
1823  else
1824  {
1825  double tmpTimePoints;
1826  bool found;
1827  for(int i=0; i<size_; i++ )
1828  {
1829  tmpTimePoints = fmod(fastTimes_[i], 1.0/freqs_[0]) + initial_time;
1830 
1831  goodTimePoints_[i] = tmpTimePoints;
1832  found = false;
1833 
1834  for(int j=0; (j< (numPoints - 1) && !found ); j++)
1835  {
1836  if((dsPtr->timeSteps[j] <= tmpTimePoints ) && ( tmpTimePoints < dsPtr->timeSteps[j+1]))
1837  {
1838  // found a good point so save the index
1839  goodIndicies.push_back( j );
1840  found=true;
1841  }
1842  }
1843  }
1844  }
1845 
1846  for(int i=0; i<size_; i++ )
1847  {
1848  int currentIndex = goodIndicies[i];
1849  Linear::Vector * firstSolVecPtr = dsPtr->fastTimeSolutionVec[currentIndex];
1850  Linear::Vector * secondSolVecPtr = dsPtr->fastTimeSolutionVec[currentIndex+1];
1851 
1852  Linear::Vector * firstStateVecPtr = dsPtr->fastTimeStateVec[currentIndex];
1853  Linear::Vector * secondStateVecPtr = dsPtr->fastTimeStateVec[currentIndex+1];
1854 
1855  Linear::Vector * firstQVecPtr = dsPtr->fastTimeQVec[currentIndex];
1856  Linear::Vector * secondQVecPtr = dsPtr->fastTimeQVec[currentIndex+1];
1857 
1858  Linear::Vector * firstStoreVecPtr = dsPtr->fastTimeStoreVec[currentIndex];
1859  Linear::Vector * secondStoreVecPtr = dsPtr->fastTimeStoreVec[currentIndex+1];
1860 
1861  double fraction = (goodTimePoints_[i] - dsPtr->timeSteps[currentIndex])/(dsPtr->timeSteps[currentIndex+1] - dsPtr->timeSteps[currentIndex]);
1862 
1863  RCP<Linear::Vector> InterpICSolVecPtr = rcp( new Linear::Vector( *secondSolVecPtr ) );
1864  RCP<Linear::Vector> InterpICStateVecPtr = rcp( new Linear::Vector( *secondStateVecPtr ) );
1865  RCP<Linear::Vector> InterpICQVecPtr = rcp( new Linear::Vector( *secondQVecPtr ) );
1866  RCP<Linear::Vector> InterpICStoreVecPtr = rcp( new Linear::Vector( *secondStoreVecPtr ) );
1867 
1868  InterpICSolVecPtr->putScalar(0.0);
1869  InterpICStateVecPtr->putScalar(0.0);
1870  InterpICQVecPtr->putScalar(0.0);
1871  InterpICStoreVecPtr->putScalar(0.0);
1872 
1873  InterpICSolVecPtr->linearCombo(-1.0, *firstSolVecPtr, 1.0, *secondSolVecPtr );
1874  InterpICSolVecPtr->linearCombo(1.0, *firstSolVecPtr, fraction , *InterpICSolVecPtr);
1875 
1876  InterpICStateVecPtr->linearCombo(-1.0, *firstStateVecPtr, 1.0, *secondStateVecPtr );
1877  InterpICStateVecPtr->linearCombo(1.0, *firstStateVecPtr, fraction , *InterpICStateVecPtr);
1878 
1879  InterpICQVecPtr->linearCombo(-1.0, *firstQVecPtr, 1.0, *secondQVecPtr );
1880  InterpICQVecPtr->linearCombo(1.0, *firstQVecPtr, fraction , *InterpICQVecPtr);
1881 
1882  InterpICStoreVecPtr->linearCombo(-1.0, *firstStoreVecPtr, 1.0, *secondStoreVecPtr );
1883  InterpICStoreVecPtr->linearCombo(1.0, *firstStoreVecPtr, fraction , *InterpICStoreVecPtr);
1884 
1885  goodSolutionVec_.push_back(InterpICSolVecPtr);
1886  goodStateVec_.push_back(InterpICStateVecPtr);
1887  goodQVec_.push_back(InterpICQVecPtr);
1888  goodStoreVec_.push_back(InterpICStoreVecPtr);
1889  }
1890 
1891  // Clean up the fast time data since we are finished computing the initial condition.
1892  // The fast time data can take a considerable amount of memory for large problems.
1893  dsPtr->resetFastTimeData();
1894 
1895  return true;
1896 }
1897 
1898 namespace {
1899 
1900 //-----------------------------------------------------------------------------
1901 // Class : HBFactory
1902 // Purpose :
1903 // Special Notes :
1904 // Scope : public
1905 // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
1906 // Creation Date : Thu Jan 29 12:53:02 2015
1907 //-----------------------------------------------------------------------------
1908 ///
1909 /// Factory for parsing HB parameters from the netlist and creating HB analysis.
1910 ///
1911 class HBFactory : public Factory<HB>
1912 {
1913 public:
1914  //-----------------------------------------------------------------------------
1915  // Function : HBFactory
1916  // Purpose :
1917  // Special Notes :
1918  // Scope : public
1919  // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
1920  // Creation Date : Thu Jan 29 12:54:09 2015
1921  //-----------------------------------------------------------------------------
1922  ///
1923  /// Constructs the HB analysis factory
1924  ///
1925  /// @invariant Stores the results of parsing, so if more than one of the analysis and
1926  /// associated lines are parsed, the second options simply overwrite the previously parsed
1927  /// values.
1928  ///
1929  /// @invariant The existence of the parameters specified in the constructor cannot
1930  /// change.
1931  ///
1932  /// @param analysis_manager
1933  /// @param linear_system
1934  /// @param nonlinear_manager
1935  /// @param device_manager
1936  /// @param builder
1937  /// @param topology
1938  ///
1939  HBFactory(
1940  Analysis::AnalysisManager & analysis_manager,
1941  Linear::System & linear_system,
1942  Nonlinear::Manager & nonlinear_manager,
1943  Device::DeviceMgr & device_manager,
1944  Linear::Builder & builder,
1945  Topo::Topology & topology)
1946  : Factory<HB>(),
1947  analysisManager_(analysis_manager),
1948  linearSystem_(linear_system),
1949  nonlinearManager_(nonlinear_manager),
1950  deviceManager_(device_manager),
1951  builder_(builder),
1952  topology_(topology)
1953  {}
1954 
1955  virtual ~HBFactory()
1956  {}
1957 
1958  //-----------------------------------------------------------------------------
1959  // Function : create
1960  // Purpose :
1961  // Special Notes :
1962  // Scope : public
1963  // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
1964  // Creation Date : Thu Jan 29 12:59:00 2015
1965  //-----------------------------------------------------------------------------
1966  ///
1967  /// Create a new HB analysis and applies the analysis and time integrator option blocks.
1968  ///
1969  /// @return new HB analysis object
1970  ///
1971  HB *create() const
1972  {
1973  analysisManager_.setAnalysisMode(ANP_MODE_HB);
1974 
1976  hb->setAnalysisParams(hbAnalysisOptionBlock_);
1977  hb->setHBIntParams(hbIntOptionBlock_);
1978  hb->setHBLinSol(hbLinSolOptionBlock_, builder_);
1979  hb->setLinSol(linSolOptionBlock_);
1980 
1981  return hb;
1982  }
1983 
1984  //-----------------------------------------------------------------------------
1985  // Function : setHBAnalysisOptionBlock
1986  // Purpose :
1987  // Special Notes :
1988  // Scope : public
1989  // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
1990  // Creation Date : Thu Jan 29 13:00:14 2015
1991  //-----------------------------------------------------------------------------
1992  ///
1993  /// Saves the analysis parsed options block in the factory.
1994  ///
1995  /// @invariant Overwrites any previously specified analysis option block.
1996  ///
1997  /// @param option_block parsed option block
1998  ///
1999  void setHBAnalysisOptionBlock(const Util::OptionBlock &option_block)
2000  {
2001  hbAnalysisOptionBlock_ = option_block;
2002  }
2003 
2004  //-----------------------------------------------------------------------------
2005  // Function : setHBIntOptionBlock
2006  // Purpose :
2007  // Special Notes :
2008  // Scope : public
2009  // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
2010  // Creation Date : Thu Jan 29 13:00:14 2015
2011  //-----------------------------------------------------------------------------
2012  ///
2013  /// Saves the HBINT parsed options block in the factory.
2014  ///
2015  /// @invariant Overwrites any previously specified HBINT option block.
2016  ///
2017  /// @param option_block parsed option block
2018  ///
2019  void setHBIntOptionBlock(const Util::OptionBlock &option_block)
2020  {
2021  hbIntOptionBlock_ = option_block;
2022  }
2023 
2024  //-----------------------------------------------------------------------------
2025  // Function : setHBIntOptionBlock
2026  // Purpose :
2027  // Special Notes :
2028  // Scope : public
2029  // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
2030  // Creation Date : Thu Jan 29 13:00:14 2015
2031  //-----------------------------------------------------------------------------
2032  ///
2033  /// Saves the LINSOL-HB parsed options block in the factory.
2034  ///
2035  /// @invariant Overwrites any previously specified LINSOL-HB option block.
2036  ///
2037  /// @param option_block parsed option block
2038  ///
2039  void setHBLinSolOptionBlock(const Util::OptionBlock &option_block)
2040  {
2041  hbLinSolOptionBlock_ = option_block;
2042  }
2043 
2044  //-----------------------------------------------------------------------------
2045  // Function : setLinSolOptionBlock
2046  // Purpose :
2047  // Special Notes :
2048  // Scope : public
2049  // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
2050  // Creation Date : Thu Jan 29 13:00:14 2015
2051  //-----------------------------------------------------------------------------
2052  ///
2053  /// Saves the LINSOL parsed options block in the factory.
2054  ///
2055  /// @invariant Overwrites any previously specified LINSOL option block.
2056  ///
2057  /// @param option_block parsed option block
2058  ///
2059  void setLinSolOptionBlock(const Util::OptionBlock &option_block)
2060  {
2061  linSolOptionBlock_ = option_block;
2062  }
2063 
2064 public:
2065  AnalysisManager & analysisManager_;
2066  Linear::System & linearSystem_;
2067  Nonlinear::Manager & nonlinearManager_;
2068  Device::DeviceMgr & deviceManager_;
2069  Linear::Builder & builder_;
2070  Topo::Topology & topology_;
2071 
2072 private:
2073  Util::OptionBlock hbAnalysisOptionBlock_;
2074  Util::OptionBlock timeIntegratorOptionBlock_;
2075  Util::OptionBlock hbIntOptionBlock_;
2076  Util::OptionBlock hbLinSolOptionBlock_;
2077  Util::OptionBlock linSolOptionBlock_;
2078 };
2079 
2080 // .options HBINT
2081 struct HBIntOptionsReg : public IO::PkgOptionsReg
2082 {
2083  HBIntOptionsReg(
2084  HBFactory & factory )
2085  : factory_(factory)
2086  {}
2087 
2088  bool operator()(const Util::OptionBlock &option_block)
2089  {
2090  factory_.setHBIntOptionBlock(option_block);
2091 
2092  return true;
2093  }
2094 
2095  HBFactory & factory_;
2096 };
2097 
2098 // .options LINSOL-HB
2099 struct HBLinSolOptionsReg : public IO::PkgOptionsReg
2100 {
2101  HBLinSolOptionsReg(
2102  HBFactory & factory )
2103  : factory_(factory)
2104  {}
2105 
2106  bool operator()(const Util::OptionBlock &option_block)
2107  {
2108  factory_.setHBLinSolOptionBlock(option_block);
2109 
2110  return true;
2111  }
2112 
2113  HBFactory & factory_;
2114 };
2115 
2116 // .options LINSOL
2117 struct LinSolOptionsReg : public IO::PkgOptionsReg
2118 {
2119  LinSolOptionsReg(
2120  HBFactory & factory )
2121  : factory_(factory)
2122  {}
2123 
2124  bool operator()(const Util::OptionBlock &option_block)
2125  {
2126  factory_.setLinSolOptionBlock(option_block);
2127 
2128  return true;
2129  }
2130 
2131  HBFactory & factory_;
2132 };
2133 
2134 // .HB
2135 struct HBAnalysisReg : public IO::PkgOptionsReg
2136 {
2137  HBAnalysisReg(
2138  HBFactory & factory )
2139  : factory_(factory)
2140  {}
2141 
2142  bool operator()(const Util::OptionBlock &option_block)
2143  {
2144  factory_.setHBAnalysisOptionBlock(option_block);
2145  factory_.deviceManager_.setBlockAnalysisFlag(true);
2146 
2147  factory_.analysisManager_.addAnalysis(&factory_);
2148 
2149  return true;
2150  }
2151 
2152  HBFactory & factory_;
2153 };
2154 
2155 } // namespace <unnamed>
2156 
2157 
2158 bool
2160  const std::string & netlist_filename,
2161  IO::PkgOptionsMgr & options_manager,
2162  AnalysisManager & analysis_manager,
2163  Linear::System & linear_system,
2164  Nonlinear::Manager & nonlinear_manager,
2165  Device::DeviceMgr & device_manager,
2166  Linear::Builder & builder,
2167  Topo::Topology & topology)
2168 {
2169  HBFactory *factory = new HBFactory(analysis_manager, linear_system, nonlinear_manager, device_manager, builder, topology);
2170 
2171  analysis_manager.addAnalysisFactory(factory);
2172 
2173  options_manager.submitRegistration("HB", netlist_filename, new HBAnalysisReg(*factory));
2174  options_manager.submitRegistration("HBINT", netlist_filename, new HBIntOptionsReg(*factory));
2175  options_manager.submitRegistration("LINSOL-HB", netlist_filename, new HBLinSolOptionsReg(*factory));
2176  options_manager.submitRegistration("LINSOL", netlist_filename, new LinSolOptionsReg(*factory));
2177 
2178  return true;
2179 }
2180 
2181 } // namespace Analysis
2182 } // namespace Xyce
2183 
void accumulateStatistics_(AnalysisBase &analysis)
Definition: N_ANP_HB.C:1023
std::vector< Linear::Vector * > fastTimeQVec
Util::OptionBlock saved_lsHBOB_
Definition: N_ANP_HB.h:235
Linear::HBPrecondFactory * precFactory_
Definition: N_ANP_HB.h:240
bool processFailedDCOP()
Definition: N_ANP_HB.C:591
std::vector< double > timeSteps
Util::OptionBlock linSolOptionBlock_
Definition: N_ANP_HB.C:2077
AnalysisBase * currentAnalysisObject_
Definition: N_ANP_HB.h:177
Teuchos::RCP< Linear::BlockVector > HBICQVectorPtr_
HB initial Q condition.
Definition: N_ANP_HB.h:258
Teuchos::RCP< N_MPDE_Discretization > mpdeDiscPtr_
Definition: N_ANP_HB.h:227
Linear::Builder & builder_
Definition: N_ANP_HB.h:174
Teuchos::SerialDenseMatrix< int, double > dftMatrix_
Definition: N_ANP_HB.h:232
Loader::Loader & loader_
Definition: N_ANP_HB.h:170
std::vector< double > freqs_
Problem Size.
Definition: N_ANP_HB.h:194
std::vector< bool > timeStepsBreakpointFlag
Teuchos::RCP< Linear::Vector > dcOpStateVecPtr_
Definition: N_ANP_HB.h:244
HBFactory & factory_
Definition: N_ANP_HB.C:2095
std::vector< int > numFreqs_
Definition: N_ANP_HB.h:198
void setNextOutputTime(double next_output_time)
HB(AnalysisManager &analysis_manager, Linear::System &linear_system, Nonlinear::Manager &nonlinear_manager, Device::DeviceMgr &device_manager, Linear::Builder &builder, Topo::Topology &topology)
Definition: N_ANP_HB.C:98
bool printLoopInfo(int start, int finish)
bool startUpPeriodsGiven_
Definition: N_ANP_HB.h:205
Pure virtual class to augment a linear system.
void registerDFTInterface(const Teuchos::RCP< N_UTL_DFTInterfaceDecl< std::vector< double > > > &dftInterface)
std::vector< double > freqPoints_
Definition: N_ANP_HB.h:226
bool test_
Testing Flag.
Definition: N_ANP_HB.h:190
void setFastTimes(const std::vector< double > &times)
void setTIAParams(const TimeIntg::TIAParams &tia_params)
void pushActiveAnalysis(AnalysisBase *analysis)
bool isTransient_
Current analysis state flags.
Definition: N_ANP_HB.h:188
bool setAnalysisParams(const Util::OptionBlock &option_block)
Definition: N_ANP_HB.C:638
Linear::System & linearSystem_
Definition: N_ANP_HB.C:2066
std::string method_
Definition: N_ANP_HB.h:215
Linear::Vector * currStorePtr
std::vector< double > iftOutData_
Definition: N_ANP_HB.h:220
Teuchos::RCP< Linear::Vector > dcOpSolVecPtr_
Definition: N_ANP_HB.h:243
bool isAnalysis(int analysis_type) const
Definition: N_ANP_HB.C:803
Topo::Topology & topology_
Definition: N_ANP_HB.C:2070
double finalTime
End time for simulation.
std::vector< double > timeSteps_
Definition: N_ANP_HB.h:225
AnalysisManager & analysisManager_
Definition: N_ANP_HB.h:169
Util::OptionBlock hbIntOptionBlock_
Definition: N_ANP_HB.C:2075
virtual int getDoubleDCOPStep() const
std::vector< double > ftInData_
Definition: N_ANP_HB.h:220
std::vector< Linear::Vector * > fastTimeStateVec
Teuchos::SerialDenseMatrix< int, double > idftMatrix_
Definition: N_ANP_HB.h:232
N_PDS_Manager * pdsMgrPtr_
Definition: N_ANP_HB.h:176
Util::ListenerAutoSubscribe< StepEvent > StepEventListener
std::vector< double > ftOutData_
Definition: N_ANP_HB.h:220
void setAnalysisMode(AnalysisMode mode)
Linear::Vector * currStatePtr
Teuchos::RCP< Linear::HBBuilder > hbBuilderPtr_
HB loader, builder, system, and DFT.
Definition: N_ANP_HB.h:179
Parallel::Manager * getPDSManager() const
TimeIntg::StepErrorControl & getStepErrorControl()
Device::DeviceMgr & deviceManager_
Definition: N_ANP_HB.h:173
bool registerHBFactory(const std::string &netlist_filename, IO::PkgOptionsMgr &options_manager, AnalysisManager &analysis_manager, Linear::System &linear_system, Nonlinear::Manager &nonlinear_manager, Device::DeviceMgr &device_manager, Linear::Builder &builder, Topo::Topology &topology)
Definition: N_ANP_HB.C:2159
std::vector< Linear::Vector * > fastTimeSolutionVec
std::vector< Teuchos::RCP< Linear::Vector > > goodStateVec_
Definition: N_ANP_HB.h:250
void permutedFFT(const Linear::BlockVector &xt, Linear::BlockVector *xf)
bool doLoopProcess()
Definition: N_ANP_HB.C:499
Linear::System * hbLinearSystem_
Definition: N_ANP_HB.h:181
bool interpolateIC(double initial_time)
Definition: N_ANP_HB.C:1766
bool runStartupPeriods(const TimeIntg::TIAParams &tia_params)
Definition: N_ANP_HB.C:1607
bool setLinSol(const Util::OptionBlock &option_block)
Definition: N_ANP_HB.C:766
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) const
Definition: N_ANP_HB.C:816
void setMatrixFreeFlag(bool matrixFreeFlag)
std::vector< Teuchos::RCP< Linear::Vector > > goodStoreVec_
Definition: N_ANP_HB.h:252
Linear::Vector * daeQVectorPtr
Teuchos::RCP< Linear::Vector > dcOpStoreVecPtr_
Definition: N_ANP_HB.h:246
Device::DeviceMgr & deviceManager_
Definition: N_ANP_HB.C:2068
Teuchos::RCP< Linear::BlockVector > HBICVectorPtr_
Definition: N_ANP_HB.h:255
bool setLinSolOptions(const Util::OptionBlock &option_block)
void resetAll(AnalysisMode mode)
Linear::Vector * deviceErrorWeightMask_
void setSaveTimeSteps(bool save_time_steps)
Teuchos::RCP< Linear::BlockVector > & getLeadCurrentVecFreqPtr()
bool initializeSolverSystem(const TimeIntg::TIAParams &tia_params, Loader::Loader &loader, Linear::System &linear_system, Nonlinear::Manager &nonlinear_manager, Device::DeviceMgr &device_manager)
Initializes the solver system.
bool doProcessFailedStep()
Definition: N_ANP_HB.C:578
int getDoubleDCOPStep() const
Definition: N_ANP_HB.C:222
bool resetForStepCalledBefore_
Definition: N_ANP_HB.h:264
Teuchos::RCP< Linear::BlockVector > HBICStoreVectorPtr_
HB initial store condition.
Definition: N_ANP_HB.h:259
std::vector< int > numPosFreqs
Definition: N_ANP_HB.h:197
void setMPDEFlag(bool flagVal)
bool setLoader(Loader::Loader &loader_)
Nonlinear::AnalysisMode nonlinearAnalysisMode(Mode mode)
Returns the nonlinear analysis mode given the analysis mode.
void setHBFreqs(const std::vector< double > &freqs)
Teuchos::RCP< N_UTL_DFTInterfaceDecl< std::vector< double > > > dftInterface_
Definition: N_ANP_HB.h:231
int startUpPeriods_
Periodicity Information.
Definition: N_ANP_HB.h:204
void registerHBBuilder(Teuchos::RCP< Linear::HBBuilder > hbBuilderPtr)
bool runTol(TimeIntg::TIAParams &tia_params)
Definition: N_ANP_HB.C:1507
N_MPDE_Discretization::Type fastTimeDisc_
Definition: N_ANP_HB.h:222
Teuchos::RCP< Linear::Vector > dcOpQVecPtr_
Definition: N_ANP_HB.h:245
Teuchos::RCP< Linear::BlockVector > HBICVectorFreqPtr_
Definition: N_ANP_HB.h:256
OutputMgrAdapter & getOutputManagerAdapter() const
Linear::Vector * nextStatePtr
std::vector< Linear::Vector * > fastTimeStoreVec
bool initializeAll(Linear::System &linear_system)
Loader::NonlinearEquationLoader & getNonlinearEquationLoader()
Util::OptionBlock saved_lsOB_
Definition: N_ANP_HB.h:236
bool initializeAll(Analysis::AnalysisManager &analysis_manager, Loader::NonlinearEquationLoader &nonlinear_equation_loader, Linear::System &linear_system, TimeIntg::DataStore &data_store, Parallel::Manager &parallel_manager, IO::InitialConditionsManager &initial_conditions_manager, IO::OutputMgr &output_manager, Topo::Topology &topology)
virtual ~HB()
Definition: N_ANP_HB.C:150
bool setFreqPoints_()
Definition: N_ANP_HB.C:1036
double pauseTime
Time step value at which to "pause" the simulation.
bool setInitialGuess()
Definition: N_ANP_HB.C:1440
Teuchos::RCP< Linear::BlockVector > & getStoreVecFreqPtr()
std::vector< double > iftInData_
Definition: N_ANP_HB.h:220
void addAnalysisFactory(Factory< void > *factory)
Nonlinear::Manager & nonlinearManager_
Definition: N_ANP_HB.C:2067
bool getDCOPFlag() const
Definition: N_ANP_HB.C:238
Loader::HBLoader * hbLoaderPtr_
Definition: N_ANP_HB.h:178
Linear::Vector * nextSolutionPtr
void deRegisterFastSources(const std::vector< std::string > &sourceNames)
Linear::Builder & builder_
Definition: N_ANP_HB.C:2069
Topo::Topology & topology_
Definition: N_ANP_HB.h:175
#define M_PI
virtual bool getDoubleDCOPFlag() const
Definition: N_LOA_Loader.h:255
Linear::Vector * nextStorePtr
The analysis factory template defines an interface for analysis type testing and analysis creation...
Definition: N_ANP_Factory.h:65
double initialTime
Beginning time for the time integrator (StepErrorControl, integrators access from StepErrorControl) ...
StatCounts hbStatCounts_
Definition: N_ANP_HB.h:262
Teuchos::RCP< Linear::BlockVector > HBICStateVectorPtr_
HB initial state condition.
Definition: N_ANP_HB.h:257
IO::InitialConditionsManager & getInitialConditionsManager()
std::vector< double > goodTimePoints_
Definition: N_ANP_HB.h:248
bool processSuccessfulDCOP()
Definition: N_ANP_HB.C:552
void setVoltageLimiterFlag(bool flagVal)
Linear::System & linearSystem_
Definition: N_ANP_HB.h:171
std::vector< Teuchos::RCP< Linear::Vector > > goodQVec_
Definition: N_ANP_HB.h:251
bool doProcessSuccessfulStep()
Definition: N_ANP_HB.C:565
bool setHBIntParams(const Util::OptionBlock &option_block)
Definition: N_ANP_HB.C:678
bool runTransientIC(const TimeIntg::TIAParams &tia_params)
Definition: N_ANP_HB.C:1688
Teuchos::RCP< N_UTL_FFTInterface< std::vector< double > > > ftInterface_
Definition: N_ANP_HB.h:219
Linear::Vector * currSolutionPtr
bool setTimePoints_()
Definition: N_ANP_HB.C:1281
TimeIntg::DataStore * getDataStore()
bool doubleDCOPFlag_
true if doing a double-DCOP is possible.
std::vector< Teuchos::RCP< Linear::Vector > > goodSolutionVec_
Definition: N_ANP_HB.h:249
bool setHBLinSol(const Util::OptionBlock &option_block, Linear::Builder &builder)
Definition: N_ANP_HB.C:782
AnalysisManager & analysisManager_
Definition: N_ANP_HB.C:2065
Nonlinear::Manager & nonlinearManager_
Definition: N_ANP_HB.h:172
void permutedIFT(const Linear::BlockVector &xf, Linear::BlockVector *xt)
std::vector< double > registerFastSources(Parallel::Machine comm, const std::vector< std::string > &sourceNames)
void setMatrixFreeFlag(bool matrixFreeFlag)
virtual bool getDCOPFlag() const =0
Util::OptionBlock timeIntegratorOptionBlock_
Definition: N_ANP_HB.C:2074
bool finalVerboseOutput()
Definition: N_ANP_HB.C:624
bool registerPrecondFactory(const Linear::PrecondFactory *preconditioner_factory)
Util::OptionBlock hbLinSolOptionBlock_
Definition: N_ANP_HB.C:2076
void registerAppLoader(Teuchos::RCP< Loader > appLoaderPtr)
Util::OptionBlock hbAnalysisOptionBlock_
Definition: N_ANP_HB.C:2073
bool doHandlePredictor()
Definition: N_ANP_HB.C:611
std::vector< double > fastTimes_
Definition: N_ANP_HB.h:224
void notify(const StepEvent &event)
Definition: N_ANP_HB.C:165
bool loadDeviceErrorWeightMask(Linear::Vector *deviceMask) const