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/05/22 17:40:29 $
44 //
45 // Current Owner : $Author: erkeite $
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  intNameMap[li_Bra] = spiceInternalName(getName(), "branch");
302  }
303 
304  return intNameMap;
305 }
306 
307 //----------------------------------------------------------------------------
308 // Function : jacobianStamp
309 // Purpose :
310 // Special Notes :
311 // Scope : public
312 // Creator : Lon Waters
313 // Creation Date : 11/12/2002
314 //----------------------------------------------------------------------------
315 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
316 {
317  return jacStamp;
318 }
319 
320 //----------------------------------------------------------------------------
321 // Function : registerJacLIDs
322 // Purpose :
323 // Special Notes :
324 // Scope : public
325 // Creator : Lon Waters
326 // Creation Date : 11/12/2002
327 //----------------------------------------------------------------------------
328 void Instance::registerJacLIDs(const std::vector< std::vector<int> >& jacLIDVec)
329 {
330  APosEquBraVarOffset = jacLIDVec[0][0];
331  ANegEquBraVarOffset = jacLIDVec[1][0];
332  ABraEquPosNodeOffset = jacLIDVec[2][0];
333  ABraEquNegNodeOffset = jacLIDVec[2][1];
334 }
335 
336 //----------------------------------------------------------------------------
337 // Function : Instance::updateIntermediateVars
338 // Purpose :
339 // Special Notes :
340 // Scope : public
341 // Creator : Richard Schiek, 1437, Electrical and Microsystem Sim.
342 // Creation Date : 02/19/08
343 //----------------------------------------------------------------------------
345 {
346  bool bsuccess = true;
347  double * solVector = extData.nextSolVectorRawPtr;
348 
349  // Get the value for the source.
350  updateVoltage(getSolverState().acceptedTime);
351 
352  // get the value for v_pos, v_neg, i_bra
353  v_pos = solVector[li_Pos];
354  v_neg = solVector[li_Neg];
355  i_bra = solVector[li_Bra];
357 
358  return bsuccess;
359 }
360 
361 //----------------------------------------------------------------------------
362 // Function : Instance::updatePrimaryState
363 // Purpose :
364 // Special Notes :
365 // Scope : public
366 // Creator : Lon Waters
367 // Creation Date : 07/29/2002
368 //----------------------------------------------------------------------------
370 {
371  bool bsuccess = true;
372  bsuccess = updateIntermediateVars ();
373  return bsuccess;
374 }
375 
376 //----------------------------------------------------------------------------
377 // Function : Instance::updateSecondaryState
378 // Purpose :
379 // Special Notes :
380 // Scope : public
381 // Creator : Lon Waters
382 // Creation Date : 07/29/2002
383 //----------------------------------------------------------------------------
385 {
386  bool bsuccess = true;
387 
388  return bsuccess;
389 }
390 
391 //----------------------------------------------------------------------------
392 // Function : Instance::updateTVVEC
393 // Purpose : Append the contents of newPairs to TVVEC
394 // Special Notes :
395 // Scope : public
396 // Creator : Lisa Maynes & Lon Waters
397 // Creation Date : 06/10/2003
398 //----------------------------------------------------------------------------
400  std::vector< std::pair<double, double> > const & newPairsIn )
401 {
402  int i, last, newStart;
403  double transitionTime;
404  bool bsuccess = true;
405  std::vector< std::pair<double,double> >::iterator itVec, itVec_end;
406  std::vector< std::pair<double, double> > newPairs;
407  std::vector< std::pair<double,double> >::const_iterator const_itVec;
408  std::map<double, double> tv;
409  std::map<double, double>::iterator tv_i, tv_end;
410 
411 #ifdef Xyce_DEBUG_DEVICE
412  if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
413  {
414  Xyce::dout() << "In device " << getName() << std::endl;
415  Xyce::dout() << "At time = " << getSolverState().acceptedTime <<
416  ", at beginning of Instance::updateTVVEC():\n"
417  << " TVVEC size = " << numTVpairs_ << "\n"
418  << " TVVEC loc = " << loc_ << "\n"
419  << " TVVEC contents:\n" ;
420  itVec = TVVEC.begin();
421  itVec_end = TVVEC.end();
422  for( ; itVec != itVec_end; ++itVec )
423  {
424  Xyce::dout() << " " << (*itVec).first
425  << "s, " << (*itVec).second
426  << "V\n";
427  }
428  Xyce::dout() << newPairsIn.size() << " New pairs:" << std::endl;
429  for ( const_itVec = newPairsIn.begin() ; const_itVec != newPairsIn.end() ; ++const_itVec )
430  Xyce::dout() << (*const_itVec).first << " " << (*const_itVec).second << std::endl;
431  }
432 #endif
433 
434  updateVoltage(getSolverState().acceptedTime);
435 
436  itVec = TVVEC.begin();
437  itVec_end = TVVEC.end();
438  for( ; itVec != itVec_end; ++itVec )
439  tv[(*itVec).first] = (*itVec).second;
440 
441  if (!newPairsIn.empty())
442  {
443  if (getSolverState().acceptedTime == 0)
444  {
445  TVVEC.resize(0);
446  if (newPairsIn.size() > 0)
447  TVVEC.push_back(std::pair<double,double>(0,(*(newPairsIn.end()-1)).second));
448  if (newPairsIn.size() > 1 && (*(newPairsIn.end()-1)).first > TVVEC[0].first)
449  TVVEC.push_back(*(newPairsIn.end()-1));
450  numTVpairs_ = TVVEC.size();
451  updateVoltage(getSolverState().acceptedTime);
452  return bsuccess;
453  }
454  std::vector< std::pair<double, double> >::const_iterator n_i, n_end;
455  std::vector< std::pair<double, double> >::iterator t_i, t_end;
456  n_i = newPairsIn.begin();
457  n_end = newPairsIn.end();
458  for ( ; n_i != n_end ; ++n_i)
459  {
460  if ((*n_i).first < 0)
461  {
462  double d = -(*n_i).first;
463  tv_i = lower_bound(tv.begin(), tv.end(), std::pair<const double, double>(d,0));
464  tv.erase(tv_i,tv.end());
465  }
466  }
467  n_i = newPairsIn.begin();
468  for ( ; n_i != n_end ; ++n_i)
469  {
470  if ((*n_i).first >= getSolverState().acceptedTime)
471  {
472  transitionTime = model_.riseTime;
473  if (transitionTime > 0) {
474  tv_i = lower_bound(tv.begin(), tv.end(), std::pair<const double, double>((*n_i).first,0));
475  if (tv_i != tv.begin())
476  {
477  --tv_i;
478  if ((*n_i).second < (*tv_i).second)
479  transitionTime = model_.fallTime;
480  }
481  tv[(*n_i).first] = (*tv_i).second;
482  }
483  tv[(*n_i).first + transitionTime] = (*n_i).second;
484  }
485  }
487  }
488  tv_i = lower_bound(tv.begin(), tv.end(), std::pair<const double, double>(getSolverState().acceptedTime,0));
489  if (tv_i != tv.begin())
490  --tv_i;
491  tv.erase(tv.begin(), tv_i);
492  double lastTimeEntry = -1;
493  TVVEC.clear();
494  tv_i = tv.begin();
495  tv_end = tv.end();
496  for ( ; tv_i != tv_end ; ++tv_i)
497  {
498  if ((*tv_i).first - lastTimeEntry > 1e-15)
499  {
500  TVVEC.push_back(std::pair<double, double>((*tv_i).first,(*tv_i).second));
501  lastTimeEntry = (*tv_i).first;
502  }
503  }
504  numTVpairs_ = TVVEC.size();
505 
506 #ifdef Xyce_DEBUG_DEVICE
507  if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
508  {
509  Xyce::dout() << "Instance::updateTVVEC():\n"
510  << " TVVEC size = " << numTVpairs_ << "\n"
511  << " TVVEC loc = " << loc_ << "\n"
512  << " TVVEC contents:\n" ;
513  std::vector< std::pair<double, double> >::iterator tv_i = TVVEC.begin();
514  for( ; tv_i != TVVEC.end(); ++tv_i )
515  {
516  Xyce::dout() << " " << (*tv_i).first
517  << "s, " << (*tv_i).second
518  << "V\n";
519  }
520  }
521 #endif
522 
523  return bsuccess;
524 }
525 
526 //----------------------------------------------------------------------------
527 // Function : Instance::updateVoltage
528 // Purpose :
529 // Special Notes :
530 // Scope : private
531 // Creator : Lon Waters
532 // Creation Date : 11/12/2002
533 //----------------------------------------------------------------------------
534 bool Instance::updateVoltage(double time)
535 {
536  bool bsuccess = true;
537 
538 #ifdef Xyce_DEBUG_DEVICE
539  if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
540  {
541  Xyce::dout() << std::endl;
542  Xyce::dout() << " DACInstance::updateVoltage\n";
543  Xyce::dout() << Xyce::section_divider << std::endl;
544  Xyce::dout() << " Time = " << time << std::endl;
545  }
546 #endif
547 
548 #ifdef Xyce_DEBUG_DEVICE
549  if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag && numTVpairs_ > 0)
550  {
551  Xyce::dout() << " TVVEC[numTVpairs_-1].first = "
552  << TVVEC[numTVpairs_-1].first << std::endl;
553  }
554  for (int i=0 ; i<numTVpairs_ ; ++i) {
555  Xyce::dout() << TVVEC[i].first << " :: " << TVVEC[i].second << std::endl;
556  }
557 #endif
558 
559  if( numTVpairs_ > 0 && time >= TVVEC[0].first )
560  {
561  if( time < TVVEC[numTVpairs_-1].first )
562  {
563  for( int i = 0; i < numTVpairs_ - 1; ++i )
564  {
565  if( time >= TVVEC[i].first && time <= TVVEC[i+1].first)
566  {
567  double time1 = TVVEC[i].first;
568  double voltage1 = TVVEC[i].second;
569 
570  double time2 = TVVEC[i+1].first;
571  double voltage2 = TVVEC[i+1].second;
572 
573  voltage_ = voltage1 + (voltage2 - voltage1) * (time - time1) / (time2 - time1);
574  break;
575  }
576  }
577  }
578  else
579  {
580  voltage_ = TVVEC[numTVpairs_-1].second;
581  }
582  }
583 
584 #ifdef Xyce_DEBUG_DEVICE
586  {
587  Xyce::dout() << " voltage_ = " << voltage_ << std::endl;
588  Xyce::dout() << Xyce::section_divider << std::endl;
589  }
590 #endif
591 
592  return bsuccess;
593 }
594 
595 //-----------------------------------------------------------------------------
596 // Function : Instance::loadDAEFVector
597 //
598 // Purpose : Loads the F-vector contributions for this device.
599 //
600 // Special Notes : This is an algebraic constaint, and as such the resistor
601 // does make a contribution to it.
602 //
603 // Scope : public
604 // Creator : Richard Schiek, 1437, Electrical and Microsystem Sim.
605 // Creation Date : 02/19/08
606 //-----------------------------------------------------------------------------
608 {
609  bool bsuccess = true;
610 
611  double * daeFVec = extData.daeFVectorRawPtr;
612 
613 
614  daeFVec[li_Pos] += i_bra;
615 
616  daeFVec[li_Neg] += -i_bra;
617 
618  daeFVec[li_Bra] += vDrop;
619 
620  return bsuccess;
621 }
622 
623 //-----------------------------------------------------------------------------
624 // Function : Instance::loadDAEdFdx ()
625 //
626 // Purpose : Loads the F-vector contributions for this device.
627 //
628 // Special Notes :
629 //
630 // Scope : public
631 // Creator : Richard Schiek, 1437, Electrical and Microsystem Sim.
632 // Creation Date : 02/19/08
633 //-----------------------------------------------------------------------------
635 {
636  bool bsuccess = true;
637 
638  N_LAS_Matrix * dFdxMatPtr = extData.dFdxMatrixPtr;
639 
640 
641  (*dFdxMatPtr)[li_Pos][APosEquBraVarOffset] += 1.0;
642 
643  (*dFdxMatPtr)[li_Neg][ANegEquBraVarOffset] -= 1.0;
644 
645  (*dFdxMatPtr)[li_Bra][ABraEquPosNodeOffset] += 1.0;
646 
647  (*dFdxMatPtr)[li_Bra][ABraEquNegNodeOffset] -= 1.0;
648 
649  return bsuccess;
650 }
651 
652 //-----------------------------------------------------------------------------
653 // Function : Instance::getInstanceBreakPoints
654 // Purpose :
655 // Special Notes :
656 // Scope : public
657 // Creator : Tom Russo, SNL, Component Information and Models
658 // Creation Date : 2/16/04
659 //-----------------------------------------------------------------------------
660 
661 bool Instance::getInstanceBreakPoints ( std::vector<N_UTL_BreakPoint> & breakPointTimes)
662 {
663  bool bsuccess = true;
664  double currentTime = getSolverState().currTime;
665 #ifdef Xyce_DEBUG_DEVICE
666  if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
667  {
668  Xyce::dout() << "In ::getInstanceBreakPoints " << std::endl;
669  Xyce::dout() << " I want breakpoints. Current time is " << currentTime << std::endl;
670  }
671 #endif
672 
673  for (int i = 0; i < numTVpairs_ ; ++i)
674  {
675  // ERK: the 1e-15 is a tolerance. Fix for bug 1766. Possibly use bpTol instead?
676  // DNS: No, bpTol tends to be ridiculously small and this might cause
677  // excessively small time steps. I would agree if bpTol had a floor value,
678  // such as 1e-15. Steps smaller than this are unjustified and numerically
679  // problematic. For reference, light travels 0.3 micron in 1e-15 seconds.
680  if (TVVEC[i].first >= currentTime - 1e-15 && model_.riseTime != 0 && model_.fallTime != 0)
681  {
682  breakPointTimes.push_back(Util::BreakPoint(TVVEC[i].first, Util::SIMPLE_BREAKPOINT));
683  }
684  }
685 
686 #ifdef Xyce_DEBUG_DEVICE
687  if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
688  {
689  Xyce::dout() << "DAC ----------------------------------------" << std::endl;
690  Xyce::dout() << "DAC getInstanceBreakPoints " << std::endl;
691  Xyce::dout() << "DAC Debug output. name = " << getName() << std::endl;
692  Xyce::dout() << "DAC setting breakpoints at currentTime = " << currentTime << std::endl;
693  Xyce::dout() << "DAC breakpoints: " << std::endl;
694 
695  std::vector< Util::BreakPoint >::iterator beg = breakPointTimes.begin();
696  std::vector< Util::BreakPoint >::iterator end = breakPointTimes.end();
697  std::vector< Util::BreakPoint >::iterator itBP = beg;
698  for (;itBP!=end;++itBP)
699  {
700  Util::BreakPoint & bp = *itBP;
701  Xyce::dout() << "DAC breakpoint: " << bp.value() << std::endl;
702  }
703 
704  Xyce::dout() << "DAC ----------------------------------------" << std::endl;
705  }
706 #endif
707 
708  return bsuccess;
709 }
710 
711 //-----------------------------------------------------------------------------
712 // Function : Instance::getInternalState
713 // Purpose : Generates an DeviceState object and populates
714 // it with the contents of the TVVEC vector for use by
715 // restarts
716 //
717 // Special Notes :
718 //
719 // Scope : public
720 // Creator : Tom Russo, SNL, Component Information and Models
721 // Creation Date : 09/03/04
722 //-----------------------------------------------------------------------------
724 {
725  int vsize,i,j;
726  // allocate object to return
727  DeviceState * myState = new DeviceState;
728 
729  myState->ID=getName().getEncodedName();
730  vsize=TVVEC.size();
731  // pack the pairs into the single vector of doubles.
732  myState->data.resize(vsize*2);
733  for (i=0;i<vsize;++i)
734  {
735  j=i*2;
736  myState->data[j]=TVVEC[i].first;
737  myState->data[j+1]=TVVEC[i].second;
738  }
739 
740  return myState;
741 }
742 //-----------------------------------------------------------------------------
743 // Function : Instance::setInternalState
744 // Purpose : Reload TVVEC data from restart
745 //
746 // Special Notes :
747 //
748 // Scope : public
749 // Creator : Tom Russo, SNL, Component Information and Models
750 // Creation Date : 09/03/04
751 //-----------------------------------------------------------------------------
753 {
754  int dsize=state.data.size();
755  int vsize,i,j;
756  if (getName().getEncodedName() != state.ID)
757  {
758  Report::DevelFatal().in("DAC::Instance::setInternal") << "ID(" << state.ID << ") from restart does not match my name (" << getName() << ")";
759  return false;
760  }
761 
762  if (dsize%2 != 0)
763  {
764  UserError(*this) << "Data size from restart (" << dsize << " not a multiple of 2!";
765  return false;
766  }
767 
768  vsize=dsize/2;
769  TVVEC.clear();
770  TVVEC.resize(vsize);
771  for (i=0;i<vsize;++i)
772  {
773  j=i*2;
774  TVVEC[i].first=state.data[j];
775  TVVEC[i].second=state.data[j+1];
776  }
777 
778  return true;
779 }
780 
781 //-----------------------------------------------------------------------------
782 // Function : Instance::varTypes
783 // Purpose :
784 // Special Notes :
785 // Scope : public
786 // Creator : Eric R. Keiter
787 // Creation Date : 05/12/09
788 //-----------------------------------------------------------------------------
789 void Instance::varTypes( std::vector<char> & varTypeVec )
790 {
791  varTypeVec.resize(1);
792  varTypeVec[0] = 'I';
793 }
794 
795 //----------------------------------------------------------------------------
796 // Function : Model::processParams
797 // Purpose :
798 // Special Notes :
799 // Scope : public
800 // Creator : Lon Waters
801 // Creation Date : 07/29/2002
802 //----------------------------------------------------------------------------
804 {
805  return true;
806 }
807 
808 //----------------------------------------------------------------------------
809 // Function : Model::processInstanceParams
810 // Purpose :
811 // Special Notes :
812 // Scope : public
813 // Creator : Dave Shirely, PSSI
814 // Creation Date : 03/23/06
815 //----------------------------------------------------------------------------
817 {
818 
819  std::vector<Instance*>::iterator iter;
820  std::vector<Instance*>::iterator first = instanceContainer.begin();
821  std::vector<Instance*>::iterator last = instanceContainer.end();
822 
823  for (iter=first; iter!=last; ++iter)
824  {
825  (*iter)->processParams();
826  }
827 
828  return true;
829 }
830 
831 //----------------------------------------------------------------------------
832 // Function : Model::Model
833 // Purpose : constructor
834 // Special Notes :
835 // Scope : public
836 // Creator : Lon Waters
837 // Creation Date : 07/29/2002
838 //----------------------------------------------------------------------------
840  const Configuration & configuration,
841  const ModelBlock& MB,
842  const FactoryBlock & factory_block)
843  : DeviceModel(MB, configuration.getModelParameters(), factory_block),
844  riseTime(1.0e-9),
845  fallTime(1.0e-9),
846  R(.01),
847  C(0.0),
848  L(0.0),
849  includeTransitionBP_(true)
850 {
851 
852  // Set params to constant default values:
853  setDefaultParams ();
854 
855  // Set params according to .model line and constant defaults from metadata:
856  setModParams (MB.params);
857 
858  // Set any non-constant parameter defaults:
859 
860  // Calculate any parameters specified as expressions:
862 
863  // calculate dependent (ie computed) params and check for errors:
864 
865  processParams ();
866 }
867 
868 //----------------------------------------------------------------------------
869 // Function : Model::Model
870 // Purpose : destructor
871 // Special Notes :
872 // Scope : public
873 // Creator : Lon Waters
874 // Creation Date : 07/29/2002
875 //----------------------------------------------------------------------------
877 {
878  std::vector<Instance*>::iterator iter;
879  std::vector<Instance*>::iterator first = instanceContainer.begin();
880  std::vector<Instance*>::iterator last = instanceContainer.end();
881 
882  for (iter=first; iter!=last; ++iter)
883  {
884  delete (*iter);
885  }
886 }
887 
888 //----------------------------------------------------------------------------
889 // Function : printOutInstances
890 // Purpose : debugging tool
891 // Special Notes :
892 // Scope : public
893 // Creator : Lon Waters
894 // Creation Date : 07/29/2002
895 //----------------------------------------------------------------------------
896 std::ostream &Model::printOutInstances(std::ostream &os) const
897 {
898  std::vector<Instance*>::const_iterator iter;
899  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
900  std::vector<Instance*>::const_iterator last = instanceContainer.end();
901 
902  int i;
903  os << std::endl;
904  os << " name\t\tmodelName\tParameters" << std::endl;
905 
906  for (i = 0, iter = first; iter != last; ++iter, ++i)
907  {
908  os << " " << i << ": " << (*iter)->getName() << "\t";
909  os << getName();
910  os << "\t\tfile = " << (*iter)->file;
911  os << std::endl;
912  }
913 
914  os << std::endl;
915 
916  return os;
917 }
918 
919 //-----------------------------------------------------------------------------
920 // Function : Model::forEachInstance
921 // Purpose :
922 // Special Notes :
923 // Scope : public
924 // Creator : David Baur
925 // Creation Date : 2/4/2014
926 //-----------------------------------------------------------------------------
927 /// Apply a device instance "op" to all instances associated with this
928 /// model
929 ///
930 /// @param[in] op Operator to apply to all instances.
931 ///
932 ///
933 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
934 {
935  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
936  op(*it);
937 }
938 
939 
940 
941 // DAC Master functions:
942 
943 //-----------------------------------------------------------------------------
944 // Function : Master::updateState
945 // Purpose :
946 // Special Notes :
947 // Scope : public
948 // Creator : Richard Schiek, Electrical and Microsystems Modeling
949 // Creation Date : 02/25/2009
950 //-----------------------------------------------------------------------------
951 bool Master::updateState (double * solVec, double * staVec, double * stoVec)
952 {
953  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
954  {
955  Instance & di = *(*it);
956 
957  // here we update the voltage
958  di.updateVoltage(getSolverState().currTime);
959 
960  // get the value for v_pos, v_neg, i_bra
961  di.v_pos = solVec[di.li_Pos];
962  di.v_neg = solVec[di.li_Neg];
963  di.i_bra = solVec[di.li_Bra];
964  di.vDrop = (di.v_pos-di.v_neg-di.voltage_);
965 #ifdef Xyce_DEBUG_DEVICE
966  Xyce::dout() << "DAC ----------------------------------------" << std::endl;
967  Xyce::dout() << "DAC Debug output. name = " << di.getName() << std::endl;
968  Xyce::dout() << "DAC v_pos = " << di.v_pos <<std::endl;
969  Xyce::dout() << "DAC v_neg = " << di.v_neg <<std::endl;
970  Xyce::dout() << "DAC i_bra = " << di.i_bra <<std::endl;
971  Xyce::dout() << "DAC vDrop = " << di.vDrop <<std::endl;
972  Xyce::dout() << "DAC voltage_ = " << di.voltage_ <<std::endl;
973  Xyce::dout() << "DAC ----------------------------------------" << std::endl;
974 #endif
975  }
976 
977  return true;
978 }
979 
980 //-----------------------------------------------------------------------------
981 // Function : Master::updateSecondaryState
982 // Purpose :
983 // Special Notes :
984 // Scope : public
985 // Creator : Richard Schiek, Electrical and Microsystems Modeling
986 // Creation Date : 02/25/2009
987 //-----------------------------------------------------------------------------
988 bool Master::updateSecondaryState ( double * staDerivVec, double * stoVec )
989 {
990  return true;
991 }
992 
993 //-----------------------------------------------------------------------------
994 // Function : Master::loadDAEVectors
995 // Purpose :
996 // Special Notes :
997 // Scope : public
998 // Creator : Eric Keiter, SNL
999 // Creation Date : 11/26/08
1000 //-----------------------------------------------------------------------------
1001 bool Master::loadDAEVectors (double * solVec, double * fVec, double *qVec, double * bVec, double * storeLeadF, double * storeLeadQ)
1002 {
1003  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
1004  {
1005  Instance & di = *(*it);
1006 
1007  fVec[di.li_Pos] += di.i_bra;
1008 
1009  fVec[di.li_Neg] += -di.i_bra;
1010 
1011  fVec[di.li_Bra] += di.vDrop;
1012  }
1013 
1014  return true;
1015 }
1016 
1017 //-----------------------------------------------------------------------------
1018 // Function : Master::loadDAEMatrices
1019 // Purpose :
1020 // Special Notes :
1021 // Scope : public
1022 // Creator : Eric Keiter, SNL
1023 // Creation Date : 11/26/08
1024 //-----------------------------------------------------------------------------
1025 bool Master::loadDAEMatrices (N_LAS_Matrix & dFdx, N_LAS_Matrix & dQdx)
1026 {
1027  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
1028  {
1029  Instance & di = *(*it);
1030 
1031  dFdx[di.li_Pos][di.APosEquBraVarOffset] += 1.0;
1032 
1033  dFdx[di.li_Neg][di.ANegEquBraVarOffset] -= 1.0;
1034 
1035  dFdx[di.li_Bra][di.ABraEquPosNodeOffset] += 1.0;
1036 
1037  dFdx[di.li_Bra][di.ABraEquNegNodeOffset] -= 1.0;
1038  }
1039  return true;
1040 }
1041 
1042 Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
1043 {
1044 
1045  return new Master(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
1046 }
1047 
1049 {
1051  .registerDevice("dac", 1)
1052  .registerModelType("dac", 1);
1053 }
1054 
1055 } // namespace DAC
1056 } // namespace Device
1057 } // namespace Xyce