Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_DEV_Resistor3.C
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2 // Copyright Notice
3 //
4 // Copyright 2002 Sandia Corporation. Under the terms
5 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
6 // Government retains certain rights in this software.
7 //
8 // Xyce(TM) Parallel Electrical Simulator
9 // Copyright (C) 2002-2014 Sandia Corporation
10 //
11 // This program is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation, either version 3 of the License, or
14 // (at your option) any later version.
15 //
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 //-----------------------------------------------------------------------------
24 
25 //-------------------------------------------------------------------------
26 // Filename : $RCSfile: N_DEV_Resistor3.C,v $
27 //
28 // Purpose :
29 //
30 // Special Notes :
31 //
32 // Creator : Richard Schiek, Electrical and Microsystems Modeling
33 //
34 // Creation Date : 2/1/10
35 //
36 // Revision Information:
37 // ---------------------
38 //
39 // Revision Number: $Revision: 1.44 $
40 //
41 // Revision Date : $Date: 2014/05/22 17:40:30 $
42 //
43 // Current Owner : $Author: erkeite $
44 //-------------------------------------------------------------------------
45 #include <Xyce_config.h>
46 
47 #include <memory>
48 
49 // ---------- Standard Includes ----------
50 
51 // ---------- Xyce Includes ----------
52 #include <N_DEV_DeviceOptions.h>
53 #include <N_DEV_ExternData.h>
54 #include <N_DEV_MatrixLoadData.h>
55 #include <N_DEV_Resistor3.h>
56 #include <N_DEV_SolverState.h>
57 #include <N_DEV_Message.h>
58 #include <N_ERH_ErrorMgr.h>
59 
60 #include <N_DEV_Resistor.h>
61 
62 #include <N_LAS_Vector.h>
63 #include <N_LAS_Matrix.h>
64 #include <N_UTL_BreakPoint.h>
65 
66 namespace Xyce {
67 namespace Device {
68 namespace Resistor3 {
69 
71 {
72  p.addPar ("R", 1000.0, false, ParameterType::TIME_DEP,
74  U_OHM, CAT_NONE, "Resistance");
75 
76  p.addPar ("L", 0.0, false, ParameterType::NO_DEP,
78  U_METER, CAT_NONE, "Length");
79 
80  p.addPar ("W", 0.0, false, ParameterType::NO_DEP,
82  U_METER, CAT_NONE, "Width");
83 
84  p.addPar ("TEMP", 0.0, false, ParameterType::TIME_DEP,
86  U_DEGC, CAT_NONE, "Device temperature");
87 
88  p.addPar ("TC1", 0.0, false, ParameterType::NO_DEP,
91  U_DEGCM1, CAT_NONE, "Linear Temperature Coefficient");
92 
93  p.addPar ("TC2", 0.0, false, ParameterType::NO_DEP,
96  U_DEGCM2, CAT_NONE, "Quadratic Temperature Coefficient");
97 
98  // This call tells the parameter handling code that TC can be specified
99  // as a vector with up to two elements as in TC=a,b. It then translates
100  // TC=a,b into TC1=a TC2=b. Likewise, TC=a will translate into TC1=a
101  p.makeVector ("TC", 2);
102 
103  p.addPar ("DTEMP", 0.0, false, ParameterType::NO_DEP,
106  U_DEGC, CAT_NONE, "Device Temperature -- For compatibility only. Parameter is NOT used");
107 }
108 
110 {}
111 
112 std::vector< std::vector<int> > Instance::jacStamp;
113 std::vector< std::vector<int> > Instance::jacStampPDE;
114 
115 
116 // Class Instance
117 //-----------------------------------------------------------------------------
118 // Function : Instance::Instance
119 // Purpose : "instance block" constructor
120 // Special Notes :
121 // Scope : public
122 // Creator : Richard Schiek, Electrical and Microsystems Modeling
123 // Creation Date : 2/1/10
124 //-----------------------------------------------------------------------------
126  const Configuration & configuration,
127  const InstanceBlock & IB,
128  Model & Viter,
129  const FactoryBlock & factory_block)
130  : DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
131  model_(Viter),
132  srcCurrent(0.0),
133  srcVoltage(0.0),
134  srcDrop(0.0),
135  srcBC(0.0),
136 
137  li_Pos(-1),
138  li_Neg(-1),
139  li_Bra(-1),
140  tempCoeff1(0.0),
141  tempCoeff2(0.0),
142  dtemp(0.0),
143  tempCoeff1Given(false),
144  tempCoeff2Given(false),
145  dtempGiven(false),
146 
147  ABraEquPosNodeOffset(-1),
148  ABraEquNegNodeOffset(-1),
149  APosEquBraVarOffset(-1),
150  ANegEquBraVarOffset(-1),
151  ABraEquBraVarOffset(-1),
152  APosEquPosNodeOffset(-1),
153  ANegEquNegNodeOffset(-1),
154 
156  fBraEquPosNodePtr(0),
157  fBraEquNegNodePtr(0),
158  fPosEquBraVarPtr(0),
159  fNegEquBraVarPtr(0),
160  fPosEquPosNodePtr(0),
161  fNegEquNegNodePtr(0),
162  fBraEquBraVarPtr(0),
163 #endif
164 
165  scale(1.0),
166  nlstep(-1),
167  source(0.0),
168  v_pos(0.0),
169  v_neg(0.0),
170  i_bra(0.0)
171 {
172  numIntVars = 1;
173  numExtVars = 2;
174  numStateVars = 0;
175 
176  if( jacStamp.empty() )
177  {
178  jacStamp.resize(3);
179  jacStamp[0].resize(1);
180  jacStamp[0][0] = 2;
181  jacStamp[1].resize(1);
182  jacStamp[1][0] = 2;
183  jacStamp[2].resize(2);
184  jacStamp[2][0] = 0;
185  jacStamp[2][1] = 1;
186 
187  // PDE supporting stamp. This includes diagonal elements, needed by the
188  // 2-level Newton.
189  jacStampPDE.resize(3);
190  jacStampPDE[0].resize(2);
191  jacStampPDE[0][0] = 0;
192  jacStampPDE[0][1] = 2;
193  jacStampPDE[1].resize(2);
194  jacStampPDE[1][0] = 1;
195  jacStampPDE[1][1] = 2;
196  jacStampPDE[2].resize(3);
197  jacStampPDE[2][0] = 0;
198  jacStampPDE[2][1] = 1;
199  jacStampPDE[2][2] = 2;
200  }
201 
202  // Set params to constant default values:
203  setDefaultParams ();
204 
205  // Set params according to instance line and constant defaults from metadata:
206  setParams (IB.params);
207 
208  processParams();
209 
210  // Calculate any parameters specified as expressions:
212  processParams();
213 }
214 
215 //-----------------------------------------------------------------------------
216 // Function : Instance::~Instance
217 // Purpose : destructor
218 // Special Notes :
219 // Scope : public
220 // Creator : Richard Schiek, Electrical and Microsystems Modeling
221 // Creation Date : 2/1/10
222 //-----------------------------------------------------------------------------
224 {
225 }
226 
227 //-----------------------------------------------------------------------------
228 // Function : Instance::processParams
229 // Purpose :
230 // Special Notes :
231 // Scope : public
232 // Creator : Richard Schiek, Electrical and Microsystems Modeling
233 // Creation Date : 2/1/10
234 //-----------------------------------------------------------------------------
236 {
237  return true;
238 }
239 
240 //-----------------------------------------------------------------------------
241 // Function : Instance::registerLIDs
242 // Purpose :
243 // Special Notes :
244 // Scope : public
245 // Creator : Richard Schiek, Electrical and Microsystems Modeling
246 // Creation Date : 2/1/10
247 //-----------------------------------------------------------------------------
248 void Instance::registerLIDs ( const std::vector<int> & intLIDVecRef,
249  const std::vector<int> & extLIDVecRef)
250 {
251  std::string msg;
252 
253 #ifdef Xyce_DEBUG_DEVICE
254  if (getDeviceOptions().debugLevel > 0 )
255  {
256  Xyce::dout() << std::endl << section_divider << std::endl;
257  Xyce::dout() << " Instance::registerLIDs" << std::endl;
258  Xyce::dout() << " name = " << getName() << std::endl;
259  }
260 #endif
261 
262  // Check if the size of the ID lists corresponds to the
263  // proper number of internal and external variables.
264  int numInt = intLIDVecRef.size();
265  int numExt = extLIDVecRef.size();
266 
267  if (numInt != numIntVars)
268  {
269  msg = "Instance::registerLIDs:";
270  msg += "numInt != numIntVars";
271  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL_0,msg);
272  }
273 
274  if (numExt != numExtVars)
275  {
276  msg = "Instance::registerLIDs:";
277  msg += "numExt != numExtVars";
278  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL_0,msg);
279  }
280 
281  // copy over the global ID lists.
282  intLIDVec = intLIDVecRef;
283  extLIDVec = extLIDVecRef;
284 
285  // Now use these lists to obtain the indices into the
286  // linear algebra entities. This assumes an order.
287  // For the matrix indices, first do the rows.
288 
289  li_Pos = extLIDVec[0];
290  li_Neg = extLIDVec[1];
291  li_Bra = intLIDVec[0];
292 
293 #ifdef Xyce_DEBUG_DEVICE
294  if (getDeviceOptions().debugLevel > 0 )
295  {
296  Xyce::dout() << " li_Pos = " << li_Pos << std::endl;
297  Xyce::dout() << " li_Neg = " << li_Neg << std::endl;
298  Xyce::dout() << " li_Bra = " << li_Bra << std::endl;
299  Xyce::dout() << section_divider << std::endl;
300  }
301 #endif
302 }
303 
304 //-----------------------------------------------------------------------------
305 // Function : Instance::getIntNameMap
306 // Purpose :
307 // Special Notes :
308 // Scope : public
309 // Creator : Richard Schiek, Electrical and Microsystems Modeling
310 // Creation Date : 2/1/10
311 //-----------------------------------------------------------------------------
312 std::map<int,std::string> & Instance::getIntNameMap ()
313 {
314  // set up the internal name map, if it hasn't been already.
315  if (intNameMap.empty ())
316  {
317  intNameMap[ li_Bra ] = spiceInternalName(getName(), "branch");
318  }
319 
320  return intNameMap;
321 }
322 
323 
324 
325 //-----------------------------------------------------------------------------
326 // Function : Instance::registerStateLIDs
327 // Purpose :
328 // Special Notes :
329 // Scope : public
330 // Creator : Richard Schiek, Electrical and Microsystems Modeling
331 // Creation Date : 2/1/10
332 //-----------------------------------------------------------------------------
333 void Instance::registerStateLIDs( const std::vector<int> & staLIDVecRef )
334 {
335  AssertLIDs(staLIDVecRef.size() == numStateVars);
336 }
337 
338 //-----------------------------------------------------------------------------
339 // Function : Instance::jacobianStamp
340 // Purpose :
341 // Special Notes :
342 // Scope : public
343 // Creator : Richard Schiek, Electrical and Microsystems Modeling
344 // Creation Date : 2/1/10
345 //-----------------------------------------------------------------------------
346 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
347 {
348  if (getSolverState().PDESystemFlag)
349  return jacStampPDE;
350 
351  return jacStamp;
352 }
353 
354 //-----------------------------------------------------------------------------
355 // Function : Instance::registerJacLIDs
356 // Purpose :
357 // Special Notes :
358 // Scope : public
359 // Creator : Richard Schiek, Electrical and Microsystems Modeling
360 // Creation Date : 2/1/10
361 //-----------------------------------------------------------------------------
362 void Instance::registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec )
363 {
364  DeviceInstance::registerJacLIDs( jacLIDVec );
365  if (getSolverState().PDESystemFlag)
366  {
367  APosEquBraVarOffset = jacLIDVec[0][1];
368  ANegEquBraVarOffset = jacLIDVec[1][1];
369  ABraEquPosNodeOffset = jacLIDVec[2][0];
370  ABraEquNegNodeOffset = jacLIDVec[2][1];
371  }
372  else
373  {
374  APosEquBraVarOffset = jacLIDVec[0][0];
375  ANegEquBraVarOffset = jacLIDVec[1][0];
376  ABraEquPosNodeOffset = jacLIDVec[2][0];
377  ABraEquNegNodeOffset = jacLIDVec[2][1];
378  }
379 
380 }
381 
382 //-----------------------------------------------------------------------------
383 // Function : Instance::setupPointers
384 // Purpose :
385 // Special Notes :
386 // Scope : public
387 // Creator : Richard Schiek, Electrical and Microsystems Modeling
388 // Creation Date : 2/1/10
389 //-----------------------------------------------------------------------------
391 {
392 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
393  N_LAS_Matrix & dFdx = *(extData.dFdxMatrixPtr);
394 
399 #endif
400 }
401 
402 //-----------------------------------------------------------------------------
403 // Function : Instance::updateIntermediateVars
404 // Purpose :
405 // Special Notes :
406 // Scope : public
407 // Creator : Richard Schiek, Electrical and Microsystems Modeling
408 // Creation Date : 2/1/10
409 //-----------------------------------------------------------------------------
411 {
412  double * solVec = extData.nextSolVectorRawPtr;
413 
414  // Get the value for the source.
415  source = 0.0;
416 
417  // get the value for v_pos, v_neg, i_bra
418  v_pos = solVec[li_Pos];
419  v_neg = solVec[li_Neg];
420  i_bra = solVec[li_Bra];
421 
422  srcCurrent = i_bra;
423  srcDrop = (v_pos-v_neg);
424  srcBC = source;
426 
427  if( getDeviceOptions().scale_src != 0.0 )
428  {
429  srcCurrent *= scale;
430 
431  // first newton step, generate new scaling
432  //if( nlsMgrPtr->getNonLinearIter() != nlstep )
433  if( getSolverState().newtonIter != nlstep )
434  {
435  //nlstep = nlsMgrPtr->getNonLinearIter();
437  double new_scale = fabs(i_bra) * scale;
438 
439  scale = Xycemax( new_scale, getDeviceOptions().scale_src );
440  }
441 
442  srcVoltage *= scale;
443  srcDrop *= scale;
444  srcBC *= scale;
445  }
446 
447  return true;
448 }
449 
450 //-----------------------------------------------------------------------------
451 // Function : Instance::updatePrimaryState
452 // Purpose :
453 // Special Notes :
454 // Scope : public
455 // Creator : Richard Schiek, Electrical and Microsystems Modeling
456 // Creation Date : 2/1/10
457 //-----------------------------------------------------------------------------
459 {
460  bool bsuccess = updateIntermediateVars ();
461  return bsuccess;
462 }
463 
464 //-----------------------------------------------------------------------------
465 // Function : Instance::loadDAEFVector
466 //
467 // Purpose : Loads the F-vector contributions for a single
468 // vsrc instance.
469 //
470 // Special Notes :
471 //
472 // Scope : public
473 // Creator : Richard Schiek, Electrical and Microsystems Modeling
474 // Creation Date : 2/1/10
475 //-----------------------------------------------------------------------------
477 {
478  // Using values determined during the loadRHS function call.
479  // (srcCurrent, srcVoltage).
480 
481  double * fVec = extData.daeFVectorRawPtr;
482 
483  fVec[li_Pos] += srcCurrent;
484  fVec[li_Neg] += -srcCurrent;
485  fVec[li_Bra] += srcDrop;
486  fVec[li_Bra] -= srcBC;
487 
488  return true;
489 }
490 
491 //-----------------------------------------------------------------------------
492 // Function : Instance::loadDAEdFdx ()
493 //
494 // Purpose : Loads the F-vector contributions for a single
495 // resistor instance.
496 //
497 // Special Notes :
498 //
499 // Scope : public
500 // Creator : Richard Schiek, Electrical and Microsystems Modeling
501 // Creation Date : 2/1/10
502 //-----------------------------------------------------------------------------
504 {
505  N_LAS_Matrix & dFdx = *(extData.dFdxMatrixPtr);
506 
507  dFdx[li_Pos][APosEquBraVarOffset] += 1.0;
508  dFdx[li_Neg][ANegEquBraVarOffset] -= 1.0;
509  dFdx[li_Bra][ABraEquPosNodeOffset] += 1.0;
510  dFdx[li_Bra][ABraEquNegNodeOffset] -= 1.0;
511 
512  return true;
513 }
514 
515 // end of new-DAE functions
516 
517 //-----------------------------------------------------------------------------
518 // Function : Instance::getMaxTimeStepSize
519 // Purpose :
520 // Special Notes :
521 // Scope : public
522 // Creator : Richard Schiek, Electrical and Microsystems Modeling
523 // Creation Date : 2/1/10
524 //-----------------------------------------------------------------------------
526 {
527  double maxStep = 1.0e99;
528  return maxStep;
529 }
530 
531 //-----------------------------------------------------------------------------
532 // Function : Instance::varTypes
533 // Purpose :
534 // Special Notes :
535 // Scope : public
536 // Creator : Richard Schiek, Electrical and Microsystems Modeling
537 // Creation Date : 2/1/10
538 //-----------------------------------------------------------------------------
539 void Instance::varTypes( std::vector<char> & varTypeVec )
540 {
541  varTypeVec.resize(1);
542  varTypeVec[0] = 'I';
543 }
544 
545 // Class Model
546 
547 //-----------------------------------------------------------------------------
548 // Function : Model::Model
549 // Purpose : copy constructor
550 // Special Notes :
551 // Scope : public
552 // Creator : Richard Schiek, Electrical and Microsystems Modeling
553 // Creation Date : 2/1/10
554 //-----------------------------------------------------------------------------
556  const Configuration & configuration,
557  const ModelBlock & MB,
558  const FactoryBlock & factory_block)
559  : DeviceModel(MB, configuration.getModelParameters(), factory_block),
560  DC_TRAN (0)
561 {
562 }
563 
564 //-----------------------------------------------------------------------------
565 // Function : Model::~Model
566 // Purpose : destructor
567 // Special Notes :
568 // Scope : public
569 // Creator : Richard Schiek, Electrical and Microsystems Modeling
570 // Creation Date : 2/1/10
571 //-----------------------------------------------------------------------------
573 {
574  std::vector<Instance*>::iterator iter;
575  std::vector<Instance*>::iterator first = instanceContainer.begin();
576  std::vector<Instance*>::iterator last = instanceContainer.end();
577 
578  for (iter=first; iter!=last; ++iter)
579  {
580  delete (*iter);
581  }
582 }
583 
584 // Additional Declarations
585 
586 //-----------------------------------------------------------------------------
587 // Function : Model::printOutInstances
588 // Purpose : debugging tool.
589 // Special Notes :
590 // Scope : public
591 // Creator : Richard Schiek, Electrical and Microsystems Modeling
592 // Creation Date : 2/1/10
593 //-----------------------------------------------------------------------------
594 std::ostream &Model::printOutInstances(std::ostream &os) const
595 {
596  std::vector<Instance*>::const_iterator iter;
597  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
598  std::vector<Instance*>::const_iterator last = instanceContainer.end();
599 
600  int i;
601  os << std::endl;
602  os << " name model name Parameters" << std::endl;
603  for (i=0, iter=first; iter!=last; ++iter, ++i)
604  {
605  os << " " << i << ": " << (*iter)->getName() << " ";
606  os << getName();
607  os << std::endl;
608  }
609 
610  os << std::endl;
611 
612  return os;
613 }
614 
615 //-----------------------------------------------------------------------------
616 // Function : Model::forEachInstance
617 // Purpose :
618 // Special Notes :
619 // Scope : public
620 // Creator : David Baur
621 // Creation Date : 2/4/2014
622 //-----------------------------------------------------------------------------
623 /// Apply a device instance "op" to all instances associated with this
624 /// model
625 ///
626 /// @param[in] op Operator to apply to all instances.
627 ///
628 ///
629 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
630 {
631  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
632  op(*it);
633 }
634 
635 
636 
637 //-----------------------------------------------------------------------------
638 // Vsrc Master functions:
639 //-----------------------------------------------------------------------------
640 
641 
642 //-----------------------------------------------------------------------------
643 // Function : Master::updateState
644 // Purpose :
645 // Special Notes :
646 // Scope : public
647 // Creator : Richard Schiek, Electrical and Microsystems Modeling
648 // Creation Date : 2/1/10
649 //-----------------------------------------------------------------------------
650 bool Master::updateState (double * solVec, double * staVec, double * stoVec)
651 {
652  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
653  {
654  Instance & vi = *(*it);
655 
656  // Get the value for the source.
657  vi.source = 0.0;
658 
659  // get the value for v_pos, v_neg, i_bra
660  vi.v_pos = solVec[vi.li_Pos];
661  vi.v_neg = solVec[vi.li_Neg];
662  vi.i_bra = solVec[vi.li_Bra];
663 
664  vi.srcCurrent = vi.i_bra;
665  vi.srcDrop = (vi.v_pos-vi.v_neg);
666  vi.srcBC = vi.source;
667  vi.srcVoltage = vi.srcDrop-vi.srcBC;
668 
669  if( getDeviceOptions().scale_src != 0.0 )
670  {
671  vi.srcCurrent *= vi.scale;
672 
673  // first newton step, generate new scaling
674  if( getSolverState().newtonIter != vi.nlstep )
675  {
677  double new_scale = fabs(vi.i_bra) * vi.scale;
678 
679  vi.scale = Xycemax( new_scale, getDeviceOptions().scale_src );
680  }
681 
682  vi.srcVoltage *= vi.scale;
683  vi.srcDrop *= vi.scale;
684  vi.srcBC *= vi.scale;
685  }
686  }
687 // }
688 
689  return true;
690 }
691 
692 //-----------------------------------------------------------------------------
693 // Function : Master::loadDAEVectors
694 // Purpose :
695 // Special Notes :
696 // Scope : public
697 // Creator : Richard Schiek, Electrical and Microsystems Modeling
698 // Creation Date : 2/1/10
699 //-----------------------------------------------------------------------------
700 bool Master::loadDAEVectors (double * solVec, double * fVec, double *qVec, double * bVec, double * storeLeadF, double * storeLeadQ)
701 {
702  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
703  {
704  Instance & vi = *(*it);
705 
706 
707  fVec[vi.li_Pos] += vi.srcCurrent;
708 
709  fVec[vi.li_Neg] += -vi.srcCurrent;
710 
711  fVec[vi.li_Bra] += vi.srcDrop;
712 
713  fVec[vi.li_Bra] -= vi.srcBC;
714  }
715 
716  return true;
717 }
718 
719 //-----------------------------------------------------------------------------
720 // Function : Master::loadDAEMatrices
721 // Purpose :
722 // Special Notes :
723 // Scope : public
724 // Creator : Richard Schiek, Electrical and Microsystems Modeling
725 // Creation Date : 2/1/10
726 //-----------------------------------------------------------------------------
727 bool Master::loadDAEMatrices (N_LAS_Matrix & dFdx, N_LAS_Matrix & dQdx)
728 {
729  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
730  {
731  Instance & vi = *(*it);
732 
733 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
734 
735  *(vi.fPosEquBraVarPtr) += 1.0;
736 
737  *(vi.fNegEquBraVarPtr) -= 1.0;
738 
739  *(vi.fBraEquPosNodePtr) += 1.0;
740 
741  *(vi.fBraEquNegNodePtr) -= 1.0;
742 #else
743 
744  dFdx[vi.li_Pos][vi.APosEquBraVarOffset] += 1.0;
745 
746  dFdx[vi.li_Neg][vi.ANegEquBraVarOffset] -= 1.0;
747 
748  dFdx[vi.li_Bra][vi.ABraEquPosNodeOffset] += 1.0;
749 
750  dFdx[vi.li_Bra][vi.ABraEquNegNodeOffset] -= 1.0;
751 #endif
752 
753  }
754 
755  return true;
756 }
757 
758 Device *
759 Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
760 {
761  return new Master(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
762 }
763 
765 {
767  .registerDevice("r", 3)
768  .registerModelType("r", 3);
769 }
770 
771 } // namespace Resistor3
772 } // namespace Device
773 } // namespace Xyce