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.247.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 #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  // Set any non-constant parameter defaults:
333  if (!given("TEMP"))
334  temp = factory_block.deviceOptions_.temp.getImmutableValue<double>();
335  if (!given("W"))
337 
338  // Get temperature values from model is not given in instance
339  if (!tempCoeff1Given)
341  if (!tempCoeff2Given)
343 
344  // Calculate any parameters specified as expressions
346 
347  // calculate dependent (ie computed) params and check for errors
348  if (!given("R"))
349  {
350  if (model_.given("RSH") && given("L") && (model_.sheetRes != 0) &&
351  (length != 0))
352  {
354  / (width - model_.narrow);
355  }
356  else
357  {
358  R = 1000.0;
359  UserWarning0(*this) << "Resistance is set to 0, setting to the default, " << R << " ohms";
360  }
361  }
362 
363  // Process the parameters to complete initialization
364  processParams();
365 }
366 
367 //-----------------------------------------------------------------------------
368 // Function : Xyce::Device::Resistor::Instance::processParams
369 // Purpose :
370 // Special Notes :
371 // Scope : public
372 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
373 // Creation Date : 6/3/02
374 //-----------------------------------------------------------------------------
375 /// Process parameters.
376 ///
377 /// @return true on success
378 ///
379 /// In general, the processParams method is intended as a place for complex
380 /// manipulation of parameters that must happen if temperature or other
381 /// external changes happen. In the resistor device it does nothing other
382 /// than call updateTemperature.
383 ///
384 /// @author Eric Keiter, SNL, Parallel Computational Sciences
385 /// @date 6/03/02
387 {
388  // now set the temperature related stuff.
389  return updateTemperature(temp);
390 }
391 
392 //-----------------------------------------------------------------------------
393 // Function : Xyce::Device::Resistor::Instance::registerLIDs
394 // Purpose :
395 // Special Notes :
396 // Scope : public
397 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
398 // Creation Date : 6/12/02
399 //-----------------------------------------------------------------------------
400 ///
401 /// Register local IDs
402 ///
403 /// Register the local internal and external node IDs.
404 ///
405 /// @param intLIDVecRef internal local IDs from topology package
406 /// @param extLIDVecRef external local IDs from topology package
407 ///
408 /// Instantiation (calling the device constructor) of the device
409 /// sets up variables numIntVars and numExtVars, the numbers of internal and
410 /// external variables associated with the device. This information is then
411 /// used by the Topology package to assign locations in the solution vector
412 /// (and all other vectors of the same shape) for those variables.
413 /// The "Local IDs" (LIDs) of these locations are provided by Topology
414 /// so the device can know where to load its data.
415 ///
416 /// This method saves the LIDs from Topology and associates each one with
417 /// a particular local name for the internal or external variable. They
418 /// are then used when we load the F and Q vectors.
419 ///
420 /// The resistor device has no internal variables, so this method makes no use
421 /// of the intLIDVecRef array.
422 ///
423 /// @author Robert Hoekstra, SNL, Parallel Computational Sciences
424 /// @date 6/12/02
426  const std::vector<int> & intLIDVecRef,
427  const std::vector<int> & extLIDVecRef)
428 {
429  AssertLIDs(intLIDVecRef.size() == numIntVars);
430  AssertLIDs(extLIDVecRef.size() == numExtVars);
431 
432  // Copy the local ID lists.
433  intLIDVec = intLIDVecRef; // Set the internal local IDs in DeviceInstance
434  extLIDVec = extLIDVecRef; // Set the external local IDs in DeviceInstance
435 
436  li_Pos = extLIDVec[0];
437  li_Neg = extLIDVec[1];
438 
439  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
440  {
441  dout() << getName() << " LIDs"
442  //<< Util::push << std::endl
443  << std::endl
444  << "li_Pos_ = " << li_Pos << std::endl
445  << "li_Neg_ = " << li_Neg << std::endl
446  //<< Util::pop << std::endl;
447  << std::endl;
448  }
449 }
450 
451 //-----------------------------------------------------------------------------
452 // Function : Xyce::Device::Resistor::Instance::registerStateLIDs
453 // Purpose :
454 // Special Notes :
455 // Scope : public
456 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
457 // Creation Date : 6/12/02
458 //-----------------------------------------------------------------------------
459 ///
460 /// Register the local state IDs
461 ///
462 /// @note The resistor does not have any state vars, so this function
463 /// does nothing.
464 ///
465 /// @param staLIDVecRef State variable local IDs
466 ///
467 /// In general, devices may declare at construction that they require storage
468 /// locations in the "state vector." Topology assigns locations in the
469 /// state vector and returns "Local IDs" (LIDs) for devices to use for their
470 /// state vector entries. If a device uses state vector entries, it
471 /// uses the registerStateLIDs method to save the local IDs for later use.
472 ///
473 /// @author Robert Hoekstra, SNL, Parallel Computational Sciences
474 /// @date 06/12/02
475 
476 void Instance::registerStateLIDs(const std::vector<int> & staLIDVecRef)
477 {
478  AssertLIDs(staLIDVecRef.size() == numStateVars);
479 }
480 
481 //-----------------------------------------------------------------------------
482 // Function : Xyce::Device::Resistor::Instance::registerStoreLIDs
483 // Purpose :
484 // Special Notes :
485 // Scope : public
486 // Creator : Richard Schiek, Electrical Systems Modeling
487 // Creation Date : 12/18/2012
488 //-----------------------------------------------------------------------------
489 /// Register the local store IDs
490 ///
491 /// In addition to state vector, Xyce maintains a separate datastructure
492 /// called a "store" vector. As with other such vectors, the device
493 /// declares at construction time how many store vector entries it needs,
494 /// and later Topology assigns locations for devices, returning LIDs.
495 ///
496 /// These LIDs are stored in this method for later use.
497 ///
498 /// The Resistor device uses exactly one "store vector" element, where
499 /// it keeps the "lead current" that may be used on .PRINT lines as
500 /// "I(R1)" for the current through resistor R1.
501 ///
502 /// @param stoLIDVecRef Store variable local IDs
503 ///
504 /// @author Richard Schiek, Electrical Systems Modeling
505 /// @date 12/18/2012
506 
507 void Instance::registerStoreLIDs(const std::vector<int> & stoLIDVecRef)
508 {
509  AssertLIDs(stoLIDVecRef.size() == getNumStoreVars());
510 
511  if (loadLeadCurrent)
512  {
513  li_store_dev_i = stoLIDVecRef[0];
514  }
515 }
516 
517 //-----------------------------------------------------------------------------
518 // Function : Xyce::Device::Resistor::Instance::registerBranchDataLIDs
519 // Purpose :
520 // Special Notes :
521 // Scope : public
522 // Creator : Richard Schiek, Electrical Systems Modeling
523 // Creation Date : 12/18/2012
524 //-----------------------------------------------------------------------------
525 /// Register the local store IDs
526 ///
527 /// In addition to state vector, Xyce maintains a separate datastructure
528 /// called a "branch data" vector. As with other such vectors, the device
529 /// declares at construction time how many branch vector entries it needs,
530 /// and later Topology assigns locations for devices, returning LIDs.
531 ///
532 /// These LIDs are stored in this method for later use.
533 ///
534 /// The Resistor device uses exactly one "branch data vector" element, where
535 /// it keeps the "lead current" that may be used on .PRINT lines as
536 /// "I(R1)" for the current through resistor R1. and a junction voltage.
537 ///
538 /// @param stoLIDVecRef Store variable local IDs
539 ///
540 /// @author Richard Schiek, Electrical Systems Modeling
541 /// @date 12/18/2012
542 
543 void Instance::registerBranchDataLIDs(const std::vector<int> & branchLIDVecRef)
544 {
545  AssertLIDs(branchLIDVecRef.size() == getNumBranchDataVars());
546 
547  if (loadLeadCurrent)
548  {
549  li_branch_data= branchLIDVecRef[0];
550  }
551 }
552 
553 
554 
555 //-----------------------------------------------------------------------------
556 // Function : Xyce::Device::Resistor::Instance::registerJacLIDs
557 // Purpose :
558 // Special Notes :
559 // Scope : public
560 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
561 // Creation Date : 08/27/01
562 //-----------------------------------------------------------------------------
563 ///
564 /// Register the Jacobian local IDs
565 ///
566 /// @param jacLIDVec Jacobian local Ids
567 ///
568 /// @see Xyce::Device::Resistor::Instance::initializeJacobianStamp
569 ///
570 /// Having established local IDs for the solution variables, Topology must
571 /// also assign local IDs for the elements of the Jacobian matrix.
572 ///
573 /// For each non-zero element that was identified in the jacobianStamp,
574 /// Topology will assign a Jacobian LID. The jacLIDVec will have the
575 /// same structure as the JacStamp, but the values in the jacLIDVec will
576 /// be offsets into the row of the sparse Jacobian matrix corresponding
577 /// to the non-zero identified in the stamp.
578 ///
579 /// These offsets are stored in this method for use later when we load
580 /// the Jacobian.
581 ///
582 /// @author Robert Hoekstra, SNL, Parallel Computational Sciences
583 /// @date 08/27/01
584 
585 void Instance::registerJacLIDs(const std::vector< std::vector<int> > & jacLIDVec)
586 {
587  // Let DeviceInstance do its work.
589 
590  // Store offsets of the components of the Jacobian of this instance
591  APosEquPosNodeOffset = jacLIDVec[0][0];
592  APosEquNegNodeOffset = jacLIDVec[0][1];
593  ANegEquPosNodeOffset = jacLIDVec[1][0];
594  ANegEquNegNodeOffset = jacLIDVec[1][1];
595 }
596 
597 //-----------------------------------------------------------------------------
598 // Function : Xyce::Device::Resistor::Instance::setupPointers
599 // Purpose :
600 // Special Notes :
601 // Scope : public
602 // Creator : Eric Keiter, SNL
603 // Creation Date : 11/30/08
604 //-----------------------------------------------------------------------------
605 ///
606 /// Setup direct access pointer to solution matrix and vectors.
607 ///
608 /// @see Xyce::Device::Resistor::Instance::registerJacLIDs
609 ///
610 /// As an alternative to the row offsets defined in registerJacLIDs, it
611 /// is also possible to obtain direct pointers of the Jacobian elements.
612 ///
613 /// This method uses the offsets obtained in registerJacLIDs to retrieve
614 /// the pointers.
615 ///
616 /// In the resistor device the pointers to the matrix are only saved
617 /// (and are only used for matrix access) if
618 /// Xyce_NONPOINTER_MATRIX_LOAD is NOT defined at compile time. For
619 /// some devices the use of pointers instead of array indexing can be
620 /// a performance enhancement.
621 ///
622 /// Use of pointers in this device is disabled by defining
623 /// Xyce_NONPOINTER_MATRIX_LOAD at compile time. When disabled, array
624 /// indexing with the offsets from registerJacLIDs is used in
625 /// the matrix load methods.
626 ///
627 /// @author Eric Keiter, SNL
628 /// @date 11/30/08
629 
631 {
632 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
633  Linear::Matrix & dFdx = *(extData.dFdxMatrixPtr);
638 #endif
639 }
640 
641 //-----------------------------------------------------------------------------
642 // Function : Instance::loadNodeSymbols
643 // Purpose :
644 // Special Notes :
645 // Scope : public
646 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
647 // Creation Date : 05/13/05
648 //-----------------------------------------------------------------------------
649 void Instance::loadNodeSymbols(Util::SymbolTable &symbol_table) const
650 {
651  if (loadLeadCurrent)
652  {
653  //addStoreNode(symbol_table, li_store_dev_i, getName(), "DEV_I");
654  addBranchDataNode( symbol_table, li_branch_data, getName(), "BRANCH_D");
655  }
656 }
657 
658 //-----------------------------------------------------------------------------
659 // Function : Xyce::Device::Resistor::Instance::updateIntermediateVars
660 // Purpose :
661 // Special Notes :
662 // Scope : public
663 // Creator : Eric Keiter, SNL
664 // Creation Date : 3/05/2004
665 //-----------------------------------------------------------------------------
666 ///
667 /// Update the intermediate variables
668 ///
669 /// @return true on success
670 ///
671 /// The bulk of any device's computation is handled in the instance class'
672 /// updateIntermediateVars method. For the resistor, this is
673 /// merely the computation of the current through the resistor given the
674 /// voltage difference between its terminals.
675 ///
676 /// Intermediate variables computed here are used in the methods that
677 /// load data into the F, Q, dFdX and dQdX data structures.
678 ///
679 /// @note This method is called by the updatePrimaryState
680 /// method. Since the Resistor class reimplements the "Master"
681 /// "loadState" function that loads the contributions from all
682 /// resistor devices in a single loop, THIS FUNCTION IS NOT ACTUALLY
683 /// USED!
684 ///
685 /// @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
686 /// @author Eric R. Keiter, Dept. 9233.
687 /// @date 3/05/04
688 ///
690 {
691  double * solVec = extData.nextSolVectorRawPtr;
692  double v_pos = solVec[li_Pos];
693  double v_neg = solVec[li_Neg];
694  i0 = (v_pos-v_neg)*G;
695  return true;
696 }
697 
698 //-----------------------------------------------------------------------------
699 // Function : Xyce::Device::Resistor::Instance::updatePrimaryState
700 // Purpose :
701 // Special Notes :
702 // Scope : public
703 // Creator : Eric Keiter, SNL
704 // Creation Date : 1/29/01
705 //-----------------------------------------------------------------------------
706 ///
707 /// Update the state variables.
708 ///
709 /// @return true on success
710 ///
711 /// This function is the function that is called from the device manager
712 /// each time a load of vectors and Jacobian is required. Its first
713 /// job is to call updateIntermediateVars.
714 ///
715 /// After calling updateIntermediateVars, the updatePrimaryState method
716 /// may load state vector elements as needed.
717 ///
718 /// The resistor device has no state vector elements, so all this method does
719 /// in the resistor instance class is call updateIntermediateVars.
720 ///
721 /// There is no longer a "secondary" state. The "primary" in
722 /// this method's name is purely historical.
723 ///
724 /// @note This method is called by the default implementation of the
725 /// loadState master function. Since the Resistor class reimplements
726 /// the "Master" "loadState" function that loads the contributions
727 /// from all resistor devices in a single loop, THIS FUNCTION IS NOT
728 /// ACTUALLY USED, NOR is the updateIntermediateVars method it calls!
729 /// The updatePrimaryState method is only called when a device class
730 /// does not re-implement the master class. This can be a source of
731 /// confusion when attempting to modify the Resistor device, or any
732 /// other device That reimplements the Master classes.
733 ///
734 /// @see Xyce::Device::Resistor::Master::updateState
735 ///
736 /// @author Eric Keiter, SNL, Parallel Computational Sciences
737 /// @date 01/29/01
738 ///
740 {
741  return updateIntermediateVars();
742 }
743 
744 //-----------------------------------------------------------------------------
745 // Function : Xyce::Device::Resistor::Instance::loadDAEFVector
746 // Purpose :
747 // Special Notes :
748 // Scope : public
749 // Creator : Eric Keiter, SNL
750 // Creation Date : 1/24/03
751 //-----------------------------------------------------------------------------
752 ///
753 /// Load the DAE F vector.
754 ///
755 /// @return true on success
756 ///
757 /// The Xyce DAE formulation solves the differential-algebraic
758 /// equations \f$F(x)+dQ(x)/dt=0\f$ These are vector equations
759 /// resulting from the modified nodal analysis of the circuit.
760 ///
761 /// This method loads the F-vector contributions for a single resistor
762 /// instance.
763 ///
764 /// In this method, the offsets defined in registerLIDs are used to
765 /// store the device's F contributions into the F vector.
766 ///
767 /// The Q vector is used for devices that store charge or magnetic
768 /// energy, and since the resistor does none of that, the F vector
769 /// contributions are the whole of the resistor's contribution to the
770 /// full set of DAEs.
771 ///
772 /// @note This method is called by the default implementation of the
773 /// loadDAEVectors master function. Since the Resistor class
774 /// reimplements the "Master" "loadDAEVectors" function that loads the
775 /// contributions from all resistor devices in a single loop, THIS
776 /// FUNCTION IS NOT ACTUALLY USED. The loadDAEFVector method is only
777 /// called when a device class does not re-implement the master class.
778 /// This can be a source of confusion when attempting to modify the Resistor
779 /// device, or any other device that reimplements the Master classes.
780 ///
781 /// @see Xyce::Device::Resistor::Master::loadDAEVectors
782 ///
783 /// @author Eric Keiter, SNL, Parallel Computational Sciences
784 /// @date 01/24/03
785 ///
787 {
788  double * fVec = extData.daeFVectorRawPtr;
789  fVec[li_Pos] += i0;
790  fVec[li_Neg] += -i0;
791 
792  if( loadLeadCurrent )
793  {
794  double * stoVec = extData.nextStoVectorRawPtr;
795  double * leadF = extData.nextLeadCurrFCompRawPtr;
796  double * junctionV = extData.nextJunctionVCompRawPtr;
797  double * solVec = extData.nextSolVectorRawPtr;
798  stoVec[li_store_dev_i] = i0;
799  leadF[li_branch_data] = i0;
800  junctionV[li_branch_data] = solVec[li_Pos] - solVec[li_Neg];
801  }
802 
803  return true;
804 }
805 
806 //-----------------------------------------------------------------------------
807 // Function : Xyce::Device::Resistor::Instance::loadDAEdFdx
808 // Purpose : Loads the F-vector contributions for a single
809 // resistor instance.
810 // Special Notes :
811 // Scope : public
812 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
813 // Creation Date : 03/05/04
814 //-----------------------------------------------------------------------------
815 ///
816 /// Load the DAE the derivative of the F vector with respect to the
817 /// solution vector x, dFdx
818 ///
819 /// Loads the contributions for a single resistor instance to the
820 /// dFdx matrix (the F contribution to the Jacobian).
821 ///
822 /// This method uses the Jacobian LIDs (row offsets) that were stored by
823 /// registerJacLIDs.
824 ///
825 /// @see Xyce::Device::Resistor::Instance::registerJacLIDs
826 ///
827 /// @note This method is called by the default implementation of the
828 /// loadDAEMatrices master function. Since the Resistor class
829 /// reimplements the "Master" "loadDAEMatrices" function that loads the
830 /// contributions from all resistor devices in a single loop, THIS
831 /// FUNCTION IS NOT ACTUALLY USED. The loadDAEdFdx method is only
832 /// called when a device class does not re-implement the master class.
833 /// This can be a source of confusion when attempting to modify the Resistor
834 /// device, or any other device that reimplements the Master classes.
835 ///
836 /// @see Xyce::Device::Resistor::Master::loadDAEMatrices
837 ///
838 /// @return true on success
839 ///
840 /// @author Eric Keiter, SNL, Parallel Computational Sciences
841 /// @date 03/05/04
843 {
844  Linear::Matrix & dFdx = *(extData.dFdxMatrixPtr);
845  dFdx[li_Pos][APosEquPosNodeOffset] += G;
846  dFdx[li_Pos][APosEquNegNodeOffset] -= G;
847  dFdx[li_Neg][ANegEquPosNodeOffset] -= G;
848  dFdx[li_Neg][ANegEquNegNodeOffset] += G;
849  return true;
850 }
851 
852 //-----------------------------------------------------------------------------
853 // Function : Xyce::Device::Resistor::Instance::updateTemperature
854 // Purpose :
855 // Special Notes :
856 // Scope : public
857 // Creator : Tom Russo, Component Information and Models
858 // Creation Date : 02/27/01
859 //-----------------------------------------------------------------------------
860 ///
861 /// Update the parameters that depend on the temperature of the device
862 ///
863 /// @param temp_tmp temperature
864 ///
865 /// Xyce has a number of mechanisms that allow temperature to be changed
866 /// after a device has been instantiated. These include .STEP loops over
867 /// temperature. When temperature is changed, any device that has parameters
868 /// that depend on temperature must be updated. That updating happens here.
869 ///
870 /// The Resistor device supports temperature-dependent resistance through its
871 /// TC1 (linear dependence) and TC2 (quadratic dependence) parameters.
872 /// If these parameters are specified, the resistance must be updated.
873 ///
874 /// @return true on success
875 ///
876 /// @author Tom Russo, Component Information and Models
877 /// @date 02/27/01
878 bool Instance::updateTemperature(const double & temp_tmp)
879 {
880  bool bsuccess = true;
881  double difference, factor;
882 
883  if (temp_tmp != -999.0)
884  temp = temp_tmp;
885  difference = temp - model_.tnom;
886  factor = model_.resistanceMultiplier*(1.0 + tempCoeff1*difference + tempCoeff2*difference*difference);
887 
888  if (R*factor != 0.0)
889  G = 1.0/(R * factor);
890  else
891  G = 0.0;
892 
893  return bsuccess;
894 }
895 
896 
897 //-----------------------------------------------------------------------------
898 // Function : Xyce::Device::Resistor::Instance::setupNoiseSources
899 // Purpose :
900 // Special Notes :
901 // Scope : public
902 // Creator : Eric Keiter
903 // Creation Date :
904 //-----------------------------------------------------------------------------
906 {
907  int numSources=1;
908  noiseData.numSources = numSources;
909  noiseData.resize(numSources);
910 
911  noiseData.deviceName = getName().getEncodedName();
912 
913  noiseData.noiseNames[0] = "onoise_" + getName().getEncodedName();
914  noiseData.li_Pos[0] = li_Pos;
915  noiseData.li_Neg[0] = li_Neg;
916 }
917 
918 //-----------------------------------------------------------------------------
919 // Function : Xyce::Device::Resistor::Instance::getNoiseSources
920 // Purpose :
921 // Special Notes :
922 // Scope : public
923 // Creator : Eric Keiter
924 // Creation Date :
925 //-----------------------------------------------------------------------------
927 {
929  noiseData.noiseDens[0], noiseData.lnNoiseDens[0],
930  THERMNOISE, G, temp);
931 }
932 
933 // Model functions:
934 
935 //-----------------------------------------------------------------------------
936 // Function : Xyce::Device::Resistor::Model::processParams
937 // Purpose :
938 // Special Notes :
939 // Scope : public
940 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
941 // Creation Date : 6/03/02
942 //-----------------------------------------------------------------------------
943 ///
944 /// Process model parameters
945 ///
946 /// @return true on success
947 ///
948 /// @author Eric Keiter, SNL, Parallel Computational Sciences
949 /// @date 6/03/02
951 {
952  return true;
953 }
954 
955 //----------------------------------------------------------------------------
956 // Function : Xyce::Device::Resistor::Model::processInstanceParams
957 // Purpose :
958 // Special Notes :
959 // Scope : public
960 // Creator : Dave Shirely, PSSI
961 // Creation Date : 03/23/06
962 //----------------------------------------------------------------------------
963 ///
964 /// Process the instance parameters of instance owned by this model
965 ///
966 /// This method simply loops over all instances associated with this
967 /// model and calls their processParams method.
968 ///
969 /// @return true
970 ///
971 /// @author Dave Shirely, PSSI
972 /// @date 03/23/06
973 
975 {
976  for (InstanceVector::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
977  {
978  (*it)->processParams();
979  }
980 
981  return true;
982 }
983 //-----------------------------------------------------------------------------
984 // Function : Xyce::Device::Resistor::Model::N_DEV_ResistorModel
985 // Purpose : model block constructor
986 // Special Notes :
987 // Scope : public
988 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
989 // Creation Date : 5/16/00
990 //-----------------------------------------------------------------------------
991 ///
992 /// Construct a resistor model from a "model block" that was created
993 /// by the netlist parser.
994 ///
995 /// @param configuration
996 /// @param model_block
997 /// @param factory_block
998 ///
999 /// @author Eric Keiter, SNL, Parallel Computational Sciences
1000 /// @date 5/16/00
1002  const Configuration & configuration,
1003  const ModelBlock & model_block,
1004  const FactoryBlock & factory_block)
1005  : DeviceModel(model_block, configuration.getModelParameters(), factory_block),
1006  tempCoeff1(0.0),
1007  tempCoeff2(0.0),
1008  sheetRes(0.0),
1009  resistanceMultiplier(1.0),
1010  defWidth(10e-6),
1011  narrow(0.0),
1012  tnom(getDeviceOptions().tnom)
1013 {
1014  // Set params to constant default values.
1015  setDefaultParams();
1016 
1017  // Set params according to .model line and constant defaults from metadata.
1018  setModParams(model_block.params);
1019 
1020  // Set any non-constant parameter defaults.
1021  if (!given("TNOM"))
1023 
1024  // Calculate any parameters specified as expressions.
1026 
1027  // calculate dependent (ie computed) params and check for errors.
1028  processParams();
1029 }
1030 
1031 //-----------------------------------------------------------------------------
1032 // Function : Xyce::Device::Resistor::Model::~N_DEV_ResistorModel
1033 // Purpose : destructor
1034 // Special Notes :
1035 // Scope : public
1036 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1037 // Creation Date : 3/16/00
1038 //-----------------------------------------------------------------------------
1039 ///
1040 /// Destroy this model.
1041 ///
1042 /// Also destroys all instances that use this model.
1043 ///
1044 /// @author Eric Keiter, SNL, Parallel Computational Sciences
1045 /// @date 3/16/00
1047 {
1048  // Destory all owned instances
1049  for (InstanceVector::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1050  {
1051  delete (*it);
1052  }
1053 }
1054 
1055 //-----------------------------------------------------------------------------
1056 // Function : N_DEV_ResistorModel::printOutInstances
1057 // Purpose : debugging tool.
1058 // Special Notes :
1059 // Scope : public
1060 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1061 // Creation Date : 4/03/00
1062 //-----------------------------------------------------------------------------
1063 ///
1064 /// Print instances associated with this model.
1065 ///
1066 /// Used only for debugging
1067 ///
1068 /// @param os output stream
1069 ///
1070 /// @return reference to output stream
1071 ///
1072 /// @author Eric Keiter, SNL, Parallel Computational Sciences
1073 /// @date 4/03/00
1074 ///
1075 std::ostream &Model::printOutInstances(std::ostream &os) const
1076 {
1077  os << std::endl;
1078  os << "Number of Resistor Instances: " << instanceContainer.size() << std::endl;
1079  os << " name model name Parameters" << std::endl;
1080 
1081  int i = 0;
1082  for (InstanceVector::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1083  {
1084  os << " " << i << ": " << (*it)->getName() << "\t";
1085  os << getName();
1086  os << "\t\tR(Tnom) = " << (*it)->R;
1087  os << "\tG(T) = " << (*it)->G;
1088  os << std::endl;
1089  ++i;
1090  }
1091 
1092  os << std::endl;
1093 
1094  return os;
1095 }
1096 
1097 //-----------------------------------------------------------------------------
1098 // Function : Model::forEachInstance
1099 // Purpose :
1100 // Special Notes :
1101 // Scope : public
1102 // Creator : David Baur
1103 // Creation Date : 2/4/2014
1104 //-----------------------------------------------------------------------------
1105 /// Apply a device instance "op" to all instances associated with this
1106 /// model
1107 ///
1108 /// @param[in] op Operator to apply to all instances.
1109 ///
1110 ///
1111 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
1112 {
1113  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1114  op(*it);
1115 }
1116 
1117 //-----------------------------------------------------------------------------
1118 // Function : Xyce::Device::Resistor::Master::updateState
1119 // Purpose :
1120 // Special Notes :
1121 // Scope : public
1122 // Creator : Eric Keiter, SNL
1123 // Creation Date : 11/26/08
1124 //-----------------------------------------------------------------------------
1125 ///
1126 /// Update state for all resistor instances, regardless of model.
1127 ///
1128 /// @param solVec solution vector
1129 /// @param staVec state vector
1130 /// @param stoVec store vector
1131 ///
1132 /// @return true on success
1133 ///
1134 /// @note Because the resistor device re-implements the base-class
1135 /// Master::updateState, the Instance::updatePrimaryState method is never
1136 /// called, nor is the Instance::updateIntermediateVars method. This method
1137 /// replaces those, and does the same work but inside a loop over all
1138 /// resistor instances.
1139 ///
1140 /// @see Xyce::Device::Resistor::Instance::updatePrimaryState
1141 /// @author Eric Keiter, SNL
1142 /// @date 11/26/08
1143 
1144 bool Master::updateState(double * solVec, double * staVec, double * stoVec)
1145 {
1146  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
1147  {
1148  Instance & ri = *(*it);
1149 
1150  double v_pos = solVec[ri.li_Pos];
1151  double v_neg = solVec[ri.li_Neg];
1152 
1153  // Load RHS vector element for the positive circuit node KCL equ.
1154  ri.i0 = (v_pos-v_neg)*ri.G;
1155  }
1156 
1157  return true;
1158 }
1159 
1160 //-----------------------------------------------------------------------------
1161 // Function : Xyce::Device::Resistor::Master::loadDAEVectors
1162 // Purpose :
1163 // Special Notes :
1164 // Scope : public
1165 // Creator : Eric Keiter, SNL
1166 // Creation Date : 11/26/08
1167 //-----------------------------------------------------------------------------
1168 ///
1169 /// Load DAE vectors of all resistor instances, regardless of model
1170 ///
1171 /// @param solVec solution vector
1172 /// @param fVec f vector
1173 /// @param qVec q vector
1174 /// @param storeLeadF store lead current f vector
1175 /// @param storeLeadQ store lead current q vector
1176 ///
1177 /// @return true on success
1178 ///
1179 /// @note Because the resistor device re-implements the base-class
1180 /// Master::loadDAEVectors, the Instance::loadDAEFVector method is
1181 /// never called. This method replaces those, and does the same work
1182 /// but inside a loop over all resistor instances.
1183 ///
1184 /// @see Xyce::Device::Resistor::Instance::loadDAEFVector
1185 ///
1186 /// @author Eric Keiter, SNL
1187 /// @date 11/26/08
1188 
1189 bool Master::loadDAEVectors (double * solVec, double * fVec, double *qVec, double * bVec, double * storeLeadF, double * storeLeadQ, double * leadF, double * leadQ, double * junctionV)
1190 {
1191  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
1192  {
1193  Instance & ri = *(*it);
1194  fVec[ri.li_Pos] += ri.i0;
1195  fVec[ri.li_Neg] += -ri.i0;
1196  if( ri.loadLeadCurrent )
1197  {
1198  storeLeadF[ri.li_store_dev_i] = ri.i0;
1199  leadF[ri.li_branch_data] = ri.i0;
1200  junctionV[ri.li_branch_data] = solVec[ri.li_Pos] - solVec[ri.li_Neg];
1201  }
1202  }
1203  return true;
1204 }
1205 
1206 //-----------------------------------------------------------------------------
1207 // Function : Xyce::Device::Resistor::Master::loadDAEMatrices
1208 // Purpose :
1209 // Special Notes :
1210 // Scope : public
1211 // Creator : Eric Keiter, SNL
1212 // Creation Date : 11/26/08
1213 //-----------------------------------------------------------------------------
1214 ///
1215 /// Load DAE matrices for all resistor instances, regardless of model
1216 ///
1217 /// @param dFdx matrix of derivatives of F vector with respect to solution
1218 /// @param dQdx matrix of derivatives of Q vector with respect to solution
1219 ///
1220 /// @return true on success
1221 ///
1222 /// @note Because the resistor device re-implements the base-class
1223 /// Master::loadDAEMatrices, the Instance::loadDAEdFdx method is
1224 /// never called. This method replaces those, and does the same work
1225 /// but inside a loop over all resistor instances.
1226 ///
1227 /// @see Xyce::Device::Resistor::Instance::loadDAEdFdx
1228 ///
1229 /// @author Eric Keiter, SNL
1230 /// @date 11/26/08
1231 
1232 bool Master::loadDAEMatrices(Linear::Matrix & dFdx, Linear::Matrix & dQdx)
1233 {
1234  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
1235  {
1236  Instance & ri = *(*it);
1237 
1238 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
1239  *(ri.f_PosEquPosNodePtr) += ri.G;
1240  *(ri.f_PosEquNegNodePtr) -= ri.G;
1241  *(ri.f_NegEquPosNodePtr) -= ri.G;
1242  *(ri.f_NegEquNegNodePtr) += ri.G;
1243 #else
1244  dFdx[ri.li_Pos][ri.APosEquPosNodeOffset] += ri.G;
1245  dFdx[ri.li_Pos][ri.APosEquNegNodeOffset] -= ri.G;
1246  dFdx[ri.li_Neg][ri.ANegEquPosNodeOffset] -= ri.G;
1247  dFdx[ri.li_Neg][ri.ANegEquNegNodeOffset] += ri.G;
1248 #endif
1249  }
1250 
1251  return true;
1252 }
1253 
1254 //-----------------------------------------------------------------------------
1255 // Function : Xyce::Device::Resistor::Traits::factory
1256 // Purpose :
1257 // Special Notes :
1258 // Scope : public
1259 // Creator : David Baur
1260 // Creation Date :
1261 //-----------------------------------------------------------------------------
1262 ///
1263 /// Create a new instance of the Resistor device.
1264 ///
1265 /// @param configuration
1266 /// @param factory_block
1267 ///
1268 Device *
1269 Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
1270 {
1271  return new Master(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
1272 }
1273 
1274 //-----------------------------------------------------------------------------
1275 // Function : Xyce::Device::Resistor::registerDevice
1276 // Purpose :
1277 // Special Notes :
1278 // Scope : public
1279 // Creator : David Baur
1280 // Creation Date :
1281 //-----------------------------------------------------------------------------
1282 ///
1283 /// Define how to use the device in a netlist.
1284 ///
1285 /// This method is called from the Xyce::Device::registerOpenDevices
1286 /// function, which in turn is called by the device manager.
1287 ///
1288 /// The device is declared here to be an "R" device, which may optionally
1289 /// take a model card of type "R". This device will correspond to model
1290 /// level 1 of resistor models.
1291 void
1293 {
1295  .registerDevice("r", 1)
1296  .registerModelType("r", 1)
1297  .registerModelType("res", 1);
1298 }
1299 
1300 //-----------------------------------------------------------------------------
1301 // Function : resistorSensitivity::operator
1302 // Purpose : produces df/dp and dq/dp, where p=R.
1303 // Special Notes :
1304 // Scope : public
1305 // Creator : Eric Keiter, SNL
1306 // Creation Date : 7/18/2014
1307 //-----------------------------------------------------------------------------
1309  const ParameterBase &entity,
1310  const std::string & name,
1311  std::vector<double> & dfdp,
1312  std::vector<double> & dqdp,
1313  std::vector<double> & dbdp,
1314  std::vector<int> & Findices,
1315  std::vector<int> & Qindices,
1316  std::vector<int> & Bindices
1317  ) const
1318 {
1319  const ParameterBase * e1 = &entity;
1320  const Instance * in = dynamic_cast<const Instance *> (e1);
1321 
1322  double * solVec = in->extData.nextSolVectorRawPtr;
1323  double v_pos = solVec[in->li_Pos];
1324  double v_neg = solVec[in->li_Neg];
1325 
1326  double dfdpLoc = -(v_pos-v_neg)*in->G*in->G;
1327 
1328  dfdp.resize(2);
1329  dfdp[0] = +dfdpLoc;
1330  dfdp[1] = -dfdpLoc;
1331 
1332  Findices.resize(2);
1333  Findices[0] = in->li_Pos;
1334  Findices[1] = in->li_Neg;
1335 }
1336 
1337 } // namespace Resistor
1338 } // namespace Device
1339 } // 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.
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)
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:92
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.
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.