Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_DEV_DeviceMgr.h
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2 // Copyright Notice
3 //
4 // Copyright 2002 Sandia Corporation. Under the terms
5 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
6 // Government retains certain rights in this software.
7 //
8 // Xyce(TM) Parallel Electrical Simulator
9 // Copyright (C) 2002-2014 Sandia Corporation
10 //
11 // This program is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation, either version 3 of the License, or
14 // (at your option) any later version.
15 //
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 //-----------------------------------------------------------------------------
24 
25 //-----------------------------------------------------------------------------
26 // Filename : $RCSfile: N_DEV_DeviceMgr.h,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.374.2.1 $
40 //
41 // Revision Date : $Date: 2014/08/25 20:12:49 $
42 //
43 // Current Owner : $Author: dgbaur $
44 //-----------------------------------------------------------------------------
45 
46 #ifndef Xyce_N_DEV_DeviceMgr_h
47 #define Xyce_N_DEV_DeviceMgr_h
48 
49 #include <map>
50 #include <set>
51 #include <string>
52 #include <vector>
53 
54 #include <N_DEV_fwd.h>
55 #include <N_IO_fwd.h>
56 #include <N_PDS_fwd.h>
57 #include <N_UTL_fwd.h>
58 #include <N_ANP_fwd.h>
59 #include <N_NLS_fwd.h>
60 
62 #include <N_DEV_DeviceOptions.h>
63 #include <N_DEV_ExternData.h>
64 #include <N_DEV_MatrixLoadData.h>
65 #include <N_DEV_SolverState.h>
66 #include <N_UTL_Listener.h>
67 #include <N_ANP_StepEvent.h>
68 
69 class N_LAS_Matrix;
70 class N_LAS_System;
71 class N_LAS_Vector;
73 
74 namespace Xyce {
75 namespace Device {
76 
77 //-----------------------------------------------------------------------------
78 // Class : DeviceMgr
79 // Purpose :
80 // Special Notes :
81 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
82 // Creation Date : 3/16/00
83 //-----------------------------------------------------------------------------
84 class DeviceMgr : public Util::Listener<Analysis::StepEvent>
85 {
87 
88 public:
89  typedef std::vector<Device *> DeviceVector;
90  typedef std::vector<DeviceEntity *> EntityVector;
91  typedef std::vector<DeviceInstance *> InstanceVector;
92  typedef std::vector<DeviceModel *> ModelVector;
93  typedef std::map<ModelTypeId, ModelVector> ModelTypeModelVectorMap;
94  typedef std::map<ModelTypeId, InstanceVector> ModelTypeInstanceVectorMap;
95  typedef std::map<std::string, DeviceEntity *, LessNoCase> DeviceEntityMap;
96  typedef std::map<std::string, ModelTypeId, LessNoCase> ModelTypeNameModelTypeIdMap;
97  typedef std::map<std::string, ArtificialParameters::ArtificialParameter *, LessNoCase> ArtificialParameterMap;
98 
99  static DeviceMgr * factory(IO::CmdParse & cp);
100 
101 private:
102  DeviceMgr(IO::CmdParse & cp); ///< Only the factory can create a device manager
103 
104  DeviceMgr(const DeviceMgr &); ///< No copying
105  DeviceMgr &operator=(const DeviceMgr &); ///< No assignment
106 
107 public:
108  ~DeviceMgr();
109 
110  void notify(const Analysis::StepEvent &event);
111 
112  // registration functions:
113  bool registerLinearSystem(N_LAS_System * tmp_system_ptr);
114  bool registerAnalysisManager(N_ANP_AnalysisManager * tmp_anaIntPtr);
115  bool registerOutputMgr(IO::OutputMgr * output_manager);
116  bool registerMeasureMgr(IO::Measure::Manager * measure_manager);
117  bool registerParallelMgr(N_PDS_Manager * tmp_pdsMgrPtr);
118  bool registerNonlinearSolver (Nonlinear::Manager * tmp_nlsMgrPtr);
119  bool registerICLoads( std::vector<std::pair<int,double> > * icLoads );
120  bool registerPkgOptionsMgr( IO::PkgOptionsMgr *pkgOptPtr );
121 
122  // this function is called from the output manager (through the
123  // device interface) to inform the device package of the devices for
124  // which lead currents have been requested. The device manager will
125  // take care of doing isolated F and Q loads for these devices so
126  // the lead currents can be calculated
127  bool setLeadCurrentRequests(const std::set<std::string> & deviceNames );
128 
129  // MPDE related registrations:
130  std::vector<double> getFastSourcePeriod (std::vector<std::string>& sourceNames);
131  std::vector<double> registerFastSources (std::vector<std::string> & sourceNames);
132  void deRegisterFastSources (std::vector<std::string> & sourceNames);
133  void deactivateSlowSources();
134  void activateSlowSources();
135 
136  void setMPDEFlag( bool flagVal );
137  void setBlockAnalysisFlag( bool flagVal );
138  void setFastTime( double timeVal );
139 
140  // Initialization function, to be called after all registrations are
141  // finished, and the linear system class is completely set up.
142  bool initializeAll();
143 
144  // Device accessor functions:
145 
146  bool addDeviceModel(const ModelBlock & MB);
147 
148  std::pair<ModelTypeId, ModelTypeId> getModelType(const InstanceBlock &instance_block);
149 
151 
153 
154  bool deleteDeviceInstance (const std::string & name);
155 
156  int getHomotopyBlockSize() const;
157 
158  bool output ();
159  bool finishOutput ();
160 
161  void dotOpOutput ();
162 
163  // Load functions:
164  bool setInitialGuess (N_LAS_Vector * solVectorPtr);
165  bool loadDeviceMask();
166 
167  void debugOutput1();
168  void debugOutput2();
169 
171  std::string & name,
172  std::vector<double> & dfdpVec,
173  std::vector<double> & dqdpVec,
174  std::vector<double> & dbdpVec,
175  std::vector<int> & FindicesVec,
176  std::vector<int> & QindicesVec,
177  std::vector<int> & BindicesVec);
178 
179  bool analyticSensitivitiesAvailable (std::string & name);
180  bool setParam(std::string & name, double val);
181  double getParamAndReduce(const std::string & name) const;
182  bool getParamAndReduce(const std::string & name, double & val) const;
183  double getParamNoReduce(const std::string & name) const;
184 
185  bool findParam(const std::string & name) const;
186 
187  bool updateTemperature(double val);
188 
189  bool updateSources();
190 
191  bool resetRHSLoadFlags (int index);
192 
194  {
195  return *nlsMgrPtr_;
196  }
197 
199  {
200  return linearSystemFlag_;
201  }
202 
204  {
206  }
207 
209  {
210  return solState_.PDESystemFlag;
211  }
212 
213  // setup initial conditions on devices
214  bool setICs (N_LAS_Vector * tmpSolVectorPtr,
215  N_LAS_Vector * tmpCurrSolVectorPtr,
216  N_LAS_Vector * tmpLastSolVectorPtr,
217  N_LAS_Vector * tmpStaVectorPtr,
218  N_LAS_Vector * tmpCurrStaVectorPtr,
219  N_LAS_Vector * tmpLasStaVectorPtr,
220  N_LAS_Vector * tmpStaDerivVectorPtr,
221  N_LAS_Vector * tmpStoVectorPtr,
222  N_LAS_Vector * tmpCurrStoVectorPtr,
223  N_LAS_Vector * tmpLastStoVectorPtr,
224  N_LAS_Vector * tmpQVectorPtr,
225  N_LAS_Vector * tmpFVectorPtr,
226  N_LAS_Vector * tmpBVectorPtr,
227  N_LAS_Vector * tmpdFdxdVpVectorPtr,
228  N_LAS_Vector * tmpdQdxdVpVectorPtr);
229 
230  // time integration stuff:
231  bool getBreakPoints ( std::vector<Util::BreakPoint> & breakPointTimes );
232  double getMaxTimeStepSize ();
234 
235  // two-level newton and pde-continuation
236  int enablePDEContinuation ();
237  bool disablePDEContinuation ();
238  void getNumInterfaceNodes (std::vector<int> & numInterfaceNodes);
239  bool loadCouplingRHS (int iPDEDevice, int iElectrode, N_LAS_Vector * dfdvPtr);
240  bool calcCouplingTerms (int iSubProblem, int iElectrode, const N_LAS_Vector * dxdvPtr);
241  bool raiseDebugLevel (int increment);
242 
243  bool calcPDESubProblemInfo ();
244 
245  // load functions:
246  bool loadDAEMatrices (N_LAS_Vector * tmpSolVectorPtr,
247  N_LAS_Vector * tmpStaVectorPtr,
248  N_LAS_Vector * tmpStaDerivVectorPtr,
249  N_LAS_Vector * tmpStoVectorPtr,
250  N_LAS_Matrix * tmpdQdxMatrixPtr,
251  N_LAS_Matrix * tmpdFdxMatrixPtr);
252 
253  bool loadDAEVectors (N_LAS_Vector * tmpNextSolVectorPtr,
254  N_LAS_Vector * tmpCurrSolVectorPtr,
255  N_LAS_Vector * tmpLastSolVectorPtr,
256  N_LAS_Vector * tmpNextStaVectorPtr,
257  N_LAS_Vector * tmpCurrStaVectorPtr,
258  N_LAS_Vector * tmpLastStaVectorPtr,
259  N_LAS_Vector * tmpStaDerivVectorPtr,
260  N_LAS_Vector * tmpNextStoVectorPtr,
261  N_LAS_Vector * tmpCurrStoVectorPtr,
262  N_LAS_Vector * tmpLastStoVectorPtr,
263  N_LAS_Vector * tmpStoLeadCurrQCompVectorPtr,
264  N_LAS_Vector * tmpQVectorPtr,
265  N_LAS_Vector * tmpFVectorPtr,
266  N_LAS_Vector * tmpBVectorPtr,
267  N_LAS_Vector * tmpdFdxdVpVectorPtr,
268  N_LAS_Vector * tmpdQdxdVpVectorPtr);
269 
270  bool updateState (N_LAS_Vector * nextSolVectorPtr,
271  N_LAS_Vector * currSolVectorPtr,
272  N_LAS_Vector * lastSolVectorPtr,
273  N_LAS_Vector * nextStaVectorPtr,
274  N_LAS_Vector * currStaVectorPtr,
275  N_LAS_Vector * lastStaVectorPtr,
276  N_LAS_Vector * nextStoVectorPtr,
277  N_LAS_Vector * currStoVectorPtr,
278  N_LAS_Vector * lastStoVectorPtr
279  );
280 
281  bool loadBVectorsforAC (N_LAS_Vector * bVecRealPtr,
282  N_LAS_Vector * bVecImagPtr);
283 
284  bool getBMatrixEntriesforMOR(std::vector<int>& bMatEntriesVec, std::vector<int>& bMatPosEntriesVec);
285 
286  // voltlim doesn't work with MPDE, but does work for DCOP and the
287  // various initial conditions used in MPDE. Hence the need for these
288  // functions.
289  // void setVoltageLimiterFlag ();
290  void unsetVoltageLimiterFlag ();
291 
292  void setVoltageLimiterFlag ( bool flagVal );
293 
294  void addGlobalPar(const Util::Param &);
295  const double *findGlobalPar( const std::string & parName) const;
296  double getGlobalPar( const std::string & parName ) const;
297 
298 
299  // functions related to options registration
300  bool registerOptions(const Util::OptionBlock & OB) {
301  bool result = devOptions_.registerOptions(OB);
303  return result;
304  }
305  bool registerSensParams(const Util::OptionBlock & OB);
306  bool registerTimeOptions(const Util::OptionBlock & OB){return true;}
307  bool setTranAnalysisParams(const Util::OptionBlock & OB);
308  bool setDCAnalysisParams(const Util::OptionBlock & OB);
309  bool setOPAnalysisParams(const Util::OptionBlock & OB);
310  bool setSTEPAnalysisParams(const Util::OptionBlock & OB);
311  bool setMPDEAnalysisParams(const Util::OptionBlock & OB);
312  bool setHBAnalysisParams(const Util::OptionBlock & OB);
313  bool setACAnalysisParams(const Util::OptionBlock & OB);
314  bool setMORAnalysisParams(const Util::OptionBlock & OB);
315 
316  // convergence: allow devices to signal back to the solvers that
317  // they've played some game that invalidates normal convergence tests,
318  // and so the solution should be considered unconverged no matter how
319  // small the various norms are.
320  bool allDevsConverged();
321 
322  // Similar to allDevsConverged, but specific to "inner" devices of
323  // 2-level solves. They are handled slightly differently.
324  bool innerDevsConverged();
325 
326  // Functions needed for power node (2-level) algorithm):
327 
328  // for the parallel case, we need to give all the processors a copy
329  // of the device so all the parallel synchronized calls such are
330  // called by all processors together.
331  bool setupExternalDevices();
332 
333  const std::map<std::string,int> &getDeviceCountMap() {
334  return localDeviceCountMap_;
335  }
336 
337  void addDeviceToCount(const std::string & device_name, int num_devs = 1)
338  {
339  localDeviceCountMap_[device_name] += num_devs;
340  }
341 
342  void addDevicesToCount(const std::map<std::string,int> & device_map);
343 
344  DeviceEntity *getDeviceEntity(const std::string &full_param_name) const;
345 
346  void homotopyStepSuccess(const std::vector<std::string> & paramNames, const std::vector<double> & paramVals);
347  void homotopyStepFailure ();
348 
349  void stepSuccess(Analysis::CurrentMode analysis);
350  void stepFailure(Analysis::CurrentMode analysis);
351 
352  void acceptStep();
353 
354  bool getInitialQnorm (std::vector<N_TIA_TwoLevelError> & tleVec );
355  bool getInnerLoopErrorSums (std::vector<N_TIA_TwoLevelError> & tleVec);
356 
357  bool updateStateArrays();
358  bool startTimeStep ();
359  void setExternalSolverState (const SolverState & ss);
360 
361  int restartDataSize(bool pack);
362 
363  // Output restart data.
364  bool dumpRestartData(char * buf, int bsize, int & pos, N_PDS_Comm * comm, bool pack );
365 
366  // Load restart data.
367  bool restoreRestartData(char * buf, int bsize, int & pos, N_PDS_Comm * comm, bool pack );
368 
369  // needed for parallel only:
370  void setGlobalFlags ();
371 
373  {
374  return setupSolverInfo_();
375  }
376 
377  Device *getDevice(EntityTypeId model_type_id)
378  {
379  EntityTypeIdDeviceMap::iterator it = deviceMap_.find(model_type_id);
380  return it == deviceMap_.end() ? 0 : (*it).second;
381  }
382 
383  EntityTypeId getModelGroup(const std::string &model_or_device_type_name);
384 
385  void addArtificialParameter(const std::string &name, ArtificialParameters::ArtificialParameter *artificial_parameter) {
386  artificialParameterMap_[name] = artificial_parameter;
387  passThroughParamsMap_[name] = 1;
388  }
389 
390 private:
391  bool getParam(const std::string &name, double &value) const;
392  Device &getDeviceByModelType(const EntityTypeId model_type);
393 
394  bool setupSolverInfo_ ();
395  bool setupRawVectorPointers_ ();
396  bool setupRawMatrixPointers_ ();
397 
399  bool updatePrimaryState_();
400  bool updateSecondaryState_();
401 
403 
404  // Do the actual solve/calculation for the external devices
405  void updateExternalDevices_();
406 
407  // add external devices for processors that don't own it
408  ExternDevice::Instance * addExtDeviceInstance_(const InstanceBlock & IB);
409 
410 private:
411  IO::CmdParse & commandLine_; ///< Command line
412  DeviceOptions devOptions_; ///< user-defined options:
414 
415  bool sensFlag_; ///< .SENS present in netlist
416  bool linearSystemFlag_; ///< True if all devices in netlist have isLinearDevice() true
417  bool firstDependent_; ///< True until updateDependentParameters_ is called.
418  bool parameterChanged_; ///< Only used locally in updateDependentParameters_, don't know if stateful of just a member for fun
420  double timeParamsProcessed_; ///< Time updateDependentParameters was called
421 
423  MatrixLoadData matrixLoadData_; ///< temporary jacobian load structures:
424  SolverState solState_; ///< real time solver data:
425  Globals & globals_; ///< global variables
428 
429  N_LAS_Vector * numJacSolVectorPtr_;
430  N_LAS_Vector * numJacStaVectorPtr_;
431  N_LAS_Vector * numJacStoVectorPtr_;
432  N_LAS_Vector * diagonalVectorPtr_;
433  N_LAS_System * lasSysPtr_;
435  IO::OutputMgr * outputMgrPtr_;
436  IO::Measure::Manager * measureManager_;
437  N_PDS_Manager * pdsMgrPtr_;
439  IO::PkgOptionsMgr * pkgOptMgrPtr_;
440  std::vector<std::pair<int, double> > * icLoads_;
441 
442  ModelTypeNameModelTypeIdMap modelTypeMap_; ///< Model type name to model
443  ModelTypeNameModelTypeIdMap modelGroupMap_; ///< Model type name to model group
444 
445  std::map<std::string, int> localDeviceCountMap_;
446  std::multimap<int, DeviceInstance *> solDevInstMap_;
447 
450 
452  InstanceVector bpInstancePtrVec_; ///< instances with breakpoints functions
456 
459 
460  std::vector<SourceInstance *> indepSourceInstancePtrVec_;
461  std::map<std::string, SourceInstance *, LessNoCase> indepSourcePtrMap_;
462  // this is used to store the contents of the indepSourceInstancePtrVec_
463  // during an mpde initialization where we'll remove slow sources from
464  // the that vector so that they don't get updated
465  std::vector<SourceInstance *> indepSourceInstanceBackupPtrVec_;
466 
467  std::set<std::string> devicesNeedingLeadCurrentLoads_;
468 
469  std::map<std::string, int, LessNoCase> passThroughParamsMap_;
470 
471  mutable DeviceEntityMap parameterDeviceCache_; ///< Full parameter name to device entity cache
472 
473  // vector of pointers to devices under test.
475 
479 
481 
482  std::vector<int> numInterfaceNodes_;
484 
485  // sensitivities:
487 
488  // MPDE fast source list
489  std::vector<std::string> fastSourceNames_;
490 
491  // Device mask flag:
493 
494  // .OP output flags.
496 
497  // solution variable names vector:
498  std::vector<std::string> nameVec_;
499 
501 };
502 
503 //-----------------------------------------------------------------------------
504 // Function : DeviceMgr::registerLinearSystem
505 // Purpose :
506 // Special Notes :
507 // Scope : public
508 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
509 // Creation Date : 4/13/00
510 //-----------------------------------------------------------------------------
511 inline bool DeviceMgr::registerLinearSystem (N_LAS_System * tmp_system_ptr)
512 {
513  lasSysPtr_ = tmp_system_ptr;
514 
515  if (lasSysPtr_ != 0) return true;
516  else return false;
517 }
518 
519 //-----------------------------------------------------------------------------
520 // Function : DeviceMgr::registerParallelMgr
521 // Purpose :
522 // Special Notes :
523 // Scope : public
524 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
525 // Creation Date : 6/29/01
526 //-----------------------------------------------------------------------------
527 inline bool DeviceMgr::registerParallelMgr (N_PDS_Manager * tmp_pdsMgrPtr )
528 {
529  pdsMgrPtr_ = tmp_pdsMgrPtr;
530 
531  return pdsMgrPtr_ != 0;
532 }
533 
534 //-----------------------------------------------------------------------------
535 // Function : DeviceMgr::registerNonlinearSolver
536 // Purpose :
537 // Special Notes :
538 // Scope : public
539 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
540 // Creation Date : 2/23/01
541 //-----------------------------------------------------------------------------
543 {
544  nlsMgrPtr_ = tmp_nlsMgrPtr;
545 
546  if (nlsMgrPtr_ != 0) return true;
547  else return false;
548 }
549 
550 //-----------------------------------------------------------------------------
551 // Function : DeviceMgr::setVoltageLimiterFlag ()
552 // Purpose :
553 // Special Notes :
554 // Scope : public
555 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
556 // Creation Date : 04/09/04
557 //-----------------------------------------------------------------------------
558 //inline void DeviceMgr::setVoltageLimiterFlag ()
559 //{
560 // devOptions_.voltageLimiterFlag = true;
561 //}
562 
563 //-----------------------------------------------------------------------------
564 // Function : DeviceMgr::unsetVoltageLimiterFlag ()
565 // Purpose :
566 // Special Notes :
567 // Scope : public
568 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
569 // Creation Date : 04/09/04
570 //-----------------------------------------------------------------------------
572 {
574 }
575 
576 //-----------------------------------------------------------------------------
577 // Function : DeviceMgr::setVoltageLimiterFlag ()
578 // Purpose :
579 // Special Notes :
580 // Scope : public
581 // Creator : Ting Mei, SNL
582 // Creation Date : 02/18/14
583 //-----------------------------------------------------------------------------
584 inline void DeviceMgr::setVoltageLimiterFlag ( bool flagVal )
585 {
587 }
588 
589 //-----------------------------------------------------------------------------
590 // Function : DeviceMgr::registerICLoads
591 // Purpose :
592 // Special Notes :
593 // Scope : public
594 // Creator : Robert Hoekstra, SNL, Computational Sciences
595 // Creation Date : 04/03/01
596 //-----------------------------------------------------------------------------
597 inline bool DeviceMgr::registerICLoads( std::vector< std::pair<int,double> > * icLoads )
598 {
599  return (icLoads_ = icLoads) != 0;
600 }
601 
602 } // namespace Device
603 } // namespace Xyce
604 
606 
607 #endif // Xyce_N_DEV_DeviceMgr_h