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