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