Xyce  6.1
N_DEV_Neuron9.C
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.C,v $
27 //
28 // Purpose :
29 //
30 // Special Notes :
31 //
32 // Creator : Christy Warrender, SNL, Cognitive Modeling
33 //
34 // Creation Date : 02/28/00
35 //
36 // Revision Information:
37 // ---------------------
38 //
39 // Revision Number: $Revision: 1.36 $
40 //
41 // Revision Date : $Date: 2015/10/20 22:32:48 $
42 //
43 // Current Owner : $Author: tvrusso $
44 //-------------------------------------------------------------------------
45 
46 #include <Xyce_config.h>
47 
48 
49 // ---------- Standard Includes ----------
50 
51 
52 // ---------- Xyce Includes ----------
53 #include <N_DEV_DeviceOptions.h>
54 #include <N_DEV_DeviceMaster.h>
55 #include <N_DEV_ExternData.h>
56 #include <N_DEV_MatrixLoadData.h>
57 #include <N_DEV_Neuron9.h>
58 #include <N_DEV_SolverState.h>
59 #include <N_DEV_Message.h>
60 #include <N_ERH_ErrorMgr.h>
61 
62 #include <N_DEV_Neuron.h>
63 
64 #include <N_LAS_Vector.h>
65 #include <N_LAS_Matrix.h>
66 #include <N_UTL_FeatureTest.h>
67 
68 namespace Xyce {
69 namespace Device {
70 
71 namespace Neuron9 {
72 
74 {
75 }
76 
78 {
79  p.addPar ("CMEM",0.0,&Neuron9::Model::cMem)
80  .setGivenMember(&Neuron9::Model::cMemGiven)
81  .setUnit(U_FARAD)
82  .setCategory(CAT_NONE)
83  .setDescription("Membrane capacitance");
84 
85  p.addPar ("ELEAK",0.0,&Neuron9::Model::eLeak)
86  .setGivenMember(&Neuron9::Model::eLeakGiven)
87  .setUnit(U_VOLT)
88  .setCategory(CAT_NONE)
89  .setDescription("Leak current reversal potential");
90 
91  p.addPar ("GMEM",0.0,&Neuron9::Model::gMem)
92  .setGivenMember(&Neuron9::Model::gMemGiven)
93  .setUnit(U_OHMM1)
94  .setCategory(CAT_NONE)
95  .setDescription("Membrane conductance");
96 
97  p.addPar ("EK",0.0,&Neuron9::Model::eK)
98  .setGivenMember(&Neuron9::Model::eKGiven)
99  .setUnit(U_VOLT)
100  .setCategory(CAT_NONE)
101  .setDescription("Potassium reversal potential");
102 
103  p.addPar ("GK",0.0,&Neuron9::Model::gK)
104  .setGivenMember(&Neuron9::Model::gKGiven)
105  .setUnit(U_OHMM1)
106  .setCategory(CAT_NONE)
107  .setDescription("Potassium base conductance");
108 
109  p.addPar ("ENA",0.0,&Neuron9::Model::eNa)
110  .setGivenMember(&Neuron9::Model::eNaGiven)
111  .setUnit(U_VOLT)
112  .setCategory(CAT_NONE)
113  .setDescription("Sodium reversal potential");
114 
115  p.addPar ("GNA",0.0,&Neuron9::Model::gNa)
116  .setGivenMember(&Neuron9::Model::gNaGiven)
117  .setUnit(U_OHMM1)
118  .setCategory(CAT_NONE)
119  .setDescription("Sodium base conductance");
120 
121  p.addPar ("VREST",0.0,&Neuron9::Model::vRest)
122  .setGivenMember(&Neuron9::Model::vRestGiven)
123  .setUnit(U_VOLT)
124  .setCategory(CAT_NONE)
125  .setDescription("Resting potential");
126 }
127 
128 //
129 // static class member inits
130 //
131 std::vector< std::vector<int> > Instance::jacStamp;
132 
133 const double Instance::VT = -63.0; // mV
134 
135 // Class Instance
136 //-----------------------------------------------------------------------------
137 // Function : Instance::processParams
138 // Purpose :
139 // Special Notes :
140 // Scope : public
141 // Creator : Christy Warrender, SNL, Cognitive Modeling
142 // Creation Date : 06/22/12
143 //-----------------------------------------------------------------------------
145 {
146  // If there are any time dependent parameters, set their values at for
147  // the current time.
148 
149  return true;
150 }
151 
152 //-----------------------------------------------------------------------------
153 // Function : Instance::updateTemperature
154 // Purpose :
155 // Special Notes :
156 // Scope : public
157 // Creator : Christy Warrender, SNL, Cognitive Modeling
158 // Creation Date : 06/22/12
159 //-----------------------------------------------------------------------------
160 bool Instance::updateTemperature ( const double & temp)
161 {
162  bool bsuccess = true;
163  return bsuccess;
164 }
165 
166 //-----------------------------------------------------------------------------
167 // Function : Instance::Instance
168 // Purpose : constructor
169 // Special Notes :
170 // Scope : public
171 // Creator : Christy Warrender, SNL, Cognitive Modeling
172 // Creation Date : 06/22/12
173 //-----------------------------------------------------------------------------
175  const Configuration & configuration,
176  const InstanceBlock & IB,
177  Model & Miter,
178  const FactoryBlock & factory_block)
179 
180  : DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
181  model_(Miter),
182  kcl1Fvalue(0.0),
183  kcl1Qvalue(0.0),
184  kcl2Fvalue(0.0),
185  kcl2Qvalue(0.0),
186  nEquFvalue(0.0),
187  nEquQvalue(0.0),
188  mEquFvalue(0.0),
189  mEquQvalue(0.0),
190  hEquFvalue(0.0),
191  hEquQvalue(0.0),
192  dkcl1F_dV1(0.0),
193  dkcl1F_dV2(0.0),
194  dkcl1F_dn(0.0),
195  dkcl1F_dm(0.0),
196  dkcl1F_dh(0.0),
197  dkcl1Q_dV1(0.0),
198  dkcl1Q_dV2(0.0),
199  dkcl2F_dV1(0.0),
200  dkcl2F_dV2(0.0),
201  dkcl2F_dn(0.0),
202  dkcl2F_dm(0.0),
203  dkcl2F_dh(0.0),
204  dkcl2Q_dV1(0.0),
205  dkcl2Q_dV2(0.0),
206  dnF_dV1(0.0),
207  dnF_dV2(0.0),
208  dnF_dn(0.0),
209  dnQ_dn(0.0),
210  dmF_dV1(0.0),
211  dmF_dV2(0.0),
212  dmF_dm(0.0),
213  dmQ_dm(0.0),
214  dhF_dV1(0.0),
215  dhF_dV2(0.0),
216  dhF_dh(0.0),
217  dhQ_dh(0.0)
218 {
219  numExtVars = 2;
220  numIntVars = 3;
221  numStateVars = 2;
222 
223  devConMap.resize(2);
224  devConMap[0] = 1;
225  devConMap[1] = 1;
226 
227  // set up jacStamp
228  if( jacStamp.empty() )
229  {
230  // V1, V2, n, m, h
231  // all values depend on Vm = V1-V2
232  // V1 and V2 depend on n, m, and h
233  // n, m, and h each depend on themselves as well as V1 and V2
234  jacStamp.resize(5);
235  jacStamp[0].resize(5); // V1
236  jacStamp[0][0] = 0;
237  jacStamp[0][1] = 1;
238  jacStamp[0][2] = 2;
239  jacStamp[0][3] = 3;
240  jacStamp[0][4] = 4;
241  jacStamp[1].resize(5); // V2
242  jacStamp[1][0] = 0;
243  jacStamp[1][1] = 1;
244  jacStamp[1][2] = 2;
245  jacStamp[1][3] = 3;
246  jacStamp[1][4] = 4;
247  jacStamp[2].resize(3); // n
248  jacStamp[2][0] = 0;
249  jacStamp[2][1] = 1;
250  jacStamp[2][2] = 2;
251  jacStamp[3].resize(3); // m
252  jacStamp[3][0] = 0;
253  jacStamp[3][1] = 1;
254  jacStamp[3][2] = 3;
255  jacStamp[4].resize(3); // h
256  jacStamp[4][0] = 0;
257  jacStamp[4][1] = 1;
258  jacStamp[4][2] = 4;
259  }
260 
261  // Set params to constant default values:
262  setDefaultParams ();
263 
264  // Set params according to instance line and constant defaults from metadata:
265  // there are no params for this device as yet, so calling setParams causes
266  // the code to exit.
267  // setParams (IB.params);
268 
269  // Set any non-constant parameter defaults:
270 
271  // Calculate any parameters specified as expressions:
273 
274  // calculate dependent (ie computed) params and check for errors:
275  processParams ();
276 
277 }
278 
279 //-----------------------------------------------------------------------------
280 // Function : Instance::~Instance
281 // Purpose : destructor
282 // Special Notes :
283 // Scope : public
284 // Creator : Christy Warrender, SNL, Cognitive Modeling
285 // Creation Date : 06/22/12
286 //-----------------------------------------------------------------------------
288 {
289 }
290 
291 //-----------------------------------------------------------------------------
292 // Function : Instance::registerLIDs
293 // Purpose :
294 // Special Notes :
295 // Scope : public
296 // Creator : Christy Warrender, SNL, Cognitive Modeling
297 // Creation Date : 06/22/12
298 //-----------------------------------------------------------------------------
299 void Instance::registerLIDs(const std::vector<int> & intLIDVecRef,
300  const std::vector<int> & extLIDVecRef)
301 {
302  AssertLIDs(intLIDVecRef.size() == numIntVars);
303  AssertLIDs(extLIDVecRef.size() == numExtVars);
304 
305  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
306  {
307  Xyce::dout() << std::endl << section_divider << std::endl;
308  Xyce::dout() << " Instance::registerLIDs" << std::endl;
309  Xyce::dout() << " name = " << getName() << std::endl;
310  }
311 
312  // copy over the global ID lists.
313  intLIDVec = intLIDVecRef;
314  extLIDVec = extLIDVecRef;
315 
316  li_Pos = extLIDVec[0];
317  li_Neg = extLIDVec[1];
318  li_nPro = intLIDVec[0];
319  li_mPro = intLIDVec[1];
320  li_hPro = intLIDVec[2];
321 
322  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) )
323  {
324  Xyce::dout() << " li_Pos = " << li_Pos << std::endl
325  << " li_Neg = " << li_Neg << std::endl
326  << " li_nPro = " << li_nPro << std::endl
327  << " li_mPro = " << li_mPro << std::endl
328  << " li_hPro = " << li_hPro << std::endl;
329  }
330 
331  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) )
332  {
333  Xyce::dout() << section_divider << std::endl;
334  }
335 }
336 
337 //-----------------------------------------------------------------------------
338 // Function : Instance::loadNodeSymbols
339 // Purpose :
340 // Special Notes :
341 // Scope : public
342 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
343 // Creation Date : 05/13/05
344 //-----------------------------------------------------------------------------
345 void Instance::loadNodeSymbols(Util::SymbolTable &symbol_table) const
346 {
347  addInternalNode(symbol_table, li_nPro, getName(), "N");
348  addInternalNode(symbol_table, li_mPro, getName(), "M");
349  addInternalNode(symbol_table, li_hPro, getName(), "H");
350 }
351 
352 //-----------------------------------------------------------------------------
353 // Function : Instance::registerStateLIDs
354 // Purpose :
355 // Special Notes :
356 // Scope : public
357 // Creator : Christy Warrender, SNL, Cognitive Modeling
358 // Creation Date : 06/22/12
359 //-----------------------------------------------------------------------------
360 void Instance::registerStateLIDs( const std::vector<int> & staLIDVecRef )
361 {
362  AssertLIDs(staLIDVecRef.size() == numStateVars);
363 
364  // copy over the global ID lists.
365  staLIDVec = staLIDVecRef;
366 
367  li_KCurrentState = staLIDVec[0];
368  li_NaCurrentState = staLIDVec[1];
369 
370 }
371 
372 //-----------------------------------------------------------------------------
373 // Function : Instance::jacobianStamp
374 // Purpose :
375 // Special Notes :
376 // Scope : public
377 // Creator : Christy Warrender, SNL, Cognitive Modeling
378 // Creation Date : 06/22/12
379 //-----------------------------------------------------------------------------
380 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
381 {
382  return jacStamp;
383 }
384 
385 //-----------------------------------------------------------------------------
386 // Function : Instance::registerJacLIDs
387 // Purpose :
388 // Special Notes :
389 // Scope : public
390 // Creator : Christy Warrender, SNL, Cognitive Modeling
391 // Creation Date : 06/22/12
392 //-----------------------------------------------------------------------------
393 void Instance::registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec )
394 {
395  DeviceInstance::registerJacLIDs( jacLIDVec );
396 
397  APosEquPosNodeOffset = jacLIDVec[0][0];
398  APosEquNegNodeOffset = jacLIDVec[0][1];
399  APosEquNNodeOffset = jacLIDVec[0][2];
400  APosEquMNodeOffset = jacLIDVec[0][3];
401  APosEquHNodeOffset = jacLIDVec[0][4];
402 
403  ANegEquPosNodeOffset = jacLIDVec[1][0];
404  ANegEquNegNodeOffset = jacLIDVec[1][1];
405  ANegEquNNodeOffset = jacLIDVec[1][2];
406  ANegEquMNodeOffset = jacLIDVec[1][3];
407  ANegEquHNodeOffset = jacLIDVec[1][4];
408 
409  ANEquPosNodeOffset = jacLIDVec[2][0];
410  ANEquNegNodeOffset = jacLIDVec[2][1];
411  ANEquNNodeOffset = jacLIDVec[2][2];
412 
413  AMEquPosNodeOffset = jacLIDVec[3][0];
414  AMEquNegNodeOffset = jacLIDVec[3][1];
415  AMEquMNodeOffset = jacLIDVec[3][2];
416 
417  AHEquPosNodeOffset = jacLIDVec[4][0];
418  AHEquNegNodeOffset = jacLIDVec[4][1];
419  AHEquHNodeOffset = jacLIDVec[4][2];
420 }
421 
422 
423 //-----------------------------------------------------------------------------
424 // Function : Instance::updateIntermediateVars
425 // Purpose :
426 // Special Notes :
427 // Scope : public
428 // Creator : Christy Warrender, SNL, Cognitive Modeling
429 // Creation Date : 06/22/12
430 //-----------------------------------------------------------------------------
432 {
433  //Xyce::dout() << "Instance::updateIntermediateVars()" << std::endl;
434 
435  bool bsuccess = true;
436 
437  // here we take the current solutions for V1, V2, n, m and h
438  // and use those to calculate all the terms needed for the next
439  // load cycle (F, Q, dFdX, dQdX)
440  Linear::Vector * solVectorPtr = extData.nextSolVectorPtr;
441 
442  // use suffix "now" to to clarify that this for the latest solution
443  double v1Now = (*solVectorPtr)[li_Pos];
444  double v2Now = (*solVectorPtr)[li_Neg];
445  double nNow = (*solVectorPtr)[li_nPro];
446  double mNow = (*solVectorPtr)[li_mPro];
447  double hNow = (*solVectorPtr)[li_hPro];
448 
449  // get function and derivative values
450  // independent variables
451  // use scoping to avoid lots of similar variable names
452 
453  // kcl F
454  {
455  const int numDeriv = 5;
456  Sacado::Fad::SFad<double,5> v1Var( numDeriv, 0, v1Now );
457  Sacado::Fad::SFad<double,5> v2Var( numDeriv, 1, v2Now );
458  Sacado::Fad::SFad<double,5> nVar( numDeriv, 2, nNow );
459  Sacado::Fad::SFad<double,5> mVar( numDeriv, 3, mNow );
460  Sacado::Fad::SFad<double,5> hVar( numDeriv, 4, hNow );
461  // parameters
462  Sacado::Fad::SFad<double,5> gMemVar( model_.gMem );
463  Sacado::Fad::SFad<double,5> eLeakVar( model_.eLeak );
464  Sacado::Fad::SFad<double,5> gKVar( model_.gK );
465  Sacado::Fad::SFad<double,5> eKVar( model_.eK );
466  Sacado::Fad::SFad<double,5> gNaVar( model_.gNa );
467  Sacado::Fad::SFad<double,5> eNaVar( model_.eNa );
468 
469  // compute the vaud and derivative terms for KCL 1 F
470  Sacado::Fad::SFad<double,5> resultFad;
471  resultFad = kcl1EquF( v1Var, v2Var, nVar, mVar, hVar, gMemVar, eLeakVar, gKVar, eKVar, gNaVar, eNaVar );
472  kcl1Fvalue = resultFad.val();
473  dkcl1F_dV1 = resultFad.dx(0);
474  dkcl1F_dV2 = resultFad.dx(1);
475  dkcl1F_dn = resultFad.dx(2);
476  dkcl1F_dm = resultFad.dx(3);
477  dkcl1F_dh = resultFad.dx(4);
478 
479  // compute the vaud and derivative terms for KCL 2 F
480  resultFad = kcl2EquF( v1Var, v2Var, nVar, mVar, hVar, gMemVar, eLeakVar, gKVar, eKVar, gNaVar, eNaVar );
481  kcl2Fvalue = resultFad.val();
482  dkcl2F_dV1 = resultFad.dx(0);
483  dkcl2F_dV2 = resultFad.dx(1);
484  dkcl2F_dn = resultFad.dx(2);
485  dkcl2F_dm = resultFad.dx(3);
486  dkcl2F_dh = resultFad.dx(4);
487  }
488 
489  // kcl Q
490  {
491  const int numDeriv = 2;
492  Sacado::Fad::SFad<double,2> v1Var( numDeriv, 0, v1Now );
493  Sacado::Fad::SFad<double,2> v2Var( numDeriv, 1, v2Now );
494 
495  // parameters
496  Sacado::Fad::SFad<double,2> cMemVar( model_.cMem );
497 
498  Sacado::Fad::SFad<double,2> resultFad;
499  resultFad = kcl1EquQ( v1Var, v2Var, cMemVar );
500  kcl1Qvalue = resultFad.val();
501  dkcl1Q_dV1 = resultFad.dx(0);
502  dkcl1Q_dV2 = resultFad.dx(1);
503 
504  resultFad = kcl2EquQ( v1Var, v2Var, cMemVar );
505  kcl2Qvalue = resultFad.val();
506  dkcl2Q_dV1 = resultFad.dx(0);
507  dkcl2Q_dV2 = resultFad.dx(1);
508  }
509 
510  // n - equation
511  {
512  const int numDeriv = 3;
513  Sacado::Fad::SFad<double,3> v1Var( numDeriv, 0, v1Now );
514  Sacado::Fad::SFad<double,3> v2Var( numDeriv, 1, v2Now );
515  Sacado::Fad::SFad<double,3> nVar( numDeriv, 2, nNow );
516  // parameter
517  Sacado::Fad::SFad<double,3> vRestVar( model_.vRest );
518 
519  Sacado::Fad::SFad<double,3> resultFad = nEquF( v1Var, v2Var, nVar, vRestVar);
520  nEquFvalue = resultFad.val();
521  dnF_dV1 = resultFad.dx(0);
522  dnF_dV2 = resultFad.dx(1);
523  dnF_dn = resultFad.dx(2);
524  }
525  {
526  const int numDeriv = 1;
527  Sacado::Fad::SFad<double,1> nVar( numDeriv, 0, nNow );
528 
529  Sacado::Fad::SFad<double,1> resultFad = nEquQ( nVar );
530  nEquQvalue = resultFad.val();
531  dnQ_dn = resultFad.dx(0);
532  }
533 
534  // m - equation
535  {
536  const int numDeriv = 3;
537  Sacado::Fad::SFad<double,3> v1Var( numDeriv, 0, v1Now );
538  Sacado::Fad::SFad<double,3> v2Var( numDeriv, 1, v2Now );
539  Sacado::Fad::SFad<double,3> mVar( numDeriv, 2, mNow );
540  // parameter
541  Sacado::Fad::SFad<double,3> vRestVar( model_.vRest );
542 
543  Sacado::Fad::SFad<double,3> resultFad = mEquF( v1Var, v2Var, mVar, vRestVar );
544  mEquFvalue = resultFad.val();
545  dmF_dV1 = resultFad.dx(0);
546  dmF_dV2 = resultFad.dx(1);
547  dmF_dm = resultFad.dx(2);
548  }
549  {
550  const int numDeriv = 1;
551  Sacado::Fad::SFad<double,1> mVar( numDeriv, 0, mNow );
552 
553  Sacado::Fad::SFad<double,1> resultFad = mEquQ( mVar );
554  mEquQvalue = resultFad.val();
555  dmQ_dm = resultFad.dx(0);
556  }
557 
558  // h - equation
559  {
560  const int numDeriv = 3;
561  Sacado::Fad::SFad<double,3> v1Var( numDeriv, 0, v1Now );
562  Sacado::Fad::SFad<double,3> v2Var( numDeriv, 1, v2Now );
563  Sacado::Fad::SFad<double,3> hVar( numDeriv, 2, hNow );
564  // parameter
565  Sacado::Fad::SFad<double,3> vRestVar( model_.vRest );
566 
567  Sacado::Fad::SFad<double,3> resultFad = hEquF( v1Var, v2Var, hVar, vRestVar );
568  hEquFvalue = resultFad.val();
569  dhF_dV1 = resultFad.dx(0);
570  dhF_dV2 = resultFad.dx(1);
571  dhF_dh = resultFad.dx(2);
572  }
573  {
574  const int numDeriv = 1;
575  Sacado::Fad::SFad<double,1> hVar( numDeriv, 0, hNow );
576 
577  Sacado::Fad::SFad<double,1> resultFad = hEquQ( hVar );
578  hEquQvalue = resultFad.val();
579  dhQ_dh = resultFad.dx(0);
580  }
581 
582  // calculate potassium current
583  potassiumCurrent = model_.gK * pow(nNow, 4.0) * (v1Now - v2Now - model_.eK);
584 
585  // calculate sodium current
586  sodiumCurrent = model_.gNa * pow(mNow, 3.0) * hNow * (v1Now - v2Now - model_.eNa);
587 
588  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
589  {
590  double vRest = model_.vRest;
591  Xyce::dout() << "Instance::updateIntermediateVars()" << std::endl
592  << "vRest(input) = " << vRest << std::endl
593  << "v1 = " << v1Now << std::endl
594  << "v2 = " << v2Now << std::endl
595  << "nNow = " << nNow << std::endl
596  << "mNow = " << mNow << std::endl
597  << "hNow = " << hNow << std::endl
598  << "kcl1Fvalue = " << kcl1Fvalue << std::endl
599  << "dkcl1F_dV1 = " << dkcl1F_dV1 << std::endl
600  << "dkcl1F_dV2 = " << dkcl1F_dV2 << std::endl
601  << "dkcl1F_dn = " << dkcl1F_dn << std::endl
602  << "dkcl1F_dm = " << dkcl1F_dm << std::endl
603  << "dkcl1F_dh = " << dkcl1F_dh << std::endl
604  << "kcl2Fvalue = " << kcl2Fvalue << std::endl
605  << "dkcl2F_dV1 = " << dkcl2F_dV1 << std::endl
606  << "dkcl2F_dV2 = " << dkcl2F_dV2 << std::endl
607  << "dkcl2F_dn = " << dkcl2F_dn << std::endl
608  << "dkcl2F_dm = " << dkcl2F_dm << std::endl
609  << "dkcl2F_dh = " << dkcl2F_dh << std::endl
610  << "alphaN = " << alphaN<double>( v1Now, v2Now, vRest) << std::endl
611  << "betaN = " << betaN<double>( v1Now, v2Now, vRest) << std::endl
612  << "nEquFvalue = " << nEquFvalue << std::endl
613  << "dnF_dV1 = " << dnF_dV1 << std::endl
614  << "dnF_dV2 = " << dnF_dV2 << std::endl
615  << "dnF_dn = " << dnF_dn << std::endl
616  << "nEquQvalue = " << nEquQvalue << std::endl
617  << "dnQ_dn = " << dnQ_dn << std::endl
618  << "alphaM = " << alphaM<double>( v1Now, v2Now, vRest) << std::endl
619  << "betaM = " << betaM<double>( v1Now, v2Now, vRest) << std::endl
620  << "mEquFvalue = " << mEquFvalue << std::endl
621  << "dmF_dV1 = " << dmF_dV1 << std::endl
622  << "dmF_dV2 = " << dmF_dV2 << std::endl
623  << "dmF_dm = " << dmF_dm << std::endl
624  << "mEquQvalue = " << mEquQvalue << std::endl
625  << "dmQ_dm = " << dmQ_dm << std::endl
626  << "alphaH = " << alphaH<double>( v1Now, v2Now, vRest) << std::endl
627  << "betaH = " << betaH<double>( v1Now, v2Now, vRest) << std::endl
628  << "hEquFvalue = " << hEquFvalue << std::endl
629  << "dhF_dV1 = " << dhF_dV1 << std::endl
630  << "dhF_dV2 = " << dhF_dV2 << std::endl
631  << "dhF_dh = " << dhF_dh << std::endl
632  << "hEquQvalue = " << hEquQvalue << std::endl
633  << "dhQ_dh = " << dhQ_dh << std::endl
634  << std::endl;
635  }
636 
637  return bsuccess;
638 }
639 //-----------------------------------------------------------------------------
640 // Function : Instance::updatePrimaryState
641 // Purpose :
642 // Special Notes :
643 // Scope : public
644 // Creator : Christy Warrender, SNL, Cognitive Modeling
645 // Creation Date : 06/22/12
646 //-----------------------------------------------------------------------------
648 {
649  bool bsuccess = true;
650 
652 
653  Linear::Vector * solVectorPtr = extData.nextSolVectorPtr;
654  Linear::Vector * staVectorPtr = extData.nextStaVectorPtr;
655 
656  (*staVectorPtr)[li_KCurrentState] = potassiumCurrent;
657  (*staVectorPtr)[li_NaCurrentState] = sodiumCurrent;
658 
659  return bsuccess;
660 }
661 
662 //-----------------------------------------------------------------------------
663 // Function : Instance::updateSecondaryState
664 // Purpose :
665 // Special Notes :
666 // Scope : public
667 // Creator : Christy Warrender, SNL, Cognitive Modeling
668 // Creation Date : 06/22/12
669 //-----------------------------------------------------------------------------
671 {
672  bool bsuccess = true;
673  Linear::Vector * staVectorPtr = extData.nextStaVectorPtr;
674 
675  return bsuccess;
676 }
677 
678 //-----------------------------------------------------------------------------
679 // Function : Instance::loadDAEQVector
680 //
681 // Purpose : Loads the Q-vector contributions for a single
682 // Neuron instance.
683 //
684 // Special Notes : The "Q" vector is part of a standard DAE formalism in
685 // which the system of equations is represented as:
686 //
687 // f(x) = dQ(x)/dt + F(x) - B(t) = 0
688 //
689 // Scope : public
690 // Creator : Christy Warrender, SNL, Cognitive Modeling
691 // Creation Date : 06/22/12
692 //-----------------------------------------------------------------------------
694 {
695  bool bsuccess = true;
696 
697  Linear::Vector * daeQVecPtr = extData.daeQVectorPtr;
698 
699  (*daeQVecPtr)[li_Pos] += kcl1Qvalue;
700  (*daeQVecPtr)[li_Neg] += kcl2Qvalue;
701  (*daeQVecPtr)[li_nPro] += nEquQvalue;
702  (*daeQVecPtr)[li_mPro] += mEquQvalue;
703  (*daeQVecPtr)[li_hPro] += hEquQvalue;
704 
705  return bsuccess;
706 }
707 
708 
709 
710 //-----------------------------------------------------------------------------
711 // Function : Instance::loadDAEFVector
712 //
713 // Purpose : Loads the F-vector contributions for a single
714 // Neuron instance.
715 //
716 // Special Notes :
717 //
718 //
719 // Scope : public
720 // Creator : Christy Warrender, SNL, Cognitive Modeling
721 // Creation Date : 06/22/12
722 //-----------------------------------------------------------------------------
724 {
725  bool bsuccess=true;
726 
727  Linear::Vector * daeFVecPtr = extData.daeFVectorPtr;
728 
729  (*daeFVecPtr)[li_Pos] += kcl1Fvalue;
730  (*daeFVecPtr)[li_Neg] += kcl2Fvalue;
731  (*daeFVecPtr)[li_nPro] += nEquFvalue;
732  (*daeFVecPtr)[li_mPro] += mEquFvalue;
733  (*daeFVecPtr)[li_hPro] += hEquFvalue;
734 
735  return bsuccess;
736 }
737 
738 //-----------------------------------------------------------------------------
739 // Function : Instance::loadDAEdQdx
740 //
741 // Purpose : Loads the Q-vector contributions for a single
742 // Neuron instance.
743 // Scope : public
744 // Creator : Christy Warrender, SNL, Cognitive Modeling
745 // Creation Date : 06/22/12
746 //-----------------------------------------------------------------------------
748 {
749  bool bsuccess = true;
750 
751  Linear::Matrix * dQdxMatPtr = extData.dQdxMatrixPtr;
752 
753  (*dQdxMatPtr)[li_Pos][APosEquPosNodeOffset] += dkcl1Q_dV1;
754  (*dQdxMatPtr)[li_Pos][APosEquNegNodeOffset] += dkcl1Q_dV2;
755 
756  (*dQdxMatPtr)[li_Neg][ANegEquPosNodeOffset] += dkcl2Q_dV1;
757  (*dQdxMatPtr)[li_Neg][ANegEquNegNodeOffset] += dkcl2Q_dV2;
758 
759  (*dQdxMatPtr)[li_nPro][ANEquNNodeOffset] += dnQ_dn;
760 
761  (*dQdxMatPtr)[li_mPro][AMEquMNodeOffset] += dmQ_dm;
762 
763  (*dQdxMatPtr)[li_hPro][AHEquHNodeOffset] += dhQ_dh;
764 
765  return bsuccess;
766 }
767 
768 
769 
770 //-----------------------------------------------------------------------------
771 // Function : Instance::loadDAEdFdx ()
772 //
773 // Purpose : Loads the F-vector contributions for a single
774 // Neuron instance.
775 //
776 // Special Notes : This is an algebraic constaint.
777 //
778 // Scope : public
779 // Creator : Christy Warrender, SNL, Cognitive Modeling
780 // Creation Date : 06/22/12
781 //-----------------------------------------------------------------------------
783 {
784  bool bsuccess = true;
785 
786  Linear::Matrix * dFdxMatPtr = extData.dFdxMatrixPtr;
787 
788  (*dFdxMatPtr)[li_Pos][APosEquPosNodeOffset] += dkcl1F_dV1;
789  (*dFdxMatPtr)[li_Pos][APosEquNegNodeOffset] += dkcl1F_dV2;
790  (*dFdxMatPtr)[li_Pos][APosEquNNodeOffset] += dkcl1F_dn;
791  (*dFdxMatPtr)[li_Pos][APosEquMNodeOffset] += dkcl1F_dm;
792  (*dFdxMatPtr)[li_Pos][APosEquHNodeOffset] += dkcl1F_dh;
793 
794  (*dFdxMatPtr)[li_Neg][ANegEquPosNodeOffset] += dkcl2F_dV1;
795  (*dFdxMatPtr)[li_Neg][ANegEquNegNodeOffset] += dkcl2F_dV2;
796  (*dFdxMatPtr)[li_Neg][ANegEquNNodeOffset] += dkcl2F_dn;
797  (*dFdxMatPtr)[li_Neg][ANegEquMNodeOffset] += dkcl2F_dm;
798  (*dFdxMatPtr)[li_Neg][ANegEquHNodeOffset] += dkcl2F_dh;
799 
800  (*dFdxMatPtr)[li_nPro][ANEquPosNodeOffset] += dnF_dV1;
801  (*dFdxMatPtr)[li_nPro][ANEquNegNodeOffset] += dnF_dV2;
802  (*dFdxMatPtr)[li_nPro][ANEquNNodeOffset] += dnF_dn;
803 
804  (*dFdxMatPtr)[li_mPro][AMEquPosNodeOffset] += dmF_dV1;
805  (*dFdxMatPtr)[li_mPro][AMEquNegNodeOffset] += dmF_dV2;
806  (*dFdxMatPtr)[li_mPro][AMEquMNodeOffset] += dmF_dm;
807 
808  (*dFdxMatPtr)[li_hPro][AHEquPosNodeOffset] += dhF_dV1;
809  (*dFdxMatPtr)[li_hPro][AHEquNegNodeOffset] += dhF_dV2;
810  (*dFdxMatPtr)[li_hPro][AHEquHNodeOffset] += dhF_dh;
811 
812  return bsuccess;
813 }
814 
815 //-----------------------------------------------------------------------------
816 // Function : Instance::setIC
817 // Purpose :
818 // Special Notes :
819 // Scope : public
820 // Creator : Christy Warrender, SNL, Cognitive Modeling
821 // Creation Date : 06/22/12
822 //-----------------------------------------------------------------------------
824 {
825  bool bsuccess = true;
826 
827  return bsuccess;
828 }
829 
830 //-----------------------------------------------------------------------------
831 // Function : Instance::varTypes
832 // Purpose :
833 // Special Notes :
834 // Scope : public
835 // Creator : Christy Warrender, SNL, Cognitive Modeling
836 // Creation Date : 06/22/12
837 //-----------------------------------------------------------------------------
838 void Instance::varTypes( std::vector<char> & varTypeVec )
839 {
840  //varTypeVec.resize(1);
841  //varTypeVec[0] = 'I';
842 }
843 
844 
845 //-----------------------------------------------------------------------------
846 // Function : Model::processParams
847 // Purpose :
848 // Special Notes :
849 // Scope : public
850 // Creator : Christy Warrender, SNL, Cognitive Modeling
851 // Creation Date : 06/22/12
852 //-----------------------------------------------------------------------------
854 {
855  return true;
856 }
857 
858 //----------------------------------------------------------------------------
859 // Function : Model::processInstanceParams
860 // Purpose :
861 // Special Notes :
862 // Scope : public
863 // Creator : Christy Warrender, SNL, Cognitive Modeling
864 // Creation Date : 06/22/12
865 //----------------------------------------------------------------------------
867 {
868 
869  std::vector<Instance*>::iterator iter;
870  std::vector<Instance*>::iterator first = instanceContainer.begin();
871  std::vector<Instance*>::iterator last = instanceContainer.end();
872 
873  for (iter=first; iter!=last; ++iter)
874  {
875  (*iter)->processParams();
876  }
877 
878  return true;
879 }
880 
881 //-----------------------------------------------------------------------------
882 // Function : Model::Model
883 // Purpose : block constructor
884 // Special Notes :
885 // Scope : public
886 // Creator : Christy Warrender, SNL, Cognitive Modeling
887 // Creation Date : 06/22/12
888 //-----------------------------------------------------------------------------
890  const Configuration & configuration,
891  const ModelBlock & MB,
892  const FactoryBlock & factory_block)
893  : DeviceModel(MB, configuration.getModelParameters(), factory_block)
894 {
895 
896  // Set params to constant default values:
897  setDefaultParams ();
898 
899  // Set params according to .model line and constant defaults from metadata:
900  setModParams (MB.params);
901 
902  // Set any non-constant parameter defaults:
903  //if (!given("TNOM"))
904  // tnom = getDeviceOptions().tnom;
905 
906  // Calculate any parameters specified as expressions:
908 
909  // calculate dependent (ie computed) params and check for errors:
910 
911  processParams ();
912 }
913 
914 //-----------------------------------------------------------------------------
915 // Function : Model::~Model
916 // Purpose : destructor
917 // Special Notes :
918 // Scope : public
919 // Creator : Christy Warrender, SNL, Cognitive Modeling
920 // Creation Date : 06/22/12
921 //-----------------------------------------------------------------------------
923 {
924  std::vector<Instance*>::iterator iter;
925  std::vector<Instance*>::iterator first = instanceContainer.begin();
926  std::vector<Instance*>::iterator last = instanceContainer.end();
927 
928  for (iter=first; iter!=last; ++iter)
929  {
930  delete (*iter);
931  }
932 }
933 
934 // additional Declarations
935 
936 //-----------------------------------------------------------------------------
937 // Function : Model::printOutInstances
938 // Purpose : debugging tool.
939 // Special Notes :
940 // Scope : public
941 // Creator : Christy Warrender, SNL, Cognitive Modeling
942 // Creation Date : 06/22/12
943 //-----------------------------------------------------------------------------
944 std::ostream &Model::printOutInstances(std::ostream &os) const
945 {
946  std::vector<Instance*>::const_iterator iter;
947  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
948  std::vector<Instance*>::const_iterator last = instanceContainer.end();
949 
950  int i, isize;
951  isize = instanceContainer.size();
952 
953  os << std::endl;
954  os << "Number of Neuron instances: " << isize << std::endl;
955  os << " name=\t\tmodelName\tParameters" << std::endl;
956  for (i=0, iter=first; iter!=last; ++iter, ++i)
957  {
958  os << " " << i << ": " << (*iter)->getName() << "\t";
959  os << getName();
960  os << std::endl;
961  }
962 
963  os << std::endl;
964  return os;
965 }
966 
967 //-----------------------------------------------------------------------------
968 // Function : Model::forEachInstance
969 // Purpose :
970 // Special Notes :
971 // Scope : public
972 // Creator : David Baur
973 // Creation Date : 2/4/2014
974 //-----------------------------------------------------------------------------
975 /// Apply a device instance "op" to all instances associated with this
976 /// model
977 ///
978 /// @param[in] op Operator to apply to all instances.
979 ///
980 ///
981 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
982 {
983  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
984  op(*it);
985 }
986 
987 
988 
989 //-----------------------------------------------------------------------------
990 // Function : Master::updateState
991 // Purpose :
992 // Special Notes :
993 // Scope : public
994 // Creator : Christy Warrender, SNL, Cognitive Modeling
995 // Creation Date : 06/22/12
996 //-----------------------------------------------------------------------------
997 bool Master::updateState (double * solVec, double * staVec, double * stoVec)
998 {
999  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
1000  {
1001  // just call the instance level update state
1002  (*it)->updatePrimaryState();
1003  }
1004  return true;
1005 }
1006 
1007 Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
1008 {
1009 
1010  return new Master(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
1011 }
1012 
1014 {
1016  .registerDevice("neuron", 9)
1017  .registerModelType("neuron", 9);
1018 }
1019 
1020 } // namespace Neuron9
1021 } // namespace Device
1022 } // namespace Xyce
const InstanceName & getName() const
bool processParams()
processParams
const DeviceOptions & deviceOptions_
static ScalarT nEquF(const ScalarT &Vn1, const ScalarT &Vn2, const ScalarT &n, const ScalarT &Vrest)
Descriptor & addPar(const char *parName, T default_value, T U::*varPtr)
Adds the parameter description to the parameter map.
Definition: N_DEV_Pars.h:1429
Linear::Vector * nextSolVectorPtr
Linear::Vector * daeQVectorPtr
static ScalarT hEquF(const ScalarT &Vn1, const ScalarT &Vn2, const ScalarT &h, const ScalarT &Vrest)
Pure virtual class to augment a linear system.
void addInternalNode(Util::SymbolTable &symbol_table, int index, const InstanceName &instance_name, const std::string &lead_name)
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)
InstanceVector::const_iterator getInstanceEnd() const
Returns an iterator to the ending of the vector of all instances created for this device...
#define AssertLIDs(cmp)
virtual void registerJacLIDs(const JacobianStamp &jacLIDVec)
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
InstanceVector::const_iterator getInstanceBegin() const
Returns an iterator to the beginning of the vector of all instances created for this device...
std::vector< Param > params
Parameters from the line.
const std::string & getName() const
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 void loadModelParameters(ParametricData< Model > &model_parameters)
Definition: N_DEV_Neuron9.C:77
virtual std::ostream & printOutInstances(std::ostream &os) const
Linear::Vector * nextStaVectorPtr
static Config< T > & addConfiguration()
Adds the device to the Xyce device configuration.
static ScalarT hEquQ(const ScalarT &h)
Linear::Matrix * dFdxMatrixPtr
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
const SolverState & solverState_
Class Configuration contains device configuration data.
void registerStateLIDs(const std::vector< int > &staLIDVecRef)
const SolverState & getSolverState() const
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 kcl2EquQ(const ScalarT &Vn1, const ScalarT &Vn2, const ScalarT &memC)
Linear::Vector * daeFVectorPtr
bool updateTemperature(const double &temp_tmp)
static ScalarT mEquF(const ScalarT &Vn1, const ScalarT &Vn2, const ScalarT &m, 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.
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)
Linear::Matrix * dQdxMatrixPtr
void setModParams(const std::vector< Param > &params)