Xyce  6.1
N_DEV_Neuron4.h
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$
27 //
28 // Purpose : Neuron classes.
29 //
30 // Special Notes :
31 //
32 // Creator : Richard Schiek, SNL, Electrical and Microsystem Modeling
33 //
34 // Creation Date : 06/10/09
35 //
36 // Revision Information:
37 // ---------------------
38 //
39 // Revision Number: $Revision$
40 //
41 // Revision Date : $Date$
42 //
43 // Current Owner : $Author$
44 //-----------------------------------------------------------------------------
45 
46 #ifndef Xyce_N_DEV_Neuron4_h
47 #define Xyce_N_DEV_Neuron4_h
48 
49 #include <N_DEV_Configuration.h>
50 #include <Sacado.hpp>
51 
52 // ---------- Xyce Includes ----------
53 #include <N_DEV_DeviceBlock.h>
54 #include <N_DEV_DeviceInstance.h>
55 #include <N_DEV_DeviceModel.h>
56 
57 #include <N_DEV_Neuron.h>
58 
59 namespace Xyce {
60 namespace Device {
61 namespace Neuron4 {
62 
63 class Model;
64 class Instance;
65 
66 struct Traits : public DeviceTraits<Model, Instance, Neuron::Traits>
67 {
68  static const char *name() {return "Neuron";}
69  static const char *deviceTypeName() {return "YNEURON level 4";}
70  static int numNodes() {return 2;}
71  static bool modelRequired() {return true;}
72  static bool isLinearDevice() {return true;}
73 
74  static Device *factory(const Configuration &configuration, const FactoryBlock &factory_block);
75  static void loadModelParameters(ParametricData<Model> &model_parameters);
76  static void loadInstanceParameters(ParametricData<Instance> &instance_parameters);
77 };
78 
79 //-----------------------------------------------------------------------------
80 // Class : Instance
81 // Purpose : This is class refers to a single instance of the
82 // Neuron device. It has two nodes associated with it, a
83 // positive and a negative node. See the NeuronInstance
84 // class for a more detailed explanation.
85 // Special Notes :
86 // Creator : Richard Schiek, SNL, Electrical and Microsystem Modeling
87 // Creation Date : 06/10/09
88 //-----------------------------------------------------------------------------
89 class Instance : public DeviceInstance
90 {
91  friend class ParametricData<Instance>;
92  friend class Model;
93  friend class Traits;
94 
95 public:
96 
97  Instance(
98  const Configuration & configuration,
99  const InstanceBlock & IB,
100  Model & Miter,
101  const FactoryBlock & factory_block);
102 
103  ~Instance();
104 
105 private:
106  Instance(const Instance &);
107  Instance &operator=(const Instance &);
108 
109 public:
110  void registerLIDs( const std::vector<int> & intLIDVecRef,
111  const std::vector<int> & extLIDVecRef );
112  void registerStateLIDs( const std::vector<int> & staLIDVecRef );
113 
114  void loadNodeSymbols(Util::SymbolTable &symbol_table) const; // override
115 
116  const std::vector< std::vector<int> > & jacobianStamp() const;
117  void registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec );
118 
119  bool processParams ();
120  bool updateTemperature(const double & temp_tmp);
121 
122  bool updateIntermediateVars ();
123  bool updatePrimaryState ();
124  bool updateSecondaryState ();
125  bool setIC ();
126 
127  void varTypes( std::vector<char> & varTypeVec );
128 
129  // load functions, residual:
130  bool loadDAEQVector ();
131  bool loadDAEFVector ();
132 
133  void auxDAECalculations ();
134 
135  // load functions, Jacobian:
136  bool loadDAEdQdx ();
137  bool loadDAEdFdx ();
138 
139 private:
140  // These functions represents the equations that need to be solved
141  // for this device. Since Xyce loads an F and Q contribution, the
142  // equations are broken up into their F and Q components. Thus there
143  // is a kcl1EquF() and kcl1EquQ(). Automatic differentiation will
144  // be used to generate all the derivatives of these equations for the
145  // dF/dX and dQ/dX loads
146 
147  // first we list some utility functions for calculating coefficients
148  //
149  // These functions expect V to be in milli-volts and then return values that
150  // are in 1/ms. Thus the extra factor's of 1000 here and there
151 
152  // potassium current, functions for activator equation
153  template <typename ScalarT>
154  static ScalarT alphaN( const ScalarT Vin)
155  {
156  ScalarT vScaled = 1000.0 * Vin; // convert voltage to milli-volts
157  ScalarT r = 1000.0 * (0.02 * (vScaled + 45.7)) / (1.0 - std::exp(-0.1*(vScaled+45.7)));
158  // result. the 1000 factor is to change from 1/ms to 1/s
159  return r;
160  }
161 
162  template <typename ScalarT>
163  static ScalarT betaN( const ScalarT Vin)
164  {
165  ScalarT vScaled = 1000.0 * Vin; // convert voltage to milli-volts
166  ScalarT r = 1000.0 * 0.25 * std::exp( -0.0125 * (vScaled + 55.7));
167  // result. the 1000 factor is to change from 1/ms to 1/s
168  return r;
169  }
170 
171  // sodium current, functions for activator equation
172  template <typename ScalarT>
173  static ScalarT alphaM( const ScalarT Vin)
174  {
175  ScalarT vScaled = 1000.0 * Vin; // convert voltage to milli-volts
176  ScalarT r = 1000.0 * (0.38 * (vScaled + 29.7)) / (1.0 - std::exp(-0.1*(vScaled+29.7)));
177  // result. the 1000 factor is to change from 1/ms to 1/s
178  return r;
179  }
180 
181  template <typename ScalarT>
182  static ScalarT betaM( const ScalarT Vin)
183  {
184  ScalarT vScaled = 1000.0 * Vin; // convert voltage to milli-volts
185  ScalarT r = 1000.0 * 15.2 * std::exp( -0.0556 * (vScaled + 54.7));
186  // result. the 1000 factor is to change from 1/ms to 1/s
187  return r;
188  }
189 
190  template <typename ScalarT>
191  static ScalarT alphaH( const ScalarT Vin)
192  {
193  ScalarT vScaled = 1000.0 * Vin; // convert voltage to milli-volts
194  ScalarT r = 1000.0 * 0.266 * std::exp( -0.05 * (vScaled + 48.0));
195  // result. the 1000 factor is to change from 1/ms to 1/s
196  return r;
197  }
198 
199  template <typename ScalarT>
200  static ScalarT betaH( const ScalarT Vin)
201  {
202  ScalarT vScaled = 1000.0 * Vin; // convert voltage to milli-volts
203  ScalarT r = 1000.0 * 3.8 / (1.0 + std::exp(-0.1*(vScaled+18.0)));
204  // result. the 1000 factor is to change from 1/ms to 1/s
205  return r;
206  }
207 
208  // a-current functions
209  template <typename ScalarT>
210  static ScalarT aInf( const ScalarT Vin)
211  {
212  ScalarT vScaled = 1000.0 * Vin; // convert voltage to milli-volts
213  ScalarT r = std::pow( ((0.0761 * std::exp(0.0314 * (vScaled+94.22))) / (1.0+std::exp(0.0346*(vScaled+1.17)))), 1.0/3.0);
214  return r;
215  }
216 
217  template <typename ScalarT>
218  static ScalarT aTau( const ScalarT Vin)
219  {
220  ScalarT vScaled = 1000.0 * Vin; // convert voltage to milli-volts
221  ScalarT r = (0.3632 + 1.158 / (1.0 + std::exp(0.0497 * (vScaled + 55.96)))) / 1000.0;
222  return r;
223  }
224 
225  template <typename ScalarT>
226  static ScalarT bInf( const ScalarT Vin)
227  {
228  ScalarT vScaled = 1000.0 * Vin; // convert voltage to milli-volts
229  ScalarT r = std::pow( (1.0 / (1.0 + std::exp(0.0688*(vScaled+53.3)))), 4.0);
230  return r;
231  }
232 
233  template <typename ScalarT>
234  static ScalarT bTau( const ScalarT Vin)
235  {
236  ScalarT vScaled = 1000.0 * Vin; // convert voltage to milli-volts
237  ScalarT r = (1.24 + 2.678 / (1.0 + std::exp(0.0624 * (vScaled + 50.0)))) / 1000.0;
238  return r;
239  }
240 
241  // transient calcium functions
242  template <typename ScalarT>
243  static ScalarT M_Inf( const ScalarT Vin)
244  {
245  ScalarT vScaled = 1000.0 * Vin; // convert voltage to milli-volts
246  ScalarT r = 1.0/(1.0 + std::exp(-(vScaled+57)/6.2));
247  return r;
248  }
249 
250  template <typename ScalarT>
251  static ScalarT M_Tau( const ScalarT Vin)
252  {
253  ScalarT vScaled = 1000.0 * Vin; // convert voltage to milli-volts
254  ScalarT r = (0.612 + 1.0/(std::exp(-(vScaled+132)/16.7) + std::exp((vScaled+16.8)/18.2)) ) / 1000.0;
255  return r;
256  }
257 
258  template <typename ScalarT>
259  static ScalarT H_Inf( const ScalarT Vin)
260  {
261  ScalarT vScaled = 1000.0 * Vin; // convert voltage to milli-volts
262  ScalarT r = 1.0 / (1.0 + std::exp((vScaled+81)/4.0));
263  return r;
264  }
265 
266  template <typename ScalarT>
267  static ScalarT H_Tau( const ScalarT Vin)
268  {
269  ScalarT vScaled = 1000.0 * Vin; // convert voltage to milli-volts
270  ScalarT r;
271  if( vScaled < -80.0 )
272  {
273  r = std::exp( (vScaled + 467)/66.6 ) / 1000.0;
274  }
275  else
276  {
277  r = ( 28.0 + std::exp(-(vScaled+22.0)/10.5)) / 1000.0;
278  }
279  return r;
280  }
281 
282  // Calcium dependent Potassium conductances
283  template <typename ScalarT>
284  static ScalarT C_Inf( const ScalarT Vin, const ScalarT CaConc)
285  {
286  ScalarT vScaled = 1000.0 * Vin; // convert voltage to milli-volts
287  ScalarT r = (CaConc / (CaConc + 3.0)) * (1.0 / (1.0 + std::exp(-(vScaled+28.3)/12.6 )));
288  return r;
289  }
290 
291  template <typename ScalarT>
292  static ScalarT C_Tau( const ScalarT Vin)
293  {
294  ScalarT vScaled = 1000.0 * Vin; // convert voltage to milli-volts
295  ScalarT r = (90.3 - 75.1/(1.0 + std::exp(-(vScaled+46)/22.7))) / 1000.0;
296  return r;
297  }
298 
299 
300  // now the device equations
301  // KCL equation 1
302  template <typename ScalarT>
303  static ScalarT kcl1EquF( const ScalarT& VSeg, const ScalarT& VSegP, const ScalarT & VSegN, const ScalarT& n, const ScalarT& m, const ScalarT& h,
304  const ScalarT& a, const ScalarT& b, const ScalarT& MC, const ScalarT& HC, const ScalarT& CC,
305  const ScalarT& gPrev, const ScalarT& gNext,
306  const ScalarT& memG, const ScalarT& restV, const ScalarT& Kg, const ScalarT& Ke, const ScalarT& NaG, const ScalarT& NaE,
307  const ScalarT& Ag, const ScalarT& Ae, const ScalarT& CaTg, const ScalarT& CaE, const ScalarT& KCaG)
308  {
309  ScalarT powN = n * n * n * n;
310  ScalarT powM = m * m * m;
311  ScalarT powA = a * a * a;
312  ScalarT powMC = MC * MC;
313  ScalarT powCC = CC * CC * CC * CC;
314  ScalarT r = memG * (VSeg - restV) + Kg * powN * (VSeg - Ke ) + NaG * powM * h * (VSeg - NaE )
315  + Ag * powA * b * (VSeg - Ae) + CaTg * powMC * HC * (VSeg - CaE) + KCaG * powCC * (VSeg - Ke) - gNext * (VSegN - VSeg) - gPrev * (VSegP - VSeg);
316  return r;
317  }
318 
319  template <typename ScalarT>
320  static ScalarT kcl1EquQ( const ScalarT& VSeg, const ScalarT& memC )
321  {
322  ScalarT r = memC * VSeg;
323  return r;
324  }
325 
326 #if 0
327  // KCL equation 2 -- -1 * equation 1 because of device symmetry
328  template <typename ScalarT>
329  static ScalarT kcl2EquF( const ScalarT& Vn1, const ScalarT& Vn2, const ScalarT& n, const ScalarT& m, const ScalarT& h,
330  const ScalarT& a, const ScalarT& b, const ScalarT& MC, const ScalarT& HC, const ScalarT& CC,
331  const ScalarT& memG, const ScalarT& restV, const ScalarT& Kg, const ScalarT& Ke, const ScalarT& NaG, const ScalarT& NaE,
332  const ScalarT& Ag, const ScalarT& Ae, const ScalarT& CaTg, const ScalarT& CaE, const ScalarT& KCaG)
333  {
334  ScalarT powN = n * n * n * n;
335  ScalarT powM = m * m * m;
336  ScalarT powA = a * a * a;
337  ScalarT powMC = MC * MC;
338  ScalarT powCC = CC * CC * CC * CC;
339  ScalarT r = -1.0 * (memG * (Vn1 - Vn2 - restV) + Kg * powN * (Vn1 - Vn2 - Ke ) + NaG * powM * h * (Vn1 - Vn2 - NaE )
340  + Ag * powA * b * (Vn1 - Vn2 - Ae) + CaTg * powMC * HC * (Vn1 - Vn2 - CaE) + KCaG * powCC * (Vn1 - Vn2 - Ke) );
341  return r;
342  }
343 
344  template <typename ScalarT>
345  static ScalarT kcl2EquQ( const ScalarT& Vn1, const ScalarT& Vn2, const ScalarT& memC )
346  {
347  ScalarT r = -1.0 * memC * (Vn1 - Vn2);
348  return r;
349  }
350 #endif
351 
352  // n conservation equation
353  template <typename ScalarT>
354  static ScalarT nEquF( const ScalarT& Vn1, const ScalarT& n, const ScalarT& Vrest )
355  {
356  ScalarT vDiff = Vn1; // - Vrest;
357  ScalarT alpha = alphaN<ScalarT>(vDiff);
358  ScalarT beta = betaN<ScalarT>(vDiff);
359  ScalarT r = (alpha + beta) * n - alpha;
360  return r;
361  }
362 
363  template <typename ScalarT>
364  static ScalarT nEquQ( const ScalarT& n )
365  {
366  ScalarT r = n;
367  return r;
368  }
369 
370  // m conservation equation
371  template <typename ScalarT>
372  static ScalarT mEquF( const ScalarT& Vn1, const ScalarT& m, const ScalarT& Vrest )
373  {
374  ScalarT vDiff = Vn1; // - Vrest;
375  ScalarT alpha = alphaM<ScalarT>(vDiff);
376  ScalarT beta = betaM<ScalarT>(vDiff);
377  ScalarT r = (alpha + beta) * m - alpha;
378  return r;
379  }
380 
381  template <typename ScalarT>
382  static ScalarT mEquQ( const ScalarT& m )
383  {
384  ScalarT r = m;
385  return r;
386  }
387 
388  // h conservation equation
389  template <typename ScalarT>
390  static ScalarT hEquF( const ScalarT& Vn1, const ScalarT& h, const ScalarT& Vrest )
391  {
392  ScalarT vDiff = Vn1; // - Vrest;
393  ScalarT alpha = alphaH<ScalarT>(vDiff);
394  ScalarT beta = betaH<ScalarT>(vDiff);
395  ScalarT r = (alpha + beta) * h - alpha;
396  return r;
397  }
398 
399  template <typename ScalarT>
400  static ScalarT hEquQ( const ScalarT& h )
401  {
402  ScalarT r = h;
403  return r;
404  }
405 
406  // a conservation equation
407  template <typename ScalarT>
408  static ScalarT aEquF( const ScalarT& Vn1, const ScalarT& a, const ScalarT& Vrest )
409  {
410  ScalarT vDiff = Vn1; // - Vrest;
411  ScalarT Inf = aInf<ScalarT>(vDiff);
412  ScalarT Tau = aTau<ScalarT>(vDiff);
413  ScalarT r = (a - Inf)/Tau;
414  return r;
415  }
416 
417  template <typename ScalarT>
418  static ScalarT aEquQ( const ScalarT& a )
419  {
420  ScalarT r = a;
421  return r;
422  }
423 
424  // b conservation equation
425  template <typename ScalarT>
426  static ScalarT bEquF( const ScalarT& Vn1, const ScalarT& b, const ScalarT& Vrest )
427  {
428  ScalarT vDiff = Vn1; // - Vrest;
429  ScalarT Inf = bInf<ScalarT>(vDiff);
430  ScalarT Tau = bTau<ScalarT>(vDiff);
431  ScalarT r = (b - Inf)/Tau;
432  return r;
433  }
434 
435  template <typename ScalarT>
436  static ScalarT bEquQ( const ScalarT& b )
437  {
438  ScalarT r = b;
439  return r;
440  }
441 
442  // M conservation equation
443  template <typename ScalarT>
444  static ScalarT M_EquF( const ScalarT& Vn1, const ScalarT& M, const ScalarT& Vrest )
445  {
446  ScalarT vDiff = Vn1; // - Vrest;
447  ScalarT Inf = M_Inf<ScalarT>(vDiff);
448  ScalarT Tau = M_Tau<ScalarT>(vDiff);
449  ScalarT r = (M - Inf)/Tau;
450  return r;
451  }
452 
453  template <typename ScalarT>
454  static ScalarT M_EquQ( const ScalarT& M )
455  {
456  ScalarT r = M;
457  return r;
458  }
459 
460  // H conservation equation
461  template <typename ScalarT>
462  static ScalarT H_EquF( const ScalarT& Vn1, const ScalarT& H, const ScalarT& Vrest )
463  {
464  ScalarT vDiff = Vn1; // - Vrest;
465  ScalarT Inf = H_Inf<ScalarT>(vDiff);
466  ScalarT Tau = H_Tau<ScalarT>(vDiff);
467  ScalarT r = (H - Inf)/Tau;
468  return r;
469  }
470 
471  template <typename ScalarT>
472  static ScalarT H_EquQ( const ScalarT& H )
473  {
474  ScalarT r = H;
475  return r;
476  }
477 
478  // C conservation equation
479  template <typename ScalarT>
480  static ScalarT C_EquF( const ScalarT& Vn1, const ScalarT& C, const ScalarT& CaConc, const ScalarT& Vrest )
481  {
482  ScalarT vDiff = Vn1; // - Vrest;
483  ScalarT Inf = C_Inf<ScalarT>(vDiff, CaConc);
484  ScalarT Tau = C_Tau<ScalarT>(vDiff);
485  ScalarT r = (C - Inf)/Tau;
486  return r;
487  }
488 
489  template <typename ScalarT>
490  static ScalarT C_EquQ( const ScalarT& C )
491  {
492  ScalarT r = C;
493  return r;
494  }
495 
496  // Calcium conservation equation
497  template <typename ScalarT>
498  static ScalarT Ca_EquF( const ScalarT& Vn1, const ScalarT& MC, const ScalarT& HC, const ScalarT& Ca,
499  const ScalarT& CaTg, const ScalarT& CaE, const ScalarT& CaGamma, const ScalarT& CaTau )
500  {
501  ScalarT r = CaGamma * CaTg * MC * MC * HC * (Vn1 - CaE) + Ca / CaTau;
502  return r;
503  }
504 
505  template <typename ScalarT>
506  static ScalarT Ca_EquQ( const ScalarT& Ca)
507  {
508  ScalarT r = Ca;
509  return r;
510  }
511 
512 public:
513  // iterator reference to the Neuron model which owns this instance.
514  // Getters and setters
516  {
517  return model_;
518  }
519 
520 private:
521 
522  Model & model_; //< Owning model
523 
524  // model level parameters that can be overridden at the instance level
525  double rInt; // intracellular resistivity
526  double radius; // Segment radius
527  double length; // cable length (segment length = length/nSeg)
528  double segArea; // segment area (derrived from radius, length and nSeg)
529  int nSeg; // number of segments
530  bool rIntGiven;
533  bool nSegGiven;
534 
535  // the cable equation is dependent on parameters from the previous and next segment of other
536  // cables attached to the input/ouput nodes (i.e. when we branch a cable). This lets
537  // one set the parameters for the previous/next cable segment.
538  double rIntPrevious;
541  double rIntNext;
542  double radiusNext;
543  double lengthNext;
550 
551  // conductance between segments -- calculated from radius, rInt and length and number of segments
552  // gBackward connects to previous node. gForward connects to the next node
553  std::vector<double> gBackward;
554  std::vector<double> gForward;
555 
556  // derrived quantities computed in updateIntermediateVars
557  // and used in the load functions (no q terms on the external nodes)
558  double kcl1Fvalue;
559  double kcl2Fvalue;
560  // internal segments
561  std::vector<double> segFvalue;
562  std::vector<double> segQvalue;
563  std::vector<double> segNEquFvalue, segNEquQvalue;
564  std::vector<double> segMEquFvalue, segMEquQvalue;
565  std::vector<double> segHEquFvalue, segHEquQvalue;
566  std::vector<double> segAEquFvalue, segAEquQvalue;
567  std::vector<double> segBEquFvalue, segBEquQvalue;
568  std::vector<double> segM_EquFvalue, segM_EquQvalue;
569  std::vector<double> segH_EquFvalue, segH_EquQvalue;
570  std::vector<double> segCEquFvalue, segCEquQvalue;
571  std::vector<double> segCaEquFvalue, segCaEquQvalue;
572 
573  // jacobian terms
576  // internal equations
578  std::vector<double> segQ_dV;
579  std::vector<double> dnF_dV, dnF_dn, dnQ_dn;
580  std::vector<double> dmF_dV, dmF_dm, dmQ_dm;
581  std::vector<double> dhF_dV, dhF_dh, dhQ_dh;
582  std::vector<double> daF_dV, daF_da, daQ_da;
583  std::vector<double> dbF_dV, dbF_db, dbQ_db;
584  std::vector<double> dMF_dV, dMF_dM, dMQ_dM;
585  std::vector<double> dHF_dV, dHF_dH, dHQ_dH;
586  std::vector<double> dcF_dV, dcF_dc, dcF_dCa, dcQ_dc;
587  std::vector<double> dCaF_dV, dCaF_dM, dCaF_dH, dCaF_dCa, dCaQ_dCa;
588 
589  // state variables
590  std::vector<double> potassiumCurrent;
591  std::vector<double> sodiumCurrent;
592 
593  // local state indices (offsets)
594  std::vector<int> li_KCurrentState;
595  std::vector<int> li_NaCurrentState;
596 
597  // local solution indices (offsets)
598  int li_Pos; // local index to positive node on this device
599  int li_Neg; // local index to negative node on this device
600  // local solution indices for internal vars (variable number of these)
601  std::vector<int> li_Vol; // local index to segment voltage
602  std::vector<int> li_nPro; // local index to n promoter value (Na current)
603  std::vector<int> li_mPro; // local index to m promoter value (K current)
604  std::vector<int> li_hPro; // local index to h promoter value (K current)
605  std::vector<int> li_aPro; // local index to a promoter value
606  std::vector<int> li_bPro; // local index to a promoter value
607  std::vector<int> li_MPro; // local index to a promoter value
608  std::vector<int> li_HPro; // local index to a promoter value
609  std::vector<int> li_cPro; // local index to a promoter value
610  std::vector<int> li_CaPro; // local index to a promoter value
611 
612  // Matrix equation index variables:
613 
614  // Offset variables corresponding to the above declared indices.
617  std::vector<int> SegVEqnVpreOffset;
618  std::vector<int> SegVEqnVsegOffset;
619  std::vector<int> SegVEqnVnexOffset;
620  std::vector<int> SegVEqnNOffset;
621  std::vector<int> SegVEqnMOffset;
622  std::vector<int> SegVEqnHOffset;
623  std::vector<int> SegVEqnAOffset;
624  std::vector<int> SegVEqnBOffset;
625  std::vector<int> SegVEqnM_Offset;
626  std::vector<int> SegVEqnH_Offset;
627  std::vector<int> SegVEqnCOffset;
628  std::vector<int> NEquVNodeOffset;
629  std::vector<int> NEquNNodeOffset;
630  std::vector<int> MEquVNodeOffset;
631  std::vector<int> MEquMNodeOffset;
632  std::vector<int> HEquVNodeOffset;
633  std::vector<int> HEquHNodeOffset;
634  std::vector<int> AEquVNodeOffset;
635  std::vector<int> AEquANodeOffset;
636  std::vector<int> BEquVNodeOffset;
637  std::vector<int> BEquBNodeOffset;
638  std::vector<int> M_EquVNodeOffset;
639  std::vector<int> M_EquM_NodeOffset;
640  std::vector<int> H_EquVNodeOffset;
641  std::vector<int> H_EquH_NodeOffset;
642  std::vector<int> CEquVNodeOffset;
643  std::vector<int> CEquCNodeOffset;
644  std::vector<int> CEquCaNodeOffset;
645  std::vector<int> CaEquVNodeOffset;
646  std::vector<int> CaEquM_NodeOffset;
647  std::vector<int> CaEquH_NodeOffset;
648  std::vector<int> CaEquCaNodeOffset;
649 
650  std::vector< std::vector<int> > jacStamp;
651 };
652 
653 //-----------------------------------------------------------------------------
654 // Class : Model
655 // Purpose :
656 // Special Notes :
657 // Creator : Richard Schiek, SNL, Electrical and Microsystem Modeling
658 // Creation Date : 06/10/09
659 //-----------------------------------------------------------------------------
660 class Model : public DeviceModel
661 {
662  typedef std::vector<Instance *> InstanceVector;
663 
664  friend class ParametricData<Model>;
665  friend class Instance;
666  friend class Traits;
667 
668 public:
669  Model(
670  const Configuration & configuration,
671  const ModelBlock & MB,
672  const FactoryBlock & factory_block);
673  ~Model();
674 
675 private:
676  Model();
677  Model(const Model &);
678  Model &operator=(const Model &);
679 
680 public:
681  virtual void forEachInstance(DeviceInstanceOp &op) const /* override */;
682 
683  virtual std::ostream &printOutInstances(std::ostream &os) const;
684 
685  bool processParams ();
686  bool processInstanceParams ();
687 
688 private:
689 
690  // parameter variables
691  double cMem; // membrane capacitance
692  double gMem; // membrane conductance
693  double vRest; // resting potential
694  double eNa; // sodium rest potential
695  double gNa; // sodium base conductance
696  double eK; // potassium rest potential
697  double gK; // potassium base conductance
698  double eA; // a-current rest potential
699  double gA; // a-current base conductance
700  double eCa; // Calcium rest potential
701  double gCa; // Calcium base conductance
702  double eKCa; // potassium-calcium rest potential
703  double gKCa; // potassium-calcium base conductance
704  double CaInit; // initial intra-cellular calcium concentration
705  double CaGamma; // calcium current to concentration multiplier
706  double CaTau; // calcium removal time constant
707  double rInt; // intracellular resistivity
708  double radius; // Segment radius
709  double length; // cable length (segment length = length/nSeg)
710  int nSeg; // number of segments
711 
712  // the cable equation is dependent on parameters from the previous and next segment of other
713  // cables attached to the input/ouput nodes (i.e. when we branch a cable). This lets
714  // one set the parameters for the previous/next cable segment.
715  double rIntPrevious;
718  double rIntNext;
719  double radiusNext;
720  double lengthNext;
727 
728  // flags that parameters were given
729  bool rIntGiven;
732  bool nSegGiven;
733 
734  // flags that parameters were given
735  bool cMemGiven;
736  bool gMemGiven;
738  bool eNaGiven;
739  bool gNaGiven;
740  bool eKGiven;
741  bool gKGiven;
742  bool eAGiven;
743  bool gAGiven;
744  bool eCaGiven;
745  bool gCaGiven;
746  bool eKCaGiven;
747  bool gKCaGiven;
751 
752 
753 public:
754  void addInstance(Instance *instance)
755  {
756  instanceContainer.push_back(instance);
757  }
758 
759 private:
760  std::vector<Instance*> instanceContainer;
761 };
762 
763 void registerDevice();
764 
765 } // namespace Neuron4
766 } // namespace Device
767 } // namespace Xyce
768 
769 #endif
static ScalarT bEquQ(const ScalarT &b)
std::vector< double > segHEquFvalue
bool updateTemperature(const double &temp_tmp)
std::vector< double > dmF_dV
std::vector< double > segBEquFvalue
std::vector< int > SegVEqnVsegOffset
std::vector< int > li_NaCurrentState
std::vector< double > dCaQ_dCa
std::vector< double > dCaF_dM
bool processInstanceParams()
processInstanceParams
static ScalarT bInf(const ScalarT Vin)
std::vector< double > dMF_dM
std::vector< double > segAEquFvalue
static ScalarT H_Inf(const ScalarT Vin)
std::vector< int > SegVEqnH_Offset
static ScalarT M_Tau(const ScalarT Vin)
std::vector< double > dnF_dn
std::vector< double > dcF_dV
std::vector< double > dnQ_dn
Pure virtual class to augment a linear system.
std::vector< int > li_KCurrentState
#define MC
std::vector< int > MEquVNodeOffset
std::vector< double > dcF_dc
std::vector< double > segF_dM
static ScalarT aTau(const ScalarT Vin)
std::vector< Instance * > instanceContainer
std::vector< double > segFvalue
std::vector< double > segH_EquFvalue
std::vector< double > gForward
static ScalarT M_EquQ(const ScalarT &M)
void registerStateLIDs(const std::vector< int > &staLIDVecRef)
static ScalarT nEquQ(const ScalarT &n)
std::vector< double > segF_dn
static ScalarT betaH(const ScalarT Vin)
std::vector< int > CEquCNodeOffset
std::vector< double > dhF_dV
virtual std::ostream & printOutInstances(std::ostream &os) const
std::vector< int > HEquHNodeOffset
std::vector< int > CaEquVNodeOffset
std::vector< double > dbQ_db
std::vector< int > BEquBNodeOffset
std::vector< double > dcF_dCa
std::vector< double > segM_EquQvalue
std::vector< double > segQ_dV
std::vector< int > CaEquCaNodeOffset
Instance(const Configuration &configuration, const InstanceBlock &IB, Model &Miter, const FactoryBlock &factory_block)
std::vector< int > CaEquM_NodeOffset
std::vector< double > dmQ_dm
std::vector< int > M_EquM_NodeOffset
std::vector< double > dHF_dV
virtual void forEachInstance(DeviceInstanceOp &op) const
Apply a device instance "op" to all instances associated with this model.
std::vector< int > MEquMNodeOffset
std::vector< double > dmF_dm
std::vector< int > SegVEqnBOffset
std::vector< double > dCaF_dCa
static ScalarT H_Tau(const ScalarT Vin)
std::vector< int > NEquVNodeOffset
const std::vector< std::vector< int > > & jacobianStamp() const
std::vector< double > segF_dc
static ScalarT mEquQ(const ScalarT &m)
static ScalarT C_EquQ(const ScalarT &C)
std::vector< double > segNEquQvalue
The FactoryBlock contains parameters needed by the device, instance and model creation functions...
std::vector< double > potassiumCurrent
std::vector< double > segMEquFvalue
static ScalarT betaM(const ScalarT Vin)
static ScalarT alphaM(const ScalarT Vin)
static ScalarT C_Tau(const ScalarT Vin)
static ScalarT hEquQ(const ScalarT &h)
std::vector< double > gBackward
static ScalarT aEquF(const ScalarT &Vn1, const ScalarT &a, const ScalarT &Vrest)
std::vector< double > segF_dh
std::vector< double > segF_db
void varTypes(std::vector< char > &varTypeVec)
static ScalarT bEquF(const ScalarT &Vn1, const ScalarT &b, const ScalarT &Vrest)
std::vector< double > segMEquQvalue
std::vector< int > SegVEqnAOffset
static ScalarT C_Inf(const ScalarT Vin, const ScalarT CaConc)
std::vector< double > dMF_dV
std::vector< double > segF_dVn
static ScalarT bTau(const ScalarT Vin)
std::vector< double > dCaF_dH
std::vector< double > dbF_dV
std::vector< double > segF_dH
std::vector< int > SegVEqnM_Offset
std::vector< double > daF_dV
static ScalarT M_Inf(const ScalarT Vin)
static ScalarT H_EquQ(const ScalarT &H)
std::vector< double > segF_dVp
static ScalarT aEquQ(const ScalarT &a)
The Device class is an interface for device implementations.
Definition: N_DEV_Device.h:101
std::vector< Instance * > InstanceVector
static ScalarT kcl1EquQ(const ScalarT &VSeg, const ScalarT &memC)
static ScalarT betaN(const ScalarT Vin)
std::vector< double > segF_dV
std::vector< int > M_EquVNodeOffset
void loadNodeSymbols(Util::SymbolTable &symbol_table) const
Populates and returns the store name map.
std::vector< double > dMQ_dM
static ScalarT alphaH(const ScalarT Vin)
std::vector< double > dnF_dV
std::vector< double > segF_dm
Class Configuration contains device configuration data.
static ScalarT mEquF(const ScalarT &Vn1, const ScalarT &m, const ScalarT &Vrest)
std::vector< double > segBEquQvalue
std::vector< int > CEquVNodeOffset
std::vector< double > segH_EquQvalue
std::vector< double > daQ_da
std::vector< int > H_EquVNodeOffset
std::vector< int > AEquANodeOffset
#define M
std::vector< int > SegVEqnVnexOffset
std::vector< double > dhQ_dh
static ScalarT kcl2EquQ(const ScalarT &Vn1, const ScalarT &Vn2, const ScalarT &memC)
std::vector< double > segCaEquQvalue
static void loadInstanceParameters(ParametricData< Instance > &instance_parameters)
Definition: N_DEV_Neuron4.C:76
std::vector< double > segNEquFvalue
std::vector< int > SegVEqnCOffset
Model & operator=(const Model &)
std::vector< double > dHF_dH
static ScalarT C_EquF(const ScalarT &Vn1, const ScalarT &C, const ScalarT &CaConc, const ScalarT &Vrest)
Instance & operator=(const Instance &)
void registerJacLIDs(const std::vector< std::vector< int > > &jacLIDVec)
static ScalarT nEquF(const ScalarT &Vn1, const ScalarT &n, const ScalarT &Vrest)
std::vector< double > daF_da
static ScalarT aInf(const ScalarT Vin)
std::vector< double > segCEquQvalue
static ScalarT Ca_EquF(const ScalarT &Vn1, const ScalarT &MC, const ScalarT &HC, const ScalarT &Ca, const ScalarT &CaTg, const ScalarT &CaE, const ScalarT &CaGamma, const ScalarT &CaTau)
static Device * factory(const Configuration &configuration, const FactoryBlock &factory_block)
static ScalarT alphaN(const ScalarT Vin)
std::vector< double > segAEquQvalue
std::vector< double > sodiumCurrent
std::vector< int > SegVEqnMOffset
std::vector< int > SegVEqnVpreOffset
std::vector< int > CEquCaNodeOffset
std::vector< double > dhF_dh
std::vector< int > AEquVNodeOffset
static ScalarT kcl1EquF(const ScalarT &VSeg, const ScalarT &VSegP, const ScalarT &VSegN, const ScalarT &n, const ScalarT &m, const ScalarT &h, const ScalarT &a, const ScalarT &b, const ScalarT &MC, const ScalarT &HC, const ScalarT &CC, const ScalarT &gPrev, const ScalarT &gNext, const ScalarT &memG, const ScalarT &restV, const ScalarT &Kg, const ScalarT &Ke, const ScalarT &NaG, const ScalarT &NaE, const ScalarT &Ag, const ScalarT &Ae, const ScalarT &CaTg, const ScalarT &CaE, const ScalarT &KCaG)
std::vector< int > SegVEqnHOffset
static ScalarT kcl2EquF(const ScalarT &Vn1, const ScalarT &Vn2, const ScalarT &n, const ScalarT &m, const ScalarT &h, const ScalarT &a, const ScalarT &b, const ScalarT &MC, const ScalarT &HC, const ScalarT &CC, const ScalarT &memG, const ScalarT &restV, const ScalarT &Kg, const ScalarT &Ke, const ScalarT &NaG, const ScalarT &NaE, const ScalarT &Ag, const ScalarT &Ae, const ScalarT &CaTg, const ScalarT &CaE, const ScalarT &KCaG)
std::vector< double > dHQ_dH
std::vector< double > segM_EquFvalue
ModelBlock represents a .MODEL line from the netlist.
std::vector< std::vector< int > > jacStamp
The DeviceTraits template describes the configuration of a device.
static const char * deviceTypeName()
Definition: N_DEV_Neuron4.h:69
Manages parameter binding for class C.
Definition: N_DEV_Pars.h:214
std::vector< int > HEquVNodeOffset
InstanceBlock represent a device instance line from the netlist.
static ScalarT M_EquF(const ScalarT &Vn1, const ScalarT &M, const ScalarT &Vrest)
static const char * name()
Definition: N_DEV_Neuron4.h:68
std::vector< double > dCaF_dV
static ScalarT H_EquF(const ScalarT &Vn1, const ScalarT &H, const ScalarT &Vrest)
static ScalarT Ca_EquQ(const ScalarT &Ca)
std::vector< double > segQvalue
std::vector< double > segCaEquFvalue
std::vector< int > H_EquH_NodeOffset
std::vector< double > segHEquQvalue
static void loadModelParameters(ParametricData< Model > &model_parameters)
std::vector< double > segCEquFvalue
std::vector< int > BEquVNodeOffset
static ScalarT hEquF(const ScalarT &Vn1, const ScalarT &h, const ScalarT &Vrest)
std::vector< int > CaEquH_NodeOffset
void addInstance(Instance *instance)
std::vector< int > SegVEqnNOffset
bool processParams()
processParams
void registerLIDs(const std::vector< int > &intLIDVecRef, const std::vector< int > &extLIDVecRef)
std::vector< double > segF_da
std::vector< double > dbF_db
std::vector< int > NEquNNodeOffset
std::vector< double > dcQ_dc