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