Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_DEV_DAC.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_DAC.C,v $
27 //
28 // Purpose : This file implements the DAC digital to analog conversion
29 // device used in the integration of Xyce withe SAVANT VHDL
30 // simulator.
31 //
32 // Special Notes :
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/03/06 23:33:43 $
44 //
45 // Current Owner : $Author: tvrusso $
46 //----------------------------------------------------------------------------
47 
48 #include <Xyce_config.h>
49 
50 // ---------- Standard Includes ----------
51 
52 #ifdef HAVE_CSTDIO
53 #include <cstdio>
54 #else
55 #include <stdio.h>
56 #endif
57 
58 #include <algorithm>
59 
60 // ---------- Xyce Includes ----------
61 #include <N_DEV_DAC.h>
62 #include <N_DEV_DeviceOptions.h>
63 #include <N_DEV_DeviceState.h>
64 #include <N_DEV_ExternData.h>
65 #include <N_DEV_MatrixLoadData.h>
66 #include <N_DEV_SolverState.h>
67 #include <N_DEV_Message.h>
68 #include <N_ERH_ErrorMgr.h>
69 
70 #include <N_LAS_Vector.h>
71 #include <N_LAS_Matrix.h>
72 
73 #include <N_UTL_BreakPoint.h>
74 
75 namespace Xyce {
76 namespace Device {
77 
78 
79 namespace DAC {
80 
81 
83 {
84  // Set up configuration constants:
85 // Set up double precision variables:
86 
87  // Set up exceptions (ie variables that are not doubles):
88 
89  p.addPar ("FILE", std::string(""), &DAC::Instance::file);
90 }
91 
93 {
94  // Set up double precision variables:
95  p.addPar ("TR", 1.e-9, &DAC::Model::riseTime)
96  .setUnit(U_SECOND)
97  .setDescription("Rise Time");
98 
99  p.addPar ("TF", 1.e-9, &DAC::Model::fallTime)
100  .setUnit(U_SECOND)
101  .setDescription("Fall Time");
102 
103  p.addPar ("R", 0.01, &DAC::Model::R)
104  .setUnit(U_OHM)
105  .setDescription("Resistance");
106 
107  p.addPar ("L", 1.e-5, &DAC::Model::L)
108  .setUnit(U_HENRY)
109  .setDescription("Inductance");
110 
111  p.addPar ("C", 0.0, &DAC::Model::C)
112  .setUnit(U_FARAD)
113  .setDescription("Capacitance");
114 
115  // Set up non-double precision variables:
116  p.addPar ("TRANBP", true, &DAC::Model::includeTransitionBP_)
117  .setCategory(CAT_CONTROL)
118  .setDescription("Flag for transitional breakpoints");
119 }
120 
121 
122 
123 
124 std::vector< std::vector<int> > Instance::jacStamp;
125 
126 
127 //----------------------------------------------------------------------------
128 // Function : Instance::processParams
129 // Purpose :
130 // Special Notes :
131 // Scope : public
132 // Creator : Lon Waters
133 // Creation Date : 07/29/2002
134 //----------------------------------------------------------------------------
136 {
137 
138  return true;
139 }
140 
141 //----------------------------------------------------------------------------
142 // Function : Instance::Instance
143 // Purpose : constructor
144 // Special Notes :
145 // Scope : public
146 // Creator : Lon Waters
147 // Creation Date : 07/29/2002
148 //----------------------------------------------------------------------------
150  const Configuration & configuration,
151  const InstanceBlock & IB,
152  Model & DACiter,
153  const FactoryBlock & factory_block)
154  : DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
155  model_(DACiter),
156  v_pos(0),
157  v_neg(0),
158  i_bra(0),
159  vDrop(0),
160  voltage_(0),
161  file(""),
162  loc_(0),
163  numTVpairs_(0),
164  li_Pos(-1),
165  li_Neg(-1),
166  li_Bra(-1),
167  ABraEquPosNodeOffset(-1),
168  ABraEquNegNodeOffset(-1),
169  APosEquBraVarOffset(-1),
170  ANegEquBraVarOffset(-1)
171 {
172  numIntVars = 1;
173  numExtVars = 2;
174  numStateVars = 0;
175 
176  if( jacStamp.empty() )
177  {
178  jacStamp.resize(3);
179  jacStamp[0].resize(1);
180  jacStamp[0][0] = 2;
181  jacStamp[1].resize(1);
182  jacStamp[1][0] = 2;
183  jacStamp[2].resize(2);
184  jacStamp[2][0] = 0;
185  jacStamp[2][1] = 1;
186  }
187 
188 
189  // Set params to constant default values:
190  setDefaultParams ();
191 
192  // Set params according to instance line and constant defaults from metadata:
193  setParams (IB.params);
194 
195  // Set any non-constant parameter defaults:
196 
197  // Calculate any parameters specified as expressions:
199 
200  // calculate dependent (ie computed) params and check for errors:
201 
202  processParams ();
203 }
204 
205 //----------------------------------------------------------------------------
206 // Function : Instance::~Instance
207 // Purpose :
208 // Special Notes :
209 // Scope : public
210 // Creator : Lon Waters
211 // Creation Date : 07/29/2002
212 //----------------------------------------------------------------------------
214 {
215 }
216 
217 //----------------------------------------------------------------------------
218 // Function : Instance::registerLIDs
219 // Purpose :
220 // Special Notes :
221 // Scope : public
222 // Creator : Lon Waters
223 // Creation Date : 07/29/2002
224 //----------------------------------------------------------------------------
225 void Instance::registerLIDs( const std::vector<int> & intLIDVecRef,
226  const std::vector<int> & extLIDVecRef)
227 {
228  AssertLIDs(intLIDVecRef.size() == numIntVars);
229  AssertLIDs(extLIDVecRef.size() == numExtVars);
230 
231 #ifdef Xyce_DEBUG_DEVICE
232  if (getDeviceOptions().debugLevel > 0 )
233  {
234  Xyce::dout() << std::endl << section_divider << std::endl;
235  Xyce::dout() << " DACInstance::registerLIDs" << std::endl;
236  Xyce::dout() << " name = " << getName() << std::endl;
237  }
238 #endif
239 
240  // copy over the global ID lists.
241  intLIDVec = intLIDVecRef;
242  extLIDVec = extLIDVecRef;
243 
244  // Now use these lists to obtain the indices into the
245  // linear algebra entities. This assumes an order.
246  // For the matrix indices, first do the rows.
247 
248  li_Pos = extLIDVec[0];
249 
250 #ifdef Xyce_DEBUG_DEVICE
251  if (getDeviceOptions().debugLevel > 0 )
252  Xyce::dout() << " li_Pos = " << li_Pos << std::endl;
253 #endif
254 
255  li_Neg = extLIDVec[1];
256 
257 #ifdef Xyce_DEBUG_DEVICE
258  if (getDeviceOptions().debugLevel > 0 )
259  Xyce::dout() << " li_Neg = " << li_Neg << std::endl;
260 #endif
261 
262  li_Bra = intLIDVec[0];
263 
264 #ifdef Xyce_DEBUG_DEVICE
265  if (getDeviceOptions().debugLevel > 0 )
266  Xyce::dout() << " li_Bra = " << li_Bra << std::endl;
267 #endif
268 
269 #ifdef Xyce_DEBUG_DEVICE
270  if (getDeviceOptions().debugLevel > 0 )
271  Xyce::dout() << section_divider << std::endl;
272 #endif
273 }
274 
275 //----------------------------------------------------------------------------
276 // Function : Instance::registerStateLIDs
277 // Purpose :
278 // Special Notes :
279 // Scope : public
280 // Creator : Lon Waters
281 // Creation Date : 07/29/2002
282 //----------------------------------------------------------------------------
283 void Instance::registerStateLIDs( const std::vector<int> & staLIDVecRef)
284 {
285  AssertLIDs(staLIDVecRef.size() == numStateVars);
286 }
287 
288 //-----------------------------------------------------------------------------
289 // Function : Instance::getIntNameMap
290 // Purpose :
291 // Special Notes :
292 // Scope : public
293 // Creator : Dave Shirley, PSSi
294 // Creation Date : 11/20/09
295 //-----------------------------------------------------------------------------
296 std::map<int,std::string> & Instance::getIntNameMap ()
297 {
298  // set up the internal name map, if it hasn't been already.
299  if (intNameMap.empty ())
300  {
301  std::string tmpstr;
302  tmpstr = getName()+"_branch";
303  spiceInternalName (tmpstr);
304  intNameMap[li_Bra] = tmpstr;
305  }
306 
307  return intNameMap;
308 }
309 
310 //----------------------------------------------------------------------------
311 // Function : jacobianStamp
312 // Purpose :
313 // Special Notes :
314 // Scope : public
315 // Creator : Lon Waters
316 // Creation Date : 11/12/2002
317 //----------------------------------------------------------------------------
318 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
319 {
320  return jacStamp;
321 }
322 
323 //----------------------------------------------------------------------------
324 // Function : registerJacLIDs
325 // Purpose :
326 // Special Notes :
327 // Scope : public
328 // Creator : Lon Waters
329 // Creation Date : 11/12/2002
330 //----------------------------------------------------------------------------
331 void Instance::registerJacLIDs(const std::vector< std::vector<int> >& jacLIDVec)
332 {
333  APosEquBraVarOffset = jacLIDVec[0][0];
334  ANegEquBraVarOffset = jacLIDVec[1][0];
335  ABraEquPosNodeOffset = jacLIDVec[2][0];
336  ABraEquNegNodeOffset = jacLIDVec[2][1];
337 }
338 
339 //----------------------------------------------------------------------------
340 // Function : Instance::updateIntermediateVars
341 // Purpose :
342 // Special Notes :
343 // Scope : public
344 // Creator : Richard Schiek, 1437, Electrical and Microsystem Sim.
345 // Creation Date : 02/19/08
346 //----------------------------------------------------------------------------
348 {
349  bool bsuccess = true;
350  double * solVector = extData.nextSolVectorRawPtr;
351 
352  // Get the value for the source.
353  updateVoltage(getSolverState().acceptedTime);
354 
355  // get the value for v_pos, v_neg, i_bra
356  v_pos = solVector[li_Pos];
357  v_neg = solVector[li_Neg];
358  i_bra = solVector[li_Bra];
360 
361  return bsuccess;
362 }
363 
364 //----------------------------------------------------------------------------
365 // Function : Instance::updatePrimaryState
366 // Purpose :
367 // Special Notes :
368 // Scope : public
369 // Creator : Lon Waters
370 // Creation Date : 07/29/2002
371 //----------------------------------------------------------------------------
373 {
374  bool bsuccess = true;
375  bsuccess = updateIntermediateVars ();
376  return bsuccess;
377 }
378 
379 //----------------------------------------------------------------------------
380 // Function : Instance::updateSecondaryState
381 // Purpose :
382 // Special Notes :
383 // Scope : public
384 // Creator : Lon Waters
385 // Creation Date : 07/29/2002
386 //----------------------------------------------------------------------------
388 {
389  bool bsuccess = true;
390 
391  return bsuccess;
392 }
393 
394 //----------------------------------------------------------------------------
395 // Function : Instance::updateTVVEC
396 // Purpose : Append the contents of newPairs to TVVEC
397 // Special Notes :
398 // Scope : public
399 // Creator : Lisa Maynes & Lon Waters
400 // Creation Date : 06/10/2003
401 //----------------------------------------------------------------------------
403  std::vector< std::pair<double, double> > const & newPairsIn )
404 {
405  int i, last, newStart;
406  double transitionTime;
407  bool bsuccess = true;
408  std::vector< std::pair<double,double> >::iterator itVec, itVec_end;
409  std::vector< std::pair<double, double> > newPairs;
410  std::vector< std::pair<double,double> >::const_iterator const_itVec;
411  std::map<double, double> tv;
412  std::map<double, double>::iterator tv_i, tv_end;
413 
414 #ifdef Xyce_DEBUG_DEVICE
415  if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
416  {
417  Xyce::dout() << "In device " << getName() << std::endl;
418  Xyce::dout() << "At time = " << getSolverState().acceptedTime <<
419  ", at beginning of Instance::updateTVVEC():\n"
420  << " TVVEC size = " << numTVpairs_ << "\n"
421  << " TVVEC loc = " << loc_ << "\n"
422  << " TVVEC contents:\n" ;
423  itVec = TVVEC.begin();
424  itVec_end = TVVEC.end();
425  for( ; itVec != itVec_end; ++itVec )
426  {
427  Xyce::dout() << " " << (*itVec).first
428  << "s, " << (*itVec).second
429  << "V\n";
430  }
431  Xyce::dout() << newPairsIn.size() << " New pairs:" << std::endl;
432  for ( const_itVec = newPairsIn.begin() ; const_itVec != newPairsIn.end() ; ++const_itVec )
433  Xyce::dout() << (*const_itVec).first << " " << (*const_itVec).second << std::endl;
434  }
435 #endif
436 
437  updateVoltage(getSolverState().acceptedTime);
438 
439  itVec = TVVEC.begin();
440  itVec_end = TVVEC.end();
441  for( ; itVec != itVec_end; ++itVec )
442  tv[(*itVec).first] = (*itVec).second;
443 
444  if (!newPairsIn.empty())
445  {
446  if (getSolverState().acceptedTime == 0)
447  {
448  TVVEC.resize(0);
449  if (newPairsIn.size() > 0)
450  TVVEC.push_back(std::pair<double,double>(0,(*(newPairsIn.end()-1)).second));
451  if (newPairsIn.size() > 1 && (*(newPairsIn.end()-1)).first > TVVEC[0].first)
452  TVVEC.push_back(*(newPairsIn.end()-1));
453  numTVpairs_ = TVVEC.size();
454  updateVoltage(getSolverState().acceptedTime);
455  return bsuccess;
456  }
457  std::vector< std::pair<double, double> >::const_iterator n_i, n_end;
458  std::vector< std::pair<double, double> >::iterator t_i, t_end;
459  n_i = newPairsIn.begin();
460  n_end = newPairsIn.end();
461  for ( ; n_i != n_end ; ++n_i)
462  {
463  if ((*n_i).first < 0)
464  {
465  double d = -(*n_i).first;
466  tv_i = lower_bound(tv.begin(), tv.end(), std::pair<const double, double>(d,0));
467  tv.erase(tv_i,tv.end());
468  }
469  }
470  n_i = newPairsIn.begin();
471  for ( ; n_i != n_end ; ++n_i)
472  {
473  if ((*n_i).first >= getSolverState().acceptedTime)
474  {
475  transitionTime = model_.riseTime;
476  if (transitionTime > 0) {
477  tv_i = lower_bound(tv.begin(), tv.end(), std::pair<const double, double>((*n_i).first,0));
478  if (tv_i != tv.begin())
479  {
480  --tv_i;
481  if ((*n_i).second < (*tv_i).second)
482  transitionTime = model_.fallTime;
483  }
484  tv[(*n_i).first] = (*tv_i).second;
485  }
486  tv[(*n_i).first + transitionTime] = (*n_i).second;
487  }
488  }
490  }
491  tv_i = lower_bound(tv.begin(), tv.end(), std::pair<const double, double>(getSolverState().acceptedTime,0));
492  if (tv_i != tv.begin())
493  --tv_i;
494  tv.erase(tv.begin(), tv_i);
495  double lastTimeEntry = -1;
496  TVVEC.clear();
497  tv_i = tv.begin();
498  tv_end = tv.end();
499  for ( ; tv_i != tv_end ; ++tv_i)
500  {
501  if ((*tv_i).first - lastTimeEntry > 1e-15)
502  {
503  TVVEC.push_back(std::pair<double, double>((*tv_i).first,(*tv_i).second));
504  lastTimeEntry = (*tv_i).first;
505  }
506  }
507  numTVpairs_ = TVVEC.size();
508 
509 #ifdef Xyce_DEBUG_DEVICE
510  if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
511  {
512  Xyce::dout() << "Instance::updateTVVEC():\n"
513  << " TVVEC size = " << numTVpairs_ << "\n"
514  << " TVVEC loc = " << loc_ << "\n"
515  << " TVVEC contents:\n" ;
516  std::vector< std::pair<double, double> >::iterator tv_i = TVVEC.begin();
517  for( ; tv_i != TVVEC.end(); ++tv_i )
518  {
519  Xyce::dout() << " " << (*tv_i).first
520  << "s, " << (*tv_i).second
521  << "V\n";
522  }
523  }
524 #endif
525 
526  return bsuccess;
527 }
528 
529 //----------------------------------------------------------------------------
530 // Function : Instance::updateVoltage
531 // Purpose :
532 // Special Notes :
533 // Scope : private
534 // Creator : Lon Waters
535 // Creation Date : 11/12/2002
536 //----------------------------------------------------------------------------
537 bool Instance::updateVoltage(double time)
538 {
539  bool bsuccess = true;
540 
541 #ifdef Xyce_DEBUG_DEVICE
542  if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
543  {
544  Xyce::dout() << std::endl;
545  Xyce::dout() << " DACInstance::updateVoltage\n";
546  Xyce::dout() << Xyce::section_divider << std::endl;
547  Xyce::dout() << " Time = " << time << std::endl;
548  }
549 #endif
550 
551 #ifdef Xyce_DEBUG_DEVICE
552  if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag && numTVpairs_ > 0)
553  {
554  Xyce::dout() << " TVVEC[numTVpairs_-1].first = "
555  << TVVEC[numTVpairs_-1].first << std::endl;
556  }
557  for (int i=0 ; i<numTVpairs_ ; ++i) {
558  Xyce::dout() << TVVEC[i].first << " :: " << TVVEC[i].second << std::endl;
559  }
560 #endif
561 
562  if( numTVpairs_ > 0 && time >= TVVEC[0].first )
563  {
564  if( time < TVVEC[numTVpairs_-1].first )
565  {
566  for( int i = 0; i < numTVpairs_ - 1; ++i )
567  {
568  if( time >= TVVEC[i].first && time <= TVVEC[i+1].first)
569  {
570  double time1 = TVVEC[i].first;
571  double voltage1 = TVVEC[i].second;
572 
573  double time2 = TVVEC[i+1].first;
574  double voltage2 = TVVEC[i+1].second;
575 
576  voltage_ = voltage1 + (voltage2 - voltage1) * (time - time1) / (time2 - time1);
577  break;
578  }
579  }
580  }
581  else
582  {
583  voltage_ = TVVEC[numTVpairs_-1].second;
584  }
585  }
586 
587 #ifdef Xyce_DEBUG_DEVICE
589  {
590  Xyce::dout() << " voltage_ = " << voltage_ << std::endl;
591  Xyce::dout() << Xyce::section_divider << std::endl;
592  }
593 #endif
594 
595  return bsuccess;
596 }
597 
598 //-----------------------------------------------------------------------------
599 // Function : Instance::loadDAEFVector
600 //
601 // Purpose : Loads the F-vector contributions for this device.
602 //
603 // Special Notes : This is an algebraic constaint, and as such the resistor
604 // does make a contribution to it.
605 //
606 // Scope : public
607 // Creator : Richard Schiek, 1437, Electrical and Microsystem Sim.
608 // Creation Date : 02/19/08
609 //-----------------------------------------------------------------------------
611 {
612  bool bsuccess = true;
613 
614  double * daeFVec = extData.daeFVectorRawPtr;
615 
616 
617  daeFVec[li_Pos] += i_bra;
618 
619  daeFVec[li_Neg] += -i_bra;
620 
621  daeFVec[li_Bra] += vDrop;
622 
623  return bsuccess;
624 }
625 
626 //-----------------------------------------------------------------------------
627 // Function : Instance::loadDAEdFdx ()
628 //
629 // Purpose : Loads the F-vector contributions for this device.
630 //
631 // Special Notes :
632 //
633 // Scope : public
634 // Creator : Richard Schiek, 1437, Electrical and Microsystem Sim.
635 // Creation Date : 02/19/08
636 //-----------------------------------------------------------------------------
638 {
639  bool bsuccess = true;
640 
641  N_LAS_Matrix * dFdxMatPtr = extData.dFdxMatrixPtr;
642 
643 
644  (*dFdxMatPtr)[li_Pos][APosEquBraVarOffset] += 1.0;
645 
646  (*dFdxMatPtr)[li_Neg][ANegEquBraVarOffset] -= 1.0;
647 
648  (*dFdxMatPtr)[li_Bra][ABraEquPosNodeOffset] += 1.0;
649 
650  (*dFdxMatPtr)[li_Bra][ABraEquNegNodeOffset] -= 1.0;
651 
652  return bsuccess;
653 }
654 
655 //-----------------------------------------------------------------------------
656 // Function : Instance::getInstanceBreakPoints
657 // Purpose :
658 // Special Notes :
659 // Scope : public
660 // Creator : Tom Russo, SNL, Component Information and Models
661 // Creation Date : 2/16/04
662 //-----------------------------------------------------------------------------
663 
664 bool Instance::getInstanceBreakPoints ( std::vector<N_UTL_BreakPoint> & breakPointTimes)
665 {
666  bool bsuccess = true;
667  double currentTime = getSolverState().currTime;
668 #ifdef Xyce_DEBUG_DEVICE
669  if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
670  {
671  Xyce::dout() << "In ::getInstanceBreakPoints " << std::endl;
672  Xyce::dout() << " I want breakpoints. Current time is " << currentTime << std::endl;
673  }
674 #endif
675 
676  for (int i = 0; i < numTVpairs_ ; ++i)
677  {
678  // ERK: the 1e-15 is a tolerance. Fix for bug 1766. Possibly use bpTol instead?
679  // DNS: No, bpTol tends to be ridiculously small and this might cause
680  // excessively small time steps. I would agree if bpTol had a floor value,
681  // such as 1e-15. Steps smaller than this are unjustified and numerically
682  // problematic. For reference, light travels 0.3 micron in 1e-15 seconds.
683  if (TVVEC[i].first >= currentTime - 1e-15 && model_.riseTime != 0 && model_.fallTime != 0)
684  {
685  breakPointTimes.push_back(Util::BreakPoint(TVVEC[i].first, Util::SIMPLE_BREAKPOINT));
686  }
687  }
688 
689 #ifdef Xyce_DEBUG_DEVICE
690  if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
691  {
692  Xyce::dout() << "DAC ----------------------------------------" << std::endl;
693  Xyce::dout() << "DAC getInstanceBreakPoints " << std::endl;
694  Xyce::dout() << "DAC Debug output. name = " << getName() << std::endl;
695  Xyce::dout() << "DAC setting breakpoints at currentTime = " << currentTime << std::endl;
696  Xyce::dout() << "DAC breakpoints: " << std::endl;
697 
698  std::vector< Util::BreakPoint >::iterator beg = breakPointTimes.begin();
699  std::vector< Util::BreakPoint >::iterator end = breakPointTimes.end();
700  std::vector< Util::BreakPoint >::iterator itBP = beg;
701  for (;itBP!=end;++itBP)
702  {
703  Util::BreakPoint & bp = *itBP;
704  Xyce::dout() << "DAC breakpoint: " << bp.value() << std::endl;
705  }
706 
707  Xyce::dout() << "DAC ----------------------------------------" << std::endl;
708  }
709 #endif
710 
711  return bsuccess;
712 }
713 
714 //-----------------------------------------------------------------------------
715 // Function : Instance::getInternalState
716 // Purpose : Generates an DeviceState object and populates
717 // it with the contents of the TVVEC vector for use by
718 // restarts
719 //
720 // Special Notes :
721 //
722 // Scope : public
723 // Creator : Tom Russo, SNL, Component Information and Models
724 // Creation Date : 09/03/04
725 //-----------------------------------------------------------------------------
727 {
728  int vsize,i,j;
729  // allocate object to return
730  DeviceState * myState = new DeviceState;
731 
732  myState->ID=getName();
733  vsize=TVVEC.size();
734  // pack the pairs into the single vector of doubles.
735  myState->data.resize(vsize*2);
736  for (i=0;i<vsize;++i)
737  {
738  j=i*2;
739  myState->data[j]=TVVEC[i].first;
740  myState->data[j+1]=TVVEC[i].second;
741  }
742 
743  return myState;
744 }
745 //-----------------------------------------------------------------------------
746 // Function : Instance::setInternalState
747 // Purpose : Reload TVVEC data from restart
748 //
749 // Special Notes :
750 //
751 // Scope : public
752 // Creator : Tom Russo, SNL, Component Information and Models
753 // Creation Date : 09/03/04
754 //-----------------------------------------------------------------------------
756 {
757  int dsize=state.data.size();
758  int vsize,i,j;
759  if ( state.ID != getName())
760  {
761  std::string msg;
762  msg = "Instance::setInternalState: ID ("+state.ID+")";
763  msg += "from restart does not match my name ("+getName()+")!\n";
764  N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL, msg);
765  }
766 
767  if (dsize%2 != 0)
768  {
769  std::string msg;
770  char msg2[256];
771  sprintf(msg2, "Instance::setInternalState: "
772  "Data size from restart (%d) not a multiple of 2!",
773  dsize);
774  msg=msg2;
775  N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL, msg);
776  }
777 
778  vsize=dsize/2;
779  TVVEC.clear();
780  TVVEC.resize(vsize);
781  for (i=0;i<vsize;++i)
782  {
783  j=i*2;
784  TVVEC[i].first=state.data[j];
785  TVVEC[i].second=state.data[j+1];
786  }
787 
788  return true;
789 }
790 
791 //-----------------------------------------------------------------------------
792 // Function : Instance::varTypes
793 // Purpose :
794 // Special Notes :
795 // Scope : public
796 // Creator : Eric R. Keiter
797 // Creation Date : 05/12/09
798 //-----------------------------------------------------------------------------
799 void Instance::varTypes( std::vector<char> & varTypeVec )
800 {
801  varTypeVec.resize(1);
802  varTypeVec[0] = 'I';
803 }
804 
805 //----------------------------------------------------------------------------
806 // Function : Model::processParams
807 // Purpose :
808 // Special Notes :
809 // Scope : public
810 // Creator : Lon Waters
811 // Creation Date : 07/29/2002
812 //----------------------------------------------------------------------------
814 {
815  return true;
816 }
817 
818 //----------------------------------------------------------------------------
819 // Function : Model::processInstanceParams
820 // Purpose :
821 // Special Notes :
822 // Scope : public
823 // Creator : Dave Shirely, PSSI
824 // Creation Date : 03/23/06
825 //----------------------------------------------------------------------------
827 {
828 
829  std::vector<Instance*>::iterator iter;
830  std::vector<Instance*>::iterator first = instanceContainer.begin();
831  std::vector<Instance*>::iterator last = instanceContainer.end();
832 
833  for (iter=first; iter!=last; ++iter)
834  {
835  (*iter)->processParams();
836  }
837 
838  return true;
839 }
840 
841 //----------------------------------------------------------------------------
842 // Function : Model::Model
843 // Purpose : constructor
844 // Special Notes :
845 // Scope : public
846 // Creator : Lon Waters
847 // Creation Date : 07/29/2002
848 //----------------------------------------------------------------------------
850  const Configuration & configuration,
851  const ModelBlock& MB,
852  const FactoryBlock & factory_block)
853  : DeviceModel(MB, configuration.getModelParameters(), factory_block),
854  riseTime(1.0e-9),
855  fallTime(1.0e-9),
856  R(.01),
857  C(0.0),
858  L(0.0),
859  includeTransitionBP_(true)
860 {
861 
862  // Set params to constant default values:
863  setDefaultParams ();
864 
865  // Set params according to .model line and constant defaults from metadata:
866  setModParams (MB.params);
867 
868  // Set any non-constant parameter defaults:
869 
870  // Calculate any parameters specified as expressions:
872 
873  // calculate dependent (ie computed) params and check for errors:
874 
875  processParams ();
876 }
877 
878 //----------------------------------------------------------------------------
879 // Function : Model::Model
880 // Purpose : destructor
881 // Special Notes :
882 // Scope : public
883 // Creator : Lon Waters
884 // Creation Date : 07/29/2002
885 //----------------------------------------------------------------------------
887 {
888  std::vector<Instance*>::iterator iter;
889  std::vector<Instance*>::iterator first = instanceContainer.begin();
890  std::vector<Instance*>::iterator last = instanceContainer.end();
891 
892  for (iter=first; iter!=last; ++iter)
893  {
894  delete (*iter);
895  }
896 }
897 
898 //----------------------------------------------------------------------------
899 // Function : printOutInstances
900 // Purpose : debugging tool
901 // Special Notes :
902 // Scope : public
903 // Creator : Lon Waters
904 // Creation Date : 07/29/2002
905 //----------------------------------------------------------------------------
906 std::ostream &Model::printOutInstances(std::ostream &os) const
907 {
908  std::vector<Instance*>::const_iterator iter;
909  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
910  std::vector<Instance*>::const_iterator last = instanceContainer.end();
911 
912  int i;
913  os << std::endl;
914  os << " name\t\tmodelName\tParameters" << std::endl;
915 
916  for (i = 0, iter = first; iter != last; ++iter, ++i)
917  {
918  os << " " << i << ": " << (*iter)->getName() << "\t";
919  os << getName();
920  os << "\t\tfile = " << (*iter)->file;
921  os << std::endl;
922  }
923 
924  os << std::endl;
925 
926  return os;
927 }
928 
929 //-----------------------------------------------------------------------------
930 // Function : Model::forEachInstance
931 // Purpose :
932 // Special Notes :
933 // Scope : public
934 // Creator : David Baur
935 // Creation Date : 2/4/2014
936 //-----------------------------------------------------------------------------
937 /// Apply a device instance "op" to all instances associated with this
938 /// model
939 ///
940 /// @param[in] op Operator to apply to all instances.
941 ///
942 ///
943 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
944 {
945  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
946  op(*it);
947 }
948 
949 
950 
951 // DAC Master functions:
952 
953 //-----------------------------------------------------------------------------
954 // Function : Master::updateState
955 // Purpose :
956 // Special Notes :
957 // Scope : public
958 // Creator : Richard Schiek, Electrical and Microsystems Modeling
959 // Creation Date : 02/25/2009
960 //-----------------------------------------------------------------------------
961 bool Master::updateState (double * solVec, double * staVec, double * stoVec)
962 {
963  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
964  {
965  Instance & di = *(*it);
966 
967  // here we update the voltage
968  di.updateVoltage(getSolverState().currTime);
969 
970  // get the value for v_pos, v_neg, i_bra
971  di.v_pos = solVec[di.li_Pos];
972  di.v_neg = solVec[di.li_Neg];
973  di.i_bra = solVec[di.li_Bra];
974  di.vDrop = (di.v_pos-di.v_neg-di.voltage_);
975 #ifdef Xyce_DEBUG_DEVICE
976  Xyce::dout() << "DAC ----------------------------------------" << std::endl;
977  Xyce::dout() << "DAC Debug output. name = " << di.getName() << std::endl;
978  Xyce::dout() << "DAC v_pos = " << di.v_pos <<std::endl;
979  Xyce::dout() << "DAC v_neg = " << di.v_neg <<std::endl;
980  Xyce::dout() << "DAC i_bra = " << di.i_bra <<std::endl;
981  Xyce::dout() << "DAC vDrop = " << di.vDrop <<std::endl;
982  Xyce::dout() << "DAC voltage_ = " << di.voltage_ <<std::endl;
983  Xyce::dout() << "DAC ----------------------------------------" << std::endl;
984 #endif
985  }
986 
987  return true;
988 }
989 
990 //-----------------------------------------------------------------------------
991 // Function : Master::updateSecondaryState
992 // Purpose :
993 // Special Notes :
994 // Scope : public
995 // Creator : Richard Schiek, Electrical and Microsystems Modeling
996 // Creation Date : 02/25/2009
997 //-----------------------------------------------------------------------------
998 bool Master::updateSecondaryState ( double * staDerivVec, double * stoVec )
999 {
1000  return true;
1001 }
1002 
1003 //-----------------------------------------------------------------------------
1004 // Function : Master::loadDAEVectors
1005 // Purpose :
1006 // Special Notes :
1007 // Scope : public
1008 // Creator : Eric Keiter, SNL
1009 // Creation Date : 11/26/08
1010 //-----------------------------------------------------------------------------
1011 bool Master::loadDAEVectors (double * solVec, double * fVec, double *qVec, double * storeLeadF, double * storeLeadQ)
1012 {
1013  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
1014  {
1015  Instance & di = *(*it);
1016 
1017  fVec[di.li_Pos] += di.i_bra;
1018 
1019  fVec[di.li_Neg] += -di.i_bra;
1020 
1021  fVec[di.li_Bra] += di.vDrop;
1022  }
1023 
1024  return true;
1025 }
1026 
1027 //-----------------------------------------------------------------------------
1028 // Function : Master::loadDAEMatrices
1029 // Purpose :
1030 // Special Notes :
1031 // Scope : public
1032 // Creator : Eric Keiter, SNL
1033 // Creation Date : 11/26/08
1034 //-----------------------------------------------------------------------------
1035 bool Master::loadDAEMatrices (N_LAS_Matrix & dFdx, N_LAS_Matrix & dQdx)
1036 {
1037  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
1038  {
1039  Instance & di = *(*it);
1040 
1041  dFdx[di.li_Pos][di.APosEquBraVarOffset] += 1.0;
1042 
1043  dFdx[di.li_Neg][di.ANegEquBraVarOffset] -= 1.0;
1044 
1045  dFdx[di.li_Bra][di.ABraEquPosNodeOffset] += 1.0;
1046 
1047  dFdx[di.li_Bra][di.ABraEquNegNodeOffset] -= 1.0;
1048  }
1049  return true;
1050 }
1051 
1052 //-----------------------------------------------------------------------------
1053 // Function : Master::getDACDeviceNames
1054 // Purpose : Get a list of names of all DACs in the circuit
1055 // Special Notes :
1056 // Scope : public
1057 // Creator : Tom Russo, SNL, Component Information and MOdels
1058 // Creation Date : 05/05/04
1059 //-----------------------------------------------------------------------------
1060 bool Master::getDACDeviceNames( std::vector<std::string> & dacNames)
1061 {
1062  bool bSuccess = true;
1063 
1064  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
1065  {
1066  Instance & di = *(*it);
1067  dacNames.push_back(di.getName());
1068  }
1069  return bSuccess;
1070 }
1071 
1072 Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
1073 {
1074 
1075  return new Master(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
1076 }
1077 
1079 {
1081  .registerDevice("dac", 1)
1082  .registerModelType("dac", 1);
1083 }
1084 
1085 } // namespace DAC
1086 } // namespace Device
1087 } // namespace Xyce