Xyce  6.1
N_DEV_Neuron6.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_Neuron6.h,v $
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: 1.39 $
40 //
41 // Revision Date : $Date: 2015/04/08 19:18:23 $
42 //
43 // Current Owner : $Author: tvrusso $
44 //-----------------------------------------------------------------------------
45 
46 #ifndef Xyce_N_DEV_Neuron6_h
47 #define Xyce_N_DEV_Neuron6_h
48 
49 #include <N_DEV_Configuration.h>
50 #include <N_DEV_DeviceBlock.h>
51 #include <N_DEV_DeviceInstance.h>
52 #include <N_DEV_DeviceModel.h>
53 #include <N_DEV_MembraneModel.h>
54 
55 #include <N_DEV_Neuron.h>
56 
57 #include <Teuchos_RCP.hpp>
58 using Teuchos::RCP;
59 
60 namespace Xyce {
61 namespace Device {
62 namespace Neuron6 {
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 6";}
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 : Richard Schiek, SNL, Electrical and Microsystem Modeling
88 // Creation Date : 06/10/09
89 //-----------------------------------------------------------------------------
90 class Instance : public DeviceInstance
91 {
92  friend class ParametricData<Instance>;
93  friend class Model;
94  friend class Traits;
95 
96 public:
97 
98  Instance(
99  const Configuration & configuration,
100  const InstanceBlock & IB,
101  Model & Miter,
102  const FactoryBlock & factory_block);
103 
104  ~Instance();
105 
106 private:
107  Instance(const Instance &);
108  Instance &operator=(const Instance &);
109 
110 public:
111  void registerLIDs( const std::vector<int> & intLIDVecRef,
112  const std::vector<int> & extLIDVecRef );
113  void registerStateLIDs( const std::vector<int> & staLIDVecRef );
114 
115  void loadNodeSymbols(Util::SymbolTable &symbol_table) const; // override
116 
117  const std::vector< std::vector<int> > & jacobianStamp() const;
118  void registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec );
119 
120  bool processParams ();
121  bool updateTemperature(const double & temp_tmp);
122 
123  bool updateIntermediateVars ();
124  bool updatePrimaryState ();
125  bool updateSecondaryState ();
126  bool setIC ();
127 
128  void varTypes( std::vector<char> & varTypeVec );
129 
130  // load functions, residual:
131  bool loadDAEQVector ();
132  bool loadDAEFVector ();
133 
134  void auxDAECalculations ();
135 
136  // load functions, Jacobian:
137  bool loadDAEdQdx ();
138  bool loadDAEdFdx ();
139 
140 public:
141  // iterator reference to the Neuron model which owns this instance.
142  // Getters and setters
144  {
145  return model_;
146  }
147 
148 private:
149 
150  Model & model_; //< Owning model
151 
152  // model level parameters that can be overridden at the instance level
153  double rInt; // intracellular resistivity
154  double radius; // Segment radius
155  double length; // cable length (segment length = length/nSeg)
156  double segArea; // segment area (derrived from radius, length and nSeg)
157  int nSeg; // number of segments
158  bool rIntGiven;
161  bool nSegGiven;
162 
163  // conductance between segments -- calculated from radius, rInt and length and number of segments
164  double gSeg;
165 
168 
169  // storage for local ID's of internal vars and jacobian offsets
170  std::vector< int > li_internalVars;
171  std::vector< std::vector< int > > jacobianOffsets;
172 
173  // derrived quantities computed in updateIntermediateVars
174  // and used in the load functions (no q terms on the external nodes)
175  double kcl1Fvalue;
176  double kcl2Fvalue;
177  // internal segments
178  std::vector<double> segFvalue;
179  std::vector<double> segQvalue;
180  std::vector<double> segNEquFvalue, segNEquQvalue;
181  std::vector<double> segMEquFvalue, segMEquQvalue;
182  std::vector<double> segHEquFvalue, segHEquQvalue;
183  std::vector<double> segAEquFvalue, segAEquQvalue;
184  std::vector<double> segBEquFvalue, segBEquQvalue;
185  std::vector<double> segM_EquFvalue, segM_EquQvalue;
186  std::vector<double> segH_EquFvalue, segH_EquQvalue;
187  std::vector<double> segCEquFvalue, segCEquQvalue;
188  std::vector<double> segCaEquFvalue, segCaEquQvalue;
189 
190  // jacobian terms
193  // internal equations
195  std::vector<double> segQ_dV;
196  std::vector<double> dnF_dV, dnF_dn, dnQ_dn;
197  std::vector<double> dmF_dV, dmF_dm, dmQ_dm;
198  std::vector<double> dhF_dV, dhF_dh, dhQ_dh;
199  std::vector<double> daF_dV, daF_da, daQ_da;
200  std::vector<double> dbF_dV, dbF_db, dbQ_db;
201  std::vector<double> dMF_dV, dMF_dM, dMQ_dM;
202  std::vector<double> dHF_dV, dHF_dH, dHQ_dH;
203  std::vector<double> dcF_dV, dcF_dc, dcF_dCa, dcQ_dc;
204  std::vector<double> dCaF_dV, dCaF_dM, dCaF_dH, dCaF_dCa, dCaQ_dCa;
205 
206  // state variables
207  std::vector<double> potassiumCurrent;
208  std::vector<double> sodiumCurrent;
209 
210  // local state indices (offsets)
211  std::vector<int> li_KCurrentState;
212  std::vector<int> li_NaCurrentState;
213 
214  // local solution indices (offsets)
215  int li_Pos; // local index to positive node on this device
216  int li_Neg; // local index to negative node on this device
217  // local solution indices for internal vars (variable number of these)
218  std::vector<int> li_Vol; // local index to segment voltage
219  std::vector<int> li_nPro; // local index to n promoter value (Na current)
220  std::vector<int> li_mPro; // local index to m promoter value (K current)
221  std::vector<int> li_hPro; // local index to h promoter value (K current)
222  std::vector<int> li_aPro; // local index to a promoter value
223  std::vector<int> li_bPro; // local index to a promoter value
224  std::vector<int> li_MPro; // local index to a promoter value
225  std::vector<int> li_HPro; // local index to a promoter value
226  std::vector<int> li_cPro; // local index to a promoter value
227  std::vector<int> li_CaPro; // local index to a promoter value
228 
229  // Matrix equation index variables:
230 
231  // Offset variables corresponding to the above declared indices.
234  std::vector<int> SegVEqnVpreOffset;
235  std::vector<int> SegVEqnVsegOffset;
236  std::vector<int> SegVEqnVnexOffset;
237  std::vector<int> SegVEqnNOffset;
238  std::vector<int> SegVEqnMOffset;
239  std::vector<int> SegVEqnHOffset;
240  std::vector<int> SegVEqnAOffset;
241  std::vector<int> SegVEqnBOffset;
242  std::vector<int> SegVEqnM_Offset;
243  std::vector<int> SegVEqnH_Offset;
244  std::vector<int> SegVEqnCOffset;
245  std::vector<int> NEquVNodeOffset;
246  std::vector<int> NEquNNodeOffset;
247  std::vector<int> MEquVNodeOffset;
248  std::vector<int> MEquMNodeOffset;
249  std::vector<int> HEquVNodeOffset;
250  std::vector<int> HEquHNodeOffset;
251  std::vector<int> AEquVNodeOffset;
252  std::vector<int> AEquANodeOffset;
253  std::vector<int> BEquVNodeOffset;
254  std::vector<int> BEquBNodeOffset;
255  std::vector<int> M_EquVNodeOffset;
256  std::vector<int> M_EquM_NodeOffset;
257  std::vector<int> H_EquVNodeOffset;
258  std::vector<int> H_EquH_NodeOffset;
259  std::vector<int> CEquVNodeOffset;
260  std::vector<int> CEquCNodeOffset;
261  std::vector<int> CEquCaNodeOffset;
262  std::vector<int> CaEquVNodeOffset;
263  std::vector<int> CaEquM_NodeOffset;
264  std::vector<int> CaEquH_NodeOffset;
265  std::vector<int> CaEquCaNodeOffset;
266 
267  // maps to track the appropriate jacobian offsets for each segment's previous, current, and next segment
268  std::map <int, int> prevMap;
269  std::map<int, int> segMap;
270  std::map<int, int> nextMap;
271 
272  std::vector< std::vector<int> > jacStamp;
273 };
274 
275 //-----------------------------------------------------------------------------
276 // Class : Model
277 // Purpose :
278 // Special Notes :
279 // Creator : Richard Schiek, SNL, Electrical and Microsystem Modeling
280 // Creation Date : 06/10/09
281 //-----------------------------------------------------------------------------
282 class Model : public DeviceModel
283 {
284  friend class ParametricData<Model>;
285  typedef std::vector<Instance *> InstanceVector;
286 
287 
288  friend class Instance;
289  friend class Traits;
290 
291 public:
292  Model(
293  const Configuration & configuration,
294  const ModelBlock & MB,
295  const FactoryBlock & factory_block);
296  ~Model();
297 
298 private:
299  Model();
300  Model(const Model &);
301  Model &operator=(const Model &);
302 
303 public:
304  virtual void forEachInstance(DeviceInstanceOp &op) const /* override */;
305 
306  virtual std::ostream &printOutInstances(std::ostream &os) const;
307 
308  bool processParams ();
309  bool processInstanceParams ();
310 
311 private:
312 
313  // parameter variables
314  double cMem; // membrane capacitance
315  double gMem; // membrane conductance
316  double vRest; // resting potential
317  double eNa; // sodium rest potential
318  double gNa; // sodium base conductance
319  double eK; // potassium rest potential
320  double gK; // potassium base conductance
321  double eA; // a-current rest potential
322  double gA; // a-current base conductance
323  double eCa; // Calcium rest potential
324  double gCa; // Calcium base conductance
325  double eKCa; // potassium-calcium rest potential
326  double gKCa; // potassium-calcium base conductance
327  double CaInit; // initial intra-cellular calcium concentration
328  double CaGamma; // calcium current to concentration multiplier
329  double CaTau; // calcium removal time constant
330  double rInt; // intracellular resistivity
331  double radius; // Segment radius
332  double length; // cable length (segment length = length/nSeg)
333  std::string ionChannelModel; // what model will be used for the ion channels
334  int nSeg; // number of segments
335 
336  // Value of current expression for user-defined membranem model
337  double I;
338 
339  // these are vectors of strings to allow the user to specify independant vars and
340  // equations for a given membrane
341  std::vector<std::string> membraneCurrentEqus;
342  std::vector<std::string> membraneIndpVars;
343  std::vector<std::string> membraneIndpFEqus;
344  std::vector<std::string> membraneIndpQEqus;
345  std::vector<std::string> membraneFunctions;
346  std::vector<std::string> membraneParameters;
347 
348  // flags that parameters were given
349  bool rIntGiven;
353  bool nSegGiven;
354 
355  // flags that parameters were given
356  bool cMemGiven;
357  bool gMemGiven;
359  bool eNaGiven;
360  bool gNaGiven;
361  bool eKGiven;
362  bool gKGiven;
363  bool eAGiven;
364  bool gAGiven;
365  bool eCaGiven;
366  bool gCaGiven;
367  bool eKCaGiven;
368  bool gKCaGiven;
372 
379 
380  // these are meta flags. If one component of the a sodium current is given
381  // then all of the required equaitons will be used. Otherwise they are off
382  // Or, if hodgenHuxleyOn_ is true, then all of the H odgenHuxley equations are loaded.
383  // by default all of these are off.
386  bool sodiumOn_;
390  RCP< MembraneModel > membraneModel_;
391 
392 
393 public:
394  void addInstance(Instance *instance)
395  {
396  instanceContainer.push_back(instance);
397  }
398 
399 private:
400  std::vector<Instance*> instanceContainer;
401 };
402 
403 void registerDevice();
404 
405 } // namespace Neuron6
406 } // namespace Device
407 } // namespace Xyce
408 
409 #endif
Model & operator=(const Model &)
std::vector< double > segF_dM
std::map< int, int > nextMap
std::vector< int > SegVEqnH_Offset
virtual std::ostream & printOutInstances(std::ostream &os) const
std::vector< int > SegVEqnNOffset
std::vector< double > segQ_dV
std::vector< double > dCaF_dH
std::vector< double > segF_dVn
const std::vector< std::vector< int > > & jacobianStamp() const
std::vector< double > segF_dVp
std::vector< double > dHQ_dH
std::vector< double > segCEquFvalue
std::vector< int > SegVEqnAOffset
std::vector< double > segMEquQvalue
std::vector< double > dmF_dm
std::vector< double > daQ_da
std::vector< int > li_internalVars
std::vector< int > SegVEqnHOffset
std::vector< double > dbF_dV
std::vector< int > MEquVNodeOffset
std::vector< std::string > membraneIndpFEqus
RCP< MembraneModel > membraneModel_
static void loadModelParameters(ParametricData< Model > &model_parameters)
std::vector< double > dcF_dCa
std::vector< double > segF_db
static const char * name()
Definition: N_DEV_Neuron6.h:69
std::vector< int > CEquCNodeOffset
std::vector< int > MEquMNodeOffset
bool updateTemperature(const double &temp_tmp)
std::vector< double > daF_dV
Pure virtual class to augment a linear system.
bool processParams()
processParams
std::vector< double > segF_dm
std::vector< double > dbQ_db
std::vector< double > dcF_dV
std::vector< std::string > membraneCurrentEqus
std::vector< int > CaEquH_NodeOffset
std::vector< int > SegVEqnCOffset
std::vector< int > M_EquVNodeOffset
std::vector< double > segHEquQvalue
std::map< int, int > segMap
std::vector< double > dmQ_dm
std::vector< double > segCEquQvalue
std::vector< double > dnF_dn
std::vector< double > dCaF_dV
std::vector< double > segHEquFvalue
static Device * factory(const Configuration &configuration, const FactoryBlock &factory_block)
std::vector< std::string > membraneFunctions
std::vector< int > HEquHNodeOffset
std::vector< double > segF_dc
std::vector< int > H_EquVNodeOffset
std::vector< double > dCaQ_dCa
std::vector< double > segNEquQvalue
std::vector< int > CaEquCaNodeOffset
std::vector< double > segF_dH
std::vector< double > segCaEquQvalue
static void loadInstanceParameters(ParametricData< Instance > &instance_parameters)
Definition: N_DEV_Neuron6.C:79
std::vector< int > HEquVNodeOffset
std::vector< int > CaEquM_NodeOffset
std::vector< double > segBEquQvalue
The FactoryBlock contains parameters needed by the device, instance and model creation functions...
std::vector< double > segAEquFvalue
std::vector< double > segM_EquFvalue
std::vector< int > BEquBNodeOffset
void registerJacLIDs(const std::vector< std::vector< int > > &jacLIDVec)
std::vector< double > segMEquFvalue
std::vector< std::string > membraneParameters
std::vector< double > dbF_db
std::vector< double > dnF_dV
std::vector< double > potassiumCurrent
std::vector< double > segCaEquFvalue
std::vector< int > SegVEqnVpreOffset
static const char * deviceTypeName()
Definition: N_DEV_Neuron6.h:70
void registerLIDs(const std::vector< int > &intLIDVecRef, const std::vector< int > &extLIDVecRef)
std::vector< Instance * > instanceContainer
void varTypes(std::vector< char > &varTypeVec)
std::vector< Instance * > InstanceVector
std::vector< double > dhQ_dh
std::map< int, int > prevMap
std::vector< double > segQvalue
std::vector< int > SegVEqnM_Offset
std::vector< double > dMF_dV
std::vector< double > segF_dh
std::vector< int > AEquVNodeOffset
std::vector< double > segF_dn
std::vector< int > CEquVNodeOffset
std::vector< int > li_NaCurrentState
The Device class is an interface for device implementations.
Definition: N_DEV_Device.h:101
std::vector< std::vector< int > > jacStamp
std::vector< int > SegVEqnVsegOffset
std::vector< double > segM_EquQvalue
std::vector< double > dhF_dh
void loadNodeSymbols(Util::SymbolTable &symbol_table) const
Populates and returns the store name map.
std::vector< int > SegVEqnMOffset
std::vector< int > SegVEqnBOffset
std::vector< double > dhF_dV
Class Configuration contains device configuration data.
void registerStateLIDs(const std::vector< int > &staLIDVecRef)
std::vector< double > dMQ_dM
std::vector< int > H_EquH_NodeOffset
std::vector< std::vector< int > > jacobianOffsets
std::vector< double > segF_da
std::vector< double > segAEquQvalue
std::vector< double > dcQ_dc
std::vector< double > dCaF_dM
std::vector< int > CEquCaNodeOffset
std::vector< double > dmF_dV
std::vector< int > CaEquVNodeOffset
std::vector< double > dHF_dV
std::vector< int > SegVEqnVnexOffset
std::vector< int > NEquVNodeOffset
std::vector< double > dcF_dc
virtual void forEachInstance(DeviceInstanceOp &op) const
Apply a device instance "op" to all instances associated with this model.
std::vector< double > segH_EquQvalue
std::vector< double > segH_EquFvalue
std::vector< int > li_KCurrentState
std::vector< int > BEquVNodeOffset
std::vector< double > dCaF_dCa
std::vector< double > segNEquFvalue
void addInstance(Instance *instance)
std::vector< double > dMF_dM
std::vector< double > segF_dV
std::vector< int > M_EquM_NodeOffset
std::vector< std::string > membraneIndpVars
std::vector< double > segFvalue
std::vector< double > daF_da
std::vector< std::string > membraneIndpQEqus
Instance(const Configuration &configuration, const InstanceBlock &IB, Model &Miter, const FactoryBlock &factory_block)
bool processInstanceParams()
processInstanceParams
std::vector< double > dnQ_dn
std::vector< int > AEquANodeOffset
ModelBlock represents a .MODEL line from the netlist.
The DeviceTraits template describes the configuration of a device.
std::vector< double > sodiumCurrent
Manages parameter binding for class C.
Definition: N_DEV_Pars.h:214
InstanceBlock represent a device instance line from the netlist.
std::vector< double > segBEquFvalue
std::vector< double > dHF_dH
std::vector< int > NEquNNodeOffset
Instance & operator=(const Instance &)