Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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-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_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.269.2.4 $
40 //
41 // Revision Date : $Date: 2014/03/06 23:33:43 $
42 //
43 // Current Owner : $Author: tvrusso $
44 //-------------------------------------------------------------------------
45 #include <Xyce_config.h>
46 
47 // ---------- Standard Includes ----------
48 #include <N_UTL_Misc.h>
49 
50 #ifdef HAVE_CMATH
51 #include <cmath>
52 #else
53 #include <math.h>
54 #endif
55 
56 #include <algorithm>
57 #include <fstream>
58 #include <set>
59 #include <vector>
60 
61 // ---------- Xyce Includes ----------
62 #include <N_DEV_DeviceOptions.h>
63 #include <N_DEV_ExternData.h>
64 #include <N_DEV_Inductor.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 namespace Xyce {
74 namespace Device {
75 
76 
77 namespace Inductor {
78 
79 
81 {
82  p.addPar("L", 0.0, &Inductor::Instance::baseL)
83  .setExpressionAccess(ParameterType::TIME_DEP)
84  .setUnit(U_HENRY)
85  .setDescription("Inductance");
86 
87  p.addPar("IC", 0.0, &Inductor::Instance::IC)
88  .setGivenMember(&Inductor::Instance::ICGiven)
89  .setUnit(U_AMP)
90  .setDescription("Initial current through device");
91 
92  p.addPar("TEMP", 0.0, &Inductor::Instance::temp)
93  .setExpressionAccess(ParameterType::TIME_DEP)
94  .setGivenMember(&Inductor::Instance::tempGiven)
95  .setUnit(U_DEGC)
96  .setCategory(CAT_MATERIAL)
97  .setDescription("Device temperature");
98 
100  .setGivenMember(&Inductor::Instance::tempCoeff1Given)
101  .setUnit(U_DEGCM1)
102  .setDescription("Linear Temperature Coefficient");
103 
104  p.addPar("TC2", 0.0, &Inductor::Instance::tempCoeff2)
105  .setGivenMember(&Inductor::Instance::tempCoeff2Given)
106  .setUnit(U_DEGCM2)
107  .setDescription("Quadratic Temperature Coefficient");
108 
109  // This call tells the parameter handling code that TC can be specified
110  // as a vector with up to two elements as in TC=a,b. It then translates
111  // TC=a,b into TC1=a TC2=b. Likewise, TC=a will translate into TC1=a
112  p.makeVector ("TC", 2);
113 }
114 
116 {
117  // Set up double precision variables:
118  p.addPar("L", 1.0, &Inductor::Model::L)
119  .setDescription("Inductance Multiplier");
120 
121  p.addPar("IC", 0.0, &Inductor::Model::IC)
122  .setUnit(U_AMP)
123  .setDescription("Initial current through device");
124 
125  p.addPar("TNOM", 27.0, &Inductor::Model::tnom)
126  .setUnit(U_DEGC)
127  .setCategory(CAT_MATERIAL)
128  .setDescription("Reference temperature");
129 
130  p.addPar("TC1",0.0, &Inductor::Model::tempCoeff1)
131  .setUnit(U_DEGCM1)
132  .setCategory(CAT_MATERIAL)
133  .setDescription("First order temperature coeff.");
134 
135  p.addPar("TC2", 0.0, &Inductor::Model::tempCoeff2)
136  .setUnit(U_DEGCM2)
137  .setCategory(CAT_MATERIAL)
138  .setDescription("Second order temperature coeff.");
139 }
140 
141 //
142 // static class member inits
143 //
144 std::vector< std::vector<int> > Instance::jacStamp_BASE;
145 
146 // Class Instance
147 //-----------------------------------------------------------------------------
148 // Function : Instance::processParams
149 // Purpose :
150 // Special Notes :
151 // Scope : public
152 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
153 // Creation Date : 6/03/02
154 //-----------------------------------------------------------------------------
156 {
157  // If there are any time dependent parameters, set their values at for
158  // the current time.
159 
160  // now set the temperature related stuff.
162  return true;
163 }
164 
165 //-----------------------------------------------------------------------------
166 // Function : Instance::updateTemperature
167 // Purpose :
168 // Special Notes :
169 // Scope : public
170 // Creator : Tom Russo, Component Information and Models
171 // Creation Date : 02/27/01
172 //-----------------------------------------------------------------------------
173 bool Instance::updateTemperature ( const double & temp)
174 {
175  double difference = temp - model_.tnom;
176  double factor = model_.L*(1.0 + tempCoeff1*difference +
177  tempCoeff2*difference*difference);
178  L = baseL*factor;
179  return true;
180 }
181 
182 //-----------------------------------------------------------------------------
183 // Function : Instance::Instance
184 // Purpose : constructor
185 // Special Notes :
186 // Scope : public
187 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
188 // Creation Date : 3/16/00
189 //-----------------------------------------------------------------------------
191  const Configuration & configuration,
192  const InstanceBlock & instance_block,
193  Model & model,
194  const FactoryBlock & factory_block)
195  : DeviceInstance(instance_block, configuration.getInstanceParameters(), factory_block),
196  L(0),
197  IC(0),
198  ICGiven(false),
199  model_(model),
200  baseL(0.0),
201  temp(getDeviceOptions().temp.getImmutableValue<double>()),
202  tempGiven(0),
203  tempCoeff1(0.0),
204  tempCoeff2(0.0),
205  tempCoeff1Given(false),
206  tempCoeff2Given(false),
207  li_fstate(-1),
208  li_Pos(-1),
209  li_Neg(-1),
210  li_Bra(-1),
211  ABraEquPosNodeOffset(-1),
212  ABraEquNegNodeOffset(-1),
213  ABraEquBraVarOffset(-1),
214  APosEquBraVarOffset(-1),
215  ANegEquBraVarOffset(-1)
217  ,
218  fPosEquBraVarPtr(0),
219  fNegEquBraVarPtr(0),
220  fBraEquPosNodePtr(0),
221  fBraEquNegNodePtr(0),
222  fBraEquBraVarPtr(0),
223  qBraEquBraVarPtr(0)
224 #endif
225 {
226  numExtVars = 2;
227  numIntVars = 1;
228  numStateVars = 1;
229 
230  if( jacStamp_BASE.empty() )
231  {
232  jacStamp_BASE.resize(3);
233 
234  jacStamp_BASE[0].resize(1);
235  jacStamp_BASE[0][0] = 2;
236 
237  jacStamp_BASE[1].resize(1);
238  jacStamp_BASE[1][0] = 2;
239 
240  jacStamp_BASE[2].resize(3);
241  jacStamp_BASE[2][0] = 0;
242  jacStamp_BASE[2][1] = 1;
243  jacStamp_BASE[2][2] = 2;
244  }
245 
246  // Set params to constant default values:
247  setDefaultParams ();
248 
249  // Set params according to instance line and constant defaults from metadata:
250  setParams (instance_block.params);
251 
252  // Set any non-constant parameter defaults:
253  if (!given("L"))
254  {
255  UserError0(*this) << "Could not find L parameter in instance.";
256  }
257 
258  if (!given("TEMP"))
259  temp = getDeviceOptions().temp.getImmutableValue<double>();
260 
261  if (!tempCoeff1Given)
263  if (!tempCoeff2Given)
265 
266  // Calculate any parameters specified as expressions:
268 
269  // calculate dependent (ie computed) params and check for errors:
270  processParams ();
271 
272  // set up numIntVars:
273  numIntVars = 1;
274 
275  // set up numStateVars:
276  numStateVars = 2;
277 }
278 
279 //-----------------------------------------------------------------------------
280 // Function : Instance::~Instance
281 // Purpose : destructor
282 // Special Notes :
283 // Scope : public
284 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
285 // Creation Date : 3/16/00
286 //-----------------------------------------------------------------------------
288 {
289 }
290 
291 //-----------------------------------------------------------------------------
292 // Function : Instance::setupPointers
293 // Purpose :
294 // Special Notes :
295 // Scope : public
296 // Creator : Eric Keiter, SNL
297 // Creation Date : 11/30/08
298 //-----------------------------------------------------------------------------
300 {
301 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
302  N_LAS_Matrix & dFdx = *(extData.dFdxMatrixPtr);
303  N_LAS_Matrix & dQdx = *(extData.dQdxMatrixPtr);
304 
310 
312 
313 #endif
314 }
315 
316 //-----------------------------------------------------------------------------
317 // Function : Instance::registerLIDs
318 // Purpose :
319 // Special Notes :
320 // Scope : public
321 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
322 // Creation Date : 6/21/02
323 //-----------------------------------------------------------------------------
324 void Instance::registerLIDs(const std::vector<int> & intLIDVecRef,
325  const std::vector<int> & extLIDVecRef)
326 {
327  AssertLIDs(intLIDVecRef.size() == numIntVars);
328  AssertLIDs(extLIDVecRef.size() == numExtVars);
329 
330  // copy over the global ID lists.
331  intLIDVec = intLIDVecRef;
332  extLIDVec = extLIDVecRef;
333 
334  // Now use these lists to obtain the indices into the
335  // linear algebra entities. This assumes an order.
336  // For the matrix indices, first do the rows.
337 
338  li_Pos = extLIDVec[0];
339  li_Neg = extLIDVec[1];
340  li_Bra = intLIDVec[0];
341 
342 #ifdef Xyce_DEBUG_DEVICE
343  if (getDeviceOptions().debugLevel > 0)
344  {
345  Xyce::dout() << section_divider << std::endl;
346 
347  Xyce::dout() << "::registerLIDs:\n";
348  Xyce::dout() << " name = " << getName() << std::endl;
349 
350  Xyce::dout() << "\nlocal solution indices:\n";
351  Xyce::dout() << " li_Pos = "<< li_Pos << std::endl;
352  Xyce::dout() << " li_Neg = "<< li_Neg << std::endl;
353  Xyce::dout() << " li_Bra = "<< li_Bra << std::endl;
354 
355  Xyce::dout() << section_divider << std::endl;
356  }
357 #endif
358 
359 }
360 
361 //-----------------------------------------------------------------------------
362 // Function : Instance::getIntNameMap
363 // Purpose :
364 // Special Notes :
365 // Scope : public
366 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
367 // Creation Date : 05/13/05
368 //-----------------------------------------------------------------------------
369 std::map<int,std::string> & Instance::getIntNameMap ()
370 {
371  // set up the internal name map, if it hasn't been already.
372  if (intNameMap.empty ())
373  {
374  // set up internal name map
375  std::string tmpstr(getName()+"_branch");
376  spiceInternalName (tmpstr);
377  intNameMap[ li_Bra ] = tmpstr;
378  }
379 
380  return intNameMap;
381 }
382 
383 //-----------------------------------------------------------------------------
384 // Function : Instance::registerStateLIDs
385 // Purpose :
386 // Special Notes :
387 // Scope : public
388 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
389 // Creation Date : 6/22/02
390 //-----------------------------------------------------------------------------
391 void Instance::registerStateLIDs( const std::vector<int> & staLIDVecRef )
392 {
393  AssertLIDs(staLIDVecRef.size() == numStateVars);
394 
395  // copy over the global ID lists.
396  staLIDVec = staLIDVecRef;
397 
398  li_fstate = staLIDVec[0];
399 }
400 
401 //-----------------------------------------------------------------------------
402 // Function : Instance::jacobianStamp
403 // Purpose :
404 // Special Notes :
405 // Scope : public
406 // Creator : Robert Hoekstra, SNL
407 // Creation Date : 08/21/02
408 //-----------------------------------------------------------------------------
409 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
410 {
411  return jacStamp_BASE;
412 }
413 
414 //-----------------------------------------------------------------------------
415 // Function : Instance::registerJacLIDs
416 // Purpose :
417 // Special Notes :
418 // Scope : public
419 // Creator : Robert Hoekstra, SNL
420 // Creation Date : 08/27/02
421 //-----------------------------------------------------------------------------
422 void Instance::registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec )
423 {
424  DeviceInstance::registerJacLIDs( jacLIDVec );
425 
426  APosEquBraVarOffset = jacLIDVec[0][0];
427  ANegEquBraVarOffset = jacLIDVec[1][0];
428  ABraEquPosNodeOffset = jacLIDVec[2][0];
429  ABraEquNegNodeOffset = jacLIDVec[2][1];
430  ABraEquBraVarOffset = jacLIDVec[2][2];
431 }
432 
433 //-----------------------------------------------------------------------------
434 // Function : Instance::updatePrimaryState
435 // Purpose :
436 // Special Notes :
437 // Scope : public
438 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
439 // Creation Date : 02/01/01
440 //-----------------------------------------------------------------------------
442 {
443  double * solVec = extData.nextSolVectorRawPtr;
444  double * staVec = extData.nextStaVectorRawPtr;
445  double current = solVec[li_Bra];
446  if( (getSolverState().dcopFlag) && ICGiven )
447  current = IC;
448 
449  f0 = L*current;
450  staVec[li_fstate] = f0;
451 
452  return true;
453 }
454 
455 //-----------------------------------------------------------------------------
456 // Function : Instance::updateSecondaryState
457 // Purpose :
458 // Special Notes :
459 // Scope : public
460 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
461 // Creation Date : 02/01/01
462 //-----------------------------------------------------------------------------
464 {
465  return true;
466 }
467 
468 //-----------------------------------------------------------------------------
469 // Function : Instance::loadDAEQVector
470 //
471 // Purpose : Loads the Q-vector contributions for a single
472 // instance.
473 //
474 // Special Notes : The "Q" vector is part of a standard DAE formalism in
475 // which the system of equations is represented as:
476 //
477 // f(x) = dQ(x)/dt + F(x) - B(t) = 0
478 //
479 // Scope : public
480 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
481 // Creation Date : 01/26/03
482 //-----------------------------------------------------------------------------
484 {
485  double * qVec = extData.daeQVectorRawPtr;
486 
487  qVec[li_Bra] += f0;
488 
489  return true;
490 }
491 
492 //-----------------------------------------------------------------------------
493 // Function : Instance::loadDAEFVector
494 //
495 // Purpose : Loads the F-vector contributions for a single
496 // instance.
497 //
498 // Special Notes :
499 //
500 // Scope : public
501 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
502 // Creation Date : 01/26/03
503 //-----------------------------------------------------------------------------
505 {
506  double current;
507  double coef;
508 
509  double * solVec = extData.nextSolVectorRawPtr;
510  double * fVec = extData.daeFVectorRawPtr;
511 
512  double v_pos = solVec[li_Pos];
513  double v_neg = solVec[li_Neg];
514  double vind = v_pos-v_neg;
515 
516  // In the case that an initial condition is specified, the inductor is set up
517  // like a current source for the DC operating point. We don't deal with the
518  // node voltages in that case, so set coef to 0.
519  if (getSolverState().dcopFlag && ICGiven)
520  {
521  current = IC;
522  coef = 0.0;
523  }
524  else
525  {
526  current = solVec[li_Bra];
527  coef = -vind;
528  }
529 
530  // load the current into the two KCL rhs vector elements
531  fVec[li_Pos] += current;
532  fVec[li_Neg] += -current;
533  fVec[li_Bra] += coef;
534 
535  return true;
536 }
537 
538 //-----------------------------------------------------------------------------
539 // Function : Instance::loadDAEdQdx
540 //
541 // Purpose : Loads the Q-vector contributions for a single
542 // instance.
543 // Scope : public
544 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
545 // Creation Date : 03/05/04
546 //-----------------------------------------------------------------------------
548 {
549  N_LAS_Matrix & dQdx = *(extData.dQdxMatrixPtr);
550  dQdx[li_Bra][ABraEquBraVarOffset] += L;
551  return true;
552 }
553 
554 //-----------------------------------------------------------------------------
555 // Function : Instance::loadDAEdFdx ()
556 //
557 // Purpose : Loads the F-vector contributions for a single
558 // instance.
559 //
560 // Special Notes :
561 //
562 // Scope : public
563 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
564 // Creation Date : 03/05/04
565 //-----------------------------------------------------------------------------
567 {
568  N_LAS_Matrix & dFdx = *(extData.dFdxMatrixPtr);
569  if ( getSolverState().dcopFlag && ICGiven )
570  {
571  // In the case that an initial condition is specified for an
572  // inductor, the DC op should be set up like a current source just
573  // for the operating point calculation.
574  dFdx[li_Pos][APosEquBraVarOffset] += 0.0;
575  dFdx[li_Neg][ANegEquBraVarOffset] += 0.0;
576  dFdx[li_Bra][ABraEquPosNodeOffset] += 0.0;
577  dFdx[li_Bra][ABraEquNegNodeOffset] += 0.0;
578  dFdx[li_Bra][ABraEquBraVarOffset] += 1.0;
579  }
580  else
581  {
582  dFdx[li_Pos][APosEquBraVarOffset] += 1.0;
583  dFdx[li_Neg][ANegEquBraVarOffset] -= 1.0;
584  dFdx[li_Bra][ABraEquPosNodeOffset] -= 1.0;
585  dFdx[li_Bra][ABraEquNegNodeOffset] += 1.0;
586  dFdx[li_Bra][ABraEquBraVarOffset] += 0.0;
587  }
588 
589  return true;
590 }
591 
592 //-----------------------------------------------------------------------------
593 // Function : Instance::setIC
594 // Purpose :
595 // Special Notes :
596 // Scope : public
597 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
598 // Creation Date : 1/11/02
599 //-----------------------------------------------------------------------------
601 {
602  int i_bra_sol;
603  int i_f_state;
604  double * nextStaVector = extData.nextStaVectorRawPtr;
605  double * currStaVector = extData.currStaVectorRawPtr;
606 
607  double * nextSolVector = extData.nextSolVectorRawPtr;
608  double * currSolVector = extData.currSolVectorRawPtr;
609 
610  if (ICGiven)
611  {
612  f0 = L*IC;
613  currStaVector[li_fstate] = f0;
614  nextStaVector[li_fstate] = f0;
615 
616  currSolVector[li_Bra] = IC;
617  nextSolVector[li_Bra] = IC;
618  }
619 
620  return true;
621 }
622 
623 //-----------------------------------------------------------------------------
624 // Function : Instance::varTypes
625 // Purpose :
626 // Special Notes :
627 // Scope : public
628 // Creator : Rob Hoekstra, SNL, Parallel Computational Sciences
629 // Creation Date : 2/17/04
630 //-----------------------------------------------------------------------------
631 void Instance::varTypes( std::vector<char> & varTypeVec )
632 {
633  varTypeVec.resize(1);
634  varTypeVec[0] = 'I';
635 }
636 
637 //-----------------------------------------------------------------------------
638 // Function : Model::processParams
639 // Purpose :
640 // Special Notes :
641 // Scope : public
642 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
643 // Creation Date : 6/03/02
644 //-----------------------------------------------------------------------------
646 {
647  return true;
648 }
649 
650 //----------------------------------------------------------------------------
651 // Function : Model::processInstanceParams
652 // Purpose :
653 // Special Notes :
654 // Scope : public
655 // Creator : Dave Shirely, PSSI
656 // Creation Date : 03/23/06
657 //----------------------------------------------------------------------------
659 {
660  std::vector<Instance*>::iterator iter;
661  std::vector<Instance*>::iterator first = instanceContainer.begin();
662  std::vector<Instance*>::iterator last = instanceContainer.end();
663 
664  for (iter=first; iter!=last; ++iter)
665  {
666  (*iter)->processParams();
667  }
668 
669  return true;
670 }
671 
672 //-----------------------------------------------------------------------------
673 // Function : Model::Model
674 // Purpose : block constructor
675 // Special Notes :
676 // Scope : public
677 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
678 // Creation Date : 3/16/00
679 //-----------------------------------------------------------------------------
681  const Configuration & configuration,
682  const ModelBlock & MB,
683  const FactoryBlock & factory_block)
684  : DeviceModel(MB, configuration.getModelParameters(), factory_block),
685  L(0.0),
686  IC(0.0),
687  tempCoeff1(0.0),
688  tempCoeff2(0.0),
689  tnom(getDeviceOptions().tnom),
690  tnomGiven(0)
691 {
692 
693  // Set params to constant default values:
694  setDefaultParams ();
695 
696  // Set params according to .model line and constant defaults from metadata:
697  setModParams (MB.params);
698 
699  // Set any non-constant parameter defaults:
700  if (!given("TNOM"))
702 
703  // Calculate any parameters specified as expressions:
705 
706  // calculate dependent (ie computed) params and check for errors:
707 
708  processParams ();
709 }
710 
711 //-----------------------------------------------------------------------------
712 // Function : Model::~Model
713 // Purpose : destructor
714 // Special Notes :
715 // Scope : public
716 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
717 // Creation Date : 3/16/00
718 //-----------------------------------------------------------------------------
720 {
721  std::vector<Instance*>::iterator iter;
722  std::vector<Instance*>::iterator first = instanceContainer.begin();
723  std::vector<Instance*>::iterator last = instanceContainer.end();
724 
725  for (iter=first; iter!=last; ++iter)
726  {
727  delete (*iter);
728  }
729 
730 }
731 
732 //-----------------------------------------------------------------------------
733 // Function : Model::printOutInstances
734 // Purpose : debugging tool.
735 // Special Notes :
736 // Scope : public
737 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
738 // Creation Date : 4/04/00
739 //-----------------------------------------------------------------------------
740 std::ostream &Model::printOutInstances(std::ostream &os) const
741 {
742  std::vector<Instance*>::const_iterator iter;
743  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
744  std::vector<Instance*>::const_iterator last = instanceContainer.end();
745 
746  int i, isize;
747  isize = instanceContainer.size();
748 
749  os << std::endl;
750  os << "Number of Inductor instances: " << isize << std::endl;
751  os << " name=\t\tmodelName\tParameters" << std::endl;
752  for (i=0, iter=first; iter!=last; ++iter, ++i)
753  {
754  os << " " << i << ": " << (*iter)->getName() << "\t";
755  os << getName();
756  os << "\t\tL = " << (*iter)->L;
757  os << "\tIC = " << (*iter)->IC;
758  os << std::endl;
759  }
760 
761  os << std::endl;
762 
763  return os;
764 }
765 
766 //-----------------------------------------------------------------------------
767 // Function : Model::forEachInstance
768 // Purpose :
769 // Special Notes :
770 // Scope : public
771 // Creator : David Baur
772 // Creation Date : 2/4/2014
773 //-----------------------------------------------------------------------------
774 /// Apply a device instance "op" to all instances associated with this
775 /// model
776 ///
777 /// @param[in] op Operator to apply to all instances.
778 ///
779 ///
780 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
781 {
782  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
783  op(*it);
784 }
785 
786 
787 // Inductor Master functions:
788 
789 //-----------------------------------------------------------------------------
790 // Function : Master::updateState
791 // Purpose :
792 // Special Notes :
793 // Scope : public
794 // Creator : Eric Keiter, SNL
795 // Creation Date : 11/26/08
796 //-----------------------------------------------------------------------------
797 bool Master::updateState (double * solVec, double * staVec, double * stoVec)
798 {
799  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
800  {
801  Instance & inst = *(*it);
802 
803  double current = solVec[inst.li_Bra];
804 
805  if( (getSolverState().dcopFlag) && inst.ICGiven )
806  current = inst.IC;
807 
808  inst.f0 = inst.L*current;
809  staVec[inst.li_fstate] = inst.f0;
810  }
811 
812  return true;
813 }
814 
815 //-----------------------------------------------------------------------------
816 // Function : Master::updateSecondaryState
817 // Purpose :
818 // Special Notes :
819 // Scope : public
820 // Creator : Eric Keiter, SNL
821 // Creation Date : 11/26/08
822 //-----------------------------------------------------------------------------
823 bool Master::updateSecondaryState ( double * staDerivVec, double * stoVec )
824 {
825  return true;
826 }
827 
828 //-----------------------------------------------------------------------------
829 // Function : Master::loadDAEVectors
830 // Purpose :
831 // Special Notes :
832 // Scope : public
833 // Creator : Eric Keiter, SNL
834 // Creation Date : 11/26/08
835 //-----------------------------------------------------------------------------
836 bool Master::loadDAEVectors (double * solVec, double * fVec, double *qVec, double * storeLeadF, double * storeLeadQ)
837 {
838  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
839  {
840  Instance & inst = *(*it);
841 
842  double current = 0.0;
843  double coef = 0.0;
844 
845  double v_pos = solVec[inst.li_Pos];
846  double v_neg = solVec[inst.li_Neg];
847  double vind = v_pos-v_neg;
848 
849  // In the case that an initial condition is specified, the inductor is set up
850  // like a current source for the DC operating point. We don't deal with the
851  // node voltages in that case, so set coef to 0.
852  if (getSolverState().dcopFlag && inst.ICGiven)
853  {
854  current = inst.IC;
855  solVec[inst.li_Bra] = current;
856  coef = 0.0;
857  }
858  else
859  {
860  current = solVec[inst.li_Bra];
861  coef = -vind;
862  }
863 
864  // load the current into the two KCL rhs vector elements
865  fVec[inst.li_Pos] += current;
866  fVec[inst.li_Neg] += -current;
867  fVec[inst.li_Bra] += coef;
868  qVec[inst.li_Bra] += inst.f0;
869  }
870 return true;
871 }
872 
873 //-----------------------------------------------------------------------------
874 // Function : Master::loadDAEMatrices
875 // Purpose :
876 // Special Notes :
877 // Scope : public
878 // Creator : Eric Keiter, SNL
879 // Creation Date : 11/26/08
880 //-----------------------------------------------------------------------------
881 bool Master::loadDAEMatrices (N_LAS_Matrix & dFdx, N_LAS_Matrix & dQdx)
882 {
883  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
884  {
885  Instance & inst = *(*it);
886 
887  if ( getSolverState().dcopFlag && inst.ICGiven )
888  {
889  // In the case that an initial condition is specified for an
890  // inductor, the DC op should be set up like a current source just
891  // for the operating point calculation.
892 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
893  *inst.fBraEquBraVarPtr += 1.0;
894 #else
895  dFdx[inst.li_Bra][inst.ABraEquBraVarOffset] += 1.0;
896 #endif
897  }
898  else
899  {
900 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
901  *inst.fPosEquBraVarPtr += 1.0;
902  *inst.fNegEquBraVarPtr -= 1.0;
903  *inst.fBraEquPosNodePtr -= 1.0;
904  *inst.fBraEquNegNodePtr += 1.0;
905 #else
906  dFdx[inst.li_Pos][inst.APosEquBraVarOffset] += 1.0;
907  dFdx[inst.li_Neg][inst.ANegEquBraVarOffset] -= 1.0;
908  dFdx[inst.li_Bra][inst.ABraEquPosNodeOffset] -= 1.0;
909  dFdx[inst.li_Bra][inst.ABraEquNegNodeOffset] += 1.0;
910 #endif
911  }
912 
913 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
914  *inst.qBraEquBraVarPtr += inst.L;
915 #else
916  dQdx[inst.li_Bra][inst.ABraEquBraVarOffset] += inst.L;
917 #endif
918  }
919  return true;
920 }
921 
922 Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
923 {
924 
925  return new Master(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
926 }
927 
929 {
931  .registerDevice("l", 1)
932  .registerModelType("l", 1);
933 }
934 
935 } // namespace Inductor
936 } // namespace Device
937 } // namespace Xyce