Xyce  6.1
N_DEV_ThermalResistor.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_ThermalResistor.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.65.2.1 $
40 //
41 // Revision Date : $Date: 2015/04/02 18:20:11 $
42 //
43 // Current Owner : $Author: tvrusso $
44 //----------------------------------------------------------------------------
45 #include <Xyce_config.h>
46 
47 // ---------- Standard Includes ----------
48 
49 // ---------- Xyce Includes ----------
50 #include <N_DEV_Const.h>
51 #include <N_DEV_DeviceOptions.h>
52 #include <N_DEV_ExternData.h>
53 #include <N_DEV_MatrixLoadData.h>
54 #include <N_DEV_SolverState.h>
55 #include <N_DEV_ThermalResistor.h>
56 #include <N_DEV_Message.h>
57 #include <N_ERH_ErrorMgr.h>
58 
59 #include <N_DEV_Resistor.h>
60 
61 #include <N_LAS_Matrix.h>
62 #include <N_LAS_Vector.h>
63 
64 #include <N_UTL_Expression.h>
65 #include <N_UTL_FeatureTest.h>
66 
67 namespace Xyce {
68 namespace Device {
69 
70 namespace ThermalResistor {
71 
73 {
74  // Set up double precision variables:
75  p.addPar ("R",1000.0,&ThermalResistor::Instance::R)
76  .setUnit(U_OHM)
77  .setCategory(CAT_NONE)
78  .setDescription("Resistance");
79 
81  .setUnit(U_METER)
82  .setCategory(CAT_NONE)
83  .setDescription("Length of conductor");
84 
86  .setUnit(U_METER)
87  .setCategory(CAT_NONE)
88  .setDescription("Width of conductor");
89 
91  .setUnit(U_METER2)
92  .setCategory(CAT_NONE)
93  .setDescription("Area of conductor");
94 
96  .setUnit(U_METER)
97  .setCategory(CAT_NONE)
98  .setDescription("Length of material thermally coupled to conductor");
99 
101  .setUnit(U_METER2)
102  .setCategory(CAT_NONE)
103  .setDescription("Area of material thermally coupled to conductor");
104 
105  // This stuff is copied from the model:
106  p.addPar ("RESISTIVITY",0.0,&ThermalResistor::Instance::resistivity)
107  .setUnit(U_OHMM)
108  .setCategory(CAT_NONE)
109  .setDescription("Resistor material resistivity");
110 
111  p.addPar ("DENSITY",0.0,&ThermalResistor::Instance::density)
112  .setUnit(U_KGMM3)
113  .setCategory(CAT_NONE)
114  .setDescription("Resistor material density (unused)");
115 
116  p.addPar ("HEATCAPACITY",0.0,&ThermalResistor::Instance::heatCapacity)
117  .setUnit(U_JMM3KM1)
118  .setCategory(CAT_NONE)
119  .setDescription("Resistor material volumetric heat capacity");
120 
121  p.addPar ("THERMAL_HEATCAPACITY",0.0,&ThermalResistor::Instance::thermalHeatCapacity)
122  .setUnit(U_JMM3KM1)
123  .setCategory(CAT_NONE)
124  .setDescription("Volumetric heat capacity of material thermally coupled to conductor");
125 
127  .setUnit(U_DEGC)
128  .setCategory(CAT_NONE)
129  .setDescription("Device temperature");
130 
131  // Set up non-double precision variables:
133  .setUnit(U_NONE)
134  .setCategory(CAT_CONTROL)
135  .setDescription("Debug Output switch");
136 }
137 
139 {
141  .setUnit(U_DEGCM1)
142  .setCategory(CAT_NONE)
143  .setDescription("Linear Temperature Coefficient");
144 
146  .setUnit(U_DEGCM2)
147  .setCategory(CAT_NONE)
148  .setDescription("Quadratic Temperature Coefficient");
149 
151  .setUnit(U_OHM)
152  .setCategory(CAT_NONE)
153  .setDescription("Sheet Resistance");
154 
156  .setUnit(U_NONE)
157  .setDescription("Resistance Multiplier");
158 
159  p.addPar ("RESISTIVITY",0.0,&ThermalResistor::Model::resistivity)
160  .setUnit(U_OHMM)
161  .setCategory(CAT_NONE)
162  .setDescription("Resistor material resistivity");
163 
164  p.addPar ("DENSITY",0.0,&ThermalResistor::Model::density)
165  .setUnit(U_KGMM3)
166  .setCategory(CAT_NONE)
167  .setDescription("Resistor material density (unused)");
168 
169  p.addPar ("HEATCAPACITY",0.0,&ThermalResistor::Model::heatCapacity)
170  .setUnit(U_JMM3KM1)
171  .setCategory(CAT_NONE)
172  .setDescription("Resistor material volumetric heat capacity");
173 
174  p.addPar ("THERMAL_HEATCAPACITY",0.0,&ThermalResistor::Model::thermalHeatCapacity)
175  .setUnit(U_JMM3KM1)
176  .setCategory(CAT_NONE)
177  .setDescription("Volumetric heat capacity of material thermally coupled to conductor");
178 
179  p.addPar ("DEFW",1.e-5,&ThermalResistor::Model::defWidth)
180  .setUnit(U_METER)
181  .setCategory(CAT_NONE)
182  .setDescription("Default Instance Width");
183 
184  p.addPar ("NARROW",0.0,&ThermalResistor::Model::narrow)
185  .setUnit(U_METER)
186  .setCategory(CAT_NONE)
187  .setDescription("Narrowing due to side etching");
188 
189  p.addPar ("TNOM",0.0,&ThermalResistor::Model::tnom)
190  .setUnit(STANDARD)
191  .setCategory(CAT_NONE)
192  .setDescription("Parameter Measurement Temperature");
193 }
194 
195 std::vector< std::vector<int> > Instance::jacStamp;
196 
197 
198 // Class Instance
199 //-----------------------------------------------------------------------------
200 // Function : Instance::processParams
201 // Purpose :
202 // Special Notes :
203 // Scope : public
204 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
205 // Creation Date : 6/03/02
206 //-----------------------------------------------------------------------------
208 {
209 
210  // now set the temperature related stuff.
212 
213  return true;
214 }
215 
216 //-----------------------------------------------------------------------------
217 // Function : Instance::Instance
218 // Purpose : instance block constructor
219 // Special Notes :
220 // Scope : public
221 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
222 // Creation Date : 3/16/00
223 //-----------------------------------------------------------------------------
225  const Configuration & configuration,
226  const InstanceBlock & IB,
227  Model & Riter,
228  const FactoryBlock & factory_block)
229  : DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
230  model_(Riter),
231  R(0.0), G(0.0),
232  i0(0.0),
233  length(0.0),
234  width(0.0),
235  temp(getDeviceOptions().temp.getImmutableValue<double>()),
236  li_Pos(-1),
237  li_Neg(-1),
238  APosEquPosNodeOffset(-1),
239  APosEquNegNodeOffset(-1),
240  ANegEquPosNodeOffset(-1),
241  ANegEquNegNodeOffset(-1),
242  f_PosEquPosNodePtr(0),
243  f_PosEquNegNodePtr(0),
244  f_NegEquPosNodePtr(0),
245  f_NegEquNegNodePtr(0),
246  tempModelEnabled(false),
247  outputInternalVarsFlag(false),
248  li_TempState(-1),
249  li_store_dev_i(-1)
250 {
251  numIntVars = 0;
252  numExtVars = 2;
253  numStateVars = 0;
254  numLeadCurrentStoreVars = 1; // one potential lead current
255 
256  if( jacStamp.empty() )
257  {
258  jacStamp.resize(2);
259  jacStamp[0].resize(2);
260  jacStamp[1].resize(2);
261  jacStamp[0][0] = 0;
262  jacStamp[0][1] = 1;
263  jacStamp[1][0] = 0;
264  jacStamp[1][1] = 1;
265  }
266 
267 
268  // Set params to constant default values:
269  setDefaultParams ();
270 
271  // Set params according to instance line and constant defaults from metadata:
272  setParams (IB.params);
273 
274  // Set any non-constant parameter defaults:
275  if (!given("TEMP"))
276  temp = getDeviceOptions().temp.getImmutableValue<double>();
277  if (!given("W"))
278  width = model_.defWidth;;
279 
280  // Nonzero value for numStateVars indicates that the self-consistent thermal
281  // resistor model is being used.
282  if (given("A") && given("L") &&
283  ( (model_.given("HEATCAPACITY") && model_.given("RESISTIVITY"))
284  || (given("HEATCAPACITY") && given("RESISTIVITY")) )
285  )
286  {
287  numStateVars++;
288  tempModelEnabled = true;
289  }
290 
291  // If the instance parameters are NOT given, but the model parameters
292  // ARE given, then copy the model params into the instance. All the
293  // work is actually done in the instance anyway,
294  // but this stuff can be specified on the model level.
295  if ( !(given("HEATCAPACITY")) && !(given("RESISTIVITY")) &&
296  model_.given("HEATCAPACITY") && model_.given("RESISTIVITY") )
297  {
301 
302  // copy over the dependent parameters. For now, it only appears necessary
303  // to copy the dependentParams vector, and not anything else like
304  // the expVarLIDs vector.
305 
306  if (!(model_.getDependentParams().empty()))
307  {
308  const std::vector<Depend> & model_dp = model_.getDependentParams();
309  int dpSize = model_dp.size();
310 
311  for (int i=0;i<dpSize;++i)
312  {
313  Depend dpTmp;
314  dpTmp.name = model_dp[i].name;
315  dpTmp.vals = model_dp[i].vals;
316  dpTmp.global_params = model_dp[i].global_params;
317  dpTmp.n_vars = model_dp[i].n_vars;
318  dpTmp.lo_var = model_dp[i].lo_var;
319  dpTmp.vectorIndex = -1;
320 
321  // dpTmp needs to point to a copy of the original expression.
322  dpTmp.expr = new Util::Expression( *(model_dp[i].expr) );
323 
324  double *Dval;
325  if (dpTmp.name=="RESISTIVITY")
326  {
327  //Dval = &Instance::resistivity;
328  Dval = &resistivity;
329  dpTmp.resultU.result = Dval;
330 
331  }
332 
333  if (dpTmp.name=="HEATCAPACITY")
334  {
335  Dval = &heatCapacity;
336  dpTmp.resultU.result = Dval;
337  }
338 
339  addDependentParameter(dpTmp);
340  }
341  }
342  }
343 
344  // Calculate any parameters specified as expressions:
346 
347  // calculate dependent (ie computed) params and check for errors:
348 
349  if (!given("R") && numStateVars == 0)
350  {
351  if (model_.given("RSH") && given("L") && (model_.sheetRes!=0) &&
352  (length != 0))
353  {
355  / (width - model_.narrow);
356  }
357  else
358  {
359  UserWarning(*this) << "Resistance is0, set to default of 1000 ohms " << getName();
360 
361  R = 1000;
362  }
363  }
364 
365  processParams ();
366 }
367 
368 //-----------------------------------------------------------------------------
369 // Function : Instance::~Instance
370 // Purpose : destructor
371 // Special Notes :
372 // Scope : public
373 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
374 // Creation Date : 3/16/00
375 //-----------------------------------------------------------------------------
377 {}
378 
379 //-----------------------------------------------------------------------------
380 // Function : Instance::registerLIDs
381 // Purpose :
382 // Special Notes :
383 // Scope : public
384 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
385 // Creation Date : 6/12/02
386 //-----------------------------------------------------------------------------
387 void Instance::registerLIDs( const std::vector<int> & intLIDVecRef,
388  const std::vector<int> & extLIDVecRef )
389 {
390  AssertLIDs(intLIDVecRef.size() == numIntVars);
391  AssertLIDs(extLIDVecRef.size() == numExtVars);
392 
393  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
394  {
395  Xyce::dout() << std::endl << section_divider << std::endl;
396  Xyce::dout() << " ResistorInstance::registerLIDs" << std::endl;
397  Xyce::dout() << " name = " << getName() << std::endl;
398  }
399 
400  // copy over the global ID lists.
401  intLIDVec = intLIDVecRef;
402  extLIDVec = extLIDVecRef;
403 
404  li_Pos = extLIDVec[0];
405  li_Neg = extLIDVec[1];
406 
407  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) )
408  {
409  Xyce::dout() << " li_Pos = " << li_Pos << std::endl;
410  Xyce::dout() << " li_Neg = " << li_Neg << std::endl;
411  }
412 
413  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) )
414  {
415  Xyce::dout() << section_divider << std::endl;
416  }
417 }
418 
419 //-----------------------------------------------------------------------------
420 // Function : Instance::registerStateLIDs
421 // Purpose : Note that the resistor does not have any state vars.
422 // Special Notes :
423 // Scope : public
424 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
425 // Creation Date : 06/12/02
426 //-----------------------------------------------------------------------------
427 void Instance::registerStateLIDs(const std::vector<int> & staLIDVecRef )
428 {
429  AssertLIDs(staLIDVecRef.size() == numStateVars);
430 
431  // Copy over the global ID lists:
432  staLIDVec = staLIDVecRef;
433 
434  if (numStateVars > 0)
435  li_TempState = staLIDVec[0];
436 
437 }
438 
439 // ----------------------------------------------------------------------------
440 // Function : Instance::registerStoreLIDs
441 // Purpose : One store var for device current.
442 // Special Notes :
443 // Scope : public
444 // Creator : Richard Schiek, Electrical Systems Modeling
445 // Creation Date : 04/24/2013
446 // ----------------------------------------------------------------------------
447 void Instance::registerStoreLIDs(const std::vector<int> & stoLIDVecRef)
448 {
449  AssertLIDs(stoLIDVecRef.size() == getNumStoreVars());
450 
451  if( loadLeadCurrent )
452  {
453  li_store_dev_i = stoLIDVecRef[0];
454  }
455 }
456 
457 //-----------------------------------------------------------------------------
458 // Function : Instance::jacobianStamp
459 // Purpose :
460 // Special Notes :
461 // Scope : public
462 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
463 // Creation Date : 08/20/01
464 //-----------------------------------------------------------------------------
465 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
466 {
467  return jacStamp;
468 }
469 
470 //-----------------------------------------------------------------------------
471 // Function : Instance::registerJacLIDs
472 // Purpose :
473 // Special Notes :
474 // Scope : public
475 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
476 // Creation Date : 08/27/01
477 //-----------------------------------------------------------------------------
478 void Instance::registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec )
479 {
480  DeviceInstance::registerJacLIDs( jacLIDVec );
481 
482  APosEquPosNodeOffset = jacLIDVec[0][0];
483  APosEquNegNodeOffset = jacLIDVec[0][1];
484  ANegEquPosNodeOffset = jacLIDVec[1][0];
485  ANegEquNegNodeOffset = jacLIDVec[1][1];
486 }
487 
488 //-----------------------------------------------------------------------------
489 // Function : Instance::setupPointers
490 // Purpose :
491 // Special Notes :
492 // Scope : public
493 // Creator : Eric Keiter, SNL
494 // Creation Date : 12/12/08
495 //-----------------------------------------------------------------------------
497 {
498 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
499  Linear::Matrix & dFdx = *(extData.dFdxMatrixPtr);
504 #endif
505 }
506 
507 //-----------------------------------------------------------------------------
508 // Function : Instance::loadNodeSymbols
509 // Purpose :
510 // Special Notes :
511 // Scope : public
512 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
513 // Creation Date : 05/13/05
514 //-----------------------------------------------------------------------------
515 void Instance::loadNodeSymbols(Util::SymbolTable &symbol_table) const
516 {
517  if (loadLeadCurrent)
518  addStoreNode(symbol_table, li_store_dev_i, getName(), "DEV_I");
519 }
520 
521 
522 //-----------------------------------------------------------------------------
523 // Function : Instance::updateIntermediateVars
524 // Purpose : update intermediate variables for one diode instance
525 // Special Notes :
526 // Scope : public
527 // Creator : Eric R. Keiter, Dept. 9233.
528 // Creation Date : 3/05/04
529 //-----------------------------------------------------------------------------
531 {
532  double * solVec = extData.nextSolVectorRawPtr;
533 
534  if (tempModelEnabled)
535  {
536  Linear::Vector * staVectorPtr = extData.currStaVectorPtr;
537 
538  if (!getSolverState().dcopFlag)
539  {
540  if (li_TempState >= 0)
541  {
542  temp = (*staVectorPtr)[li_TempState];
544  }
545  }
546  }
547 
548  double v_pos = solVec[li_Pos];
549  double v_neg = solVec[li_Neg];
550 
551  // Load RHS vector element for the positive circuit node KCL equ.
552  i0 = (v_pos-v_neg)*G;
553 
554  return true;
555 }
556 
557 //-----------------------------------------------------------------------------
558 // Function : Instance::updatePrimaryState
559 // Purpose :
560 // Special Notes :
561 // Scope : public
562 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
563 // Creation Date : 01/29/01
564 //-----------------------------------------------------------------------------
566 {
567  bool bsuccess = updateIntermediateVars ();
568 
569  if (tempModelEnabled)
570  {
571  double * staVec = extData.nextStaVectorRawPtr;
572  if (li_TempState >= 0)
573  {
574  double dissipation = i0*i0*R;
577  staVec[li_TempState] = temp;
578  }
579  }
580 
581  return bsuccess;
582 }
583 
584 //-----------------------------------------------------------------------------
585 // Function : Instance::outputPlotFiles
586 // Purpose :
587 // Special Notes :
588 // Scope : public
589 // Creator :
590 // Creation Date :
591 //-----------------------------------------------------------------------------
593 {
594  bool bsuccess = true;
595 
597  {
598  Xyce::dout().width(28); Xyce::dout().precision(20); Xyce::dout().setf(std::ios::scientific);
599  Linear::Vector * sta1VectorPtr = extData.nextStaVectorPtr;
600  Linear::Vector * sta2VectorPtr = extData.currStaVectorPtr;
601  Xyce::dout() << "TEMP("<<getName()<<"): " << getSolverState().currTime << " "
602  << ((*sta1VectorPtr)[li_TempState]-CONSTCtoK) << " "
603  << ((*sta2VectorPtr)[li_TempState]-CONSTCtoK)
604  << std::endl;
605  }
606 
607  return bsuccess;
608 }
609 
610 //-----------------------------------------------------------------------------
611 // Function : Instance::loadDAEFVector
612 //
613 // Purpose : Loads the F-vector contributions for a single
614 // resistor instance.
615 //
616 // Special Notes :
617 //
618 // Scope : public
619 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
620 // Creation Date : 01/24/03
621 //-----------------------------------------------------------------------------
623 {
624  double * fVec = extData.daeFVectorRawPtr;
625  fVec[li_Pos] += i0;
626  fVec[li_Neg] += -i0;
627 
628  if( loadLeadCurrent )
629  {
630  double * stoVec = extData.nextStoVectorRawPtr;
631  stoVec[li_store_dev_i] = i0;
632  }
633  return true;
634 }
635 
636 //-----------------------------------------------------------------------------
637 // Function : Instance::loadDAEdFdx ()
638 //
639 // Purpose : Loads the F-vector contributions for a single
640 // resistor instance.
641 //
642 // Special Notes :
643 //
644 // Scope : public
645 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
646 // Creation Date : 03/05/04
647 //-----------------------------------------------------------------------------
649 {
650  Linear::Matrix & dFdx = *(extData.dFdxMatrixPtr);
651 
652  dFdx[li_Pos][APosEquPosNodeOffset] += G;
653  dFdx[li_Pos][APosEquNegNodeOffset] -= G;
654  dFdx[li_Neg][ANegEquPosNodeOffset] -= G;
655  dFdx[li_Neg][ANegEquNegNodeOffset] += G;
656 
657  return true;
658 }
659 
660 //-----------------------------------------------------------------------------
661 // Function : Instance::updateTemperature
662 // Purpose :
663 // Special Notes :
664 // Scope : public
665 // Creator : Tom Russo, Component Information and Models
666 // Creation Date : 02/27/01
667 //-----------------------------------------------------------------------------
668 bool Instance::updateTemperature ( const double & temp_tmp)
669 {
670  double difference, factor;
671 
672  if (tempModelEnabled)
673  {
674  updateDependentParameters(temp_tmp);
675  R = resistivity * length / area;
676  factor = 1;
677  }
678  else
679  {
680  difference = temp_tmp - model_.tnom;
681  factor = model_.resistanceMultiplier*(1.0 + (model_.tempCoeff1)*difference +
682  (model_.tempCoeff2)*difference*difference);
683  }
684 
685  if (R*factor != 0.0)
686  G = 1.0/(R * factor);
687  else
688  G = 0.0;
689 
690 
691  return true;
692 }
693 
694 //-----------------------------------------------------------------------------
695 // Function : Model::processParams
696 // Purpose :
697 // Special Notes :
698 // Scope : public
699 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
700 // Creation Date : 6/03/02
701 //-----------------------------------------------------------------------------
703 {
704  return true;
705 }
706 
707 //----------------------------------------------------------------------------
708 // Function : Model::processInstanceParams
709 // Purpose :
710 // Special Notes :
711 // Scope : public
712 // Creator : Dave Shirely, PSSI
713 // Creation Date : 03/23/06
714 //----------------------------------------------------------------------------
716 {
717  std::vector<Instance*>::iterator iter;
718  std::vector<Instance*>::iterator first = instanceContainer.begin();
719  std::vector<Instance*>::iterator last = instanceContainer.end();
720 
721  for (iter=first; iter!=last; ++iter)
722  {
723  (*iter)->processParams();
724  }
725 
726  return true;
727 }
728 
729 //-----------------------------------------------------------------------------
730 // Function : Model::Model
731 // Purpose : model block constructor
732 // Special Notes :
733 // Scope : public
734 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
735 // Creation Date : 5/16/00
736 //-----------------------------------------------------------------------------
738  const Configuration & configuration,
739  const ModelBlock & MB,
740  const FactoryBlock & factory_block)
741  : DeviceModel(MB, configuration.getModelParameters(), factory_block),
742  tempCoeff1(0.0),
743  tempCoeff2(0.0),
744  sheetRes(0.0),
745  resistanceMultiplier(1.0),
746  defWidth(10e-6),
747  narrow(0.0),
748  tnom(getDeviceOptions().tnom)
749 {
750 
751  // Set params to constant default values:
752  setDefaultParams ();
753 
754  // Set params according to .model line and constant defaults from metadata:
755  setModParams (MB.params);
756 
757  // Set any non-constant parameter defaults:
758  if (!given("TNOM"))
760 
761  // Calculate any parameters specified as expressions:
763 
764  if (!given("THERMAL_HEATCAPACITY"))
766 
767  // calculate dependent (ie computed) params and check for errors:
768  processParams();
769 }
770 
771 //-----------------------------------------------------------------------------
772 // Function : Model::~Model
773 // Purpose : destructor
774 // Special Notes :
775 // Scope : public
776 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
777 // Creation Date : 3/16/00
778 //-----------------------------------------------------------------------------
780 {
781  std::vector<Instance*>::iterator iter;
782  std::vector<Instance*>::iterator first = instanceContainer.begin();
783  std::vector<Instance*>::iterator last = instanceContainer.end();
784 
785  for (iter=first; iter!=last; ++iter)
786  {
787  delete (*iter);
788  }
789 }
790 
791 //-----------------------------------------------------------------------------
792 // Function : Model::printOutInstances
793 // Purpose : debugging tool.
794 // Special Notes :
795 // Scope : public
796 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
797 // Creation Date : 4/03/00
798 //-----------------------------------------------------------------------------
799 std::ostream &Model::printOutInstances(std::ostream &os) const
800 {
801  std::vector<Instance*>::const_iterator iter;
802  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
803  std::vector<Instance*>::const_iterator last = instanceContainer.end();
804 
805  int i,isize;
806  isize = instanceContainer.size();
807  os << std::endl;
808  os << "Number of Resistor Instances: " << isize << std::endl;
809  os << " name model name Parameters" << std::endl;
810  for (i=0, iter=first; iter!=last; ++iter, ++i)
811  {
812  os << " " << i << ": " << (*iter)->getName() << "\t";
813  os << getName();
814  os << "\t\tR(Tnom) = " << (*iter)->R;
815  os << "\tG(T) = " << (*iter)->G;
816  os << std::endl;
817  }
818 
819  os << std::endl;
820 
821  return os;
822 }
823 
824 //-----------------------------------------------------------------------------
825 // Function : Model::forEachInstance
826 // Purpose :
827 // Special Notes :
828 // Scope : public
829 // Creator : David Baur
830 // Creation Date : 2/4/2014
831 //-----------------------------------------------------------------------------
832 /// Apply a device instance "op" to all instances associated with this
833 /// model
834 ///
835 /// @param[in] op Operator to apply to all instances.
836 ///
837 ///
838 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
839 {
840  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
841  op(*it);
842 }
843 
844 
845 // ThermalResistor Master functions:
846 
847 //-----------------------------------------------------------------------------
848 // Function : Master::updateState
849 // Purpose :
850 // Special Notes :
851 // Scope : public
852 // Creator : Eric Keiter, SNL
853 // Creation Date : 11/26/08
854 //-----------------------------------------------------------------------------
855 bool Master::updateState (double * solVec, double * staVec, double * stoVec)
856 {
857  bool bsuccess = true;
858  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
859  {
860  Instance & ri = *(*it);
861 
862  bool btmp = ri.updateIntermediateVars ();
863  bsuccess = bsuccess && btmp;
864 
865  if (ri.tempModelEnabled)
866  {
867  if (ri.li_TempState >= 0)
868  {
869  double dissipation = ri.i0*ri.i0*ri.R;
870  double dt = ri.getSolverState().currTimeStep;
871  ri.temp += dissipation*dt/(ri.area*ri.length*ri.heatCapacity +
873  staVec[ri.li_TempState] = ri.temp;
874  }
875  }
876  }
877 // }
878 
879  return bsuccess;
880 }
881 
882 //-----------------------------------------------------------------------------
883 // Function : Master::loadDAEVectors
884 // Purpose :
885 // Special Notes :
886 // Scope : public
887 // Creator : Eric Keiter, SNL
888 // Creation Date : 11/26/08
889 //-----------------------------------------------------------------------------
890 bool Master::loadDAEVectors (double * solVec, double * fVec, double *qVec, double * bVec, double * storeLeadF, double * storeLeadQ, double * leadF, double * leadQ, double * junctionV)
891 {
892  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
893  {
894  Instance & ri = *(*it);
895  fVec[ri.li_Pos] += ri.i0;
896  fVec[ri.li_Neg] += -ri.i0;
897  if( ri.loadLeadCurrent )
898  {
899  storeLeadF[ri.li_store_dev_i] = ri.i0;
900  }
901  }
902 
903  return true;
904 }
905 
906 //-----------------------------------------------------------------------------
907 // Function : Master::loadDAEMatrices
908 // Purpose :
909 // Special Notes :
910 // Scope : public
911 // Creator : Eric Keiter, SNL
912 // Creation Date : 11/26/08
913 //-----------------------------------------------------------------------------
914 bool Master::loadDAEMatrices (Linear::Matrix & dFdx, Linear::Matrix & dQdx)
915 {
916 #ifdef _OMP
917 #pragma omp parallel for
918 #endif
919  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
920  {
921  Instance & ri = *(*it);
922 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
923 
924  *(ri.f_PosEquPosNodePtr) += ri.G;
925 
926  *(ri.f_PosEquNegNodePtr) -= ri.G;
927 
928  *(ri.f_NegEquPosNodePtr) -= ri.G;
929 
930  *(ri.f_NegEquNegNodePtr) += ri.G;
931 #else
932 
933  dFdx[ri.li_Pos][ri.APosEquPosNodeOffset] += ri.G;
934 
935  dFdx[ri.li_Pos][ri.APosEquNegNodeOffset] -= ri.G;
936 
937  dFdx[ri.li_Neg][ri.ANegEquPosNodeOffset] -= ri.G;
938 
939  dFdx[ri.li_Neg][ri.ANegEquNegNodeOffset] += ri.G;
940 #endif
941  }
942 
943  return true;
944 }
945 
946 Device *
947 Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
948 {
949 
950  return new Master(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
951 }
952 
953 void
955 {
957  .registerDevice("r", 2)
958  .registerModelType("r", 2);
959 }
960 
961 } // namespace ThermalResistor
962 } // namespace Device
963 } // namespace Xyce
const InstanceName & getName() const
virtual void loadNodeSymbols(Util::SymbolTable &symbol_table) const
Populates and returns the store name map.
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
#define CONSTCtoK
Definition: N_DEV_Const.h:52
void registerStoreLIDs(const std::vector< int > &stoLIDVecRef)
bool given(const std::string &parameter_name) const
virtual void forEachInstance(DeviceInstanceOp &op) const
Apply a device instance "op" to all instances associated with this model.
Pure virtual class to augment a linear system.
void registerStateLIDs(const std::vector< int > &staLIDVecRef)
static std::vector< std::vector< int > > jacStamp
void registerLIDs(const std::vector< int > &intLIDVecRef, const std::vector< int > &extLIDVecRef)
InstanceVector::const_iterator getInstanceEnd() const
Returns an iterator to the ending of the vector of all instances created for this device...
const std::vector< Depend > & getDependentParams()
#define AssertLIDs(cmp)
virtual void registerJacLIDs(const JacobianStamp &jacLIDVec)
bool processInstanceParams()
processInstanceParams
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.
void setParams(const std::vector< Param > &params)
const std::string & getName() const
std::vector< double > vals
The FactoryBlock contains parameters needed by the device, instance and model creation functions...
static void loadModelParameters(ParametricData< Model > &model_parameters)
Instance(const Configuration &configuration, const InstanceBlock &IB, Model &Riter, const FactoryBlock &factory_block)
const DeviceOptions & getDeviceOptions() const
virtual std::ostream & printOutInstances(std::ostream &os) const
union Xyce::Device::Depend::resUnion resultU
Linear::Vector * nextStaVectorPtr
std::vector< std::string > global_params
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 addStoreNode(Util::SymbolTable &symbol_table, int index, const InstanceName &instance_name, const std::string &lead_name)
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.
static void loadInstanceParameters(ParametricData< Instance > &instance_parameters)
const SolverState & solverState_
Class Configuration contains device configuration data.
virtual bool updateState(double *solVec, double *staVec, double *stoVec)
Updates the devices state information.
virtual bool loadDAEMatrices(Linear::Matrix &dFdx, Linear::Matrix &dQdx)
Populates the device's Jacobian object with these pointers.
const SolverState & getSolverState() const
void addDependentParameter(const Depend &param)
bool updateTemperature(const double &temp_tmp)
Linear::Vector * currStaVectorPtr
Util::Expression * expr
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
InstanceBlock represent a device instance line from the netlist.
std::vector< Param > params
void registerJacLIDs(const std::vector< std::vector< int > > &jacLIDVec)
std::vector< Instance * > instanceContainer
const std::vector< std::vector< int > > & jacobianStamp() const
void setModParams(const std::vector< Param > &params)