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