Xyce  6.1
N_DEV_Inductor.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_Inductor.C,v $
27 //
28 // Purpose :
29 //
30 // Special Notes :
31 //
32 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
33 //
34 // Creation Date : 02/28/00
35 //
36 // Revision Information:
37 // ---------------------
38 //
39 // Revision Number: $Revision: 1.287 $
40 //
41 // Revision Date : $Date: 2015/09/09 19:26:09 $
42 //
43 // Current Owner : $Author: tvrusso $
44 //-------------------------------------------------------------------------
45 #include <Xyce_config.h>
46 
47 // ---------- Standard Includes ----------
48 #include <N_UTL_Math.h>
49 #include <algorithm>
50 #include <fstream>
51 #include <set>
52 #include <vector>
53 
54 // ---------- Xyce Includes ----------
55 #include <N_DEV_DeviceOptions.h>
56 #include <N_DEV_ExternData.h>
57 #include <N_DEV_Inductor.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 #include <N_UTL_FeatureTest.h>
66 
67 namespace Xyce {
68 namespace Device {
69 namespace Inductor {
70 
72 {
73  p.addPar("L", 0.0, &Inductor::Instance::baseL)
74  .setExpressionAccess(ParameterType::TIME_DEP)
75  .setUnit(U_HENRY)
76  .setDescription("Inductance")
77  .setAnalyticSensitivityAvailable(true)
78  .setSensitivityFunctor(&indSens);
79 
80  p.addPar("IC", 0.0, &Inductor::Instance::IC)
81  .setGivenMember(&Inductor::Instance::ICGiven)
82  .setUnit(U_AMP)
83  .setDescription("Initial current through device");
84 
85  p.addPar("TEMP", 0.0, &Inductor::Instance::temp)
86  .setExpressionAccess(ParameterType::TIME_DEP)
87  .setGivenMember(&Inductor::Instance::tempGiven)
88  .setUnit(U_DEGC)
89  .setCategory(CAT_MATERIAL)
90  .setDescription("Device temperature");
91 
93  .setGivenMember(&Inductor::Instance::tempCoeff1Given)
94  .setUnit(U_DEGCM1)
95  .setDescription("Linear Temperature Coefficient");
96 
98  .setGivenMember(&Inductor::Instance::tempCoeff2Given)
99  .setUnit(U_DEGCM2)
100  .setDescription("Quadratic Temperature Coefficient");
101 
102  // This call tells the parameter handling code that TC can be specified
103  // as a vector with up to two elements as in TC=a,b. It then translates
104  // TC=a,b into TC1=a TC2=b. Likewise, TC=a will translate into TC1=a
105  p.makeVector ("TC", 2);
106 }
107 
109 {
110  // Set up double precision variables:
112  .setUnit(U_NONE)
113  .setDescription("Inductance Multiplier");
114 
115  p.addPar("IC", 0.0, &Inductor::Model::IC)
116  .setUnit(U_AMP)
117  .setDescription("Initial current through device");
118 
119  p.addPar("TNOM", 27.0, &Inductor::Model::tnom)
120  .setUnit(U_DEGC)
121  .setCategory(CAT_MATERIAL)
122  .setDescription("Reference temperature");
123 
124  p.addPar("TC1",0.0, &Inductor::Model::tempCoeff1)
125  .setUnit(U_DEGCM1)
126  .setCategory(CAT_MATERIAL)
127  .setDescription("First order temperature coeff.");
128 
129  p.addPar("TC2", 0.0, &Inductor::Model::tempCoeff2)
130  .setUnit(U_DEGCM2)
131  .setCategory(CAT_MATERIAL)
132  .setDescription("Second order temperature coeff.");
133 }
134 
135 //
136 // static class member inits
137 //
138 std::vector< std::vector<int> > Instance::jacStamp_BASE;
139 
140 // Class Instance
141 //-----------------------------------------------------------------------------
142 // Function : Instance::processParams
143 // Purpose :
144 // Special Notes :
145 // Scope : public
146 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
147 // Creation Date : 6/03/02
148 //-----------------------------------------------------------------------------
150 {
151  if (!given("TEMP"))
152  temp = getDeviceOptions().temp.getImmutableValue<double>();
153 
154  if (!tempCoeff1Given)
156  if (!tempCoeff2Given)
158 
159  // If there are any time dependent parameters, set their values at for
160  // the current time.
161 
162  // now set the temperature related stuff.
164  return true;
165 }
166 
167 //-----------------------------------------------------------------------------
168 // Function : Instance::updateTemperature
169 // Purpose :
170 // Special Notes :
171 // Scope : public
172 // Creator : Tom Russo, Component Information and Models
173 // Creation Date : 02/27/01
174 //-----------------------------------------------------------------------------
175 bool Instance::updateTemperature ( const double & temp)
176 {
177  double difference = temp - model_.tnom;
178  double factor = model_.inductanceMultiplier*(1.0 + tempCoeff1*difference +
179  tempCoeff2*difference*difference);
180  L = baseL*factor;
181  return true;
182 }
183 
184 //-----------------------------------------------------------------------------
185 // Function : Instance::Instance
186 // Purpose : constructor
187 // Special Notes :
188 // Scope : public
189 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
190 // Creation Date : 3/16/00
191 //-----------------------------------------------------------------------------
193  const Configuration & configuration,
194  const InstanceBlock & instance_block,
195  Model & model,
196  const FactoryBlock & factory_block)
197  : DeviceInstance(instance_block, configuration.getInstanceParameters(), factory_block),
198  L(0),
199  IC(0),
200  ICGiven(false),
201  model_(model),
202  baseL(0.0),
203  temp(getDeviceOptions().temp.getImmutableValue<double>()),
204  tempGiven(0),
205  tempCoeff1(0.0),
206  tempCoeff2(0.0),
207  tempCoeff1Given(false),
208  tempCoeff2Given(false),
209  li_fstate(-1),
210  li_Pos(-1),
211  li_Neg(-1),
212  li_Bra(-1),
213  li_branch_data(0),
214  ABraEquPosNodeOffset(-1),
215  ABraEquNegNodeOffset(-1),
216  ABraEquBraVarOffset(-1),
217  APosEquBraVarOffset(-1),
218  ANegEquBraVarOffset(-1)
220  ,
221  fPosEquBraVarPtr(0),
222  fNegEquBraVarPtr(0),
223  fBraEquPosNodePtr(0),
224  fBraEquNegNodePtr(0),
225  fBraEquBraVarPtr(0),
226  qBraEquBraVarPtr(0)
227 #endif
228 {
229  numExtVars = 2;
230  numIntVars = 1;
231  numStateVars = 1;
232  setNumBranchDataVars(0); // by default don't allocate space in branch vectors
233  numBranchDataVarsIfAllocated = 1; // this is the space to allocate if lead current or power is needed.
234 
235  if( jacStamp_BASE.empty() )
236  {
237  jacStamp_BASE.resize(3);
238 
239  jacStamp_BASE[0].resize(1);
240  jacStamp_BASE[0][0] = 2;
241 
242  jacStamp_BASE[1].resize(1);
243  jacStamp_BASE[1][0] = 2;
244 
245  jacStamp_BASE[2].resize(3);
246  jacStamp_BASE[2][0] = 0;
247  jacStamp_BASE[2][1] = 1;
248  jacStamp_BASE[2][2] = 2;
249  }
250 
251  // Set params to constant default values:
252  setDefaultParams ();
253 
254  // Set params according to instance line and constant defaults from metadata:
255  setParams (instance_block.params);
256 
257  // Set any non-constant parameter defaults:
258  if (!given("L"))
259  {
260  UserError0(*this) << "Could not find L parameter in instance.";
261  }
262 
263  // Calculate any parameters specified as expressions:
265 
266  // calculate dependent (ie computed) params and check for errors:
267  processParams ();
268 
269  // set up numIntVars:
270  numIntVars = 1;
271 
272  // set up numStateVars:
273  numStateVars = 2;
274 }
275 
276 //-----------------------------------------------------------------------------
277 // Function : Instance::~Instance
278 // Purpose : destructor
279 // Special Notes :
280 // Scope : public
281 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
282 // Creation Date : 3/16/00
283 //-----------------------------------------------------------------------------
285 {
286 }
287 
288 //-----------------------------------------------------------------------------
289 // Function : Instance::setupPointers
290 // Purpose :
291 // Special Notes :
292 // Scope : public
293 // Creator : Eric Keiter, SNL
294 // Creation Date : 11/30/08
295 //-----------------------------------------------------------------------------
297 {
298 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
299  Linear::Matrix & dFdx = *(extData.dFdxMatrixPtr);
300  Linear::Matrix & dQdx = *(extData.dQdxMatrixPtr);
301 
307 
309 
310 #endif
311 }
312 
313 //-----------------------------------------------------------------------------
314 // Function : Instance::registerLIDs
315 // Purpose :
316 // Special Notes :
317 // Scope : public
318 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
319 // Creation Date : 6/21/02
320 //-----------------------------------------------------------------------------
321 void Instance::registerLIDs(const std::vector<int> & intLIDVecRef,
322  const std::vector<int> & extLIDVecRef)
323 {
324  AssertLIDs(intLIDVecRef.size() == numIntVars);
325  AssertLIDs(extLIDVecRef.size() == numExtVars);
326 
327  // copy over the global ID lists.
328  intLIDVec = intLIDVecRef;
329  extLIDVec = extLIDVecRef;
330 
331  // Now use these lists to obtain the indices into the
332  // linear algebra entities. This assumes an order.
333  // For the matrix indices, first do the rows.
334 
335  li_Pos = extLIDVec[0];
336  li_Neg = extLIDVec[1];
337  li_Bra = intLIDVec[0];
338 
339  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
340  {
341  Xyce::dout() << section_divider << std::endl;
342 
343  Xyce::dout() << "::registerLIDs:\n";
344  Xyce::dout() << " name = " << getName() << std::endl;
345 
346  Xyce::dout() << "\nlocal solution indices:\n";
347  Xyce::dout() << " li_Pos = "<< li_Pos << std::endl;
348  Xyce::dout() << " li_Neg = "<< li_Neg << std::endl;
349  Xyce::dout() << " li_Bra = "<< li_Bra << std::endl;
350 
351  Xyce::dout() << section_divider << std::endl;
352  }
353 
354 }
355 
356 //-----------------------------------------------------------------------------
357 // Function : Instance::registerBranchDataLIDs
358 // Purpose :
359 // Special Notes :
360 // Scope : public
361 // Creator : Richard Schiek, Electrical Systems Modeling
362 // Creation Date : 12/18/2012
363 //-----------------------------------------------------------------------------
364 /// Register the local store IDs
365 ///
366 /// In addition to state vector, Xyce maintains a separate datastructure
367 /// called a "branch data" vector. As with other such vectors, the device
368 /// declares at construction time how many branch vector entries it needs,
369 /// and later Topology assigns locations for devices, returning LIDs.
370 ///
371 /// These LIDs are stored in this method for later use.
372 ///
373 /// The Resistor device uses exactly one "branch data vector" element, where
374 ///
375 /// @param stoLIDVecRef Store variable local IDs
376 ///
377 /// @author Richard Schiek, Electrical Systems Modeling
378 /// @date 12/18/2012
379 
380 void Instance::registerBranchDataLIDs(const std::vector<int> & branchLIDVecRef)
381 {
382  AssertLIDs(branchLIDVecRef.size() == getNumBranchDataVars());
383 
384  if (loadLeadCurrent)
385  {
386  li_branch_data= branchLIDVecRef[0];
387  }
388 }
389 
390 //-----------------------------------------------------------------------------
391 // Function : Instance::loadNodeSymbols
392 // Purpose :
393 // Special Notes :
394 // Scope : public
395 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
396 // Creation Date : 05/13/05
397 //-----------------------------------------------------------------------------
398 void Instance::loadNodeSymbols(Util::SymbolTable &symbol_table) const
399 {
400  addInternalNode(symbol_table, li_Bra, getName(), "branch");
401  if (loadLeadCurrent)
402  {
403  addBranchDataNode( symbol_table, li_branch_data, getName(), "BRANCH_D");
404  }
405 }
406 
407 //-----------------------------------------------------------------------------
408 // Function : Instance::registerStateLIDs
409 // Purpose :
410 // Special Notes :
411 // Scope : public
412 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
413 // Creation Date : 6/22/02
414 //-----------------------------------------------------------------------------
415 void Instance::registerStateLIDs( const std::vector<int> & staLIDVecRef )
416 {
417  AssertLIDs(staLIDVecRef.size() == numStateVars);
418 
419  // copy over the global ID lists.
420  staLIDVec = staLIDVecRef;
421 
422  li_fstate = staLIDVec[0];
423 }
424 
425 //-----------------------------------------------------------------------------
426 // Function : Instance::jacobianStamp
427 // Purpose :
428 // Special Notes :
429 // Scope : public
430 // Creator : Robert Hoekstra, SNL
431 // Creation Date : 08/21/02
432 //-----------------------------------------------------------------------------
433 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
434 {
435  return jacStamp_BASE;
436 }
437 
438 //-----------------------------------------------------------------------------
439 // Function : Instance::registerJacLIDs
440 // Purpose :
441 // Special Notes :
442 // Scope : public
443 // Creator : Robert Hoekstra, SNL
444 // Creation Date : 08/27/02
445 //-----------------------------------------------------------------------------
446 void Instance::registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec )
447 {
448  DeviceInstance::registerJacLIDs( jacLIDVec );
449 
450  APosEquBraVarOffset = jacLIDVec[0][0];
451  ANegEquBraVarOffset = jacLIDVec[1][0];
452  ABraEquPosNodeOffset = jacLIDVec[2][0];
453  ABraEquNegNodeOffset = jacLIDVec[2][1];
454  ABraEquBraVarOffset = jacLIDVec[2][2];
455 }
456 
457 //-----------------------------------------------------------------------------
458 // Function : Instance::updatePrimaryState
459 // Purpose :
460 // Special Notes :
461 // Scope : public
462 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
463 // Creation Date : 02/01/01
464 //-----------------------------------------------------------------------------
466 {
467  double * solVec = extData.nextSolVectorRawPtr;
468  double * staVec = extData.nextStaVectorRawPtr;
469  double current = solVec[li_Bra];
470  if( (getSolverState().dcopFlag) && ICGiven )
471  current = IC;
472 
473  f0 = L*current;
474  staVec[li_fstate] = f0;
475 
476  return true;
477 }
478 
479 //-----------------------------------------------------------------------------
480 // Function : Instance::updateSecondaryState
481 // Purpose :
482 // Special Notes :
483 // Scope : public
484 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
485 // Creation Date : 02/01/01
486 //-----------------------------------------------------------------------------
488 {
489  return true;
490 }
491 
492 //-----------------------------------------------------------------------------
493 // Function : Instance::loadDAEQVector
494 //
495 // Purpose : Loads the Q-vector contributions for a single
496 // instance.
497 //
498 // Special Notes : The "Q" vector is part of a standard DAE formalism in
499 // which the system of equations is represented as:
500 //
501 // f(x) = dQ(x)/dt + F(x) - B(t) = 0
502 //
503 // Scope : public
504 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
505 // Creation Date : 01/26/03
506 //-----------------------------------------------------------------------------
508 {
509  double * qVec = extData.daeQVectorRawPtr;
510 
511  qVec[li_Bra] += f0;
512 
513  return true;
514 }
515 
516 //-----------------------------------------------------------------------------
517 // Function : Instance::loadDAEFVector
518 //
519 // Purpose : Loads the F-vector contributions for a single
520 // instance.
521 //
522 // Special Notes :
523 //
524 // Scope : public
525 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
526 // Creation Date : 01/26/03
527 //-----------------------------------------------------------------------------
529 {
530  double current;
531  double coef;
532 
533  double * solVec = extData.nextSolVectorRawPtr;
534  double * fVec = extData.daeFVectorRawPtr;
535 
536  double v_pos = solVec[li_Pos];
537  double v_neg = solVec[li_Neg];
538  double vind = v_pos-v_neg;
539 
540  // In the case that an initial condition is specified, the inductor is set up
541  // like a current source for the DC operating point. We don't deal with the
542  // node voltages in that case, so set coef to 0.
543  if (getSolverState().dcopFlag && ICGiven)
544  {
545  current = IC;
546  coef = 0.0;
547  }
548  else
549  {
550  current = solVec[li_Bra];
551  coef = -vind;
552  }
553 
554  // load the current into the two KCL rhs vector elements
555  fVec[li_Pos] += current;
556  fVec[li_Neg] += -current;
557  fVec[li_Bra] += coef;
558 
559  return true;
560 }
561 
562 //-----------------------------------------------------------------------------
563 // Function : Instance::loadDAEdQdx
564 //
565 // Purpose : Loads the Q-vector contributions for a single
566 // instance.
567 // Scope : public
568 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
569 // Creation Date : 03/05/04
570 //-----------------------------------------------------------------------------
572 {
573  Linear::Matrix & dQdx = *(extData.dQdxMatrixPtr);
574  dQdx[li_Bra][ABraEquBraVarOffset] += L;
575  return true;
576 }
577 
578 //-----------------------------------------------------------------------------
579 // Function : Instance::loadDAEdFdx ()
580 //
581 // Purpose : Loads the F-vector contributions for a single
582 // instance.
583 //
584 // Special Notes :
585 //
586 // Scope : public
587 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
588 // Creation Date : 03/05/04
589 //-----------------------------------------------------------------------------
591 {
592  Linear::Matrix & dFdx = *(extData.dFdxMatrixPtr);
593  if ( getSolverState().dcopFlag && ICGiven )
594  {
595  // In the case that an initial condition is specified for an
596  // inductor, the DC op should be set up like a current source just
597  // for the operating point calculation.
598  dFdx[li_Pos][APosEquBraVarOffset] += 0.0;
599  dFdx[li_Neg][ANegEquBraVarOffset] += 0.0;
600  dFdx[li_Bra][ABraEquPosNodeOffset] += 0.0;
601  dFdx[li_Bra][ABraEquNegNodeOffset] += 0.0;
602  dFdx[li_Bra][ABraEquBraVarOffset] += 1.0;
603  }
604  else
605  {
606  dFdx[li_Pos][APosEquBraVarOffset] += 1.0;
607  dFdx[li_Neg][ANegEquBraVarOffset] -= 1.0;
608  dFdx[li_Bra][ABraEquPosNodeOffset] -= 1.0;
609  dFdx[li_Bra][ABraEquNegNodeOffset] += 1.0;
610  dFdx[li_Bra][ABraEquBraVarOffset] += 0.0;
611  }
612 
613  return true;
614 }
615 
616 //-----------------------------------------------------------------------------
617 // Function : Instance::setIC
618 // Purpose :
619 // Special Notes :
620 // Scope : public
621 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
622 // Creation Date : 1/11/02
623 //-----------------------------------------------------------------------------
625 {
626  int i_bra_sol;
627  int i_f_state;
628  double * nextStaVector = extData.nextStaVectorRawPtr;
629  double * currStaVector = extData.currStaVectorRawPtr;
630 
631  double * nextSolVector = extData.nextSolVectorRawPtr;
632  double * currSolVector = extData.currSolVectorRawPtr;
633 
634  if (ICGiven)
635  {
636  f0 = L*IC;
637  currStaVector[li_fstate] = f0;
638  nextStaVector[li_fstate] = f0;
639 
640  currSolVector[li_Bra] = IC;
641  nextSolVector[li_Bra] = IC;
642  }
643 
644  return true;
645 }
646 
647 //-----------------------------------------------------------------------------
648 // Function : Instance::varTypes
649 // Purpose :
650 // Special Notes :
651 // Scope : public
652 // Creator : Rob Hoekstra, SNL, Parallel Computational Sciences
653 // Creation Date : 2/17/04
654 //-----------------------------------------------------------------------------
655 void Instance::varTypes( std::vector<char> & varTypeVec )
656 {
657  varTypeVec.resize(1);
658  varTypeVec[0] = 'I';
659 }
660 
661 //-----------------------------------------------------------------------------
662 // Function : Model::processParams
663 // Purpose :
664 // Special Notes :
665 // Scope : public
666 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
667 // Creation Date : 6/03/02
668 //-----------------------------------------------------------------------------
670 {
671  return true;
672 }
673 
674 //----------------------------------------------------------------------------
675 // Function : Model::processInstanceParams
676 // Purpose :
677 // Special Notes :
678 // Scope : public
679 // Creator : Dave Shirely, PSSI
680 // Creation Date : 03/23/06
681 //----------------------------------------------------------------------------
683 {
684  std::vector<Instance*>::iterator iter;
685  std::vector<Instance*>::iterator first = instanceContainer.begin();
686  std::vector<Instance*>::iterator last = instanceContainer.end();
687 
688  for (iter=first; iter!=last; ++iter)
689  {
690  (*iter)->processParams();
691  }
692 
693  return true;
694 }
695 
696 //-----------------------------------------------------------------------------
697 // Function : Model::Model
698 // Purpose : block constructor
699 // Special Notes :
700 // Scope : public
701 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
702 // Creation Date : 3/16/00
703 //-----------------------------------------------------------------------------
705  const Configuration & configuration,
706  const ModelBlock & MB,
707  const FactoryBlock & factory_block)
708  : DeviceModel(MB, configuration.getModelParameters(), factory_block),
709  inductanceMultiplier(1.0),
710  IC(0.0),
711  tempCoeff1(0.0),
712  tempCoeff2(0.0),
713  tnom(getDeviceOptions().tnom),
714  tnomGiven(0)
715 {
716 
717  // Set params to constant default values:
718  setDefaultParams ();
719 
720  // Set params according to .model line and constant defaults from metadata:
721  setModParams (MB.params);
722 
723  // Set any non-constant parameter defaults:
724  if (!given("TNOM"))
726 
727  // Calculate any parameters specified as expressions:
729 
730  // calculate dependent (ie computed) params and check for errors:
731 
732  processParams ();
733 }
734 
735 //-----------------------------------------------------------------------------
736 // Function : Model::~Model
737 // Purpose : destructor
738 // Special Notes :
739 // Scope : public
740 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
741 // Creation Date : 3/16/00
742 //-----------------------------------------------------------------------------
744 {
745  std::vector<Instance*>::iterator iter;
746  std::vector<Instance*>::iterator first = instanceContainer.begin();
747  std::vector<Instance*>::iterator last = instanceContainer.end();
748 
749  for (iter=first; iter!=last; ++iter)
750  {
751  delete (*iter);
752  }
753 
754 }
755 
756 //-----------------------------------------------------------------------------
757 // Function : Model::printOutInstances
758 // Purpose : debugging tool.
759 // Special Notes :
760 // Scope : public
761 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
762 // Creation Date : 4/04/00
763 //-----------------------------------------------------------------------------
764 std::ostream &Model::printOutInstances(std::ostream &os) const
765 {
766  std::vector<Instance*>::const_iterator iter;
767  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
768  std::vector<Instance*>::const_iterator last = instanceContainer.end();
769 
770  int i, isize;
771  isize = instanceContainer.size();
772 
773  os << std::endl;
774  os << "Number of Inductor instances: " << isize << std::endl;
775  os << " name=\t\tmodelName\tParameters" << std::endl;
776  for (i=0, iter=first; iter!=last; ++iter, ++i)
777  {
778  os << " " << i << ": " << (*iter)->getName() << "\t";
779  os << getName();
780  os << "\t\tL = " << (*iter)->L;
781  os << "\tIC = " << (*iter)->IC;
782  os << std::endl;
783  }
784 
785  os << std::endl;
786 
787  return os;
788 }
789 
790 //-----------------------------------------------------------------------------
791 // Function : Model::forEachInstance
792 // Purpose :
793 // Special Notes :
794 // Scope : public
795 // Creator : David Baur
796 // Creation Date : 2/4/2014
797 //-----------------------------------------------------------------------------
798 /// Apply a device instance "op" to all instances associated with this
799 /// model
800 ///
801 /// @param[in] op Operator to apply to all instances.
802 ///
803 ///
804 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
805 {
806  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
807  op(*it);
808 }
809 
810 
811 // Inductor Master functions:
812 
813 //-----------------------------------------------------------------------------
814 // Function : Master::updateState
815 // Purpose :
816 // Special Notes :
817 // Scope : public
818 // Creator : Eric Keiter, SNL
819 // Creation Date : 11/26/08
820 //-----------------------------------------------------------------------------
821 bool Master::updateState (double * solVec, double * staVec, double * stoVec)
822 {
823  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
824  {
825  Instance & inst = *(*it);
826 
827  double current = solVec[inst.li_Bra];
828 
829  if( (getSolverState().dcopFlag) && inst.ICGiven )
830  current = inst.IC;
831 
832  inst.f0 = inst.L*current;
833  staVec[inst.li_fstate] = inst.f0;
834  }
835 
836  return true;
837 }
838 
839 //-----------------------------------------------------------------------------
840 // Function : Master::updateSecondaryState
841 // Purpose :
842 // Special Notes :
843 // Scope : public
844 // Creator : Eric Keiter, SNL
845 // Creation Date : 11/26/08
846 //-----------------------------------------------------------------------------
847 bool Master::updateSecondaryState ( double * staDerivVec, double * stoVec )
848 {
849  return true;
850 }
851 
852 //-----------------------------------------------------------------------------
853 // Function : Master::loadDAEVectors
854 // Purpose :
855 // Special Notes :
856 // Scope : public
857 // Creator : Eric Keiter, SNL
858 // Creation Date : 11/26/08
859 //-----------------------------------------------------------------------------
860 bool Master::loadDAEVectors (double * solVec, double * fVec, double *qVec, double * bVec, double * storeLeadF, double * storeLeadQ, double * leadF, double * leadQ, double * junctionV)
861 {
862  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
863  {
864  Instance & inst = *(*it);
865 
866  double current = 0.0;
867  double coef = 0.0;
868 
869  double v_pos = solVec[inst.li_Pos];
870  double v_neg = solVec[inst.li_Neg];
871  double vind = v_pos-v_neg;
872 
873  // In the case that an initial condition is specified, the inductor is set up
874  // like a current source for the DC operating point. We don't deal with the
875  // node voltages in that case, so set coef to 0.
876  if (getSolverState().dcopFlag && inst.ICGiven)
877  {
878  current = inst.IC;
879  solVec[inst.li_Bra] = current;
880  coef = 0.0;
881  }
882  else
883  {
884  current = solVec[inst.li_Bra];
885  coef = -vind;
886  }
887 
888  // load the current into the two KCL rhs vector elements
889  fVec[inst.li_Pos] += current;
890  fVec[inst.li_Neg] += -current;
891  fVec[inst.li_Bra] += coef;
892  qVec[inst.li_Bra] += inst.f0;
893  if( inst.loadLeadCurrent )
894  {
895  leadF[inst.li_branch_data] = current;
896  junctionV[inst.li_branch_data] = vind;
897  }
898  }
899 return true;
900 }
901 
902 //-----------------------------------------------------------------------------
903 // Function : Master::loadDAEMatrices
904 // Purpose :
905 // Special Notes :
906 // Scope : public
907 // Creator : Eric Keiter, SNL
908 // Creation Date : 11/26/08
909 //-----------------------------------------------------------------------------
910 bool Master::loadDAEMatrices (Linear::Matrix & dFdx, Linear::Matrix & dQdx)
911 {
912  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
913  {
914  Instance & inst = *(*it);
915 
916  if ( getSolverState().dcopFlag && inst.ICGiven )
917  {
918  // In the case that an initial condition is specified for an
919  // inductor, the DC op should be set up like a current source just
920  // for the operating point calculation.
921 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
922  *inst.fBraEquBraVarPtr += 1.0;
923 #else
924  dFdx[inst.li_Bra][inst.ABraEquBraVarOffset] += 1.0;
925 #endif
926  }
927  else
928  {
929 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
930  *inst.fPosEquBraVarPtr += 1.0;
931  *inst.fNegEquBraVarPtr -= 1.0;
932  *inst.fBraEquPosNodePtr -= 1.0;
933  *inst.fBraEquNegNodePtr += 1.0;
934 #else
935  dFdx[inst.li_Pos][inst.APosEquBraVarOffset] += 1.0;
936  dFdx[inst.li_Neg][inst.ANegEquBraVarOffset] -= 1.0;
937  dFdx[inst.li_Bra][inst.ABraEquPosNodeOffset] -= 1.0;
938  dFdx[inst.li_Bra][inst.ABraEquNegNodeOffset] += 1.0;
939 #endif
940  }
941 
942 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
943  *inst.qBraEquBraVarPtr += inst.L;
944 #else
945  dQdx[inst.li_Bra][inst.ABraEquBraVarOffset] += inst.L;
946 #endif
947  }
948  return true;
949 }
950 
951 Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
952 {
953 
954  return new Master(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
955 }
956 
958 {
960  .registerDevice("l", 1)
961  .registerModelType("l", 1)
962  .registerModelType("ind", 1);
963 }
964 
965 //-----------------------------------------------------------------------------
966 // Function : indSensitivity::operator
967 // Purpose : produces df/dp and dq/dp, where p=L.
968 // Special Notes :
969 // Scope : public
970 // Creator : Eric Keiter, SNL
971 // Creation Date : 7/31/2014
972 //-----------------------------------------------------------------------------
974  const ParameterBase &entity,
975  const std::string & name,
976  std::vector<double> & dfdp,
977  std::vector<double> & dqdp,
978  std::vector<double> & dbdp,
979  std::vector<int> & Findices,
980  std::vector<int> & Qindices,
981  std::vector<int> & Bindices
982  ) const
983 {
984  const ParameterBase * e1 = &entity;
985  const Instance * in = dynamic_cast<const Instance *> (e1);
986 
987  double * solVec = in->extData.nextSolVectorRawPtr;
988  double current = solVec[in->li_Bra];
989  if( (in->getSolverState().dcopFlag) && in->ICGiven )
990  {
991  current = in->IC;
992  }
993 
994  double dqdpLoc = current;
995 
996  dqdp.resize(1);
997  dqdp[0] = dqdpLoc;
998 
999  Qindices.resize(1);
1000  Qindices[0] = in->li_Bra;
1001 }
1002 
1003 } // namespace Inductor
1004 } // namespace Device
1005 } // namespace Xyce
const InstanceName & getName() const
const DeviceOptions & deviceOptions_
int li_branch_data
Index for lead current and junction voltage (for power calculations)
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
void registerBranchDataLIDs(const std::vector< int > &branchLIDVecRef)
Register the local store IDs.
static void loadInstanceParameters(ParametricData< Instance > &instance_parameters)
bool given(const std::string &parameter_name) const
Pure virtual class to augment a linear system.
Parameter may be specified as time dependent expression from netlist.
Definition: N_DEV_Pars.h:67
void addInternalNode(Util::SymbolTable &symbol_table, int index, const InstanceName &instance_name, const std::string &lead_name)
void addBranchDataNode(Util::SymbolTable &symbol_table, int index, const InstanceName &instance_name, const std::string &lead_name)
void makeVector(const std::string &cname, int len)
Allows the parameter to be specified as a vector.
Definition: N_DEV_Pars.h:1597
InstanceVector::const_iterator getInstanceEnd() const
Returns an iterator to the ending of the vector of all instances created for this device...
Base class for all parameters.
Definition: N_DEV_Pars.h:169
virtual void forEachInstance(DeviceInstanceOp &op) const
Apply a device instance "op" to all instances associated with this model.
#define AssertLIDs(cmp)
const std::vector< std::vector< int > > & jacobianStamp() const
virtual void registerJacLIDs(const JacobianStamp &jacLIDVec)
double tnom
nominal temperature for device params.
static std::vector< std::vector< int > > jacStamp_BASE
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.
void registerJacLIDs(const std::vector< std::vector< int > > &jacLIDVec)
InstanceVector::const_iterator getInstanceBegin() const
Returns an iterator to the beginning of the vector of all instances created for this device...
void varTypes(std::vector< char > &varTypeVec)
std::vector< Param > params
Parameters from the line.
void setParams(const std::vector< Param > &params)
const std::string & getName() const
void registerLIDs(const std::vector< int > &intLIDVecRef, const std::vector< int > &extLIDVecRef)
The FactoryBlock contains parameters needed by the device, instance and model creation functions...
virtual bool processParams()
processParams
const DeviceOptions & getDeviceOptions() const
void loadNodeSymbols(Util::SymbolTable &symbol_table) const
Populates and returns the store name map.
Instance(const Configuration &configuration, const InstanceBlock &instance_block, Model &model, const FactoryBlock &factory_block)
virtual bool loadDAEMatrices(Linear::Matrix &dFdx, Linear::Matrix &dQdx)
Populates the device's Jacobian object with these pointers.
virtual std::ostream & printOutInstances(std::ostream &os) const
static Config< T > & addConfiguration()
Adds the device to the Xyce device configuration.
Linear::Matrix * dFdxMatrixPtr
The Device class is an interface for device implementations.
Definition: N_DEV_Device.h:101
void registerStateLIDs(const std::vector< int > &staLIDVecRef)
bool updateTemperature(const double &temp_tmp)
static indSensitivity indSens
const SolverState & solverState_
Class Configuration contains device configuration data.
#define L
static void loadModelParameters(ParametricData< Model > &model_parameters)
const SolverState & getSolverState() const
void setNumBranchDataVars(int num_branch_data_vars)
#define Xyce_NONPOINTER_MATRIX_LOAD
Definition: N_DEV_Bsrc.C:97
static Device * factory(const Configuration &configuration, const FactoryBlock &factory_block)
ModelBlock represents a .MODEL line from the netlist.
Manages parameter binding for class C.
Definition: N_DEV_Pars.h:214
virtual bool updateSecondaryState(double *staDeriv, double *stoVec)
Updates the devices secondary state information.
InstanceBlock represent a device instance line from the netlist.
virtual bool updateState(double *solVec, double *staVec, double *stoVec)
Updates the devices state information.
Util::Param temp
operating temperature of ckt.
std::vector< Param > params
Linear::Matrix * dQdxMatrixPtr
virtual void operator()(const ParameterBase &entity, const std::string &name, std::vector< double > &dfdp, std::vector< double > &dqdp, std::vector< double > &dbdp, std::vector< int > &Findices, std::vector< int > &Qindices, std::vector< int > &Bindices) const
std::vector< Instance * > instanceContainer
virtual bool processInstanceParams()
processInstanceParams
const SolverState & getSolverState() const
Returns the solver state given during device construction.
void setModParams(const std::vector< Param > &params)