Xyce  6.1
N_DEV_Neuron9.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: N_DEV_Neuron9.h,v $
27 //
28 // Purpose : Neuron classes.
29 //
30 // Special Notes :
31 //
32 // Creator : Christy Warrender, SNL, Cognitive Modeling
33 //
34 // Creation Date : 06/22/12
35 //
36 // Revision Information:
37 // ---------------------
38 //
39 // Revision Number: $Revision: 1.29 $
40 //
41 // Revision Date : $Date: 2015/04/08 19:18:23 $
42 //
43 // Current Owner : $Author: tvrusso $
44 //-----------------------------------------------------------------------------
45 
46 #ifndef Xyce_N_DEV_Neuron9_h
47 #define Xyce_N_DEV_Neuron9_h
48 
49 #include <N_DEV_Configuration.h>
50 #include <Sacado.hpp>
51 
52 // ---------- Xyce Includes ----------
53 #include <N_DEV_DeviceMaster.h>
54 #include <N_DEV_DeviceBlock.h>
55 #include <N_DEV_DeviceInstance.h>
56 #include <N_DEV_DeviceModel.h>
57 
58 #include <N_DEV_Neuron.h>
59 
60 namespace Xyce {
61 namespace Device {
62 namespace Neuron9 {
63 
64 class Model;
65 class Instance;
66 
67 struct Traits : public DeviceTraits<Model, Instance, Neuron::Traits>
68 {
69  static const char *name() {return "Neuron";}
70  static const char *deviceTypeName() {return "YNEURON level 9";}
71  static int numNodes() {return 2;}
72  static bool modelRequired() {return true;}
73  static bool isLinearDevice() {return true;}
74 
75  static Device *factory(const Configuration &configuration, const FactoryBlock &factory_block);
76  static void loadModelParameters(ParametricData<Model> &model_parameters);
77  static void loadInstanceParameters(ParametricData<Instance> &instance_parameters);
78 };
79 
80 //-----------------------------------------------------------------------------
81 // Class : Instance
82 // Purpose : This is class refers to a single instance of the
83 // Neuron device. It has two nodes associated with it, a
84 // positive and a negative node. See the NeuronInstance
85 // class for a more detailed explanation.
86 // Special Notes :
87 // Creator : Christy Warrender, SNL, Cognitive Modeling
88 // Creation Date : 06/22/12
89 //-----------------------------------------------------------------------------
90 class Instance : public DeviceInstance
91 {
92  friend class ParametricData<Instance>;
93  friend class Model;
94  friend class Traits;friend class Master;
95 
96 public:
97  static std::vector< std::vector<int> > jacStamp;
98 
99  Instance(
100  const Configuration & configuration,
101  const InstanceBlock & IB,
102  Model & Miter,
103  const FactoryBlock & factory_block);
104 
105 
106  ~Instance();
107 
108 private:
109  Instance(const Instance &);
110  Instance &operator=(const Instance &);
111 
112 public:
113  void registerLIDs( const std::vector<int> & intLIDVecRef,
114  const std::vector<int> & extLIDVecRef );
115  void registerStateLIDs( const std::vector<int> & staLIDVecRef );
116 
117  void loadNodeSymbols(Util::SymbolTable &symbol_table) const; // override
118 
119  const std::vector< std::vector<int> > & jacobianStamp() const;
120  void registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec );
121 
122  bool processParams ();
123  bool updateTemperature(const double & temp_tmp);
124 
125  bool updateIntermediateVars ();
126  bool updatePrimaryState ();
127  bool updateSecondaryState ();
128  bool setIC ();
129 
130  void varTypes( std::vector<char> & varTypeVec );
131 
132  // load functions, residual:
133  bool loadDAEQVector ();
134  bool loadDAEFVector ();
135 
136  void auxDAECalculations ();
137 
138  // load functions, Jacobian:
139  bool loadDAEdQdx ();
140  bool loadDAEdFdx ();
141 
142 private:
143  // These functions represent the equations that need to be solved
144  // for this device. Since Xyce loads an F and Q contribution, the
145  // equations are broken up into their F and Q components. Thus there
146  // is a kcl1EquF() and kcl1EquQ(). Automatic differentiation will
147  // be used to generate all the derivatives of these equations for the
148  // dF/dX and dQ/dX loads
149 
150  // first we list some utility functions for calculating coefficients.
151  // alpha and beta equations are taken from Brette et al 07.
152  // They're generally functions of membrane voltage; here, the membrane voltage is
153  // the difference between Vn1 and Vn2.
154  // These functions expect V to be in milli-volts and then return values that
155  // are in 1/ms. Thus the extra factor's of 1000 here and there
156 
157  // potassium current, functions for activator equation
158  template <typename ScalarT>
159  static ScalarT alphaN( const ScalarT & Vn1, const ScalarT & Vn2, const ScalarT & Vrest)
160  {
161  ScalarT vDiff = 1000.0 * (Vn1 - Vn2); // convert voltage to milli-volts
162  ScalarT r;
163  r = 0.032*(15.0 - vDiff + VT)/( std::exp( (15.0 - vDiff + VT)/5.0) - 1.0);
164  r *= 1000.0; // change from 1/ms to 1/s
165  return r;
166  }
167 
168  template <typename ScalarT>
169  static ScalarT betaN( const ScalarT & Vn1, const ScalarT & Vn2, const ScalarT & Vrest)
170  {
171  ScalarT vDiff = 1000.0 * (Vn1 - Vn2); // convert voltage to milli-volts
172  ScalarT r;
173  r = 0.5*( std::exp( (10.0 - vDiff + VT)/40.0) );
174  r *= 1000.0; // change from 1/ms to 1/s
175  return r;
176  }
177 
178  // sodium current, functions for activator equation
179  template <typename ScalarT>
180  static ScalarT alphaM( const ScalarT & Vn1, const ScalarT & Vn2, const ScalarT & Vrest)
181  {
182  ScalarT vDiff = 1000.0 * (Vn1 - Vn2); // convert voltage to milli-volts
183  ScalarT r;
184  r = 0.32*(13.0 - vDiff + VT )/( std::exp((13.0 - vDiff + VT )/4.0) - 1.0);
185  r *= 1000.0; // change from 1/ms to 1/s
186  return r;
187  }
188 
189  template <typename ScalarT>
190  static ScalarT betaM( const ScalarT & Vn1, const ScalarT & Vn2, const ScalarT & Vrest)
191  {
192  ScalarT vDiff = 1000.0 * (Vn1 - Vn2); // convert voltage to milli-volts
193  ScalarT r;
194  r = 0.28*(vDiff - VT - 40.0)/( std::exp((vDiff - VT - 40.0)/5.0) - 1.0);
195  r *= 1000.0; // change from 1/ms to 1/s
196  return r;
197  }
198 
199  template <typename ScalarT>
200  static ScalarT alphaH( const ScalarT & Vn1, const ScalarT & Vn2, const ScalarT & Vrest)
201  {
202  ScalarT vDiff = 1000.0 * (Vn1 - Vn2); // convert voltage to milli-volts
203  ScalarT r;
204  r = 0.128 * std::exp( (17.0 - vDiff + VT)/18.0 );
205  r *= 1000.0; // change from 1/ms to 1/s
206  return r;
207  }
208 
209  template <typename ScalarT>
210  static ScalarT betaH( const ScalarT & Vn1, const ScalarT & Vn2, const ScalarT & Vrest)
211  {
212  ScalarT vDiff = 1000.0 * (Vn1 - Vn2); // convert voltage to milli-volts
213  ScalarT r;
214  r = 4.0/( 1.0 + std::exp( (40.0 - vDiff + VT)/5.0) );
215  r *= 1000.0; // change from 1/ms to 1/s
216  return r;
217  }
218 
219  // now the device equations
220  // KCL equation 1
221  template <typename ScalarT>
222  static ScalarT kcl1EquF( const ScalarT& Vn1, const ScalarT& Vn2, const ScalarT& n, const ScalarT& m, const ScalarT& h,
223  const ScalarT& memG, const ScalarT& leakE, const ScalarT& Kg, const ScalarT& Ke, const ScalarT& NaG, const ScalarT& NaE )
224  {
225  ScalarT powN = n * n * n * n;
226  ScalarT powM = m * m * m;
227  ScalarT r = memG * (Vn1 - Vn2 - leakE) + Kg * powN * (Vn1 - Vn2 - Ke ) + NaG * powM * h * (Vn1 - Vn2 - NaE );
228  return r;
229  }
230 
231  template <typename ScalarT>
232  static ScalarT kcl1EquQ( const ScalarT& Vn1, const ScalarT& Vn2, const ScalarT& memC )
233  {
234  ScalarT r = memC * (Vn1 - Vn2);
235  return r;
236  }
237 
238  // KCL equation 2 -- -1 * equation 1 because of device symmetry
239  template <typename ScalarT>
240  static ScalarT kcl2EquF( const ScalarT& Vn1, const ScalarT& Vn2, const ScalarT& n, const ScalarT& m, const ScalarT& h,
241  const ScalarT& memG, const ScalarT& leakE, const ScalarT& Kg, const ScalarT& Ke, const ScalarT& NaG, const ScalarT& NaE )
242  {
243  ScalarT powN = n * n * n * n;
244  ScalarT powM = m * m * m;
245  ScalarT r = -1.0*(memG * (Vn1 - Vn2 - leakE) + Kg * powN * (Vn1 - Vn2 - Ke ) + NaG * powM * h * (Vn1 - Vn2 - NaE ));
246  return r;
247  }
248 
249  template <typename ScalarT>
250  static ScalarT kcl2EquQ( const ScalarT& Vn1, const ScalarT& Vn2, const ScalarT& memC )
251  {
252  ScalarT r = -1.0 * memC * (Vn1 - Vn2);
253  return r;
254  }
255 
256  // n conservation equation
257  template <typename ScalarT>
258  static ScalarT nEquF( const ScalarT& Vn1, const ScalarT& Vn2, const ScalarT& n, const ScalarT& Vrest )
259  {
260  ScalarT r = alphaN<ScalarT>( Vn1, Vn2, Vrest ) * (1.0 - n ) - betaN<ScalarT>( Vn1, Vn2, Vrest ) * n;
261  return r;
262  }
263 
264  template <typename ScalarT>
265  static ScalarT nEquQ( const ScalarT& n )
266  {
267  ScalarT r = -n;
268  return r;
269  }
270 
271  // m conservation equation
272  template <typename ScalarT>
273  static ScalarT mEquF( const ScalarT& Vn1, const ScalarT& Vn2, const ScalarT& m, const ScalarT& Vrest )
274  {
275  ScalarT r = alphaM<ScalarT>( Vn1, Vn2, Vrest ) * (1.0 - m ) - betaM<ScalarT>( Vn1, Vn2, Vrest ) * m;
276  return r;
277  }
278 
279  template <typename ScalarT>
280  static ScalarT mEquQ( const ScalarT& m )
281  {
282  ScalarT r = -m;
283  return r;
284  }
285 
286  // h conservation equation
287  template <typename ScalarT>
288  static ScalarT hEquF( const ScalarT& Vn1, const ScalarT& Vn2, const ScalarT& h, const ScalarT& Vrest )
289  {
290  ScalarT r = alphaH<ScalarT>( Vn1, Vn2, Vrest ) * (1.0 - h ) - betaH<ScalarT>( Vn1, Vn2, Vrest ) * h;
291  return r;
292  }
293 
294  template <typename ScalarT>
295  static ScalarT hEquQ( const ScalarT& h )
296  {
297  ScalarT r = -h;
298  return r;
299  }
300 
301 public:
302  // iterator reference to the Neuron model which owns this instance.
303  // Getters and setters
305  {
306  return model_;
307  }
308 
309 private:
310 
311  Model & model_; //< Owning model
312 
313  // constant threshold adjustment
314  static const double VT;
315 
316  // derrived quantities computed in updateIntermediateVars
317  // and used in the load functions
328 
329  // state variables
332 
333  // local state indices (offsets)
336 
337  // local solution indices (offsets)
338  int li_Pos; // local index to positive node on this device
339  int li_Neg; // local index to negative node on this device
340  int li_nPro; // local index to n promoter value (Na current)
341  int li_mPro; // local index to m promoter value (K current)
342  int li_hPro; // local index to h promoter value (K current)
343 
344  // Matrix equation index variables:
345 
346  // Offset variables corresponding to the above declared indices.
352 
358 
362 
366 
370 };
371 
372 //-----------------------------------------------------------------------------
373 // Class : Model
374 // Purpose :
375 // Special Notes :
376 // Creator : Christy Warrender, SNL, Cognitive Modeling
377 // Creation Date : 06/22/12
378 //-----------------------------------------------------------------------------
379 class Model : public DeviceModel
380 {
381  typedef std::vector<Instance *> InstanceVector;
382 
383  friend class ParametricData<Model>;
384  friend class Instance;
385  friend class Traits;
386 
387 public:
388  Model(
389  const Configuration & configuration,
390  const ModelBlock & MB,
391  const FactoryBlock & factory_block);
392  ~Model();
393 
394 private:
395  Model();
396  Model(const Model &);
397  Model &operator=(const Model &);
398 
399 public:
400  virtual void forEachInstance(DeviceInstanceOp &op) const /* override */;
401 
402  virtual std::ostream &printOutInstances(std::ostream &os) const;
403 
404  bool processParams ();
405  bool processInstanceParams ();
406 
407 private:
408 
409  // parameter variables
410  double cMem; // membrane capacitance
411  double gMem; // membrane conductance of leak current
412  double eLeak; // reversal potential of leak current
413  double eNa; // sodium reversal potential
414  double gNa; // sodium base conductance
415  double eK; // potassium reversal potential
416  double gK; // potassium base conductance
417  double vRest; // resting potential
418 
419  // flags that parameters were given
420  bool cMemGiven;
421  bool gMemGiven;
423  bool eNaGiven;
424  bool gNaGiven;
425  bool eKGiven;
426  bool gKGiven;
428 
429 
430 public:
431  void addInstance(Instance *instance)
432  {
433  instanceContainer.push_back(instance);
434  }
435 
436 private:
437  std::vector<Instance*> instanceContainer;
438 };
439 
440 
441 //-----------------------------------------------------------------------------
442 // Class : Master
443 // Purpose :
444 // Special Notes :
445 // Creator : Christy Warrender, SNL, Cognitive Modeling
446 // Creation Date : 06/01/12
447 //-----------------------------------------------------------------------------
448 class Master : public DeviceMaster<Traits>
449 {
450 public:
452  const Configuration & configuration,
453  const FactoryBlock & factory_block,
454  const SolverState & ss1,
455  const DeviceOptions & do1)
456  : DeviceMaster<Traits>(configuration, factory_block, ss1, do1)
457  {}
458 
459  virtual bool updateState (double * solVec, double * staVec, double * stoVec);
460 };
461 
462 void registerDevice();
463 
464 } // namespace Neuron9
465 } // namespace Device
466 } // namespace Xyce
467 
468 #endif
static ScalarT betaM(const ScalarT &Vn1, const ScalarT &Vn2, const ScalarT &Vrest)
bool processParams()
processParams
static ScalarT nEquF(const ScalarT &Vn1, const ScalarT &Vn2, const ScalarT &n, const ScalarT &Vrest)
void addInstance(Instance *instance)
static ScalarT hEquF(const ScalarT &Vn1, const ScalarT &Vn2, const ScalarT &h, const ScalarT &Vrest)
Pure virtual class to augment a linear system.
void loadNodeSymbols(Util::SymbolTable &symbol_table) const
Populates and returns the store name map.
virtual void forEachInstance(DeviceInstanceOp &op) const
Apply a device instance "op" to all instances associated with this model.
static Device * factory(const Configuration &configuration, const FactoryBlock &factory_block)
static ScalarT kcl1EquF(const ScalarT &Vn1, const ScalarT &Vn2, const ScalarT &n, const ScalarT &m, const ScalarT &h, const ScalarT &memG, const ScalarT &leakE, const ScalarT &Kg, const ScalarT &Ke, const ScalarT &NaG, const ScalarT &NaE)
Master(const Configuration &configuration, const FactoryBlock &factory_block, const SolverState &ss1, const DeviceOptions &do1)
static const char * deviceTypeName()
Definition: N_DEV_Neuron9.h:70
static const char * name()
Definition: N_DEV_Neuron9.h:69
static ScalarT kcl1EquQ(const ScalarT &Vn1, const ScalarT &Vn2, const ScalarT &memC)
Instance(const Configuration &configuration, const InstanceBlock &IB, Model &Miter, const FactoryBlock &factory_block)
bool processInstanceParams()
processInstanceParams
DeviceMaster instantiates a device as described by the device traits T.
void registerJacLIDs(const std::vector< std::vector< int > > &jacLIDVec)
The FactoryBlock contains parameters needed by the device, instance and model creation functions...
static ScalarT mEquQ(const ScalarT &m)
virtual bool updateState(double *solVec, double *staVec, double *stoVec)
Updates the devices state information.
static void loadInstanceParameters(ParametricData< Instance > &instance_parameters)
Definition: N_DEV_Neuron9.C:73
static ScalarT betaN(const ScalarT &Vn1, const ScalarT &Vn2, const ScalarT &Vrest)
static void loadModelParameters(ParametricData< Model > &model_parameters)
Definition: N_DEV_Neuron9.C:77
virtual std::ostream & printOutInstances(std::ostream &os) const
Model & operator=(const Model &)
static ScalarT hEquQ(const ScalarT &h)
static ScalarT nEquQ(const ScalarT &n)
The Device class is an interface for device implementations.
Definition: N_DEV_Device.h:101
std::vector< Instance * > instanceContainer
Class Configuration contains device configuration data.
Instance & operator=(const Instance &)
std::vector< Instance * > InstanceVector
void registerStateLIDs(const std::vector< int > &staLIDVecRef)
static ScalarT kcl2EquF(const ScalarT &Vn1, const ScalarT &Vn2, const ScalarT &n, const ScalarT &m, const ScalarT &h, const ScalarT &memG, const ScalarT &leakE, const ScalarT &Kg, const ScalarT &Ke, const ScalarT &NaG, const ScalarT &NaE)
static ScalarT alphaM(const ScalarT &Vn1, const ScalarT &Vn2, const ScalarT &Vrest)
static ScalarT kcl2EquQ(const ScalarT &Vn1, const ScalarT &Vn2, const ScalarT &memC)
bool updateTemperature(const double &temp_tmp)
static ScalarT mEquF(const ScalarT &Vn1, const ScalarT &Vn2, const ScalarT &m, const ScalarT &Vrest)
static ScalarT alphaN(const ScalarT &Vn1, const ScalarT &Vn2, const ScalarT &Vrest)
const std::vector< std::vector< int > > & jacobianStamp() const
void varTypes(std::vector< char > &varTypeVec)
static std::vector< std::vector< int > > jacStamp
Definition: N_DEV_Neuron9.h:97
ModelBlock represents a .MODEL line from the netlist.
The DeviceTraits template describes the configuration of a device.
static ScalarT alphaH(const ScalarT &Vn1, const ScalarT &Vn2, const ScalarT &Vrest)
Manages parameter binding for class C.
Definition: N_DEV_Pars.h:214
InstanceBlock represent a device instance line from the netlist.
void registerLIDs(const std::vector< int > &intLIDVecRef, const std::vector< int > &extLIDVecRef)
static ScalarT betaH(const ScalarT &Vn1, const ScalarT &Vn2, const ScalarT &Vrest)