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