Xyce  6.1
N_DEV_MESFET.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_MESFET.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.133 $
40 //
41 // Revision Date : $Date: 2015/09/15 19:53:49 $
42 //
43 // Current Owner : $Author: tvrusso $
44 //-------------------------------------------------------------------------
45 
46 #include <Xyce_config.h>
47 
48 
49 // ---------- Standard Includes ----------
50 #include <N_UTL_Math.h>
51 
52 // ---------- Xyce Includes ----------
53 #include <N_DEV_Const.h>
54 #include <N_DEV_DeviceOptions.h>
55 #include <N_DEV_ExternData.h>
56 #include <N_DEV_MESFET.h>
57 #include <N_DEV_MatrixLoadData.h>
58 #include <N_DEV_SolverState.h>
59 #include <N_DEV_Message.h>
60 #include <N_ERH_ErrorMgr.h>
61 
62 #include <N_LAS_Matrix.h>
63 #include <N_LAS_Vector.h>
64 #include <N_UTL_FeatureTest.h>
65 
66 namespace Xyce {
67 namespace Device {
68 namespace MESFET {
69 
71 {
72  p.addPar("TEMP", 0.0, &MESFET::Instance::temp)
73  .setExpressionAccess(ParameterType::TIME_DEP)
74  .setDescription("Device temperature");
75 
76  p.addPar("AREA", 1.0, &MESFET::Instance::area)
77  .setUnit(U_METER2)
78  .setCategory(CAT_GEOMETRY)
79  .setDescription("device area");
80 }
81 
83 {
84  p.addPar("AF", 1.0, &MESFET::Model::AF)
85  .setUnit(U_NONE)
86  .setCategory(CAT_FLICKER)
87  .setDescription("Flicker noise exponent");
88 
89  p.addPar("B", 0.3, &MESFET::Model::B)
90  .setUnit(U_VOLTM1)
91  .setCategory(CAT_PROCESS)
92  .setDescription("Doping tail parameter");
93 
94  p.addPar("BETA", 2.5e-3, &MESFET::Model::BETA)
95  .setUnit(U_AMPVM2)
96  .setCategory(CAT_PROCESS)
97  .setDescription("Transconductance parameter");
98 
99  p.addPar("ALPHA", 2.0, &MESFET::Model::ALPHA)
100  .setUnit(U_VOLTM1)
101  .setCategory(CAT_PROCESS)
102  .setDescription("Saturation voltage parameter");
103 
104  p.addPar("CGS", 0.0, &MESFET::Model::CGS)
105  .setExpressionAccess(ParameterType::MIN_CAP)
106  .setUnit(U_FARAD)
107  .setCategory(CAT_CAP)
108  .setDescription("Zero-bias gate-source junction capacitance");
109 
110  p.addPar("CGD", 0.0, &MESFET::Model::CGD)
111  .setExpressionAccess(ParameterType::MIN_CAP)
112  .setUnit(U_FARAD)
113  .setCategory(CAT_CAP)
114  .setDescription("Zero-bias gate-drain junction capacitance");
115 
116  p.addPar("FC", 0.5, &MESFET::Model::FC)
117  .setUnit(U_FARAD)
118  .setCategory(CAT_CAP)
119  .setDescription("Coefficient for forward-bias depletion capacitance");
120 
121  p.addPar("IS", 1e-14, &MESFET::Model::IS)
122  .setUnit(U_AMP)
123  .setCategory(CAT_CURRENT)
124  .setDescription("Gate junction saturation current");
125 
126  p.addPar("KF", 0.05, &MESFET::Model::KF)
127  .setUnit(U_NONE)
128  .setCategory(CAT_FLICKER)
129  .setDescription("Flicker noise coefficient");
130 
131  p.addPar("LAMBDA",0.0, &MESFET::Model::LAMBDA)
132  .setUnit(U_VOLTM1)
133  .setCategory(CAT_VOLT)
134  .setDescription("Channel length modulation");
135 
136  p.addPar("PB", 1.0, &MESFET::Model::PB)
137  .setUnit(U_VOLT)
138  .setCategory(CAT_VOLT)
139  .setDescription("Gate junction potential");
140 
141  p.addPar("RD", 0.0, &MESFET::Model::RD)
142  .setExpressionAccess(ParameterType::MIN_RES)
143  .setUnit(U_OHM)
144  .setCategory(CAT_RES)
145  .setDescription("Drain ohmic resistance");
146 
147  p.addPar("RS", 0.0, &MESFET::Model::RS)
148  .setExpressionAccess(ParameterType::MIN_RES)
149  .setUnit(U_OHM)
150  .setCategory(CAT_RES)
151  .setDescription("Source ohmic resistance");
152 
153  p.addPar("TNOM", 0.0, &MESFET::Model::TNOM)
154  .setUnit(STANDARD)
155  .setCategory(CAT_NONE)
156  .setDescription("Parameter measurement temperature");
157 
158  p.addPar("VTO", 0.0, &MESFET::Model::VTO)
159  .setUnit(U_VOLT)
160  .setCategory(CAT_VOLT)
161  .setDescription("Threshold voltage");
162 
164 }
165 
166 std::vector< std::vector<int> > Instance::jacStamp_DC_SC;
167 std::vector< std::vector<int> > Instance::jacStamp_DC;
168 std::vector< std::vector<int> > Instance::jacStamp_SC;
169 std::vector< std::vector<int> > Instance::jacStamp;
170 
171 std::vector<int> Instance::jacMap_DC_SC;
172 std::vector<int> Instance::jacMap_DC;
173 std::vector<int> Instance::jacMap_SC;
174 std::vector<int> Instance::jacMap;
175 
176 std::vector< std::vector<int> > Instance::jacMap2_DC_SC;
177 std::vector< std::vector<int> > Instance::jacMap2_DC;
178 std::vector< std::vector<int> > Instance::jacMap2_SC;
179 std::vector< std::vector<int> > Instance::jacMap2;
180 
181 //------------------- Class Model ---------------------------------
182 //-----------------------------------------------------------------------------
183 // Function : Model::Model
184 // Purpose : model block constructor
185 // Special Notes :
186 // Scope : public
187 // Creator : pmc
188 // Creation Date : 11/16/2003
189 //-----------------------------------------------------------------------------
191  const Configuration & configuration,
192  const ModelBlock & MB,
193  const FactoryBlock & factory_block)
194  : DeviceModel(MB, configuration.getModelParameters(), factory_block),
195  AF(1.0),
196  B(0.3),
197  ALPHA(2.0),
198  BETA(2.5e-3),
199  CGS(0.0),
200  CGD(0.0),
201  FC(0.5),
202  IS(1.0e-14),
203  KF(0.0),
204  LAMBDA(0.0),
205  PB(1.0),
206  RD(0.0),
207  RS(0.0),
208  TNOM(CONSTREFTEMP),
209  VTO(-2.0),
210  fNcoef(0.0),
211  fNexp(1.0),
212  dtype(CONSTNMOS)
213 {
214  if (getType() != "")
215  {
216  if (getType() == "NMF") {
217  dtype = CONSTNMOS;
218  }
219  else if (getType() == "PMF") {
220  dtype = CONSTPMOS;
221  }
222  else
223  {
224  UserError0(*this) << "Could not recognize the type for model " << getName();
225  }
226  }
227 
228 
229  // Set params to constant default values:
230  setDefaultParams ();
231 
232  // Set params according to .model line and constant defaults from metadata:
233  setModParams (MB.params);
234 
235  // Set any non-constant parameter defaults:
236  if (!given("TNOM"))
238 
239  // Calculate any parameters specified as expressions:
241 
242  // calculate dependent (ie computed) params and check for errors:
243  processParams ();
244 }
245 
246 //-----------------------------------------------------------------------------
247 // Function : Model::~Model
248 // Purpose : destructor
249 // Special Notes :
250 // Scope : public
251 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
252 // Creation Date : 3/16/00
253 //-----------------------------------------------------------------------------
255 {
256  std::vector<Instance*>::iterator iter;
257  std::vector<Instance*>::iterator first = instanceContainer.begin();
258  std::vector<Instance*>::iterator last = instanceContainer.end();
259 
260  for (iter=first; iter!=last; ++iter)
261  {
262  delete (*iter);
263  }
264 
265 }
266 
267 
268 //-----------------------------------------------------------------------------
269 // Function : Model::printOutInstances
270 // Purpose : debugging tool.
271 // Special Notes :
272 // Scope : public
273 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
274 // Creation Date : 3/16/00
275 //-----------------------------------------------------------------------------
276 std::ostream &Model::printOutInstances(std::ostream &os) const
277 {
278  std::vector<Instance*>::const_iterator iter;
279  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
280  std::vector<Instance*>::const_iterator last = instanceContainer.end();
281 
282  int i,isize;
283  isize = instanceContainer.size();
284  os << std::endl;
285  os << "Number of MESFET Instances: " << isize << std::endl;
286  os << " name model name Parameters" << std::endl;
287 
288  for (i=0, iter=first; iter!=last; ++iter, ++i)
289  {
290  os << " " << i << ": " << (*iter)->getName() << "\t";
291  os << getName();
292  os << std::endl;
293  }
294 
295  os << std::endl;
296 
297  return os;
298 }
299 
300 //-----------------------------------------------------------------------------
301 // Function : Model::forEachInstance
302 // Purpose :
303 // Special Notes :
304 // Scope : public
305 // Creator : David Baur
306 // Creation Date : 2/4/2014
307 //-----------------------------------------------------------------------------
308 /// Apply a device instance "op" to all instances associated with this
309 /// model
310 ///
311 /// @param[in] op Operator to apply to all instances.
312 ///
313 ///
314 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
315 {
316  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
317  op(*it);
318 }
319 
320 
321 //-----------------------------------------------------------------------------
322 // Function : Model::processParams
323 // Purpose :
324 // Special Notes :
325 // Scope : public
326 // Creator : pmc
327 // Creation Date : 11/16/2003
328 //-----------------------------------------------------------------------------
330 {
331 
332  return true;
333 }
334 
335 //----------------------------------------------------------------------------
336 // Function : Model::processInstanceParams
337 // Purpose :
338 // Special Notes :
339 // Scope : public
340 // Creator : Dave Shirely, PSSI
341 // Creation Date : 03/23/06
342 //----------------------------------------------------------------------------
344 {
345 
346  std::vector<Instance*>::iterator iter;
347  std::vector<Instance*>::iterator first = instanceContainer.begin();
348  std::vector<Instance*>::iterator last = instanceContainer.end();
349 
350  for (iter=first; iter!=last; ++iter)
351  {
352  (*iter)->processParams();
353  }
354 
355  return true;
356 }
357 
358 //------------------------ Class Instance -------------------------
359 //-----------------------------------------------------------------------------
360 // Function : Instance::Instance
361 // Purpose : instance block constructor
362 // Special Notes :
363 // Scope : public
364 // Creator : pmc
365 // Creation Date : 11/16/2003
366 //-----------------------------------------------------------------------------
368  const Configuration & configuration,
369  const InstanceBlock & instance_block,
370  Model & model,
371  const FactoryBlock & factory_block)
372  : DeviceInstance(instance_block, configuration.getInstanceParameters(), factory_block),
373  model_(model),
374  limitedFlag(false),
375  off(0),
376  ic(0),
377  area(1.0),
378  ic_vds(0.0),
379  ic_vgs(0.0),
380  temp(getDeviceOptions().temp.getImmutableValue<double>()),
381  sourceCond(0.0),
382  drainCond(0.0),
383  tCGS(0.0),
384  tCGD(0.0),
385  tIS(0.0),
386  tPB(0.0),
387  tBeta(0.0),
388  tvt0(0.0),
389  tLambda(0.0),
390  tAlpha(0.0),
391  tRD(0.0),
392  tRS(0.0),
393  tMESb(0.0),
394  Bfac(0.0),
395  dNode(0),
396  gNode(0),
397  sNode(0),
398  dpNode(0),
399  spNode(0),
400  Vgs(0.0),
401  Vgd(0.0),
402  gm(0.0),
403  gds(0.0),
404  ggs(0.0),
405  ggd(0.0),
406  p(0.0),
407  // Solution variables and intermediate quantities
408  // drain,source,gate, drainprime and sourceprime voltages
409  Vd(0.0),
410  Vs(0.0),
411  Vg(0.0),
412  Vdp(0.0),
413  Vsp(0.0),
414  // vector local indices
415  li_Drain(-1),
416  li_DrainPrime(-1),
417  li_Source(-1),
418  li_SourcePrime(-1),
419  li_Gate(-1),
420  // Jacobian Matrix
421  // Jacobian Matrix Offset:
422  // V_d Row:
423  ADrainEquDrainNodeOffset(-1),
424  ADrainEquDrainPrimeNodeOffset(-1),
425  // V_g Row:
426  AGateEquGateNodeOffset(-1),
427  AGateEquDrainPrimeNodeOffset(-1),
428  AGateEquSourcePrimeNodeOffset(-1),
429  // V_s Row:
430  ASourceEquSourceNodeOffset(-1),
431  ASourceEquSourcePrimeNodeOffset(-1),
432  // V_d' Row:
433  ADrainPrimeEquDrainNodeOffset(-1),
434  ADrainPrimeEquGateNodeOffset(-1),
435  ADrainPrimeEquDrainPrimeNodeOffset(-1),
436  ADrainPrimeEquSourcePrimeNodeOffset(-1),
437  // V_s' Row:
438  ASourcePrimeEquGateNodeOffset(-1),
439  ASourcePrimeEquSourceNodeOffset(-1),
440  ASourcePrimeEquDrainPrimeNodeOffset(-1),
441  ASourcePrimeEquSourcePrimeNodeOffset(-1),
442 
444  // dFdx Matrix Ptr:
445  // V_d Row:
446  f_DrainEquDrainNodePtr(0),
447  f_DrainEquDrainPrimeNodePtr(0),
448  // V_g Row:
449  f_GateEquGateNodePtr(0),
450  f_GateEquDrainPrimeNodePtr(0),
451  f_GateEquSourcePrimeNodePtr(0),
452  // V_s Row:
453  f_SourceEquSourceNodePtr(0),
454  f_SourceEquSourcePrimeNodePtr(0),
455  // V_d' Row:
456  f_DrainPrimeEquDrainNodePtr(0),
457  f_DrainPrimeEquGateNodePtr(0),
458  f_DrainPrimeEquDrainPrimeNodePtr(0),
459  f_DrainPrimeEquSourcePrimeNodePtr(0),
460  // V_s' Row:
461  f_SourcePrimeEquGateNodePtr(0),
462  f_SourcePrimeEquSourceNodePtr(0),
463  f_SourcePrimeEquDrainPrimeNodePtr(0),
464  f_SourcePrimeEquSourcePrimeNodePtr(0),
465 
466  // dQdx Matrix Ptr:
467  // V_d Row:
468  q_DrainEquDrainNodePtr(0),
469  q_DrainEquDrainPrimeNodePtr(0),
470  // V_g Row:
471  q_GateEquGateNodePtr(0),
472  q_GateEquDrainPrimeNodePtr(0),
473  q_GateEquSourcePrimeNodePtr(0),
474  // V_s Row:
475  q_SourceEquSourceNodePtr(0),
476  q_SourceEquSourcePrimeNodePtr(0),
477  // V_d' Row:
478  q_DrainPrimeEquDrainNodePtr(0),
479  q_DrainPrimeEquGateNodePtr(0),
480  q_DrainPrimeEquDrainPrimeNodePtr(0),
481  q_DrainPrimeEquSourcePrimeNodePtr(0),
482  // V_s' Row:
483  q_SourcePrimeEquGateNodePtr(0),
484  q_SourcePrimeEquSourceNodePtr(0),
485  q_SourcePrimeEquDrainPrimeNodePtr(0),
486  q_SourcePrimeEquSourcePrimeNodePtr(0),
487 #endif
488  vgs(0.0),
489  vgd(0.0),
490  vgs_old(0.0),
491  vgd_old(0.0),
492  vds_old(0.0),
493  vgs_orig(0.0),
494  vgd_orig(0.0),
495 
496  capgs(0.0),
497  qgs(0.0),
498  cqgs(0.0),
499  capgd(0.0),
500  qgd(0.0),
501  cqgd(0.0),
502  mode(1),
503  // local indices
504  li_store_vgs(-1),
505  li_store_vgd(-1),
506  li_store_dev_id(-1),
507  li_store_dev_ig(-1),
508  li_store_dev_is(-1),
509  li_state_qgs(-1),
510  li_state_gcgs(-1),
511  li_state_qgd(-1),
512  li_state_gcgd(-1)
513 {
514  numIntVars = 2;
515  numExtVars = 3;
516  numStateVars = 4;
517  setNumStoreVars(2);
518  numLeadCurrentStoreVars = 3; // lead currents drain, gate and source
519 
520  devConMap.resize(3);
521  devConMap[0] = 1;
522  devConMap[1] = 2;
523  devConMap[2] = 1;
524 
525  if( jacStamp.empty() )
526  {
527  // stamp for RS!=0, RD!=0
528  jacStamp_DC_SC.resize(5);
529  jacStamp_DC_SC[0].resize(2); // Drain row
530  jacStamp_DC_SC[0][0]=0; // d-d
531  jacStamp_DC_SC[0][1]=3; // d-d'
532  jacStamp_DC_SC[1].resize(3); // Gate row
533  jacStamp_DC_SC[1][0]=1; // g-g
534  jacStamp_DC_SC[1][1]=3; // g-d'
535  jacStamp_DC_SC[1][2]=4; // g-s'
536  jacStamp_DC_SC[2].resize(2); // Source row
537  jacStamp_DC_SC[2][0]=2; // s-s
538  jacStamp_DC_SC[2][1]=4; // s-s'
539  jacStamp_DC_SC[3].resize(4); // Drain' row
540  jacStamp_DC_SC[3][0]=0; // d'-d
541  jacStamp_DC_SC[3][1]=1; // d'-g
542  jacStamp_DC_SC[3][2]=3; // d'-d'
543  jacStamp_DC_SC[3][3]=4; // d'-s'
544  jacStamp_DC_SC[4].resize(4); // Source' row
545  jacStamp_DC_SC[4][0]=1; // s'-g
546  jacStamp_DC_SC[4][1]=2; // s'-s
547  jacStamp_DC_SC[4][2]=3; // s'-d'
548  jacStamp_DC_SC[4][3]=4; // s'-s'
549 
550  jacMap_DC_SC.clear();
552  jacStamp_DC, jacMap_DC, jacMap2_DC, 4, 2, 5);
553 
555  jacStamp_SC, jacMap_SC, jacMap2_SC, 3, 0, 5);
556 
558  jacStamp, jacMap, jacMap2, 3, 0, 5);
559 
560  }
561 
562  // Set params to constant default values:
563  setDefaultParams ();
564 
565  // Set params according to instance line and constant defaults from metadata:
566  setParams(instance_block.params);
567 
568  // Set any non-constant parameter defaults:
569  if (!given("TEMP"))
570  temp = getDeviceOptions().temp.getImmutableValue<double>();
571 
573 
574  // Calculate any parameters specified as expressions:
575  processParams ();
576 
577  numIntVars = (((sourceCond == 0.0)?0:1)+((drainCond == 0.0)?0:1));
578 
579 }
580 
581 //-----------------------------------------------------------------------------
582 // Function : Instance::~Instance
583 // Purpose : destructor
584 // Special Notes :
585 // Scope : public
586 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
587 // Creation Date : 3/16/00
588 //-----------------------------------------------------------------------------
590 {
591 }
592 
593 //----------------------------------------------------------------------------
594 // Function : Instance::registerLIDs
595 // Purpose :
596 // Special Notes :
597 // Scope : public
598 // Creator : pmc
599 // Creation Date : 11/16/2003
600 //----------------------------------------------------------------------------
601 void Instance::registerLIDs( const std::vector<int> & intLIDVecRef,
602  const std::vector<int> & extLIDVecRef )
603 {
604  numIntVars = (((sourceCond == 0.0)?0:1)+((drainCond == 0.0)?0:1));
605 
606  AssertLIDs(intLIDVecRef.size() == numIntVars);
607  AssertLIDs(extLIDVecRef.size() == numExtVars);
608 
609  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
610  {
611  Xyce::dout() << std::endl << section_divider << std::endl;
612  Xyce::dout() << " Instance::registerLIDs" << std::endl;
613  Xyce::dout() << " name = " << getName() << std::endl;
614  Xyce::dout() << " number of internal variables: " << numIntVars << std::endl;
615  Xyce::dout() << " number of external variables: " << numExtVars << std::endl;
616  }
617 
618  // copy over the global ID lists.
619  intLIDVec = intLIDVecRef;
620  extLIDVec = extLIDVecRef;
621 
622  // now use these lists to obtain the indices into the
623  // linear algebra entities. This assumes an order.
624  // For the matrix indices, first do the rows.
625 
626  li_Drain = extLIDVec[0];
627  li_Gate = extLIDVec[1];
628  li_Source = extLIDVec[2];
629 
630  int intLoc = 0;
631 
632  if( drainCond )
633  li_DrainPrime = intLIDVec[intLoc++];
634  else
636 
637  if( sourceCond )
638  li_SourcePrime = intLIDVec[intLoc];
639  else
641 
642  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
643  {
644  Xyce::dout() << "\n variable local indices:\n";
645  Xyce::dout() << " li_Drain = " << li_Drain << std::endl;
646  Xyce::dout() << " li_DrainPrime = " << li_DrainPrime << std::endl;
647  Xyce::dout() << " li_Source = " << li_Source << std::endl;
648  Xyce::dout() << " li_SourcePrime = " << li_SourcePrime << std::endl;
649  Xyce::dout() << " li_Gate = " << li_Gate << std::endl;
650 
651  Xyce::dout() << section_divider << std::endl;
652  }
653 }
654 
655 //-----------------------------------------------------------------------------
656 // Function : Instance::loadNodeSymbols
657 // Purpose :
658 // Special Notes :
659 // Scope : public
660 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
661 // Creation Date : 05/13/05
662 //-----------------------------------------------------------------------------
663 void Instance::loadNodeSymbols(Util::SymbolTable &symbol_table) const
664 {
665  if (drainCond != 0.0)
666  addInternalNode(symbol_table, li_DrainPrime, getName(), "drainprime");
667 
668  if (sourceCond != 0.0)
669  addInternalNode(symbol_table, li_SourcePrime, getName(), "sourceprime");
670 
671  if (loadLeadCurrent)
672  {
673  addStoreNode(symbol_table, li_store_dev_id, getName(), "DEV_ID");
674  addStoreNode(symbol_table, li_store_dev_is, getName(), "DEV_IS");
675  addStoreNode(symbol_table, li_store_dev_ig, getName(), "DEV_IG");
676  }
677 }
678 
679 //----------------------------------------------------------------------------
680 // Function : Instance::registerStateLIDs
681 // Purpose :
682 // Special Notes :
683 // Scope : public
684 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
685 // Creation Date : 3/16/00
686 //----------------------------------------------------------------------------
687 void Instance::registerStateLIDs(const std::vector<int> & staLIDVecRef)
688 {
689  AssertLIDs(staLIDVecRef.size() == numStateVars);
690 
691  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
692  {
693  Xyce::dout() << std::endl;
694  Xyce::dout() << section_divider << std::endl;
695  Xyce::dout() << " In Instance::registerStateLIDs\n\n";
696  Xyce::dout() << " name = " << getName() << std::endl;
697  Xyce::dout() << " Number of State LIDs: " << numStateVars << std::endl;
698  }
699 
700  // Copy over the global ID lists:
701  staLIDVec = staLIDVecRef;
702 
703  int lid=0;
704  li_state_qgs = staLIDVec[lid++];
705  li_state_gcgs = staLIDVec[lid++];
706 
707  li_state_qgd = staLIDVec[lid++];
708  li_state_gcgd = staLIDVec[lid++];
709 
710  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
711  {
712  Xyce::dout() << " State local indices:" << std::endl;
713  Xyce::dout() << std::endl;
714 
715  Xyce::dout() << " li_state_qgs = " << li_state_qgs << std::endl;
716  Xyce::dout() << " li_state_gcgs = " << li_state_gcgs;
717  Xyce::dout() << " li_state_qgd = " << li_state_qgd;
718  Xyce::dout() << " li_state_gcgd = " << li_state_gcgd << std::endl;;
719 
720  Xyce::dout() << section_divider << std::endl;
721  }
722 
723 }
724 
725 //----------------------------------------------------------------------------
726 // Function : Instance::registerStoreLIDs
727 // Purpose :
728 // Special Notes :
729 // Scope : public
730 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
731 // Creation Date : 12/9/11
732 //----------------------------------------------------------------------------
733 void Instance::registerStoreLIDs(const std::vector<int> & stoLIDVecRef)
734 {
735  AssertLIDs(stoLIDVecRef.size() == getNumStoreVars());
736 
737  // Copy over the global ID lists:
738  stoLIDVec = stoLIDVecRef;
739 
740  int lid=0;
741  li_store_vgs = stoLIDVec[lid++];
742  li_store_vgd = stoLIDVec[lid++];
743 
744  if( loadLeadCurrent )
745  {
746  li_store_dev_id = stoLIDVec[lid++];
747  li_store_dev_ig = stoLIDVec[lid++];
748  li_store_dev_is = stoLIDVec[lid++];
749  }
750 }
751 
752 //----------------------------------------------------------------------------
753 // Function : Instance::jacobianStamp
754 // Purpose :
755 // Special Notes :
756 // Scope : public
757 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
758 // Creation Date : 3/16/00
759 //----------------------------------------------------------------------------
760 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
761 {
762  if( drainCond != 0.0 && sourceCond != 0.0 )
763  return jacStamp_DC_SC;
764  else if( drainCond != 0.0 && sourceCond == 0.0 )
765  return jacStamp_DC;
766  else if( drainCond == 0.0 && sourceCond != 0.0 )
767  return jacStamp_SC;
768  else if( drainCond == 0.0 && sourceCond == 0.0 )
769  return jacStamp;
770  else
771  return jacStamp;
772 }
773 
774 //----------------------------------------------------------------------------
775 // Function : Instance::registerJacLIDs
776 // Special Notes :
777 // Scope : public
778 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
779 // Creation Date : 3/16/00
780 //----------------------------------------------------------------------------
781 void Instance::registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec )
782 {
783  DeviceInstance::registerJacLIDs( jacLIDVec );
784  std::vector<int> map;
785  std::vector< std::vector<int> > map2;
786 
787  if (drainCond != 0.0)
788  {
789  if (sourceCond != 0.0)
790  {
791  map = jacMap_DC_SC;
792  map2 = jacMap2_DC_SC;
793  }
794  else
795  {
796  map = jacMap_DC;
797  map2 = jacMap2_DC;
798  }
799  }
800  else
801  {
802  if (sourceCond != 0.0)
803  {
804  map = jacMap_SC;
805  map2 = jacMap2_SC;
806  }
807  else
808  {
809  map = jacMap;
810  map2 = jacMap2;
811  }
812  }
813 
814  ADrainEquDrainNodeOffset = jacLIDVec[map[0]][map2[0][0]];
815  ADrainEquDrainPrimeNodeOffset = jacLIDVec[map[0]][map2[0][1]];
816 
817  AGateEquGateNodeOffset = jacLIDVec[map[1]][map2[1][0]];
818  AGateEquDrainPrimeNodeOffset = jacLIDVec[map[1]][map2[1][1]];
819  AGateEquSourcePrimeNodeOffset = jacLIDVec[map[1]][map2[1][2]];
820 
821  ASourceEquSourceNodeOffset = jacLIDVec[map[2]][map2[2][0]];
822  ASourceEquSourcePrimeNodeOffset = jacLIDVec[map[2]][map2[2][1]];
823 
824  ADrainPrimeEquDrainNodeOffset = jacLIDVec[map[3]][map2[3][0]];
825  ADrainPrimeEquGateNodeOffset = jacLIDVec[map[3]][map2[3][1]];
826  ADrainPrimeEquDrainPrimeNodeOffset = jacLIDVec[map[3]][map2[3][2]];
827  ADrainPrimeEquSourcePrimeNodeOffset = jacLIDVec[map[3]][map2[3][3]];
828 
829  ASourcePrimeEquGateNodeOffset = jacLIDVec[map[4]][map2[4][0]];
830  ASourcePrimeEquSourceNodeOffset = jacLIDVec[map[4]][map2[4][1]];
831  ASourcePrimeEquDrainPrimeNodeOffset = jacLIDVec[map[4]][map2[4][2]];
832  ASourcePrimeEquSourcePrimeNodeOffset = jacLIDVec[map[4]][map2[4][3]];
833 }
834 
835 //-----------------------------------------------------------------------------
836 // Function : Instance::setupPointers
837 // Purpose :
838 // Special Notes :
839 // Scope : public
840 // Creator : Eric Keiter, SNL
841 // Creation Date : 11/30/08
842 //-----------------------------------------------------------------------------
844 {
845 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
846  Linear::Matrix & dFdx = *(extData.dFdxMatrixPtr);
847  Linear::Matrix & dQdx = *(extData.dQdxMatrixPtr);
848 
849  // F-matrix:
852 
856 
859 
864 
869 
870  // Q-matrix:
873 
877 
880 
885 
890 
891 #endif
892 }
893 
894 //----------------------------------------------------------------------------
895 // Function : Instance::updatePrimaryState
896 // Purpose :
897 // Special Notes :
898 // Scope : public
899 // Creator : pmc
900 // Creation Date : 11/16/2003
901 //----------------------------------------------------------------------------
903 {
904  double * staVec = extData.nextStaVectorRawPtr;
905  bool bsuccess = updateIntermediateVars ();
906 
907  double * stoVec = extData.nextStoVectorRawPtr;
908  stoVec[li_store_vgs] = vgs;
909  stoVec[li_store_vgd] = vgd;
910  staVec[li_state_qgs] = qgs;
911  staVec[li_state_qgd] = qgd;
912 
913  return bsuccess;
914 }
915 
916 //-----------------------------------------------------------------------------
917 // Function : Instance::updateIntermediateVars
918 // Purpose :
919 // Special Notes :
920 // Scope : public
921 // Creator : pmc
922 // Creation Date : 11/16/2003
923 //-----------------------------------------------------------------------------
925 {
926  double * solVec = extData.nextSolVectorRawPtr;
927  double * currStaVec = extData.currStaVectorRawPtr;
928 
929  int dtype;
930  double csat, betap;
931  double vgst, vgdt;
932  double evgs, evgd;
933  double sarg, vtf;;
934 
935 // from the spice jfet
936  double czgd, czgs;
937  double czgdf2, czgsf2;
938  double fcpb2;
939  double twop;
940  int icheck, ichk1;
941 
942 // for the Shockley version
943 // double A, B, C, B12, C12, D, Vdsat;
944 // double delta;
945  double prod, denom, invdenom, afact, lfact;
946 
947  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
948  {
949  Xyce::dout() << subsection_divider << std::endl;
950  Xyce::dout() <<" Instance::updateIntermediateVars.\n"<<std::endl;
951  Xyce::dout() <<" name = " << getName() << std::endl;
952  Xyce::dout() <<" Model name = " << model_.getName() << std::endl;
953  Xyce::dout() <<" dtype is " << model_.dtype << std::endl;
954  Xyce::dout() << std::endl;
955  Xyce::dout().width(25); Xyce::dout().precision(17); Xyce::dout().setf(std::ios::scientific);
956  }
957 
958  icheck = 1;
959  dtype = model_.dtype;
960 
961  // we need our solution variables for any of this stuff
962  Vd = 0.0;
963  Vs = 0.0;
964  Vg = 0.0;
965  Vdp = 0.0;
966  Vsp = 0.0;
967 
968  Vd = solVec[li_Drain];
969  Vg = solVec[li_Gate];
970  Vs = solVec[li_Source];
971  Vsp = solVec[li_SourcePrime];
972  Vdp = solVec[li_DrainPrime];
973 
974  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
975  {
976  Xyce::dout() << " " << std::endl;
977  Xyce::dout() << " Vg = " << Vg << std::endl;
978  Xyce::dout() << " Vd = " << Vd << std::endl;
979  Xyce::dout() << " Vs = " << Vs << std::endl;
980  Xyce::dout() << " Vdp = " << Vdp << std::endl;
981  Xyce::dout() << " Vsp = " << Vsp << std::endl;
982  }
983 
984  // now we need voltage drops
985  Vddp = Vd - Vdp;
986  Vssp = Vs - Vsp;
987  Vgsp = Vg - Vsp;
988  Vgdp = Vg - Vdp;
989  Vdpsp = Vdp - Vsp;
990 
991  // Now the things that the 3f5 code really uses
992  vgs = dtype * Vgsp;
993  vgd = dtype * Vgdp;
994  vds = vgs-vgd;
995 
996  origFlag = 1;
997  limitedFlag = false;
998  vgs_orig = vgs;
999  vgd_orig = vgd;
1000  vds_orig = vds;
1001 
1002  if (getSolverState().newtonIter == 0)
1003  {
1004  if (getSolverState().initJctFlag_ && getDeviceOptions().voltageLimiterFlag)
1005  {
1006  if (getSolverState().inputOPFlag)
1007  {
1008  Linear::Vector * flagSolVectorPtr = extData.flagSolVectorPtr;
1009  if ((*flagSolVectorPtr)[li_Drain] == 0 || (*flagSolVectorPtr)[li_Gate] == 0 ||
1010  (*flagSolVectorPtr)[li_Source] == 0 || (*flagSolVectorPtr)[li_SourcePrime] ||
1011  (*flagSolVectorPtr)[li_DrainPrime] )
1012  {
1013  vgs = 0;
1014  vgd = 0;
1015  vds = vgs-vgd;
1016  }
1017  }
1018  else
1019  {
1020  vgs = 0;
1021  vgd = 0;
1022  vds = vgs-vgd;
1023  }
1024  }
1025  if (!(getSolverState().dcopFlag)||(getSolverState().locaEnabledFlag && getSolverState().dcopFlag))
1026  {
1027  double * currStoVec = extData.currStoVectorRawPtr;
1028  vgs_old = currStoVec[li_store_vgs];
1029  vgd_old = currStoVec[li_store_vgd];
1030  }
1031  else
1032  { // there is no history
1033  vgs_old = vgs;
1034  vgd_old = vgd;
1035  }
1036  }
1037  else
1038  {
1039  double *stoVec = extData.nextStoVectorRawPtr;
1040  vgs_old = stoVec[li_store_vgs];
1041  vgd_old = stoVec[li_store_vgd];
1042  }
1043 
1044  // SPICE-type Voltage Limiting
1045  ///////////////////////////////
1046 
1047  if (getDeviceOptions().voltageLimiterFlag)
1048  {
1049  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
1050  {
1051  Xyce::dout() << " before limiting: " << std::endl;
1052  Xyce::dout() << " vgs = " << vgs << " vgs_old = " << vgs_old << std::endl;
1053  Xyce::dout() << " vgd = " << vgd << " vgd_old = " << vgd_old << std::endl;
1054  }
1055 
1056  ichk1=1;
1057  vgs = devSupport.pnjlim(vgs, vgs_old, vt, vcrit, &icheck);
1058  vgd = devSupport.pnjlim(vgd, vgd_old, vt, vcrit, &ichk1);
1059 
1060  if (ichk1 == 1) {icheck=1;}
1061  if (icheck == 1) limitedFlag=true;
1062 
1064  vgd = devSupport.fetlim(vgd, vgd_old, tvt0);
1065  vds = vgs-vgd;
1066 
1067  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
1068  {
1069  Xyce::dout() << " After limiting: " << std::endl;
1070  Xyce::dout() << " vgs = " << vgs << std::endl;
1071  Xyce::dout() << " vgd = " << vgd << std::endl;
1072  Xyce::dout() << " " << std::endl;
1073  }
1074  }
1075 
1076  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
1077  {
1078  Xyce::dout() << "vgs = " << vgs << std::endl;
1079  Xyce::dout() << "vgd = " << vgd << std::endl;
1080  Xyce::dout() << "vds = " << vds << std::endl;
1081  Xyce::dout() << "Vddp = " << Vddp << std::endl;
1082  Xyce::dout() << "Vssp = " << Vssp << std::endl;
1083  Xyce::dout() << "Vgsp = " << Vgsp << std::endl;
1084  Xyce::dout() << "Vgdp = " << Vgdp << std::endl;
1085  Xyce::dout() << "Vdpsp = " << Vdpsp << std::endl;
1086  Xyce::dout() << " " << std::endl;
1087  }
1088  // Now set the origFlag
1089  if (vgs_orig != vgs || vds_orig != vds || vgd_orig != vgd) origFlag = 0;
1090 
1091  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
1092  {
1093  if (origFlag == 0)
1094  {
1095  Xyce::dout() << " Something modified the voltages. " << std::endl;
1096  Xyce::dout() << " Voltage before after diff " << std::endl;
1097  Xyce::dout() << " vgs " << vgs_orig << " " << vgs << " " << vgs-vgs_orig << std::endl;
1098  Xyce::dout() << " vgd " << vgd_orig << " " << vgd << " " << vgd-vgd_orig << std::endl;
1099  Xyce::dout() << " vds " << vds_orig << " " << vds << " " << vds-vds_orig << std::endl;
1100  Xyce::dout() << " " << std::endl;
1101  }
1102  }
1103 
1104  //
1105  // the following block of code evaluates the dc current and its
1106  // derivatives and the charges associated with the gate and
1107  // channel
1108  //
1109 
1110  // vt set in updateTemperature
1111  vtf = 5.0*vt;
1112  csat = tIS;
1113  if (vgs <= -vtf)
1114  {
1115  ggs = -csat/vgs + getDeviceOptions().gmin;
1116  cg = ggs*vgs;
1117  }
1118  else
1119  {
1120  evgs = exp(vgs/vt);
1121  ggs = csat*evgs/vt + getDeviceOptions().gmin;
1122  cg = csat*(evgs-1) + getDeviceOptions().gmin*vgs;
1123  }
1124  if (vgd <= -vtf)
1125  {
1126  ggd = -csat/vgd + getDeviceOptions().gmin;
1127  cgd = ggd*vgd;
1128  }
1129  else
1130  {
1131  evgd = exp(vgd/vt);
1132  ggd = csat*evgd/vt + getDeviceOptions().gmin;
1133  cgd = csat*(evgd-1) + getDeviceOptions().gmin*vgd;
1134  }
1135  cg = cg + cgd;
1136 
1137  // 3f5 does this simple stuff
1138  if (vds >= 0)
1139  mode = 1;
1140  else
1141  mode = -1;
1142 
1143  if (vds >= 0) // normal mode
1144  {
1145  vgst = vgs-tvt0;
1146  if (vgst <= 0)
1147  {
1148  //
1149  // normal mode, cutoff region
1150  //
1151  cdrain = 0;
1152  gm = 0;
1153  gds = 0;
1154  }
1155  else
1156  {
1157  prod = 1 + tLambda*vds;
1158  betap = tBeta*prod;
1159  denom = 1 + tMESb*vgst;
1160  invdenom = 1/denom;
1161  if (vds >= ( 3/tAlpha ) )
1162  {
1163  //
1164  // normal mode, saturation region
1165  //
1166  cdrain = betap*vgst*vgst*invdenom;
1167  gm = betap*vgst*(1 + denom)*invdenom*invdenom;
1168  gds = tLambda*tBeta*vgst*vgst*invdenom;
1169  }
1170  else
1171  {
1172  //
1173  // normal mode, linear region
1174  //
1175  afact = 1 - tAlpha*vds/3;
1176  lfact = 1 - afact*afact*afact;
1177  cdrain = betap*vgst*vgst*invdenom*lfact;
1178  gm = betap*vgst*(1 + denom)*invdenom*invdenom*lfact;
1179  gds = tBeta*vgst*vgst*invdenom*(tAlpha*afact*afact*prod + lfact*tLambda);
1180  }
1181  }
1182  }
1183  else // inverse mode
1184  {
1185  vgdt = vgd - tvt0;
1186  if (vgdt <= 0)
1187  {
1188  //
1189  // inverse mode, cutoff region
1190  //
1191  cdrain = 0;
1192  gm = 0;
1193  gds = 0;
1194  }
1195  else
1196  {
1197  //
1198  // inverse mode, saturation region
1199  //
1200  prod = 1 - tLambda*vds;
1201  betap = tBeta*prod;
1202  denom = 1 + tMESb*vgdt;
1203  invdenom = 1/denom;
1204  if ( -vds >= 3/tAlpha )
1205  {
1206  cdrain = -betap*vgdt*vgdt*invdenom;
1207  gm = -betap*vgdt*(1 + denom)*invdenom*invdenom;
1208  gds = tLambda*tBeta*vgdt*vgdt*invdenom - gm;
1209  }
1210  else
1211  {
1212  //
1213  // inverse mode, linear region
1214  //
1215  afact = 1 + tAlpha*vds/3;
1216  lfact = 1 - afact*afact*afact;
1217  cdrain = -betap*vgdt*vgdt*invdenom*lfact;
1218  gm = -betap*vgdt*(1 + denom)*invdenom*invdenom*lfact;
1219  gds = tBeta*vgdt*vgdt*invdenom*(tAlpha*afact*afact*prod
1220  + lfact*tLambda) - gm;
1221  }
1222  }
1223  }
1224  cd = cdrain-cgd;
1225 
1226  //
1227  // charge storage elements
1228  //
1229  twop = 2.0*tPB;
1230  fcpb2 = corDepCap*corDepCap;
1231  czgs = tCGS;
1232  czgd = tCGD;
1233  if(czgs != 0)
1234  {
1235  czgsf2=czgs/f2;
1236  if (vgs < corDepCap)
1237  {
1238  sarg=sqrt(1-vgs/tPB);
1239  qgs = twop*czgs*(1-sarg);
1240  capgs=czgs/sarg;
1241  }
1242  else
1243  {
1244  qgs = czgs*f1 + czgsf2*(f3 *(vgs - corDepCap)
1245  +(vgs*vgs - fcpb2)/(2*twop));
1246  capgs=czgsf2*(f3 + vgs/twop);
1247  }
1248  }
1249  else
1250  {
1251  qgs=0.0;
1252  capgs=0.0;
1253  }
1254 
1255  if(czgd != 0)
1256  {
1257  czgdf2=czgd/f2;
1258  if (vgd < corDepCap)
1259  {
1260  sarg=sqrt(1-vgd/tPB);
1261  qgd = twop*czgd*(1-sarg);
1262  capgd=czgd/sarg;
1263  }
1264  else
1265  {
1266  qgd = czgd*f1 + czgdf2*( f3*(vgd - corDepCap)
1267  +(vgd*vgd - fcpb2)/(2*twop) );
1268  capgd=czgdf2*(f3 + vgd/twop);
1269  }
1270  }
1271  else
1272  {
1273  qgd=0.0;
1274  capgd=0.0;
1275  }
1276 
1277  Idrain = drainCond * Vddp;
1278  Isource = sourceCond * Vssp;
1279 
1280  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
1281  {
1282  Xyce::dout() << " Done with Instance::updateIntermediateVars." << std::endl;
1283  Xyce::dout() << " mode = " << mode << std::endl;
1284  Xyce::dout() << " tBeta = " << tBeta << std::endl;
1285  Xyce::dout() << " Idrain = " << Idrain << std::endl;
1286  Xyce::dout() << " Isource = " << Isource << std::endl;
1287  Xyce::dout() << " gds = " << gds << std::endl;
1288  Xyce::dout() << " gm = " << gm << std::endl;
1289  }
1290 
1291  /// CURRENTS to load into RHS:
1292 
1293  // so at this point:
1294 
1295  // current out of drain is
1296  // Idrain
1297 
1298  // current out of gate:
1299  // dtype*( d/dt(qgs) + d/dt(qgd) )
1300 
1301  // the current *out of* the source should be simply
1302  // Isource
1303 
1304  // current out of drain' is
1305  // -Idrain - dtype*( d/dt(qgd) - cdrain )
1306 
1307  // the current out of the source' is
1308  // -Isource - dtype*( d/dt(qgs) + cdrain )
1309 
1310  return true;
1311 }
1312 
1313 //-----------------------------------------------------------------------------
1314 // Function : Instance::loadDAEQVector
1315 //
1316 // Purpose : Loads the Q-vector contributions for a single
1317 // voltage source instance.
1318 //
1319 // Special Notes : The "Q" vector is part of a standard DAE formalism in
1320 // which the system of equations is represented as:
1321 //
1322 // f(x) = dQ(x)/dt + F(x) + B(t) = 0
1323 //
1324 // The "Q" vector contains charges and fluxes, mostly.
1325 // The voltage source will not make any contributions to Q,
1326 // so this function does nothing.
1327 //
1328 // from updateSecondaryState:
1329 //
1330 // ggd = ggd + capgd*(getSolverState().pdt);
1331 // ggs = ggs + capgs*(getSolverState().pdt);
1332 //
1333 // // Sum the capacitor currents into the DC currents.
1334 // cg = cg + cqgs + cqgd;
1335 // cd = cd - cqgd;
1336 // cgd = cgd + cqgd;
1337 //
1338 // So:
1339 //
1340 // replace ggd with capgd.
1341 // replace ggs with capgs
1342 //
1343 // replace cg with qgs+qgd
1344 // replace cd with -qgd
1345 // replace cgd with qgd.
1346 //
1347 //
1348 // Scope : public
1349 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
1350 // Creation Date : 06/01/05
1351 //-----------------------------------------------------------------------------
1353 {
1354  double * qVec = extData.daeQVectorRawPtr;
1355  double * dQdxdVp = extData.dQdxdVpVectorRawPtr;
1356 
1357  // set up the final load variables:
1358  int Dtype = model_.dtype;
1359  double ceqgd = Dtype*(qgd);
1360  double ceqgs = Dtype*(((qgs+qgd)-qgd));
1361  double cdreq = Dtype*(((-qgd)+qgd));
1362 
1363  double ceqgd_Jdxp = -Dtype*(capgd*(vgd-vgd_orig));
1364  double ceqgs_Jdxp = -Dtype*(capgs*(vgs-vgs_orig));
1365  double cdreq_Jdxp = 0.0;
1366 
1367  qVec[li_Gate ] += ( ceqgs+ceqgd);
1368  qVec[li_DrainPrime ] -= (-cdreq+ceqgd);
1369  qVec[li_SourcePrime] -= ( cdreq+ceqgs);
1370 
1371  if (!origFlag)
1372  {
1373  dQdxdVp[li_Gate ] -= ( ceqgs_Jdxp+ceqgd_Jdxp);
1374  dQdxdVp[li_DrainPrime ] += (-cdreq_Jdxp+ceqgd_Jdxp);
1375  dQdxdVp[li_SourcePrime] += ( cdreq_Jdxp+ceqgs_Jdxp);
1376  }
1377 
1378  return true;
1379 }
1380 
1381 //-----------------------------------------------------------------------------
1382 // Function : Instance::loadDAEFVector
1383 //
1384 // Purpose : Loads the F-vector contributions for a single
1385 // MESFET instance.
1386 //
1387 // Special Notes :
1388 //
1389 // Scope : public
1390 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
1391 // Creation Date : 06/01/05
1392 //-----------------------------------------------------------------------------
1394 {
1395  double * fVec = extData.daeFVectorRawPtr;
1396  double * dFdxdVp = extData.dFdxdVpVectorRawPtr;
1397 
1398  // set up the final load variables:
1399  int Dtype = model_.dtype;
1400  double ceqgd = Dtype*(cgd);
1401  double ceqgs = Dtype*((cg-cgd));
1402  double cdreq = Dtype*((cd+cgd));
1403 
1404  double ceqgd_Jdxp = -Dtype*(ggd*(vgd-vgd_orig));
1405  double ceqgs_Jdxp = -Dtype*(ggs*(vgs-vgs_orig));
1406  double cdreq_Jdxp = -Dtype*(gds*(vds-vds_orig)+gm*(vgs-vgs_orig));
1407 
1408  // optional load resistors:
1409  if (drainCond != 0.0)
1410  {
1411  fVec[li_Drain ] += Idrain;
1412  }
1413  if (sourceCond != 0.0)
1414  {
1415  fVec[li_Source] += Isource;
1416  }
1417 
1418  fVec[li_Gate ] += (ceqgs+ceqgd);
1419  fVec[li_DrainPrime ] -= (Idrain +(-cdreq+ceqgd));
1420  fVec[li_SourcePrime] -= (Isource+(cdreq+ceqgs));
1421 
1422  if (!origFlag)
1423  {
1424  dFdxdVp[li_Gate ] -= ( ceqgs_Jdxp+ceqgd_Jdxp);
1425  dFdxdVp[li_DrainPrime ] += (-cdreq_Jdxp+ceqgd_Jdxp);
1426  dFdxdVp[li_SourcePrime] += ( cdreq_Jdxp+ceqgs_Jdxp);
1427  }
1428 
1429  return true;
1430 }
1431 
1432 //-----------------------------------------------------------------------------
1433 // Function : Instance::loadDAEdQdx
1434 //
1435 // Purpose : Loads the Q-vector contributions for a single
1436 // MESFET instance.
1437 //
1438 // Special Notes : The "Q" vector is part of a standard DAE formalism in
1439 // which the system of equations is represented as:
1440 //
1441 // f(x) = dQ(x)/dt + F(x) - B(t) = 0
1442 //
1443 // Scope : public
1444 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
1445 // Creation Date : 06/01/05
1446 //-----------------------------------------------------------------------------
1448 {
1449  Linear::Matrix & dQdx = *(extData.dQdxMatrixPtr);
1450 
1458 
1459  return true;
1460 }
1461 
1462 //-----------------------------------------------------------------------------
1463 // Function : Instance::loadDAEdFdx ()
1464 //
1465 // Purpose : Loads the F-vector contributions for a single
1466 // resistor instance.
1467 //
1468 // Special Notes : The F-vector is an algebraic constaint.
1469 //
1470 // Scope : public
1471 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
1472 // Creation Date : 06/01/05
1473 //-----------------------------------------------------------------------------
1475 {
1476  Linear::Matrix & dFdx = *(extData.dFdxMatrixPtr);
1477 
1480 
1484 
1487 
1491  drainCond+gds+ggd;
1493 
1498  += sourceCond+gds+gm+ggs;
1499 
1500  return true;
1501 }
1502 
1503 //-----------------------------------------------------------------------------
1504 // Function : Instance::updateTemperature
1505 // Purpose :
1506 // Special Notes :
1507 // Scope : public
1508 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1509 // Creation Date : 3/16/00
1510 //-----------------------------------------------------------------------------
1511 bool Instance::updateTemperature ( const double & temp_tmp)
1512 {
1513  bool bsuccess = true;
1514  double tnom, ratio;
1515  double arg, arg1;
1516  double ratio1;
1517  double fact1, fact2;
1518  double kt, kt1;
1519  double vtnom;
1520  double egfet, egfet1;
1521  double pbfact;
1522  double cjfact, cjfact1;
1523  double gmanew, gmaold;
1524  double pbo;
1525  double xfc;
1526  double Pb;
1527 
1528  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
1529  {
1530 // Xyce::dout() << subsection_divider << std::endl;
1531  Xyce::dout() << " Instance::Begin of updateTemperature. \n";
1532  Xyce::dout() << " name = " << getName() << std::endl;
1533  Xyce::dout() << std::endl;
1534  }
1535 
1536  // first set the instance temperature to the new temperature:
1537  if (temp_tmp != -999.0) temp = temp_tmp;
1539  {
1540  // make sure interpolation doesn't take any resistance negative
1541  if(model_.RD < 0) model_.RD = 0;
1542  if(model_.RS < 0) model_.RS = 0;
1543 
1544  // some params may have changed during interpolation
1545  // model_.processParams();
1546  }
1547 
1548  Pb = model_.PB;
1549  tnom = model_.TNOM;
1550  ratio = temp/tnom;
1551 
1552  // first do the model stuff
1553 
1554  vtnom = tnom*CONSTKoverQ;
1555  fact1 = tnom/CONSTREFTEMP;
1556  kt1 = CONSTboltz*tnom;
1557  egfet1 = 1.16 - (7.02e-4*tnom*tnom)/(tnom + 1108);
1558  arg1 = -egfet1/(2.0*kt1) + 1.1150877/(CONSTboltz*2.0*CONSTREFTEMP);
1559  pbfact = -2.0*vtnom*(1.5*log(fact1) + CONSTQ*arg1);
1560  pbo = (Pb - pbfact)/fact1;
1561  gmaold = (Pb - pbo)/pbo;
1562  cjfact = 1.0/(1.0 + 0.5*(4e-4*(tnom - CONSTREFTEMP) - gmaold));
1563 
1564  if(model_.FC >.95) {
1565  Xyce::dout() << "Depletion cap. coeff. FC too large, limited to .95";
1566  Xyce::dout() << std::endl;
1567  model_.FC = .95;
1568  }
1569  xfc = log(1.0 - model_.FC);
1570  f2 = exp(1.5*xfc);
1571  f3 = 1.0 - 1.5*model_.FC;
1572  // skip bFac
1573 
1574  // now do the instance stuff
1575 
1576  vt = temp*CONSTKoverQ;
1577  kt = temp*CONSTboltz;
1578  fact2 = temp/CONSTREFTEMP;
1579  ratio1 = ratio - 1.0;
1580  tIS = model_.IS*exp(ratio1*1.11/vt)*area;
1581 
1582  tCGS = model_.CGS*cjfact*area;
1583  tCGD = model_.CGD*cjfact*area;
1584  egfet = 1.16 - (7.02e-4*temp*temp)/(temp + 1108);
1585  arg = -egfet/(2.0*kt) + 1.1150877/(CONSTboltz*2.0*CONSTREFTEMP);
1586  pbfact = -2.0*vt*(1.5*log(fact2) + CONSTQ*arg);
1587  tPB = fact2*pbo + pbfact;
1588  gmanew = (tPB - pbo)/pbo;
1589  cjfact1 = 1.0 + 0.5*(4e-4*(temp - CONSTREFTEMP) - gmanew);
1590  tCGS *= cjfact1;
1591  tCGD *= cjfact1;
1592 
1593  corDepCap = model_.FC*tPB;
1594  f1 = tPB*(1.0 - exp((0.5)*xfc))/(0.5);
1595  vcrit = vt * log(vt/(CONSTroot2 * tIS));
1596 
1597  // the following parameters have no temperature dependence in Spice 3f5
1598  //
1599  tBeta = model_.BETA*area; // transconductance parameter
1600  tvt0 = model_.VTO; // threshold voltage
1601  tLambda = model_.LAMBDA; // channel-length modulation
1602  tAlpha = model_.ALPHA; // saturation voltage parameter
1603  tRD = model_.RD/area; // drain ohmic resistance
1604  tRS = model_.RS/area; // source ohmic resistance
1605  tMESb = model_.B; // dopinng tail parameter
1606 
1607  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
1608  {
1609  Xyce::dout() << "temp = "<< temp << std::endl;
1610  Xyce::dout() << "tnom = " << tnom << std::endl;
1611  Xyce::dout() << "ratio = " << ratio << std::endl;
1612  Xyce::dout() << "vt = " << vt << std::endl;
1613  Xyce::dout() << "kt = " << kt << std::endl;
1614  Xyce::dout() << "fact2 = " << fact2 << std::endl;
1615  Xyce::dout() << "egfet = " << egfet << std::endl;
1616  Xyce::dout() << "arg = " << arg << std::endl;
1617  Xyce::dout() << "pbfact = " << pbfact << std::endl;
1618  Xyce::dout() << "PB = " << Pb << std::endl;
1619  Xyce::dout() << "pbo = " << pbo << std::endl;
1620  Xyce::dout() << "f2 = " << f2 << std::endl;
1621  Xyce::dout() << "f3 = " << f3 << std::endl;
1622  Xyce::dout() << "corDepCap= " << corDepCap << std::endl;
1623  Xyce::dout() << "tBeta = " << tBeta << std::endl;
1624  Xyce::dout() << "tvt0 = " << tvt0 << std::endl;
1625  Xyce::dout() << "tPB = " << tPB << std::endl;
1626  Xyce::dout() << "tMESb = " << tMESb << std::endl;
1627  Xyce::dout() << "tLambda = " << tLambda << std::endl;
1628  //Xyce::dout() << "tTheta = " << tTheta << std::endl;
1629  Xyce::dout() << "tRD = " << tRD << std::endl;
1630  Xyce::dout() << "tRS = " << tRS << std::endl;
1631  Xyce::dout() << " " << std::endl;
1632  }
1633 
1634  return bsuccess;
1635 }
1636 
1637 //-----------------------------------------------------------------------------
1638 // Function : Instance::processParams
1639 // Purpose :
1640 // Special Notes :
1641 // Scope : public
1642 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1643 // Creation Date : 3/16/00
1644 //-----------------------------------------------------------------------------
1646 {
1647  // process source/drain series resistance
1648  drainCond = 0;
1649  if (model_.RD != 0)
1650  drainCond = area/model_.RD;
1651  sourceCond = 0;
1652  if (model_.RS != 0)
1654 
1656 
1657  return true;
1658 }
1659 
1660 // MESFET Master functions:
1661 
1662 //-----------------------------------------------------------------------------
1663 // Function : Master::updateState
1664 // Purpose :
1665 // Special Notes :
1666 // Scope : public
1667 // Creator : Eric Keiter, SNL
1668 // Creation Date : 11/26/08
1669 //-----------------------------------------------------------------------------
1670 bool Master::updateState (double * solVec, double * staVec, double * stoVec)
1671 {
1672  bool bsuccess = true;
1673 
1674  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
1675  {
1676  Instance & ji = *(*it);
1677 
1678  bool btmp = ji.updateIntermediateVars ();
1679  bsuccess = bsuccess && btmp;
1680 
1681  double * stoVec = ji.extData.nextStoVectorRawPtr;
1682  stoVec[ji.li_store_vgs] = ji.vgs;
1683  stoVec[ji.li_store_vgd] = ji.vgd;
1684  staVec[ji.li_state_qgs] = ji.qgs;
1685  staVec[ji.li_state_qgd] = ji.qgd;
1686  }
1687 
1688  return bsuccess;
1689 }
1690 
1691 //-----------------------------------------------------------------------------
1692 // Function : Master::loadDAEVectors
1693 // Purpose :
1694 // Special Notes :
1695 // Scope : public
1696 // Creator : Eric Keiter, SNL
1697 // Creation Date : 11/26/08
1698 //-----------------------------------------------------------------------------
1699 bool Master::loadDAEVectors (double * solVec, double * fVec, double *qVec, double * bVec, double * storeLeadF, double * storeLeadQ, double * leadF, double * leadQ, double * junctionV)
1700 {
1701  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
1702  {
1703  Instance & ji = *(*it);
1704 
1705  // F-vector:
1706  double * dFdxdVp = ji.extData.dFdxdVpVectorRawPtr;
1707 
1708  // set up the final load variables:
1709  int Dtype = ji.getModel().dtype;
1710  double f_ceqgd = Dtype*(ji.cgd);
1711  double f_ceqgs = Dtype*((ji.cg-ji.cgd));
1712  double f_cdreq = Dtype*((ji.cd+ji.cgd));
1713 
1714  double f_ceqgd_Jdxp = -Dtype*(ji.ggd*(ji.vgd-ji.vgd_orig));
1715  double f_ceqgs_Jdxp = -Dtype*(ji.ggs*(ji.vgs-ji.vgs_orig));
1716  double f_cdreq_Jdxp = -Dtype*(ji.gds*(ji.vds-ji.vds_orig)+ji.gm*(ji.vgs-ji.vgs_orig));
1717 
1718  // optional load resistors:
1719  if (ji.drainCond != 0.0)
1720  {
1721  fVec[ji.li_Drain ] += ji.Idrain;
1722  }
1723  if (ji.sourceCond != 0.0)
1724  {
1725  fVec[ji.li_Source] += ji.Isource;
1726  }
1727  fVec[ji.li_Gate ] += (f_ceqgs+f_ceqgd);
1728  fVec[ji.li_DrainPrime ] -= (ji.Idrain +(-f_cdreq+f_ceqgd));
1729  fVec[ji.li_SourcePrime] -= (ji.Isource+(f_cdreq+f_ceqgs));
1730 
1731  if (!ji.origFlag)
1732  {
1733  dFdxdVp[ji.li_Gate ] -= ( f_ceqgs_Jdxp+f_ceqgd_Jdxp);
1734  dFdxdVp[ji.li_DrainPrime ] += (-f_cdreq_Jdxp+f_ceqgd_Jdxp);
1735  dFdxdVp[ji.li_SourcePrime] += ( f_cdreq_Jdxp+f_ceqgs_Jdxp);
1736  }
1737 
1738  // Q-vector:
1739  double * dQdxdVp = ji.extData.dQdxdVpVectorRawPtr;
1740 
1741  // set up the final load variables:
1742  double q_ceqgd = Dtype*(ji.qgd);
1743  double q_ceqgs = Dtype*(((ji.qgs+ji.qgd)-ji.qgd));
1744  double q_cdreq = Dtype*(((-ji.qgd)+ji.qgd));
1745 
1746  double q_ceqgd_Jdxp = -Dtype*(ji.capgd*(ji.vgd-ji.vgd_orig));
1747  double q_ceqgs_Jdxp = -Dtype*(ji.capgs*(ji.vgs-ji.vgs_orig));
1748  double q_cdreq_Jdxp = 0.0;
1749 
1750  qVec[ji.li_Gate ] += ( q_ceqgs+q_ceqgd);
1751  qVec[ji.li_DrainPrime ] -= (-q_cdreq+q_ceqgd);
1752  qVec[ji.li_SourcePrime] -= ( q_cdreq+q_ceqgs);
1753 
1754  if (!ji.origFlag)
1755  {
1756  dQdxdVp[ji.li_Gate ] -= ( q_ceqgs_Jdxp+q_ceqgd_Jdxp);
1757  dQdxdVp[ji.li_DrainPrime ] += (-q_cdreq_Jdxp+q_ceqgd_Jdxp);
1758  dQdxdVp[ji.li_SourcePrime] += ( q_cdreq_Jdxp+q_ceqgs_Jdxp);
1759  }
1760 
1761  if( ji.loadLeadCurrent )
1762  {
1763  if (ji.drainCond != 0.0)
1764  {
1765  storeLeadF[ji.li_store_dev_id] = ji.Idrain;
1766  }
1767  else
1768  {
1769  storeLeadF[ji.li_store_dev_id] = -(ji.Idrain +(-f_cdreq+f_ceqgd));
1770  storeLeadQ[ji.li_store_dev_id] = -(-q_cdreq+q_ceqgd);
1771  }
1772  if (ji.sourceCond != 0.0)
1773  {
1774  storeLeadF[ji.li_store_dev_is] = ji.Isource;
1775  }
1776  else
1777  {
1778  storeLeadF[ji.li_store_dev_is] = -(ji.Isource+(f_cdreq+f_ceqgs));
1779  storeLeadQ[ji.li_store_dev_is] = -( q_cdreq+q_ceqgs);
1780  }
1781  storeLeadF[ji.li_store_dev_ig] = (f_ceqgs+f_ceqgd);
1782  storeLeadQ[ji.li_store_dev_ig] = (q_ceqgs+q_ceqgd);
1783  }
1784 
1785  }
1786 
1787  return true;
1788 }
1789 
1790 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
1791 //-----------------------------------------------------------------------------
1792 // Function : Master::loadDAEMatrices
1793 // Purpose :
1794 // Special Notes :
1795 // Scope : public
1796 // Creator : Eric Keiter, SNL
1797 // Creation Date : 12/12/08
1798 //-----------------------------------------------------------------------------
1799 bool Master::loadDAEMatrices (Linear::Matrix & dFdx, Linear::Matrix & dQdx)
1800 {
1801  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
1802  {
1803  Instance & ji = *(*it);
1804 
1805  // F-matrix:
1806 
1808 
1810 
1811 
1812  *ji.f_GateEquGateNodePtr += ji.ggd+ji.ggs;
1813 
1814  *ji.f_GateEquDrainPrimeNodePtr -= ji.ggd;
1815 
1816  *ji.f_GateEquSourcePrimeNodePtr -= ji.ggs;
1817 
1818 
1820 
1822 
1823 
1825 
1826  *ji.f_DrainPrimeEquGateNodePtr += ji.gm-ji.ggd;
1827 
1829 
1831 
1832 
1833  *ji.f_SourcePrimeEquGateNodePtr -= ji.gm+ji.ggs;
1834 
1836 
1838 
1840 
1841  // Q-matrix:
1842 
1843  *ji.q_GateEquGateNodePtr += ji.capgd+ji.capgs;
1844 
1846 
1848 
1850 
1852 
1854 
1856  }
1857 
1858  return true;
1859 }
1860 
1861 #else
1862 //-----------------------------------------------------------------------------
1863 // Function : Master::loadDAEMatrices
1864 // Purpose :
1865 // Special Notes :
1866 // Scope : public
1867 // Creator : Eric Keiter, SNL
1868 // Creation Date : 12/12/08
1869 //-----------------------------------------------------------------------------
1870 bool Master::loadDAEMatrices (Linear::Matrix & dFdx, Linear::Matrix & dQdx)
1871 {
1872  int sizeInstances = instanceContainer_.size();
1873  for (int i=0; i<sizeInstances; ++i)
1874  {
1875  Instance & ji = *(instanceContainer_.at(i));
1876 
1877  // dFdx matrix:
1878 
1879  dFdx[ji.li_Drain][ji.ADrainEquDrainNodeOffset] += ji.drainCond;
1880 
1882 
1883 
1884  dFdx[ji.li_Gate][ji.AGateEquGateNodeOffset] += ji.ggd+ji.ggs;
1885 
1886  dFdx[ji.li_Gate][ji.AGateEquDrainPrimeNodeOffset] -= ji.ggd;
1887 
1888  dFdx[ji.li_Gate][ji.AGateEquSourcePrimeNodeOffset] -= ji.ggs;
1889 
1890 
1891  dFdx[ji.li_Source][ji.ASourceEquSourceNodeOffset] += ji.sourceCond;
1892 
1894 
1895 
1897 
1898  dFdx[ji.li_DrainPrime][ji.ADrainPrimeEquGateNodeOffset] += ji.gm-ji.ggd;
1899 
1901  ji.drainCond+ji.gds+ji.ggd;
1902 
1904 
1905 
1906  dFdx[ji.li_SourcePrime][ji.ASourcePrimeEquGateNodeOffset] -= ji.gm+ji.ggs;
1907 
1909 
1911 
1913  += ji.sourceCond+ji.gds+ji.gm+ji.ggs;
1914 
1915  // dQdx matrix:
1916 
1917  dQdx[ji.li_Gate ][ji.AGateEquGateNodeOffset ] += ji.capgd+ji.capgs;
1918 
1919  dQdx[ji.li_Gate ][ji.AGateEquDrainPrimeNodeOffset ] -= ji.capgd;
1920 
1921  dQdx[ji.li_Gate ][ji.AGateEquSourcePrimeNodeOffset ] -= ji.capgs;
1922 
1923  dQdx[ji.li_DrainPrime ][ji.ADrainPrimeEquGateNodeOffset ] -= ji.capgd;
1924 
1926 
1928 
1930  }
1931 
1932  return true;
1933 }
1934 #endif
1935 
1936 Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
1937 {
1938 
1939  return new Master(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
1940 }
1941 
1943 {
1945  .registerDevice("z", 1)
1946  .registerModelType("nmf", 1)
1947  .registerModelType("pmf", 1);
1948 }
1949 
1950 } // namespace MESFET
1951 } // namespace Device
1952 } // namespace Xyce
const InstanceName & getName() const
#define CONSTPMOS
Definition: N_DEV_Const.h:80
static std::vector< std::vector< int > > jacMap2_DC_SC
Definition: N_DEV_MESFET.h:150
static void initThermalModel(ParametricData< T > &parametric_data)
Add the parameter "TEMPMODEL" to the parametric_data.
static std::vector< std::vector< int > > jacStamp_SC
Definition: N_DEV_MESFET.h:142
static std::vector< std::vector< int > > jacStamp_DC
Definition: N_DEV_MESFET.h:141
std::vector< Instance * > instanceContainer
Definition: N_DEV_MESFET.h:423
const DeviceOptions & deviceOptions_
Descriptor & addPar(const char *parName, T default_value, T U::*varPtr)
Adds the parameter description to the parameter map.
Definition: N_DEV_Pars.h:1429
#define CONSTQ
Definition: N_DEV_Const.h:51
#define CONSTREFTEMP
Definition: N_DEV_Const.h:56
#define RD
double pnjlim(double vnew, double vold, double vt, double vcrit, int *icheck)
bool given(const std::string &parameter_name) const
Pure virtual class to augment a linear system.
Parameter may be specified as time dependent expression from netlist.
Definition: N_DEV_Pars.h:67
void addInternalNode(Util::SymbolTable &symbol_table, int index, const InstanceName &instance_name, const std::string &lead_name)
virtual bool loadDAEMatrices(Linear::Matrix &dFdx, Linear::Matrix &dQdx)
Populates the device's Jacobian object with these pointers.
void setNumStoreVars(int num_store_vars)
InstanceVector::const_iterator getInstanceEnd() const
Returns an iterator to the ending of the vector of all instances created for this device...
void loadNodeSymbols(Util::SymbolTable &symbol_table) const
Populates and returns the store name map.
Definition: N_DEV_MESFET.C:663
#define AssertLIDs(cmp)
#define CONSTNMOS
Definition: N_DEV_Const.h:79
static Device * factory(const Configuration &configuration, const FactoryBlock &factory_block)
Parameter is subject to being set to minimum junction capacitance.
Definition: N_DEV_Pars.h:71
virtual void registerJacLIDs(const JacobianStamp &jacLIDVec)
Parameter is subject to being set to minimum lead resistance.
Definition: N_DEV_Pars.h:70
bool updateTemperature(const double &temp_tmp)
double fetlim(double vnew, double vold, double vto)
void registerJacLIDs(const std::vector< std::vector< int > > &jacLIDVec)
Definition: N_DEV_MESFET.C:781
double tnom
nominal temperature for device params.
static std::vector< int > jacMap_DC
Definition: N_DEV_MESFET.h:146
void registerStateLIDs(const std::vector< int > &staLIDVecRef)
Definition: N_DEV_MESFET.C:687
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.
static std::vector< std::vector< int > > jacStamp
Definition: N_DEV_MESFET.h:143
virtual bool updateState(double *solVec, double *staVec, double *stoVec)
Updates the devices state information.
static std::vector< std::vector< int > > jacMap2
Definition: N_DEV_MESFET.h:153
void setParams(const std::vector< Param > &params)
const std::string & getName() const
virtual bool loadDAEVectors(double *solVec, double *fVec, double *qVec, double *bVec, double *storeLeadF, double *storeLeadQ, double *leadF, double *leadQ, double *junctionV)
Populates the device's ExternData object with these pointers.
The FactoryBlock contains parameters needed by the device, instance and model creation functions...
const DeviceOptions & getDeviceOptions() const
#define CONSTroot2
Definition: N_DEV_Const.h:50
static std::vector< std::vector< int > > jacMap2_SC
Definition: N_DEV_MESFET.h:152
static void loadInstanceParameters(ParametricData< Instance > &instance_parameters)
Definition: N_DEV_MESFET.C:70
static Config< T > & addConfiguration()
Adds the device to the Xyce device configuration.
Linear::Matrix * dFdxMatrixPtr
The Device class is an interface for device implementations.
Definition: N_DEV_Device.h:101
void addStoreNode(Util::SymbolTable &symbol_table, int index, const InstanceName &instance_name, const std::string &lead_name)
static std::vector< int > jacMap_DC_SC
Definition: N_DEV_MESFET.h:145
const SolverState & solverState_
Class Configuration contains device configuration data.
void registerStoreLIDs(const std::vector< int > &stoLIDVecRef)
Definition: N_DEV_MESFET.C:733
virtual std::ostream & printOutInstances(std::ostream &os) const
Definition: N_DEV_MESFET.C:276
void jacStampMap(const JacobianStamp &stamp_parent, IdVector &map_parent, JacobianStamp &map2_parent, JacobianStamp &stamp, IdVector &map, JacobianStamp &map2, int from, int to, int original_size)
const std::vector< std::vector< int > > & jacobianStamp() const
Definition: N_DEV_MESFET.C:760
const SolverState & getSolverState() const
static std::vector< std::vector< int > > jacMap2_DC
Definition: N_DEV_MESFET.h:151
static void loadModelParameters(ParametricData< Model > &model_parameters)
Definition: N_DEV_MESFET.C:82
static std::vector< int > jacMap
Definition: N_DEV_MESFET.h:148
#define Xyce_NONPOINTER_MATRIX_LOAD
Definition: N_DEV_Bsrc.C:97
bool processInstanceParams()
processInstanceParams
Definition: N_DEV_MESFET.C:343
Instance(const Configuration &configuration, const InstanceBlock &instance_block, Model &model, const FactoryBlock &factory_block)
Definition: N_DEV_MESFET.C:367
const std::string & getType() const
double gmin
minimum allowed conductance.
#define RS
virtual void forEachInstance(DeviceInstanceOp &op) const
Apply a device instance "op" to all instances associated with this model.
Definition: N_DEV_MESFET.C:314
#define CONSTKoverQ
Definition: N_DEV_Const.h:58
static std::vector< int > jacMap_SC
Definition: N_DEV_MESFET.h:147
ModelBlock represents a .MODEL line from the netlist.
Manages parameter binding for class C.
Definition: N_DEV_Pars.h:214
InstanceBlock represent a device instance line from the netlist.
Util::Param temp
operating temperature of ckt.
std::vector< Param > params
Linear::Matrix * dQdxMatrixPtr
void registerLIDs(const std::vector< int > &intLIDVecRef, const std::vector< int > &extLIDVecRef)
Definition: N_DEV_MESFET.C:601
static std::vector< std::vector< int > > jacStamp_DC_SC
Definition: N_DEV_MESFET.h:140
Linear::Vector * flagSolVectorPtr
bool processParams()
processParams
Definition: N_DEV_MESFET.C:329
#define LAMBDA
void setModParams(const std::vector< Param > &params)
#define CONSTboltz
Definition: N_DEV_Const.h:53
#define ALPHA