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