Xyce  6.1
N_DEV_DeviceMgr.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_DEV_DeviceMgr.C,v $
27 //
28 // Purpose :
29 //
30 // Special Notes :
31 //
32 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
33 //
34 // Creation Date : 02/28/00
35 //
36 // Revision Information:
37 // ---------------------
38 //
39 // Revision Number: $Revision: 1.681.2.1 $
40 //
41 // Revision Date : $Date: 2015/04/02 18:20:09 $
42 //
43 // Current Owner : $Author: tvrusso $
44 //-------------------------------------------------------------------------
45 
46 #include <Xyce_config.h>
47 
48 #include <algorithm>
49 #include <sstream>
50 #include <stdexcept>
51 
52 #include <N_ANP_AnalysisManager.h>
53 #include <N_DEV_Algorithm.h>
54 #include <N_DEV_Const.h>
55 #include <N_DEV_DeviceMgr.h>
57 #include <N_DEV_ExternDevice.h>
58 #include <N_DEV_InstanceName.h>
59 #include <N_DEV_Op.h>
60 #include <N_DEV_Print.h>
61 #include <N_DEV_RegisterDevices.h>
62 #include <N_DEV_Source.h>
63 #include <N_ERH_ErrorMgr.h>
64 #include <N_ERH_Message.h>
65 #include <N_IO_CmdParse.h>
66 #include <N_IO_MeasureManager.h>
67 #include <N_IO_Op.h>
68 #include <N_IO_PkgOptionsMgr.h>
69 #include <N_LAS_Builder.h>
70 #include <N_LAS_Matrix.h>
71 #include <N_LAS_System.h>
72 #include <N_NLS_Manager.h>
73 #include <N_PDS_Comm.h>
74 #include <N_PDS_MPI.h>
75 #include <N_PDS_Manager.h>
76 #include <N_TOP_Topology.h>
77 #include <N_UTL_Algorithm.h>
78 #include <N_UTL_BreakPoint.h>
79 #include <N_UTL_FeatureTest.h>
80 #include <N_UTL_Op.h>
81 
82 // These are slowly being removed as DeviceMgr should not depend on Devices. Devices should plug in to DeviceMgr.
83 #include <N_DEV_Bsrc.h>
84 #include <N_DEV_ISRC.h>
85 #include <N_DEV_MOSFET_B3.h>
86 #include <N_DEV_MOSFET_B3SOI.h>
87 #include <N_DEV_MOSFET_B4.h>
88 #include <N_DEV_Resistor.h>
89 #include <N_DEV_Resistor3.h>
90 #include <N_DEV_Vsrc.h>
91 
92 
93 namespace Xyce {
94 namespace Device {
95 
96 namespace {
97 
98 // structs related to options registration
99 struct OptionsReg : public IO::PkgOptionsReg
100 {
101  OptionsReg(DeviceMgr & device_manager) : deviceManager_(device_manager)
102  {}
103 
104  bool operator()(const Util::OptionBlock & options)
105  {
106  return deviceManager_.registerOptions(options);
107  }
108 
109  DeviceMgr & deviceManager_;
110 };
111 
112 struct SensOptionsReg : public IO::PkgOptionsReg
113 {
114  SensOptionsReg(DeviceMgr & device_manager) : deviceManager_(device_manager)
115  {}
116 
117  bool operator()(const Util::OptionBlock & options)
118  {return deviceManager_.registerSensParams(options);}
119 
120  DeviceMgr & deviceManager_;
121 };
122 
123 // .OP
124 struct OPAnalysisReg : public IO::PkgOptionsReg
125 {
126  OPAnalysisReg(DeviceMgr & device_manager) : deviceManager_(device_manager)
127  {}
128 
129  bool operator()(const Util::OptionBlock & options)
130  {return deviceManager_.setOPAnalysisParams(options);}
131 
132  DeviceMgr & deviceManager_;
133 };
134 
135 // .HB
136 struct HB_AnalysisReg : public IO::PkgOptionsReg
137 {
138  HB_AnalysisReg(DeviceMgr & device_manager) : deviceManager_(device_manager)
139  {}
140 
141  bool operator()(const Util::OptionBlock & options)
142  {return deviceManager_.setHBAnalysisParams(options);}
143 
144  DeviceMgr & deviceManager_;
145 };
146 
147 // .AC
148 struct AC_AnalysisReg : public IO::PkgOptionsReg
149 {
150  AC_AnalysisReg(DeviceMgr & deviceManager_) : deviceManager_(deviceManager_)
151  {}
152 
153  bool operator()(const Util::OptionBlock & options)
154  {return deviceManager_.setACAnalysisParams(options);}
155 
156  DeviceMgr & deviceManager_;
157 };
158 
159 // .NOISE
160 struct NOISE_AnalysisReg : public IO::PkgOptionsReg
161 {
162  NOISE_AnalysisReg(DeviceMgr & deviceManager_) : deviceManager_(deviceManager_)
163  {}
164 
165  bool operator()(const Util::OptionBlock & options)
166  {return deviceManager_.setNOISEAnalysisParams(options);}
167 
168  DeviceMgr & deviceManager_;
169 };
170 
171 // ----------------------------------------------------------------------------
172 // Function : setupIOName
173 //
174 // Purpose : This function takes the device instance name and creates
175 // an appropriate "outputName" to be used for file outputs.
176 //
177 // Special Notes :
178 // Scope : public
179 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
180 // Creation Date : 04/26/2013
181 // ----------------------------------------------------------------------------
182 const std::string setupIOName(const InstanceName &entity_name)
183 {
184  return entity_name.getDeviceName();
185 }
186 
187 // ----------------------------------------------------------------------------
188 // Function : findDeviceEntity
189 // Scope : public
190 // Creator : Dave Baur
191 // ----------------------------------------------------------------------------
192 DeviceEntity *findDeviceEntity(
193  EntityTypeIdDeviceMap::const_iterator begin,
194  EntityTypeIdDeviceMap::const_iterator end,
195  const std::string entity_name)
196 {
197  for (EntityTypeIdDeviceMap::const_iterator it = begin; it != end; ++it)
198  {
199  DeviceEntity *device_entity = (*it).second->findInstance(InstanceName(entity_name));
200  if (device_entity)
201  return device_entity;
202 
203  device_entity = (*it).second->findModel(ModelName(entity_name));
204  if (device_entity)
205  return device_entity;
206  }
207 
208  return 0;
209 }
210 
211 } // namespace <unnamed>
212 
213 //-----------------------------------------------------------------------------
214 // Function : DeviceMgr::registerPkgOptionsMgr
215 // Purpose :
216 // Special Notes :
217 // Scope : public
218 // Creator : Richard Schiek, Electrical and Mems Modeling
219 // Creation Date : 10/20/2008
220 //-----------------------------------------------------------------------------
221 bool registerPkgOptionsMgr(DeviceMgr &device_manager, const std::string &netlist_filename, IO::PkgOptionsMgr &options_manager)
222 {
223  options_manager.submitRegistration(
224  "DEVICE", netlist_filename, new OptionsReg(device_manager));
225 
226  options_manager.submitRegistration(
227  "SENS", netlist_filename, new SensOptionsReg(device_manager));
228 
229  options_manager.submitRegistration(
230  "OP", netlist_filename, new OPAnalysisReg(device_manager));
231 
232  // HB Specific netlist lines
233  options_manager.submitRegistration(
234  "HB", netlist_filename, new HB_AnalysisReg(device_manager));
235 
236  // AC Specific netlist lines
237  options_manager.submitRegistration(
238  "AC", netlist_filename, new AC_AnalysisReg(device_manager));
239 
240  // NOISE Specific netlist lines
241  options_manager.submitRegistration(
242  "NOISE", netlist_filename, new NOISE_AnalysisReg(device_manager));
243 
244  return true;
245 }
246 
247 
248 //-----------------------------------------------------------------------------
249 // Function : DeviceMgr::DeviceMgr
250 // Purpose : constructor
251 // Special Notes :
252 // Scope : private
253 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
254 // Creation Date : 3/16/00
255 //-----------------------------------------------------------------------------
257  Parallel::Machine comm,
258  Topo::Topology & topology,
259  const IO::CmdParse & command_line)
260  : commandLine_(command_line),
261  topology_(topology),
262  devOptions_(),
263  deviceMap_(),
264  sensFlag_(false),
265  linearSystemFlag_(true),
266  firstDependent_(true),
267  parameterChanged_(false),
268  breakPointInstancesInitialized(false),
269  timeParamsProcessed_(0.0),
270  externData_(),
271  matrixLoadData_(),
272  solState_(),
273  globals_(solState_.globals_),
274  solStateExternal_(),
275  externalStateFlag_(false),
276  numJacStaVectorPtr_(0),
277  numJacSolVectorPtr_(0),
278  numJacStoVectorPtr_(0),
279  diagonalVectorPtr_(0),
280  analysisManager_(0),
281  measureManager_(0),
282  comm_(comm),
283  nlsMgrPtr_(0),
284  icLoads_(NULL),
285  modelTypeMap_(),
286  modelGroupMap_(),
287  modelGroupInstanceVector_(),
288  modelTypeInstanceVector_(),
289  modelVector_(),
290  modelGroupModelVector_(),
291  modelTypeModelVector_(),
292  localDeviceCountMap_(),
293  devicePtrVec_(),
294  pdeDevicePtrVec_(),
295  instancePtrVec_(),
296  bpInstancePtrVec_(),
297  pdeInstancePtrVec_(),
298  nonPdeInstancePtrVec_(),
299  plotFileInstancePtrVec_(),
300  independentSourceVector_(),
301  independentSourceMap_(),
302  indepSourceInstanceBackupPtrVec_(),
303  testJacDevicePtrVec_(),
304  dependentPtrVec_(),
305  devicesNeedingLeadCurrentLoads_(),
306  passThroughParamsMap_(),
307  parameterDeviceCache_(),
308  numInterfaceNodes_(),
309  calledBeforeCSPI (false),
310  devSensPtr_(new DeviceSensitivities(*this, devOptions_)),
311  dotOpOutputFlag(false),
312  artificialParameterMap_()
313 {
334 
335  passThroughParamsMap_[ "MOSFET_ALL:GAINSCALE" ] = 1;
336  passThroughParamsMap_[ "MOSFET_ALL:NLTERMSCALE" ] = 1;
337  passThroughParamsMap_[ "MOSFET1:GAINSCALE" ] = 1;
338  passThroughParamsMap_[ "MOSFET1:NLTERMSCALE" ] = 1;
339 
340  devOptions_.setupDefaultOptions(command_line);
341  devOptions_.applyCmdLineOptions(command_line);
342 
343  solState_.debugTimeFlag = true;
344 }
345 
346 //-----------------------------------------------------------------------------
347 // Function : DeviceMgr::registerAnalysisManager
348 // Purpose :
349 // Special Notes :
350 // Scope : public
351 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
352 // Creation Date : 3/16/00
353 //-----------------------------------------------------------------------------
354 bool
356  Analysis::AnalysisManager * analysis_manager)
357 {
358  analysisManager_ = analysis_manager;
359 
360  return analysisManager_ != 0;
361 }
362 
363 //-----------------------------------------------------------------------------
364 // Function : DeviceMgr::~DeviceMgr
365 // Purpose : destructor
366 // Special Notes :
367 // Scope : public
368 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
369 // Creation Date : 3/16/00
370 //-----------------------------------------------------------------------------
372 {
373  delete numJacStaVectorPtr_;
374  delete numJacSolVectorPtr_;
375  delete numJacStoVectorPtr_;
376  delete diagonalVectorPtr_;
377 
383 
384  delete externData_.tmpdIdXPtr;
385  delete externData_.tmpdQdXPtr;
386 
387  for (EntityTypeIdDeviceMap::iterator it = deviceMap_.begin(), end = deviceMap_.end(); it != end; ++it)
388  delete (*it).second;
389 
390  for (ArtificialParameterMap::iterator it = artificialParameterMap_.begin(), end = artificialParameterMap_.end(); it != end; ++it)
391  delete (*it).second;
392 
393  delete icLoads_;
394  delete devSensPtr_;
395 }
396 
397 //-----------------------------------------------------------------------------
398 // Function : DeviceMgr::registerSensParams
399 // Purpose :
400 // Special Notes :
401 // Scope : public
402 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
403 // Creation Date : 6/03/02
404 //-----------------------------------------------------------------------------
405 bool DeviceMgr::registerSensParams (const Util::OptionBlock & OB)
406 {
407  sensFlag_ = true;
408 
409  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
410  {
411  dout() << "DeviceMgr::registerSensParams called!" <<std::endl;
412  }
413 
414  return devSensPtr_->registerSensParams (OB);
415 }
416 
417 
418 //-----------------------------------------------------------------------------
419 // Function : DeviceMgr::registerLeadCurrentRequests
420 // Purpose : this function is called from the output manager (through the
421 // device interface) to inform the device package of the devices
422 // for which lead currents have been requested. The device
423 // manager will take care of doing isolated F and Q loads for
424 // these devices so the lead currents can be calculated
425 // Special Notes :
426 // Scope : public
427 // Creator : Richard Schiek, SNL, Electrical Systems Modeling
428 // Creation Date : 03/20/13
429 //-----------------------------------------------------------------------------
430 bool DeviceMgr::setLeadCurrentRequests(const std::set<std::string> & deviceNames)
431 {
432  // this is called prior to fully constructing the devices. So for now
433  // save the list
434  devicesNeedingLeadCurrentLoads_ = deviceNames;
435 
436  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
437  {
438  if (! devicesNeedingLeadCurrentLoads_.empty())
439  {
440  dout() << "DeviceMgr::registerLeadCurrentRequests Devices for which lead currents were requested: ";
441  for (std::set<std::string>::iterator it = devicesNeedingLeadCurrentLoads_.begin(), end = devicesNeedingLeadCurrentLoads_.end(); it != end; ++it)
442  {
443  dout() << (*it) << " ";
444  }
445  dout() << std::endl;
446  }
447  }
448 
449  return true;
450 }
451 
452 //-----------------------------------------------------------------------------
453 // Function : DeviceMgr::setOPAnalysisParams
454 // Purpose :
455 // Special Notes :
456 // Scope : public
457 // Creator : Eric Keiter, SNL
458 // Creation Date : 10/14/11
459 //-----------------------------------------------------------------------------
460 bool DeviceMgr::setOPAnalysisParams (const Util::OptionBlock & OB)
461 {
462  solState_.OPspecified = true;
463  return true;
464 }
465 
466 //-----------------------------------------------------------------------------
467 // Function : DeviceMgr::setHBAnalysisParams
468 // Purpose :
469 // Special Notes :
470 // Scope : public
471 // Creator : Eric Keiter, SNL
472 // Creation Date : 10/14/11
473 //-----------------------------------------------------------------------------
474 bool DeviceMgr::setHBAnalysisParams (const Util::OptionBlock & OB)
475 {
476  solState_.HBspecified = true;
477  return true;
478 }
479 
480 //-----------------------------------------------------------------------------
481 // Function : DeviceMgr::setACAnalysisParams
482 // Purpose :
483 // Special Notes :
484 // Scope : public
485 // Creator : Eric Keiter, SNL
486 // Creation Date : 10/14/11
487 //-----------------------------------------------------------------------------
488 bool DeviceMgr::setACAnalysisParams (const Util::OptionBlock & OB)
489 {
490  solState_.ACspecified = true;
491  return true;
492 }
493 
494 //-----------------------------------------------------------------------------
495 // Function : DeviceMgr::setNOISEAnalysisParams
496 // Purpose :
497 // Special Notes :
498 // Scope : public
499 // Creator : Eric Keiter, SNL
500 // Creation Date : 12/14/2014
501 //-----------------------------------------------------------------------------
502 bool DeviceMgr::setNOISEAnalysisParams (const Util::OptionBlock & OB)
503 {
504  solState_.ACspecified = true;
505  return true;
506 }
507 
508 const InstanceVector &
510 {
511  static InstanceVector s_emptyVector;
512 
513  ModelTypeInstanceVectorMap::const_iterator model_type_it = modelTypeInstanceVector_.find(ExternDevice::Traits::modelType());
514  if (model_type_it != modelTypeInstanceVector_.end())
515  return (*model_type_it).second;
516  else
517  return s_emptyVector;
518 }
519 
520 //-----------------------------------------------------------------------------
521 // Function : DeviceMgr::getFastSourcePeriod
522 // Purpose :
523 // Special Notes :
524 // Scope : public
525 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
526 // Creation Date : 3/27/04
527 //-----------------------------------------------------------------------------
528 std::vector<double>
530  Parallel::Machine comm,
531  const std::vector<std::string> & sourceNames)
532 {
533  int numFastSrcs = sourceNames.size();
534 
535  // Setup return of source periods
536  std::vector<double> srcPeriods(numFastSrcs);
537 
538  // Now loop over them, and mark them.
539  for (int i = 0; i < numFastSrcs; ++i)
540  {
541  IndependentSourceMap::const_iterator it = independentSourceMap_.find(sourceNames[i]);
542  if (it != independentSourceMap_.end())
543  {
544  const SourceInstance &source_instance = *(*it).second;
545  srcPeriods[i] = source_instance.period();
546  }
547  else
548  {
549 #ifndef Xyce_PARALLEL_MPI
550  Report::UserError message;
551  message << "Unable to find source: " << sourceNames[i] << "\n"
552  << "Potential names are: ";
553  for (IndependentSourceMap::const_iterator it = independentSourceMap_.begin(); it != independentSourceMap_.end(); ++it)
554  message << (*it).first << " ";
555 #endif
556  }
557  }
558 
559  Parallel::AllReduce(comm, MPI_MAX, srcPeriods);
560 
561  return srcPeriods;
562 }
563 
564 
565 //-----------------------------------------------------------------------------
566 // Function : DeviceMgr::registerFastSources
567 // Purpose :
568 // Special Notes :
569 // Scope : public
570 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
571 // Creation Date : 3/27/04
572 //-----------------------------------------------------------------------------
573 std::vector<double>
575  Parallel::Machine comm,
576  const std::vector<std::string> & sourceNames)
577 {
578  int numFastSrcs = sourceNames.size();
579 
580  std::vector<double> srcPeriods;
581 
582  if (numFastSrcs > 0)
583  {
584  srcPeriods.resize(numFastSrcs, 0.0);
585 
586  // Now loop over them, and mark them.
587  for (int i = 0; i < numFastSrcs; ++i)
588  {
589  IndependentSourceMap::iterator it = independentSourceMap_.find(sourceNames[i]);
590  if (it != independentSourceMap_.end())
591  {
592  SourceInstance &source_instance = *(*it).second;
593  source_instance.setFastSourceFlag(true);
594  srcPeriods[i] = source_instance.period();
595  }
596  else
597  {
598 #ifndef Xyce_PARALLEL_MPI
599  Report::UserError message;
600  message << "Unable to find source: " << sourceNames[i] << "\n"
601  << "Potential names are: ";
602  for (IndependentSourceMap::const_iterator it = independentSourceMap_.begin(); it != independentSourceMap_.end(); ++it)
603  message << (*it).first << " ";
604 #endif
605  }
606  }
607 
608  }
609  else
610  {
611  // tscoffe/tmei 09/16/08
612  // Special case: Use all sources
613  // Compute the total number of fast sources for all processors.
614  // NOTE: In parallel, this will not work correctly if more than one processor has fast sources.
615 
616  int myNumFastSrcs = independentSourceVector_.size();
617  Parallel::AllReduce(comm, MPI_SUM, &myNumFastSrcs, &numFastSrcs, 1);
618 
619  if (myNumFastSrcs > independentSourceVector_.size())
620  throw std::runtime_error("registerFastSources() does not handle parallel");
621 
622  srcPeriods.resize(numFastSrcs, -1.0);
623  for (int i = 0; i < myNumFastSrcs; ++i)
624  {
625  independentSourceVector_[i]->setFastSourceFlag(true);
626  srcPeriods[i] = independentSourceVector_[i]->period();
627  }
628  }
629 
630  Parallel::AllReduce(comm, MPI_MAX, srcPeriods);
631 
632  return srcPeriods;
633 }
634 
635 
636 //-----------------------------------------------------------------------------
637 // Function : DeviceMgr::deRegisterFastSources
638 // Purpose : reverses the effect of registerFastSources
639 // Special Notes :
640 // Scope : public
641 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
642 // Creation Date : 06/12/2013
643 //-----------------------------------------------------------------------------
644 void DeviceMgr::deRegisterFastSources(const std::vector<std::string> &sourceNames)
645 {
646  int numFastSrcs = sourceNames.size();
647 
648  if (numFastSrcs > 0)
649  {
650  // Now loop over them, and mark them.
651  for (int i = 0; i < numFastSrcs; ++i)
652  {
653  IndependentSourceMap::iterator it = independentSourceMap_.find(sourceNames[i]);
654  if (it != independentSourceMap_.end())
655  {
656  SourceInstance &source_instance = *(*it).second;
657  source_instance.setFastSourceFlag(false);
658  }
659  else
660  {
661 #ifndef Xyce_PARALLEL_MPI
662  Report::DevelFatal message;
663  message.in("DeviceMgr::deRegisterFastSources");
664  message << "Unable to find source: " << sourceNames[i] << std::endl
665  << "Potential names are: ";
666  for (IndependentSourceMap::const_iterator it = independentSourceMap_.begin(); it != independentSourceMap_.end(); ++it)
667  message << (*it).first << " ";
668 #endif
669  }
670  }
671  }
672  else
673  {
674  // Special case: Use all sources
675  numFastSrcs = independentSourceVector_.size();
676  for (int i = 0; i < numFastSrcs; ++i)
677  {
678  independentSourceVector_[i]->setFastSourceFlag(false);
679  }
680  }
681  return;
682 }
683 
684 //-----------------------------------------------------------------------------
685 // Function : DeviceMgr::deactivateSlowSources
686 // Purpose : traverse fast source list and remove any slow sources from
687 // the deviceArray
688 // Special Notes :
689 // Scope : public
690 // Creator : Rich Schiek, SNL, Parallel Computational Sciences
691 // Creation Date : 3/22/07
692 //-----------------------------------------------------------------------------
694 {
695  // first back-up a copy of the deviceArray so we can edit out the slow sources
697  // indepSourceInstanceBackupPtrVec_.resize(independentSourceVector_.size());
698  // std::copy(independentSourceVector_.begin(), independentSourceVector_.end(), indepSourceInstanceBackupPtrVec_.begin());
699 
700  // erase the existing list of sources
701  independentSourceVector_.clear();
702 
703  // now copy back only those that are fast sources
704  for (IndependentSourceVector::iterator it = indepSourceInstanceBackupPtrVec_.begin(), end = indepSourceInstanceBackupPtrVec_.end(); it != end; ++it)
705  {
706  if ((*it)->getFastSourceFlag())
707  {
708  independentSourceVector_.push_back(*it);
709  }
710  }
711 }
712 
713 //-----------------------------------------------------------------------------
714 // Function : DeviceMgr::activateSlowSources
715 // Purpose : restore any slow sources to the device array.
716 // Special Notes :
717 // Scope : public
718 // Creator : Rich Schiek, SNL, Parallel Computational Sciences
719 // Creation Date : 3/22/07
720 //-----------------------------------------------------------------------------
722 {
723  // restore the independent source list from backup
725  // independentSourceVector_.clear();
726  // independentSourceVector_.resize(indepSourceInstanceBackupPtrVec_.size());
727  // std::copy(indepSourceInstanceBackupPtrVec_.begin(), indepSourceInstanceBackupPtrVec_.end(), independentSourceVector_.begin());
728 }
729 
730 //-----------------------------------------------------------------------------
731 // Function : DeviceMgr::setMPDEFlag
732 // Purpose :
733 // Special Notes :
734 // Scope : public
735 // Creator : Richard Schiek, SNL, Parallel Computational Sciences
736 // Creation Date : 07/21/08
737 //-----------------------------------------------------------------------------
738 void DeviceMgr::setMPDEFlag(bool flagVal)
739 {
740  solState_.mpdeOnFlag = flagVal;
741 }
742 
743 //-----------------------------------------------------------------------------
744 // Function : DeviceMgr::setBlockAnalysisFlag
745 // Purpose :
746 // Special Notes :
747 // Scope : public
748 // Creator : Richard Schiek, SNL, Parallel Computational Sciences
749 // Creation Date : 07/21/08
750 //-----------------------------------------------------------------------------
752 {
753  solState_.blockAnalysisFlag = flagVal;
754 
755  // tscoffe/tmei 07/30/08: Note, if we call this with "false", then the
756  // newExcessPhase and defaultNewExcessPhase flags will not go back to their
757  // "user-set" values, they will be set to false.
758  devOptions_.newExcessPhase = flagVal;
760 }
761 
762 //-----------------------------------------------------------------------------
763 // Function : DeviceMgr::setFastTime
764 // Purpose :
765 // Special Notes :
766 // Scope : public
767 // Creator : Richard Schiek, SNL, Parallel Computational Sciences
768 // Creation Date : 07/21/08
769 //-----------------------------------------------------------------------------
770 void DeviceMgr::setFastTime(double timeVal)
771 {
772  solState_.currFastTime = timeVal;
773 }
774 
775 //-----------------------------------------------------------------------------
776 // Function : DeviceMgr::initializeAll
777 // Purpose : This function, via the LAS system class, sets up
778 // the pointers to the various linear algebra entities.
779 // Special Notes :
780 // Scope : public
781 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
782 // Creation Date : 6/12/00
783 //-----------------------------------------------------------------------------
784 bool DeviceMgr::initializeAll(Linear::System &linear_system)
785 {
786  bool bsuccess = true;
787 
788  externData_.lasSysPtr = &linear_system;
789 
790  // nullify ptrs that are passed in at each step (see the loadDAEVectors function args)
816 
817  if (DEBUG_DEVICE)
818  {
819  // get f vector pointer:
820  externData_.fVectorPtr = linear_system.getFVector();
821  bsuccess = bsuccess && (externData_.fVectorPtr != 0);
822 
823  // create Jdxp vector pointer:
824  externData_.JdxpVectorPtr = linear_system.getJDXPVector();
825  bsuccess = bsuccess && (externData_.JdxpVectorPtr != 0);
826  }
827 
828  if (DEBUG_VOLTLIM)
829  {
830  // get test matrix: (old DAE)
831  externData_.JTestMatrixPtr = linear_system.getJacTestMatrix();
832  bsuccess = bsuccess && (externData_.JTestMatrixPtr != 0);
833 
834  // get test matrix:
835  externData_.FTestMatrixPtr = linear_system.getdFdxTestMatrix();
836  bsuccess = bsuccess && (externData_.FTestMatrixPtr != 0);
837  externData_.QTestMatrixPtr = linear_system.getdQdxTestMatrix();
838  bsuccess = bsuccess && (externData_.QTestMatrixPtr != 0);
839 
840  // get dxVoltlim vector pointer:
841  externData_.dxVoltlimVectorPtr = linear_system.getDxVoltlimVector() ;
842  bsuccess = bsuccess && (externData_.dxVoltlimVectorPtr != 0);
843 
844  // create Jdx2 vector pointer: (old DAE)
845  externData_.Jdx2VectorPtr = linear_system.getJDX2Vector();
846  bsuccess = bsuccess && (externData_.Jdx2VectorPtr != 0);
847 
848  // create Jdx2 vector pointer:
849  externData_.Fdx2VectorPtr = linear_system.getFDX2Vector();
850  bsuccess = bsuccess && (externData_.Fdx2VectorPtr != 0);
851  externData_.Qdx2VectorPtr = linear_system.getQDX2Vector();
852  bsuccess = bsuccess && (externData_.Qdx2VectorPtr != 0);
853  }
854 
855  // get flag solution pointer-pointer:
856  externData_.flagSolVectorPtr = linear_system.getFlagSolVector();
857  bsuccess = bsuccess && (externData_.flagSolVectorPtr != 0);
858 
859  // get device mask pointer.
860  externData_.deviceErrorWeightMask_ = linear_system.getDeviceMaskVector ();
861  bsuccess = bsuccess && (externData_.deviceErrorWeightMask_ != 0);
862 
863  // create the temporary numerical jacobian vectors
865  {
866  numJacStaVectorPtr_ = linear_system.builder().createStateVector();
867  numJacSolVectorPtr_ = linear_system.builder().createVector();
868  numJacStoVectorPtr_ = linear_system.builder().createStoreVector();
869 
870  externData_.numJacRHSVectorPtr = linear_system.builder().createVector();
871  externData_.numJacFVectorPtr = linear_system.builder().createVector();
872  externData_.numJacQVectorPtr = linear_system.builder().createVector();
873  externData_.perturbVectorPtr = linear_system.builder().createVector();
874  externData_.numJacLoadFlagPtr = linear_system.builder().createVector();
875  }
876 
877  externData_.tmpdIdXPtr = linear_system.builder().createVector();
878  externData_.tmpdQdXPtr = linear_system.builder().createVector();
879 
880  // create a diagonal vector to be used for 2-level
881  diagonalVectorPtr_ = linear_system.builder().createVector();
882 
884 
885  // For Homotopy on block gainscale
887 
888 #ifdef Xyce_SIZEOF
889  int size = sizeof(*this);
890  dout() << "Size of device package after initializeAll = " << size << std::endl;
891 #endif
892 
893  return bsuccess;
894 }
895 
896 //-----------------------------------------------------------------------------
897 // Function : DeviceMgr::resetForStepAnalysis
898 // Purpose :
899 // Special Notes : Some "resetForStep" functions (only HB so far) will
900 // call dev->initializeAll. So, this must be called first.
901 // Scope : public
902 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
903 // Creation Date : 07/12/2013
904 //-----------------------------------------------------------------------------
905 
907 {
909  {
921 
925  }
926 }
927 
928 //-----------------------------------------------------------------------------
929 // Function : DeviceMgr::createDevice
930 // Purpose : This function creates a single device based on the passed
931 // index.
932 // Special Notes :
933 // Scope : protected
934 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
935 // Creation Date : 3/16/00
936 //-----------------------------------------------------------------------------
938 {
939  Device *device = 0;
940 
941  if (model_type_id.defined())
942  {
943  EntityTypeIdDeviceMap::const_iterator it = deviceMap_.find(model_type_id);
944  if (it == deviceMap_.end())
945  {
947 
948  const Configuration *configuration = Configuration::findConfiguration(model_type_id);
949  device = configuration->createDevice(factory_block);
950  deviceMap_[model_type_id] = device;
951  devicePtrVec_.push_back(device);
952 
953  if (device->isPDEDevice())
954  {
955  pdeDevicePtrVec_.push_back(device);
956  }
957  }
958  else
959  device = (*it).second;
960  }
961 
962  return *device;
963 }
964 
965 //-----------------------------------------------------------------------------
966 // Function : DeviceMgr::getModelGroup
967 // Purpose : This function returns the device type index for a given
968 // named string. This assumes that the device names used
969 // in the simulation will obey the spice3f5 netlist language
970 // convention.
971 //
972 // Special Notes :
973 // Scope : public
974 // Creator :
975 // Creation Date : 3/16/00
976 //-----------------------------------------------------------------------------
977 /**
978  * Return the ModelGroup of the device associated with the model type name or device type name.
979  *
980  * @param model_type_name model type name or device type name
981  *
982  * @return
983  *
984  * @author David G. Baur Raytheon Sandia National Laboratories 1355
985  * @date Mon Sep 23 07:53:04 2013
986  */
987 EntityTypeId DeviceMgr::getModelGroup(const std::string &model_or_device_type_name)
988 {
989  return Configuration::getModelGroup(model_or_device_type_name);
990 }
991 
992 //-----------------------------------------------------------------------------
993 // Function : DeviceMgr::addDeviceModel
994 // Purpose :
995 // Special Notes :
996 // Scope : public
997 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
998 // Creation Date : 3/16/00
999 //-----------------------------------------------------------------------------
1000 bool DeviceMgr::addDeviceModel(const ModelBlock & model_block)
1001 {
1002  ModelTypeId model_type;
1003  ModelTypeId model_group = Configuration::getModelGroup(model_block.getType());
1004 
1005  if (!model_block.getName().empty())
1006  {
1007  model_type = Configuration::getModelType(model_block.getType(), model_block.getLevel());
1008 
1009  if (!model_type.defined())
1010  Report::UserError() << "There is no device " << model_block.getType() << " of level " << model_block.getLevel() << " to define model " << model_block.getName();
1011  }
1012 
1013  if (!model_type.defined())
1014  model_type = model_group;
1015 
1016  if (!model_type.defined())
1017  return false;
1018 
1020  Device &device = getDeviceByModelType(model_type);
1021  DeviceModel *device_model = device.addModel(model_block, factory_block);
1022 
1023  modelTypeMap_[model_block.getName()] = model_type;
1024  modelGroupMap_[model_block.getName()] = model_group;
1025 
1026  // add the various model vectors:
1027  if (device_model != 0)
1028  {
1029  modelVector_.push_back(device_model);
1030  modelGroupModelVector_[model_group].push_back(device_model);
1031  modelTypeModelVector_[model_type].push_back(device_model);
1032  }
1033 
1034  return device_model != 0;
1035 }
1036 
1037 //-----------------------------------------------------------------------------
1038 // Function : DeviceMgr::getModelType
1039 // Purpose :
1040 // Special Notes :
1041 // Scope : public
1042 // Creator : Dave Baur
1043 // Creation Date :
1044 //-----------------------------------------------------------------------------
1045 std::pair<ModelTypeId, ModelTypeId> DeviceMgr::getModelType(const InstanceBlock & instance_block)
1046 {
1047  // If the ModelName string is not a null string, use it to get the
1048  // device type index. Otherwise, use the name of the device itself to determine the device.
1049  ModelTypeId model_type;
1050  ModelTypeId model_group;
1051  if (instance_block.getModelName().empty())
1052  {
1053  model_type = getModelGroup(instance_block.getInstanceName().getDeviceType());
1054  model_group = model_type;
1055  }
1056  else
1057  {
1058  model_type = modelTypeMap_[instance_block.getModelName()];
1059  model_group = modelGroupMap_[instance_block.getModelName()];
1060  }
1061 
1062  if (!model_type.defined())
1063  {
1064  Report::UserError message;
1065  message << "Unable to determine type of device for instance name " << instance_block.getInstanceName();
1066  if (!instance_block.getModelName().empty())
1067  {
1068  message << " with model name " << instance_block.getModelName();
1069  }
1070  return std::pair<ModelTypeId, ModelTypeId>(ModelTypeId(), ModelTypeId());
1071  }
1072  else if (instance_block.bsourceFlag)
1073  {
1074  // This is an E, F, G, or H source that is to be treated as a B source,
1075  // set its type now to BSRC.
1076  model_type = Bsrc::Traits::modelType();
1077  }
1078 
1079  // Check if this is a simple resistor, but with a resistance of zero. If so,
1080  // then change the type to RESISTOR3. This variant of the resistor acts like
1081  // a voltage souce with zero voltage difference.
1083  {
1084  const double zeroResistanceValue = devOptions_.zeroResistanceTol;
1085  // loop over the parameters
1086  std::vector<Param>::const_iterator currentParam = instance_block.params.begin();
1087  std::vector<Param>::const_iterator endParam = instance_block.params.end();
1088  while(currentParam != endParam)
1089  {
1090  if ((currentParam->uTag() == "R"))
1091  {
1092  if (currentParam->given())
1093  {
1094  std::vector<std::string> variables, specials;
1095 
1096  // check if this is a time-dependent, or variable-dependent expression.
1097  // If it is, then skip.
1098  const Param * devPar = &(*(currentParam));
1099  const Util::Param * tmpPar = (dynamic_cast<const Util::Param*> (devPar));
1100  // only check if this is an expression-type parameter.
1101  if (tmpPar->getType() == Util::EXPR)
1102  {
1103  Util::Expression tmpExp = tmpPar->getValue<Util::Expression>();
1104  tmpExp.get_names(XEXP_VARIABLE, variables);
1105  tmpExp.get_names(XEXP_SPECIAL, specials);
1106  }
1107 
1108  if (specials.empty() && variables.empty())
1109  {
1110  if (fabs(currentParam->getImmutableValue<double>()) < devOptions_.zeroResistanceTol)
1111  {
1112  // change device type to be the level 3 resistor
1113  model_type = Resistor3::Traits::modelType();
1114  }
1115  }
1116  }
1117  break;
1118  }
1119  currentParam++;
1120  }
1121  }
1122 
1123  return std::pair<ModelTypeId, ModelTypeId>(model_type, model_group);
1124 }
1125 
1126 //-----------------------------------------------------------------------------
1127 // Function : DeviceMgr::verifyDeviceInstance
1128 // Purpose : This function verifies a device instance prior to
1129 // instantiating.
1130 //
1131 // Theoretically, we could do this in addDeviceInstance() and
1132 // not make a device if it fails some verification criteria (a
1133 // resistor with zero resistance is the primary case here).
1134 // However, later unlinking of redundant devices that are
1135 // connected to just one node is difficult after
1136 // addDeviceInstance() is called because the device instance
1137 // pointer can be placed in many other containers
1138 // It could be done, but this is a simpler first step to having the
1139 // device manager be in charge of device verification -- rather
1140 // than have it in topology or IO.
1141 //
1142 // Special Notes : return true if this device is ok to instantiate, false otherwise
1143 // Scope : public
1144 // Creator : Richard Schiek, Electrical and Microsystems Modeling
1145 // Creation Date : 2/18/2010
1146 //-----------------------------------------------------------------------------
1148 {
1149  ModelTypeId model_type;
1150  ModelTypeId model_group;
1151  std::pair<ModelTypeId, ModelTypeId> x = getModelType(instance_block);
1152  model_type = x.first;
1153  model_group = x.second;
1154 
1155  if (!model_type.defined())
1156  {
1157  Report::UserError message;
1158  message << "Unable to determine model type of device for instance name " << instance_block.getInstanceName();
1159  if (!instance_block.getModelName().empty())
1160  {
1161  message << " with model name" << instance_block.getModelName();
1162  }
1163 
1164  return false;
1165  }
1166 
1167  // Return false if we found a supernode.
1168  if (model_type == Resistor3::Traits::modelType())
1169  {
1170  return false;
1171  }
1172 
1173  return true;
1174 }
1175 
1176 //-----------------------------------------------------------------------------
1177 // Function : DeviceMgr::addDeviceInstance
1178 // Purpose : addDeviceInstance will create a new instance of the
1179 // designated device type. This version of the function
1180 // accepts a parameter list as one of the arguments,
1181 // so it is assumed that a parameter instance will
1182 // also have to be allocated for it.
1183 //
1184 // Special Notes :
1185 // Scope : public
1186 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1187 // Creation Date : 3/16/00
1188 //-----------------------------------------------------------------------------
1191  const InstanceBlock & instance_block)
1192 {
1193  // If the ModelName string is not a null string, use it to get the
1194  // device type index. Otherwise, use the name of the device itself to determine the device.
1195  ModelTypeId model_type;
1196  ModelTypeId model_group;
1197  std::pair<ModelTypeId, ModelTypeId> x = getModelType(instance_block);
1198  model_type = x.first;
1199  model_group = x.second;
1200 
1201  if (!model_type.defined())
1202  {
1203  Report::UserError message;
1204  message << "Unable to determine type of device for instance name " << instance_block.getInstanceName();
1205  if (!instance_block.getModelName().empty())
1206  {
1207  message << " with model name " << instance_block.getModelName();
1208  }
1209 
1210  DeviceInstance *instance = 0;
1211  return instance;
1212  }
1213 
1214  // Add an instance of this type.
1215  Device &device = getDeviceByModelType(model_type);
1216  DeviceInstance *instance = device.addInstance(
1217  instance_block,
1219 
1220  // Using setupIOName removes the "yxxx" or "uxxx" part of the name. However that leaves
1221  // an ambiguous device name to resolve after that (i.e. ymemristor mr1 becomes ymemristor!mr1 and
1222  // the value returned by setupIOName is "mr1" which looks like a mosfet device called "r1". Thus
1223  // we need to use the full instanste name here an not the IO name.
1224  //
1225  //std::string outputName = setupIOName(instance->getName());
1226  std::string outputName = (instance->getName()).getEncodedName();
1229  {
1230  instance->enableLeadCurrentCalc();
1231 
1232  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1233  {
1234  dout() << "DeviceMgr::addDeviceInstance Enabling lead current load for device \""
1235  << instance->getName()
1236  << "\" -> \""
1237  << outputName
1238  << "\"" << std::endl;
1239  }
1240  }
1241  else if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1242  {
1243  dout() << "DeviceMgr::addDeviceInstance Cannot enable lead current load for device \""
1244  << instance->getName()
1245  << "\" -> \""
1246  << outputName
1247  << "\""
1248  << std::endl;
1249  }
1250 
1251  localDeviceCountMap_[device.getDefaultModelName()]++;
1252 
1253  linearSystemFlag_ = linearSystemFlag_ && device.isLinearDevice();
1254 
1255  solState_.PDESystemFlag = solState_.PDESystemFlag || device.isPDEDevice();
1256 
1257  // Set up the instance vectors. These are the main containers used in the load procedures.
1258  instancePtrVec_.push_back(instance);
1259 
1260  // set up the list of pde device instances
1261  // and the list of non-pde devices instances.
1262  if (device.isPDEDevice())
1263  {
1264  pdeInstancePtrVec_.push_back(instance);
1265  }
1266  else
1267  {
1268  nonPdeInstancePtrVec_.push_back(instance);
1269  }
1270 
1271  modelGroupInstanceVector_[model_group].push_back(instance);
1272  modelTypeInstanceVector_[model_type].push_back(instance);
1273 
1274  // set up the independent source map.
1275  if (model_type == Vsrc::Traits::modelType() || model_type == ISRC::Traits::modelType())
1276  {
1277  independentSourceMap_[instance_block.getInstanceName().getEncodedName()] = dynamic_cast<SourceInstance *>(instance);
1278  independentSourceVector_.push_back(dynamic_cast<SourceInstance *>(instance));
1279  }
1280 
1281  if (instance->plotfileFlag ())
1282  {
1283  plotFileInstancePtrVec_.push_back(instance);
1284  }
1285 
1286  // Set up the vector of devices subject to the jacobian test.
1287  if (instance->getName() == devOptions_.testJacDeviceName)
1288  {
1289  testJacDevicePtrVec_.push_back(instance);
1290  }
1291 
1292  return instance;
1293 }
1294 
1295 //-----------------------------------------------------------------------------
1296 // Function : DeviceMgr::deleteDeviceInstance
1297 // Purpose :
1298 // Special Notes :
1299 // Scope : public
1300 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1301 // Creation Date : 3/08/01
1302 //-----------------------------------------------------------------------------
1303 bool DeviceMgr::deleteDeviceInstance(const std::string & name)
1304 {
1305  Report::DevelFatal().in("DeviceMgr::deleteDeviceInstance")
1306  << "Not ready with the new boilerplate-free device package";
1307 
1308  bool bsuccess = true;
1309 
1310  // bool tmpBool = true;
1311  // EntityTypeId type = getModelGroup(name);
1312 
1313  // DeviceMap::iterator it = deviceMap_.find(type);
1314  // if (it != deviceMap_.end())
1315  // {
1316  // // bsuccess &= (*it).second->deleteInstance(name);
1317  // DeviceEntity *entity = (*it).second->findEntity(name);
1318  // DeviceInstance *instance = dynamic_cast<DeviceInstance *>(entity);
1319  // if (instance)
1320  // bsuccess = (*it).second->deleteInstance(instance);
1321  // }
1322 
1323  // note as this is written it ignores lots of other containers
1324  // this may be used for clean up at the end of a run, but
1325  // it is not sufficient to use during simulation setup.
1326  //
1327  // need to remove pointer to the instance "name" from other arrays
1328  // candidate lists are:
1329  // InstanceVector instancePtrVec_;
1330  // InstanceVector bpInstancePtrVec_; // instances with breakpoints functions
1331  // InstanceVector pdeInstancePtrVec_;
1332  // InstanceVector nonPdeInstancePtrVec_;
1333  // InstanceVector mosfetInstancePtrVec_;
1334  // InstanceVector vsrcInstancePtrVec_;
1335  // InstanceVector bjtInstancePtrVec_;
1336  // std::map<std::string, VsrcInstance*> vsrcInstancePtrMap_;
1337  //
1338  // InstanceVector plotFileInstancePtrVec_;
1339  //
1340  // std::map<std::string,SourceInstance*> independentSourceMap_;
1341  // IndependentSourceVector independentSourceVector_;
1342 
1343  return bsuccess;
1344 }
1345 
1346 //-----------------------------------------------------------------------------
1347 // Function : DeviceMgr::debugOutput1
1348 // Purpose :
1349 // Special Notes :
1350 // Scope : public
1351 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1352 // Creation Date : 1/29/07
1353 //-----------------------------------------------------------------------------
1355 {
1356  // dump the fvector and the jdxp vector to files.
1357  if (isActive(Diag::DEVICE_DUMP_VECTORS) && solState_.debugTimeFlag)
1358  {
1359  // To match the numbering scheme of the NLS debug output files,
1360  // it is neccessary to add +1 to the newton iterartion number.
1361  int outIter = solState_.newtonIter + 1;
1362 
1363  // f-vector
1364  char fn_fv[256]; for (int ich = 0; ich < 256; ++ich) fn_fv[ich] = 0;
1365  sprintf(fn_fv, "fvector.%03d.txt", outIter);
1366 
1367  // Note: this needs to change sign to match Spice.
1368  (externData_.fVectorPtr)->scale(-1.0);
1369  (externData_.fVectorPtr)->writeToFile(fn_fv);
1370  (externData_.fVectorPtr)->scale(-1.0);
1371 
1372  // jdxp-vector
1373  char fn_jdxp[256]; for (int ich = 0; ich < 256; ++ich) fn_jdxp[ich] = 0;
1374  sprintf(fn_jdxp, "Jdxp.%03d.txt", outIter);
1375  (externData_.JdxpVectorPtr)->writeToFile(fn_jdxp);
1376 
1377  if (DEBUG_VOLTLIM)
1378  {
1379  // the voltlim dx vector.
1380  char fn_dxvl[256]; for (int ich = 0; ich < 256; ++ich) fn_dxvl[ich] = 0;
1381  sprintf(fn_dxvl, "dxVL.%03d.txt", outIter);
1382  (externData_.dxVoltlimVectorPtr)->writeToFile(fn_dxvl);
1383 
1384  // jdx2-vector
1385  char fn_jdx2[256]; for (int ich = 0; ich < 256; ++ich) fn_jdx2[ich] = 0;
1386  sprintf(fn_jdx2, "Jdx2.%03d.txt", outIter);
1387  (externData_.Jdx2VectorPtr)->writeToFile(fn_jdx2);
1388  }
1389  }
1390 }
1391 
1392 //-----------------------------------------------------------------------------
1393 // Function : DeviceMgr::debugOutput2
1394 // Purpose : new-dae version
1395 // Special Notes :
1396 // Scope : public
1397 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1398 // Creation Date : 10/19/08
1399 //-----------------------------------------------------------------------------
1401 {
1402  // dump the fvector and the jdxp vector to files.
1403  if (isActive(Diag::DEVICE_DUMP_VECTORS) && solState_.debugTimeFlag)
1404  {
1405  // To match the numbering scheme of the NLS debug output files,
1406  // it is neccessary to add +1 to the newton iterartion number.
1407  int newtonIter = solState_.newtonIter + 1;
1408  int outputStepNumber = 0;
1409 
1410  if (solState_.tranopFlag)
1411  {
1412  outputStepNumber = 0;
1413  }
1414  else if (solState_.initTranFlag)
1415  {
1416  outputStepNumber = solState_.timeStepNumber+1;
1417  }
1418  else
1419  {
1420  outputStepNumber = solState_.timeStepNumber+1;
1421  }
1422 
1423  if (DEBUG_VOLTLIM)
1424  {
1425  // the voltlim dx vector.
1426  char fn_dxvl[256]; for (int ich = 0; ich < 256; ++ich) fn_dxvl[ich] = 0;
1427  sprintf(fn_dxvl, "dxVL.%03d.%03d.txt", outputStepNumber, newtonIter);
1428  (externData_.dxVoltlimVectorPtr)->writeToFile(fn_dxvl);
1429 
1430  // Fdx2-vector
1431  char fn_fdx2[256]; for (int ich = 0; ich < 256; ++ich) fn_fdx2[ich] = 0;
1432  sprintf(fn_fdx2, "Fdx2.%03d.%03d.txt", outputStepNumber, newtonIter);
1433  (externData_.Fdx2VectorPtr)->writeToFile(fn_fdx2);
1434 
1435  // Qdx2-vector
1436  char fn_qdx2[256]; for (int ich = 0; ich < 256; ++ich) fn_qdx2[ich] = 0;
1437  sprintf(fn_qdx2, "Qdx2.%03d.%03d.txt", outputStepNumber, newtonIter);
1438  (externData_.Qdx2VectorPtr)->writeToFile(fn_qdx2);
1439  }
1440  }
1441 }
1442 
1443 //-----------------------------------------------------------------------------
1444 // Function : DeviceMgr::setInitialGuess
1445 // Purpose : This is a function call that sets the initial guess for
1446 // devices that have initial guesses.
1447 //
1448 // Special Notes :
1449 //
1450 // Scope : public
1451 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1452 // Creation Date : 5/02/03
1453 //-----------------------------------------------------------------------------
1454 bool DeviceMgr::setInitialGuess (Linear::Vector * solVectorPtr)
1455 {
1456  bool bsuccess = true;
1457 
1458  if (solVectorPtr != 0)
1459  {
1460  externData_.nextSolVectorPtr = solVectorPtr;
1461 
1462  // if two-level, and just the inner problem, only load the PDE devices.
1463  InstanceVector::iterator iter;
1464  InstanceVector::iterator begin;
1465  InstanceVector::iterator end;
1466  begin = instancePtrVec_.begin ();
1467  end = instancePtrVec_.end ();
1468  for (iter=begin; iter!=end;++iter)
1469  {
1470  bool tmpBool = (*iter)->setInitialGuess ();
1471  bsuccess = bsuccess && tmpBool;
1472  }
1473  }
1474 
1475  return bsuccess;
1476 }
1477 
1478 //-----------------------------------------------------------------------------
1479 // Function : DeviceMgr::analyticSensitivitiesAvailable
1480 // Purpose :
1481 // Special Notes : Includes a reduce, so works in parallel.
1482 // Scope : public
1483 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1484 // Creation Date : 5/30/2014
1485 //-----------------------------------------------------------------------------
1486 bool DeviceMgr::analyticSensitivitiesAvailable(const std::string & name)
1487 {
1488  // This assumes that the only available analytic sensitivities are for
1489  // non-artificial parameters.
1490  DeviceEntity * device_entity = getDeviceEntity(name);
1491 
1492  int available = 0;
1493  if (device_entity)
1494  {
1495  std::string paramName = Util::paramNameFromFullParamName(name);
1496  available = device_entity->analyticSensitivityAvailable(paramName);
1497  }
1498 
1499  Parallel::AllReduce(comm_, MPI_LOR, &available, 1);
1500 
1501  return static_cast<bool>(available);
1502 }
1503 
1504 //-----------------------------------------------------------------------------
1505 // Function : DeviceMgr::getAnalyticSensitivities
1506 // Purpose :
1507 // Special Notes :
1508 // Scope : public
1509 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1510 // Creation Date : 05/30/2014
1511 //-----------------------------------------------------------------------------
1513  (std::string & name,
1514  std::vector<double> & dfdpVec,
1515  std::vector<double> & dqdpVec,
1516  std::vector<double> & dbdpVec,
1517  std::vector<int> & FindicesVec,
1518  std::vector<int> & QindicesVec,
1519  std::vector<int> & BindicesVec)
1520 {
1521  // If not artificial, then search for the appropriate natural param(s).
1522  DeviceEntity * device_entity = getDeviceEntity(name);
1523 
1524  if (device_entity)
1525  {
1526  std::string paramName = Util::paramNameFromFullParamName(name);
1527  bool found = device_entity->getAnalyticSensitivity(paramName,
1528  dfdpVec, dqdpVec, dbdpVec,
1529  FindicesVec, QindicesVec, BindicesVec);
1530  }
1531 }
1532 
1533 //-----------------------------------------------------------------------------
1534 // Function : DeviceMgr::setParam
1535 //
1536 // Purpose : This function sets named parameters (name) to a
1537 // specified value (val).
1538 //
1539 // Special Notes : Used for continuation calculations, as well as possibly
1540 // intrusive sensitivity/optimization calculations. It is
1541 // assumed that this is called after everything (devices,
1542 // solvers, etc.) is set up.
1543 //
1544 // The specified parameter can be either a natural or
1545 // artificial parameter.
1546 //
1547 //
1548 // Scope : public
1549 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1550 // Creation Date : 5/02/03
1551 //-----------------------------------------------------------------------------
1552 bool DeviceMgr::setParam(std::string & name, double val, bool overrideOriginal)
1553 {
1554  bool bsuccess = true, success = true;
1555 
1556  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1557  {
1558  std::string netListFile("");
1559  if (commandLine_.getArgumentValue(std::string("netlist")) != "")
1560  {
1561  netListFile = commandLine_.getArgumentValue(std::string("netlist"));
1562  }
1563 
1564  dout() << netListFile << "\t\t";
1565  dout() << "DeviceMgr::setParam. ";
1566  dout() << name;
1567  dout() << " " << val;
1568  dout() << std::endl;
1569  }
1570 
1571  ArtificialParameterMap::iterator artificial_param_it = artificialParameterMap_.find(name);
1572  if (artificial_param_it != artificialParameterMap_.end())
1573  {
1574  (*artificial_param_it).second->setValue(*this, val);
1575  }
1576  else
1577  {
1578  GlobalParameterMap::iterator global_param_it = globals_.global_params.find(name);
1579  if (global_param_it != globals_.global_params.end())
1580  {
1581  if ((*global_param_it).second != val)
1582  {
1583  (*global_param_it).second = val;
1584  for (EntityVector::iterator it = dependentPtrVec_.begin(), end = dependentPtrVec_.end(); it != end; ++it)
1585  {
1586  if ((*it)->updateGlobalParameters(globals_.global_params))
1587  {
1588  (*it)->processParams();
1589  (*it)->processInstanceParams();
1590  }
1591  }
1592  }
1593  }
1594  else
1595  {
1596  if (DEBUG_DEVICE)
1597  {
1598  Xyce::dout() << " in DeviceMgr setParam, with name " << name << std::endl;
1599  }
1600  // If not artificial, then search for the appropriate natural param(s).
1601  DeviceEntity * device_entity = getDeviceEntity(name);
1602 
1603  int entityFound = (device_entity != 0);
1604  if (entityFound)
1605  {
1606  bool found;
1607  std::string paramName = Util::paramNameFromFullParamName(name);
1608  if (paramName == "")
1609  {
1610  if (DEBUG_DEVICE)
1611  {
1612  Xyce::dout() << " in DeviceMgr setParam, setting default parameter to " << val ;
1613  if (overrideOriginal)
1614  Xyce::dout() << " overriding original";
1615  Xyce::dout() << std::endl;
1616  }
1617  found = device_entity->setDefaultParam(val, overrideOriginal);
1618  }
1619  else
1620  {
1621  if (DEBUG_DEVICE)
1622  {
1623  Xyce::dout() << " in DeviceMgr setParam, setting parameter "<< paramName << " to " << val << std::endl;
1624  }
1625  found = device_entity->setParam(paramName, val);
1626  }
1627 
1628  if (found)
1629  {
1630  device_entity->processParams (); // if this "entity" is a model, then need to
1631  // also do a "processParams" on the related instances.
1632  device_entity->processInstanceParams();
1633  }
1634 
1635  entityFound = found;
1636  }
1637 
1638  Parallel::AllReduce(comm_, MPI_LOR, &entityFound, 1);
1639 
1640  if (entityFound == 0)
1641  {
1642  if (DEBUG_DEVICE)
1643  {
1644  Report::DevelWarning() << "DeviceMgr::setParam. Unable to find parameter " << name;
1645  }
1646  else
1647  {
1648  Report::UserError() << "Unable to find parameter " << name;
1649  }
1650  }
1651  }
1652  }
1653 
1654  // Certain parameters should be passed through to the inner solve,
1655  // if there is an inner circuit problem. The names of parameters
1656  // that should be passed through are stored in the map.
1657  if (passThroughParamsMap_.find(name) != passThroughParamsMap_.end())
1658  {
1659  ModelTypeInstanceVectorMap::const_iterator model_type_it = modelTypeInstanceVector_.find(ExternDevice::Traits::modelType());
1660  if (model_type_it != modelTypeInstanceVector_.end())
1661  {
1662  for (InstanceVector::const_iterator it = (*model_type_it).second.begin(); it != (*model_type_it).second.end(); ++it)
1663  {
1664  ExternDevice::Instance &extern_device = static_cast<ExternDevice::Instance &>(*(*it));
1665 
1666  bool bs1 = extern_device.setInternalParam(name, val);
1667  }
1668  }
1669  }
1670 
1671  return bsuccess;
1672 }
1673 
1674 //-----------------------------------------------------------------------------
1675 // Function : DeviceMgr::getParam
1676 // Purpose : Returns the current value of a named parameter.
1677 //
1678 // Special Notes : This works in parallel.
1679 //
1680 // If the parameter is not found, this function sets val to
1681 // 0.0, and returns a "false" boolean. It does not invoke the
1682 // error handler.
1683 //
1684 // Scope : public
1685 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1686 // Creation Date : 9/13/04
1687 //-----------------------------------------------------------------------------
1688 bool
1690  const std::string & name,
1691  double & value) const
1692 {
1693  value = 0.0;
1694  bool entityFound = false;
1695 
1696  ArtificialParameterMap::const_iterator artificial_param_it = artificialParameterMap_.find(name);
1697  if (artificial_param_it != artificialParameterMap_.end())
1698  {
1699  value = (*artificial_param_it).second->getValue(*this);
1700  entityFound = true;
1701  }
1702  else
1703  {
1704  GlobalParameterMap::const_iterator global_param_it = globals_.global_params.find(name);
1705  if (global_param_it != globals_.global_params.end())
1706  {
1707  value = (*global_param_it).second;
1708  entityFound = true;
1709  }
1710  else
1711  {
1712  const DeviceEntity *device_entity = getDeviceEntity(name);
1713  entityFound = device_entity != 0;
1714 
1715  if (entityFound)
1716  {
1717  std::string paramName = Util::paramNameFromFullParamName(name);
1718  entityFound = device_entity->getParam(paramName, value);
1719  if (paramName == "")
1720  entityFound = true;
1721  }
1722 
1723  if (!entityFound)
1724  entityFound = measureManager_->getMeasureValue(name, value);
1725  }
1726  }
1727 
1728  return entityFound;
1729 }
1730 
1731 //-----------------------------------------------------------------------------
1732 // Function : DeviceMgr::findParam
1733 // Purpose : Returns the current value of a named parameter.
1734 // Special Notes :
1735 // Scope : public
1736 // Creator :
1737 // Creation Date :
1738 //-----------------------------------------------------------------------------
1739 bool DeviceMgr::findParam(const std::string & name) const
1740 {
1741  double value = 0.0;
1742  return getParam(name, value);
1743 }
1744 
1745 //-----------------------------------------------------------------------------
1746 // Function : DeviceMgr::getParamNoReduce
1747 // Purpose : Returns the current value of a named parameter.
1748 // Special Notes :
1749 // Scope : public
1750 // Creator :
1751 // Creation Date :
1752 //-----------------------------------------------------------------------------
1753 double DeviceMgr::getParamNoReduce(const std::string & name) const
1754 {
1755  double value = 0.0;
1756  return getParam(name, value);
1757 }
1758 
1759 //-----------------------------------------------------------------------------
1760 // Function : DeviceMgr::getParam
1761 // Purpose : Returns the current value of a named parameter.
1762 //
1763 // Special Notes : This works in parallel.
1764 //
1765 // Scope : public
1766 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1767 // Creation Date : 7/26/03
1768 //-----------------------------------------------------------------------------
1769 bool DeviceMgr::getParamAndReduce(const std::string & name, double & value) const
1770 {
1771  bool found = getParam(name, value);
1772  int found_count = found ? 1 : 0;
1773  Parallel::AllReduce(comm_, MPI_SUM, &found_count, 1);
1774 
1775  if (found_count)
1776  {
1777  Parallel::AllReduce(comm_, MPI_SUM, &value, 1);
1778  value /= found_count;
1779  }
1780 
1781  return found_count != 0;
1782 }
1783 
1784 //-----------------------------------------------------------------------------
1785 // Function : DeviceMgr::getParamAndReduce
1786 // Purpose : Returns the current value of a named parameter.
1787 // Special Notes :
1788 // Scope : public
1789 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1790 // Creation Date : 7/26/03
1791 //-----------------------------------------------------------------------------
1792 double DeviceMgr::getParamAndReduce(const std::string & name) const
1793 {
1794  double value = 0.0;
1795  bool found = getParamAndReduce(name, value);
1796 
1797  if (!found)
1798  {
1799  if (DEBUG_DEVICE)
1800  {
1801  Report::DevelWarning() <<
1802  "DeviceMgr::getParamAndReduce. Unable to find parameter " << name;
1803  }
1804  else
1805  {
1806  Report::UserError() << "Unable to find parameter " << name;
1807  }
1808  }
1809 
1810  return value;
1811 }
1812 
1813 //-----------------------------------------------------------------------------
1814 // Function : DeviceMgr::updateState
1815 // Purpose : This should be called prior to loadDAEVectors.
1816 // Special Notes :
1817 // Scope : public
1818 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1819 // Creation Date : 11/17/05
1820 //-----------------------------------------------------------------------------
1821 bool
1823  Linear::Vector * nextSolVectorPtr,
1824  Linear::Vector * currSolVectorPtr,
1825  Linear::Vector * lastSolVectorPtr,
1826  Linear::Vector * nextStaVectorPtr,
1827  Linear::Vector * currStaVectorPtr,
1828  Linear::Vector * lastStaVectorPtr,
1829  Linear::Vector * nextStoVectorPtr,
1830  Linear::Vector * currStoVectorPtr,
1831  Linear::Vector * lastStoVectorPtr)
1832 {
1833  bool bsuccess = true;
1834  bool tmpBool = true;
1835 
1837  bsuccess = bsuccess && tmpBool;
1838 
1839  // copy over the passed pointers:
1840  externData_.nextSolVectorPtr = nextSolVectorPtr;
1841  externData_.currSolVectorPtr = currSolVectorPtr;
1842  externData_.lastSolVectorPtr = lastSolVectorPtr;
1843  externData_.nextStaVectorPtr = nextStaVectorPtr;
1844  externData_.currStaVectorPtr = currStaVectorPtr;
1845  externData_.lastStaVectorPtr = lastStaVectorPtr;
1846  externData_.nextStoVectorPtr = nextStoVectorPtr;
1847  externData_.currStoVectorPtr = currStoVectorPtr;
1848  externData_.lastStoVectorPtr = lastStoVectorPtr;
1849 
1850 #ifdef Xyce_PARALLEL_MPI
1851  externData_.nextSolVectorPtr->importOverlap();
1852 #endif
1853 
1854  // Now reset the relevant RAW pointers:
1864 
1866 
1867  // if inner problem, only do the PDE loads.
1869  {
1870  // call all the intermediate vars loads:
1871  for (DeviceVector::iterator iter = pdeDevicePtrVec_.begin(), end = pdeDevicePtrVec_.end(); iter != end; ++iter)
1872  {
1874  bsuccess = bsuccess && tmpBool;
1875  }
1876  }
1877  else
1878  {
1879  for (DeviceVector::iterator iter = devicePtrVec_.begin(), end = devicePtrVec_.end(); iter != end; ++iter)
1880  {
1882  }
1883  }
1884 
1886 
1887 #ifdef Xyce_PARALLEL_MPI
1888  externData_.nextStaVectorPtr->importOverlap();
1889  externData_.nextStoVectorPtr->importOverlap();
1890 #endif
1891 
1892  Report::safeBarrier(comm_);
1893 
1894  return true;
1895 }
1896 
1897 
1898 //-----------------------------------------------------------------------------
1899 // Function : DeviceMgr::loadDAEMatrices
1900 // Purpose : This function loads the various DAE related matrices to
1901 // set up the following expression:
1902 //
1903 // residual: f(x) = dQ/dt + F(x) - B(t) = 0
1904 //
1905 // jacobian: J(x) = d(dQ/dt)dx + dFdx
1906 // = d(dQdx)dt + dFdx
1907 //
1908 // Special Notes : ERK. This function is only called if using the new
1909 // (new-DAE) integrator. As such, it is also used for
1910 // MPDE. It is not used for the old (ODE) integrator.
1911 // The corresponding function for the old integrator
1912 // is loadJacobianMatrix
1913 //
1914 // Note that this function, unlike the loadJacobianMatrix
1915 // function *requires* that vector/matrix pointers
1916 // be passed in to the function. When
1917 // running in new-DAE or MPDE, we can't rely (much) on
1918 // registered vectors. (set up in initializeAll). In
1919 // particular, MPDE cycles through different vector and
1920 // matrix blocks, which each correspond to different
1921 // "fast" time points, and for each block the state
1922 // information is different.
1923 //
1924 // NOTE: This function assumes that all the load matrices
1925 // are zeroed out. That is, dFdx, dQdx are all zeros.
1926 //
1927 // If that isn't true, then this function will not produce
1928 // the correct answer. The reason for doing this
1929 // is MPDE. For the warped case, the entire linear system
1930 // needs to be zeroed out, but the full system includes
1931 // phase equations that never get passed in here.
1932 // That zeroing now happens upstream from here, in either
1933 // the MPDE loader or the time integrator.
1934 //
1935 // Scope : public
1936 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1937 // Creation Date : 03/03/04
1938 //-----------------------------------------------------------------------------
1940  (Linear::Vector * tmpSolVectorPtr,
1941  Linear::Vector * tmpStateVectorPtr,
1942  Linear::Vector * tmpStateDerivVectorPtr,
1943  Linear::Vector * tmpStoreVectorPtr,
1944  Linear::Matrix * tmpdQdxMatrixPtr,
1945  Linear::Matrix * tmpdFdxMatrixPtr)
1946 {
1947  bool bsuccess = true;
1948  bool tmpBool = true;
1949 
1950  // copy over the passed pointers:
1951  (externData_.nextSolVectorPtr) = tmpSolVectorPtr;
1952  bool resetRawMatrixPointers = true;
1953  if (
1954  (externData_.dQdxMatrixPtr == tmpdQdxMatrixPtr) &&
1955  (externData_.dFdxMatrixPtr == tmpdFdxMatrixPtr)
1956  )
1957  {
1958  resetRawMatrixPointers = false;
1959  }
1960  if (resetRawMatrixPointers)
1961  {
1962  externData_.dQdxMatrixPtr = tmpdQdxMatrixPtr;
1963  externData_.dFdxMatrixPtr = tmpdFdxMatrixPtr;
1964  }
1965 
1966  externData_.nextStaVectorPtr = tmpStateVectorPtr;
1967  externData_.nextStaDerivVectorPtr = tmpStateDerivVectorPtr;
1968  externData_.nextStoVectorPtr = tmpStoreVectorPtr;
1969 
1970  // setup the relevant RAW vector pointers:
1971  externData_.nextSolVectorRawPtr = &((*externData_.nextSolVectorPtr)[0]);
1972  externData_.nextStaVectorRawPtr = &((*externData_.nextStaVectorPtr)[0]);
1973  externData_.nextStaDerivVectorRawPtr = &((*externData_.nextStaDerivVectorPtr)[0]);
1974  externData_.nextStoVectorRawPtr = &((*externData_.nextStoVectorPtr)[0]);
1975 
1976  // setup the relevant RAW matrix pointers (down in the devices that need them):
1977  if (resetRawMatrixPointers || solState_.blockAnalysisFlag)
1978  {
1979  setupRawMatrixPointers_();
1980  }
1981 
1982  // if this is an "inner problem" phase of a Two-Level Newton
1983  // simulation, then only load the PDE devices. Everything else just
1984  // gets "1" on the diagonal.
1985  //
1986  // Note, it is possible to just load 1's using a petra call, so I may
1987  // get rid of the "trivial" matrix stamp stuff soon.
1988 
1989  if (solState_.twoLevelNewtonCouplingMode == Nonlinear::INNER_PROBLEM)
1990  {
1991  for (InstanceVector::iterator iter = nonPdeInstancePtrVec_.begin(), end = nonPdeInstancePtrVec_.end(); iter!=end; ++iter)
1992  {
1993  (*iter)->loadTrivialDAE_FMatrixStamp ();
1994  }
1995 
1996  for (InstanceVector::iterator iter = pdeInstancePtrVec_.begin(), end = pdeInstancePtrVec_.end(); iter!=end; ++iter)
1997  {
1998  tmpBool = (*iter)->loadDAEdQdx();bsuccess = bsuccess && tmpBool;
1999  tmpBool = (*iter)->loadDAEdFdx();bsuccess = bsuccess && tmpBool;
2000  }
2001  }
2002  // Else, do a normal analytical matrix load.
2003  else
2004  {
2005  for (DeviceVector::iterator it = devicePtrVec_.begin(), end = devicePtrVec_.end(); it != end; ++it)
2006  {
2007  bsuccess = (*it)->loadDAEMatrices(*externData_.dFdxMatrixPtr , *externData_.dQdxMatrixPtr);
2008  }
2009  }
2010 
2011  // Run jacobian diagnostic.
2012  if (devOptions_.testJacobianFlag &&
2013  (solState_.timeStepNumber >= devOptions_.testJacStartStep &&
2014  solState_.timeStepNumber <= devOptions_.testJacStopStep))
2015  {
2016  // Test just the specified device(s), if the user specified any.
2017  if ((devOptions_.testJacDeviceNameGiven))
2018  {
2019  for (InstanceVector::iterator iter = testJacDevicePtrVec_.begin(), end = testJacDevicePtrVec_.end(); iter != end; ++iter)
2020  {
2021  (*iter)->testDAEMatrices(topology_.getSolutionNodeNames());
2022  }
2023  }
2024  else // Test all the devices:
2025  {
2026  for (InstanceVector::iterator iter = instancePtrVec_.begin(), end = instancePtrVec_.end(); iter != end; ++iter)
2027  {
2028  (*iter)->testDAEMatrices(topology_.getSolutionNodeNames());
2029  }
2030  }
2031  }
2032 
2033  //Tell Jacobian, fill is complete allowing accumulation if necessary
2034  externData_.dQdxMatrixPtr->fillComplete();
2035  externData_.dFdxMatrixPtr->fillComplete();
2036 
2037  Report::safeBarrier(comm_);
2038 
2039  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PRINT_VECTORS) && solState_.debugTimeFlag)
2040  {
2041  int newtonIter = solState_.newtonIter;
2042  dout() << section_divider << std::endl;
2043  dout() << "Q-matrix: nonlinear iteration = " << newtonIter << "\n";
2044  externData_.dQdxMatrixPtr->printPetraObject(dout());
2045  dout() << std::endl;
2046  dout() << section_divider << std::endl;
2047  dout() << "F-matrix: nonlinear iteration = " << newtonIter << "\n";
2048  externData_.dFdxMatrixPtr->printPetraObject(dout());
2049  dout() << std::endl;
2050  dout() << section_divider << std::endl;
2051  }
2052 
2053  return bsuccess;
2054 }
2055 
2056 //-----------------------------------------------------------------------------
2057 // Function : DeviceMgr::loadDAEVectors
2058 // Purpose : This function loads the various DAE related vectors to
2059 // set up the following expression:
2060 //
2061 // f(x) = dQ/dt + F(x) - B(t) = 0
2062 //
2063 // Special Notes : ERK. This function is only called if using the new
2064 // (new-DAE) integrator. As such, it is also used for
2065 // MPDE. It is not used for the old (ODE) integrator.
2066 // The corresponding function for the old integrator
2067 // is loadRHSVector.
2068 //
2069 // Note that this function, unlike the loadRHSVector
2070 // function *requires* that vectors be passed in. When
2071 // running in new-DAE or MPDE, we can't rely (much) on
2072 // registered vectors. (set up in initializeAll). In
2073 // particular, MPDE cycles through different vector and
2074 // matrix blocks, which each correspond to different
2075 // "fast" time points, and for each block the state
2076 // information is different.
2077 //
2078 // NOTE: This function assumes that all the load vectors
2079 // are zeroed out. That is, F, Q, B, dFdxdVp and dQdxVp
2080 // are all zeros.
2081 //
2082 // If that isn't true, then this function will not produce
2083 // the correct answer. The reason for doing this
2084 // is MPDE. For the warped case, the entire linear system
2085 // needs to be zeroed out, but the full system includes
2086 // phase equations that never get passed in here.
2087 //
2088 // That zeroing now happens upstream from here, in either
2089 // the MPDE loader or the time integrator.
2090 //
2091 // Scope : public
2092 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
2093 // Creation Date : 01/26/03
2094 //-----------------------------------------------------------------------------
2096  (Linear::Vector * tmpSolVectorPtr,
2097  Linear::Vector * tmpCurrSolVectorPtr,
2098  Linear::Vector * tmpLastSolVectorPtr,
2099  Linear::Vector * tmpStaVectorPtr,
2100  Linear::Vector * tmpCurrStaVectorPtr,
2101  Linear::Vector * tmpLastStaVectorPtr,
2102  Linear::Vector * tmpStaDerivVectorPtr,
2103  Linear::Vector * tmpStoVectorPtr,
2104  Linear::Vector * tmpCurrStoVectorPtr,
2105  Linear::Vector * tmpLastStoVectorPtr,
2106  Linear::Vector * tmpStoLeadCurrQCompVectorPtr,
2107  Linear::Vector * tmpLeadFCompVectorPtr,
2108  Linear::Vector * tmpCurLeadFCompVectorPtr,
2109  Linear::Vector * tmpLastLeadFCompVectorPtr,
2110  Linear::Vector * tmpLeadQCompVectorPtr,
2111  Linear::Vector * tmpJunctionVCompVectorPtr,
2112  Linear::Vector * tmpCurrJunctionVCompVectorPtr,
2113  Linear::Vector * tmpLastJunctionCompVectorPtr,
2114  Linear::Vector * tmpQVectorPtr,
2115  Linear::Vector * tmpFVectorPtr,
2116  Linear::Vector * tmpBVectorPtr,
2117  Linear::Vector * tmpdFdxdVpVectorPtr,
2118  Linear::Vector * tmpdQdxdVpVectorPtr)
2119 {
2120  bool bsuccess = true;
2121  bool tmpBool = true;
2122 
2123  // copy over the passed pointers:
2124  externData_.nextSolVectorPtr = tmpSolVectorPtr;
2125  externData_.currSolVectorPtr = tmpCurrSolVectorPtr;
2126  externData_.lastSolVectorPtr = tmpLastSolVectorPtr;
2127  externData_.daeQVectorPtr = tmpQVectorPtr;
2128  externData_.daeFVectorPtr = tmpFVectorPtr;
2129  externData_.daeBVectorPtr = tmpBVectorPtr;
2130  externData_.dFdxdVpVectorPtr = tmpdFdxdVpVectorPtr;
2131  externData_.dQdxdVpVectorPtr = tmpdQdxdVpVectorPtr;
2132  externData_.nextStaVectorPtr = tmpStaVectorPtr;
2133  externData_.currStaVectorPtr = tmpCurrStaVectorPtr;
2134  externData_.lastStaVectorPtr = tmpLastStaVectorPtr;
2135  externData_.storeLeadCurrQCompPtr = tmpStoLeadCurrQCompVectorPtr;
2136  externData_.nextStaDerivVectorPtr = tmpStaDerivVectorPtr;
2137  externData_.nextStoVectorPtr = tmpStoVectorPtr;
2138  externData_.currStoVectorPtr = tmpCurrStoVectorPtr;
2139  externData_.lastStoVectorPtr = tmpLastStoVectorPtr;
2140  externData_.nextLeadCurrFCompPtr = tmpLeadFCompVectorPtr;
2141  externData_.currLeadCurrFCompPtr = tmpCurLeadFCompVectorPtr;
2142  externData_.lastLeadCurrFCompPtr= tmpLastLeadFCompVectorPtr;
2143  externData_.nextLeadCurrQCompPtr = tmpLeadQCompVectorPtr;
2144  externData_.nextJunctionVCompPtr = tmpJunctionVCompVectorPtr;
2145  externData_.currJunctionVCompPtr = tmpCurrJunctionVCompVectorPtr;
2146  externData_.lastJunctionVCompPtr = tmpLastJunctionCompVectorPtr;
2147 
2148 
2149  // Make sure all boundary data is valid in the solution vector
2150 #ifdef Xyce_PARALLEL_MPI
2151  externData_.nextSolVectorPtr->importOverlap();
2152  externData_.nextStaDerivVectorPtr->importOverlap();
2153 #endif
2154 
2155  // Set up the relevant RAW Pointers:
2156  setupRawVectorPointers_ ();
2157 
2158  // call all the intermediate vars loads:
2159  std::vector<Device*>::iterator iter;
2160  std::vector<Device*>::iterator begin;
2161  std::vector<Device*>::iterator end;
2162 
2163  // if inner problem, only do the PDE loads.
2164  if (solState_.twoLevelNewtonCouplingMode == Nonlinear::INNER_PROBLEM)
2165  {
2166  begin = pdeDevicePtrVec_.begin ();
2167  end = pdeDevicePtrVec_.end ();
2168  }
2169  else
2170  {
2171  begin = devicePtrVec_.begin ();
2172  end = devicePtrVec_.end ();
2173  }
2174 
2175 #ifndef Xyce_EXCLUDE_SECONDARY_STATE
2176  for (iter=begin; iter!=end;++iter)
2177  {
2178  tmpBool = (*iter)->updateSecondaryState
2179  (externData_.nextStaDerivVectorRawPtr, externData_.nextStoVectorRawPtr);
2180  bsuccess = bsuccess && tmpBool;
2181  }
2182 #endif // Xyce_EXCLUDE_SECONDARY_STATE
2183 
2184 #ifdef Xyce_PARALLEL_MPI
2185  externData_.nextStaVectorPtr->importOverlap();
2186  externData_.nextStoVectorPtr->importOverlap();
2187 #endif
2188 
2189  if (solState_.twoLevelNewtonCouplingMode == Nonlinear::INNER_PROBLEM)
2190  {
2191  int numDevices = pdeDevicePtrVec_.size();
2192  for(int i=0; i< numDevices; ++i)
2193  {
2194  bsuccess=pdeDevicePtrVec_.at(i)->loadDAEVectors(externData_.nextSolVectorRawPtr,
2195  externData_.daeFVectorRawPtr,
2196  externData_.daeQVectorRawPtr,
2197  externData_.daeBVectorRawPtr,
2198  externData_.nextStoVectorRawPtr,
2199  externData_.storeLeadCurrQCompRawPtr,
2200  externData_.nextLeadCurrFCompRawPtr,
2201  externData_.nextLeadCurrQCompRawPtr,
2202  externData_.nextJunctionVCompRawPtr);
2203 
2204  }
2205  }
2206  else
2207  {
2208  int numDevices = devicePtrVec_.size();
2209  for(int i=0; i< numDevices; ++i)
2210  {
2211  bsuccess=devicePtrVec_.at(i)->loadDAEVectors(externData_.nextSolVectorRawPtr,
2212  externData_.daeFVectorRawPtr,
2213  externData_.daeQVectorRawPtr,
2214  externData_.daeBVectorRawPtr,
2215  externData_.nextStoVectorRawPtr,
2216  externData_.storeLeadCurrQCompRawPtr,
2217  externData_.nextLeadCurrFCompRawPtr,
2218  externData_.nextLeadCurrQCompRawPtr,
2219  externData_.nextJunctionVCompRawPtr);
2220  }
2221  }
2222 
2223  // dump to the screen:
2224  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PRINT_VECTORS) && solState_.debugTimeFlag)
2225  {
2226  int newtonIter = solState_.newtonIter;
2227  dout() << "Q-vector: nonlinear iteration = " << newtonIter << "\n";
2228  externData_.daeQVectorPtr->printPetraObject(std::cout);
2229  dout() << std::endl;
2230  dout() << "F-vector: nonlinear iteration = " << newtonIter << "\n";
2231  externData_.daeFVectorPtr->printPetraObject(std::cout);
2232  dout() << std::endl;
2233 
2234  if (devOptions_.voltageLimiterFlag)
2235  {
2236  dout() << "\n\n dFdxdVp vector: nonlinear iteration = " << newtonIter << "\n";
2237  externData_.dFdxdVpVectorPtr->printPetraObject(std::cout);
2238  dout() << std::endl;
2239  dout() << "\n\n dQdxdVp vector: nonlinear iteration = " << newtonIter << "\n";
2240  externData_.dQdxdVpVectorPtr->printPetraObject(std::cout);
2241  dout() << std::endl;
2242  }
2243 
2244  debugOutput2();
2245  }
2246 
2247  // Update parallel if necessary
2248  externData_.daeQVectorPtr->fillComplete();
2249  externData_.daeFVectorPtr->fillComplete();
2250  externData_.daeBVectorPtr->fillComplete();
2251  externData_.dFdxdVpVectorPtr->fillComplete();
2252  externData_.dQdxdVpVectorPtr->fillComplete();
2253 
2254  Report::safeBarrier(comm_);
2255 
2256  return true;
2257 }
2258 
2259 //-----------------------------------------------------------------------------
2260 // Function : DeviceMgr::loadErrorWeightMask ()
2261 // Purpose : let devices set elements of a mask telling the time
2262 // integrator what equations should be ignored in taking
2263 // weighted norms for error control purposes.
2264 // Special Notes : Devices should *only* zero internal variables, and then
2265 // only those that absolutely should never be used to
2266 // control step size (e.g. excess phase variables in BJTs)
2267 // Scope : public
2268 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
2269 // Creation Date : 01/18/07
2270 //-----------------------------------------------------------------------------
2271 bool DeviceMgr::loadErrorWeightMask(Linear::Vector * deviceMask)
2272 {
2273  externData_.deviceErrorWeightMask_ = deviceMask;
2274 
2275  for (InstanceVector::const_iterator it = instancePtrVec_.begin(), end = instancePtrVec_.end(); it != end; ++it)
2276  {
2277  (*it)->loadErrorWeightMask();
2278  }
2279 
2280  externData_.deviceErrorWeightMask_->fillComplete();
2281 
2282  return true;
2283 }
2284 
2285 //-----------------------------------------------------------------------------
2286 // Function : DeviceMgr::addGlobalPar ()
2287 // Purpose :
2288 // Special Notes :
2289 // Scope : public
2290 // Creator : Dave Shirley, PSSI
2291 // Creation Date : 11/18/05
2292 //-----------------------------------------------------------------------------
2293 void DeviceMgr::addGlobalPar (const Util::Param & par)
2294 {
2295  if (par.getType() == Util::EXPR)
2296  {
2297  globals_.global_expressions.push_back(par.getValue<Util::Expression>());
2298  globals_.global_exp_names.push_back(par.uTag());
2299 
2300  Util::Expression &expression = globals_.global_expressions.back();
2301 
2302  std::vector<std::string> variables;
2303  expression.get_names(XEXP_VARIABLE, variables);
2304  std::vector<std::string> specials;
2305  expression.get_names(XEXP_SPECIAL, specials);
2306  if (!specials.empty())
2307  {
2308  expression.set_sim_time(solState_.currTime);
2309  }
2310 
2311  for (std::vector<std::string>::const_iterator it = variables.begin(),
2312  end = variables.end() ; it != end ; ++it)
2313  {
2314  expression.set_var(*it, globals_.global_params[*it]);
2315  }
2316 
2317  double val;
2318  expression.evaluateFunction(val);
2319  globals_.global_params[par.uTag()] = val;
2320  }
2321  else
2322  {
2323  globals_.global_params[par.uTag()] = par.getImmutableValue<double>();
2324  }
2325 }
2326 
2327 
2328 //-----------------------------------------------------------------------------
2329 // Function : DeviceMgr::getGlobalPar ()
2330 // Purpose :
2331 // Special Notes :
2332 // Scope : public
2333 // Creator : Rich Schie, SNL, Electrical Systems Modeling
2334 // Creation Date : 01/25/13
2335 //-----------------------------------------------------------------------------
2336 double DeviceMgr::getGlobalPar (const std::string & parName) const
2337 {
2338  double retVal = 0;
2339  GlobalParameterMap::const_iterator parLocItr = globals_.global_params.find(parName);
2340  if (parLocItr != globals_.global_params.end())
2341  {
2342  // extract the value for return
2343  retVal = parLocItr->second;
2344  }
2345  else
2346  {
2347  Report::UserError() << "Could not find global parameter \"" << parName << "\"";
2348  }
2349  return retVal;
2350 }
2351 
2352 //-----------------------------------------------------------------------------
2353 // Function : DeviceMgr::findGlobalPar
2354 // Purpose :
2355 // Special Notes :
2356 // Scope : public
2357 // Creator :
2358 // Creation Date :
2359 //-----------------------------------------------------------------------------
2360 const double *DeviceMgr::findGlobalPar (const std::string & parName) const
2361 {
2362  GlobalParameterMap::const_iterator it = globals_.global_params.find(parName);
2363  if (it != globals_.global_params.end())
2364  return &(*it).second;
2365 
2366  return 0;
2367 }
2368 
2369 //-----------------------------------------------------------------------------
2370 // Function : DeviceMgr::updateIntermediateVars_
2371 // Purpose : This function calls updateIntermediateVars
2372 // for the current devices.
2373 // Special Notes :
2374 // Scope : private
2375 // Creator : Rich Schiek, SNL, Parallel Computational Sciences
2376 // Creation Date : 12/14/2006
2377 //-----------------------------------------------------------------------------
2379 {
2380  bool bsuccess = true;
2381 
2382  InstanceVector::iterator iter;
2383  InstanceVector::iterator begin =instancePtrVec_.begin();
2384  InstanceVector::iterator end =instancePtrVec_.end();
2385  for (iter=begin; iter!=end;++iter)
2386  {
2387  (*iter)->updateIntermediateVars ();
2388  }
2389 
2390  return bsuccess;
2391 }
2392 
2393 //-----------------------------------------------------------------------------
2394 // Function : DeviceMgr::updatePrimaryState_
2395 // Purpose : This function updates primary states
2396 // for the present time step.
2397 // Special Notes :
2398 // Scope : private
2399 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
2400 // Creation Date : 6/21/00
2401 //-----------------------------------------------------------------------------
2403 {
2404  bool bsuccess = true;
2405 
2406  InstanceVector::iterator iter;
2407  InstanceVector::iterator begin =instancePtrVec_.begin();
2408  InstanceVector::iterator end =instancePtrVec_.end();
2409  for (iter=begin; iter!=end;++iter)
2410  {
2411  (*iter)->updatePrimaryState ();
2412  }
2413 
2414  return bsuccess;
2415 }
2416 
2417 //-----------------------------------------------------------------------------
2418 // Function : DeviceMgr::updateSecondaryState_
2419 // Purpose : This function function updates secondary states
2420 // for the present time step.
2421 // Special Notes :
2422 // Scope : private
2423 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
2424 // Creation Date : 6/21/00
2425 //-----------------------------------------------------------------------------
2427 {
2428  bool bsuccess = true;
2429 
2430  InstanceVector::iterator iter;
2431  InstanceVector::iterator begin =instancePtrVec_.begin();
2432  InstanceVector::iterator end =instancePtrVec_.end();
2433  for (iter=begin; iter!=end;++iter)
2434  {
2435  (*iter)->updateSecondaryState ();
2436  }
2437 
2438  return bsuccess;
2439 }
2440 
2441 //----------------------------------------------------------------------------
2442 // Function : DeviceMgr::updateDependentParameters_
2443 // Purpose : This function updates all dependent parameters for
2444 // the current time step.
2445 // Special Notes : This was evolved from updateTimeDependentParameters_
2446 // Scope : private
2447 // Creator : Dave Shirley
2448 // Creation Date : 08/17/06
2449 //----------------------------------------------------------------------------
2451 {
2452  bool bsuccess = true;
2453  Linear::Vector * solVectorPtr = externData_.nextSolVectorPtr;
2454 
2456  std::vector<Util::Expression> & ge = globals_.global_expressions;
2457 
2459  parameterChanged_ = true;
2460 
2461  // Update global params for new time and other global params
2462  int pos = 0;
2463  for (std::vector<Util::Expression>::iterator g_i = ge.begin(), g_end = ge.end();
2464  g_i != g_end; ++g_i)
2465  {
2466  bool changed = false;
2467  if (g_i->set_sim_time(solState_.currTime))
2468  changed = true;
2469 
2470  std::vector<std::string> variables;
2471  g_i->get_names(XEXP_VARIABLE, variables);
2472  for (std::vector<std::string>::iterator vs_i = variables.begin(), vs_end = variables.end();
2473  vs_i != vs_end; ++vs_i)
2474  {
2475  if (g_i->set_var(*vs_i, gp[*vs_i]))
2476  changed = true;
2477  }
2478 
2479  if (changed)
2480  {
2481  double val;
2482 
2483  parameterChanged_ = true;
2484  g_i->evaluateFunction(val);
2485  gp[globals_.global_exp_names[pos]] = val;
2486  }
2487  ++pos;
2488  }
2489 
2490  // do the models:
2491  if (firstDependent_)
2492  {
2493  firstDependent_ = false;
2494 
2495  dependentPtrVec_.clear();
2496 
2497  ModelVector::iterator iterM;
2498  ModelVector::iterator beginM =modelVector_.begin();
2499  ModelVector::iterator endM =modelVector_.end();
2500  for (iterM=beginM; iterM!=endM;++iterM)
2501  {
2502  if (!(*iterM)->getDependentParams().empty())
2503  {
2504  dependentPtrVec_.push_back(static_cast<DeviceEntity *>(*iterM));
2505  bool tmpBool = (*iterM)->updateGlobalParameters(gp);
2506  bsuccess = bsuccess && tmpBool;
2507  tmpBool = (*iterM)->updateDependentParameters (*solVectorPtr);
2508  bsuccess = bsuccess && tmpBool;
2509  (*iterM)->processParams();
2510  (*iterM)->processInstanceParams();
2511  }
2512  }
2513 
2514  // do the instances
2515  InstanceVector::iterator iter;
2516  InstanceVector::iterator begin =instancePtrVec_.begin();
2517  InstanceVector::iterator end =instancePtrVec_.end();
2518  for (iter=begin; iter!=end;++iter)
2519  {
2520  if (!(*iter)->getDependentParams().empty())
2521  {
2522  dependentPtrVec_.push_back(static_cast<DeviceEntity *>(*iter));
2523  bool tmpBool = (*iter)->updateGlobalParameters(gp);
2524  bsuccess = bsuccess && tmpBool;
2525  tmpBool = (*iter)->updateDependentParameters (*solVectorPtr);
2526  bsuccess = bsuccess && tmpBool;
2527  (*iter)->processParams();
2528  }
2529  }
2530  }
2531  else
2532  {
2533  EntityVector::iterator iter;
2534  EntityVector::iterator begin = dependentPtrVec_.begin();
2535  EntityVector::iterator end = dependentPtrVec_.end();
2536  for (iter=begin; iter!=end;++iter)
2537  {
2538  bool changed = false;
2539  if (parameterChanged_)
2540  {
2541  bool tmpBool = (*iter)->updateGlobalParameters(gp);
2542  changed = changed || tmpBool;
2543  bsuccess = bsuccess && tmpBool;
2544  }
2545  bool tmpBool = (*iter)->updateDependentParameters (*solVectorPtr);
2546  changed = changed || tmpBool;
2547  bsuccess = bsuccess && tmpBool;
2548  if (changed)
2549  {
2550  (*iter)->processParams();
2551  (*iter)->processInstanceParams();
2552  }
2553  }
2554  }
2556  parameterChanged_ = false;
2557 
2558  return bsuccess;
2559 }
2560 
2561 
2562 //-----------------------------------------------------------------------------
2563 // Function : DeviceMgr::loadBVectorsforAC
2564 // Purpose : This function loads the B-vector contributions for sources.
2565 // Special Notes :
2566 // Scope : public
2567 // Creator : Ting Mei, SNL
2568 // Creation Date :
2569 //-----------------------------------------------------------------------------
2570 bool DeviceMgr::loadBVectorsforAC(Linear::Vector * bVecRealPtr, Linear::Vector * bVecImagPtr)
2571 {
2572  bool bsuccess = true;
2573 
2574 // copy over the passed pointers:
2575  externData_.bVecRealPtr = bVecRealPtr;
2576  externData_.bVecImagPtr = bVecImagPtr;
2577 
2578 #ifdef Xyce_PARALLEL_MPI
2579  externData_.nextSolVectorPtr->importOverlap();
2580 #endif
2581 
2582  // Now reset the relevant RAW pointers:
2585 
2586  for (IndependentSourceVector::iterator it = independentSourceVector_.begin(), end = independentSourceVector_.end(); it != end; ++it)
2587  {
2588  (*it)->loadBVectorsforAC(externData_.bVecRealRawPtr, externData_.bVecImagRawPtr);
2589  }
2590 
2591  return bsuccess;
2592 }
2593 
2594 //-----------------------------------------------------------------------------
2595 // Function : DeviceMgr::getNumNoiseDevices
2596 // Purpose :
2597 // Special Notes :
2598 // Scope : public
2599 // Creator : Eric Keiter
2600 // Creation Date : 12/8/2014
2601 //-----------------------------------------------------------------------------
2603 {
2604  int totalNum=0;
2605 
2606  if (!(instancePtrVec_.empty()))
2607  {
2608  for (InstanceVector::iterator iter = instancePtrVec_.begin();
2609  iter != instancePtrVec_.end(); ++iter)
2610  {
2611  int numNoiseSources=(*iter)->getNumNoiseSources();
2612  if (numNoiseSources > 0)
2613  {
2614  totalNum++;
2615  }
2616  }
2617  }
2618 
2619  return totalNum;
2620 }
2621 
2622 //-----------------------------------------------------------------------------
2623 // Function : DeviceMgr::getNumNoiseSources
2624 // Purpose :
2625 // Special Notes :
2626 // Scope : public
2627 // Creator : Eric Keiter
2628 // Creation Date : 12/8/2014
2629 //-----------------------------------------------------------------------------
2631 {
2632  int totalNum=0;
2633  for (InstanceVector::iterator iter = instancePtrVec_.begin();
2634  iter != instancePtrVec_.end(); ++iter)
2635  {
2636  int numNoiseSources=(*iter)->getNumNoiseSources();
2637  totalNum+=numNoiseSources;
2638  }
2639 
2640  return totalNum;
2641 }
2642 
2643 
2644 //-----------------------------------------------------------------------------
2645 // Function : DeviceMgr::setupNoiseSources
2646 // Purpose :
2647 // Special Notes :
2648 // Scope : public
2649 // Creator : Eric Keiter
2650 // Creation Date : 12/8/2014
2651 //-----------------------------------------------------------------------------
2653  (std::vector<Xyce::Analysis::NoiseData*> & noiseDataVec)
2654 {
2655 #if 0
2656  if (noiseDataVec.empty())
2657  {
2658  noiseDataVec.resize(instancePtrVec_.size());
2659  }
2660  else
2661  {
2662  if (noiseDataVec.size() != instancePtrVec_.size())
2663  {
2664  Report::DevelFatal message;
2665  message.in("DeviceMgr::deRegisterFastSources");
2666  message << "Size of noise vector and device vector don't match.";
2667  message << "noiseDataVec.size = " << noiseDataVec.size()
2668  << " instancePtrVec_.size = " << instancePtrVec_.size() <<std::endl;
2669  }
2670  }
2671 #endif
2672 
2673  int i=0;
2674  for (InstanceVector::iterator iter = instancePtrVec_.begin();
2675  iter != instancePtrVec_.end(); ++iter)
2676  {
2677  int numNoiseSources=(*iter)->getNumNoiseSources();
2678  if (numNoiseSources>0)
2679  {
2680  Xyce::Analysis::NoiseData * ndPtr = noiseDataVec[i];
2681  Xyce::Analysis::NoiseData & nd = *ndPtr;
2682  (*iter)->setupNoiseSources ( nd );
2683  i++;
2684  }
2685  }
2686 }
2687 
2688 //-----------------------------------------------------------------------------
2689 // Function : DeviceMgr::getNoiseSources
2690 // Purpose :
2691 // Special Notes :
2692 // Scope : public
2693 // Creator : Eric Keiter
2694 // Creation Date : 12/8/2014
2695 //-----------------------------------------------------------------------------
2697  (std::vector<Xyce::Analysis::NoiseData*> & noiseDataVec)
2698 {
2699  int i=0;
2700  for (InstanceVector::iterator iter = instancePtrVec_.begin();
2701  iter != instancePtrVec_.end(); ++iter)
2702  {
2703  int numNoiseSources=(*iter)->getNumNoiseSources();
2704  if (numNoiseSources>0)
2705  {
2706  Xyce::Analysis::NoiseData * ndPtr = noiseDataVec[i];
2707  Xyce::Analysis::NoiseData & nd = *ndPtr;
2708  (*iter)->getNoiseSources( nd );
2709  i++;
2710  }
2711  }
2712 }
2713 
2714 //-----------------------------------------------------------------------------
2715 // Function : DeviceMgr::getBMatrixEntriesforMOR()
2716 // Purpose : This function obtains the indices for the B-vector contributions for sources.
2717 // Special Notes :
2718 // Scope : public
2719 // Creator : Heidi Thornquist and Ting Mei, SNL
2720 // Creation Date :
2721 //-----------------------------------------------------------------------------
2722 bool
2724  std::vector<int> & bMatEntriesVec,
2725  std::vector<int> & bMatPosEntriesVec)
2726 {
2727  bool bsuccess = true;
2728 
2729  for (IndependentSourceVector::iterator it = independentSourceVector_.begin(), end = independentSourceVector_.end(); it != end; ++it)
2730  {
2731  Vsrc::Instance * vsrc = dynamic_cast<Vsrc::Instance *>(*it);
2732  if (vsrc != 0)
2733  {
2734  int lpos, lneg, lbra;
2735 
2736  vsrc->getLIDs(lpos, lneg, lbra);
2737  bMatEntriesVec.push_back(lbra);
2738  bMatPosEntriesVec.push_back(lpos);
2739  }
2740  }
2741 
2742  return bsuccess;
2743 }
2744 
2745 //-----------------------------------------------------------------------------
2746 // Function : DeviceMgr::updateSources
2747 // Purpose : This function function updates sources for the present
2748 // time step.
2749 // Special Notes :
2750 // Scope : public
2751 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
2752 // Creation Date : 5/26/00
2753 //-----------------------------------------------------------------------------
2755 {
2756  bool bsuccess = true;
2757 
2759 
2760  for (IndependentSourceVector::iterator it = independentSourceVector_.begin(), end = independentSourceVector_.end(); it != end; ++it)
2761  {
2762  (*it)->updateSource();
2763  }
2764 
2765  return bsuccess;
2766 }
2767 
2768 //-----------------------------------------------------------------------------
2769 // Function : DeviceMgr::setICs
2770 // Purpose : This function function sets initial conditions for devices
2771 // Special Notes :
2772 // Scope : public
2773 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
2774 // Creation Date : 9/13/00
2775 //-----------------------------------------------------------------------------
2777  Linear::Vector * tmpSolVectorPtr,
2778  Linear::Vector * tmpCurrSolVectorPtr,
2779  Linear::Vector * tmpLastSolVectorPtr,
2780  Linear::Vector * tmpStaVectorPtr,
2781  Linear::Vector * tmpCurrStaVectorPtr,
2782  Linear::Vector * tmpLastStaVectorPtr,
2783  Linear::Vector * tmpStaDerivVectorPtr,
2784  Linear::Vector * tmpStoVectorPtr,
2785  Linear::Vector * tmpCurrStoVectorPtr,
2786  Linear::Vector * tmpLastStoVectorPtr,
2787  Linear::Vector * tmpQVectorPtr,
2788  Linear::Vector * tmpFVectorPtr,
2789  Linear::Vector * tmpBVectorPtr,
2790  Linear::Vector * tmpdFdxdVpVectorPtr,
2791  Linear::Vector * tmpdQdxdVpVectorPtr)
2792 {
2793  bool bsuccess = true;
2794 
2795  // copy over the passed pointers:
2796  externData_.nextSolVectorPtr = tmpSolVectorPtr;
2797  externData_.currSolVectorPtr = tmpCurrSolVectorPtr;
2798  externData_.lastSolVectorPtr = tmpLastSolVectorPtr;
2799  externData_.daeQVectorPtr = tmpQVectorPtr;
2800  externData_.daeFVectorPtr = tmpFVectorPtr;
2801  externData_.daeBVectorPtr = tmpBVectorPtr;
2802  externData_.dFdxdVpVectorPtr = tmpdFdxdVpVectorPtr;
2803  externData_.dQdxdVpVectorPtr = tmpdQdxdVpVectorPtr;
2804  externData_.nextStaVectorPtr = tmpStaVectorPtr;
2805  externData_.currStaVectorPtr = tmpCurrStaVectorPtr;
2806  externData_.lastStaVectorPtr = tmpLastStaVectorPtr;
2807  externData_.nextStaDerivVectorPtr = tmpStaDerivVectorPtr;
2808  externData_.nextStoVectorPtr = tmpStoVectorPtr;
2809  externData_.currStoVectorPtr = tmpCurrStoVectorPtr;
2810  externData_.lastStoVectorPtr = tmpLastStoVectorPtr;
2811 
2812  // Make sure all boundary data is valid in the solution vector
2813 #ifdef Xyce_PARALLEL_MPI
2814  externData_.nextSolVectorPtr->importOverlap();
2815  externData_.nextStaDerivVectorPtr->importOverlap();
2816 #endif
2817 
2818  // if IC's on devices are set, we need to ensure that the
2819  // raw pointers are up to date first.
2821 
2822  for (InstanceVector::iterator iter = instancePtrVec_.begin();
2823  iter != instancePtrVec_.end(); ++iter)
2824  {
2825  (*iter)->setIC();
2826  }
2827 
2828  return bsuccess;
2829 }
2830 
2831 //-----------------------------------------------------------------------------
2832 // Function : DeviceMgr::output
2833 // Purpose :
2834 // Special Notes :
2835 // Scope : public
2836 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
2837 // Creation Date : 4/13/01
2838 //-----------------------------------------------------------------------------
2840 {
2841  bool bsuccess = true;
2842 
2843  InstanceVector::iterator iter;
2844  InstanceVector::iterator begin = plotFileInstancePtrVec_.begin ();
2845  InstanceVector::iterator end = plotFileInstancePtrVec_.end ();
2846  for (iter=begin; iter!=end;++iter)
2847  {
2848  bool tmpBool = (*iter)->outputPlotFiles ();
2849  bsuccess = bsuccess && tmpBool;
2850  }
2851 
2852  // only output .OP information once.
2854  {
2855  dotOpOutput();
2856  }
2857 
2858  return bsuccess;
2859 }
2860 
2861 //-----------------------------------------------------------------------------
2862 // Function : DeviceMgr::finishOutput
2863 // Purpose : Same as output, only this one forces the output.
2864 //
2865 // Special Notes : This function was neccessary with the implementation of
2866 // outputInterval. The final output, which needs to
2867 // happen after the transient is over, won't neccessarily
2868 // happen with outputInterval enabled.
2869 //
2870 // Scope : public
2871 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
2872 // Creation Date : 6/19/04
2873 //-----------------------------------------------------------------------------
2875 {
2876  bool bsuccess = true;
2877  bool tmpBool = true;
2878 
2879  solState_.forceFinalOutput = true;
2880  tmpBool = output ();
2881  bsuccess = bsuccess && tmpBool;
2882  solState_.forceFinalOutput = false;
2883 
2884  return bsuccess;
2885 }
2886 
2887 //-----------------------------------------------------------------------------
2888 // Function : DeviceMgr::dotOpOutput
2889 // Purpose :
2890 // Special Notes : This is a quick-and-dirty implementation, to get something
2891 // working quickly.
2892 // Scope : public
2893 // Creator : Eric R. Keiter, SNL
2894 // Creation Date : 5/3/12
2895 //-----------------------------------------------------------------------------
2897 {
2898  dotOpOutputFlag = true;
2899 
2900  std::map<std::string, Device *> device_map;
2901  for (EntityTypeIdDeviceMap::const_iterator it = deviceMap_.begin();
2902  it != deviceMap_.end(); ++it)
2903  {
2904  device_map[(*it).second->getName()] = (*it).second;
2905  }
2906 
2907  lout() << section_divider << "\n"
2908  << "Operating point information:";
2909 
2910  for (std::map<std::string, Device *>::const_iterator it = device_map.begin();
2911  it != device_map.end(); ++it)
2912  {
2913  Xyce::Device::printDotOpOutput(lout(), *(*it).second);
2914  }
2915 
2916  lout() << section_divider << std::endl;
2917 }
2918 
2919 //-----------------------------------------------------------------------------
2920 // Function : DeviceMgr::setGlobalFlags
2921 // Purpose :
2922 // Special Notes :
2923 // Scope : public
2924 // Creator : Eric R. Keiter, SNL
2925 // Creation Date : 11/2/12
2926 //-----------------------------------------------------------------------------
2928 {
2929  int pde_flag = solState_.PDESystemFlag ? 1 : 0;
2930 
2931  Parallel::AllReduce(comm_, MPI_LOR, &pde_flag, 1);
2932 
2933  solState_.PDESystemFlag = pde_flag != 0;
2934 }
2935 
2936 //-----------------------------------------------------------------------------
2937 // Function : DeviceMgr::getBreakPoints
2938 // Purpose :
2939 // Special Notes :
2940 // Scope : public
2941 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
2942 // Creation Date : 6/08/01
2943 //-----------------------------------------------------------------------------
2944 bool DeviceMgr::getBreakPoints (std::vector<Util::BreakPoint> & breakPointTimes)
2945 {
2946  InstanceVector::iterator iterI;
2947  ModelVector::iterator iterM;
2948  bool bsuccess = true;
2949  bool tmpBool = true;
2950 
2952  bsuccess = bsuccess && tmpBool;
2954 
2955  // For some devices we only need to set breakpoints caused by discontinuities
2956  // in their parameters:
2957 
2958  for (iterM = modelVector_.begin() ; iterM != modelVector_.end() ; ++iterM)
2959  {
2960  if (!(*iterM)->getDependentParams().empty())
2961  {
2962  tmpBool = (*iterM)->getParamBreakpoints(breakPointTimes);
2963  bsuccess = bsuccess && tmpBool;
2964  }
2965  }
2966 
2967  for (iterI = instancePtrVec_.begin() ; iterI != instancePtrVec_.end() ; ++iterI)
2968  {
2969  if (!(*iterI)->getDependentParams().empty())
2970  {
2971  tmpBool = (*iterI)->getParamBreakpoints(breakPointTimes);
2972  bsuccess = bsuccess && tmpBool;
2973  }
2974  }
2975 
2976  // Breakpoints for global params:
2977  std::vector<Util::Expression>::iterator globalExp_i =
2978  globals_.global_expressions.begin();
2979  std::vector<Util::Expression>::iterator globalExp_end =
2981  for (; globalExp_i != globalExp_end; ++globalExp_i)
2982  {
2983  double bTime = globalExp_i->get_break_time();
2984  if (bTime > solState_.currTime)
2985  breakPointTimes.push_back(bTime);
2986  }
2987 
2989  {
2990  InstanceVector::iterator beginI = instancePtrVec_.begin ();
2991  InstanceVector::iterator endI = instancePtrVec_.end ();
2992 
2993  for (iterI=beginI;iterI!=endI;++iterI)
2994  {
2995  // this function returns false if it is the base class, and true otherwise.
2996  bool functionSetup = (*iterI)->getInstanceBreakPoints (breakPointTimes);
2997  if (functionSetup)
2998  {
2999  bpInstancePtrVec_.push_back(*iterI);
3000  }
3001  }
3003  }
3004  else
3005  {
3006  InstanceVector::iterator beginI = bpInstancePtrVec_.begin ();
3007  InstanceVector::iterator endI = bpInstancePtrVec_.end ();
3008  for (iterI=beginI;iterI!=endI;++iterI)
3009  {
3010  bool functionSetup = (*iterI)->getInstanceBreakPoints (breakPointTimes);
3011  }
3012  }
3013 
3014  ModelTypeInstanceVectorMap::const_iterator model_type_it = modelTypeInstanceVector_.find(ExternDevice::Traits::modelType());
3015  if (model_type_it != modelTypeInstanceVector_.end())
3016  {
3017  for (InstanceVector::const_iterator it = (*model_type_it).second.begin(); it != (*model_type_it).second.end(); ++it)
3018  {
3019  ExternDevice::Instance &extern_device = static_cast<ExternDevice::Instance &>(*(*it));
3020 
3021  extern_device.getBreakPoints(breakPointTimes);
3022  }
3023  }
3024 
3025  return bsuccess;
3026 }
3027 
3028 //-----------------------------------------------------------------------------
3029 // Function : DeviceMgr::setupRawVectorPointers_
3030 // Purpose : set up raw pointers
3031 // Special Notes :
3032 // Scope : public
3033 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
3034 // Creation Date : 11/25/08
3035 //-----------------------------------------------------------------------------
3037 {
3038  if (externData_.daeQVectorPtr != 0)
3039  {
3041  }
3042 
3043  if (externData_.daeFVectorPtr != 0)
3044  {
3046  }
3047 
3048  if (externData_.daeBVectorPtr != 0)
3049  {
3051  }
3052 
3053  if (externData_.dFdxdVpVectorPtr != 0)
3054  {
3056  }
3057 
3058  if (externData_.dQdxdVpVectorPtr != 0)
3059  {
3061  }
3062 
3063  if (externData_.nextSolVectorPtr != 0)
3064  {
3066  }
3067 
3068  if (externData_.currSolVectorPtr != 0)
3069  {
3071  }
3072 
3073  if (externData_.lastSolVectorPtr != 0)
3074  {
3076  }
3077 
3078  if (externData_.nextStaVectorPtr != 0)
3079  {
3081  }
3082 
3083  if (externData_.currStaVectorPtr != 0)
3084  {
3086  }
3087 
3088  if (externData_.lastStaVectorPtr != 0)
3089  {
3091  }
3092 
3094  {
3096  }
3097 
3098  if (externData_.nextStoVectorPtr != 0)
3099  {
3101  }
3102 
3103  if (externData_.currStoVectorPtr != 0)
3104  {
3106  }
3107 
3108  if (externData_.lastStoVectorPtr != 0)
3109  {
3111  }
3112 
3114  {
3116  }
3117 
3118  // lead current and junction voltage vectors
3120  {
3122  }
3123 
3125  {
3127  }
3128 
3130  {
3132  }
3133 
3135  {
3137  }
3138 
3140  {
3142  }
3143 
3145  {
3147  }
3148 
3150  {
3152  }
3153 
3155  {
3157  }
3158 
3160  {
3162  }
3163 
3164 
3165 
3166 
3167  return true;
3168 }
3169 
3170 //-----------------------------------------------------------------------------
3171 // Function : DeviceMgr::setupRawMatrixPointers_
3172 // Purpose : set up raw pointers for matrices
3173 // Special Notes :
3174 // Scope : public
3175 // Creator : Todd Coffey, 1414
3176 // Creation Date : 06/03/09
3177 //-----------------------------------------------------------------------------
3179 {
3180  for (InstanceVector::iterator it = instancePtrVec_.begin(), end = instancePtrVec_.end(); it != end; ++it)
3181  (*it)->setupPointers();
3182 
3183  return true;
3184 }
3185 
3186 //-----------------------------------------------------------------------------
3187 // Function : DeviceMgr::getMaxTimeStepSize
3188 // Purpose :
3189 // Special Notes :
3190 // Scope : public
3191 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
3192 // Creation Date : 7/31/01
3193 //-----------------------------------------------------------------------------
3195 {
3196  double maxStep = devOptions_.defaultMaxTimeStep;
3197 
3198  for (InstanceVector::iterator it = instancePtrVec_.begin(), end = instancePtrVec_.end(); it != end; ++it)
3199  {
3200  double step = (*it)->getMaxTimeStepSize ();
3201  SourceInstance * srcInst = dynamic_cast<SourceInstance*>(*it);
3202  if (!srcInst || !srcInst->getFastSourceFlag())
3203  maxStep = std::min(step, maxStep);
3204  }
3205 
3206  return maxStep;
3207 }
3208 
3209 
3210 //-----------------------------------------------------------------------------
3211 // Function : DeviceMgr::enablePDEContinuation
3212 // Purpose : This function turns on the Continuation flag, which lets
3213 // the devices which are Continuation enabled know that they
3214 // need to set up their variable parameters.
3215 //
3216 // Special Notes : Currently, only PDE devices can take advantage of this
3217 // capability, and it is only used in the context of two-level
3218 // Newton.
3219 //
3220 // Scope : public
3221 // Creator : Eric R. Keiter, SNL, Computational Sciences
3222 // Creation Date : 10/22/02
3223 //-----------------------------------------------------------------------------
3225 {
3226  if (DEBUG_DEVICE)
3227  {
3228  dout() << "DeviceMgr::enablePDEContinuation" << std::endl;
3229  }
3230 
3231  throw std::runtime_error("Using untested enablePDEContinuation()");
3232 
3233  bool bsuccess = true;
3237 
3238  int max_PDE_continuation_steps = 1;
3239  while (max_PDE_continuation_steps != solState_.maxPDEContinuationSteps) {
3240  solState_.maxPDEContinuationSteps = max_PDE_continuation_steps;
3241  for (InstanceVector::iterator it = instancePtrVec_.begin(), end = instancePtrVec_.end(); it != end; ++it)
3242  {
3243  bool tmpSuccess = (*it)->enablePDEContinuation(max_PDE_continuation_steps);
3244  bsuccess = bsuccess && tmpSuccess;
3245  }
3246  }
3247 
3248  int returnedSteps;
3249 
3250  if (!bsuccess) returnedSteps = -1;
3251  else returnedSteps = solState_.maxPDEContinuationSteps;
3252 
3253  return returnedSteps;
3254 }
3255 
3256 //-----------------------------------------------------------------------------
3257 // Function : DeviceMgr::disablePDEContinuation
3258 // Purpose :
3259 // Special Notes :
3260 // Scope : public
3261 // Creator : Eric R. Keiter, SNL, Computational Sciences
3262 // Creation Date : 10/22/02
3263 //-----------------------------------------------------------------------------
3265 {
3266  bool bsuccess = true;
3268 
3269  for (InstanceVector::iterator it = instancePtrVec_.begin(), end = instancePtrVec_.end(); it != end; ++it)
3270  {
3271  bool tmpSuccess = (*it)->disablePDEContinuation();
3272  bsuccess = bsuccess && tmpSuccess;
3273  }
3274 
3275  return bsuccess;
3276 }
3277 
3278 //-----------------------------------------------------------------------------
3279 // Function : DeviceMgr::calcPDESubProblemInfo
3280 //
3281 // Purpose : Determines the number of PDE sub-problems.,
3282 //
3283 // This is mainly used/needed for 2-level problems.
3284 //
3285 // Also determines the number of interface nodes per
3286 // sub-problem (ie number of electrodes on each device).
3287 //
3288 // Special Notes : Need to modify to work correctly in parallel, probably.
3289 //
3290 // Scope : public
3291 // Creator : Eric R. Keiter, SNL, Computational Sciences
3292 // Creation Date : 12/03/02
3293 //-----------------------------------------------------------------------------
3295 {
3296  // now set up numInterfaceNodes_;
3297  numInterfaceNodes_.reserve(pdeInstancePtrVec_.size());
3298 
3299  for (InstanceVector::const_iterator it = pdeInstancePtrVec_.begin(), end = pdeInstancePtrVec_.end(); it != end; ++it)
3300  {
3301  numInterfaceNodes_.push_back((*it)->getNumExtVars());
3302  }
3303 
3304  calledBeforeCSPI = true;
3305 
3306  return true;
3307 }
3308 
3309 //-----------------------------------------------------------------------------
3310 // Function : DeviceMgr::getNumInterfaceNodes
3311 // Purpose : returns the vector calculaed in calcPDESubProblemInfo.
3312 // Special Notes :
3313 // Scope : public
3314 // Creator : Eric R. Keiter, SNL, Computational Sciences
3315 // Creation Date : 12/03/02
3316 //-----------------------------------------------------------------------------
3317 void DeviceMgr::getNumInterfaceNodes (std::vector<int> & numINodes)
3318 {
3319  if (!calledBeforeCSPI)
3320  {
3322  }
3323 
3324  int size = numINodes.size ();
3325  int size2 = numInterfaceNodes_.size();
3326 
3327  if (size < size2) numINodes.resize(size2);
3328 
3329  for (int i=0;i<size2;++i)
3330  {
3331  numINodes[i] = numInterfaceNodes_[i];
3332  }
3333 }
3334 
3335 //-----------------------------------------------------------------------------
3336 // Function : DeviceMgr::loadCouplingRHS
3337 // Purpose :
3338 // Special Notes :
3339 // Scope : public
3340 // Creator : Eric R. Keiter, SNL, Computational Sciences
3341 // Creation Date : 12/03/02
3342 //-----------------------------------------------------------------------------
3343 bool DeviceMgr::loadCouplingRHS (int iPDEDevice, int iElectrode, Linear::Vector * dfdvPtr)
3344 {
3345  return pdeInstancePtrVec_[iPDEDevice]->loadDFDV(iElectrode,dfdvPtr);
3346 }
3347 
3348 //-----------------------------------------------------------------------------
3349 // Function : DeviceMgr::calcCouplingTerms
3350 // Purpose :
3351 // Special Notes :
3352 // Scope : public
3353 // Creator : Eric R. Keiter, SNL, Computational Sciences
3354 // Creation Date : 12/03/02
3355 //-----------------------------------------------------------------------------
3356 bool DeviceMgr::calcCouplingTerms (int iPDEDevice, int iElectrode, const Linear::Vector * dxdvPtr)
3357 {
3358  return pdeInstancePtrVec_[iPDEDevice]->calcConductance(iElectrode, dxdvPtr);
3359 }
3360 
3361 //-----------------------------------------------------------------------------
3362 // Function : DeviceMgr::getHomotopyBlockSize
3363 // Purpose : Returns the number of mosfet gainscale blocks (a value
3364 // in the device options).
3365 // Special Notes : Needed for block homotopy on gainscale.
3366 // Scope : public
3367 // Creator : Roger P. Pawlowski, SNL, Computational Sciences
3368 // Creation Date : 01/26/2005
3369 //-----------------------------------------------------------------------------
3371 {
3373 }
3374 
3375 //-----------------------------------------------------------------------------
3376 // Function : DeviceMgr::updateTemperature
3377 // Purpose :
3378 // Special Notes :
3379 // Scope : public
3380 // Creator : Eric R. Keiter, SNL, Computational Sciences
3381 // Creation Date : 10/26/04
3382 //-----------------------------------------------------------------------------
3384 {
3385  bool bsuccess = true, success = true;
3386 
3387  // convert to kelvin:
3388  double Ctemp = val;
3389  double Ktemp = val + CONSTCtoK;
3390 
3391  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && solState_.debugTimeFlag)
3392  {
3393  dout() << "In DeviceMgr::updateTemperature. new C temp = " << Ctemp << " K temp = " << Ktemp << std::endl;
3394  }
3395 
3396  // First set the global temp. This is used in each device if the "tempGiven"
3397  // variable is false. This should be in Kelvin.
3398  devOptions_.temp.setVal(Ktemp);
3399 
3400  {
3401  // loop over the bsim3 models and delete the size dep params.
3402  ModelTypeModelVectorMap::const_iterator model_type_it = modelTypeModelVector_.find(MOSFET_B3::Traits::modelType());
3403  if (model_type_it != modelTypeModelVector_.end())
3404  {
3405  for (ModelVector::const_iterator it = (*model_type_it).second.begin(); it != (*model_type_it).second.end(); ++it)
3406  {
3407  (*it)->clearTemperatureData ();
3408  }
3409  }
3410  }
3411 
3412  {
3413  // loop over the bsim4 models and delete the size dep params.
3414  ModelTypeModelVectorMap::const_iterator model_type_it = modelTypeModelVector_.find(MOSFET_B4::Traits::modelType());
3415  if (model_type_it != modelTypeModelVector_.end())
3416  {
3417  for (ModelVector::const_iterator it = (*model_type_it).second.begin(); it != (*model_type_it).second.end(); ++it)
3418  {
3419  (*it)->clearTemperatureData ();
3420  }
3421  }
3422  }
3423 
3424  {
3425  // loop over the b3soi models and delete the size dep params.
3426  ModelTypeModelVectorMap::const_iterator model_type_it = modelTypeModelVector_.find(MOSFET_B3SOI::Traits::modelType());
3427  if (model_type_it != modelTypeModelVector_.end())
3428  {
3429  for (ModelVector::const_iterator it = (*model_type_it).second.begin(); it != (*model_type_it).second.end(); ++it)
3430  {
3431  (*it)->clearTemperatureData ();
3432  }
3433  }
3434  }
3435 
3436  // Loop over all models, call processParams, with CTemp.
3437  // "XYCEADMS*TEMP is there to force Verilog devices, which might have
3438  // temperature dependence through "$temperature" instead of a "TEMP"
3439  // parameter, to work properly. If so, they need the temperature set in
3440  // Kelvin.
3441  std::string tname("TEMP");
3442  std::string tname2("XYCEADMSMODTEMP");
3443  std::string tname3("XYCEADMSINSTTEMP");
3444  for (ModelVector::const_iterator it = modelVector_.begin(), end = modelVector_.end(); it != end; ++it)
3445  {
3446  success = (*it)->setParam (tname, Ctemp);
3447  success = (*it)->setParam (tname2, Ktemp) || success;
3448  success = success && (*it)->processParams ();
3449  }
3450 
3451  // Loop over device instances, and set the temperature. This should be
3452  // in C, if going through processParams, and K if going through
3453  // the updateTemperature function.
3454  for (InstanceVector::const_iterator it = instancePtrVec_.begin(), end = instancePtrVec_.end(); it != end; ++it)
3455  {
3456  success = (*it)->setParam (tname, Ctemp);
3457  success = (*it)->setParam (tname3, Ktemp) || success;
3458  success = success && (*it)->processParams ();
3459  }
3460 
3461  return bsuccess;
3462 }
3463 
3464 //-----------------------------------------------------------------------------
3465 // Function : DeviceMgr::allDevicesConverged
3466 // Purpose : Check whether any device has taken an action that renders
3467 // normal convergence checks invalid (i.e. that the current
3468 // step must be assumed unconverged).
3469 // Special Notes :
3470 // Scope : public
3471 // Creator : Tom Russo, SNL, Component Information and Models
3472 // Creation Date : 03/22/05
3473 //-----------------------------------------------------------------------------
3474 bool
3476  Parallel::Machine comm) const
3477 {
3478  int allDevsConv = true;
3479 
3480  // if two-level, and just the inner problem, only check the PDE devices,
3481  // coz those are all we loaded.
3482 
3484  {
3485  for (InstanceVector::const_iterator it = pdeInstancePtrVec_.begin(), end = pdeInstancePtrVec_.end(); it != end; ++it)
3486  {
3487  bool tmpBool = (*it)->isConverged();
3488  allDevsConv = allDevsConv && tmpBool;
3489  }
3490  }
3491  else
3492  {
3493  for (InstanceVector::const_iterator it = instancePtrVec_.begin(), end = instancePtrVec_.end(); it != end; ++it)
3494  {
3495  bool tmpBool = (*it)->isConverged();
3496  allDevsConv = allDevsConv && tmpBool;
3497  }
3498  }
3499 
3500  Parallel::AllReduce(comm, MPI_LAND, &allDevsConv, 1);
3501 
3502  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
3503  {
3504  if (allDevsConv)
3505  {
3506  dout() << "All devices converged!" << std::endl;
3507  }
3508  else
3509  {
3510  dout() << "At least one device NOT converged!" << std::endl;
3511  }
3512  }
3513 
3514  return allDevsConv != 0;
3515 }
3516 
3517 //-----------------------------------------------------------------------------
3518 // Function : DeviceMgr::setupExternalDevices
3519 // Purpose : In parallel, we need to setup all external devices
3520 // and appropriately setup the list of instances
3521 // Special Notes :
3522 // Scope : public
3523 // Creator : Robert Hoekstra, SNL, Elec. & MicroSystems Modeling
3524 // Creation Date : 03/10/06
3525 //-----------------------------------------------------------------------------
3526 bool
3528  Parallel::Communicator & parallel_comm)
3529 {
3530  if (Parallel::is_parallel_run(parallel_comm.comm()))
3531  {
3532  InstanceVector &extern_device_vector = modelTypeInstanceVector_[ExternDevice::Traits::modelType()];
3533 
3534  int procID = parallel_comm.procID();
3535  int numProc = parallel_comm.numProc();
3536 
3537  int numExt = extern_device_vector.size();
3538  int numExtTotal = 0;
3539  parallel_comm.sumAll(&numExt, &numExtTotal, 1);
3540 
3541  InstanceVector orig_extern_device_vector = extern_device_vector;
3542 
3543  //resetup the instance vector to have a size totally the global
3544  //number of ext devices
3545  if (numExtTotal > 0)
3546  {
3547  extern_device_vector.resize(numExtTotal);
3548 
3549  int loc = 0;
3550  for (int proc = 0; proc < numProc; ++proc)
3551  {
3552  int cnt = 0;
3553  if (proc == procID)
3554  cnt = numExt;
3555  parallel_comm.bcast(&cnt, 1, proc);
3556 
3557  for (int i = 0; i < cnt; ++i)
3558  {
3559  if (proc == procID)
3560  {
3561  ExternDevice::Instance &extern_device = static_cast<ExternDevice::Instance &>(*extern_device_vector[loc]);
3562  int size = extern_device.getInstanceBlock().packedByteCount();
3563  int bufSize = size + 100;
3564  char *buf = new char[bufSize];
3565  parallel_comm.bcast(&size, 1, proc);
3566  int pos = 0;
3567  extern_device.getInstanceBlock().pack(buf, bufSize, pos, &parallel_comm);
3568  parallel_comm.bcast(buf, size, proc);
3569  extern_device_vector[loc] = orig_extern_device_vector[i];
3570  delete[] buf;
3571  }
3572  else
3573  {
3574  int size = 0;
3575  parallel_comm.bcast(&size, 1, proc);
3576  int bufSize = size + 100;
3577  char *buf = new char[bufSize];
3578  parallel_comm.bcast(buf, size, proc);
3579  int pos = 0;
3580  InstanceBlock instance_block;
3581  instance_block.unpack(buf, bufSize, pos, &parallel_comm);
3582  extern_device_vector[loc] = addExtDeviceInstance_(instance_block);
3583  delete[] buf;
3584  }
3585  ExternDevice::Instance &extern_device = static_cast<ExternDevice::Instance &>(*extern_device_vector[loc]);
3586  extern_device.setOwningProc(proc);
3587  extern_device.setComm(&parallel_comm);
3588  ++loc;
3589  }
3590  }
3591 
3592  assert(loc == numExtTotal);
3593  }
3594  }
3595  else // serial run
3596  {
3597  ModelTypeInstanceVectorMap::const_iterator model_type_it = modelTypeInstanceVector_.find(ExternDevice::Traits::modelType());
3598  if (model_type_it != modelTypeInstanceVector_.end())
3599  {
3600  for (InstanceVector::const_iterator it = (*model_type_it).second.begin(); it != (*model_type_it).second.end(); ++it)
3601  {
3602  ExternDevice::Instance &extern_device = static_cast<ExternDevice::Instance &>(*(*it));
3603 
3604  extern_device.setComm(&parallel_comm);
3605  }
3606  }
3607  }
3608 
3609  return true;
3610 }
3611 
3612 //-----------------------------------------------------------------------------
3613 // Function : DeviceMgr::updateExternalDevices_
3614 // Purpose : Do the actual solve of the external devices
3615 // Special Notes :
3616 // Scope : public
3617 // Creator : Robert Hoekstra, SNL, Elec. & MicroSystems Modeling
3618 // Creation Date : 03/10/06
3619 //-----------------------------------------------------------------------------
3620 void
3622 {
3623  ModelTypeInstanceVectorMap::const_iterator model_type_it = modelTypeInstanceVector_.find(ExternDevice::Traits::modelType());
3624  if (model_type_it != modelTypeInstanceVector_.end())
3625  {
3626  for (InstanceVector::const_iterator it = (*model_type_it).second.begin(); it != (*model_type_it).second.end(); ++it)
3627  {
3628  ExternDevice::Instance &extern_device = static_cast<ExternDevice::Instance &>(*(*it));
3629 
3630  extern_device.runExternalDevice();
3631  }
3632  }
3633 }
3634 
3635 //-----------------------------------------------------------------------------
3636 // Function : DeviceMgr::addExtDeviceInstance_
3637 // Purpose : adds an external device instance on the processors
3638 // : that don't actually own it.
3639 // Special Notes :
3640 // Scope : public
3641 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
3642 // Creation Date : 3/16/06
3643 //-----------------------------------------------------------------------------
3644 ExternDevice::Instance *
3646  const InstanceBlock & instance_block)
3647 {
3648  ModelTypeId model_type;
3649 
3650  if (instance_block.getModelName().empty())
3651  {
3652  model_type = getModelGroup(instance_block.getInstanceName().getDeviceType());
3653  }
3654  else
3655  {
3656  model_type = modelTypeMap_[instance_block.getModelName()];
3657  }
3658 
3659  if (!model_type.defined())
3660  {
3661  Report::UserError message;
3662  message << "Unable to determine type of device for instance name " << instance_block.getInstanceName();
3663  if (!instance_block.getModelName().empty())
3664  {
3665  message << " with model name " << instance_block.getModelName();
3666  }
3667  }
3668 
3669  // Add an instance of this type.
3670  Device &device = getDeviceByModelType(model_type);
3671  DeviceInstance *instance = device.addInstance(instance_block, FactoryBlock(devOptions_, solState_, matrixLoadData_, externData_, commandLine_));
3672 
3673  return static_cast<ExternDevice::Instance *>(instance);
3674 }
3675 
3676 //-----------------------------------------------------------------------------
3677 // Function : DeviceMgr::acceptStep
3678 // Purpose : Communicate to devices that the current step is accepted
3679 // Special Notes :
3680 // Scope : public
3681 // Creator : Tom Russo, SNL
3682 // Creation Date : 01/23/07
3683 //-----------------------------------------------------------------------------
3685 {
3686  // The time history for the LTRA device(s) has to be tracked
3687  // separately because it can be truncated if the user specifies that
3688  // option. This has to be called before
3689  // LTRAInstance::acceptStep(). Note that the DCOP is stored at
3690  // index zero and the first time step is stored at index 1 for the
3691  // time history vectors associated with the LTRA
3692  if (solState_.dcopFlag)
3693  {
3697  }
3698  else
3699  {
3702  {
3705  }
3707  }
3708 
3709  // make sure we have the right solver state. Putting this here
3710  // makes it essential that acceptStep be called BEFORE any changes have
3711  // been made to the solution or state vectors (e.g. rotating them) and
3712  // while "nextTime" in the solver still references the time for which the
3713  // solution vector is valid.
3714 
3717 
3718  for (InstanceVector::iterator iter = instancePtrVec_.begin(); iter != instancePtrVec_.end(); ++iter)
3719  {
3720  (*iter)->acceptStep();
3721  }
3722 
3723  // If the TRYCOMPACT option is set then the LTRA model will try to
3724  // compact the amount of data stored and speed up the convolutions. If
3725  // any of the LTRA instances request this, done in their acceptStep()
3726  // member function, then perform the time-step compaction here.
3728  {
3731 
3733 
3734  // reset the flag for the next time step
3735  solState_.ltraDoCompact = false;
3736  }
3737 }
3738 
3739 
3740 //-----------------------------------------------------------------------------
3741 // Function : DeviceMgr::getInitialQnorm
3742 // Purpose :
3743 // Special Notes :
3744 // Scope : public
3745 // Creator : Eric R. Keiter, SNL
3746 // Creation Date : 03/12/07
3747 //-----------------------------------------------------------------------------
3748 bool DeviceMgr::getInitialQnorm (std::vector<TimeIntg::TwoLevelError> & tleVec)
3749 {
3750  bool bsuccess = true;
3751 
3752  ModelTypeInstanceVectorMap::const_iterator model_type_it = modelTypeInstanceVector_.find(ExternDevice::Traits::modelType());
3753  if (model_type_it != modelTypeInstanceVector_.end())
3754  {
3755  int numExt = (*model_type_it).second.size();
3756 
3757  tleVec.resize(numExt);
3758  int iext = 0;
3759  for (InstanceVector::const_iterator it = (*model_type_it).second.begin(); it != (*model_type_it).second.end(); ++it, ++iext)
3760  {
3761  ExternDevice::Instance &extern_device = static_cast<ExternDevice::Instance &>(*(*it));
3762 
3763  bool bs1 = extern_device.getInitialQnorm(tleVec[iext]);
3764  bsuccess = bsuccess && bs1;
3765  }
3766  }
3767 
3768  return bsuccess;
3769 }
3770 
3771 //-----------------------------------------------------------------------------
3772 // Function : DeviceMgr::getInnerLoopErrorSums
3773 // Purpose :
3774 // Special Notes :
3775 // Scope : public
3776 // Creator : Eric R. Keiter, SNL
3777 // Creation Date : 03/12/06
3778 //-----------------------------------------------------------------------------
3780  std::vector<TimeIntg::TwoLevelError> & tleVec)
3781 {
3782  bool bsuccess = true;
3783 
3784  ModelTypeInstanceVectorMap::const_iterator model_type_it = modelTypeInstanceVector_.find(ExternDevice::Traits::modelType());
3785  if (model_type_it != modelTypeInstanceVector_.end())
3786  {
3787  int numExt = (*model_type_it).second.size();
3788 
3789  tleVec.resize(numExt);
3790  int iext = 0;
3791  for (InstanceVector::const_iterator it = (*model_type_it).second.begin(); it != (*model_type_it).second.end(); ++it, ++iext)
3792  {
3793  ExternDevice::Instance &extern_device = static_cast<ExternDevice::Instance &>(*(*it));
3794 
3795  bool bs1 = extern_device.getInnerLoopErrorSum(tleVec[iext]);
3796  bsuccess = bsuccess && bs1;
3797  }
3798  }
3799 
3800  return bsuccess;
3801 }
3802 
3803 //-----------------------------------------------------------------------------
3804 // Function : DeviceMgr::updateStateArrays()
3805 // Purpose :
3806 // Special Notes :
3807 // Scope : public
3808 // Creator : Eric R. Keiter, SNL
3809 // Creation Date : 03/12/06
3810 //-----------------------------------------------------------------------------
3812 {
3813  bool bsuccess = true;
3814 
3815  ModelTypeInstanceVectorMap::const_iterator model_type_it = modelTypeInstanceVector_.find(ExternDevice::Traits::modelType());
3816  if (model_type_it != modelTypeInstanceVector_.end())
3817  {
3818  for (InstanceVector::const_iterator it = (*model_type_it).second.begin(); it != (*model_type_it).second.end(); ++it)
3819  {
3820  ExternDevice::Instance &extern_device = static_cast<ExternDevice::Instance &>(*(*it));
3821 
3822  bool bs1 = extern_device.updateStateArrays();
3823  bsuccess = bsuccess && bs1;
3824  }
3825  }
3826 
3827  return bsuccess;
3828 }
3829 
3830 
3831 //-----------------------------------------------------------------------------
3832 // Function : DeviceMgr::startTimeStep
3833 // Purpose :
3834 // Special Notes :
3835 // Scope : public
3836 // Creator : Eric R. Keiter, SNL
3837 // Creation Date : 03/20/06
3838 //-----------------------------------------------------------------------------
3840 {
3841  bool bsuccess = true;
3842 
3844 
3845  ModelTypeInstanceVectorMap::const_iterator model_type_it = modelTypeInstanceVector_.find(ExternDevice::Traits::modelType());
3846  if (model_type_it != modelTypeInstanceVector_.end())
3847  {
3848  for (InstanceVector::const_iterator it = (*model_type_it).second.begin(); it != (*model_type_it).second.end(); ++it)
3849  {
3850  ExternDevice::Instance &extern_device = static_cast<ExternDevice::Instance &>(*(*it));
3851 
3852  bool bs1 = extern_device.startTimeStep();
3853  bsuccess = bsuccess && bs1;
3854  }
3855  }
3856 
3857  return bsuccess;
3858 }
3859 
3860 
3861 //-----------------------------------------------------------------------------
3862 // Function : DeviceMgr::setExternalSolverState
3863 // Purpose :
3864 // Special Notes :
3865 // Scope : public
3866 // Creator : Eric R. Keiter, SNL
3867 // Creation Date : 03/20/06
3868 //-----------------------------------------------------------------------------
3869 void
3871  const SolverState & ss)
3872 {
3873  externalStateFlag_ = true;
3874  solStateExternal_ = ss;
3875 }
3876 
3877 //-----------------------------------------------------------------------------
3878 // Function : DeviceMgr::restartDataSize
3879 // Purpose :
3880 // Special Notes :
3881 // Scope : public
3882 // Creator : Eric R. Keiter, SNL
3883 // Creation Date : 06/26/2013
3884 //-----------------------------------------------------------------------------
3885 int DeviceMgr::restartDataSize(bool pack) const
3886 {
3887  int numdoubles = solState_.ltraTimePoints.size();
3888  int numSize_t = 3;
3889  int count = sizeof(double) * (numdoubles);
3890  count += sizeof(size_t) * numSize_t;
3891 
3892  // bump up size for unpacked data. This is an empirical multiplier.
3893  if (!pack)
3894  {
3895  count *= 3;
3896  }
3897 
3898  return count;
3899 }
3900 
3901 //-----------------------------------------------------------------------------
3902 // Function : DeviceMgr::dumpRestartData
3903 // Purpose : Output restart data.
3904 // Special Notes : This function is called by the restart manager to output
3905 // persistent data for the device package. It should NOT
3906 // include any data from individual devices, as that restart
3907 // data is collected elsewhere.
3908 // Scope :
3909 // Creator : Eric R. Keiter, SNL
3910 // Creation Date : 06/26/2013
3911 //-----------------------------------------------------------------------------
3913  char * buf, int bsize, int & pos, N_PDS_Comm * comm, bool pack) const
3914 {
3915  bool retval=true;
3916 
3917  if (pack)
3918  {
3919  size_t size=solState_.ltraTimePoints.size();
3920  comm->pack(&(solState_.ltraTimeIndex), 1, buf, bsize, pos);
3921  comm->pack(&(solState_.ltraTimeHistorySize), 1, buf, bsize, pos);
3922  comm->pack(&(size), 1, buf, bsize, pos);
3923  comm->pack(&(solState_.ltraTimePoints[0]), size, buf, bsize, pos);
3924  }
3925  else
3926  {
3927  int count = restartDataSize(false);
3928  int startIndex = pos;
3929  for(int i = startIndex; i < (startIndex+count); ++i) buf[i] = ' ';
3930 
3931  size_t size=solState_.ltraTimePoints.size();
3932  std::ostringstream ost;
3933  ost.width(24);ost.precision(16);ost.setf(std::ios::scientific);
3934  ost << solState_.ltraTimeIndex << " ";
3935  ost << solState_.ltraTimeHistorySize << " ";
3936 
3937  if (DEBUG_RESTART)
3938  dout() << "DeviceMgr::getRestartData: ltraTimeIndex = " << solState_.ltraTimeIndex << std::endl
3939  << "DeviceMgr::getRestartData: ltraTimeHistorySize = " << solState_.ltraTimeHistorySize << std::endl;
3940 
3941  ost << size << " ";
3942  for (int i=0;i<size;i++)
3943  {
3944  ost << solState_.ltraTimePoints[i] << " ";
3945  if (DEBUG_RESTART)
3946  dout() << "DeviceMgr::dumpRestartData: ltraTimePoints["<<i<<"] =" << solState_.ltraTimePoints[i]<<std::endl;
3947  }
3948 
3949  std::string data(ost.str());
3950  for(unsigned int i = 0; i < data.length(); ++i) buf[startIndex+i] = data[i];
3951 
3952  // The line above copies the characters of the data string into buf,
3953  // but doesn't null-terminate buf.
3954  // it is essential to terminate the buffer with a null, or attempts
3955  // to construct a string object from it will get memory access problems.
3956  buf[startIndex+data.length()] = '\0';
3957  pos += data.length();
3958  }
3959 
3960  return retval;
3961 }
3962 
3963 //-----------------------------------------------------------------------------
3964 // Function : DeviceMgr::restoreRestartData
3965 // Purpose : Load restart data.
3966 // Special Notes :
3967 // Scope :
3968 // Creator : Eric R. Keiter, SNL
3969 // Creation Date : 06/26/2013
3970 //-----------------------------------------------------------------------------
3971 bool DeviceMgr::restoreRestartData(char * buf, int bsize, int & pos, N_PDS_Comm * comm, bool pack)
3972 {
3973  bool retval=true;
3974 
3975  if (pack)
3976  {
3977  comm->unpack(buf, bsize, pos, &(solState_.ltraTimeIndex), 1);
3978  comm->unpack(buf, bsize, pos, &(solState_.ltraTimeHistorySize), 1);
3979  size_t size=0;
3980  comm->unpack(buf, bsize, pos, &(size), 1);
3981  solState_.ltraTimePoints.resize(size);
3982  comm->unpack(buf, bsize, pos, &(solState_.ltraTimePoints[0]), size);
3983  }
3984  else
3985  {
3986  std::string str1(buf);
3987  int length = str1.size() - pos;
3988  std::string str2(str1,pos,length);
3989 
3990  std::istringstream ist(str2);
3991 
3992  ist >> solState_.ltraTimeIndex;
3994  if (DEBUG_RESTART)
3995  dout() << "DeviceMgr::restoreRestartData: ltraTimeIndex = " << solState_.ltraTimeIndex <<std::endl
3996  << "DeviceMgr::restoreRestartData: ltraTimeHistorySize = " << solState_.ltraTimeHistorySize <<std::endl;
3997 
3998  size_t size=0;
3999  ist >> size;
4000  solState_.ltraTimePoints.resize(size);
4001  for (int i=0;i<size;++i)
4002  {
4003  ist >> solState_.ltraTimePoints[i];
4004  if (DEBUG_RESTART)
4005  dout() << "DeviceMgr::restoreRestartData: ltraTimePoints["<<i<<"] = " << solState_.ltraTimePoints[i] << std::endl;
4006  }
4007 
4008  pos += ist.tellg();
4009  }
4010 
4011  return retval;
4012 }
4013 
4014 //-----------------------------------------------------------------------------
4015 // Function : DeviceMgr::getDeviceEntity
4016 // Purpose :
4017 // Special Notes :
4018 // Scope : public
4019 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
4020 // Creation Date : 5/02/03
4021 //-----------------------------------------------------------------------------
4022 DeviceEntity * DeviceMgr::getDeviceEntity(const std::string & full_param_name) const
4023 {
4024  std::string entity_name = Xyce::Util::entityNameFromFullParamName(full_param_name).getEncodedName();
4025 
4026  DeviceEntityMap::iterator it = parameterDeviceCache_.find(full_param_name);
4027  if (it == parameterDeviceCache_.end())
4028  {
4029  DeviceEntity *device_entity = findDeviceEntity(deviceMap_.begin(), deviceMap_.end(), entity_name);
4030  parameterDeviceCache_[full_param_name] = device_entity;
4031  return device_entity;
4032  }
4033  else if (!(*it).second)
4034  {
4035  DeviceEntity *device_entity = findDeviceEntity(deviceMap_.begin(), deviceMap_.end(), entity_name);
4036  (*it).second = device_entity;
4037  return device_entity;
4038  }
4039  else
4040  return (*it).second;
4041 }
4042 
4043 //-----------------------------------------------------------------------------
4044 // Function : DeviceMgr::addDevicesToCount
4045 // Purpose :
4046 // Special Notes :
4047 // Scope : public
4048 // Creator : Heidi Thornquist, SNL
4049 // Creation Date : 8/06/14
4050 //-----------------------------------------------------------------------------
4052 {
4053  // Add in devices to map for counting.
4054  for (DeviceCountMap::const_iterator it = device_map.begin(), end = device_map.end(); it != end; ++it)
4055  {
4056  if ( localDeviceCountMap_[(*it).first] )
4057  {
4058  localDeviceCountMap_[(*it).first] += (*it).second;
4059  }
4060  else
4061  {
4062  localDeviceCountMap_[(*it).first] = (*it).second;
4063  }
4064  }
4065 }
4066 
4067 //-----------------------------------------------------------------------------
4068 // Function : DeviceMgr::setupSolverInfo
4069 //
4070 // Purpose :
4071 //
4072 // Special Notes : This function gets called a lot, and this can be kind of
4073 // confusing. Probably, this function is being used to handle
4074 // too many different types of data.
4075 //
4076 // For example, it gets called at the beginning
4077 // of the "updateSources" function. Why? Because the sources
4078 // need to know which step we are at, and/or what the current
4079 // time is, to do their update properly.
4080 //
4081 // However, at the moment, updateSources also provides
4082 // information that setupSolverInfo needs. Only after the
4083 // sources have been updated do we know if a sweep source has
4084 // been reset. And, the sweepSourceResetFlag is used by
4085 // setupSolverInfo, to set up the initJctFlag boolean.
4086 // So it will need to be called at least one more
4087 // time, at the beginning of the RHS load. (which it is).
4088 //
4089 // Anyway, any of the functions that are called from the
4090 // outside, such as: updateSources, loadRHSVector,
4091 // loadJacobianMatrix, etc.... have no way of knowing when,
4092 // w.r.t. the solvers they are being called. The only way
4093 // to do this properly is to have each of them request
4094 // the current solver state, before they go to do their
4095 // work. Hence, this function is called a lot.
4096 //
4097 // Unfortunately, this has led to a somewhat sloppy and
4098 // confusing interface between the solvers and the
4099 // device package. I wanted to avoid having a lot of
4100 // function arguments being passed around for each of
4101 // these functions, in part because the calling code
4102 // (NLS) doesn't know everything. - NLS knows about the newton
4103 // step, but it doesn't know the time step, for example.
4104 //
4105 // At some point I hope to refactor this.
4106 //
4107 // Scope : private
4108 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
4109 // Creation Date : 7/30/01
4110 //-----------------------------------------------------------------------------
4111 bool
4113  Parallel::Machine comm,
4114  SolverState & solver_state,
4115  const SolverState & external_solver_state,
4116  bool external_state_flag,
4117  const Analysis::AnalysisManager & analysis_manager,
4118  const DeviceMgr & device_manager,
4119  const DeviceOptions & device_options,
4120  const Nonlinear::NonLinInfo & twoLevelNonlinearInfo)
4121 {
4122  bool bsuccess = true;
4123 
4124  Analysis::getTimeIntInfo(analysis_manager, solver_state.twoLevelTimeIntgInfo);
4125 
4126  // Time integration info:
4127  solver_state.pdt = solver_state.twoLevelTimeIntgInfo.pdt;
4128  solver_state.currTimeStep = solver_state.twoLevelTimeIntgInfo.nextTimeStep;
4129  solver_state.lastTimeStep = solver_state.twoLevelTimeIntgInfo.currTimeStep;
4130  solver_state.currTime = solver_state.twoLevelTimeIntgInfo.nextTime;
4131  solver_state.finalTime = solver_state.twoLevelTimeIntgInfo.finalTime;
4132  solver_state.startingTimeStep = solver_state.twoLevelTimeIntgInfo.startingTimeStep;
4133  solver_state.bpTol = solver_state.twoLevelTimeIntgInfo.bpTol;
4134  solver_state.currentOrder = solver_state.twoLevelTimeIntgInfo.currentOrder;
4135  solver_state.usedOrder = solver_state.twoLevelTimeIntgInfo.usedOrder;
4136 
4137  if (solver_state.mpdeOnFlag == 1)
4138  {
4139  solver_state.dcopFlag = 0;
4140  solver_state.initTranFlag = 1;
4141  solver_state.beginIntegrationFlag = 1;
4142  }
4143  else
4144  {
4145  solver_state.dcopFlag = solver_state.twoLevelTimeIntgInfo.dcopFlag;
4146  solver_state.initTranFlag = solver_state.twoLevelTimeIntgInfo.initTranFlag;
4148  }
4149 
4150  solver_state.inputOPFlag = solver_state.twoLevelTimeIntgInfo.inputOPFlag;
4151  solver_state.acopFlag = solver_state.twoLevelTimeIntgInfo.acopFlag;
4152  solver_state.tranopFlag = solver_state.twoLevelTimeIntgInfo.tranopFlag;
4153  solver_state.transientFlag = solver_state.twoLevelTimeIntgInfo.transientFlag;
4154  solver_state.dcsweepFlag = solver_state.twoLevelTimeIntgInfo.dcsweepFlag;
4156 
4157  solver_state.timeStepNumber = solver_state.twoLevelTimeIntgInfo.timeStepNumber;
4158 
4159  solver_state.doubleDCOPStep = solver_state.twoLevelTimeIntgInfo.doubleDCOPStep;
4160  solver_state.doubleDCOPEnabled = solver_state.twoLevelTimeIntgInfo.doubleDCOPEnabled;
4161 
4162  // Nonlinear solver info:
4163  solver_state.newtonIter = twoLevelNonlinearInfo.newtonIter;
4164  solver_state.twoLevelNewtonCouplingMode = twoLevelNonlinearInfo.twoLevelNewtonCouplingMode;
4165 
4166  // Get LOCA-specific information. Note - in general, LOCA is only used for
4167  // steady state calculations - there isn't much point in using it
4168  // for transient. A common case is one where LOCA is used for the
4169  // tranOP, but not for the subsequent transient phase. The
4170  // locaEnabledFlag should switch from true to false under
4171  // that scenario, once the transient phase starts.
4172  solver_state.locaEnabledFlag = twoLevelNonlinearInfo.locaFlag;
4173  if (solver_state.locaEnabledFlag) // if no LOCA, these are 0, true, respectively.
4174  {
4175  solver_state.continuationStepNumber = twoLevelNonlinearInfo.continuationStep;
4176  solver_state.firstContinuationParam = twoLevelNonlinearInfo.firstContinuationParam;
4177  solver_state.firstSolveComplete = twoLevelNonlinearInfo.firstSolveComplete;
4178  }
4179  // Done with LOCA information.
4180 
4181  // Setup the initialize junctions flag.
4182  // The initJct flag should only be true if we are at the first Newton step of
4183  // an initial point in the calculation. Examples include:
4184  // - 1st Newton step of the DCOP initialization for transient (tranOp)
4185  // - 1st Newton step of first DC sweep step.
4186  // - 1st Newton step of a sweep that has been reset. That typically
4187  // happens if the sweep is multi-dimensional, and the inner loop has
4188  // cycled back to the beginning again.
4189  //
4190  bool resetFlag = (solver_state.timeStepNumber==0) || (solver_state.sweepSourceResetFlag);
4191 
4192  // Do this if using LOCA for a DC or tranop calculation.
4193  if (solver_state.dcopFlag && solver_state.locaEnabledFlag)
4194  {
4195  resetFlag = resetFlag && (solver_state.continuationStepNumber==0);
4196  }
4197 
4198  solver_state.initJctFlag = ((solver_state.dcopFlag) &&
4199  (solver_state.newtonIter==0) &&
4200  solver_state.firstContinuationParam &&
4201  !solver_state.firstSolveComplete && resetFlag);
4202 
4203  // One final check. See if the "external state" has been set. If so,
4204  // check to see if it has the initJctFlag set. If not, then we probably
4205  // shouldn't either. The external state comes from a higher up level
4206  // in a multi-level newton solve.
4207  //
4208  // This should be made more detailed later.
4209  if (external_state_flag)
4210  {
4211  if (solver_state.newtonIter==0 && solver_state.dcopFlag)
4212  {
4213  solver_state.initJctFlag = external_solver_state.initJctFlag;
4214  }
4215  }
4216 
4217 
4218  // initFixFlag: try to mimic "MODEINITFIX" of SPICE. This is set if:
4219  // DCOP or TranOP
4220  // Not first iteration
4221  // Any device not converged
4222  solver_state.initFixFlag =
4223  solver_state.dcopFlag
4224  && !device_manager.allDevicesConverged(comm)
4225  && (solver_state.newtonIter != 0)
4226  && solver_state.firstContinuationParam
4227  && !solver_state.firstSolveComplete
4228  && resetFlag;
4229 
4230  if (solver_state.dcopFlag)
4231  {
4232  solver_state.ltraTimeIndex = 0;
4233  solver_state.ltraTimeHistorySize = 10;
4234  solver_state.ltraTimePoints.resize(solver_state.ltraTimeHistorySize);
4235  }
4236 
4237  // The first DCOP step of a "double DCOP" simulation is a special case,
4238  // in which the nonlinear poisson is solved in place of drift-diffusion
4239  // equations for the PDE devices. For this initialization problem, the
4240  // circuit subproblem should not be included.
4241  if ((solver_state.doubleDCOPEnabled) &&
4242  (solver_state.dcopFlag) &&
4243  (solver_state.doubleDCOPStep == 0))
4244  {
4246  }
4247 
4248  if (DEBUG_DEVICE) {
4249  if (isActive(Diag::DEVICE_SOLVER_STATE) && solver_state.debugTimeFlag)
4250  {
4251  dout() << solver_state;
4252  }
4253 
4254  solver_state.debugTimeFlag =
4255  (solver_state.currTime >= device_options.debugMinTime &&
4256  solver_state.currTime <= device_options.debugMaxTime) &&
4257  (solver_state.timeStepNumber >= device_options.debugMinTimestep &&
4258  solver_state.timeStepNumber <= device_options.debugMaxTimestep);
4259  }
4260 
4261  return bsuccess;
4262 }
4263 
4264 } // namespace Device
4265 } // namespace Xyce
std::vector< std::string > global_exp_names
const InstanceName & getName() const
bool dcopFlag
Analysis DCOP flag.
bool setupDefaultOptions(const IO::CmdParse &command_line)
Linear::Vector * numJacSolVectorPtr_
double finalTime
Step error control final time.
void setExternalSolverState(const SolverState &ss)
const double * findGlobalPar(const std::string &parName) const
bool setupExternalDevices(N_PDS_Comm &parallel_comm)
Linear::Vector * lastStaVectorPtr
void getAnalyticSensitivities(std::string &name, std::vector< double > &dfdpVec, std::vector< double > &dqdpVec, std::vector< double > &dbdpVec, std::vector< int > &FindicesVec, std::vector< int > &QindicesVec, std::vector< int > &BindicesVec)
const ModelName & getName() const
ModelTypeNameModelTypeIdMap modelTypeMap_
Model type name to model.
bool setLeadCurrentRequests(const std::set< std::string > &deviceNames)
Linear::Vector * numJacStaVectorPtr_
NonLinInfo getNonLinInfo() const
bool getParam(const std::string &paramName, double &result) const
Linear::Vector * bVecImagPtr
std::ostream & printDotOpOutput(std::ostream &os, const Device &device)
Definition: N_DEV_Print.C:155
bool tranopFlag
Analysis TransientOP flag.
Linear::System * lasSysPtr
#define CONSTCtoK
Definition: N_DEV_Const.h:52
DeviceEntity * getDeviceEntity(const std::string &full_param_name) const
Linear::Vector * currSolVectorPtr
Linear::Vector * nextLeadCurrFCompPtr
Linear::Vector * nextSolVectorPtr
IndependentSourceMap independentSourceMap_
DeviceMgr(Parallel::Machine comm, Topo::Topology &topology, const IO::CmdParse &command_line)
std::vector< double > getFastSourcePeriod(Parallel::Machine comm, const std::vector< std::string > &sourceNames)
void unpack(char *pB, int bsize, int &pos, N_PDS_Comm *comm)
Analysis::AnalysisManager * analysisManager_
To search for non-device parameters. This needs to be removed.
Linear::Vector * nextLeadCurrQCompPtr
bool loadErrorWeightMask(Linear::Vector *deviceMaskPtr)
double getParamNoReduce(const std::string &name) const
Linear::Vector * daeQVectorPtr
Linear::Vector * nextJunctionVCompPtr
InstanceVector instancePtrVec_
Pure virtual class to augment a linear system.
ModelTypeModelVectorMap modelGroupModelVector_
bool inputOPFlag
Analysis InputOP flag.
bool getInnerLoopErrorSums(std::vector< TimeIntg::TwoLevelError > &tleVec)
std::vector< double > ltraTimePoints
Linear::Vector * Jdx2VectorPtr
const std::string & getEncodedName() const
Return the instance name encoded as: [s:]*xname [s:]*Ytype!name [s:]*Utype!name!count.
TimeIntg::TimeIntInfo twoLevelTimeIntgInfo
void initializeHomotopyBlockSize(int numBlocks)
Device * createDevice(const FactoryBlock &factory_block) const
Creates the specified device.
Linear::Vector * perturbVectorPtr
void setFastTime(double timeVal)
Topo::Topology & topology_
Definition: N_ANP_AC.C:968
bool getBMatrixEntriesforMOR(std::vector< int > &bMatEntriesVec, std::vector< int > &bMatPosEntriesVec)
bool registerAnalysisManager(Analysis::AnalysisManager *analysis_manager)
Linear::Vector * dFdxdVpVectorPtr
Linear::Vector * numJacFVectorPtr
ModelTypeInstanceVectorMap modelTypeInstanceVector_
void getNumInterfaceNodes(std::vector< int > &numInterfaceNodes)
DeviceCountMap localDeviceCountMap_
Device & getDeviceByModelType(const EntityTypeId model_type)
Linear::Vector * tmpdQdXPtr
ExternDevice::Instance * addExtDeviceInstance_(const InstanceBlock &IB)
bool findParam(const std::string &name) const
type_index EntityTypeId
Definition: N_DEV_fwd.h:153
double nextTimeStep
Step error control next time step.
std::vector< Util::Expression > global_expressions
Nonlinear::TwoLevelNewtonMode twoLevelNewtonCouplingMode
Linear::Matrix * FTestMatrixPtr
bool getAnalyticSensitivity(const std::string &paramName, std::vector< double > &dfdpVec, std::vector< double > &dqdpVec, std::vector< double > &dbdpVec, std::vector< int > &FindicesVec, std::vector< int > &QindicesVec, std::vector< int > &BindicesVec)
Linear::Vector * tmpdIdXPtr
Linear::Vector * currJunctionVCompPtr
const T & value(const ParameterBase &entity, const Descriptor &descriptor)
Returns the value of the parameter for the entity.
Definition: N_DEV_Pars.h:1224
Linear::Vector * diagonalVectorPtr_
Linear::Vector * lastJunctionVCompPtr
ModelTypeModelVectorMap modelTypeModelVector_
DeviceEntityMap parameterDeviceCache_
Full parameter name to device entity cache.
static const Configuration * findConfiguration(ModelTypeId model_type_id)
Returns the configuration associated with the device name and level or 0 if not found.
Linear::Vector * dQdxdVpVectorPtr
void getTimeIntInfo(const AnalysisManager &analysis_manager, TimeIntg::TimeIntInfo &tiInfo)
Linear::Vector * Fdx2VectorPtr
InstanceVector testJacDevicePtrVec_
Devices under jacobian test.
DeviceInstance * addDeviceInstance(const InstanceBlock &IB)
Linear::Vector * lastSolVectorPtr
Linear::Vector * fVectorPtr
void getNoiseSources(std::vector< Xyce::Analysis::NoiseData * > &noiseDataVec)
bool dumpRestartData(char *buf, int bsize, int &pos, N_PDS_Comm *comm, bool pack) const
std::vector< DeviceInstance * > InstanceVector
Linear::Vector * lastLeadCurrFCompPtr
bool setParam(std::string &name, double val, bool overrideOriginal=false)
bool setICs(Linear::Vector *tmpSolVectorPtr, Linear::Vector *tmpCurrSolVectorPtr, Linear::Vector *tmpLastSolVectorPtr, Linear::Vector *tmpStaVectorPtr, Linear::Vector *tmpCurrStaVectorPtr, Linear::Vector *tmpLasStaVectorPtr, Linear::Vector *tmpStaDerivVectorPtr, Linear::Vector *tmpStoVectorPtr, Linear::Vector *tmpCurrStoVectorPtr, Linear::Vector *tmpLastStoVectorPtr, Linear::Vector *tmpQVectorPtr, Linear::Vector *tmpFVectorPtr, Linear::Vector *tmpBVectorPtr, Linear::Vector *tmpdFdxdVpVectorPtr, Linear::Vector *tmpdQdxdVpVectorPtr)
bool loadCouplingRHS(int iPDEDevice, int iElectrode, Linear::Vector *dfdvPtr)
The FactoryBlock contains parameters needed by the device, instance and model creation functions...
double nextTime
Step error control next time.
std::pair< ModelTypeId, ModelTypeId > getModelType(const InstanceBlock &instance_block)
bool parameterChanged_
Only used locally in updateDependentParameters_, don't know if stateful of just a member for fun...
bool setHBAnalysisParams(const Util::OptionBlock &option_block)
static ModelTypeId getModelGroup(const std::string &device_name)
Returns the model group of the device name.
bool loadDAEMatrices(Linear::Vector *tmpSolVectorPtr, Linear::Vector *tmpStaVectorPtr, Linear::Vector *tmpStaDerivVectorPtr, Linear::Vector *tmpStoVectorPtr, Linear::Matrix *tmpdQdxMatrixPtr, Linear::Matrix *tmpdFdxMatrixPtr)
bool getParam(const std::string &name, double &value) const
Linear::Vector * JdxpVectorPtr
double bpTol
Step error control breakpoint tolerance.
bool calcCouplingTerms(int iSubProblem, int iElectrode, const Linear::Vector *dxdvPtr)
void addGlobalPar(const Util::Param &)
DeviceSensitivities * devSensPtr_
InstanceVector pdeInstancePtrVec_
Linear::Vector * lastLeadCurrQCompPtr
ModelTypeNameModelTypeIdMap modelGroupMap_
Model type name to model group.
bool setNOISEAnalysisParams(const Util::OptionBlock &option_block)
Linear::Vector * lastStoVectorPtr
Linear::Vector * dxVoltlimVectorPtr
Linear::Vector * numJacRHSVectorPtr
void setMPDEFlag(bool flagVal)
int usedOrder
Time integrator used order.
const std::string & getType() const
Linear::Vector * deviceErrorWeightMask_
Linear::Vector * nextStaVectorPtr
Linear::Vector * currLeadCurrFCompPtr
bool setInitialGuess(Linear::Vector *solVectorPtr)
bool setDefaultParam(double val, bool overrideOriginal=false)
const ModelName & getModelName() const
DeviceMgr & deviceManager_
IO::Measure::Manager * measureManager_
To search for non-device parameters. This needs to be removed.
const IO::CmdParse & commandLine_
Command line.
const InstanceName & getInstanceName() const
Parallel::Machine comm_
Communicator (should be passed in when needed, not a member)
Linear::Vector * numJacLoadFlagPtr
double timeParamsProcessed_
Time updateDependentParameters was called.
The Device class is an interface for device implementations.
Definition: N_DEV_Device.h:101
EntityTypeIdDeviceMap deviceMap_
int getHomotopyBlockSize() const
Linear::Vector * daeBVectorPtr
bool allDevicesConverged(Parallel::Machine comm) const
bool initializeAll(Linear::System &linear_system)
const InstanceVector & getExternDevices() const
static const ModelTypeId modelType()
Returns the model type identifier.
TwoLevelNewtonMode twoLevelNewtonCouplingMode
type_index ModelTypeId
Definition: N_DEV_fwd.h:154
bool getBreakPoints(std::vector< Util::BreakPoint > &breakPointTimes)
Linear::Vector * numJacStoVectorPtr_
bool setACAnalysisParams(const Util::OptionBlock &option_block)
AnalysisManager & analysisManager_
Definition: N_ANP_AC.C:965
Class Configuration contains device configuration data.
void setupNoiseSources(std::vector< Xyce::Analysis::NoiseData * > &noiseDataVec)
Linear::Vector * storeLeadCurrQCompPtr
std::vector< std::pair< int, double > > * icLoads_
std::set< std::string > devicesNeedingLeadCurrentLoads_
EntityTypeId getModelGroup(const std::string &model_or_device_type_name)
Return the ModelGroup of the device associated with the model type name or device type name...
bool addDeviceModel(const ModelBlock &MB)
bool sensFlag_
.SENS present in netlist
bool setOPAnalysisParams(const Util::OptionBlock &option_block)
bool analyticSensitivityAvailable(const std::string &paramName)
double getGlobalPar(const std::string &parName) const
int restartDataSize(bool pack) const
void deRegisterFastSources(const std::vector< std::string > &sourceNames)
std::map< std::string, int, LessNoCase > passThroughParamsMap_
DeviceOptions devOptions_
user-defined options:
bool loadDAEVectors(Linear::Vector *tmpNextSolVectorPtr, Linear::Vector *tmpCurrSolVectorPtr, Linear::Vector *tmpLastSolVectorPtr, Linear::Vector *tmpNextStaVectorPtr, Linear::Vector *tmpCurrStaVectorPtr, Linear::Vector *tmpLastStaVectorPtr, Linear::Vector *tmpStaDerivVectorPtr, Linear::Vector *tmpNextStoVectorPtr, Linear::Vector *tmpCurrStoVectorPtr, Linear::Vector *tmpLastStoVectorPtr, Linear::Vector *tmpStoLeadCurrQCompVectorPtr, Linear::Vector *tmpLeadFCompVectorPtr, Linear::Vector *tmpLastLeadFCompVectorPtr, Linear::Vector *tmpNextLeadFCompVectorPtr, Linear::Vector *tmpLeadQCompVectorPtr, Linear::Vector *tmpJunctionVCompVectorPtr, Linear::Vector *tmpLastJunctionVCompVectorPtr, Linear::Vector *tmpNextJunctionCompVectorPtr, Linear::Vector *tmpQVectorPtr, Linear::Vector *tmpFVectorPtr, Linear::Vector *tmpBVectorPtr, Linear::Vector *tmpdFdxdVpVectorPtr, Linear::Vector *tmpdQdxdVpVectorPtr)
bool applyCmdLineOptions(const IO::CmdParse &command_line)
Nonlinear::Manager * nlsMgrPtr_
To get Nonlinear solver information. This needs to be removed.
void setBlockAnalysisFlag(bool flagVal)
SolverState solState_
real time solver data:
Linear::Vector * nextStoVectorPtr
unordered_map< std::string, double, HashNoCase, EqualNoCase > GlobalParameterMap
Definition: N_DEV_fwd.h:161
ArtificialParameterMap artificialParameterMap_
Specially named parameters. This needs to be removed.
InstanceVector plotFileInstancePtrVec_
std::map< std::string, int, LessNoCase > DeviceCountMap
Definition: N_DEV_fwd.h:163
Linear::Vector * currStaVectorPtr
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)
Linear::Vector * daeFVectorPtr
IndependentSourceVector indepSourceInstanceBackupPtrVec_
bool registerPkgOptionsMgr(DeviceMgr &device_manager, const std::string &netlist_filename, IO::PkgOptionsMgr &options_manager)
Linear::Vector * bVecRealPtr
void addArtificialParameter(const std::string &name, ArtificialParameters::ArtificialParameter *artificial_parameter)
bool registerSensParams(const Util::OptionBlock &option_block)
bool analyticSensitivitiesAvailable(const std::string &name)
InstanceVector bpInstancePtrVec_
instances with breakpoints functions
static ModelTypeId getModelType(const std::string &model_name, const int level)
Returns the model type identifier for the specified device, if the model type and level is not found...
bool setParam(const std::string &paramName, double val, bool overrideOriginal=false)
bool loadBVectorsforAC(Linear::Vector *bVecRealPtr, Linear::Vector *bVecImagPtr)
bool acopFlag
Analysis ACOP flag.
bool updateTemperature(double val)
void notify(const Analysis::StepEvent &event)
double pdt
Time integrator partial time deriviative.
bool setupSolverInfo(Parallel::Machine comm, SolverState &solver_state, const SolverState &external_solver_state, bool external_state_flag, const Analysis::AnalysisManager &analysis_manager, const DeviceMgr &device_manager, const DeviceOptions &device_options, const Nonlinear::NonLinInfo &twoLevelNonlinearInfo)
std::vector< int > numInterfaceNodes_
IndependentSourceVector independentSourceVector_
bool restoreRestartData(char *buf, int bsize, int &pos, N_PDS_Comm *comm, bool pack)
Globals & globals_
global variables
bool linearSystemFlag_
True if all devices in netlist have isLinearDevice() true.
Linear::Vector * currStoVectorPtr
bool verifyDeviceInstance(const InstanceBlock &IB)
bool deleteDeviceInstance(const std::string &name)
virtual bool processInstanceParams()=0
Linear::Vector * currLeadCurrQCompPtr
InstanceVector nonPdeInstancePtrVec_
GlobalParameterMap global_params
ModelBlock represents a .MODEL line from the netlist.
Linear::Matrix * JTestMatrixPtr
MatrixLoadData matrixLoadData_
temporary jacobian load structures:
Linear::Matrix * QTestMatrixPtr
double startingTimeStep
Step error control starting time step.
void setFastSourceFlag(bool value)
Definition: N_DEV_Source.C:96
std::string ModelName
Definition: N_DEV_fwd.h:157
void addDevicesToCount(const DeviceCountMap &device_map)
InstanceBlock represent a device instance line from the netlist.
std::vector< DeviceInstance * > InstanceVector
Definition: N_DEV_fwd.h:182
double getParamAndReduce(const std::string &name) const
std::vector< Param > params
const std::string & getDeviceType() const
Decodes the device type.
virtual bool processParams()=0
std::vector< double > registerFastSources(Parallel::Machine comm, const std::vector< std::string > &sourceNames)
bool registerSensParams(const Util::OptionBlock &option_block)
ModelTypeInstanceVectorMap modelGroupInstanceVector_
double currTimeStep
Step error control current time step.
bool firstDependent_
True until updateDependentParameters_ is called.
Linear::Vector * numJacQVectorPtr
Linear::Vector * Qdx2VectorPtr
bool getInitialQnorm(std::vector< TimeIntg::TwoLevelError > &tleVec)
void getLIDs(int &lpos, int &lneg, int &lbra)
Definition: N_DEV_Vsrc.h:160
Linear::Vector * flagSolVectorPtr
Linear::Vector * nextStaDerivVectorPtr
int currentOrder
Time integrator order.