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