Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_DEV_ADC.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-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_ADC.C,v $
27 //
28 // Purpose : This file implements the ADC digital to analog conversion
29 // device used in the integration of Xyce withe SAVANT VHDL
30 // simulator.
31 //
32 // Special Notes : The ADC looks to the analog simulation like a resistor.
33 //
34 // Creator : Lon Waters
35 //
36 // Creation Date : 07/26/2002
37 //
38 // Revision Information:
39 // ---------------------
40 //
41 // Revision Number: $Revsion$
42 //
43 // Revsion Date : $Date: 2014/02/25 22:30:30 $
44 //
45 // Current Owner : $Author: dgbaur $
46 //----------------------------------------------------------------------------
47 
48 #include <Xyce_config.h>
49 
50 
51 // ---------- Standard Includes ----------
52 #include <N_UTL_Misc.h>
53 
54 #ifdef HAVE_CSTDIO
55 #include <cstdio>
56 #else
57 #include <stdio.h>
58 #endif
59 
60 #ifdef HAVE_CMATH
61 #include <cmath>
62 #else
63 #include <math.h>
64 #endif
65 
66 #include <algorithm>
67 
68 // ---------- Xyce Includes ----------
69 #include <N_DEV_ADC.h>
70 #include <N_DEV_DeviceOptions.h>
71 #include <N_DEV_DeviceState.h>
72 #include <N_DEV_ExternData.h>
73 #include <N_DEV_MatrixLoadData.h>
74 #include <N_DEV_SolverState.h>
75 #include <N_DEV_Message.h>
76 
77 #include <N_LAS_Vector.h>
78 #include <N_LAS_Matrix.h>
79 
80 namespace Xyce {
81 namespace Device {
82 
83 
84 namespace ADC {
85 
86 
88 {
89  p.addPar ("R", 1.e+12, &ADC::Instance::R)
90  .setUnit(U_OHM)
91  .setDescription("internal Resistance");
92 }
93 
95 {
96  p.addPar ("LOWERVOLTAGELIMIT", 0.0, &ADC::Model::lowerVoltageLimit_)
97  .setUnit(U_VOLT)
98  .setDescription("Lower limit of ADC voltage range");
99 
100  p.addPar ("UPPERVOLTAGELIMIT", 5.0, &ADC::Model::upperVoltageLimit_)
101  .setUnit(U_VOLT)
102  .setDescription("Upper limit of ADC voltage range");
103 
104  p.addPar ("SETTLINGTIME", 1.0e-8, &ADC::Model::settlingTime_)
105  .setUnit(U_SECOND)
106  .setDescription("Settling time");
107 }
108 
109 
110 
111 std::vector< std::vector<int> > Instance::jacStamp;
112 
113 //----------------------------------------------------------------------------
114 // Function : Instance::processParams
115 // Purpose :
116 // Special Notes :
117 // Scope : public
118 // Creator : Lon Waters
119 // Creation Date : 07/29/2002
120 //----------------------------------------------------------------------------
122 {
123 
124  return true;
125 }
126 
127 //----------------------------------------------------------------------------
128 // Function : Instance::Instance
129 // Purpose : constructor
130 // Special Notes :
131 // Scope : public
132 // Creator : Lon Waters
133 // Creation Date : 07/29/2002
134 //----------------------------------------------------------------------------
136  const Configuration & configuration,
137  const InstanceBlock & IB,
138  Model & ADCiter,
139  const FactoryBlock & factory_block)
140  : DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
141  R(1.0e12),
142  G(0.0),
143  v_pos(0.0),
144  v_neg(0.0),
145  i0(0.0),
146  outputBitVectorWidth_(1),
147  nQuantLevels_(0),
148  lastOutputLevel_(0),
149  model_(ADCiter),
150  li_Pos(-1),
151  li_Neg(-1),
152  APosEquPosNodeOffset(-1),
153  APosEquNegNodeOffset(-1),
154  ANegEquPosNodeOffset(-1),
155  ANegEquNegNodeOffset(-1)
156 {
157  numIntVars = 0;
158  numExtVars = 2;
159  numStateVars = 0;
160 
161  if( jacStamp.empty() )
162  {
163  jacStamp.resize(2);
164  jacStamp[0].resize(2);
165  jacStamp[1].resize(2);
166  jacStamp[0][0] = 0;
167  jacStamp[0][1] = 1;
168  jacStamp[1][0] = 0;
169  jacStamp[1][1] = 1;
170  }
171 
172 
173  // Set params to constant default values:
174  setDefaultParams ();
175 
176  // Set params according to instance line and constant defaults from metadata:
177  setParams (IB.params);
178 
179  // Set any non-constant parameter defaults:
180 
181  // Calculate any parameters specified as expressions:
182 
184 
185  // calculate dependent (ie computed) params and check for errors:
186 
187  if (R != 0.0) G = 1.0/R;
188  else G = 0.0;
189 
190  processParams ();
191 }
192 
193 //----------------------------------------------------------------------------
194 // Function : Instance::~Instance
195 // Purpose :
196 // Special Notes :
197 // Scope : public
198 // Creator : Lon Waters
199 // Creation Date : 07/29/2002
200 //----------------------------------------------------------------------------
202 {
203 }
204 
205 //----------------------------------------------------------------------------
206 // Function : Instance::registerLIDs
207 // Purpose :
208 // Special Notes :
209 // Scope : public
210 // Creator : Lon Waters
211 // Creation Date : 07/29/2002
212 //----------------------------------------------------------------------------
213 void Instance::registerLIDs( const std::vector<int> & intLIDVecRef,
214  const std::vector<int> & extLIDVecRef)
215 {
216  AssertLIDs(intLIDVecRef.size() == numIntVars);
217  AssertLIDs(extLIDVecRef.size() == numExtVars);
218 
219  if (DEBUG_DEVICE && getDeviceOptions().debugLevel > 0 )
220  {
221  Xyce::dout() << std::endl << section_divider << std::endl;
222  Xyce::dout() << " ADCInstance::registerLIDs" << std::endl;
223  Xyce::dout() << " name = " << getName() << std::endl;
224  }
225 
226  // copy over the global ID lists.
227  intLIDVec = intLIDVecRef;
228  extLIDVec = extLIDVecRef;
229 
230  // Now use these lists to obtain the indices into the
231  // linear algebra entities. This assumes an order.
232  // For the matrix indices, first do the rows.
233 
234  li_Pos = extLIDVec[0];
235 
236  if (DEBUG_DEVICE && getDeviceOptions().debugLevel > 0 )
237  Xyce::dout() << " li_Pos = " << li_Pos << std::endl;
238 
239  li_Neg = extLIDVec[1];
240 
241  if (DEBUG_DEVICE && getDeviceOptions().debugLevel > 0 )
242  Xyce::dout() << " li_Neg = " << li_Neg << std::endl;
243 
244  if (DEBUG_DEVICE && getDeviceOptions().debugLevel > 0 )
245  Xyce::dout() << section_divider << std::endl;
246 }
247 
248 //----------------------------------------------------------------------------
249 // Function : Instance::registerStateLIDs
250 // Purpose :
251 // Special Notes :
252 // Scope : public
253 // Creator : Lon Waters
254 // Creation Date : 07/29/2002
255 //----------------------------------------------------------------------------
256 void Instance::registerStateLIDs( const std::vector<int> & staLIDVecRef)
257 {
258  AssertLIDs(staLIDVecRef.size() == numStateVars);
259 }
260 
261 //----------------------------------------------------------------------------
262 // Function : jacobianStamp
263 // Purpose :
264 // Special Notes :
265 // Scope : public
266 // Creator : Lon Waters
267 // Creation Date : 11/12/2002
268 //----------------------------------------------------------------------------
269 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
270 {
271  return jacStamp;
272 }
273 
274 //----------------------------------------------------------------------------
275 // Function : registerJacLIDs
276 // Purpose :
277 // Special Notes :
278 // Scope : public
279 // Creator : Lon Waters
280 // Creation Date : 11/12/2002
281 //----------------------------------------------------------------------------
282 void Instance::registerJacLIDs(const std::vector< std::vector<int> >& jacLIDVec)
283 {
284  APosEquPosNodeOffset = jacLIDVec[0][0];
285  APosEquNegNodeOffset = jacLIDVec[0][1];
286  ANegEquPosNodeOffset = jacLIDVec[1][0];
287  ANegEquNegNodeOffset = jacLIDVec[1][1];
288 }
289 
290 //----------------------------------------------------------------------------
291 // Function : Instance::updatePrimaryState
292 // Purpose :
293 // Special Notes :
294 // Scope : public
295 // Creator : Richard Schiek, 1437, Electrical and Microsystem Sim.
296 // Creation Date : 02/19/08
297 //----------------------------------------------------------------------------
299 {
300  bool bsuccess = true;
301  double * solVector = extData.nextSolVectorRawPtr;
302 
303  v_pos = solVector[li_Pos];
304  v_neg = solVector[li_Neg];
305  i0 = (v_pos-v_neg)*G;
306 
307  return bsuccess;
308 }
309 
310 //----------------------------------------------------------------------------
311 // Function : Instance::updatePrimaryState
312 // Purpose :
313 // Special Notes :
314 // Scope : public
315 // Creator : Lon Waters
316 // Creation Date : 07/29/2002
317 //----------------------------------------------------------------------------
319 {
320  return updateIntermediateVars ();
321 }
322 
323 //----------------------------------------------------------------------------
324 // Function : Instance::updateSecondaryState
325 // Purpose :
326 // Special Notes :
327 // Scope : public
328 // Creator : Lon Waters
329 // Creation Date : 07/29/2002
330 //----------------------------------------------------------------------------
332 {
333  // There is no secondary state
334  return true;
335 }
336 
337 //----------------------------------------------------------------------------
338 // Function : Instance::getTVVec
339 // Purpose :
340 // Special Notes :
341 // Scope :
342 // Creator : Lon Waters
343 // Creation Date : 08/28/2003
344 //----------------------------------------------------------------------------
345 void Instance::getTVVEC(std::vector< std::pair<double, double> > & TVVEC_Out)
346 {
347  TVVEC_Out.clear();
348 
349  TVVEC_Out.insert(TVVEC_Out.end(), TVVEC.begin(), TVVEC.end());
350 
351  // Now that the digital simulator knows about these, let's forget them
352  // and not worry about maintaining the list anymore
353  TVVEC.clear();
354 }
355 
356 
357 //----------------------------------------------------------------------------
358 // Function : Instance::trimTVVEC
359 // Purpose : clear out old time-voltage pairs
360 // Special Notes : ASSUMES the vector of t-v pairs is sorted by time!
361 // Scope : public
362 // Creator : Tom Russo, SNL, Component Information and Models
363 // Creation Date : 05/10/2004
364 //----------------------------------------------------------------------------
365 void Instance::trimTVVEC(double earliestTime)
366 {
367  std::vector< std::pair<double,double> >::iterator itVec;
368 
369  // get reference pointing to first element that exceeds earliestTime
370  itVec = lower_bound(TVVEC.begin(),TVVEC.end(),std::pair<double,double>(earliestTime,0.0));
371  // delete everything prior to that.
372  TVVEC.erase(TVVEC.begin(),itVec);
373 }
374 
375 //-----------------------------------------------------------------------------
376 // Function : Instance::loadDAEFVector
377 //
378 // Purpose : Loads the F-vector contributions for this device which
379 // effectively is a single instance.
380 //
381 // Special Notes :
382 //
383 // Scope : public
384 // Creator : Richard Schiek, 1437, Electrical and Microsystem Sim.
385 // Creation Date : 02/19/08
386 //-----------------------------------------------------------------------------
388 {
389  bool bsuccess = true;
390 
391  double * daeFVec = extData.daeFVectorRawPtr;
392 
393  // Load DAE F-vector
394 
395  daeFVec[li_Pos] += i0;
396 
397  daeFVec[li_Neg] += -i0;
398 
399  return bsuccess;
400 }
401 
402 //-----------------------------------------------------------------------------
403 // Function : Instance::loadDAEdFdx ()
404 //
405 // Purpose : Loads the F-vector contributions for this device which
406 // effectively is a single instance.
407 //
408 // Special Notes :
409 //
410 // Scope : public
411 // Creator : Richard Schiek, 1437, Electrical and Microsystem Sim.
412 // Creation Date : 02/19/08
413 //-----------------------------------------------------------------------------
415 {
416  bool bsuccess = true;
417 
418  N_LAS_Matrix * dFdxMatPtr = extData.dFdxMatrixPtr;
419 
420  if (DEBUG_DEVICE && getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
421  {
422  Xyce::dout() << subsection_divider <<std::endl;
423  Xyce::dout() << " name = " << getName() << std::endl;
424  Xyce::dout() << " G = " << G << std::endl;
425  }
426 
427  (*dFdxMatPtr)[li_Pos][APosEquPosNodeOffset] += G;
428 
429  (*dFdxMatPtr)[li_Pos][APosEquNegNodeOffset] -= G;
430 
431  (*dFdxMatPtr)[li_Neg][ANegEquPosNodeOffset] -= G;
432 
433  (*dFdxMatPtr)[li_Neg][ANegEquNegNodeOffset] += G;
434 
435  return bsuccess;
436 }
437 
438 //-----------------------------------------------------------------------------
439 // Function : Instance::getBreakPoints
440 // Purpose :
441 // Special Notes :
442 // Scope : public
443 // Creator : Tom Russo, SNL, Component Information and Models
444 // Creation Date : 05/06/04
445 //-----------------------------------------------------------------------------
446 
447 bool Instance::getInstanceBreakPoints ( std::vector<N_UTL_BreakPoint> & breakPointTimes)
448 {
449  bool bsuccess = true;
450 
451  // getBreakPoints is called after a timesteps solution is converged and
452  // the step is finished. So we can count on our voltage being the real one
453  // that is valid for this time.
454 
455  // In this routine we need to check our current voltage value and see if it
456  // has changed enough since our last time step to change a bit in the digital
457  // output. If so, we need to set a time/voltage pair of the current value
458  // and (the current time + this device's conversion time), then set a
459  // breakpoint of type PAUSE_BREAKPOINT for the that time
460 
461  double vPos(0.0);
462  double vNeg(0.0);
463  double deltaV(0.0), vFrac(0.0);
464  double currentTime = getSolverState().currTime;
465  int newState;
466 
467  // Get the pointer to the vector of accepted solution values
468  double * solVector = extData.nextSolVectorRawPtr;
469 
470  vPos = solVector[li_Pos];
471  vNeg = solVector[li_Neg];
472 
473  deltaV = vPos-vNeg;
474 
475  // This "upper voltage limit" and "lower voltage limit" crap is not right,
476  // and needs to be replaced with a "Vref+" node against which
477  // Vin is compared, with a common negative reference (e.g. ground)
478  // For now, let's always just document this failing, and tell the users
479  // to wire vNeg to ground, and use 0.0 as the
480  // lower limit. Worry about doing it right later.
481  vFrac = deltaV/(model_.upperVoltageLimit_
483 
484 #if 1
485  // I believe this is how it SHOULD be done
486  if (vFrac < (1.0)/(nQuantLevels_) )
487  {
488  newState = 0;
489  }
490  else if (vFrac >= (nQuantLevels_-1.0)/(nQuantLevels_))
491  {
492  newState = nQuantLevels_ -1;
493  }
494  else
495  {
496  newState = int(vFrac*nQuantLevels_);
497  }
498 #else
499  // but this is how simbus is doing it:
500  newState = int(vFrac*(nQuantLevels_-1));
501 #endif
502 
503  if (DEBUG_DEVICE && getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
504  {
505  Xyce::dout() << "In Instance::getInstanceBreakPoints. deltaV = " << deltaV
506  << " and output state is " << newState
507  << " vFrac = " << vFrac << " nQuantLevels = " << nQuantLevels_ << std::endl;
508  }
509 
510  if (newState != lastOutputLevel_)
511  {
512  // get time rounded to nearest femptosecond
513  long long int timeInFS =static_cast<long long int>(
514  (currentTime+model_.settlingTime_+6e-16)/1e-15);
515 
516  // we need to pause
517 #ifdef Xyce_OLD_PRE_ROLLBACK
518  breakPointTimes.push_back( Util::BreakPoint(timeInFS*1e-15,PAUSE_BREAKPOINT));
519 #else
520 
521  // See bug # 1720 on charleston bugzilla. This breakpoint pushback is being
522  // commented out to fix this bug.
523  //
524  // However, this should not be a long-term fix!
525 
526 #endif
527 
528  // since time is always advancing, we can simply push_back the pair,
529  // and always be sure
530  TVVEC.push_back(std::pair<double,double>(timeInFS*1e-15,deltaV));
531  lastOutputLevel_ = newState;
532 
533  if (DEBUG_DEVICE && getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
534  {
535  Xyce::dout() << "ADC ----------------------------------------" << std::endl;
536  Xyce::dout() << "ADC Debug output. name = " << getName() << std::endl;
537  Xyce::dout() << "ADC setting pause breakpoint for " << currentTime << std::endl;
538  double approxTime = timeInFS*1e-15;
539  Xyce::dout() << "ADC Approximated time, to nearest femptosecond: " << approxTime << std::endl;
540  Xyce::dout() << "ADC Time value pairs: " << std::endl;
541 
542  std::vector< std::pair<double, double> >::iterator beg = TVVEC.begin();
543  std::vector< std::pair<double, double> >::iterator end = TVVEC.end();
544  std::vector< std::pair<double, double> >::iterator itTV = beg;
545 
546  for (; itTV!=end; ++itTV)
547  {
548  std::pair<double, double> & tvPair = *itTV;
549  Xyce::dout() << "ADC time: " << tvPair.first << " value: " << tvPair.second << std::endl;
550  }
551 
552  Xyce::dout() << "ADC ----------------------------------------" << std::endl;
553  }
554  }
555 
556  return bsuccess;
557 }
558 
559 //-----------------------------------------------------------------------------
560 // Function : Instance::acceptStep
561 // Purpose :
562 // Special Notes :
563 // Scope : public
564 // Creator : Eric Keiter, SNL
565 // Creation Date : 12/05/08
566 //-----------------------------------------------------------------------------
568 {
569  double vPos(0.0), vNeg(0.0), deltaV(0.0), vFrac(0.0);
570  double currentTime = getSolverState().currTime;
571 
572  if (getSolverState().dcopFlag)
573  {
574  double * solVector = extData.nextSolVectorRawPtr;
575 
576  vPos = solVector[li_Pos];
577  vNeg = solVector[li_Neg];
578  deltaV = vPos-vNeg;
579 
580  TVVEC.push_back(std::pair<double,double>(0.0,deltaV));
581  }
582 
583 }
584 
585 //----------------------------------------------------------------------------
586 // Function : Model::processParams
587 // Purpose :
588 // Special Notes :
589 // Scope : public
590 // Creator : Lon Waters
591 // Creation Date : 07/29/2002
592 //----------------------------------------------------------------------------
594 {
595  return true;
596 }
597 
598 //----------------------------------------------------------------------------
599 // Function : Model::processInstanceParams
600 // Purpose :
601 // Special Notes :
602 // Scope : public
603 // Creator : Dave Shirely, PSSI
604 // Creation Date : 03/23/06
605 //----------------------------------------------------------------------------
607 {
608  std::vector<Instance*>::iterator iter;
609  std::vector<Instance*>::iterator first = instanceContainer.begin();
610  std::vector<Instance*>::iterator last = instanceContainer.end();
611 
612  for (iter=first; iter!=last; ++iter)
613  {
614  (*iter)->processParams();
615  }
616 
617  return true;
618 }
619 
620 //----------------------------------------------------------------------------
621 // Function : Instance::getInstanceParamsMap
622 // Purpose : Return a map of name,parameter for this instance
623 // Special Notes : used by API for mixed signal
624 // in zero order version, these parameters happen to be
625 // model parameters, but that is not necessarily where they'll
626 // stay (the voltage limits, for example, should actually be
627 // taken from the nodal voltages of the reference nodes of the
628 // device instance)
629 // Scope : public
630 // Creator : Tom Russo, SNL, Component Information and Models
631 // Creation Date : 05/07/2004
632 //----------------------------------------------------------------------------
633 bool Instance::getInstanceParamsMap(std::map<std::string,double>& paramsMap)
634 {
635  paramsMap.clear();
636 
637  paramsMap["lowerVoltageLimit"] = model_.lowerVoltageLimit_;
638  paramsMap["upperVoltageLimit"] = model_.upperVoltageLimit_;
639  paramsMap["settlingTime"] = model_.settlingTime_;
640 
641  return true;
642 }
643 
644 //----------------------------------------------------------------------------
645 // Function : Instance::setBitVectorWidth
646 // Purpose : set the number of bits in the output of this ADC
647 // Special Notes :
648 // Scope : public
649 // Creator : Tom Russo
650 // Creation Date : 05/07/2004
651 //----------------------------------------------------------------------------
653 {
654  outputBitVectorWidth_ = width;
655  nQuantLevels_ = 1;
656  for (int i=0; i<width;++i)
657  nQuantLevels_ *= 2;
658 
659  if (DEBUG_DEVICE && getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
660  {
661  Xyce::dout() << "Instance::setBitVectorWidth name = "
662  << getName() << " width = " << width
663  << " nQuantLevels_ = " << nQuantLevels_ << std::endl;
664  }
665 
666  return true;
667 }
668 //----------------------------------------------------------------------------
669 // Function : Model::Model
670 // Purpose : constructor
671 // Special Notes :
672 // Scope : public
673 // Creator : Lon Waters
674 // Creation Date : 07/29/2002
675 //----------------------------------------------------------------------------
677  const Configuration & configuration,
678  const ModelBlock& MB,
679  const FactoryBlock & factory_block)
680  : DeviceModel(MB, configuration.getModelParameters(), factory_block),
681  lowerVoltageLimit_(0.0),
682  upperVoltageLimit_(5.0),
683  settlingTime_(1e-8)
684 
685 {
686 
687  // Set params to constant default values:
688  setDefaultParams ();
689 
690  // Set params according to .model line and constant defaults from metadata:
691  setModParams (MB.params);
692 
693  // Set any non-constant parameter defaults:
694 
695  // Calculate any parameters specified as expressions:
697 
698  // calculate dependent (ie computed) params and check for errors:
699  processParams ();
700 }
701 
702 //----------------------------------------------------------------------------
703 // Function : Model::Model
704 // Purpose : destructor
705 // Special Notes :
706 // Scope : public
707 // Creator : Lon Waters
708 // Creation Date : 07/29/2002
709 //----------------------------------------------------------------------------
711 {
712  std::vector<Instance*>::iterator iter;
713  std::vector<Instance*>::iterator first = instanceContainer.begin();
714  std::vector<Instance*>::iterator last = instanceContainer.end();
715 
716  for (iter=first; iter!=last; ++iter)
717  {
718  delete (*iter);
719  }
720 }
721 
722 //----------------------------------------------------------------------------
723 // Function : printOutInstances
724 // Purpose : debugging tool
725 // Special Notes :
726 // Scope : public
727 // Creator : Lon Waters
728 // Creation Date : 07/29/2002
729 //----------------------------------------------------------------------------
730 std::ostream &Model::printOutInstances(std::ostream &os) const
731 {
732  std::vector<Instance*>::const_iterator iter;
733  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
734  std::vector<Instance*>::const_iterator last = instanceContainer.end();
735 
736  int i;
737  os << std::endl;
738  os << " name\t\tmodelName\tParameters" << std::endl;
739 
740  for (i = 0, iter = first; iter != last; ++iter, ++i)
741  {
742  os << " " << i << ": " << (*iter)->getName() << "\t";
743  os << getName();
744  os << std::endl;
745  }
746 
747  os << std::endl;
748 
749  return os;
750 }
751 
752 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */ {
753  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
754  op(*it);
755 }
756 
757 
758 // ADC Master functions:
759 
760 //-----------------------------------------------------------------------------
761 // Function : Master::updateState
762 // Purpose :
763 // Special Notes :
764 // Scope : public
765 // Creator : Richard Schiek, Electrical and Microsystems Modeling
766 // Creation Date : 02/25/2009
767 //-----------------------------------------------------------------------------
768 bool Master::updateState (double * solVec, double * staVec, double * stoVec)
769 {
770  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
771  {
772  Instance & di = *(*it);
773 
774  di.v_pos = solVec[di.li_Pos];
775  di.v_neg = solVec[di.li_Neg];
776  di.i0 = (di.v_pos-di.v_neg)*di.G;
777  }
778 
779  return true;
780 }
781 
782 //-----------------------------------------------------------------------------
783 // Function : Master::updateSecondaryState
784 // Purpose :
785 // Special Notes :
786 // Scope : public
787 // Creator : Richard Schiek, Electrical and Microsystems Modeling
788 // Creation Date : 02/25/2009
789 //-----------------------------------------------------------------------------
790 bool Master::updateSecondaryState ( double * staDerivVec, double * stoVec )
791 {
792  return true;
793 }
794 
795 //-----------------------------------------------------------------------------
796 // Function : Master::loadDAEVectors
797 // Purpose :
798 // Special Notes :
799 // Scope : public
800 // Creator : Richard Schiek, Electrical and Microsystems Modeling
801 // Creation Date : 02/25/2009
802 //-----------------------------------------------------------------------------
803 bool Master::loadDAEVectors (double * solVec, double * fVec, double *qVec, double * storeLeadF, double * storeLeadQ)
804 {
805  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
806  {
807  Instance & di = *(*it);
808 
809  fVec[di.li_Pos] += di.i0;
810 
811  fVec[di.li_Neg] += -di.i0;
812  }
813 
814  return true;
815 }
816 
817 //-----------------------------------------------------------------------------
818 // Function : Master::loadDAEMatrices
819 // Purpose :
820 // Special Notes :
821 // Scope : public
822 // Creator : Richard Schiek, Electrical and Microsystems Modeling
823 // Creation Date : 02/25/2009
824 //-----------------------------------------------------------------------------
825 bool Master::loadDAEMatrices (N_LAS_Matrix & dFdx, N_LAS_Matrix & dQdx)
826 {
827  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
828  {
829  Instance & di = *(*it);
830 
831  dFdx[di.li_Pos][di.APosEquPosNodeOffset] += di.G;
832 
833  dFdx[di.li_Pos][di.APosEquNegNodeOffset] -= di.G;
834 
835  dFdx[di.li_Neg][di.ANegEquPosNodeOffset] -= di.G;
836 
837  dFdx[di.li_Neg][di.ANegEquNegNodeOffset] += di.G;
838  }
839  return true;
840 }
841 
842 //-----------------------------------------------------------------------------
843 // Function : ::getADCMap
844 // Purpose : Get a list of names of all ADCs in the circuit
845 // Special Notes : We assume the map we're given is cleared already
846 // Scope : public
847 // Creator : Richard Schiek, Electrical and Microsystems Modeling
848 // Creation Date : 02/25/2009
849 //-----------------------------------------------------------------------------
850 bool Master::getADCMap( std::map<std::string, std::map<std::string,double> > & ADCMap )
851 {
852  bool bSuccess = true;
853  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
854  {
855  Instance & di = *(*it);
856  std::string adcName(di.getName());
857 
858  std::map<std::string,double> TmpMap;
859  di.getInstanceParamsMap(TmpMap);
860  ADCMap[adcName] = TmpMap;
861  }
862  return bSuccess;
863 }
864 
865 //-----------------------------------------------------------------------------
866 // Function : ::getTimeVoltagePairs
867 // Purpose : Get time/voltage pairs for all ADCs in the circuit
868 // Special Notes : We assume the map we're given is cleared already
869 // Scope : public
870 // Creator : Richard Schiek, Electrical and Microsystems Modeling
871 // Creation Date : 02/25/2009
872 //-----------------------------------------------------------------------------
873 bool Master::getTimeVoltagePairs( std::map<std::string, std::vector< std::pair<double,double> > >& TimeVoltageMap )
874 {
875  bool bSuccess = true;
876  double vPos, vNeg;
877 
878  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
879  {
880  Instance & di = *(*it);
881  std::string adcName(di.getName());
882 
883  std::vector<std::pair <double,double> > TmpVec;
884  di.getTVVEC(TmpVec);
885  double currentTime = getSolverState().currTime;
886  double * solVector = di.extData.nextSolVectorRawPtr;
887 
888  vPos = solVector[di.li_Pos];
889  vNeg = solVector[di.li_Neg];
890  TmpVec.push_back(std::pair<double,double>(currentTime, vPos-vNeg));
891  TimeVoltageMap[adcName] = TmpVec;
892  }
893  return bSuccess;
894 }
895 
896 //-----------------------------------------------------------------------------
897 // Function : ::getBreakPoints
898 // Purpose : getBreakPoints for all instances
899 // Special Notes :
900 // Scope : public
901 // Creator : Richard Schiek, Electrical and Microsystems Modeling
902 // Creation Date : 02/25/2009
903 //-----------------------------------------------------------------------------
904 bool Master::getBreakPoints ( std::vector<N_UTL_BreakPoint> & breakPointTimes )
905 {
906  bool bsuccess = true;
907  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
908  {
909  Instance & di = *(*it);
910  bool tmpBool = di.getInstanceBreakPoints(breakPointTimes);
911  bsuccess = bsuccess && tmpBool;
912  }
913 
914  return bsuccess;
915 
916 }
917 
918 Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
919 {
920 
921  return new Master(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
922 }
923 
925 {
927  .registerDevice("adc", 1)
928  .registerModelType("adc", 1);
929 }
930 
931 } // namespace ADC
932 } // namespace Device
933 } // namespace Xyce