Xyce  6.1
N_DEV_Neuron8.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_Neuron8.C,v $
27 //
28 // Purpose :
29 //
30 // Special Notes :
31 //
32 // Creator : Richard Schiek, Electrical Systems Modeling
33 //
34 // Creation Date : 03/08/2012
35 //
36 // Revision Information:
37 // ---------------------
38 //
39 // Revision Number: $Revision: 1.35 $
40 //
41 // Revision Date : $Date: 2015/10/20 22:32:48 $
42 //
43 // Current Owner : $Author: tvrusso $
44 //-------------------------------------------------------------------------
45 
46 #include <Xyce_config.h>
47 
48 
49 #include <N_DEV_DeviceOptions.h>
50 #include <N_DEV_DeviceMaster.h>
51 #include <N_DEV_ExternData.h>
52 #include <N_DEV_MatrixLoadData.h>
53 #include <N_DEV_Neuron8.h>
55 #include <N_DEV_SolverState.h>
56 #include <N_DEV_Message.h>
57 #include <N_ERH_ErrorMgr.h>
58 
59 #include <N_DEV_Neuron.h>
60 
61 #include <N_LAS_Vector.h>
62 #include <N_LAS_Matrix.h>
63 #include <N_UTL_FeatureTest.h>
64 
65 namespace Xyce {
66 namespace Device {
67 
68 namespace Neuron8 {
69 
71 {
72  p.addPar ("MEMC",0.0,&Neuron8::Instance::memCap)
73  .setGivenMember(&Neuron8::Instance::memCapGiven)
74  .setUnit(U_FARAD)
75  .setCategory(CAT_NONE)
76  .setDescription("Membrane capacitance");
77 
78  p.addPar ("VT",0.0,&Neuron8::Instance::Vt)
79  .setGivenMember(&Neuron8::Instance::VtGiven)
80  .setUnit(U_VOLT)
81  .setCategory(CAT_NONE)
82  .setDescription("Instantaneous threshold voltage");
83 
84  p.addPar ("VR",0.0,&Neuron8::Instance::Vr)
85  .setGivenMember(&Neuron8::Instance::VrGiven)
86  .setUnit(U_VOLT)
87  .setCategory(CAT_NONE)
88  .setDescription("Resting membrane potential");
89 
90  p.addPar ("VP",0.0,&Neuron8::Instance::Vpeak)
91  .setGivenMember(&Neuron8::Instance::VpeakGiven)
92  .setUnit(U_VOLT)
93  .setCategory(CAT_NONE)
94  .setDescription("Peak voltage");
95 
96  p.addPar ("K",0.0,&Neuron8::Instance::k)
97  .setGivenMember(&Neuron8::Instance::kGiven)
98  .setUnit(U_NONE)
99  .setCategory(CAT_NONE)
100  .setDescription("modeling parameter");
101 
102  p.addPar ("A",0.0,&Neuron8::Instance::a)
103  .setGivenMember(&Neuron8::Instance::aGiven)
104  .setUnit(U_NONE)
105  .setCategory(CAT_NONE)
106  .setDescription("modeling parameter");
107 
108  p.addPar ("B",0.0,&Neuron8::Instance::b)
109  .setGivenMember(&Neuron8::Instance::bGiven)
110  .setUnit(U_NONE)
111  .setCategory(CAT_NONE)
112  .setDescription("modeling parameter");
113 
114  p.addPar ("C",0.0,&Neuron8::Instance::c)
115  .setGivenMember(&Neuron8::Instance::cGiven)
116  .setUnit(U_NONE)
117  .setCategory(CAT_NONE)
118  .setDescription("modeling parameter");
119 
120  p.addPar ("D",0.0,&Neuron8::Instance::d)
121  .setGivenMember(&Neuron8::Instance::dGiven)
122  .setUnit(U_NONE)
123  .setCategory(CAT_NONE)
124  .setDescription("modeling parameter");
125 
126  p.addPar ("USCALE",1.0e-9,&Neuron8::Instance::uscale)
127  .setGivenMember(&Neuron8::Instance::uscaleGiven)
128  .setUnit(U_NONE)
129  .setCategory(CAT_NONE)
130  .setDescription("scaling for u variable");
131 
132  p.addPar ("FALLRATE",1.0e3,&Neuron8::Instance::fallRate)
133  .setGivenMember(&Neuron8::Instance::fallRateGiven)
134  .setUnit(U_NONE)
135  .setCategory(CAT_NONE)
136  .setDescription("recovery rate");
137 }
138 
140 {
141  p.addPar ("MEMC",0.0,&Neuron8::Model::memCap)
142  .setGivenMember(&Neuron8::Model::memCapGiven)
143  .setUnit(U_FARAD)
144  .setCategory(CAT_NONE)
145  .setDescription("Membrane capacitance");
146 
147  p.addPar ("VT",0.0,&Neuron8::Model::Vt)
148  .setGivenMember(&Neuron8::Model::VtGiven)
149  .setUnit(U_VOLT)
150  .setCategory(CAT_NONE)
151  .setDescription("Instantaneous threshold voltage");
152 
153  p.addPar ("VR",0.0,&Neuron8::Model::Vr)
154  .setGivenMember(&Neuron8::Model::VrGiven)
155  .setUnit(U_VOLT)
156  .setCategory(CAT_NONE)
157  .setDescription("Resting membrane potential");
158 
159  p.addPar ("VP",0.0,&Neuron8::Model::Vpeak)
160  .setGivenMember(&Neuron8::Model::VpeakGiven)
161  .setUnit(U_VOLT)
162  .setCategory(CAT_NONE)
163  .setDescription("Peak voltage");
164 
165  p.addPar ("K",0.0,&Neuron8::Model::k)
166  .setGivenMember(&Neuron8::Model::kGiven)
167  .setUnit(U_NONE)
168  .setCategory(CAT_NONE)
169  .setDescription("Neuron8::Modeling parameter");
170 
171  p.addPar ("A",0.0,&Neuron8::Model::a)
172  .setGivenMember(&Neuron8::Model::aGiven)
173  .setUnit(U_NONE)
174  .setCategory(CAT_NONE)
175  .setDescription("Neuron8::Modeling parameter");
176 
177  p.addPar ("B",0.0,&Neuron8::Model::b)
178  .setGivenMember(&Neuron8::Model::bGiven)
179  .setUnit(U_NONE)
180  .setCategory(CAT_NONE)
181  .setDescription("Neuron8::Modeling parameter");
182 
183  p.addPar ("C",0.0,&Neuron8::Model::c)
184  .setGivenMember(&Neuron8::Model::cGiven)
185  .setUnit(U_NONE)
186  .setCategory(CAT_NONE)
187  .setDescription("Neuron8::Modeling parameter");
188 
189  p.addPar ("D",0.0,&Neuron8::Model::d)
190  .setGivenMember(&Neuron8::Model::dGiven)
191  .setUnit(U_NONE)
192  .setCategory(CAT_NONE)
193  .setDescription("Neuron8::Modeling parameter");
194 
195  p.addPar ("USCALE",1.0e-9,&Neuron8::Model::uscale)
196  .setGivenMember(&Neuron8::Model::uscaleGiven)
197  .setUnit(U_NONE)
198  .setCategory(CAT_NONE)
199  .setDescription("scaling for u variable");
200 
201  p.addPar ("FALLRATE",1.0e3,&Neuron8::Model::fallRate)
202  .setGivenMember(&Neuron8::Model::fallRateGiven)
203  .setUnit(U_NONE)
204  .setCategory(CAT_NONE)
205  .setDescription("recovery rate");
206 }
207 
208 //
209 // static class member inits
210 //
211 std::vector< std::vector<int> > Instance::jacStamp;
212 
213 // Class Instance
214 
215 //-----------------------------------------------------------------------------
216 // Function : Instance::Instance
217 // Purpose : constructor
218 // Special Notes :
219 // Scope : public
220 // Creator : Richard Schiek, Electrical Systems Modeling
221 // Creation Date : 03/08/2012
222 //-----------------------------------------------------------------------------
224  const Configuration & configuration,
225  const InstanceBlock & IB,
226  Model & Miter,
227  const FactoryBlock & factory_block)
228  : DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
229  model_(Miter),
230  memCap(0.0),
231  Vt(0.0),
232  Vr(0.0),
233  Vpeak(0.0),
234  k(0.0),
235  a(0.0),
236  b(0.0),
237  c(0.0),
238  d(0.0),
239  uscale(1.0e-9),
240  fallRate(1.0e3),
241  memCapGiven(false),
242  VtGiven(false),
243  VrGiven(false),
244  VpeakGiven(false),
245  kGiven(false),
246  aGiven(false),
247  bGiven(false),
248  cGiven(false),
249  dGiven(false),
250  uscaleGiven(false),
251  fallRateGiven(false),
252  vEquFvalue(0.0),
253  vEquQvalue(0.0),
254  vEqudFdv(0.0),
255  vEqudFdu(0.0),
256  vEqudQdv(0.0),
257  uEquFvalue(0.0),
258  uEquQvalue(0.0),
259  uEqudFdv(0.0),
260  uEqudFdu(0.0),
261  uEqudQdu(0.0),
262  resetting(false),
263  uPeak(0.0),
264  li_V(-1),
265  li_U(-1),
266  vEquVOffset(-1),
267  vEquUOffset(-1),
268  uEquVOffset(-1),
269  uEquUOffset(-1)
270 {
271  numExtVars = 1; // membrane voltage
272 
273  // Set params to constant default values:
274  setDefaultParams ();
275 
276  // Set params according to instance line
277  setParams (IB.params);
278 
279  // Set any non-constant parameter defaults:
280 
281  //if (!given("TEMP"))
282  // temp = getDeviceOptions().temp.dVal();
283 
284  // Calculate any parameters specified as expressions:
286 
287  // calculate dependent (ie computed) params and check for errors:
288  processParams ();
289 
290  /*
291  Xyce::dout() << "Instance::Instance" << std::endl
292  << "memC = " << memCap << std::endl
293  << "Vt = " << Vt << std::endl
294  << "Vr = " << Vr << std::endl
295  << "Vp = " << Vpeak << std::endl
296  << "k = " << k << std::endl
297  << "a = " << a << std::endl
298  << "b = " << b << std::endl
299  << "c = " << c << std::endl
300  << "d = " << d << std::endl
301  << "uscale = " << uscale << std::endl
302  << "fallRate = " << fallRate << std::endl;
303  */
304 
305  numIntVars = 1; // u
306  numStateVars = 0;
307 
308  // total up number of vars.
309  int numVars = numExtVars + numIntVars;
310 
311 
312  //
313  // equations are:
314  // v equation
315  // k * (v-Vr) * (v-Vt) - u + I - C dv/dt = 0
316  // u euqtion
317  // a * ( b * (v-Vr) - u ) - du/dt = 0
318 
319  // df/dx
320  // V u
321  // Vequ 2k V - Vt - Vr -1
322  // Uequ a b -a
323  //
324  // dq/dx
325  // V u
326  // Vequ -memCap 0
327  // Uequ 0 -1
328  //
329  // so jacStamp is dense.
330 
331 
332  // set up jacStamp
333  if( jacStamp.empty() )
334  {
335  jacStamp.resize(2);
336  jacStamp[0].resize(2);
337  jacStamp[0][0] = 0;
338  jacStamp[0][1] = 1;
339  jacStamp[1].resize(2);
340  jacStamp[1][0] = 0;
341  jacStamp[1][1] = 1;
342  }
343 
344  /*
345  // print out jacStamp
346  Xyce::dout() << "jacStamp for Neuron6" << std::endl;
347  int numRows = jacStamp.size();
348  for( int i=0; i< numRows; i++ )
349  {
350  int numCol = jacStamp[i].size();
351  Xyce::dout() << "jacStamp[ " << i << " ] = { ";
352  for(int j=0; j<numCol; j++)
353  {
354  Xyce::dout() << jacStamp[i][j] << " ";
355  }
356  Xyce::dout() << " } " << std::endl;
357  }
358  Xyce::dout() << std::endl;
359  */
360 
361 }
362 
363 //-----------------------------------------------------------------------------
364 // Function : Instance::~Instance
365 // Purpose : destructor
366 // Special Notes :
367 // Scope : public
368 // Creator : Richard Schiek, Electrical Systems Modeling
369 // Creation Date : 03/08/2012
370 //-----------------------------------------------------------------------------
372 {
373 }
374 
375 //-----------------------------------------------------------------------------
376 // Function : Instance::processParams
377 // Purpose :
378 // Special Notes :
379 // Scope : public
380 // Creator : Richard Schiek, Electrical Systems Modeling
381 // Creation Date : 03/08/2012
382 //-----------------------------------------------------------------------------
384 {
385  // If there are any time dependent parameters, set their values at for
386  // the current time.
387 
388  // pull unspecified params out of the model if they weren't specified here
389  if( !memCapGiven && model_.memCapGiven )
390  {
391  memCap = model_.memCap;
392  }
393  if( !VtGiven && model_.VtGiven )
394  {
395  Vt = model_.Vt;
396  }
397  if( !VrGiven && model_.VrGiven )
398  {
399  Vr = model_.Vr;
400  }
401  if( !VpeakGiven && model_.VpeakGiven )
402  {
403  Vpeak = model_.Vpeak;
404  }
405  if( !kGiven && model_.kGiven )
406  {
407  k = model_.k;
408  }
409  if( !aGiven && model_.aGiven )
410  {
411  a = model_.a;
412  }
413  if( !bGiven && model_.bGiven )
414  {
415  b = model_.b;
416  }
417  if( !cGiven && model_.cGiven )
418  {
419  c = model_.c;
420  }
421  if( !dGiven && model_.dGiven )
422  {
423  d = model_.d;
424  }
425  if( !uscaleGiven && model_.uscaleGiven )
426  {
427  uscale = model_.uscale;
428  }
430  {
432  }
433 
434  return true;
435 }
436 
437 //-----------------------------------------------------------------------------
438 // Function : Instance::updateTemperature
439 // Purpose :
440 // Special Notes :
441 // Scope : public
442 // Creator : Richard Schiek, Electrical Systems Modeling
443 // Creation Date : 03/08/2012
444 //-----------------------------------------------------------------------------
445 bool Instance::updateTemperature ( const double & temp)
446 {
447  bool bsuccess = true;
448  return bsuccess;
449 }
450 
451 //-----------------------------------------------------------------------------
452 // Function : Instance::registerLIDs
453 // Purpose :
454 // Special Notes :
455 // Scope : public
456 // Creator : Richard Schiek, Electrical Systems Modeling
457 // Creation Date : 03/08/2012
458 //-----------------------------------------------------------------------------
459 void Instance::registerLIDs(const std::vector<int> & intLIDVecRef,
460  const std::vector<int> & extLIDVecRef)
461 {
462  AssertLIDs(intLIDVecRef.size() == numIntVars);
463  AssertLIDs(extLIDVecRef.size() == numExtVars);
464 
465  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
466  {
467  Xyce::dout() << std::endl << section_divider << std::endl;
468  Xyce::dout() << " Instance::registerLIDs" << std::endl;
469  Xyce::dout() << " name = " << getName() << std::endl;
470  }
471 
472  // copy over the global ID lists.
473  intLIDVec = intLIDVecRef;
474  extLIDVec = extLIDVecRef;
475 
476  li_V = extLIDVec[0];
477  li_U = intLIDVec[0];
478 
479  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) )
480  {
481  Xyce::dout() << " li_V = " << li_V << std::endl
482  << " li_U = " << li_U << std::endl;
483 
484  }
485 
486  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) )
487  {
488  Xyce::dout() << section_divider << std::endl;
489  }
490 
491 }
492 
493 //-----------------------------------------------------------------------------
494 // Function : Instance::loadNodeSymbols
495 // Purpose :
496 // Special Notes :
497 // Scope : public
498 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
499 // Creation Date : 05/13/05
500 //-----------------------------------------------------------------------------
501 void Instance::loadNodeSymbols(Util::SymbolTable &symbol_table) const
502 {
503  addInternalNode(symbol_table, li_U, getName(), "U");
504 }
505 
506 //-----------------------------------------------------------------------------
507 // Function : Instance::registerStateLIDs
508 // Purpose :
509 // Special Notes :
510 // Scope : public
511 // Creator : Richard Schiek, Electrical Systems Modeling
512 // Creation Date : 03/08/2012
513 //-----------------------------------------------------------------------------
514 void Instance::registerStateLIDs( const std::vector<int> & staLIDVecRef )
515 {
516  AssertLIDs(staLIDVecRef.size() == numStateVars);
517 }
518 
519 //-----------------------------------------------------------------------------
520 // Function : Instance::jacobianStamp
521 // Purpose :
522 // Special Notes :
523 // Scope : public
524 // Creator : Richard Schiek, Electrical Systems Modeling
525 // Creation Date : 03/08/2012
526 //-----------------------------------------------------------------------------
527 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
528 {
529  return jacStamp;
530 }
531 
532 //-----------------------------------------------------------------------------
533 // Function : Instance::registerJacLIDs
534 // Purpose :
535 // Special Notes :
536 // Scope : public
537 // Creator : Richard Schiek, Electrical Systems Modeling
538 // Creation Date : 03/08/2012
539 //-----------------------------------------------------------------------------
540 void Instance::registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec )
541 {
542  DeviceInstance::registerJacLIDs( jacLIDVec );
543 
544  vEquVOffset = jacLIDVec[0][0];
545  vEquUOffset = jacLIDVec[0][1];
546  uEquVOffset = jacLIDVec[1][0];
547  uEquUOffset = jacLIDVec[1][1];
548 }
549 
550 
551 //-----------------------------------------------------------------------------
552 // Function : Instance::updateIntermediateVars
553 // Purpose :
554 // Special Notes :
555 // Scope : public
556 // Creator : Richard Schiek, Electrical Systems Modeling
557 // Creation Date : 03/08/2012
558 //-----------------------------------------------------------------------------
560 {
561  bool bsuccess = true;
562 
563  // here we take the current solutions for V1, V2, n, m and h
564  // and use those to calculate all the terms needed for the next
565  // load cycle (F, Q, dFdX, dQdX)
566  Linear::Vector * solVectorPtr = extData.nextSolVectorPtr;
567 
568  double vVal = (*solVectorPtr)[li_V];
569  double uVal = (*solVectorPtr)[li_U];
570 
571  // not sure if I need to do this as it should just
572  // fall out of the solution when d/dt = 0. Possibly
573  // it doesn't because there are two solutions when d/dt = 0,
574  // either vVal = Vr or vVal = Vt we want vVal=Vr.
575  if( getSolverState().dcopFlag )
576  {
577  // vVal - Vr = 0 and uVal=0
578  vEquFvalue = vVal - Vr;
579  vEquQvalue = - memCap * vVal;
580  vEqudFdv = 1.0;
581  vEqudFdu = 0.0;
582  vEqudQdv = - memCap;
583  uEquFvalue = uVal*uscale;
584  uEquQvalue = -uVal*uscale;
585  uEqudFdv = 0.0;
586  uEqudFdu = 1.0*uscale;
587  uEqudQdu = uscale;
588  }
589  else
590  {
591  // need to cacth case where v> Vpeak
592  if( !resetting && (vVal >= Vpeak) )
593  {
594  resetting = true;
595  uPeak = uVal;
596  }
597  else
598  {
599  // only break out of the resetting phase at the start of a newton solve
600  if( (getSolverState().newtonIter == 0 ) && (vVal <= (c+0.0001) ) && (uVal >= (uPeak + (d-1.0e-13)/uscale) ))
601  {
602  // reset is done, go back to old form
603  resetting = false;
604  }
605  }
606 
607  if ( resetting )
608  {
609  //Xyce::dout() << "In resetting section. (uPeak*uscale + d) = " << (uPeak + d/uscale) << std::endl;
610  vEquFvalue = -fallRate*(vVal - c) - uVal*uscale;
611  vEquQvalue = -memCap* vVal;
612  vEqudFdv = -fallRate;
613  vEqudFdu = -uscale;
614  vEqudQdv = -memCap;
615 
616  uEquFvalue = -fallRate*(uVal - (uPeak + d/uscale) );
617  uEquQvalue = -uVal;
618  uEqudFdv = 0.0;
619  uEqudFdu = -fallRate;
620  uEqudQdu = -1.0;
621  }
622  else
623  {
624  //Xyce::dout() << "In normal section." << std::endl;
625  vEquFvalue = k * (vVal - Vr) * (vVal - Vt) - uVal*uscale;
626  vEquQvalue = - memCap * vVal;
627  vEqudFdv = k * ( 2*vVal - Vt - Vr);
628  vEqudFdu = -uscale;
629  vEqudQdv = -memCap;
630 
631  uEquFvalue = a * ( b * (vVal - Vr)/uscale - uVal );
632  uEquQvalue = -uVal;
633  uEqudFdv = a * b / uscale;
634  uEqudFdu = -a;
635  uEqudQdu = -1.0;
636  }
637 
638 
639  }
640 
641  /*
642  Xyce::dout() << "Instance::updateIntermediateVars()" << std::endl
643  << "vEquFvalue = " << vEquFvalue << std::endl
644  << "vEquQvalue = " << vEquQvalue << std::endl
645  << "vEqudFdv = " << vEqudFdv << std::endl
646  << "vEqudFdu = " << vEqudFdu << std::endl
647  << "vEqudQdv = " << vEqudQdv << std::endl
648  << "uEquFvalue = " << uEquFvalue << std::endl
649  << "uEquQvalue = " << uEquQvalue << std::endl
650  << "uEqudFdv = " << uEqudFdv << std::endl
651  << "uEqudFdu = " << uEqudFdu << std::endl
652  << "uEqudQdu = " << uEqudQdu << std::endl
653  << "vVal = " << vVal << std::endl
654  << "uVal = " << uVal << std::endl;
655  */
656  return bsuccess;
657 }
658 
659 /*
660  this approach can be problematic if many of these devices are out of
661  phase and issueing breakpoints all the time. Thus, not very workable -- RLS
662 //-----------------------------------------------------------------------------
663 // Function : Instance::getInstanceBreakPoints
664 // Purpose :
665 // Special Notes :
666 // Scope : public
667 // Creator : Richard Schiek, Electrical Systems Modeling
668 // Creation Date : 03/08/2012
669 //-----------------------------------------------------------------------------
670 bool Instance::getInstanceBreakPoints(
671 std::vector<Util::BreakPoint> &breakPointTimes)
672 {
673 breakPointTimes.push_back(breakPoint);
674 return true;
675 }
676 */
677 
678 //-----------------------------------------------------------------------------
679 // Function : Instance::updatePrimaryState
680 // Purpose :
681 // Special Notes :
682 // Scope : public
683 // Creator : Richard Schiek, Electrical Systems Modeling
684 // Creation Date : 03/08/2012
685 //-----------------------------------------------------------------------------
687 {
688  bool bsuccess = true;
689 
691 
692  return bsuccess;
693 }
694 
695 //-----------------------------------------------------------------------------
696 // Function : Instance::updateSecondaryState
697 // Purpose :
698 // Special Notes :
699 // Scope : public
700 // Creator : Richard Schiek, Electrical Systems Modeling
701 // Creation Date : 03/08/2012
702 //-----------------------------------------------------------------------------
704 {
705  bool bsuccess = true;
706 
707  return bsuccess;
708 }
709 
710 //-----------------------------------------------------------------------------
711 // Function : Instance::loadDAEQVector
712 //
713 // Purpose : Loads the Q-vector contributions for a single
714 // Neuron 7 instance.
715 //
716 // Special Notes : The "Q" vector is part of a standard DAE formalism in
717 // which the system of equations is represented as:
718 //
719 // f(x) = dQ(x)/dt + F(x) - B(t) = 0
720 //
721 // Scope : public
722 // Creator : Richard Schiek, Electrical Systems Modeling
723 // Creation Date : 03/08/2012
724 //-----------------------------------------------------------------------------
726 {
727  bool bsuccess = true;
728 
729  Linear::Vector * daeQVecPtr = extData.daeQVectorPtr;
730  (*daeQVecPtr)[li_V] += vEquQvalue;
731  (*daeQVecPtr)[li_U] += uEquQvalue;
732 
733  return bsuccess;
734 }
735 
736 //-----------------------------------------------------------------------------
737 // Function : Instance::loadDAEFVector
738 //
739 // Purpose : Loads the F-vector contributions for a single
740 // Neuron 7 instance.
741 //
742 // Special Notes :
743 //
744 // Scope : public
745 // Creator : Richard Schiek, Electrical Systems Modeling
746 // Creation Date : 03/08/2012
747 //-----------------------------------------------------------------------------
749 {
750  bool bsuccess=true;
751 
752  Linear::Vector * daeFVecPtr = extData.daeFVectorPtr;
753 
754  (*daeFVecPtr)[li_V] += vEquFvalue;
755  (*daeFVecPtr)[li_U] += uEquFvalue;
756 
757  return bsuccess;
758 }
759 
760 //-----------------------------------------------------------------------------
761 // Function : Instance::loadDAEdQdx
762 //
763 // Purpose : Loads the Q-vector contributions for a single
764 // Neuron 7 instance.
765 // Scope : public
766 // Creator : Richard Schiek, Electrical Systems Modeling
767 // Creation Date : 03/08/2012
768 //-----------------------------------------------------------------------------
770 {
771  bool bsuccess = true;
772 
773  Linear::Matrix * dQdxMatPtr = extData.dQdxMatrixPtr;
774 
775  (*dQdxMatPtr)[li_V][vEquVOffset] += vEqudQdv;
776  (*dQdxMatPtr)[li_U][uEquUOffset] += uEqudQdu;
777 
778  return bsuccess;
779 }
780 
781 
782 
783 //-----------------------------------------------------------------------------
784 // Function : Instance::loadDAEdFdx ()
785 //
786 // Purpose : Loads the F-vector contributions for a single
787 // Neuron 7 instance.
788 //
789 // Special Notes : This is an algebraic constaint.
790 //
791 // Scope : public
792 // Creator : Richard Schiek, Electrical Systems Modeling
793 // Creation Date : 03/08/2012
794 //-----------------------------------------------------------------------------
796 {
797  bool bsuccess = true;
798 
799  Linear::Matrix * dFdxMatPtr = extData.dFdxMatrixPtr;
800 
801  (*dFdxMatPtr)[li_V][vEquVOffset] += vEqudFdv;
802  (*dFdxMatPtr)[li_V][vEquUOffset] += vEqudFdu;
803 
804  (*dFdxMatPtr)[li_U][uEquVOffset] += uEqudFdv;
805  (*dFdxMatPtr)[li_U][uEquUOffset] += uEqudFdu;
806 
807  return bsuccess;
808 }
809 
810 //-----------------------------------------------------------------------------
811 // Function : Instance::setIC
812 // Purpose :
813 // Special Notes :
814 // Scope : public
815 // Creator : Richard Schiek, Electrical Systems Modeling
816 // Creation Date : 03/08/2012
817 //-----------------------------------------------------------------------------
819 {
820  bool bsuccess = true;
821 
822  return bsuccess;
823 }
824 
825 //-----------------------------------------------------------------------------
826 // Function : Instance::varTypes
827 // Purpose :
828 // Special Notes :
829 // Scope : public
830 // Creator : Richard Schiek, Electrical Systems Modeling
831 // Creation Date : 03/08/2012
832 //-----------------------------------------------------------------------------
833 void Instance::varTypes( std::vector<char> & varTypeVec )
834 {
835  //varTypeVec.resize(1);
836  //varTypeVec[0] = 'I';
837 }
838 
839 
840 //-----------------------------------------------------------------------------
841 // Function : Model::Model
842 // Purpose : block constructor
843 // Special Notes :
844 // Scope : public
845 // Creator : Richard Schiek, Electrical Systems Modeling
846 // Creation Date : 03/08/2012
847 //-----------------------------------------------------------------------------
849  const Configuration & configuration,
850  const ModelBlock & MB,
851  const FactoryBlock & factory_block)
852  : DeviceModel(MB, configuration.getModelParameters(), factory_block),
853  memCap(0.0),
854  Vt(0.0),
855  Vr(0.0),
856  Vpeak(0.0),
857  k(0.0),
858  a(0.0),
859  b(0.0),
860  c(0.0),
861  d(0.0),
862  uscale(1.0e-9),
863  fallRate(1.0e3),
864  memCapGiven(false),
865  VtGiven(false),
866  VrGiven(false),
867  VpeakGiven(false),
868  kGiven(false),
869  aGiven(false),
870  bGiven(false),
871  cGiven(false),
872  dGiven(false),
873  uscaleGiven(false),
874  fallRateGiven(false)
875 {
876 
877  /*
878  Xyce::dout() << "Model::Model" << std::endl
879  << "memC = " << memCap << std::endl
880  << "Vt = " << Vt << std::endl
881  << "Vr = " << Vr << std::endl
882  << "Vp = " << Vpeak << std::endl
883  << "k = " << k << std::endl
884  << "a = " << a << std::endl
885  << "b = " << b << std::endl
886  << "c = " << c << std::endl
887  << "d = " << d << std::endl
888  << "uscale = " << uscale << std::endl
889  << "fallRate = " << fallRate << std::endl;
890  */
891 
892  // Set params to constant default values:
893  setDefaultParams ();
894 
895  // Set params according to .model line and constant defaults from metadata:
896  setModParams (MB.params);
897 
898  // Set any non-constant parameter defaults:
899  //if (!given("TNOM"))
900  // tnom = getDeviceOptions().tnom;
901 
902  // Calculate any parameters specified as expressions:
904 
905  // calculate dependent (ie computed) params and check for errors:
906 
907  processParams ();
908 }
909 
910 
911 //-----------------------------------------------------------------------------
912 // Function : Model::~Model
913 // Purpose : destructor
914 // Special Notes :
915 // Scope : public
916 // Creator : Richard Schiek, Electrical Systems Modeling
917 // Creation Date : 03/08/2012
918 //-----------------------------------------------------------------------------
920 {
921  std::vector<Instance*>::iterator iter;
922  std::vector<Instance*>::iterator first = instanceContainer.begin();
923  std::vector<Instance*>::iterator last = instanceContainer.end();
924 
925  for (iter=first; iter!=last; ++iter)
926  {
927  delete (*iter);
928  }
929 
930 }
931 
932 // additional Declarations
933 //-----------------------------------------------------------------------------
934 // Function : Model::processParams
935 // Purpose :
936 // Special Notes :
937 // Scope : public
938 // Creator : Richard Schiek, Electrical Systems Modeling
939 // Creation Date : 03/08/2012
940 //-----------------------------------------------------------------------------
942 {
943  return true;
944 }
945 
946 //----------------------------------------------------------------------------
947 // Function : Model::processInstanceParams
948 // Purpose :
949 // Special Notes :
950 // Scope : public
951 // Creator : Richard Schiek, Electrical Systems Modeling
952 // Creation Date : 03/08/2012
953 //----------------------------------------------------------------------------
955 {
956 
957  std::vector<Instance*>::iterator iter;
958  std::vector<Instance*>::iterator first = instanceContainer.begin();
959  std::vector<Instance*>::iterator last = instanceContainer.end();
960 
961  for (iter=first; iter!=last; ++iter)
962  {
963  (*iter)->processParams();
964  }
965 
966  return true;
967 }
968 //-----------------------------------------------------------------------------
969 // Function : Model::printOutInstances
970 // Purpose : debugging tool.
971 // Special Notes :
972 // Scope : public
973 // Creator : Richard Schiek, Electrical Systems Modeling
974 // Creation Date : 03/08/2012
975 //-----------------------------------------------------------------------------
976 std::ostream &Model::printOutInstances(std::ostream &os) const
977 {
978  std::vector<Instance*>::const_iterator iter;
979  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
980  std::vector<Instance*>::const_iterator last = instanceContainer.end();
981 
982  int i, isize;
983  isize = instanceContainer.size();
984 
985  os << std::endl;
986  os << "Number of Neuron instances: " << isize << std::endl;
987  os << " name=\t\tmodelName\tParameters" << std::endl;
988  for (i=0, iter=first; iter!=last; ++iter, ++i)
989  {
990  os << " " << i << ": " << (*iter)->getName() << "\t";
991  os << getName();
992  os << std::endl;
993  }
994 
995  os << std::endl;
996  return os;
997 }
998 
999 //-----------------------------------------------------------------------------
1000 // Function : Model::forEachInstance
1001 // Purpose :
1002 // Special Notes :
1003 // Scope : public
1004 // Creator : David Baur
1005 // Creation Date : 2/4/2014
1006 //-----------------------------------------------------------------------------
1007 /// Apply a device instance "op" to all instances associated with this
1008 /// model
1009 ///
1010 /// @param[in] op Operator to apply to all instances.
1011 ///
1012 ///
1013 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
1014 {
1015  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1016  op(*it);
1017 }
1018 
1019 
1020 Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
1021 {
1022 
1023  return new DeviceMaster<Traits>(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
1024 }
1025 
1027 {
1029  .registerDevice("neuron", 8)
1030  .registerModelType("neuron", 8);
1031 }
1032 
1033 } // namespace Neuron8
1034 } // namespace Device
1035 } // namespace Xyce
const InstanceName & getName() const
const SolverState & solverState_
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
void registerJacLIDs(const std::vector< std::vector< int > > &jacLIDVec)
void registerStateLIDs(const std::vector< int > &staLIDVecRef)
Linear::Vector * nextSolVectorPtr
Linear::Vector * daeQVectorPtr
Pure virtual class to augment a linear system.
void addInternalNode(Util::SymbolTable &symbol_table, int index, const InstanceName &instance_name, const std::string &lead_name)
std::vector< Instance * > instanceContainer
#define AssertLIDs(cmp)
RetScalarT Vt(Arg1ScalarT U, Arg2ScalarT Ud)
virtual void registerJacLIDs(const JacobianStamp &jacLIDVec)
static Device * factory(const Configuration &configuration, const FactoryBlock &factory_block)
static std::vector< std::vector< int > > jacStamp
Definition: N_DEV_Neuron8.h:94
static void loadInstanceParameters(ParametricData< Instance > &instance_parameters)
Definition: N_DEV_Neuron8.C:70
static void loadModelParameters(ParametricData< Model > &model_parameters)
std::vector< Param > params
Parameters from the line.
void setParams(const std::vector< Param > &params)
const std::string & getName() const
The FactoryBlock contains parameters needed by the device, instance and model creation functions...
virtual std::ostream & printOutInstances(std::ostream &os) const
const DeviceOptions & deviceOptions_
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 varTypes(std::vector< char > &varTypeVec)
bool processInstanceParams()
processInstanceParams
Class Configuration contains device configuration data.
const std::vector< std::vector< int > > & jacobianStamp() const
const SolverState & getSolverState() const
Instance(const Configuration &configuration, const InstanceBlock &IB, Model &Miter, const FactoryBlock &factory_block)
virtual void forEachInstance(DeviceInstanceOp &op) const
Apply a device instance "op" to all instances associated with this model.
Linear::Vector * daeFVectorPtr
bool updateTemperature(const double &temp_tmp)
void loadNodeSymbols(Util::SymbolTable &symbol_table) const
Populates and returns the store name map.
ModelBlock represents a .MODEL line from the netlist.
Manages parameter binding for class C.
Definition: N_DEV_Pars.h:214
InstanceBlock represent a device instance line from the netlist.
std::vector< Param > params
bool processParams()
processParams
Linear::Matrix * dQdxMatrixPtr
void setModParams(const std::vector< Param > &params)
void registerLIDs(const std::vector< int > &intLIDVecRef, const std::vector< int > &extLIDVecRef)