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