Xyce  6.1
N_DEV_Resistor.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_Resistor.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.251 $
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 #include <N_DEV_Resistor.h>
48 
49 #include <N_DEV_DeviceOptions.h>
50 #include <N_DEV_ExternData.h>
51 #include <N_DEV_Message.h>
52 #include <N_LAS_Matrix.h>
53 #include <N_UTL_FeatureTest.h>
54 #include <N_ANP_NoiseData.h>
55 
56 namespace Xyce {
57 namespace Device {
58 namespace Resistor {
59 
60 
61 ///
62 /// Common Jacobian Stamp for all Resistor devices.
63 /// Because all resistors have identical Jacobian stamps, this data is
64 /// declared static and is shared by all resistor instances.
65 ///
66 std::vector<std::vector<int> > Instance::jacStamp;
67 
68 //-----------------------------------------------------------------------------
69 // Function : Xyce::Device::Resistor::Instance::initializeJacobianStamp
70 // Purpose :
71 // Special Notes : Initialization of jacobian stamp moved from constructor
72 // in revision 1.227 of N_DEV_Resistor.C by David Baur.
73 // The code itself code was written by R. Hoekstra, 9/27/2002
74 // Scope : private
75 // Creator : David Baur
76 // Creation Date : 2/11/2014
77 //-----------------------------------------------------------------------------
78 ///
79 /// @brief Common Jacobian stamp initializer for all Resistor devices.
80 ///
81 /// The Jacobian stamp is a sparse-matrix representation of the pattern
82 /// of non-zero elements that a device will put into the Jacobian matrix.
83 ///
84 /// The Jacobian stamp is used by the Topology package to determine indices
85 /// into the full Jacobian matrix for elements that correspond to this
86 /// device.
87 ///
88 /// There is one row of the Jacobian stamp for each equation associated with
89 /// a device. The number of elements in a row are the number of non-zero
90 /// elements in that row of the device's contribution to the Jacobian.
91 /// The values of the elements are numbers local to the device that
92 /// represent the column in which the non-zero element appears.
93 ///
94 /// For the resistor, there are two external nodes (the positive and negative
95 /// terminals of the device). The positive node is referred to as the 0th
96 /// node of the device, and the negative node the 1st node.
97 /// Considering positive current flow from the positive node to the negative
98 /// node, current out of the positive node is \f$(V_+-V_-)*G\f$, and current
99 /// out of the negative node is \f$-(V_+-V_-)*G\f$. Thus, the Jacobian
100 /// matrix contribution for the resistor is:
101 /// \f[
102 /// \left[\begin{array}{rr}
103 /// G& -G\\
104 /// -G& G
105 /// \end{array}
106 /// \right] \f]
107 ///
108 /// This is a dense Jacobian with two rows. The first row is the row
109 /// for the positive node's KCL, the second row is the row for the
110 /// negative node KCL. Each row has two non-zero elements. The
111 /// columns correspond to the nodes of the device: the first column is
112 /// the positive node, the second the negative node. The element of
113 /// the jacobian is the dependence of the equation associated with the
114 /// row on the variable associated with the column.
115 ///
116 /// The Jacobian stamp therefore has two rows, and each row has two elements.
117 /// In this trivial device (because the matrix is small and fully dense),
118 /// the stamp values are 0 ("positive node") for the first nonzero in
119 /// each row, and 1 ("negative node") for the second nonzero.
120 ///
122 {
123  if (jacStamp.empty())
124  {
125  jacStamp.resize(2);
126  jacStamp[0].resize(2);
127  jacStamp[1].resize(2);
128  jacStamp[0][0] = 0;
129  jacStamp[0][1] = 1;
130  jacStamp[1][0] = 0;
131  jacStamp[1][1] = 1;
132  }
133 }
134 
135 //-----------------------------------------------------------------------------
136 // Function : Xyce::Device::Resistor::Traits::loadInstanceParameters
137 // Purpose :
138 // Special Notes : The addPar calls here were refactored and moved here
139 // from the instance constructor. Those addPars had been
140 // in place from 2/4/2005.
141 // Scope : private
142 // Creator : David Baur
143 // Creation Date : 1/27/2014
144 //-----------------------------------------------------------------------------
145 ///
146 /// Loads the parameter definition into the instance parameter map.
147 ///
148 /// @param p instance parameter map
149 ///
150 /// Each parameter supported by the resistor device instance is
151 /// defined via the addPar call. The minimum information required is
152 /// the name of the parameter, the default value, and a member pointer
153 /// to a variable in the instance class to which the value will be
154 /// assigned.
155 ///
156 /// Additional information such as documentation for the parameter, units
157 /// (used only in output of tables for documentation), whether a special
158 /// boolean should be set if the parameter is given, etc. may be specified
159 /// using the various set* calls of the Xyce::Device::Descriptor class.
160 ///
161 /// It is important to note that since parameters defined by addPar are
162 /// defined as metadata separate from any instance, it is not possible to
163 /// establish interrelationships between parameter defaults here. Parameter
164 /// defaults specified in addPar are always constants. If a device requires
165 /// that parameter defaults depend on values of other parameters, this has to
166 /// be done in the instance constructor. Examples of such parameters in this
167 /// device arethe "DTEMP" and "W" parameters, which are set to special defaults
168 /// at device instantiation time. Defaults for those parameters in the addPar
169 /// calls (and hence in the LaTeX tables in the reference guide produced from
170 /// this data) are misleading.
171 ///
173 {
174  p.addPar("R", 1000.0, &Resistor::Instance::R)
175  .setExpressionAccess(ParameterType::TIME_DEP)
176  .setUnit(U_OHM)
177  .setDescription("Resistance")
178  .setAnalyticSensitivityAvailable(true)
179  .setSensitivityFunctor(&resSens);
180  p.addPar("L", 0.0, &Resistor::Instance::length)
181  .setUnit(U_METER)
182  .setDescription("Length");
183  p.addPar("W", 0.0, &Resistor::Instance::width)
184  .setUnit(U_METER)
185  .setDescription("Width");
186  p.addPar("TEMP", 0.0, &Resistor::Instance::temp)
187  .setExpressionAccess(ParameterType::TIME_DEP)
188  .setUnit(U_DEGC)
189  .setDescription("Device temperature");
190 
191  p.addPar("TC1", 0.0, &Resistor::Instance::tempCoeff1)
192  .setGivenMember(&Resistor::Instance::tempCoeff1Given)
193  .setUnit(U_DEGCM1)
194  .setDescription("Linear Temperature Coefficient");
195  p.addPar("TC2", 0.0, &Resistor::Instance::tempCoeff2)
196  .setGivenMember(&Resistor::Instance::tempCoeff2Given)
197  .setUnit(U_DEGCM2)
198  .setDescription("Quadratic Temperature Coefficient");
199  p.makeVector("TC", 2); // Allow TC to be entered as a vector (TC=1,2)
200 
201  p.addPar("DTEMP", 0.0, &Resistor::Instance::dtemp)
202  .setGivenMember(&Resistor::Instance::dtempGiven)
203  .setUnit(U_DEGC)
204  .setDescription("Device Temperature -- For compatibility only. Parameter is NOT used");
205 }
206 
207 //-----------------------------------------------------------------------------
208 // Function : Xyce::Device::Resistor::Traits::loadModelParameters
209 // Purpose :
210 // Special Notes : The addPar calls here were refactored and moved here
211 // from the model constructor. Those addPars had been
212 // in place from 2/4/2005.
213 // Scope : private
214 // Creator : David Baur
215 // Creation Date : 1/27/2014
216 //-----------------------------------------------------------------------------
217 ///
218 /// Loads the parameter definition into the model parameter map.
219 ///
220 /// @param p model parameter map
221 ///
222 /// @see Xyce::Device::Resistor::Traits::loadInstanceParameters
223 ///
224 /// Resistors may optionally be given a model name to enable a semiconductor
225 /// resistor model with a sheet resistance. The resistance of an instance
226 /// is then determined by the length and width given on the instance line.
227 /// This loadModelParameters method defines the parameters that may be
228 /// specified on model cards associated with semiconductor resistors.
229 ///
231 {
232  // Create parameter definitions for parameter member variables
233  p.addPar("TC1", 0.0, &Resistor::Model::tempCoeff1)
234  .setUnit(U_DEGCM1)
235  .setDescription("Linear Temperature Coefficient");
236  p.addPar("TC2", 0.0, &Resistor::Model::tempCoeff2)
237  .setUnit(U_DEGCM2)
238  .setDescription("Quadratic Temperature Coefficient");
239  p.addPar("RSH", 0.0, &Resistor::Model::sheetRes)
240  .setUnit(U_OHM)
241  .setDescription("Sheet Resistance");
243  .setUnit(U_NONE)
244  .setDescription("Resistance Multiplier");
245  p.addPar("DEFW", 1.e-5, &Resistor::Model::defWidth)
246  .setUnit(U_METER)
247  .setDescription("Default Instance Width");
248  p.addPar("NARROW",0.0, &Resistor::Model::narrow)
249  .setUnit(U_METER)
250  .setDescription("Narrowing due to side etching");
251  p.addPar("TNOM", 0.0, &Resistor::Model::tnom)
252  .setUnit(U_DEGC)
253  .setDescription("Parameter Measurement Temperature");
254 }
255 
256 //-----------------------------------------------------------------------------
257 // Function : Xyce::Device::Resistor::Instance::Instance
258 // Purpose : Instance constructor
259 // Special Notes :
260 // Scope : public
261 // Creator : Eric Keiter
262 // Creation Date : 3/16/2000
263 //-----------------------------------------------------------------------------
264 ///
265 /// Construct a resistor instance.
266 ///
267 /// @param[in] configuration Device configuration and traits.
268 /// @param[in] instance_block Instance information from parser.
269 /// @param[in] model Resistor Model to which we should add this instance.
270 /// @param[in] factory_block Device options defined in netlist.
271 ///
272 /// @note The parameter member variable values from the initializers
273 /// are immediately replaced with the values from the parameter
274 /// definitions by the setDefaultParams() function.
275 
277  const Configuration & configuration,
278  const InstanceBlock & instance_block,
279  Model & model,
280  const FactoryBlock & factory_block)
281  : DeviceInstance(instance_block, configuration.getInstanceParameters(), factory_block),
282  model_(model),
283  R(0.0),
284  length(0.0),
285  width(0.0),
286  temp(factory_block.deviceOptions_.temp.getImmutableValue<double>()),
287  tempCoeff1(0.0),
288  tempCoeff2(0.0),
289  dtemp(0.0),
290  tempCoeff1Given(false),
291  tempCoeff2Given(false),
292  dtempGiven(false),
293  G(0.0),
294  i0(0.0),
295  li_Pos(-1),
296  li_Neg(-1),
297  li_store_dev_i(0),
298  li_branch_data(0),
299  APosEquPosNodeOffset(-1),
300  APosEquNegNodeOffset(-1),
301  ANegEquPosNodeOffset(-1),
302  ANegEquNegNodeOffset(-1)
304  ,
305  f_PosEquPosNodePtr(0),
306  f_PosEquNegNodePtr(0),
307  f_NegEquPosNodePtr(0),
308  f_NegEquNegNodePtr(0)
309  // ,
310 #endif
311  //resSens(*this)
312 {
313  // Initialize DeviceInstance values
314  numIntVars = 0; // Initialize number if internal nodes in DeviceInstance
315  numExtVars = 2; // Initialize number if external nodes in DeviceInstance
316  numStateVars = 0; // Initialize number if state variables in DeviceInstance
317  setNumStoreVars(0); // Initialize number if store variables in DeviceInstance
318  numLeadCurrentStoreVars = 1; // Initialize number if lead current variables
319  //in DeviceInstance
320 
321  setNumBranchDataVars(0); // by default don't allocate space in branch vectors
322  numBranchDataVarsIfAllocated = 1; // this is the space to allocate if lead current or power is needed.
323 
325 
326  // Set params to constant default values from parameter definition
328 
329  // Set params according to instance line and constant defaults from metadata
330  setParams(instance_block.params);
331 
332  // Calculate any parameters specified as expressions
334 
335  // calculate dependent (ie computed) params and check for errors
336  processParams();
337 }
338 
339 //-----------------------------------------------------------------------------
340 // Function : Xyce::Device::Resistor::Instance::processParams
341 // Purpose :
342 // Special Notes :
343 // Scope : public
344 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
345 // Creation Date : 6/3/02
346 //-----------------------------------------------------------------------------
347 /// Process parameters.
348 ///
349 /// @return true on success
350 ///
351 /// In general, the processParams method is intended as a place for complex
352 /// manipulation of parameters that must happen if temperature or other
353 /// external changes happen (e.g. step loops).
354 ///
355 /// @author Eric Keiter, SNL, Parallel Computational Sciences
356 /// @date 6/03/02
358 {
359  // Set any non-constant parameter defaults:
360  if (!given("TEMP"))
361  temp = getDeviceOptions().temp.getImmutableValue<double>();
362  if (!given("W"))
364 
365  // Get temperature values from model is not given in instance
366  if (!tempCoeff1Given)
368  if (!tempCoeff2Given)
370 
371  if (!given("R"))
372  {
373  if (model_.given("RSH") && given("L") && (model_.sheetRes != 0) &&
374  (length != 0))
375  {
377  / (width - model_.narrow);
378  }
379  else
380  {
381  R = 1000.0;
382  UserWarning0(*this) << "Resistance is set to 0, setting to the default, " << R << " ohms";
383  }
384  }
385 
386  // now set the temperature related stuff.
387  return updateTemperature(temp);
388 }
389 
390 //-----------------------------------------------------------------------------
391 // Function : Xyce::Device::Resistor::Instance::registerLIDs
392 // Purpose :
393 // Special Notes :
394 // Scope : public
395 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
396 // Creation Date : 6/12/02
397 //-----------------------------------------------------------------------------
398 ///
399 /// Register local IDs
400 ///
401 /// Register the local internal and external node IDs.
402 ///
403 /// @param intLIDVecRef internal local IDs from topology package
404 /// @param extLIDVecRef external local IDs from topology package
405 ///
406 /// Instantiation (calling the device constructor) of the device
407 /// sets up variables numIntVars and numExtVars, the numbers of internal and
408 /// external variables associated with the device. This information is then
409 /// used by the Topology package to assign locations in the solution vector
410 /// (and all other vectors of the same shape) for those variables.
411 /// The "Local IDs" (LIDs) of these locations are provided by Topology
412 /// so the device can know where to load its data.
413 ///
414 /// This method saves the LIDs from Topology and associates each one with
415 /// a particular local name for the internal or external variable. They
416 /// are then used when we load the F and Q vectors.
417 ///
418 /// The resistor device has no internal variables, so this method makes no use
419 /// of the intLIDVecRef array.
420 ///
421 /// @author Robert Hoekstra, SNL, Parallel Computational Sciences
422 /// @date 6/12/02
424  const std::vector<int> & intLIDVecRef,
425  const std::vector<int> & extLIDVecRef)
426 {
427  AssertLIDs(intLIDVecRef.size() == numIntVars);
428  AssertLIDs(extLIDVecRef.size() == numExtVars);
429 
430  // Copy the local ID lists.
431  intLIDVec = intLIDVecRef; // Set the internal local IDs in DeviceInstance
432  extLIDVec = extLIDVecRef; // Set the external local IDs in DeviceInstance
433 
434  li_Pos = extLIDVec[0];
435  li_Neg = extLIDVec[1];
436 
437  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
438  {
439  dout() << getName() << " LIDs"
440  //<< Util::push << std::endl
441  << std::endl
442  << "li_Pos_ = " << li_Pos << std::endl
443  << "li_Neg_ = " << li_Neg << std::endl
444  //<< Util::pop << std::endl;
445  << std::endl;
446  }
447 }
448 
449 //-----------------------------------------------------------------------------
450 // Function : Xyce::Device::Resistor::Instance::registerStateLIDs
451 // Purpose :
452 // Special Notes :
453 // Scope : public
454 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
455 // Creation Date : 6/12/02
456 //-----------------------------------------------------------------------------
457 ///
458 /// Register the local state IDs
459 ///
460 /// @note The resistor does not have any state vars, so this function
461 /// does nothing.
462 ///
463 /// @param staLIDVecRef State variable local IDs
464 ///
465 /// In general, devices may declare at construction that they require storage
466 /// locations in the "state vector." Topology assigns locations in the
467 /// state vector and returns "Local IDs" (LIDs) for devices to use for their
468 /// state vector entries. If a device uses state vector entries, it
469 /// uses the registerStateLIDs method to save the local IDs for later use.
470 ///
471 /// @author Robert Hoekstra, SNL, Parallel Computational Sciences
472 /// @date 06/12/02
473 
474 void Instance::registerStateLIDs(const std::vector<int> & staLIDVecRef)
475 {
476  AssertLIDs(staLIDVecRef.size() == numStateVars);
477 }
478 
479 //-----------------------------------------------------------------------------
480 // Function : Xyce::Device::Resistor::Instance::registerStoreLIDs
481 // Purpose :
482 // Special Notes :
483 // Scope : public
484 // Creator : Richard Schiek, Electrical Systems Modeling
485 // Creation Date : 12/18/2012
486 //-----------------------------------------------------------------------------
487 /// Register the local store IDs
488 ///
489 /// In addition to state vector, Xyce maintains a separate datastructure
490 /// called a "store" vector. As with other such vectors, the device
491 /// declares at construction time how many store vector entries it needs,
492 /// and later Topology assigns locations for devices, returning LIDs.
493 ///
494 /// These LIDs are stored in this method for later use.
495 ///
496 /// The Resistor device uses exactly one "store vector" element, where
497 /// it keeps the "lead current" that may be used on .PRINT lines as
498 /// "I(R1)" for the current through resistor R1.
499 ///
500 /// @param stoLIDVecRef Store variable local IDs
501 ///
502 /// @author Richard Schiek, Electrical Systems Modeling
503 /// @date 12/18/2012
504 
505 void Instance::registerStoreLIDs(const std::vector<int> & stoLIDVecRef)
506 {
507  AssertLIDs(stoLIDVecRef.size() == getNumStoreVars());
508 
509  if (loadLeadCurrent)
510  {
511  li_store_dev_i = stoLIDVecRef[0];
512  }
513 }
514 
515 //-----------------------------------------------------------------------------
516 // Function : Xyce::Device::Resistor::Instance::registerBranchDataLIDs
517 // Purpose :
518 // Special Notes :
519 // Scope : public
520 // Creator : Richard Schiek, Electrical Systems Modeling
521 // Creation Date : 12/18/2012
522 //-----------------------------------------------------------------------------
523 /// Register the local store IDs
524 ///
525 /// In addition to state vector, Xyce maintains a separate datastructure
526 /// called a "branch data" vector. As with other such vectors, the device
527 /// declares at construction time how many branch vector entries it needs,
528 /// and later Topology assigns locations for devices, returning LIDs.
529 ///
530 /// These LIDs are stored in this method for later use.
531 ///
532 /// The Resistor device uses exactly one "branch data vector" element, where
533 /// it keeps the "lead current" that may be used on .PRINT lines as
534 /// "I(R1)" for the current through resistor R1. and a junction voltage.
535 ///
536 /// @param stoLIDVecRef Store variable local IDs
537 ///
538 /// @author Richard Schiek, Electrical Systems Modeling
539 /// @date 12/18/2012
540 
541 void Instance::registerBranchDataLIDs(const std::vector<int> & branchLIDVecRef)
542 {
543  AssertLIDs(branchLIDVecRef.size() == getNumBranchDataVars());
544 
545  if (loadLeadCurrent)
546  {
547  li_branch_data= branchLIDVecRef[0];
548  }
549 }
550 
551 
552 
553 //-----------------------------------------------------------------------------
554 // Function : Xyce::Device::Resistor::Instance::registerJacLIDs
555 // Purpose :
556 // Special Notes :
557 // Scope : public
558 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
559 // Creation Date : 08/27/01
560 //-----------------------------------------------------------------------------
561 ///
562 /// Register the Jacobian local IDs
563 ///
564 /// @param jacLIDVec Jacobian local Ids
565 ///
566 /// @see Xyce::Device::Resistor::Instance::initializeJacobianStamp
567 ///
568 /// Having established local IDs for the solution variables, Topology must
569 /// also assign local IDs for the elements of the Jacobian matrix.
570 ///
571 /// For each non-zero element that was identified in the jacobianStamp,
572 /// Topology will assign a Jacobian LID. The jacLIDVec will have the
573 /// same structure as the JacStamp, but the values in the jacLIDVec will
574 /// be offsets into the row of the sparse Jacobian matrix corresponding
575 /// to the non-zero identified in the stamp.
576 ///
577 /// These offsets are stored in this method for use later when we load
578 /// the Jacobian.
579 ///
580 /// @author Robert Hoekstra, SNL, Parallel Computational Sciences
581 /// @date 08/27/01
582 
583 void Instance::registerJacLIDs(const std::vector< std::vector<int> > & jacLIDVec)
584 {
585  // Let DeviceInstance do its work.
587 
588  // Store offsets of the components of the Jacobian of this instance
589  APosEquPosNodeOffset = jacLIDVec[0][0];
590  APosEquNegNodeOffset = jacLIDVec[0][1];
591  ANegEquPosNodeOffset = jacLIDVec[1][0];
592  ANegEquNegNodeOffset = jacLIDVec[1][1];
593 }
594 
595 //-----------------------------------------------------------------------------
596 // Function : Xyce::Device::Resistor::Instance::setupPointers
597 // Purpose :
598 // Special Notes :
599 // Scope : public
600 // Creator : Eric Keiter, SNL
601 // Creation Date : 11/30/08
602 //-----------------------------------------------------------------------------
603 ///
604 /// Setup direct access pointer to solution matrix and vectors.
605 ///
606 /// @see Xyce::Device::Resistor::Instance::registerJacLIDs
607 ///
608 /// As an alternative to the row offsets defined in registerJacLIDs, it
609 /// is also possible to obtain direct pointers of the Jacobian elements.
610 ///
611 /// This method uses the offsets obtained in registerJacLIDs to retrieve
612 /// the pointers.
613 ///
614 /// In the resistor device the pointers to the matrix are only saved
615 /// (and are only used for matrix access) if
616 /// Xyce_NONPOINTER_MATRIX_LOAD is NOT defined at compile time. For
617 /// some devices the use of pointers instead of array indexing can be
618 /// a performance enhancement.
619 ///
620 /// Use of pointers in this device is disabled by defining
621 /// Xyce_NONPOINTER_MATRIX_LOAD at compile time. When disabled, array
622 /// indexing with the offsets from registerJacLIDs is used in
623 /// the matrix load methods.
624 ///
625 /// @author Eric Keiter, SNL
626 /// @date 11/30/08
627 
629 {
630 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
631  Linear::Matrix & dFdx = *(extData.dFdxMatrixPtr);
636 #endif
637 }
638 
639 //-----------------------------------------------------------------------------
640 // Function : Instance::loadNodeSymbols
641 // Purpose :
642 // Special Notes :
643 // Scope : public
644 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
645 // Creation Date : 05/13/05
646 //-----------------------------------------------------------------------------
647 void Instance::loadNodeSymbols(Util::SymbolTable &symbol_table) const
648 {
649  if (loadLeadCurrent)
650  {
651  //addStoreNode(symbol_table, li_store_dev_i, getName(), "DEV_I");
652  addBranchDataNode( symbol_table, li_branch_data, getName(), "BRANCH_D");
653  }
654 }
655 
656 //-----------------------------------------------------------------------------
657 // Function : Xyce::Device::Resistor::Instance::updateIntermediateVars
658 // Purpose :
659 // Special Notes :
660 // Scope : public
661 // Creator : Eric Keiter, SNL
662 // Creation Date : 3/05/2004
663 //-----------------------------------------------------------------------------
664 ///
665 /// Update the intermediate variables
666 ///
667 /// @return true on success
668 ///
669 /// The bulk of any device's computation is handled in the instance class'
670 /// updateIntermediateVars method. For the resistor, this is
671 /// merely the computation of the current through the resistor given the
672 /// voltage difference between its terminals.
673 ///
674 /// Intermediate variables computed here are used in the methods that
675 /// load data into the F, Q, dFdX and dQdX data structures.
676 ///
677 /// @note This method is called by the updatePrimaryState
678 /// method. Since the Resistor class reimplements the "Master"
679 /// "loadState" function that loads the contributions from all
680 /// resistor devices in a single loop, THIS FUNCTION IS NOT ACTUALLY
681 /// USED!
682 ///
683 /// @see Xyce::Device::Resistor::Instance::loadDAEFVector Xyce::Device::Resistor::Instance::loadDAEQVector Xyce::Device::Resistor::Instance::loadDAEdFdx Xyce::Device::Resistor::Instance::loadDAEdQdx Xyce::Device::Resistor::Instance::updatePrimaryState
684 /// @author Eric R. Keiter, Dept. 9233.
685 /// @date 3/05/04
686 ///
688 {
689  double * solVec = extData.nextSolVectorRawPtr;
690  double v_pos = solVec[li_Pos];
691  double v_neg = solVec[li_Neg];
692  i0 = (v_pos-v_neg)*G;
693  return true;
694 }
695 
696 //-----------------------------------------------------------------------------
697 // Function : Xyce::Device::Resistor::Instance::updatePrimaryState
698 // Purpose :
699 // Special Notes :
700 // Scope : public
701 // Creator : Eric Keiter, SNL
702 // Creation Date : 1/29/01
703 //-----------------------------------------------------------------------------
704 ///
705 /// Update the state variables.
706 ///
707 /// @return true on success
708 ///
709 /// This function is the function that is called from the device manager
710 /// each time a load of vectors and Jacobian is required. Its first
711 /// job is to call updateIntermediateVars.
712 ///
713 /// After calling updateIntermediateVars, the updatePrimaryState method
714 /// may load state vector elements as needed.
715 ///
716 /// The resistor device has no state vector elements, so all this method does
717 /// in the resistor instance class is call updateIntermediateVars.
718 ///
719 /// There is no longer a "secondary" state. The "primary" in
720 /// this method's name is purely historical.
721 ///
722 /// @note This method is called by the default implementation of the
723 /// loadState master function. Since the Resistor class reimplements
724 /// the "Master" "loadState" function that loads the contributions
725 /// from all resistor devices in a single loop, THIS FUNCTION IS NOT
726 /// ACTUALLY USED, NOR is the updateIntermediateVars method it calls!
727 /// The updatePrimaryState method is only called when a device class
728 /// does not re-implement the master class. This can be a source of
729 /// confusion when attempting to modify the Resistor device, or any
730 /// other device That reimplements the Master classes.
731 ///
732 /// @see Xyce::Device::Resistor::Master::updateState
733 ///
734 /// @author Eric Keiter, SNL, Parallel Computational Sciences
735 /// @date 01/29/01
736 ///
738 {
739  return updateIntermediateVars();
740 }
741 
742 //-----------------------------------------------------------------------------
743 // Function : Xyce::Device::Resistor::Instance::loadDAEFVector
744 // Purpose :
745 // Special Notes :
746 // Scope : public
747 // Creator : Eric Keiter, SNL
748 // Creation Date : 1/24/03
749 //-----------------------------------------------------------------------------
750 ///
751 /// Load the DAE F vector.
752 ///
753 /// @return true on success
754 ///
755 /// The Xyce DAE formulation solves the differential-algebraic
756 /// equations \f$F(x)+dQ(x)/dt=0\f$ These are vector equations
757 /// resulting from the modified nodal analysis of the circuit.
758 ///
759 /// This method loads the F-vector contributions for a single resistor
760 /// instance.
761 ///
762 /// In this method, the offsets defined in registerLIDs are used to
763 /// store the device's F contributions into the F vector.
764 ///
765 /// The Q vector is used for devices that store charge or magnetic
766 /// energy, and since the resistor does none of that, the F vector
767 /// contributions are the whole of the resistor's contribution to the
768 /// full set of DAEs.
769 ///
770 /// @note This method is called by the default implementation of the
771 /// loadDAEVectors master function. Since the Resistor class
772 /// reimplements the "Master" "loadDAEVectors" function that loads the
773 /// contributions from all resistor devices in a single loop, THIS
774 /// FUNCTION IS NOT ACTUALLY USED. The loadDAEFVector method is only
775 /// called when a device class does not re-implement the master class.
776 /// This can be a source of confusion when attempting to modify the Resistor
777 /// device, or any other device that reimplements the Master classes.
778 ///
779 /// @see Xyce::Device::Resistor::Master::loadDAEVectors
780 ///
781 /// @author Eric Keiter, SNL, Parallel Computational Sciences
782 /// @date 01/24/03
783 ///
785 {
786  double * fVec = extData.daeFVectorRawPtr;
787  fVec[li_Pos] += i0;
788  fVec[li_Neg] += -i0;
789 
790  if( loadLeadCurrent )
791  {
792  double * stoVec = extData.nextStoVectorRawPtr;
793  double * leadF = extData.nextLeadCurrFCompRawPtr;
794  double * junctionV = extData.nextJunctionVCompRawPtr;
795  double * solVec = extData.nextSolVectorRawPtr;
796  stoVec[li_store_dev_i] = i0;
797  leadF[li_branch_data] = i0;
798  junctionV[li_branch_data] = solVec[li_Pos] - solVec[li_Neg];
799  }
800 
801  return true;
802 }
803 
804 //-----------------------------------------------------------------------------
805 // Function : Xyce::Device::Resistor::Instance::loadDAEdFdx
806 // Purpose : Loads the F-vector contributions for a single
807 // resistor instance.
808 // Special Notes :
809 // Scope : public
810 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
811 // Creation Date : 03/05/04
812 //-----------------------------------------------------------------------------
813 ///
814 /// Load the DAE the derivative of the F vector with respect to the
815 /// solution vector x, dFdx
816 ///
817 /// Loads the contributions for a single resistor instance to the
818 /// dFdx matrix (the F contribution to the Jacobian).
819 ///
820 /// This method uses the Jacobian LIDs (row offsets) that were stored by
821 /// registerJacLIDs.
822 ///
823 /// @see Xyce::Device::Resistor::Instance::registerJacLIDs
824 ///
825 /// @note This method is called by the default implementation of the
826 /// loadDAEMatrices master function. Since the Resistor class
827 /// reimplements the "Master" "loadDAEMatrices" function that loads the
828 /// contributions from all resistor devices in a single loop, THIS
829 /// FUNCTION IS NOT ACTUALLY USED. The loadDAEdFdx method is only
830 /// called when a device class does not re-implement the master class.
831 /// This can be a source of confusion when attempting to modify the Resistor
832 /// device, or any other device that reimplements the Master classes.
833 ///
834 /// @see Xyce::Device::Resistor::Master::loadDAEMatrices
835 ///
836 /// @return true on success
837 ///
838 /// @author Eric Keiter, SNL, Parallel Computational Sciences
839 /// @date 03/05/04
841 {
842  Linear::Matrix & dFdx = *(extData.dFdxMatrixPtr);
843  dFdx[li_Pos][APosEquPosNodeOffset] += G;
844  dFdx[li_Pos][APosEquNegNodeOffset] -= G;
845  dFdx[li_Neg][ANegEquPosNodeOffset] -= G;
846  dFdx[li_Neg][ANegEquNegNodeOffset] += G;
847  return true;
848 }
849 
850 //-----------------------------------------------------------------------------
851 // Function : Xyce::Device::Resistor::Instance::updateTemperature
852 // Purpose :
853 // Special Notes :
854 // Scope : public
855 // Creator : Tom Russo, Component Information and Models
856 // Creation Date : 02/27/01
857 //-----------------------------------------------------------------------------
858 ///
859 /// Update the parameters that depend on the temperature of the device
860 ///
861 /// @param temp_tmp temperature
862 ///
863 /// Xyce has a number of mechanisms that allow temperature to be changed
864 /// after a device has been instantiated. These include .STEP loops over
865 /// temperature. When temperature is changed, any device that has parameters
866 /// that depend on temperature must be updated. That updating happens here.
867 ///
868 /// The Resistor device supports temperature-dependent resistance through its
869 /// TC1 (linear dependence) and TC2 (quadratic dependence) parameters.
870 /// If these parameters are specified, the resistance must be updated.
871 ///
872 /// @return true on success
873 ///
874 /// @author Tom Russo, Component Information and Models
875 /// @date 02/27/01
876 bool Instance::updateTemperature(const double & temp_tmp)
877 {
878  bool bsuccess = true;
879  double difference, factor;
880 
881  if (temp_tmp != -999.0)
882  temp = temp_tmp;
883  difference = temp - model_.tnom;
884  factor = model_.resistanceMultiplier*(1.0 + tempCoeff1*difference + tempCoeff2*difference*difference);
885 
886  if (R*factor != 0.0)
887  G = 1.0/(R * factor);
888  else
889  G = 0.0;
890 
891  return bsuccess;
892 }
893 
894 
895 //-----------------------------------------------------------------------------
896 // Function : Xyce::Device::Resistor::Instance::setupNoiseSources
897 // Purpose :
898 // Special Notes :
899 // Scope : public
900 // Creator : Eric Keiter
901 // Creation Date :
902 //-----------------------------------------------------------------------------
904 {
905  int numSources=1;
906  noiseData.numSources = numSources;
907  noiseData.resize(numSources);
908 
909  noiseData.deviceName = getName().getEncodedName();
910 
911  noiseData.noiseNames[0] = "onoise_" + getName().getEncodedName();
912  noiseData.li_Pos[0] = li_Pos;
913  noiseData.li_Neg[0] = li_Neg;
914 }
915 
916 //-----------------------------------------------------------------------------
917 // Function : Xyce::Device::Resistor::Instance::getNoiseSources
918 // Purpose :
919 // Special Notes :
920 // Scope : public
921 // Creator : Eric Keiter
922 // Creation Date :
923 //-----------------------------------------------------------------------------
925 {
927  noiseData.noiseDens[0], noiseData.lnNoiseDens[0],
928  THERMNOISE, G, temp);
929 }
930 
931 // Model functions:
932 
933 //-----------------------------------------------------------------------------
934 // Function : Xyce::Device::Resistor::Model::processParams
935 // Purpose :
936 // Special Notes :
937 // Scope : public
938 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
939 // Creation Date : 6/03/02
940 //-----------------------------------------------------------------------------
941 ///
942 /// Process model parameters
943 ///
944 /// @return true on success
945 ///
946 /// @author Eric Keiter, SNL, Parallel Computational Sciences
947 /// @date 6/03/02
949 {
950  return true;
951 }
952 
953 //----------------------------------------------------------------------------
954 // Function : Xyce::Device::Resistor::Model::processInstanceParams
955 // Purpose :
956 // Special Notes :
957 // Scope : public
958 // Creator : Dave Shirely, PSSI
959 // Creation Date : 03/23/06
960 //----------------------------------------------------------------------------
961 ///
962 /// Process the instance parameters of instance owned by this model
963 ///
964 /// This method simply loops over all instances associated with this
965 /// model and calls their processParams method.
966 ///
967 /// @return true
968 ///
969 /// @author Dave Shirely, PSSI
970 /// @date 03/23/06
971 
973 {
974  for (InstanceVector::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
975  {
976  (*it)->processParams();
977  }
978 
979  return true;
980 }
981 //-----------------------------------------------------------------------------
982 // Function : Xyce::Device::Resistor::Model::N_DEV_ResistorModel
983 // Purpose : model block constructor
984 // Special Notes :
985 // Scope : public
986 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
987 // Creation Date : 5/16/00
988 //-----------------------------------------------------------------------------
989 ///
990 /// Construct a resistor model from a "model block" that was created
991 /// by the netlist parser.
992 ///
993 /// @param configuration
994 /// @param model_block
995 /// @param factory_block
996 ///
997 /// @author Eric Keiter, SNL, Parallel Computational Sciences
998 /// @date 5/16/00
1000  const Configuration & configuration,
1001  const ModelBlock & model_block,
1002  const FactoryBlock & factory_block)
1003  : DeviceModel(model_block, configuration.getModelParameters(), factory_block),
1004  tempCoeff1(0.0),
1005  tempCoeff2(0.0),
1006  sheetRes(0.0),
1007  resistanceMultiplier(1.0),
1008  defWidth(10e-6),
1009  narrow(0.0),
1010  tnom(getDeviceOptions().tnom)
1011 {
1012  // Set params to constant default values.
1013  setDefaultParams();
1014 
1015  // Set params according to .model line and constant defaults from metadata.
1016  setModParams(model_block.params);
1017 
1018  // Set any non-constant parameter defaults.
1019  if (!given("TNOM"))
1021 
1022  // Calculate any parameters specified as expressions.
1024 
1025  // calculate dependent (ie computed) params and check for errors.
1026  processParams();
1027 }
1028 
1029 //-----------------------------------------------------------------------------
1030 // Function : Xyce::Device::Resistor::Model::~N_DEV_ResistorModel
1031 // Purpose : destructor
1032 // Special Notes :
1033 // Scope : public
1034 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1035 // Creation Date : 3/16/00
1036 //-----------------------------------------------------------------------------
1037 ///
1038 /// Destroy this model.
1039 ///
1040 /// Also destroys all instances that use this model.
1041 ///
1042 /// @author Eric Keiter, SNL, Parallel Computational Sciences
1043 /// @date 3/16/00
1045 {
1046  // Destory all owned instances
1047  for (InstanceVector::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1048  {
1049  delete (*it);
1050  }
1051 }
1052 
1053 //-----------------------------------------------------------------------------
1054 // Function : N_DEV_ResistorModel::printOutInstances
1055 // Purpose : debugging tool.
1056 // Special Notes :
1057 // Scope : public
1058 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1059 // Creation Date : 4/03/00
1060 //-----------------------------------------------------------------------------
1061 ///
1062 /// Print instances associated with this model.
1063 ///
1064 /// Used only for debugging
1065 ///
1066 /// @param os output stream
1067 ///
1068 /// @return reference to output stream
1069 ///
1070 /// @author Eric Keiter, SNL, Parallel Computational Sciences
1071 /// @date 4/03/00
1072 ///
1073 std::ostream &Model::printOutInstances(std::ostream &os) const
1074 {
1075  os << std::endl;
1076  os << "Number of Resistor Instances: " << instanceContainer.size() << std::endl;
1077  os << " name model name Parameters" << std::endl;
1078 
1079  int i = 0;
1080  for (InstanceVector::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1081  {
1082  os << " " << i << ": " << (*it)->getName() << "\t";
1083  os << getName();
1084  os << "\t\tR(Tnom) = " << (*it)->R;
1085  os << "\tG(T) = " << (*it)->G;
1086  os << std::endl;
1087  ++i;
1088  }
1089 
1090  os << std::endl;
1091 
1092  return os;
1093 }
1094 
1095 //-----------------------------------------------------------------------------
1096 // Function : Model::forEachInstance
1097 // Purpose :
1098 // Special Notes :
1099 // Scope : public
1100 // Creator : David Baur
1101 // Creation Date : 2/4/2014
1102 //-----------------------------------------------------------------------------
1103 /// Apply a device instance "op" to all instances associated with this
1104 /// model
1105 ///
1106 /// @param[in] op Operator to apply to all instances.
1107 ///
1108 ///
1109 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
1110 {
1111  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1112  op(*it);
1113 }
1114 
1115 //-----------------------------------------------------------------------------
1116 // Function : Xyce::Device::Resistor::Master::updateState
1117 // Purpose :
1118 // Special Notes :
1119 // Scope : public
1120 // Creator : Eric Keiter, SNL
1121 // Creation Date : 11/26/08
1122 //-----------------------------------------------------------------------------
1123 ///
1124 /// Update state for all resistor instances, regardless of model.
1125 ///
1126 /// @param solVec solution vector
1127 /// @param staVec state vector
1128 /// @param stoVec store vector
1129 ///
1130 /// @return true on success
1131 ///
1132 /// @note Because the resistor device re-implements the base-class
1133 /// Master::updateState, the Instance::updatePrimaryState method is never
1134 /// called, nor is the Instance::updateIntermediateVars method. This method
1135 /// replaces those, and does the same work but inside a loop over all
1136 /// resistor instances.
1137 ///
1138 /// @see Xyce::Device::Resistor::Instance::updatePrimaryState
1139 /// @author Eric Keiter, SNL
1140 /// @date 11/26/08
1141 
1142 bool Master::updateState(double * solVec, double * staVec, double * stoVec)
1143 {
1144  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
1145  {
1146  Instance & ri = *(*it);
1147 
1148  double v_pos = solVec[ri.li_Pos];
1149  double v_neg = solVec[ri.li_Neg];
1150 
1151  // Load RHS vector element for the positive circuit node KCL equ.
1152  ri.i0 = (v_pos-v_neg)*ri.G;
1153  }
1154 
1155  return true;
1156 }
1157 
1158 //-----------------------------------------------------------------------------
1159 // Function : Xyce::Device::Resistor::Master::loadDAEVectors
1160 // Purpose :
1161 // Special Notes :
1162 // Scope : public
1163 // Creator : Eric Keiter, SNL
1164 // Creation Date : 11/26/08
1165 //-----------------------------------------------------------------------------
1166 ///
1167 /// Load DAE vectors of all resistor instances, regardless of model
1168 ///
1169 /// @param solVec solution vector
1170 /// @param fVec f vector
1171 /// @param qVec q vector
1172 /// @param storeLeadF store lead current f vector
1173 /// @param storeLeadQ store lead current q vector
1174 ///
1175 /// @return true on success
1176 ///
1177 /// @note Because the resistor device re-implements the base-class
1178 /// Master::loadDAEVectors, the Instance::loadDAEFVector method is
1179 /// never called. This method replaces those, and does the same work
1180 /// but inside a loop over all resistor instances.
1181 ///
1182 /// @see Xyce::Device::Resistor::Instance::loadDAEFVector
1183 ///
1184 /// @author Eric Keiter, SNL
1185 /// @date 11/26/08
1186 
1187 bool Master::loadDAEVectors (double * solVec, double * fVec, double *qVec, double * bVec, double * storeLeadF, double * storeLeadQ, double * leadF, double * leadQ, double * junctionV)
1188 {
1189  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
1190  {
1191  Instance & ri = *(*it);
1192  fVec[ri.li_Pos] += ri.i0;
1193  fVec[ri.li_Neg] += -ri.i0;
1194  if( ri.loadLeadCurrent )
1195  {
1196  storeLeadF[ri.li_store_dev_i] = ri.i0;
1197  leadF[ri.li_branch_data] = ri.i0;
1198  junctionV[ri.li_branch_data] = solVec[ri.li_Pos] - solVec[ri.li_Neg];
1199  }
1200  }
1201  return true;
1202 }
1203 
1204 //-----------------------------------------------------------------------------
1205 // Function : Xyce::Device::Resistor::Master::loadDAEMatrices
1206 // Purpose :
1207 // Special Notes :
1208 // Scope : public
1209 // Creator : Eric Keiter, SNL
1210 // Creation Date : 11/26/08
1211 //-----------------------------------------------------------------------------
1212 ///
1213 /// Load DAE matrices for all resistor instances, regardless of model
1214 ///
1215 /// @param dFdx matrix of derivatives of F vector with respect to solution
1216 /// @param dQdx matrix of derivatives of Q vector with respect to solution
1217 ///
1218 /// @return true on success
1219 ///
1220 /// @note Because the resistor device re-implements the base-class
1221 /// Master::loadDAEMatrices, the Instance::loadDAEdFdx method is
1222 /// never called. This method replaces those, and does the same work
1223 /// but inside a loop over all resistor instances.
1224 ///
1225 /// @see Xyce::Device::Resistor::Instance::loadDAEdFdx
1226 ///
1227 /// @author Eric Keiter, SNL
1228 /// @date 11/26/08
1229 
1230 bool Master::loadDAEMatrices(Linear::Matrix & dFdx, Linear::Matrix & dQdx)
1231 {
1232  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
1233  {
1234  Instance & ri = *(*it);
1235 
1236 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
1237  *(ri.f_PosEquPosNodePtr) += ri.G;
1238  *(ri.f_PosEquNegNodePtr) -= ri.G;
1239  *(ri.f_NegEquPosNodePtr) -= ri.G;
1240  *(ri.f_NegEquNegNodePtr) += ri.G;
1241 #else
1242  dFdx[ri.li_Pos][ri.APosEquPosNodeOffset] += ri.G;
1243  dFdx[ri.li_Pos][ri.APosEquNegNodeOffset] -= ri.G;
1244  dFdx[ri.li_Neg][ri.ANegEquPosNodeOffset] -= ri.G;
1245  dFdx[ri.li_Neg][ri.ANegEquNegNodeOffset] += ri.G;
1246 #endif
1247  }
1248 
1249  return true;
1250 }
1251 
1252 //-----------------------------------------------------------------------------
1253 // Function : Xyce::Device::Resistor::Traits::factory
1254 // Purpose :
1255 // Special Notes :
1256 // Scope : public
1257 // Creator : David Baur
1258 // Creation Date :
1259 //-----------------------------------------------------------------------------
1260 ///
1261 /// Create a new instance of the Resistor device.
1262 ///
1263 /// @param configuration
1264 /// @param factory_block
1265 ///
1266 Device *
1267 Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
1268 {
1269  return new Master(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
1270 }
1271 
1272 //-----------------------------------------------------------------------------
1273 // Function : Xyce::Device::Resistor::registerDevice
1274 // Purpose :
1275 // Special Notes :
1276 // Scope : public
1277 // Creator : David Baur
1278 // Creation Date :
1279 //-----------------------------------------------------------------------------
1280 ///
1281 /// Define how to use the device in a netlist.
1282 ///
1283 /// This method is called from the Xyce::Device::registerOpenDevices
1284 /// function, which in turn is called by the device manager.
1285 ///
1286 /// The device is declared here to be an "R" device, which may optionally
1287 /// take a model card of type "R". This device will correspond to model
1288 /// level 1 of resistor models.
1289 void
1291 {
1293  .registerDevice("r", 1)
1294  .registerModelType("r", 1)
1295  .registerModelType("res", 1);
1296 }
1297 
1298 //-----------------------------------------------------------------------------
1299 // Function : resistorSensitivity::operator
1300 // Purpose : produces df/dp and dq/dp, where p=R.
1301 // Special Notes :
1302 // Scope : public
1303 // Creator : Eric Keiter, SNL
1304 // Creation Date : 7/18/2014
1305 //-----------------------------------------------------------------------------
1307  const ParameterBase &entity,
1308  const std::string & name,
1309  std::vector<double> & dfdp,
1310  std::vector<double> & dqdp,
1311  std::vector<double> & dbdp,
1312  std::vector<int> & Findices,
1313  std::vector<int> & Qindices,
1314  std::vector<int> & Bindices
1315  ) const
1316 {
1317  const ParameterBase * e1 = &entity;
1318  const Instance * in = dynamic_cast<const Instance *> (e1);
1319 
1320  double * solVec = in->extData.nextSolVectorRawPtr;
1321  double v_pos = solVec[in->li_Pos];
1322  double v_neg = solVec[in->li_Neg];
1323 
1324  double dfdpLoc = -(v_pos-v_neg)*in->G*in->G;
1325 
1326  dfdp.resize(2);
1327  dfdp[0] = +dfdpLoc;
1328  dfdp[1] = -dfdpLoc;
1329 
1330  Findices.resize(2);
1331  Findices[0] = in->li_Pos;
1332  Findices[1] = in->li_Neg;
1333 }
1334 
1335 } // namespace Resistor
1336 } // namespace Device
1337 } // namespace Xyce
const InstanceName & getName() const
static void loadModelParameters(ParametricData< Model > &p)
Loads the parameter definition into the model parameter map.
virtual bool updatePrimaryState()
Update the state variables.
int li_Pos
Index for Positive Node.
int ANegEquNegNodeOffset
Column index into force matrix of Neg/Neg conductance.
virtual void setupPointers()
Setup direct access pointer to solution matrix and vectors.
double sheetRes
Sheet resistance.
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
int li_branch_data
Index for Lead Current and junction voltage (for power calculations)
InstanceVector instanceContainer
List of owned resistor instances.
bool given(const std::string &parameter_name) const
double length
Resistor length.
void G(const ScalarT &V1, const ScalarT &V2, const ScalarT &Ap, const ScalarT &An, ScalarT &Vp, ScalarT &Vn, ScalarT &fval)
Resistor model class.
Pure virtual class to augment a linear system.
Parameter may be specified as time dependent expression from netlist.
Definition: N_DEV_Pars.h:67
static resistorSensitivity resSens
static void initializeJacobianStamp()
Common Jacobian stamp initializer for all Resistor devices.
const std::string & getEncodedName() const
Return the instance name encoded as: [s:]*xname [s:]*Ytype!name [s:]*Utype!name!count.
double tempCoeff2
Second order temperature coeff.
virtual void registerBranchDataLIDs(const std::vector< int > &branchLIDVecRef)
Register the local store IDs.
void setNumStoreVars(int num_store_vars)
double resistanceMultiplier
resistance multiplier
int APosEquPosNodeOffset
Column index into force matrix of Pos/Pos conductance.
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
std::vector< int > li_Neg
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
#define AssertLIDs(cmp)
std::vector< int > li_Pos
virtual bool processParams()
Process parameters.
virtual void registerJacLIDs(const JacobianStamp &jacLIDVec)
double tnom
nominal temperature for device params.
virtual bool updateState(double *solVec, double *staVec, double *stoVec)
Update state for all resistor instances, regardless of model.
static void loadInstanceParameters(ParametricData< Instance > &p)
Loads the parameter definition into the instance parameter map.
virtual void loadNodeSymbols(Util::SymbolTable &symbol_table) const
Populates and returns the store name map.
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.
std::vector< double > noiseDens
virtual bool loadDAEVectors(double *solVec, double *fVec, double *qVec, double *bVec, double *storeLeadF, double *storeLeadQ, double *leadF, double *leadQ, double *junctionV)
Load DAE vectors of all resistor instances, regardless of model.
virtual void forEachInstance(DeviceInstanceOp &op) const
Apply a device instance "op" to all instances associated with this model.
std::vector< std::string > noiseNames
virtual bool loadDAEFVector()
Load the DAE F vector.
void setParams(const std::vector< Param > &params)
double tempCoeff1
First order temperature coeff.
const std::string & getName() const
The FactoryBlock contains parameters needed by the device, instance and model creation functions...
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
const DeviceOptions & getDeviceOptions() const
double temp
Temperature of this instance.
double dtemp
Externally specified device temperature.
int li_store_dev_i
Index for Lead Current.
virtual void registerJacLIDs(const std::vector< std::vector< int > > &jacLIDVec)
Register the Jacobian local IDs.
bool tempCoeff2Given
Second order temperature coeff was given in netlist.
Resistor device instance class.
static Config< T > & addConfiguration()
Adds the device to the Xyce device configuration.
Linear::Matrix * dFdxMatrixPtr
double narrow
Narrowing due to side etching.
double R
Resistance (ohms)
The Device class is an interface for device implementations.
Definition: N_DEV_Device.h:101
virtual bool processInstanceParams()
Process the instance parameters of instance owned by this model.
void setupNoiseSources(Xyce::Analysis::NoiseData &noiseData)
virtual void registerStateLIDs(const std::vector< int > &staLIDVecRef)
Register the local state IDs.
virtual std::ostream & printOutInstances(std::ostream &os) const
Print instances associated with this model.
virtual bool loadDAEdFdx()
Load the DAE the derivative of the F vector with respect to the solution vector x, dFdx.
Model & model_
Owning model.
const SolverState & solverState_
Class Configuration contains device configuration data.
virtual void registerLIDs(const std::vector< int > &intLIDVecRef, const std::vector< int > &extLIDVecRef)
Register local IDs.
std::vector< double > lnNoiseDens
static Device * factory(const Configuration &configuration, const FactoryBlock &factory_block)
Create a new instance of the Resistor device.
double width
Resistor width.
void setNumBranchDataVars(int num_branch_data_vars)
int ANegEquPosNodeOffset
Column index into force matrix of Neg/Pos conductance.
double G
Conductance(1.0/ohms)
#define Xyce_NONPOINTER_MATRIX_LOAD
Definition: N_DEV_Bsrc.C:97
void noiseSupport(double &noise, double &lnNoise, const int type, const double param, const double temp)
virtual bool processParams()
Process model parameters.
double tempCoeff1
First order temperature coefficient.
double tempCoeff2
Second order temperature coefficient.
virtual bool loadDAEMatrices(Linear::Matrix &dFdx, Linear::Matrix &dQdx)
Load DAE matrices for all resistor instances, regardless of model.
double defWidth
Default width.
virtual void registerStoreLIDs(const std::vector< int > &stoLIDVecRef)
Register the local store IDs.
ModelBlock represents a .MODEL line from the netlist.
Manages parameter binding for class C.
Definition: N_DEV_Pars.h:214
~Model()
Destroy this model.
int li_Neg
Index for Negative Node.
static std::vector< std::vector< int > > jacStamp
All Resistor instances have a common Jacobian Stamp.
InstanceBlock represent a device instance line from the netlist.
void registerDevice()
Define how to use the device in a netlist.
Instance(const Configuration &configuration, const InstanceBlock &instance_block, Model &model, const FactoryBlock &factory_block)
Construct a resistor instance.
Util::Param temp
operating temperature of ckt.
std::vector< Param > params
virtual bool updateTemperature(const double &temp_tmp)
Update the parameters that depend on the temperature of the device.
int APosEquNegNodeOffset
Column index into force matrix of Pos/Neg conductance.
void getNoiseSources(Xyce::Analysis::NoiseData &noiseData)
double tnom
Parameter measurement temperature.
bool tempCoeff1Given
First order temperation value was given in netlist.
void setModParams(const std::vector< Param > &params)
virtual bool updateIntermediateVars()
Update the intermediate variables.
bool dtempGiven
Externally specified device temperature was given in netlist.