Xyce  6.1
N_ANP_MOR.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_MOR.C,v $
27 // Purpose : MOR analysis functions.
28 // Special Notes :
29 // Creator : Ting Mei
30 // Creation Date : 7/11
31 //
32 // Revision Information:
33 // ---------------------
34 // Revision Number: $Revision: 1.112 $
35 // Revision Date : $Date: 2015/06/19 15:43:14 $
36 // Current Owner : $Author: dgbaur $
37 //-----------------------------------------------------------------------------
38 
39 #include <Xyce_config.h>
40 
41 
42 // ---------- Standard Includes ----------
43 #include <iomanip>
44 
45 
46 // ---------- Xyce Includes ----------
47 
48 #include <N_ANP_AnalysisManager.h>
49 #include <N_ANP_MOR.h>
50 #include <N_ANP_OutputMgrAdapter.h>
51 #include <N_ANP_Report.h>
52 
53 #include <N_LAS_BlockMatrix.h>
54 #include <N_LAS_BlockSystemHelpers.h>
55 #include <N_LAS_BlockVector.h>
56 #include <N_LAS_MOROperators.h>
57 #include <N_LAS_Matrix.h>
58 #include <N_LAS_MultiVector.h>
59 #include <N_LAS_System.h>
60 
61 #include <N_IO_CircuitBlock.h>
62 #include <N_IO_CmdParse.h>
63 #include <N_IO_InitialConditions.h>
64 #include <N_IO_OptionBlock.h>
65 #include <N_IO_OutputROM.h>
66 #include <N_IO_PkgOptionsMgr.h>
67 #include <N_IO_SpiceSeparatedFieldTool.h>
68 
69 #include <N_LOA_Loader.h>
70 
71 #include <N_NLS_Manager.h>
72 #include <N_NLS_ReturnCodes.h>
73 
74 #include <N_PDS_Comm.h>
75 #include <N_PDS_ParMap.h>
76 #include <N_PDS_Serial.h>
77 #include <N_PDS_MPI.h>
78 
79 #include <N_TIA_DataStore.h>
82 #include <N_TIA_StepErrorControl.h>
83 
84 #include <N_TOP_Topology.h>
85 
86 #include <N_UTL_Diagnostic.h>
87 #include <N_UTL_ExtendedString.h>
88 #include <N_UTL_Factory.h>
89 #include <N_UTL_FeatureTest.h>
90 #include <N_UTL_Math.h>
91 #include <N_UTL_Timer.h>
92 
93 #ifdef Xyce_PARALLEL_MPI
94 #include <N_PDS_ParComm.h>
95 #include <mpi.h>
96 #else
97 #include <N_PDS_SerialComm.h>
98 #endif
99 
100 // ---------- Other Includes ----------
101 
102 #include <Epetra_CrsMatrix.h>
103 #include <Epetra_Operator.h>
104 #include <Epetra_CrsGraph.h>
105 #include <Epetra_MultiVector.h>
106 #include <Epetra_LinearProblem.h>
107 #include <Amesos.h>
108 
109 #ifdef Xyce_BELOS
110 #include <BelosLinearProblem.hpp>
111 #include <BelosBlockGmresIter.hpp>
112 #include <BelosDGKSOrthoManager.hpp>
113 #include <BelosStatusTestMaxIters.hpp>
114 #include <BelosOutputManager.hpp>
115 #include <BelosEpetraAdapter.hpp>
116 #endif
117 
118 #include <Teuchos_SerialDenseMatrix.hpp>
119 #include <Teuchos_ScalarTraits.hpp>
120 #include <Teuchos_LAPACK.hpp>
121 #include <Teuchos_BLAS.hpp>
122 
123 namespace Xyce {
124 namespace Analysis {
125 
126 //-----------------------------------------------------------------------------
127 // Function : MOR::MOR( AnalysisManager * )
128 // Purpose : constructor
129 // Special Notes :
130 // Scope : public
131 // Creator : Ting Mei
132 // Creation Date : 5/11
133 //-----------------------------------------------------------------------------
135  AnalysisManager & analysis_manager,
136  Nonlinear::Manager & nonlinear_manager,
137  Loader::Loader & loader,
138  Topo::Topology & topology,
139  IO::InitialConditionsManager & initial_conditions_manager)
140  : AnalysisBase(analysis_manager, "MOR"),
141  comm_(analysis_manager.getPDSManager()->getPDSComm()->comm()),
142  analysisManager_(analysis_manager),
143  loader_(loader),
144  nonlinearManager_(nonlinear_manager),
145  topology_(topology),
146  initialConditionsManager_(initial_conditions_manager),
147  outputManagerAdapter_(analysis_manager.getOutputManagerAdapter()),
148  outputMOR_(analysisManager_.getNetlistFilename()),
149  ROMsize_(-1),
150  morMethod_("PRIMA"),
151  morSaveRedSys_(false),
152  morCompOrigTF_(false),
153  morCompRedTF_(false),
154  morCompType_("DEC"),
155  morCompNP_(10),
156  morCompFStart_(1.0),
157  morAutoSize_(false),
158  morMaxSize_(-1),
159  morMaxFreq_(1.0e9),
160  morCompFStop_(1.0),
161  morExpPoint_(0.0),
162  morScaleFactor_(1.0),
163  morScaleType_(0),
164  morScaleFactor1_(1.0),
165  morSparsificationType_(0),
166  isROMSparse_(false),
167  morEvalSize_(0),
168  numPorts_(0),
169  isSingleFreq_(false),
170  stepMult_(0.0),
171  fStep_(0.0),
172  currentFreq_(0.0),
173  s0_(0.0)
174 {}
175 
176 //-----------------------------------------------------------------------------
177 // Function : MOR::~MOR()
178 // Purpose : destructor
179 // Special Notes :
180 // Scope : public
181 // Creator : Ting Mei
182 // Creation Date : 5/11
183 //-----------------------------------------------------------------------------
185 {}
186 
187 //-----------------------------------------------------------------------------
188 // Function : MOR::setAnalysisParams
189 // Purpose :
190 // Special Notes : These are from the .MOR statement.
191 // Scope : public
192 // Creator : Ting Mei, SNL
193 // Creation Date : 6/11
194 //-----------------------------------------------------------------------------
195 bool MOR::setAnalysisParams(const Util::OptionBlock & paramsBlock)
196 {
197  for (Util::ParamList::const_iterator it = paramsBlock.begin(), end = paramsBlock.end(); it != end; ++it)
198  {
199  if ((*it).uTag() == "PORTLIST")
200  {
201  portList_ = (*it).getValue<std::vector<std::string> >();
202  }
203  }
204 
205  if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
206  {
207  dout() << std::endl
208  << section_divider << std::endl
209  <<" MOR simulation parameters" << std::endl
210  << " size = " << ROMsize_ << std::endl;
211  }
212 
213  return true;
214 }
215 
216 //-----------------------------------------------------------------------------
217 // Function : MOR::setMOROptions
218 // Purpose :
219 // Special Notes : These are from '.options mor'
220 // Scope : public
221 // Creator : Heidi Thornquist and Ting Mei, SNL
222 // Creation Date : 05/31/12
223 //-----------------------------------------------------------------------------
224 bool
226  const Util::OptionBlock & option_block)
227 {
228  for (Util::ParamList::const_iterator it = option_block.begin(), end = option_block.end(); it != end; ++it)
229  {
230  bool value_set =
231  Util::setValue(*it, "METHOD", morMethod_)
232  || Util::setValue(*it, "SAVEREDSYS", morSaveRedSys_)
233  || Util::setValue(*it, "COMPORIGTF", morCompOrigTF_)
234  || Util::setValue(*it, "COMPREDTF", morCompRedTF_)
235  || Util::setValue(*it, "COMPTYPE", morCompType_)
236  || Util::setValue(*it, "COMPNP", morCompNP_)
237  || Util::setValue(*it, "COMPFSTART", morCompFStart_)
238  || Util::setValue(*it, "AUTOSIZE", morAutoSize_)
239  || Util::setValue(*it, "MAXSIZE", morMaxSize_)
240  || Util::setValue(*it, "MAXFREQ", morMaxFreq_)
241  || Util::setValue(*it, "SIZE", ROMsize_)
242  || Util::setValue(*it, "COMPFSTOP", morCompFStop_)
243  || Util::setValue(*it, "EXPPOINT", morExpPoint_)
244  || Util::setValue(*it, "SCALETYPE", morScaleType_)
245  || Util::setValue(*it, "SCALEFACTOR", morScaleFactor_)
246  || Util::setValue(*it, "SCALEFACTOR1", morScaleFactor1_)
247  || Util::setValue(*it, "SPARSIFICATIONTYPE", morSparsificationType_)
248  || Util::setValue(*it, "SUBCKTS", subcircuitNames_);
249 
250  if (value_set)
251  ;
252  else
253  {
254  Report::UserError0() << (*it).uTag() << " is not a recognized model-order reduction option.";
255  }
256  }
257 
258  // If we are computing the transfer function, make sure the frequency range is valid.
260  {
262  {
263  Report::UserError() << ".options mor COMPFSTART = " << morCompFStart_ << " > " << morCompFStop_ << " = COMPFSTOP!";
264  }
265  }
266 
267  return true;
268 }
269 
270 //-----------------------------------------------------------------------------
271 // Function : MOR::run()
272 // Purpose :
273 // Special Notes :
274 // Scope : public
275 // Creator : Ting Mei, SNL
276 // Creation Date : 5/11
277 //-----------------------------------------------------------------------------
279 {
280  bool bsuccess = doInit() && reduceSystem();
281 
282  if (morCompOrigTF_)
283  {
284  // Evaluate original system
285  bsuccess = bsuccess && evalOrigTransferFunction();
286  }
287 
288  // Reset the output adapter, just in case the reduced system needs to output
289  // its transfer functions.
290  // outputManagerAdapter_.resetOutputMORTF();
291  outputMOR_.reset();
292 
293  if (morCompRedTF_)
294  {
295  // Evaluate reduced system
296  bsuccess = bsuccess && evalRedTransferFunction();
297  }
298 
299  bsuccess = bsuccess && doFinish();
300 
301  return bsuccess;
302 }
303 
304 //-----------------------------------------------------------------------------
305 // Function : MOR::init()
306 // Purpose :
307 // Special Notes :
308 // Scope : public
309 // Creator : Ting Mei, SNL
310 // Creation Date : 5/11
311 //-----------------------------------------------------------------------------
313 {
314  bool bsuccess = true;
315 
316  // Compute expansion point in transformed space.
317  s0_ = 2.0 * M_PI * morExpPoint_;
318 
320  {
322  }
323 
324  // Get set to do the operating point.
327 
328  stepNumber = 0;
330 
331  // set initial guess, if there is one to be set.
332  // this setInitialGuess call is to up an initial guess in the
333  // devices that have them (usually PDE devices). This is different than
334  // the "intializeProblem" call, which sets IC's. (initial conditions are
335  // different than initial guesses.
337 
338  // If available, set initial solution
339  // setInputOPFlag(
340  // outputManagerAdapter_.setupInitialConditions(
341  // *analysisManager_.getDataStore()->nextSolutionPtr,
342  // *analysisManager_.getDataStore()->flagSolutionPtr));
343 
346  topology_.getSolutionNodeNameMap(),
349 
350  // Set a constant history for operating point calculation
354 
355  // solving for DC op
362 
364  {
365  Report::UserError() << "Solving for DC operating point failed, cannot continue MOR analysis";
366  return false;
367  }
368 
369  // Create B matrix stamp
370  std::vector<int> tempVec;
372 
373  // Determine how many global ports there are by performing a sumAll()
374  int hsize = tempVec.size();
375  Parallel::AllReduce(comm_, MPI_SUM, &hsize, &numPorts_, 1);
376 
377  // Check that the listed ports on the .mor line are the same number as the B matrix entries.
378  if ( numPorts_ != (int)portList_.size() )
379  {
380  Report::UserError() << "Number of specified ports in .MOR line is inconsistent with number of voltage sources";
381  return false;
382  }
383 
384  // Getting the GIDs for the port list in the order specified in the .MOR line
385  // This is used to permute the bMatEntriesVec_ in the order specified by the user.
386  std::vector<int> gidPosEntries( hsize );
387  for (int i=0; i<hsize; ++i)
388  {
389  std::vector<int> svGIDList1, dummyList;
390  char type1;
391  topology_.getNodeSVarGIDs(NodeID(portList_[i],_VNODE), svGIDList1, dummyList, type1);
392 
393  // Grab the GID for this port.
394  gidPosEntries[i] = svGIDList1.front();
395  }
396 
397  // Use the base map to get the global IDs
398  // Get the parallel maps for the original system
399  N_PDS_Manager &pdsManager = *analysisManager_.getPDSManager();
400  RCP<N_PDS_ParMap> BaseMap = rcp(pdsManager.getParallelMap( Parallel::SOLUTION ), false);
401 
402  // Find the voltage source corresponding to each port and place the LID in the bMatEntriesVec_.
403  bMatEntriesVec_.resize( hsize );
404  for (int i=0; i<hsize; ++i)
405  {
406  int gid = gidPosEntries[i];
407  bool found = false;
408  for (int j=0; j<hsize; ++j)
409  {
410  if (gid == BaseMap->localToGlobalIndex(bMatPosEntriesVec_[j]))
411  {
412  bMatEntriesVec_[i] = tempVec[j];
413  found = true;
414  break;
415  }
416  }
417  if (!found)
418  {
419  Report::UserError() << "Did not find voltage source corresponding to port";
420  return false;
421  }
422  }
423 
424  if (morCompOrigTF_)
425  {
426  // Resize transfer function matrices
427  origH_.shape(numPorts_, numPorts_);
428  }
429  if (morCompRedTF_)
430  {
431  // Resize transfer function matrices
432  redH_.shape(numPorts_, numPorts_);
433  }
434 
435  // Create C and G matrices from DCOP solution
436  analysisManager_.getDataStore()->daeQVectorPtr->putScalar(0.0);
437  analysisManager_.getDataStore()->daeFVectorPtr->putScalar(0.0);
438  analysisManager_.getDataStore()->daeBVectorPtr->putScalar(0.0);
439 
444 
455  );
456 
481 
486 
489 
490 
491  /// Xyce::dout() << "Branch nodes: " << std::endl;
492  /// for (unsigned int i=0; i < bMatEntriesVec_.size(); ++i)
493  /// {
494  /// Xyce::dout() << "Node " << i << " : " << bMatEntriesVec_[i] << std::endl;
495  /// }
496 
497  /// Xyce::dout() << "Printing GPtr: " << std::endl;
498  /// GPtr_->printPetraObject();
499  /// Xyce::dout() << "Printing CPtr: " << std::endl;
500  /// CPtr_->printPetraObject();
501 
502 
503  // Storage for row extraction
504  int length=1, numEntries=0;
505  std::vector<int> colIndices(length);
506  std::vector<double> coeffs(length);
507 
508  for (unsigned int i=0; i < bMatEntriesVec_.size(); ++i)
509  {
510  // Get the number of non-zero entries in this row.
511  numEntries = GPtr_->getLocalRowLength( bMatEntriesVec_[i] );
512  if ( numEntries != 1 )
513  {
514  Report::UserError0() << "Supposed voltage source row has too many entries, cannot continue MOR analysis";
515  return false;
516  }
517 
518  // Extract out rows of G based on indices in bMatEntriesVec_.
519  GPtr_->getLocalRowCopy(bMatEntriesVec_[i], length, numEntries, &coeffs[0], &colIndices[0]);
520 
521  // If the coefficient for this voltage source is positive, make it negative.
522  if ( coeffs[0] > 0.0 )
523  {
524  coeffs[0] *= -1.0;
525  GPtr_->putLocalRow(bMatEntriesVec_[i], length, &coeffs[0], &colIndices[0]);
526  }
527  }
528 
529 
530  /// Xyce::dout() << "Printing GPtr (after scaling): " << std::endl;
531  /// GPtr_->printPetraObject();
532 
533  return bsuccess;
534 }
535 
536 //-----------------------------------------------------------------------------
537 // Function : MOR::reduceSystem()
538 // Purpose :
539 // Special Notes :
540 // Scope : public
541 // Creator : Heidi Thornquist, SNL
542 // Creation Date : 6/4/2012
543 //-----------------------------------------------------------------------------
545 {
546  // At this time, the reduceSystem() method will compute the reduced-order system using
547  // multi-port PRIMA. This method should allow the user multiple algorithms, defined by
548  // the morMethod_ option, which would be best implemented using a factory design.
549 
550  bool bsuccess = true;
551 
552  // Get the parallel maps for the original system
553  N_PDS_Manager &pdsManager = *analysisManager_.getPDSManager();
554 
555  N_PDS_ParMap &BaseMap = *pdsManager.getParallelMap( Parallel::SOLUTION );
556 
557  // Create matrix for (G + s0 * C)
558  if (s0_ != 0.0)
559  {
560  sCpG_MatrixPtr_ = rcp( new Linear::Matrix( &CPtr_->epetraObj(), false ) );
561  sCpG_MatrixPtr_->scale( s0_ );
562  sCpG_MatrixPtr_->add( *GPtr_ );
563  }
564  else
565  {
566  sCpG_MatrixPtr_ = rcp( new Linear::Matrix( &GPtr_->epetraObj(), false ) );
567  }
568 
569  // Create multivector for B and R
570  RPtr_ = rcp( new Linear::MultiVector( BaseMap, numPorts_ ) );
571  RPtr_->putScalar( 0.0 );
572  BPtr_ = rcp( new Linear::MultiVector( BaseMap, numPorts_ ) );
573  for (unsigned int j=0; j < bMatEntriesVec_.size(); ++j)
574  {
575  BPtr_->setElementByGlobalIndex( BaseMap.localToGlobalIndex(bMatEntriesVec_[j]), -1.0, j );
576  }
577 
578  /// Xyce::dout() << "Printing out BPtr" << std::endl;
579  /// BPtr_->epetraObj().Print(Xyce::dout());
580 
581  /// Xyce::dout() << "Printing out sCpG" << std::endl;
582  /// (sCpG_MatrixPtr_->epetraObj()).Print(Xyce::dout());
583 
584  // Create linear problem for (G + s0 * C)
585  origProblem_ = rcp(new Epetra_LinearProblem(&sCpG_MatrixPtr_->epetraObj(), &RPtr_->epetraObj(), &BPtr_->epetraObj() ) );
586 
587  // Create solver object for this linear problem, which will be used to generate the projection basis
588  Amesos amesosFactory;
589  origSolver_ = rcp( amesosFactory.Create( "Klu", *origProblem_ ) );
590 
591  // Solve for R = inv(G + s0*C)*B
592  // Perform symbolic factorization.
593  int linearStatus = origSolver_->SymbolicFactorization();
594  if (linearStatus != 0)
595  {
596  Xyce::dout() << "Amesos symbolic factorization exited with error: " << linearStatus << std::endl;
597  bsuccess = false;
598  }
599 
600  // Perform numeric factorization
601  linearStatus = origSolver_->NumericFactorization();
602  if (linearStatus != 0)
603  {
604  Xyce::dout() << "Amesos numeric factorization exited with error: " << linearStatus << std::endl;
605  bsuccess = false;
606  }
607 
608  // Perform solve for R = inv(G + s0*C)*B
609  linearStatus = origSolver_->Solve();
610  if (linearStatus != 0)
611  {
612  Xyce::dout() << "Amesos solve exited with error: " << linearStatus << std::endl;
613  bsuccess = false;
614  }
615 
616  /// Xyce::dout() << "Printing out R" << std::endl;
617  /// (RPtr_->epetraObj()).Print(Xyce::dout());
618 
619  // Create an Epetra_Operator object to apply the operator inv(G + s0*C)*C
620  RCP<Epetra_Operator> COpPtr_ = rcp( &CPtr_->epetraObj(), false );
621  RCP<Linear::AmesosGenOp> AOp = rcp( new Linear::AmesosGenOp( origSolver_, COpPtr_ ) );
622 
623  // Check to see if the requested size of the ROM is valid.
624  // An orthogonal basis cannot be generated that is larger than the dimension of the original system
625  int kblock = 0;
626 
627 
628 
629  if (morAutoSize_)
630  {
631  if (morMaxSize_ != -1)
633  else
634  ROMsize_ = RPtr_->globalLength()/4;
635  }
636  else
637  {
638 
639  if (ROMsize_ == -1)
640  {
641  Report::UserError() << "Automatic Sizing is OFF. Please specify the ROM dimension";
642  }
643  }
644 
645 
646  if (ROMsize_ > RPtr_->globalLength())
647  {
648  kblock = (int)(RPtr_->globalLength() / numPorts_);
649  UserWarning(*this) << "Requested reduced-order model dimension is larger than original system dimension, resizing to original system dimension";
650  }
651  else
652  {
653  kblock = (int)(ROMsize_ / numPorts_);
654  }
655  int k = kblock * numPorts_;
656 
657  // Resize the projection matrices
658  redG_.shape(k, k);
659  redC_.shape(k, k);
660  redB_.shape(k, numPorts_);
661  redL_.shape(k, numPorts_);
662 
663 #ifdef Xyce_BELOS
664  // ---------------------------------------------------------------------
665  // Now use Belos to compute the basis vectors for K_k(inv(G + s0*C)*C, R)
666  // ---------------------------------------------------------------------
667 
668  // Helpful typedefs for the templates
669  typedef double ST;
670  typedef Epetra_MultiVector MV;
671  typedef Epetra_Operator OP;
672  typedef Belos::MultiVecTraits<ST,MV> MVT;
673 
674  // Output manager.
675  Belos::OutputManager<ST> printer;
676 
677  // Status test.
678  Belos::StatusTestMaxIters<ST, MV, OP> maxIterTest( kblock );
679 
680  // Orthogonalization manager.
681  Belos::DGKSOrthoManager<ST, MV, OP> orthoMgr;
682 
683  // Linear Problem.
684  // Reuse RPtr_. We need the basis vectors for K(inv(G + s0*C)*C, R)
685  Linear::MultiVector temp( BaseMap, numPorts_ );
686  Belos::LinearProblem<ST, MV, OP > problem( AOp,
687  rcp( &temp.epetraObj(), false ),
688  rcp( &RPtr_->epetraObj(), false ));
689  problem.setProblem();
690 
691  // Create parameter list.
692  Teuchos::ParameterList params;
693  params.set("Num Blocks", kblock);
694  params.set("Block Size", numPorts_ );
695 
696  // Create Krylov subspace iteration from Belos
697  Belos::BlockGmresIter<ST, MV, OP> krylovIter( rcp( &problem, false ),
698  rcp( &printer, false ),
699  rcp( &maxIterTest, false ),
700  rcp( &orthoMgr, false ),
701  params );
702 
703  // Get a matrix to hold the orthonormalization coefficients.
704  RCP<Teuchos::SerialDenseMatrix<int,ST> > z
705  = rcp( new Teuchos::SerialDenseMatrix<int,ST>( numPorts_, numPorts_ ) );
706 
707  // Orthonormalize the Krylov kernel vectors V
708  RCP<MV> V = rcp( new Epetra_MultiVector( RPtr_->epetraObj() ) );
709  orthoMgr.normalize( *V, z );
710 
711  // Set the new state and initialize the solver to use R as the kernel vectors.
712  Belos::GmresIterationState<ST,MV> initState;
713  initState.V = V;
714  initState.z = z;
715  initState.curDim = 0;
716  krylovIter.initializeGmres(initState);
717 
718  // Have the solver iterate until the basis size is computed
719  try {
720  krylovIter.iterate();
721  }
722  catch (const Belos::GmresIterationOrthoFailure &e) {
723  // This might happen if the basis size is the same as the operator's dimension.
724  }
725  catch (const std::exception &e) {
726  bsuccess = false; // Anything else is a failure.
727  }
728 
729  // Get the basis vectors back from the iteration object
730  Belos::GmresIterationState<ST,MV> newState = krylovIter.getState();
731 
732  // Create a view into the first k vectors of newState.V
733  // std::vector<int> indices( k );
734 
735  // search for a size for automated MOR
736 
737  RCP<MV> W = rcp( new Epetra_MultiVector( V->Map(), k ) );
738 
739  int low = 1, high = k;
740  if (morAutoSize_)
741  {
742 
743  double abstol = 1e-6;
744  double reltol = 1e-3;
745 
746  int mid;
747 
748  while ((high - low) > 0 )
749  {
750  mid = (low + high)/2;
751 
752  std::vector<int> indices(mid);
753 
754  // Resize the projection matrices
755  redG_.shape(mid, mid);
756  redC_.shape(mid, mid);
757  redB_.shape(mid, numPorts_);
758  redL_.shape(mid, numPorts_);
759 
760  for (int i=0; i<mid; ++i) { indices[i] = i; }
761 
762  V = rcp( new Epetra_MultiVector( View, *newState.V, &indices[0], mid) );
763 
764  W = V;
765 
766 // project the system
767  Linear::MultiVector xyceV( &*V, false );
768  Linear::MultiVector temp2( BaseMap, mid);
769 
770  Linear::MultiVector xyceW( &*W, false );
771  // G * V
772  GPtr_->matvec( false, xyceV, temp2 );
773  // V' * G * V
774 
775  MVT::MvTransMv( 1.0, xyceW.epetraObj(), temp2.epetraObj(), redG_ );
776 
777  // C * V
778  CPtr_->matvec( false, xyceV, temp2 );
779  // V' * C * V
780  MVT::MvTransMv( 1.0, xyceW.epetraObj(), temp2.epetraObj(), redC_ );
781  //redC_.print( Xyce::dout() );
782 
783  // V' * B
784  MVT::MvTransMv( 1.0, xyceW.epetraObj(), BPtr_->epetraObj(), redB_ );
785 
786  MVT::MvTransMv( 1.0, xyceV.epetraObj(), BPtr_->epetraObj(), redL_ );
787 
788  //redB_.print( Xyce::dout() );
789 
790  // calculate transfer functions:
791  isSingleFreq_ = true;
792 
794  origH_.shape(numPorts_, numPorts_);
795  redH_.shape(numPorts_, numPorts_);
796 
799 
800 
801  Teuchos::SerialDenseMatrix<int, double> H_diff, totaltol, errOverTol;
802 
803  totaltol.shape(numPorts_, numPorts_);
804  H_diff.shape(numPorts_, numPorts_);
805 
806 
807  errOverTol.shape(numPorts_, numPorts_);
808  for (unsigned int j=0; j < bMatEntriesVec_.size(); ++j)
809  {
810  for (unsigned int i=0; i < bMatEntriesVec_.size(); ++i)
811  {
812  totaltol(i,j) = reltol*abs( origH_(i,j)) + abstol;
813 
814  H_diff(i,j) = abs( origH_(i,j) - redH_(i, j));
815 
816  errOverTol(i, j) = H_diff(i,j)/totaltol(i,j);
817  }
818  }
819 
820  double totalErrOverTol = errOverTol.normFrobenius()/numPorts_;
821 
822 
823  if( totalErrOverTol < 1)
824  high = mid;
825  else
826  low = mid+1;
827 
828  }
829 
830  isSingleFreq_ = false;
831 
832  ROMsize_ = high;
833 
834  if (ROMsize_ > RPtr_->globalLength())
835  {
836  kblock = (int)(RPtr_->globalLength() / numPorts_);
837  UserWarning(*this) << "Requested reduced-order model dimension is larger than original system dimension, resizing to original system dimension";
838  }
839  else
840  {
841  kblock = (int)(ROMsize_ / numPorts_);
842  }
843 
844  k = kblock * numPorts_;
845 
846  // Resize the projection matrices
847  redG_.shape(k, k);
848  redC_.shape(k, k);
849  redB_.shape(k, numPorts_);
850  redL_.shape(k, numPorts_);
851 
852  }
853  std::vector<int> indices(k);
854  for (int i=0; i<k; ++i) { indices[i] = i; }
855 
856  V = rcp( new Epetra_MultiVector( View, *newState.V, &indices[0], k) );
857  W = V;
858 
859  // ---------------------------------------------------------------------
860  // Sparsify the reduced system, if requested.
861  // ---------------------------------------------------------------------
863  {
864 
865  Linear::MultiVector xyceV( &*V, false );
866  Linear::MultiVector temp2( BaseMap, k );
867 
868  // G * V
869  GPtr_->matvec( false, xyceV, temp2 );
870  // V' * G * V
871  MVT::MvTransMv( 1.0, xyceV.epetraObj(), temp2.epetraObj(), redG_ );
872  //redG_.print( Xyce::dout() );
873 
874  // C * V
875  CPtr_->matvec( false, xyceV, temp2 );
876  // V' * C * V
877  MVT::MvTransMv( 1.0, xyceV.epetraObj(), temp2.epetraObj(), redC_ );
878  //redC_.print( Xyce::dout() );
879 
880  // V' * B
881  MVT::MvTransMv( 1.0, xyceV.epetraObj(), BPtr_->epetraObj(), redB_ );
882  //redB_.print( Xyce::dout() );
883 
884  bsuccess = bsuccess & sparsifyRedSystem_();
885  }
886 
887  // -----------------------------------------------------------------------------
888  // Scale the basis vectors, if requested, before computing the projected system
889  // -----------------------------------------------------------------------------
890 
891  // Create the scaling vector.
892  Teuchos::SerialDenseMatrix<int,ST> Xhatscale( k, 1 );
893 
894  int scaleType = morScaleType_;
895 
896  if ( scaleType == 1 )
897  {
898  for (int i=0; i<k; ++i)
899  {
900  Xhatscale( i, 0 ) = morScaleFactor_;
901  }
902  }
903 
904 // if ( scaleType == 2 )
905 // {
906 
907 // }
908 
909 if ( scaleType == 2 || scaleType == 3 || scaleType ==4)
910  {
911  Epetra_MultiVector Xmag( V->Map(), 1 );
912 
913  if ( scaleType == 2 )
914  Xmag.PutScalar( morScaleFactor_ );
915 
916  if ( scaleType == 4)
917  Xmag.PutScalar(1.0);
918 
919  MVT::MvTransMv( 1.0, *V, Xmag, Xhatscale );
920 
921 // Xhatscale.print(Xyce::dout());
922  for (int i=0; i<k; ++i)
923  {
924 
925  if ( scaleType == 2 )
926  {
927  if ( fabs(Xhatscale( i, 0 )) > morScaleFactor_)
928  {
929  Xhatscale( i, 0 ) = morScaleFactor_ / fabs( Xhatscale( i, 0 ) );
930  }
931  else
932  {
933  Xhatscale( i, 0 ) = morScaleFactor1_ / fabs( Xhatscale( i, 0 ) );
934  }
935  }
936 
937  if ( scaleType == 3 )
938  Xhatscale( i, 0 ) = morScaleFactor_ * fabs( Xhatscale( i, 0 ) );
939 
940  if ( scaleType == 4 )
941  {
942  if ( fabs(Xhatscale( i, 0 )) > 1.0 )
943  {
944  Xhatscale( i, 0 ) = morScaleFactor_ / fabs( Xhatscale( i, 0 ) );
945  }
946  else
947  {
948  Xhatscale( i, 0 ) = morScaleFactor1_ / fabs( Xhatscale( i, 0 ) );
949  }
950  }
951 
952 
953  }
954  }
955 
956 // Xhatscale.print(Xyce::dout());
957 
958  // Scale the computed basis vectors before projecting the original system
959  Teuchos::SerialDenseMatrix<int,ST> D(k,k);
960  if ( scaleType != 0 )
961  {
962  RCP<MV> Vtemp = rcp( new Epetra_MultiVector( V->Map(), k ) );
963 // Teuchos::SerialDenseMatrix<int,ST> D(k,k);
964  for (int i=0; i<k; ++i)
965  {
966  if (Xhatscale( i, 0 ) != 0.0)
967  D(i,i) = 1.0/Xhatscale( i, 0 );
968  else
969  D(i,i) = 1.0;
970  }
971  Xyce::dout() << " the scaling matrix " << std::endl;
972 
973 // D.print(Xyce::dout());
974 
975  MVT::MvTimesMatAddMv( 1.0, *V, D, 0.0, *Vtemp );
976  V = Vtemp;
977  }
978 
979 // Xyce::dout() << "Printing out V" << std::endl;
980 // V->Print(Xyce::dout());
981 // Xyce::dout() << "Printing out W" << std::endl;
982 // W->Print(Xyce::dout());
983 
984  // ---------------------------------------------------------------------
985  // Now use the basis vectors for K_k(inv(G + s0*C)*C, R) to compute
986  // the projected system.
987  // ---------------------------------------------------------------------
988  Linear::MultiVector xyceV( &*V, false );
989  Linear::MultiVector xyceW( &*W, false );
990  Linear::MultiVector temp2( BaseMap, k );
991 
993  {
994  // G * V
995  GPtr_->matvec( false, xyceV, temp2 );
996  // V' * G * V
997  MVT::MvTransMv( 1.0, xyceW.epetraObj(), temp2.epetraObj(), redG_ );
998  //redG_.print( Xyce::dout() );
999 
1000  // C * V
1001  CPtr_->matvec( false, xyceV, temp2 );
1002  // V' * C * V
1003  MVT::MvTransMv( 1.0, xyceW.epetraObj(), temp2.epetraObj(), redC_ );
1004 
1005  // V' * B
1006  MVT::MvTransMv( 1.0, xyceW.epetraObj(), BPtr_->epetraObj(), redB_ );
1007 
1008  MVT::MvTransMv( 1.0, xyceV.epetraObj(), BPtr_->epetraObj(), redL_ );
1009  }
1010  else
1011  {
1012  if ( scaleType <= 1 )
1013  {
1014  redCPtr_->scale(1.0/morScaleFactor_);
1015  redGPtr_->scale(1.0/morScaleFactor_);
1016 
1017  redL_.scale(1.0/morScaleFactor_);
1018  }
1019  else
1020  {
1021  Report::UserError0() << "MOR options sparsificationType=1 can only be used with scaletype=1, other scale types have not been supported for sparsification";
1022  return false;
1023  }
1024  }
1025 
1026  // ---------------------------------------------------------------------
1027  // Output the projected system, redG_, redC_, and redB_.
1028  // ---------------------------------------------------------------------
1029 
1030  if (morSaveRedSys_)
1031  {
1032  // If sparsification was used, write out the Linear::Matrix object instead of the dense object.
1034  // outputManagerAdapter_.outputROM ( *redGPtr_, *redCPtr_, redB_, redL_ );
1036  else
1037  // outputManagerAdapter_.outputROM ( redG_, redC_, redB_, redL_ ); // L = B'
1039  }
1040 
1041 #else
1042  Report::UserError0() << "Belos is necessary to compute a reduced-order model, please recompile Xyce with Belos enabled";
1043  return false;
1044 
1045 #endif // Xyce_BELOS
1046 
1047  return bsuccess;
1048 }
1049 
1050 //-----------------------------------------------------------------------------
1051 // Function : MOR::evalOrigTransferFunction()
1052 // Purpose : Evaluate original transfer function.
1053 // Special Notes :
1054 // Scope : public
1055 // Creator : Heidi Thornquist and Ting Mei, SNL
1056 // Creation Date : 5/29/2012
1057 //-----------------------------------------------------------------------------
1059 {
1060  bool bsuccess = true;
1061 
1063 
1064  int currentStep = 0;
1065  int finalStep = morEvalSize_;
1066 
1067  if ( isSingleFreq_ )
1068  finalStep = 1;
1069 
1070  bool stepAttemptStatus;
1071 
1072  while (currentStep < finalStep)
1073  {
1074 
1075  if (!isSingleFreq_)
1076  updateCurrentFreq_(currentStep);
1077 
1079 
1080  stepAttemptStatus = solveOrigLinearSystem_();
1081 
1082  currentStep++;
1083 
1084  if (stepAttemptStatus)
1085  {
1086  processSuccessfulStep(true);
1087  }
1088  else // stepAttemptStatus (ie do this if the step FAILED)
1089  {
1091  }
1092 
1093  }
1094 
1095  return bsuccess;
1096 }
1097 
1098 //-----------------------------------------------------------------------------
1099 // Function : MOR::evalRedTransferFunction()
1100 // Purpose : Evaluate reduced transfer function.
1101 // Special Notes :
1102 // Scope : public
1103 // Creator : Heidi Thornquist and Ting Mei, SNL
1104 // Creation Date : 5/29/2012
1105 //-----------------------------------------------------------------------------
1107 {
1108  bool bsuccess = true;
1109 
1111 
1112  int currentStep = 0;
1113 
1114  int finalStep = morEvalSize_;
1115 
1116  if ( isSingleFreq_ )
1117  finalStep = 1;
1118 
1119  bool stepAttemptStatus;
1120 
1121  while (currentStep < finalStep)
1122  {
1123  if (!isSingleFreq_)
1124  updateCurrentFreq_(currentStep);
1125 
1127 
1128  stepAttemptStatus = solveRedLinearSystem_();
1129 
1130  currentStep++;
1131 
1132  if (stepAttemptStatus)
1133  {
1134  processSuccessfulStep(false);
1135  }
1136  else // stepAttemptStatus (ie do this if the step FAILED)
1137  {
1139  }
1140  }
1141 
1142  return bsuccess;
1143 }
1144 
1145 //-----------------------------------------------------------------------------
1146 // Function : MOR::createOrigLinearSystem_()
1147 // Purpose :
1148 // Special Notes :
1149 // Scope : public
1150 // Creator : Ting Mei, Heidi Thornquist, SNL
1151 // Creation Date : 6/20/2011
1152 //-----------------------------------------------------------------------------
1154 {
1155  bool bsuccess = true;
1156 
1157  N_PDS_Manager &pdsManager = *analysisManager_.getPDSManager();
1158 
1159  N_PDS_ParMap &BaseMap = *pdsManager.getParallelMap(Parallel::SOLUTION);
1160  N_PDS_ParMap &oBaseMap = *pdsManager.getParallelMap(Parallel::SOLUTION_OVERLAP_GND);
1161  Epetra_CrsGraph &BaseFullGraph = *pdsManager.getMatrixGraph(Parallel::JACOBIAN);
1162 
1163  int numBlocks = 2;
1164 
1165  std::vector<RCP<N_PDS_ParMap> > blockMaps = Linear::createBlockParMaps(numBlocks, BaseMap, oBaseMap);
1166 
1167  std::vector<std::vector<int> > blockPattern(2);
1168  blockPattern[0].resize(2);
1169  blockPattern[0][0] = 0; blockPattern[0][1] = 1;
1170  blockPattern[1].resize(2);
1171  blockPattern[1][0] = 0; blockPattern[1][1] = 1;
1172 
1173  int offset = Linear::generateOffset( BaseMap );
1174  RCP<Epetra_CrsGraph> blockGraph = Linear::createBlockGraph( offset, blockPattern, *blockMaps[0], BaseFullGraph);
1175 
1176  sCpG_REFMatrixPtr_ = rcp ( new Linear::BlockMatrix( numBlocks, offset, blockPattern, *blockGraph, BaseFullGraph) );
1177 
1178  // Load diagonal blocks of real equivalent form: (G - s0*C)
1179  sCpG_REFMatrixPtr_->put( 0.0 ); // Zero out whole matrix
1180 
1181  // Add scaled C matrix first if expansion point is not zero.
1182  if (s0_ != 0.0)
1183  {
1184  sCpG_REFMatrixPtr_->block( 0, 0 ).add(*CPtr_);
1185  sCpG_REFMatrixPtr_->block( 0, 0 ).scale(-s0_);
1186  sCpG_REFMatrixPtr_->block( 1, 1 ).add(*CPtr_);
1187  sCpG_REFMatrixPtr_->block( 1, 1 ).scale(-s0_);
1188  }
1189  // Add G into diagonal block to obtain (G - s0*C)
1190  sCpG_REFMatrixPtr_->block( 0, 0 ).add(*GPtr_);
1191  sCpG_REFMatrixPtr_->block( 1, 1 ).add(*GPtr_);
1192 
1193  // Create solver factory
1194  Amesos amesosFactory;
1195 
1196  // Create block vectors
1197  REFBPtr_ = rcp ( new Linear::BlockVector ( numBlocks, blockMaps[0], rcp(&BaseMap, false) ) );
1198  REFXPtr_ = rcp ( new Linear::BlockVector ( numBlocks, blockMaps[0], rcp(&BaseMap, false) ) );
1199  REFXPtr_->putScalar( 0.0 );
1200 
1201  blockProblem_ = rcp(new Epetra_LinearProblem(&sCpG_REFMatrixPtr_->epetraObj(), &REFXPtr_->epetraObj(), &REFBPtr_->epetraObj() ) );
1202 
1203  blockSolver_ = rcp( amesosFactory.Create( "Klu", *blockProblem_ ) );
1204 
1205  int linearStatus = blockSolver_->SymbolicFactorization();
1206 
1207  if (linearStatus != 0)
1208  {
1209  Xyce::dout() << "Amesos symbolic factorization exited with error: " << linearStatus;
1210  bsuccess = false;
1211  }
1212 
1213  return bsuccess;
1214 
1215 }
1216 
1217 //-----------------------------------------------------------------------------
1218 // Function : MOR::createRedLinearSystem_()
1219 // Purpose :
1220 // Special Notes :
1221 // Scope : public
1222 // Creator : Ting Mei, Heidi Thornquist, SNL
1223 // Creation Date : 6/20/2011
1224 //-----------------------------------------------------------------------------
1226 {
1227  // Create a dense linear system if sparsification has not been, or will not be, performed.
1229  {
1230  // The reduced system is dense, so create a dense linear system for transfer function comparisons.
1231 
1232  // Get the reduced system size.
1233  int k = redG_.numRows();
1234 
1235  // Resize serial dense matrix for real-equivalent form.
1236  sCpG_redMatrix_.shape(2*k, 2*k);
1237  sCpG_tmpMatrix_.shape(2*k, 2*k);
1238  ref_redB_.shape(2*k, numPorts_);
1239 
1240  // First, load the diagonals.
1241  // Get a view of the primary diagonal block, insert (G - s0*C).
1242  Teuchos::SerialDenseMatrix<int, double> subMtx( Teuchos::View, sCpG_tmpMatrix_, k, k, 0, 0 );
1243  subMtx.assign( redC_ );
1244  subMtx.scale( -s0_ );
1245  subMtx += redG_;
1246 
1247  // Get a view of the lower k x k diagonal block, insert (G - s0*C).
1248  Teuchos::SerialDenseMatrix<int, double> subMtx2( Teuchos::View, sCpG_tmpMatrix_, k, k, k, k );
1249  subMtx2.assign( redC_ );
1250  subMtx2.scale( -s0_ );
1251  subMtx2 += redG_;
1252  }
1253  else
1254  {
1255  // The reduced system is sparse, so create a sparse linear system.
1256 
1257  int numBlocks = 2;
1258 
1259  N_PDS_Manager &pdsManager = *analysisManager_.getPDSManager();
1260  N_PDS_ParMap redPDSMap( redMapPtr_.get(), *pdsManager.getPDSComm() );
1261 
1262  RCP<N_PDS_ParMap> redBlockMapPtr = Linear::createBlockParMap(numBlocks, redPDSMap);
1263 
1264  std::vector<std::vector<int> > blockPattern(2);
1265  blockPattern[0].resize(2);
1266  blockPattern[0][0] = 0; blockPattern[0][1] = 1;
1267  blockPattern[1].resize(2);
1268  blockPattern[1][0] = 0; blockPattern[1][1] = 1;
1269 
1270  int offset= Linear::generateOffset( redPDSMap );
1271  RCP<Epetra_CrsGraph> blockGraph = Linear::createBlockGraph( offset, blockPattern, *redBlockMapPtr, (redCPtr_->epetraObj()).Graph() );
1272 
1273  sCpG_ref_redMatrixPtr_ = rcp( new Linear::BlockMatrix( numBlocks, offset, blockPattern, *blockGraph, (redCPtr_->epetraObj()).Graph() ) );
1274 
1275  // Load diagonal blocks of real equivalent form: (G - s0*C)
1276  sCpG_ref_redMatrixPtr_->put( 0.0 ); // Zero out whole matrix
1277 
1278  // Add scaled C matrix first if expansion point is not zero.
1279  if (s0_ != 0.0)
1280  {
1281  sCpG_ref_redMatrixPtr_->block( 0, 0 ).add(*redCPtr_);
1282  sCpG_ref_redMatrixPtr_->block( 0, 0 ).scale(-s0_);
1283  sCpG_ref_redMatrixPtr_->block( 1, 1 ).add(*redCPtr_);
1284  sCpG_ref_redMatrixPtr_->block( 1, 1 ).scale(-s0_);
1285  }
1286  // Add G into diagonal block to obtain (G - s0*C)
1287  sCpG_ref_redMatrixPtr_->block( 0, 0 ).add(*redGPtr_);
1288  sCpG_ref_redMatrixPtr_->block( 1, 1 ).add(*redGPtr_);
1289 
1290  // Create solver factory
1291  Amesos amesosFactory;
1292 
1293  // Create a block vector
1294  ref_redBPtr_ = rcp ( new Linear::BlockVector ( numBlocks, redBlockMapPtr, rcp(&redPDSMap, false) ) );
1295  ref_redXPtr_ = rcp ( new Linear::BlockVector ( numBlocks, redBlockMapPtr, rcp(&redPDSMap, false) ) );
1296  ref_redXPtr_->putScalar( 0.0 );
1297 
1298  blockRedProblem_ = rcp(new Epetra_LinearProblem(&sCpG_ref_redMatrixPtr_->epetraObj(),
1299  &ref_redXPtr_->epetraObj(), &ref_redBPtr_->epetraObj() ) );
1300 
1301  blockRedSolver_ = rcp( amesosFactory.Create( "Klu", *blockRedProblem_ ) );
1302 
1303  int linearStatus = blockRedSolver_->SymbolicFactorization();
1304 
1305  if (linearStatus != 0)
1306  {
1307  Xyce::dout() << "Amesos symbolic factorization exited with error: " << linearStatus;
1308  return false;
1309  }
1310  }
1311 
1312  return true;
1313 }
1314 
1315 //-----------------------------------------------------------------------------
1316 // Function : MOR::updateOrigLinearSystemFreq_()
1317 // Purpose :
1318 // Special Notes :
1319 // Scope : public
1320 // Creator : Ting Mei, Heidi Thornquist, SNL
1321 // Creation Date : 6/20/2011
1322 //-----------------------------------------------------------------------------
1323 
1325 {
1326  double omega = 2.0 * M_PI * currentFreq_;
1327 
1328  sCpG_REFMatrixPtr_->block( 0, 1).put( 0.0);
1329  sCpG_REFMatrixPtr_->block( 0, 1).add(*CPtr_);
1330  sCpG_REFMatrixPtr_->block( 0, 1).scale(-omega);
1331 
1332  sCpG_REFMatrixPtr_->block(1, 0).put( 0.0);
1333  sCpG_REFMatrixPtr_->block(1, 0).add(*CPtr_);
1334  sCpG_REFMatrixPtr_->block(1, 0).scale(omega);
1335 
1336  return true;
1337 }
1338 
1339 //-----------------------------------------------------------------------------
1340 // Function : MOR::updateRedLinearSystemFreq_()
1341 // Purpose :
1342 // Special Notes :
1343 // Scope : public
1344 // Creator : Ting Mei, Heidi Thornquist, SNL
1345 // Creation Date : 6/20/2011
1346 //-----------------------------------------------------------------------------
1347 
1349 {
1350  double omega = 2.0 * M_PI * currentFreq_;
1351 
1353  {
1354  sCpG_ref_redMatrixPtr_->block( 0, 1).put( 0.0);
1355  sCpG_ref_redMatrixPtr_->block( 0, 1).add(*redCPtr_);
1356  sCpG_ref_redMatrixPtr_->block( 0, 1).scale(-omega);
1357 
1358  sCpG_ref_redMatrixPtr_->block(1, 0).put( 0.0);
1359  sCpG_ref_redMatrixPtr_->block(1, 0).add(*redCPtr_);
1360  sCpG_ref_redMatrixPtr_->block(1, 0).scale(omega);
1361  }
1362  else
1363  {
1364  int k = redG_.numRows();
1365 
1366  // Reset reduced real equivalent form matrix to sCpG_tmpMatrix_
1367  sCpG_redMatrix_.assign( sCpG_tmpMatrix_ );
1368 
1369  // Insert off diagonals.
1370  Teuchos::SerialDenseMatrix<int, double> subMtx( Teuchos::View, sCpG_redMatrix_, k, k, 0, k );
1371  subMtx.assign( redC_ );
1372  subMtx.scale( -omega );
1373 
1374  Teuchos::SerialDenseMatrix<int, double> subMtx2( Teuchos::View, sCpG_redMatrix_, k, k, k, 0 );
1375  subMtx2.assign( redC_ );
1376  subMtx2.scale( omega );
1377  }
1378 
1379  return true;
1380 }
1381 
1382 //-----------------------------------------------------------------------------
1383 // Function : MOR::solveLinearSystem_()
1384 // Purpose :
1385 // Special Notes :
1386 // Scope : public
1387 // Creator : Ting Mei, Heidi Thornquist, SNL
1388 // Creation Date : 6/2011
1389 //-----------------------------------------------------------------------------
1390 
1392 {
1393 
1394  bool bsuccess = true;
1395 
1396  // Solve the block problem
1397  int linearStatus = blockSolver_->NumericFactorization();
1398 
1399  if (linearStatus != 0)
1400  {
1401  Xyce::dout() << "Amesos numeric factorization exited with error: " << linearStatus;
1402  bsuccess = false;
1403  }
1404 
1405  // Loop over number of I/O ports here
1406  for (unsigned int j=0; j < bMatEntriesVec_.size(); ++j)
1407  {
1408  REFBPtr_->putScalar( 0.0 );
1409  (REFBPtr_->block( 0 ))[bMatEntriesVec_[j]] = -1.0;
1410 
1411  linearStatus = blockSolver_->Solve();
1412  if (linearStatus != 0)
1413  {
1414  Xyce::dout() << "Amesos solve exited with error: " << linearStatus;
1415  bsuccess = false;
1416  }
1417 
1418  // Compute transfer function entries for all I/O
1419  for (unsigned int i=0; i < bMatEntriesVec_.size(); ++i)
1420  {
1421  // Populate H for all ports in L
1422  // L is the same as B and also a set of canonical basis vectors (e_i), so
1423  // we can pick off the appropriate entries of REFXPtr to place into H.
1424  origH_(i,j) = std::complex<double>(-(REFXPtr_->block( 0 ))[bMatEntriesVec_[i]],
1425  -(REFXPtr_->block( 1 ))[bMatEntriesVec_[i]]);
1426  }
1427  }
1428  return bsuccess;
1429 }
1430 
1431 //-----------------------------------------------------------------------------
1432 // Function : MOR::solveRedLinearSystem_()
1433 // Purpose :
1434 // Special Notes :
1435 // Scope : public
1436 // Creator : Ting Mei, Heidi Thornquist, SNL
1437 // Creation Date : 6/2011
1438 //-----------------------------------------------------------------------------
1439 
1441 {
1442  bool bsuccess = true;
1443 
1445  {
1446  // Solve the block problem
1447  int linearStatus = blockRedSolver_->NumericFactorization();
1448 
1449  if (linearStatus != 0)
1450  {
1451  Xyce::dout() << "Amesos numeric factorization exited with error: " << linearStatus;
1452  bsuccess = false;
1453  }
1454 
1455  // Create a multivector with the reduced B and L vectors.
1456  Epetra_MultiVector tmp_redL( View, *redMapPtr_, redL_.values(), redL_.stride(), numPorts_ );
1457  Epetra_MultiVector tmp_redB( View, *redMapPtr_, redB_.values(), redB_.stride(), numPorts_ );
1458  Linear::MultiVector redBmv( &tmp_redB, false ), redLmv( &tmp_redL, false );
1459 
1460  // Loop over number of I/O ports here
1461  for (int j=0; j < numPorts_; ++j)
1462  {
1463  // Set the B vector for this port.
1464  ref_redBPtr_->putScalar( 0.0 );
1465  (ref_redBPtr_->block( 0 )) = *(redBmv.getVectorView( j ));
1466 
1467  linearStatus = blockRedSolver_->Solve();
1468  if (linearStatus != 0)
1469  {
1470  Xyce::dout() << "Amesos solve exited with error: " << linearStatus;
1471  bsuccess = false;
1472  }
1473 
1474  // Compute transfer function entries for all I/O
1475  for (int i=0; i < numPorts_; ++i)
1476  {
1477  // L is probably not B in this case, so explicitly multiply to compute transfer function entries.
1478  double realPart = ( redLmv.getVectorView( i ) )->dotProduct( ref_redXPtr_->block( 0 ) );
1479  double imagPart = ( redLmv.getVectorView( i ) )->dotProduct( ref_redXPtr_->block( 1 ) );
1480 
1481  redH_(i,j) = std::complex<double>(realPart, imagPart);
1482  }
1483  }
1484  }
1485  else
1486  {
1487  int k = redG_.numRows();
1488  Teuchos::LAPACK<int, double> lapack;
1489 
1490  ref_redB_.putScalar( 0.0 );
1491  Teuchos::SerialDenseMatrix<int, double> tmpRedB( Teuchos::View, ref_redB_, redB_.numRows(), redB_.numCols(), 0, 0 );
1492  tmpRedB.assign( redB_ );
1493 
1494  // First factor matrix using LU.
1495  int info = 0;
1496  std::vector<int> ipiv( sCpG_redMatrix_.numRows() );
1497  lapack.GETRF( sCpG_redMatrix_.numRows(), sCpG_redMatrix_.numCols(), sCpG_redMatrix_.values(),
1498  sCpG_redMatrix_.stride(), &ipiv[0], &info );
1499  if (info != 0)
1500  {
1501  Xyce::dout() << "LAPACK::GETRF: LU factorization failed with error: " << info << std::endl;
1502  bsuccess = false;
1503  }
1504 
1505  // Next solve for all ports at once using LU factors.
1506  const char trans = 'N';
1507  lapack.GETRS( trans, sCpG_redMatrix_.numRows(), ref_redB_.numCols(), sCpG_redMatrix_.values(),
1508  sCpG_redMatrix_.stride(), &ipiv[0], ref_redB_.values(), ref_redB_.stride(), &info );
1509  if (info != 0)
1510  {
1511  Xyce::dout() << "LAPACK::GETRS: LU solve failed with error: " << info << std::endl;
1512  bsuccess = false;
1513  }
1514 
1515  Teuchos::SerialDenseMatrix<int, double> tmpRedImag( numPorts_, numPorts_ ), tmpRedReal( numPorts_, numPorts_ );
1516 
1517  // Compute real part.
1518  tmpRedReal.multiply( Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, redB_, tmpRedB, 0.0 );
1519 
1520  // Compute imaginary part.
1521  Teuchos::SerialDenseMatrix<int, double> tmpRedB2( Teuchos::View, ref_redB_, redB_.numRows(), redB_.numCols(), k, 0 );
1522  tmpRedImag.multiply( Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, redB_, tmpRedB2, 0.0 );
1523 
1524  // Compute transfer function entries for all I/O
1525  for (unsigned int j=0; j < bMatEntriesVec_.size(); ++j)
1526  {
1527  for (unsigned int i=0; i < bMatEntriesVec_.size(); ++i)
1528  {
1529  redH_(i,j) = std::complex<double>(tmpRedReal(i,j), tmpRedImag(i,j));
1530  }
1531  }
1532  }
1533 
1534  return bsuccess;
1535 }
1536 
1537 //-----------------------------------------------------------------------------
1538 // Function : MOR::sparsifyRedSystem_()
1539 // Purpose : Use techniques to sparsify the projected system.
1540 // Special Notes :
1541 // Scope : public
1542 // Creator : Heidi Thornquist and Ting Mei, SNL
1543 // Creation Date : 8/20/2012
1544 //-----------------------------------------------------------------------------
1546 {
1547  bool bsuccess = true;
1548 
1549  int k = redB_.numRows();
1550 
1551  // Storage vectors
1552  Teuchos::SerialDenseMatrix<int, double> R(redB_);
1553  Teuchos::SerialDenseMatrix<int, double> A(redC_);
1554 
1555  // Factor Ghat.
1556  Teuchos::LAPACK<int, double> lapack;
1557  Teuchos::SerialDenseMatrix<int, double> tmp_Ghat( redG_ );
1558 
1559  int info = 0;
1560  std::vector<int> ipiv( tmp_Ghat.numRows() );
1561  lapack.GETRF( tmp_Ghat.numRows(), tmp_Ghat.numCols(), tmp_Ghat.values(),
1562  tmp_Ghat.stride(), &ipiv[0], &info );
1563  if (info != 0)
1564  {
1565  Xyce::dout() << "LAPACK::GETRF: LU factorization of Ghat failed with error: " << info << std::endl;
1566  bsuccess = false;
1567  }
1568 
1569  // Compute reciprocal condition estimate of Ghat.
1570  const char norm = '1';
1571  double condGhat = 0.0;
1572  std::vector<double> condWork( 4*k );
1573  std::vector<int> condIWork( k );
1574  lapack.GECON( norm, tmp_Ghat.numRows(), tmp_Ghat.values(), tmp_Ghat.stride(), tmp_Ghat.normOne(), &condGhat, &condWork[0], &condIWork[0], &info );
1575  // Xyce::dout() << "Condition estimate for Ghat is : " << 1.0/ condGhat << std::endl;
1576  if (info != 0)
1577  {
1578  Xyce::dout() << "LAPACK::GECON: Computing condition estimate of Ghat failed with error: " << info << std::endl;
1579  bsuccess = false;
1580  }
1581 
1582  // Compute A = inv(Ghat)* Chat
1583  const char trans = 'N';
1584  lapack.GETRS( trans, tmp_Ghat.numRows(), A.numCols(), tmp_Ghat.values(),
1585  tmp_Ghat.stride(), &ipiv[0], A.values(), A.stride(), &info );
1586  if (info != 0)
1587  {
1588  Xyce::dout() << "LAPACK::GETRS: LU solve failed with error: " << info << std::endl;
1589  bsuccess = false;
1590  }
1591  //Xyce::dout() << "A = inv(Ghat)*Chat" << std::endl;
1592  //A.print(Xyce::dout());
1593 
1594  // Compute R = inv(Ghat)* Bhat
1595  lapack.GETRS( trans, tmp_Ghat.numRows(), R.numCols(), tmp_Ghat.values(),
1596  tmp_Ghat.stride(), &ipiv[0], R.values(), R.stride(), &info );
1597  if (info != 0)
1598  {
1599  Xyce::dout() << "LAPACK::GETRS: LU solve failed with error: " << info << std::endl;
1600  bsuccess = false;
1601  }
1602  //Xyce::dout() << "R = inv(Ghat)*Bhat" << std::endl;
1603  //R.print(Xyce::dout());
1604 
1605  // Reduce A to Schur form and compute the eigenvalues.
1606  // Allocate the work space. This space will be used below for calls to:
1607  // * GEES (requires 3*k for real)
1608  // * TREVC (requires 3*k for real)
1609  // Furthermore, GEES requires a real array of length k
1610  //
1611  int lwork = 8*k;
1612  std::vector<double> work( lwork );
1613  std::vector<double> revals( k );
1614  std::vector<double> ievals( k );
1615  Teuchos::SerialDenseMatrix<int, double> Q(k, k);
1616 
1617  // Create diagonal tmpB for the eigenproblem (A, tmpB), beta should return as a vector of ones.
1618  const int ldvl = 1;
1619  double vl[ ldvl ];
1620  std::vector<double> beta( k );
1621  Teuchos::SerialDenseMatrix<int, double> tmpB( k, k );
1622  for (int i=0; i<k; i++)
1623  tmpB(i,i) = 1.0;
1624  lapack.GGEV( 'N', 'V', k, A.values(), A.stride(), tmpB.values(), tmpB.stride(),
1625  &revals[0], &ievals[0], &beta[0], &vl[0], ldvl, Q.values(), Q.stride(),
1626  &work[0], lwork, &info );
1627  if (info != 0)
1628  {
1629  Xyce::dout() << "LAPACK::GGEV: Computing eigenvectors and values of A = inv(Ghat)*Chat failed with error: " << info << std::endl;
1630  bsuccess = false;
1631  }
1632 
1633  // Scale the eigenvectors returned from GGEV to have 2-norm = 1
1634  // They are initially scaled to have inf-norm = 1 from LAPACK
1635  Teuchos::BLAS<int, double> blas;
1636  std::vector<int> rowIndex( k );
1637  int i = 0;
1638 
1639  while( i < k ) {
1640  if ( ievals[i] != 0.0 )
1641  {
1642  rowIndex[i] = 1;
1643  rowIndex[i+1] = -1;
1644 
1645  // Compute the 2-norm of the complex eigenvector
1646  double norm_r = blas.NRM2( k, Q[i], 1 );
1647  double norm_i = blas.NRM2( k, Q[i+1], 1 );
1648  double norm = lapack.LAPY2( norm_r, norm_i );
1649 
1650  // Scale the complex eigenvector
1651  for (int j=0; j<k; j++)
1652  {
1653  Q(j,i) /= norm;
1654  Q(j,i+1) /= norm;
1655  }
1656  i += 2;
1657  }
1658  else
1659  {
1660  rowIndex[i] = 0;
1661 
1662  // Compute the 2-norm of the i-th column
1663  double norm = blas.NRM2( k, Q[i], 1 );
1664 
1665  // Scale the real eigenvector
1666  for (int j=0; j<k; j++)
1667  {
1668  Q(j,i) /= norm;
1669  }
1670  i++;
1671  }
1672  }
1673 
1674  // Xyce::dout() << "Eigenvalues of A: " << std::endl;
1675  // for (int i=0; i<k; ++i)
1676  // Xyce::dout() << revals[i] << "\t" << ievals[i] << "\t" << beta[i] << std::endl;
1677 
1678  // Xyce::dout() << "Eigenvectors of A: " << std::endl;
1679  // Q.print(Xyce::dout());
1680 
1681  // Construct complex eigenvectors
1682  Teuchos::SerialDenseMatrix<int, std::complex<double> > V(k, k);
1683  for (int i=0; i<k; i++)
1684  {
1685  if (rowIndex[i] == 1)
1686  {
1687  for (int j=0; j<k; j++)
1688  {
1689  // Insert both conjugate pairs simultaneously.
1690  V(j,i) = std::complex<double>( Q(j,i), Q(j,i+1) );
1691  V(j,i+1) = std::complex<double>( Q(j,i), -Q(j,i+1) );
1692  }
1693  i++; // Need to increment an extra value for the conjugate pair.
1694  }
1695  else // The eigenvector is real, copy directly
1696  {
1697  for (int j=0; j<k; j++)
1698  {
1699  V(j,i) = std::complex<double>( Q(j,i), 0.0 );
1700  }
1701  }
1702  }
1703 
1704  // Factor V
1705  Teuchos::LAPACK<int, std::complex<double> > lapack_complex;
1706  lapack_complex.GETRF( V.numRows(), V.numCols(), V.values(), V.stride(), &ipiv[0], &info );
1707  if (info != 0)
1708  {
1709  Xyce::dout() << "LAPACK::GETRF: LU factorization of eigenvectors failed with error: " << info << std::endl;
1710  bsuccess = false;
1711  }
1712 
1713  // Compute condition estimate of V.
1714  double condV = 0.0;
1715  std::vector<std::complex<double> > condCWork( 2*k );
1716  lapack_complex.GECON( norm, V.numRows(), V.values(), V.stride(), V.normOne(), &condV, &condCWork[0], &condWork[0], &info );
1717  //Xyce::dout() << "Condition estimate for V is : " << 1.0/condV << std::endl;
1718  if (info != 0)
1719  {
1720  Xyce::dout() << "LAPACK::GECON: Computing condition estimate of V failed with error: " << info << std::endl;
1721  bsuccess = false;
1722  }
1723 
1724  // Compute inv(V)
1725  std::vector<std::complex<double> > cwork( lwork );
1726  lapack_complex.GETRI( V.numRows(), V.values(), V.stride(), &ipiv[0], &cwork[0], lwork, &info );
1727  if (info != 0)
1728  {
1729  Xyce::dout() << "LAPACK::GETRI: Computing inverse of V failed with error: " << info << std::endl;
1730  bsuccess = false;
1731  }
1732 
1733  // Convert R to a complex vector to use the multiply routine for inv(V).
1734  Teuchos::SerialDenseMatrix<int, std::complex<double> > tmpR( k, numPorts_ );
1735  for (int j=0; j<numPorts_; j++)
1736  for (int i=0; i<k; i++)
1737  tmpR(i,j) = std::complex<double>( R(i,j), 0.0 );
1738 
1739  // Compute inv(V) * R
1740  Teuchos::SerialDenseMatrix<int, std::complex<double> > tmp_redB(k ,numPorts_);
1741  tmp_redB.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, V, tmpR, 0.0);
1742 
1743  // Generate compressed real storage of V*R and inv(V)
1744  redL_ = redB_; // Store copy of redB_ before destroying it below.
1745  Teuchos::SerialDenseMatrix<int, double> invV(k, k);
1746  for (int i=0; i<k; i++)
1747  {
1748  if (rowIndex[i] == 1) // Complex conjugate pair.
1749  {
1750  for (int j=0; j<k; j++)
1751  {
1752  invV(i, j) = V(i,j).real();
1753  invV(i+1, j) = V(i,j).imag();
1754  }
1755  for (int j=0; j<numPorts_; j++)
1756  {
1757  redB_(i, j) = tmp_redB(i, j).real();
1758  redB_(i+1, j) = tmp_redB(i, j).imag();
1759  }
1760  i++; // Increment by one to skip complex conjugate.
1761  }
1762  else // Eigenvalue is real, so is eigenvector.
1763  {
1764  for (int j=0; j<k; j++)
1765  invV(i, j) = V(i,j).real();
1766  for (int j=0; j<numPorts_; j++)
1767  redB_(i, j) = tmp_redB(i, j).real();
1768  }
1769  }
1770 
1771  // Factor invV.
1772  lapack.GETRF( invV.numRows(), invV.numCols(), invV.values(), invV.stride(), &ipiv[0], &info );
1773  if (info != 0)
1774  {
1775  Xyce::dout() << "LAPACK::GETRF: LU factorization of inv(V) failed with error: " << info << std::endl;
1776  bsuccess = false;
1777  }
1778 
1779  // Compute A = inv(invV)^T*Lhat
1780  const char trans2 = 'T';
1781  lapack.GETRS( trans2, invV.numRows(), redL_.numCols(), invV.values(),
1782  invV.stride(), &ipiv[0], redL_.values(), redL_.stride(), &info );
1783  if (info != 0)
1784  {
1785  Xyce::dout() << "LAPACK::GETRS: LU solve for Lhat failed with error: " << info << std::endl;
1786  bsuccess = false;
1787  }
1788 
1789  // Xyce::dout() << "Bhat : " << std::endl;
1790  // redB_.print(Xyce::dout());
1791  // Xyce::dout() << "Lhat : " << std::endl;
1792  // redL_.print(Xyce::dout());
1793 
1794  // Create redCPtr_ and redGPtr_
1795  // Generate Epetra_Map that puts all the values of the reduced system on one processor.
1796  N_PDS_Manager &pdsManager = *analysisManager_.getPDSManager();
1797  N_PDS_ParMap &BaseMap = *pdsManager.getParallelMap(Parallel::SOLUTION);
1798  if (BaseMap.petraMap()->Comm().MyPID() == 0)
1799  redMapPtr_ = Teuchos::rcp( new Epetra_Map( k, k, 0, BaseMap.petraMap()->Comm() ) );
1800  else
1801  redMapPtr_ = Teuchos::rcp( new Epetra_Map( k, 0, 0, BaseMap.petraMap()->Comm() ) );
1802 
1803  Epetra_CrsMatrix* tmpRedG = new Epetra_CrsMatrix( Copy, *redMapPtr_, 1 );
1804  Epetra_CrsMatrix* tmpRedC = new Epetra_CrsMatrix( Copy, *redMapPtr_, 2 );
1805 
1806  // Let processor 0 insert entries into tmpRedG and tmpRedC
1807  if (BaseMap.petraMap()->Comm().MyPID() == 0)
1808  {
1809  std::vector<int> index(2);
1810  std::vector<double> val(2);
1811  for (int i=0; i<k; i++)
1812  {
1813  // Insert G, which is a diagonal of ones.
1814  index[0] = i; val[0] = 1.0;
1815  tmpRedG->InsertGlobalValues( i, 1, &val[0], &index[0] );
1816 
1817  // Insert C, which is block diagonal, where the blocks represent conjugate eigenvalues.
1818  if (rowIndex[i] == 1)
1819  {
1820  index[0] = i; index[1] = i+1;
1821  val[0] = revals[i]; val[1] = -ievals[i];
1822  tmpRedC->InsertGlobalValues( i, 2, &val[0], &index[0] );
1823  }
1824  else if (rowIndex[i] == -1)
1825  {
1826  index[0] = i-1; index[1] = i;
1827  val[0] = ievals[i-1]; val[1] = revals[i-1];
1828  tmpRedC->InsertGlobalValues( i, 2, &val[0], &index[0] );
1829  }
1830  else // Must be real.
1831  {
1832  index[0] = i; val[0] = revals[i];
1833  tmpRedC->InsertGlobalValues( i, 1, &val[0], &index[0] );
1834  }
1835  }
1836  }
1837  // We are done inserting values.
1838  tmpRedC->FillComplete();
1839  tmpRedG->FillComplete();
1840 
1841  // Pass tmpRedG and tmpRedC into redGPtr_ and redGPtr_, respectively, which will manage the memory.
1842  redGPtr_ = rcp( new Linear::Matrix( tmpRedG ) );
1843  redCPtr_ = rcp( new Linear::Matrix( tmpRedC ) );
1844 
1845  // We now have a sparse ROM.
1846  if (bsuccess)
1847  isROMSparse_ = true;
1848 
1849  return bsuccess;
1850 }
1851 
1852 //-----------------------------------------------------------------------------
1853 // Function : MOR::processSuccessfulStep()
1854 // Purpose :
1855 // Special Notes :
1856 // Scope : public
1857 // Creator : Ting Mei, SNL
1858 // Creation Date :
1859 //-----------------------------------------------------------------------------
1860 bool MOR::processSuccessfulStep(bool origSys)
1861 {
1862  bool bsuccess = true;
1863 
1864  // Output H.
1865  if (!isSingleFreq_)
1866  {
1867  if (origSys)
1868  {
1869  // outputManagerAdapter_.outputMORTF (origSys, currentFreq_, origH_);
1871  }
1872  else
1873  {
1874  // outputManagerAdapter_.outputMORTF (origSys, currentFreq_, redH_);
1876  }
1877  }
1878 
1879  if ( !firstDoubleDCOPStep() )
1880  {
1881  stepNumber += 1;
1884  }
1885 
1886  return bsuccess;
1887 }
1888 
1889 //-----------------------------------------------------------------------------
1890 // Function : MOR::processFailedStep
1891 // Purpose :
1892 // Special Notes :
1893 // Scope : public
1894 // Creator : Ting Mei, SNL
1895 // Creation Date :
1896 //-----------------------------------------------------------------------------
1898 {
1899  bool bsuccess = true;
1900 
1901  stepNumber += 1;
1902  morEvalFailures_.push_back(stepNumber);
1905 
1906  return bsuccess;
1907 }
1908 
1909 //-----------------------------------------------------------------------------
1910 // Function : MOR::finish
1911 // Purpose :
1912 // Special Notes :
1913 // Scope : public
1914 // Creator : Ting Mei, SNL
1915 // Creation Date :
1916 //-----------------------------------------------------------------------------
1918 {
1919  bool bsuccess = true;
1920 
1921  if (DEBUG_ANALYSIS)
1922  Xyce::dout() << "Calling MOR::doFinish() outputs!" << std::endl;
1923 
1924  if (!(morEvalFailures_.empty()))
1925  {
1926  bsuccess = false;
1927  }
1928 
1929  return bsuccess;
1930 }
1931 
1932 
1933 //-----------------------------------------------------------------------------
1934 // Function : MOR::doHandlePredictor
1935 // Purpose :
1936 // Special Notes :
1937 // Scope : private
1938 // Creator : Eric Keiter, SNL
1939 // Creation Date : 06/24/2013
1940 //-----------------------------------------------------------------------------
1942 {
1946 
1947  // In case this is the upper level of a 2-level sim, tell the
1948  // inner solve to do its prediction:
1949  bool beginIntegrationFlag = analysisManager_.getBeginningIntegrationFlag(); // system_state.beginIntegrationFlag;
1950  double nextTimeStep = analysisManager_.getStepErrorControl().currentTimeStep; // system_state.nextTimeStep;
1951  double nextTime = analysisManager_.getStepErrorControl().nextTime; // system_state.nextTime;
1952  int currentOrder = analysisManager_.getWorkingIntegrationMethod().getOrder(); // system_state.currentOrder;
1953 
1954  loader_.startTimeStep(beginIntegrationFlag, nextTimeStep, nextTime, currentOrder);
1955 
1956  return true;
1957 }
1958 
1959 //-----------------------------------------------------------------------------
1960 // Function : MOR::updateCurrentFreq_(int stepNumber )
1961 // Purpose :
1962 // Special Notes : Used for MOR analysis classes.
1963 // Scope : public
1964 // Creator : Ting Mei, SNL.
1965 // Creation Date :
1966 //-----------------------------------------------------------------------------
1967 bool MOR::updateCurrentFreq_(int stepNumber)
1968 {
1969  double fStart = morCompFStart_;
1970 
1971  if (equal_nocase(morCompType_, "LIN"))
1972  {
1973  currentFreq_ = fStart + static_cast<double>(stepNumber)*fStep_;
1974  }
1975  else if (equal_nocase(morCompType_, "DEC") || equal_nocase(morCompType_, "OCT"))
1976  {
1977  currentFreq_ = fStart*pow(stepMult_, static_cast<double>(stepNumber) );
1978  }
1979  else
1980  {
1981  Report::DevelFatal().in("MOR::updateCurrentFreq_") << "Unsupported STEP type";
1982  }
1983 
1984  return true;
1985 }
1986 
1987 //-----------------------------------------------------------------------------
1988 // Function : MOR::setupSweepParam_
1989 // Purpose : Processes sweep parameters.
1990 // Special Notes : Used for MOR analysis classes.
1991 // Scope : public
1992 // Creator : Ting Mei, SNL.
1993 // Creation Date :
1994 //-----------------------------------------------------------------------------
1996 {
1997  int fCount = 0;
1998  double fStart = morCompFStart_;
1999  double fStop = morCompFStop_;
2000 
2001  if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
2002  {
2003  Xyce::dout() << std::endl << std::endl;
2004  Xyce::dout() << section_divider << std::endl;
2005  Xyce::dout() << "MOR::setupSweepParam_" << std::endl;
2006  }
2007 
2008  if (equal_nocase(morCompType_, "LIN"))
2009  {
2010  if ( morCompNP_ == 1)
2011  fStep_ = 0;
2012  else
2013  fStep_ = (fStop - fStart)/(morCompNP_ - 1);
2014 
2015  fCount = morCompNP_;
2016 
2017  if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
2018  {
2019  Xyce::dout() << "fStep = " << fStep_ << std::endl;
2020  }
2021  }
2022  else if (equal_nocase(morCompType_, "DEC"))
2023  {
2024  stepMult_ = pow(10,(1/(double)morCompNP_));
2025  fCount = (int)(floor(fabs(log10(fStart) - log10(fStop)) * morCompNP_ + 1));
2026  if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
2027  {
2028  Xyce::dout() << "stepMult_ = " << stepMult_ << std::endl;
2029  }
2030  }
2031  else if (equal_nocase(morCompType_, "OCT"))
2032  {
2033  stepMult_ = pow(2,1/(double)(morCompNP_));
2034 
2035  // changed to remove dependence on "log2" function, which apparently
2036  // doesn't exist in the math libraries of FreeBSD or the mingw
2037  // cross-compilation suite. Log_2(x)=log_e(x)/log_e(2.0)
2038  double ln2=log(2.0);
2039  fCount = floor(fabs(log(fStart) - log(fStop))/ln2 * morCompNP_ + 1);
2040  if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
2041  {
2042  Xyce::dout() << "stepMult_ = " << stepMult_ << std::endl;
2043  }
2044  }
2045  else
2046  {
2047  Report::DevelFatal().in("MOR::setupSweepParam_") << "Unsupported type";
2048  }
2049 
2050  // At this point, pinterval equals the total number of steps
2051  // for the step loop.
2052  return fCount;
2053 }
2054 
2055 namespace {
2056 
2057 typedef Util::Factory<AnalysisBase, MOR> MORFactoryBase;
2058 
2059 //-----------------------------------------------------------------------------
2060 // Class : MORFactory
2061 // Purpose :
2062 // Special Notes :
2063 // Scope : public
2064 // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
2065 // Creation Date : Thu Jan 29 12:53:02 2015
2066 //-----------------------------------------------------------------------------
2067 ///
2068 /// Factory for parsing MOR parameters from the netlist and creating MOR analysis.
2069 ///
2070 class MORFactory : public MORFactoryBase
2071 {
2072 public:
2073  //-----------------------------------------------------------------------------
2074  // Function : MORFactory
2075  // Purpose :
2076  // Special Notes :
2077  // Scope : public
2078  // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
2079  // Creation Date : Thu Jan 29 12:54:09 2015
2080  //-----------------------------------------------------------------------------
2081  ///
2082  /// Constructs the MOR analysis factory
2083  ///
2084  /// @invariant Stores the results of parsing, so if more than one of the analysis and
2085  /// associated lines are parsed, the second options simply overwrite the previously parsed
2086  /// values.
2087  ///
2088  /// @invariant The existence of the parameters specified in the constructor cannot
2089  /// change.
2090  ///
2091  /// @param analysis_manager
2092  /// @param linear_system
2093  /// @param nonlinear_manager
2094  /// @param topology
2095  ///
2096  MORFactory(
2097  Analysis::AnalysisManager & analysis_manager,
2098  Linear::System & linear_system,
2099  Nonlinear::Manager & nonlinear_manager,
2100  Loader::Loader & loader,
2101  Topo::Topology & topology,
2102  IO::InitialConditionsManager & initial_conditions_manager)
2103  : MORFactoryBase(),
2104  analysisManager_(analysis_manager),
2105  linearSystem_(linear_system),
2106  nonlinearManager_(nonlinear_manager),
2107  loader_(loader),
2108  topology_(topology),
2109  initialConditionsManager_(initial_conditions_manager)
2110  {}
2111 
2112  virtual ~MORFactory()
2113  {}
2114 
2115  //-----------------------------------------------------------------------------
2116  // Function : create
2117  // Purpose :
2118  // Special Notes :
2119  // Scope : public
2120  // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
2121  // Creation Date : Thu Jan 29 12:59:00 2015
2122  //-----------------------------------------------------------------------------
2123  ///
2124  /// Create a new MOR analysis and applies the analysis and time integrator option blocks.
2125  ///
2126  /// @return new MOR analysis object
2127  ///
2128  MOR *create() const
2129  {
2130  analysisManager_.setAnalysisMode(ANP_MODE_MOR);
2131 
2133  mor->setAnalysisParams(morAnalysisOptionBlock_);
2134  mor->setMOROptions(morOptsOptionBlock_);
2135 
2136  return mor;
2137  }
2138 
2139  //-----------------------------------------------------------------------------
2140  // Function : setMORAnalysisOptionBlock
2141  // Purpose :
2142  // Special Notes :
2143  // Scope : public
2144  // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
2145  // Creation Date : Thu Jan 29 13:00:14 2015
2146  //-----------------------------------------------------------------------------
2147  ///
2148  /// Saves the analysis parsed options block in the factory.
2149  ///
2150  /// @invariant Overwrites any previously specified analysis option block.
2151  ///
2152  /// @param option_block parsed option block
2153  ///
2154  void setMORAnalysisOptionBlock(const Util::OptionBlock &option_block)
2155  {
2156  morAnalysisOptionBlock_ = option_block;
2157  }
2158 
2159  //-----------------------------------------------------------------------------
2160  // Function : setMOROptsOptionBlock
2161  // Purpose :
2162  // Special Notes :
2163  // Scope : public
2164  // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
2165  // Creation Date : Thu Jan 29 13:00:14 2015
2166  //-----------------------------------------------------------------------------
2167  ///
2168  /// Saves the MOR_OPTS parsed options block in the factory.
2169  ///
2170  /// @invariant Overwrites any previously specified MOR_OPTS option block.
2171  ///
2172  /// @param option_block parsed option block
2173  ///
2174  bool setMOROptsOptionBlock(const Util::OptionBlock &option_block)
2175  {
2176  morOptsOptionBlock_ = option_block;
2177 
2178  return true;
2179  }
2180 
2181 public:
2182  AnalysisManager & analysisManager_;
2183  Linear::System & linearSystem_;
2184  Nonlinear::Manager & nonlinearManager_;
2185  Loader::Loader & loader_;
2186  Topo::Topology & topology_;
2187  IO::InitialConditionsManager & initialConditionsManager_;
2188 
2189 private:
2190  Util::OptionBlock morAnalysisOptionBlock_;
2191  Util::OptionBlock morOptsOptionBlock_;
2192 };
2193 
2194 // .MOR
2195 struct MORAnalysisReg : public IO::PkgOptionsReg
2196 {
2197  MORAnalysisReg(
2198  MORFactory & factory )
2199  : factory_(factory)
2200  {}
2201 
2202  bool operator()(const Util::OptionBlock &option_block)
2203  {
2204  factory_.setMORAnalysisOptionBlock(option_block);
2205 
2206  factory_.analysisManager_.addAnalysis(&factory_);
2207 
2208  return true;
2209  }
2210 
2211  MORFactory & factory_;
2212 };
2213 
2214 //-----------------------------------------------------------------------------
2215 // Function : extractMORData
2216 // Purpose : Extract the parameters from a netlist .MOR line held in
2217 // parsed_line.
2218 // Special Notes :
2219 // Scope : public
2220 // Creator :
2221 // Creation Date : 5/25/12
2222 //-----------------------------------------------------------------------------
2223 bool
2224 extractMORData(
2225  IO::PkgOptionsMgr & options_manager,
2226  IO::CircuitBlock & circuit_block,
2227  const std::string & netlist_filename,
2228  const IO::TokenVector & parsed_line)
2229 {
2230  Util::OptionBlock option_block("MOR", Util::OptionBlock::NO_EXPRESSIONS, netlist_filename, parsed_line[0].lineNumber_);
2231 
2232  int numFields = parsed_line.size();
2233 
2234  int linePosition = 0; // Start of parameters on .param line.
2235 
2236  Util::Param parameter("", "");
2237 
2238  if (numFields > 1)
2239  {
2240  std::vector<std::string> portNames(numFields - 1);
2241  for (int i=0; i<(numFields-1); ++i)
2242  {
2243  ++linePosition; // Advance to next parameter.
2244 
2245  // Insert next port name
2246  ExtendedString stringVal ( parsed_line[linePosition].string_ );
2247  stringVal.toUpper();
2248  portNames[i] = stringVal;
2249  }
2250 
2251  parameter.setTag( "PORTLIST" );
2252  parameter.setVal( portNames );
2253  option_block.addParam( parameter );
2254  }
2255 
2256  circuit_block.addOptions(option_block);
2257 
2258  return true;
2259 }
2260 
2261 void
2262 populateMetadata(
2263  IO::PkgOptionsMgr & options_manager)
2264 {
2265  Util::ParamMap &parameters = options_manager.addOptionsMetadataMap("MOR_OPTS");
2266 
2267  parameters.insert(Util::ParamMap::value_type("SIZE", Util::Param("SIZE", -1)));
2268  parameters.insert(Util::ParamMap::value_type("METHOD", Util::Param("METHOD", "PRIMA")));
2269  parameters.insert(Util::ParamMap::value_type("AUTOSIZE", Util::Param("AUTOSIZE", false)));
2270  parameters.insert(Util::ParamMap::value_type("ANALYSISONLY", Util::Param("ANALYSISONLY", false)));
2271  parameters.insert(Util::ParamMap::value_type("MAXSIZE", Util::Param("MAXSIZE", -1)));
2272  parameters.insert(Util::ParamMap::value_type("MAXFREQ", Util::Param("MAXFREQ", 1.0e9)));
2273  parameters.insert(Util::ParamMap::value_type("SAVEREDSYS", Util::Param("SAVEREDSYS", false)));
2274  parameters.insert(Util::ParamMap::value_type("COMPORIGTF", Util::Param("COMPORIGTF", false)));
2275  parameters.insert(Util::ParamMap::value_type("COMPREDTF", Util::Param("COMPREDTF", false)));
2276  parameters.insert(Util::ParamMap::value_type("COMPTYPE", Util::Param("COMPTYPE", "DEC")));
2277  parameters.insert(Util::ParamMap::value_type("COMPNP", Util::Param("COMPNP", 10)));
2278  parameters.insert(Util::ParamMap::value_type("COMPFSTART", Util::Param("COMPFSTART", 1.0)));
2279  parameters.insert(Util::ParamMap::value_type("COMPFSTOP", Util::Param("COMPFSTOP", 1.0)));
2280  parameters.insert(Util::ParamMap::value_type("EXPPOINT", Util::Param("EXPPOINT", 0.0)));
2281  parameters.insert(Util::ParamMap::value_type("SCALETYPE", Util::Param("SCALETYPE", 0)));
2282  parameters.insert(Util::ParamMap::value_type("SCALEFACTOR", Util::Param("SCALEFACTOR", 1)));
2283  parameters.insert(Util::ParamMap::value_type("SCALEFACTOR1", Util::Param("SCALEFACTOR1", 0.01)));
2284  parameters.insert(Util::ParamMap::value_type("SPARSIFICATIONTYPE", Util::Param("SPARSIFICATIONTYPE", 0)));
2285  parameters.insert(Util::ParamMap::value_type("SUBCKTS", Util::Param("SUBCKTS", "VECTOR")));
2286 }
2287 
2288 } // namespace <unnamed>
2289 
2290 
2291 bool
2293  FactoryBlock & factory_block)
2294 {
2295  MORFactory *factory = new MORFactory(factory_block.analysisManager_, factory_block.linearSystem_, factory_block.nonlinearManager_, factory_block.loader_, factory_block.topology_, factory_block.initialConditionsManager_);
2296 
2297  addAnalysisFactory(factory_block, factory);
2298 
2299  populateMetadata(factory_block.optionsManager_);
2300 
2301  factory_block.optionsManager_.addCommandParser(".MOR", extractMORData);
2302 
2303  factory_block.optionsManager_.addCommandProcessor("MOR", new MORAnalysisReg(*factory));
2304 
2305  factory_block.optionsManager_.addOptionsProcessor("MOR_OPTS", IO::createRegistrationOptions(*factory, &MORFactory::setMOROptsOptionBlock));
2306 
2307  return true;
2308 }
2309 
2310 } // namespace Analysis
2311 } // namespace Xyce
RCP< Linear::MultiVector > RPtr_
Definition: N_ANP_MOR.h:195
Linear::Vector * lastSolutionPtr
unsigned int successfulStepsTaken_
Number of consecutive successful time-integration steps.
Topo::Topology & topology_
Definition: N_ANP_MOR.h:134
virtual bool setInitialGuess(Linear::Vector *solVectorPtr)
Definition: N_LOA_Loader.h:232
double morScaleFactor_
Definition: N_ANP_MOR.h:155
Linear::Vector * lastLeadDeltaVPtr
Teuchos::SerialDenseMatrix< int, double > redB_
Definition: N_ANP_MOR.h:206
RCP< Epetra_LinearProblem > origProblem_
Definition: N_ANP_MOR.h:228
RCP< Epetra_LinearProblem > blockRedProblem_
Definition: N_ANP_MOR.h:232
RCP< Linear::BlockVector > ref_redBPtr_
Definition: N_ANP_MOR.h:219
virtual bool getBMatrixEntriesforMOR(std::vector< int > &bMatEntriesVec, std::vector< int > &bMatPosEntriesVec)
Definition: N_LOA_Loader.h:226
bool evalOrigTransferFunction()
Definition: N_ANP_MOR.C:1058
void evaluateStepError(const Loader::Loader &loader, const TIAParams &tia_params)
Pure virtual class to augment a linear system.
RCP< Linear::MultiVector > BPtr_
Definition: N_ANP_MOR.h:195
Linear::System & linearSystem_
Definition: N_ANP_MOR.C:2183
RCP< Linear::BlockMatrix > sCpG_REFMatrixPtr_
Definition: N_ANP_MOR.h:199
virtual bool loadDAEVectors(Linear::Vector *nextSolVectorPtr, Linear::Vector *currSolVectorPtr, Linear::Vector *lastSolVectorPtr, Linear::Vector *nextStaVectorPtr, Linear::Vector *currStaVectorPtr, Linear::Vector *lastStaVectorPtr, Linear::Vector *StaDerivVectorPtr, Linear::Vector *nextStoVectorPtr, Linear::Vector *currStoVectorPtr, Linear::Vector *lastStoVectorPtr, Linear::Vector *stoLeadCurrQVectorPtr, Linear::Vector *nextLeadFVectorPtr, Linear::Vector *currLeadFVectorPtr, Linear::Vector *lastLeadFVectorPtr, Linear::Vector *nextLeadQVectorPtr, Linear::Vector *nextJunctionVVectorPtr, Linear::Vector *currJunctionVVectorPtr, Linear::Vector *lastJunctionVVectorPtr, Linear::Vector *QVectorPtr, Linear::Vector *FVectorPtr, Linear::Vector *BVectorPtr, Linear::Vector *dFdxdVpVectorPtr, Linear::Vector *dQdxdVpVectorPtr)
Definition: N_LOA_Loader.h:122
MOR(AnalysisManager &analysis_manager, Nonlinear::Manager &nonlinear_manager, Loader::Loader &loader, Topo::Topology &topology, IO::InitialConditionsManager &initial_conditions_manager)
Definition: N_ANP_MOR.C:134
unsigned int stepNumber
Time-integration step number counter.
Nonlinear::Manager & nonlinearManager_
Definition: N_ANP_MOR.h:133
bool registerMORFactory(FactoryBlock &factory_block)
Definition: N_ANP_MOR.C:2292
std::vector< std::string > portList_
Definition: N_ANP_MOR.h:169
Linear::Vector * currStorePtr
Linear::Vector * lastStatePtr
bool createOrigLinearSystem_()
Definition: N_ANP_MOR.C:1153
Teuchos::SerialDenseMatrix< int, std::complex< double > > origH_
Definition: N_ANP_MOR.h:223
RCP< Linear::BlockMatrix > sCpG_ref_redMatrixPtr_
Definition: N_ANP_MOR.h:218
void gatherStepStatistics(StatCounts &stats, Nonlinear::NonLinearSolver &nonlinear_solver, int newton_convergence_status)
void createTimeIntegratorMethod(const TimeIntg::TIAParams &tia_params, const unsigned int integration_method)
RCP< Epetra_LinearProblem > blockProblem_
Definition: N_ANP_MOR.h:228
void setValue(ParameterBase &entity, const Descriptor &descriptor, const T &value)
Sets the value of the parameter.
Definition: N_DEV_Pars.h:1281
RCP< Amesos_BaseSolver > blockSolver_
Definition: N_ANP_MOR.h:227
Teuchos::SerialDenseMatrix< int, double > sCpG_redMatrix_
Definition: N_ANP_MOR.h:214
bool updateOrigLinearSystemFreq_()
Definition: N_ANP_MOR.C:1324
Linear::Vector * nextLeadDeltaVPtr
Linear::Vector * currStatePtr
bool setAnalysisParams(const Util::OptionBlock &paramsBlock)
Definition: N_ANP_MOR.C:195
unsigned int failedStepsAttempted_
Total number of failed time-integration steps.
Parallel::Manager * getPDSManager() const
Topo::Topology & topology_
Definition: N_ANP_MOR.C:2186
std::string morMethod_
Definition: N_ANP_MOR.h:142
TimeIntg::StepErrorControl & getStepErrorControl()
const std::string & getNetlistFilename() const
NonLinearSolver & getNonlinearSolver()
RCP< Linear::BlockVector > REFXPtr_
Definition: N_ANP_MOR.h:201
AnalysisManager & analysisManager_
Definition: N_ANP_MOR.h:131
Util::OptionBlock morAnalysisOptionBlock_
Definition: N_ANP_MOR.C:2190
Linear::Vector * daeQVectorPtr
Teuchos::SerialDenseMatrix< int, double > sCpG_tmpMatrix_
Definition: N_ANP_MOR.h:214
RCP< Amesos_BaseSolver > origSolver_
Definition: N_ANP_MOR.h:227
Linear::Vector * lastLeadCurrentPtr
Teuchos::SerialDenseMatrix< int, double > redG_
Definition: N_ANP_MOR.h:205
std::string morCompType_
Definition: N_ANP_MOR.h:146
virtual bool startTimeStep(bool beginIntegrationFlag, double nextTimeStep, double nextTime, int currentOrder)
Definition: N_LOA_Loader.h:305
void setErrorWtVector(const TIAParams &tia_params)
virtual bool isPDESystem() const
Definition: N_LOA_Loader.h:256
std::vector< int > bMatEntriesVec_
Definition: N_ANP_MOR.h:196
MORFactory & factory_
Definition: N_ANP_MOR.C:2211
RCP< Amesos_BaseSolver > blockRedSolver_
Definition: N_ANP_MOR.h:231
Linear::Vector * daeFVectorPtr
Linear::Vector * currLeadCurrentQPtr
Nonlinear::Manager & nonlinearManager_
Definition: N_ANP_MOR.C:2184
void info(const std::string &msg)
Definition: N_NLS_NOX.C:71
Teuchos::SerialDenseMatrix< int, std::complex< double > > redH_
Definition: N_ANP_MOR.h:224
Teuchos::SerialDenseMatrix< int, double > redL_
Definition: N_ANP_MOR.h:207
The FactoryBlock contains parameters needed by the analysis creation functions.
IO::InitialConditionsManager & initialConditionsManager_
IO::InitialConditionsManager & initialConditionsManager_
Definition: N_ANP_MOR.C:2187
Linear::Matrix * dFdxMatrixPtr
Parallel::Machine comm_
Definition: N_ANP_MOR.h:129
bool sparsifyRedSystem_()
Definition: N_ANP_MOR.C:1545
bool solveRedLinearSystem_()
Definition: N_ANP_MOR.C:1440
virtual bool updateSources()
Definition: N_LOA_Loader.h:244
Linear::Vector * nextStatePtr
IO::OutputMOR outputMOR_
Definition: N_ANP_MOR.h:137
Linear::Vector * dFdxdVpVectorPtr
RCP< Linear::Matrix > redCPtr_
Definition: N_ANP_MOR.h:210
virtual bool loadDAEMatrices(Linear::Vector *tmpSolVectorPtr, Linear::Vector *tmpStaVectorPtr, Linear::Vector *tmpStaDerivVectorPtr, Linear::Vector *tmpStoVectorPtr, Linear::Matrix *tmpdQdxMatrixPtr, Linear::Matrix *tmpdFdxMatrixPtr)
Definition: N_LOA_Loader.h:110
virtual bool updateState(Linear::Vector *nextSolVectorPtr, Linear::Vector *currSolVectorPtr, Linear::Vector *lastSolVectorPtr, Linear::Vector *nextStaVectorPtr, Linear::Vector *currStaVectorPtr, Linear::Vector *lastStaVectorPtr, Linear::Vector *nextStoVectorPtr, Linear::Vector *currStoVectorPtr, Linear::Vector *lastStoVectorPtr)
Definition: N_LOA_Loader.h:189
Teuchos::SerialDenseMatrix< int, double > redC_
Definition: N_ANP_MOR.h:204
Linear::Vector * currLeadDeltaVPtr
Loader::Loader & loader_
Definition: N_ANP_MOR.h:132
RCP< Epetra_Map > redMapPtr_
Definition: N_ANP_MOR.h:211
AnalysisManager & analysisManager_
Definition: N_ANP_MOR.C:2182
void setDoubleDCOPEnabled(bool enable)
RCP< Linear::BlockVector > REFBPtr_
Definition: N_ANP_MOR.h:200
RCP< Linear::BlockVector > ref_redXPtr_
Definition: N_ANP_MOR.h:220
Nonlinear::Manager & nonlinearManager_
bool createRedLinearSystem_()
Definition: N_ANP_MOR.C:1225
Linear::Vector * nextSolutionPtr
#define M_PI
Linear::Vector * nextStorePtr
std::vector< int > bMatPosEntriesVec_
Definition: N_ANP_MOR.h:196
void addAnalysisFactory(FactoryBlock &factory_block, Util::Factory< AnalysisBase, void > *factory)
Linear::Vector * dQdxdVpVectorPtr
virtual bool doProcessFailedStep()
Definition: N_ANP_MOR.C:1897
bool setMOROptions(const Util::OptionBlock &option_block)
Definition: N_ANP_MOR.C:225
Linear::Vector * currLeadCurrentPtr
Linear::Vector * lastStorePtr
void setInputOPFlag(bool initial_conditions_loaded)
TimeIntg::WorkingIntegrationMethod & getWorkingIntegrationMethod()
Loader::Loader & loader_
Definition: N_ANP_MOR.C:2185
RCP< Linear::Matrix > redGPtr_
Definition: N_ANP_MOR.h:210
std::list< int > morEvalFailures_
Definition: N_ANP_MOR.h:166
RCP< Linear::Matrix > GPtr_
Definition: N_ANP_MOR.h:193
double morScaleFactor1_
Definition: N_ANP_MOR.h:157
Linear::Vector * currSolutionPtr
std::vector< std::string > subcircuitNames_
Definition: N_ANP_MOR.h:160
TimeIntg::DataStore * getDataStore()
unsigned int baseIntegrationMethod_
Current time-integration method flag.
bool evalRedTransferFunction()
Definition: N_ANP_MOR.C:1106
#define W
Linear::Vector * nextStoreLeadCurrQPtr
Util::OptionBlock morOptsOptionBlock_
Definition: N_ANP_MOR.C:2191
RCP< Linear::Matrix > sCpG_MatrixPtr_
Definition: N_ANP_MOR.h:194
Linear::Vector * nextStateDerivPtr
bool updateCurrentFreq_(int stepNumber)
Definition: N_ANP_MOR.C:1967
Teuchos::SerialDenseMatrix< int, double > ref_redB_
Definition: N_ANP_MOR.h:215
RCP< Linear::Matrix > CPtr_
Definition: N_ANP_MOR.h:192
Linear::Matrix * dQdxMatrixPtr
TimeIntg::TIAParams tiaParams_
Definition: N_ANP_MOR.h:139
Linear::Vector * flagSolutionPtr
IO::InitialConditionsManager & initialConditionsManager_
Definition: N_ANP_MOR.h:135
OutputMgrAdapter & outputManagerAdapter_
Definition: N_ANP_MOR.h:136
Linear::Vector * daeBVectorPtr
bool solveOrigLinearSystem_()
Definition: N_ANP_MOR.C:1391
virtual bool doHandlePredictor()
Definition: N_ANP_MOR.C:1941
bool updateRedLinearSystemFreq_()
Definition: N_ANP_MOR.C:1348
virtual bool doFinish()
Definition: N_ANP_MOR.C:1917
Linear::Vector * nextLeadCurrentPtr