Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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-2011 Sandia Corporation
10 //
11 // This program is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation, either version 3 of the License, or
14 // (at your option) any later version.
15 //
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 //-----------------------------------------------------------------------------
24 
25 //-------------------------------------------------------------------------
26 // Filename : $RCSfile: N_DEV_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.27 $
40 //
41 // Revision Date : $Date: 2014/05/13 14:50:39 $
42 //
43 // Current Owner : $Author: dgbaur $
44 //-------------------------------------------------------------------------
45 
46 #include <Xyce_config.h>
47 
48 
49 // ---------- Standard Includes ----------
50 
51 #include <N_UTL_Misc.h>
52 
53 // ---------- Xyce Includes ----------
54 #include <N_DEV_DeviceOptions.h>
55 #include <N_DEV_DeviceMaster.h>
56 #include <N_DEV_ExternData.h>
57 #include <N_DEV_MatrixLoadData.h>
58 #include <N_DEV_Neuron9.h>
59 #include <N_DEV_SolverState.h>
60 #include <N_DEV_Message.h>
61 #include <N_ERH_ErrorMgr.h>
62 
63 #include <N_DEV_Neuron.h>
64 
65 #include <N_LAS_Vector.h>
66 #include <N_LAS_Matrix.h>
67 
68 namespace Xyce {
69 namespace Device {
70 
71 
72 namespace Neuron9 {
73 
74 
76 {
77 }
78 
80 {
81  // Set up map for double precision variables:
82  p.addPar ("CMEM", 0.0, false, ParameterType::NO_DEP,
85  U_FARAD, CAT_NONE, "Membrane capacitance");
86 
87  p.addPar ("ELEAK", 0.0, false, ParameterType::NO_DEP,
90  U_VOLT, CAT_NONE, "Leak current reversal potential");
91 
92  p.addPar ("GMEM", 0.0, false, ParameterType::NO_DEP,
95  U_OHMM1, CAT_NONE, "Membrane conductance");
96 
97  p.addPar ("EK", 0.0, false, ParameterType::NO_DEP,
100  U_VOLT, CAT_NONE, "Potassium reversal potential");
101 
102  p.addPar ("GK", 0.0, false, ParameterType::NO_DEP,
105  U_OHMM1, CAT_NONE, "Potassium base conductance");
106 
107  p.addPar ("ENA", 0.0, false, ParameterType::NO_DEP,
110  U_VOLT, CAT_NONE, "Sodium reversal potential");
111 
112  p.addPar ("GNA", 0.0, false, ParameterType::NO_DEP,
115  U_OHMM1, CAT_NONE, "Sodium base conductance");
116 
117  p.addPar ("VREST", 0.0, false, ParameterType::NO_DEP,
120  U_VOLT, CAT_NONE, "Resting potential");
121 }
122 
123 
124 
125 //
126 // static class member inits
127 //
128 std::vector< std::vector<int> > Instance::jacStamp;
129 
130 const double Instance::VT = -63.0; // mV
131 
132 // Class Instance
133 //-----------------------------------------------------------------------------
134 // Function : Instance::processParams
135 // Purpose :
136 // Special Notes :
137 // Scope : public
138 // Creator : Christy Warrender, SNL, Cognitive Modeling
139 // Creation Date : 06/22/12
140 //-----------------------------------------------------------------------------
142 {
143  // If there are any time dependent parameters, set their values at for
144  // the current time.
145 
146  // now set the temperature related stuff.
147  //updateTemperature(temp);
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  //if (!given("TEMP"))
272  // temp = getDeviceOptions().temp.dVal();
273 
274  // Calculate any parameters specified as expressions:
276 
277  // calculate dependent (ie computed) params and check for errors:
278  processParams ();
279 
280 }
281 
282 //-----------------------------------------------------------------------------
283 // Function : Instance::~Instance
284 // Purpose : destructor
285 // Special Notes :
286 // Scope : public
287 // Creator : Christy Warrender, SNL, Cognitive Modeling
288 // Creation Date : 06/22/12
289 //-----------------------------------------------------------------------------
291 {
292 }
293 
294 //-----------------------------------------------------------------------------
295 // Function : Instance::registerLIDs
296 // Purpose :
297 // Special Notes :
298 // Scope : public
299 // Creator : Christy Warrender, SNL, Cognitive Modeling
300 // Creation Date : 06/22/12
301 //-----------------------------------------------------------------------------
302 void Instance::registerLIDs(const std::vector<int> & intLIDVecRef,
303  const std::vector<int> & extLIDVecRef)
304 {
305  AssertLIDs(intLIDVecRef.size() == numIntVars);
306  AssertLIDs(extLIDVecRef.size() == numExtVars);
307 
308 #ifdef Xyce_DEBUG_DEVICE
309  if (getDeviceOptions().debugLevel > 0)
310  {
311  Xyce::dout() << std::endl << section_divider << std::endl;
312  Xyce::dout() << " Instance::registerLIDs" << std::endl;
313  Xyce::dout() << " name = " << getName() << std::endl;
314  }
315 #endif
316 
317  // copy over the global ID lists.
318  intLIDVec = intLIDVecRef;
319  extLIDVec = extLIDVecRef;
320 
321  li_Pos = extLIDVec[0];
322  li_Neg = extLIDVec[1];
323  li_nPro = intLIDVec[0];
324  li_mPro = intLIDVec[1];
325  li_hPro = intLIDVec[2];
326 
327 #ifdef Xyce_DEBUG_DEVICE
328  if (getDeviceOptions().debugLevel > 0 )
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 #endif
337 
338 #ifdef Xyce_DEBUG_DEVICE
339  if (getDeviceOptions().debugLevel > 0 )
340  {
341  Xyce::dout() << section_divider << std::endl;
342  }
343 #endif
344 }
345 
346 //-----------------------------------------------------------------------------
347 // Function : Instance::getIntNameMap
348 // Purpose :
349 // Special Notes :
350 // Scope : public
351 // Creator : Christy Warrender, SNL, Cognitive Modeling
352 // Creation Date : 06/22/12
353 //-----------------------------------------------------------------------------
354 std::map<int,std::string> & Instance::getIntNameMap ()
355 {
356  // set up the internal name map, if it hasn't been already.
357  if (intNameMap.empty ())
358  {
362  }
363  return intNameMap;
364 }
365 
366 //-----------------------------------------------------------------------------
367 // Function : Instance::registerStateLIDs
368 // Purpose :
369 // Special Notes :
370 // Scope : public
371 // Creator : Christy Warrender, SNL, Cognitive Modeling
372 // Creation Date : 06/22/12
373 //-----------------------------------------------------------------------------
374 void Instance::registerStateLIDs( const std::vector<int> & staLIDVecRef )
375 {
376  AssertLIDs(staLIDVecRef.size() == numStateVars);
377 
378  // copy over the global ID lists.
379  staLIDVec = staLIDVecRef;
380 
381  li_KCurrentState = staLIDVec[0];
382  li_NaCurrentState = staLIDVec[1];
383 
384 }
385 
386 //-----------------------------------------------------------------------------
387 // Function : Instance::loadDeviceMask
388 //
389 // Purpose : Loads the zero elements of the device mask
390 //
391 // Special Notes : elements of the error vector associated with zero
392 // elements of the mask will not be included in weighted
393 // norms by the time integrator.
394 //
395 // Scope : public
396 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
397 // Creation Date : 01/19/07
398 //-----------------------------------------------------------------------------
400 {
401  bool returnVal=false;
402  N_LAS_Vector * maskVectorPtr = extData.deviceMaskVectorPtr;
403 
404 // Xyce::dout() << "Masking n, m and h" << std::endl;
405 // (*maskVectorPtr)[li_nPro] = 0.0;
406 // (*maskVectorPtr)[li_mPro] = 0.0;
407 // (*maskVectorPtr)[li_hPro] = 0.0;
408 // returnVal = true;
409 
410  return (returnVal);
411 }
412 
413 //-----------------------------------------------------------------------------
414 // Function : Instance::jacobianStamp
415 // Purpose :
416 // Special Notes :
417 // Scope : public
418 // Creator : Christy Warrender, SNL, Cognitive Modeling
419 // Creation Date : 06/22/12
420 //-----------------------------------------------------------------------------
421 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
422 {
423  return jacStamp;
424 }
425 
426 //-----------------------------------------------------------------------------
427 // Function : Instance::registerJacLIDs
428 // Purpose :
429 // Special Notes :
430 // Scope : public
431 // Creator : Christy Warrender, SNL, Cognitive Modeling
432 // Creation Date : 06/22/12
433 //-----------------------------------------------------------------------------
434 void Instance::registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec )
435 {
436  DeviceInstance::registerJacLIDs( jacLIDVec );
437 
438  APosEquPosNodeOffset = jacLIDVec[0][0];
439  APosEquNegNodeOffset = jacLIDVec[0][1];
440  APosEquNNodeOffset = jacLIDVec[0][2];
441  APosEquMNodeOffset = jacLIDVec[0][3];
442  APosEquHNodeOffset = jacLIDVec[0][4];
443 
444  ANegEquPosNodeOffset = jacLIDVec[1][0];
445  ANegEquNegNodeOffset = jacLIDVec[1][1];
446  ANegEquNNodeOffset = jacLIDVec[1][2];
447  ANegEquMNodeOffset = jacLIDVec[1][3];
448  ANegEquHNodeOffset = jacLIDVec[1][4];
449 
450  ANEquPosNodeOffset = jacLIDVec[2][0];
451  ANEquNegNodeOffset = jacLIDVec[2][1];
452  ANEquNNodeOffset = jacLIDVec[2][2];
453 
454  AMEquPosNodeOffset = jacLIDVec[3][0];
455  AMEquNegNodeOffset = jacLIDVec[3][1];
456  AMEquMNodeOffset = jacLIDVec[3][2];
457 
458  AHEquPosNodeOffset = jacLIDVec[4][0];
459  AHEquNegNodeOffset = jacLIDVec[4][1];
460  AHEquHNodeOffset = jacLIDVec[4][2];
461 }
462 
463 
464 //-----------------------------------------------------------------------------
465 // Function : Instance::updateIntermediateVars
466 // Purpose :
467 // Special Notes :
468 // Scope : public
469 // Creator : Christy Warrender, SNL, Cognitive Modeling
470 // Creation Date : 06/22/12
471 //-----------------------------------------------------------------------------
473 {
474  //Xyce::dout() << "Instance::updateIntermediateVars()" << std::endl;
475 
476  bool bsuccess = true;
477 
478  // here we take the current solutions for V1, V2, n, m and h
479  // and use those to calculate all the terms needed for the next
480  // load cycle (F, Q, dFdX, dQdX)
481  N_LAS_Vector * solVectorPtr = extData.nextSolVectorPtr;
482 
483  // use suffix "now" to to clarify that this for the latest solution
484  double v1Now = (*solVectorPtr)[li_Pos];
485  double v2Now = (*solVectorPtr)[li_Neg];
486  double nNow = (*solVectorPtr)[li_nPro];
487  double mNow = (*solVectorPtr)[li_mPro];
488  double hNow = (*solVectorPtr)[li_hPro];
489 
490  // get function and derivative values
491  // independent variables
492  // use scoping to avoid lots of similar variable names
493 
494  // kcl F
495  {
496  const int numDeriv = 5;
497  Sacado::Fad::SFad<double,5> v1Var( numDeriv, 0, v1Now );
498  Sacado::Fad::SFad<double,5> v2Var( numDeriv, 1, v2Now );
499  Sacado::Fad::SFad<double,5> nVar( numDeriv, 2, nNow );
500  Sacado::Fad::SFad<double,5> mVar( numDeriv, 3, mNow );
501  Sacado::Fad::SFad<double,5> hVar( numDeriv, 4, hNow );
502  // parameters
503  Sacado::Fad::SFad<double,5> gMemVar( model_.gMem );
504  Sacado::Fad::SFad<double,5> eLeakVar( model_.eLeak );
505  Sacado::Fad::SFad<double,5> gKVar( model_.gK );
506  Sacado::Fad::SFad<double,5> eKVar( model_.eK );
507  Sacado::Fad::SFad<double,5> gNaVar( model_.gNa );
508  Sacado::Fad::SFad<double,5> eNaVar( model_.eNa );
509 
510  // compute the vaud and derivative terms for KCL 1 F
511  Sacado::Fad::SFad<double,5> resultFad;
512  resultFad = kcl1EquF( v1Var, v2Var, nVar, mVar, hVar, gMemVar, eLeakVar, gKVar, eKVar, gNaVar, eNaVar );
513  kcl1Fvalue = resultFad.val();
514  dkcl1F_dV1 = resultFad.dx(0);
515  dkcl1F_dV2 = resultFad.dx(1);
516  dkcl1F_dn = resultFad.dx(2);
517  dkcl1F_dm = resultFad.dx(3);
518  dkcl1F_dh = resultFad.dx(4);
519 
520  // compute the vaud and derivative terms for KCL 2 F
521  resultFad = kcl2EquF( v1Var, v2Var, nVar, mVar, hVar, gMemVar, eLeakVar, gKVar, eKVar, gNaVar, eNaVar );
522  kcl2Fvalue = resultFad.val();
523  dkcl2F_dV1 = resultFad.dx(0);
524  dkcl2F_dV2 = resultFad.dx(1);
525  dkcl2F_dn = resultFad.dx(2);
526  dkcl2F_dm = resultFad.dx(3);
527  dkcl2F_dh = resultFad.dx(4);
528  }
529 
530  // kcl Q
531  {
532  const int numDeriv = 2;
533  Sacado::Fad::SFad<double,2> v1Var( numDeriv, 0, v1Now );
534  Sacado::Fad::SFad<double,2> v2Var( numDeriv, 1, v2Now );
535 
536  // parameters
537  Sacado::Fad::SFad<double,2> cMemVar( model_.cMem );
538 
539  Sacado::Fad::SFad<double,2> resultFad;
540  resultFad = kcl1EquQ( v1Var, v2Var, cMemVar );
541  kcl1Qvalue = resultFad.val();
542  dkcl1Q_dV1 = resultFad.dx(0);
543  dkcl1Q_dV2 = resultFad.dx(1);
544 
545  resultFad = kcl2EquQ( v1Var, v2Var, cMemVar );
546  kcl2Qvalue = resultFad.val();
547  dkcl2Q_dV1 = resultFad.dx(0);
548  dkcl2Q_dV2 = resultFad.dx(1);
549  }
550 
551  // n - equation
552  {
553  const int numDeriv = 3;
554  Sacado::Fad::SFad<double,3> v1Var( numDeriv, 0, v1Now );
555  Sacado::Fad::SFad<double,3> v2Var( numDeriv, 1, v2Now );
556  Sacado::Fad::SFad<double,3> nVar( numDeriv, 2, nNow );
557  // parameter
558  Sacado::Fad::SFad<double,3> vRestVar( model_.vRest );
559 
560  Sacado::Fad::SFad<double,3> resultFad = nEquF( v1Var, v2Var, nVar, vRestVar);
561  nEquFvalue = resultFad.val();
562  dnF_dV1 = resultFad.dx(0);
563  dnF_dV2 = resultFad.dx(1);
564  dnF_dn = resultFad.dx(2);
565  }
566  {
567  const int numDeriv = 1;
568  Sacado::Fad::SFad<double,1> nVar( numDeriv, 0, nNow );
569 
570  Sacado::Fad::SFad<double,1> resultFad = nEquQ( nVar );
571  nEquQvalue = resultFad.val();
572  dnQ_dn = resultFad.dx(0);
573  }
574 
575  // m - equation
576  {
577  const int numDeriv = 3;
578  Sacado::Fad::SFad<double,3> v1Var( numDeriv, 0, v1Now );
579  Sacado::Fad::SFad<double,3> v2Var( numDeriv, 1, v2Now );
580  Sacado::Fad::SFad<double,3> mVar( numDeriv, 2, mNow );
581  // parameter
582  Sacado::Fad::SFad<double,3> vRestVar( model_.vRest );
583 
584  Sacado::Fad::SFad<double,3> resultFad = mEquF( v1Var, v2Var, mVar, vRestVar );
585  mEquFvalue = resultFad.val();
586  dmF_dV1 = resultFad.dx(0);
587  dmF_dV2 = resultFad.dx(1);
588  dmF_dm = resultFad.dx(2);
589  }
590  {
591  const int numDeriv = 1;
592  Sacado::Fad::SFad<double,1> mVar( numDeriv, 0, mNow );
593 
594  Sacado::Fad::SFad<double,1> resultFad = mEquQ( mVar );
595  mEquQvalue = resultFad.val();
596  dmQ_dm = resultFad.dx(0);
597  }
598 
599  // h - equation
600  {
601  const int numDeriv = 3;
602  Sacado::Fad::SFad<double,3> v1Var( numDeriv, 0, v1Now );
603  Sacado::Fad::SFad<double,3> v2Var( numDeriv, 1, v2Now );
604  Sacado::Fad::SFad<double,3> hVar( numDeriv, 2, hNow );
605  // parameter
606  Sacado::Fad::SFad<double,3> vRestVar( model_.vRest );
607 
608  Sacado::Fad::SFad<double,3> resultFad = hEquF( v1Var, v2Var, hVar, vRestVar );
609  hEquFvalue = resultFad.val();
610  dhF_dV1 = resultFad.dx(0);
611  dhF_dV2 = resultFad.dx(1);
612  dhF_dh = resultFad.dx(2);
613  }
614  {
615  const int numDeriv = 1;
616  Sacado::Fad::SFad<double,1> hVar( numDeriv, 0, hNow );
617 
618  Sacado::Fad::SFad<double,1> resultFad = hEquQ( hVar );
619  hEquQvalue = resultFad.val();
620  dhQ_dh = resultFad.dx(0);
621  }
622 
623  // calculate potassium current
624  potassiumCurrent = model_.gK * pow(nNow, 4.0) * (v1Now - v2Now - model_.eK);
625 
626  // calculate sodium current
627  sodiumCurrent = model_.gNa * pow(mNow, 3.0) * hNow * (v1Now - v2Now - model_.eNa);
628 
629 #ifdef Xyce_DEBUG_DEVICE
631  {
632  double vRest = model_.vRest;
633  Xyce::dout() << "Instance::updateIntermediateVars()" << std::endl
634  << "vRest(input) = " << vRest << std::endl
635  << "v1 = " << v1Now << std::endl
636  << "v2 = " << v2Now << std::endl
637  << "nNow = " << nNow << std::endl
638  << "mNow = " << mNow << std::endl
639  << "hNow = " << hNow << std::endl
640  << "kcl1Fvalue = " << kcl1Fvalue << std::endl
641  << "dkcl1F_dV1 = " << dkcl1F_dV1 << std::endl
642  << "dkcl1F_dV2 = " << dkcl1F_dV2 << std::endl
643  << "dkcl1F_dn = " << dkcl1F_dn << std::endl
644  << "dkcl1F_dm = " << dkcl1F_dm << std::endl
645  << "dkcl1F_dh = " << dkcl1F_dh << std::endl
646  << "kcl2Fvalue = " << kcl2Fvalue << std::endl
647  << "dkcl2F_dV1 = " << dkcl2F_dV1 << std::endl
648  << "dkcl2F_dV2 = " << dkcl2F_dV2 << std::endl
649  << "dkcl2F_dn = " << dkcl2F_dn << std::endl
650  << "dkcl2F_dm = " << dkcl2F_dm << std::endl
651  << "dkcl2F_dh = " << dkcl2F_dh << std::endl
652  << "alphaN = " << alphaN<double>( v1Now, v2Now, vRest) << std::endl
653  << "betaN = " << betaN<double>( v1Now, v2Now, vRest) << std::endl
654  << "nEquFvalue = " << nEquFvalue << std::endl
655  << "dnF_dV1 = " << dnF_dV1 << std::endl
656  << "dnF_dV2 = " << dnF_dV2 << std::endl
657  << "dnF_dn = " << dnF_dn << std::endl
658  << "nEquQvalue = " << nEquQvalue << std::endl
659  << "dnQ_dn = " << dnQ_dn << std::endl
660  << "alphaM = " << alphaM<double>( v1Now, v2Now, vRest) << std::endl
661  << "betaM = " << betaM<double>( v1Now, v2Now, vRest) << std::endl
662  << "mEquFvalue = " << mEquFvalue << std::endl
663  << "dmF_dV1 = " << dmF_dV1 << std::endl
664  << "dmF_dV2 = " << dmF_dV2 << std::endl
665  << "dmF_dm = " << dmF_dm << std::endl
666  << "mEquQvalue = " << mEquQvalue << std::endl
667  << "dmQ_dm = " << dmQ_dm << std::endl
668  << "alphaH = " << alphaH<double>( v1Now, v2Now, vRest) << std::endl
669  << "betaH = " << betaH<double>( v1Now, v2Now, vRest) << std::endl
670  << "hEquFvalue = " << hEquFvalue << std::endl
671  << "dhF_dV1 = " << dhF_dV1 << std::endl
672  << "dhF_dV2 = " << dhF_dV2 << std::endl
673  << "dhF_dh = " << dhF_dh << std::endl
674  << "hEquQvalue = " << hEquQvalue << std::endl
675  << "dhQ_dh = " << dhQ_dh << std::endl
676  << std::endl;
677  }
678 #endif
679 
680  return bsuccess;
681 }
682 //-----------------------------------------------------------------------------
683 // Function : Instance::updatePrimaryState
684 // Purpose :
685 // Special Notes :
686 // Scope : public
687 // Creator : Christy Warrender, SNL, Cognitive Modeling
688 // Creation Date : 06/22/12
689 //-----------------------------------------------------------------------------
691 {
692  bool bsuccess = true;
693 
695 
696  N_LAS_Vector * solVectorPtr = extData.nextSolVectorPtr;
697  N_LAS_Vector * staVectorPtr = extData.nextStaVectorPtr;
698 
699  (*staVectorPtr)[li_KCurrentState] = potassiumCurrent;
700  (*staVectorPtr)[li_NaCurrentState] = sodiumCurrent;
701 
702  return bsuccess;
703 }
704 
705 //-----------------------------------------------------------------------------
706 // Function : Instance::updateSecondaryState
707 // Purpose :
708 // Special Notes :
709 // Scope : public
710 // Creator : Christy Warrender, SNL, Cognitive Modeling
711 // Creation Date : 06/22/12
712 //-----------------------------------------------------------------------------
714 {
715  bool bsuccess = true;
716  N_LAS_Vector * staVectorPtr = extData.nextStaVectorPtr;
717 
718  return bsuccess;
719 }
720 
721 //-----------------------------------------------------------------------------
722 // Function : Instance::loadDAEQVector
723 //
724 // Purpose : Loads the Q-vector contributions for a single
725 // Neuron instance.
726 //
727 // Special Notes : The "Q" vector is part of a standard DAE formalism in
728 // which the system of equations is represented as:
729 //
730 // f(x) = dQ(x)/dt + F(x) - B(t) = 0
731 //
732 // Scope : public
733 // Creator : Christy Warrender, SNL, Cognitive Modeling
734 // Creation Date : 06/22/12
735 //-----------------------------------------------------------------------------
737 {
738  bool bsuccess = true;
739 
740  N_LAS_Vector * daeQVecPtr = extData.daeQVectorPtr;
741 
742  (*daeQVecPtr)[li_Pos] += kcl1Qvalue;
743  (*daeQVecPtr)[li_Neg] += kcl2Qvalue;
744  (*daeQVecPtr)[li_nPro] += nEquQvalue;
745  (*daeQVecPtr)[li_mPro] += mEquQvalue;
746  (*daeQVecPtr)[li_hPro] += hEquQvalue;
747 
748  return bsuccess;
749 }
750 
751 
752 
753 //-----------------------------------------------------------------------------
754 // Function : Instance::loadDAEFVector
755 //
756 // Purpose : Loads the F-vector contributions for a single
757 // Neuron instance.
758 //
759 // Special Notes :
760 //
761 //
762 // Scope : public
763 // Creator : Christy Warrender, SNL, Cognitive Modeling
764 // Creation Date : 06/22/12
765 //-----------------------------------------------------------------------------
767 {
768  bool bsuccess=true;
769 
770  N_LAS_Vector * daeFVecPtr = extData.daeFVectorPtr;
771 
772  (*daeFVecPtr)[li_Pos] += kcl1Fvalue;
773  (*daeFVecPtr)[li_Neg] += kcl2Fvalue;
774  (*daeFVecPtr)[li_nPro] += nEquFvalue;
775  (*daeFVecPtr)[li_mPro] += mEquFvalue;
776  (*daeFVecPtr)[li_hPro] += hEquFvalue;
777 
778  return bsuccess;
779 }
780 
781 //-----------------------------------------------------------------------------
782 // Function : Instance::loadDAEdQdx
783 //
784 // Purpose : Loads the Q-vector contributions for a single
785 // Neuron instance.
786 // Scope : public
787 // Creator : Christy Warrender, SNL, Cognitive Modeling
788 // Creation Date : 06/22/12
789 //-----------------------------------------------------------------------------
791 {
792  bool bsuccess = true;
793 
794  N_LAS_Matrix * dQdxMatPtr = extData.dQdxMatrixPtr;
795 
796  (*dQdxMatPtr)[li_Pos][APosEquPosNodeOffset] += dkcl1Q_dV1;
797  (*dQdxMatPtr)[li_Pos][APosEquNegNodeOffset] += dkcl1Q_dV2;
798 
799  (*dQdxMatPtr)[li_Neg][ANegEquPosNodeOffset] += dkcl2Q_dV1;
800  (*dQdxMatPtr)[li_Neg][ANegEquNegNodeOffset] += dkcl2Q_dV2;
801 
802  (*dQdxMatPtr)[li_nPro][ANEquNNodeOffset] += dnQ_dn;
803 
804  (*dQdxMatPtr)[li_mPro][AMEquMNodeOffset] += dmQ_dm;
805 
806  (*dQdxMatPtr)[li_hPro][AHEquHNodeOffset] += dhQ_dh;
807 
808  return bsuccess;
809 }
810 
811 
812 
813 //-----------------------------------------------------------------------------
814 // Function : Instance::loadDAEdFdx ()
815 //
816 // Purpose : Loads the F-vector contributions for a single
817 // Neuron instance.
818 //
819 // Special Notes : This is an algebraic constaint.
820 //
821 // Scope : public
822 // Creator : Christy Warrender, SNL, Cognitive Modeling
823 // Creation Date : 06/22/12
824 //-----------------------------------------------------------------------------
826 {
827  bool bsuccess = true;
828 
829  N_LAS_Matrix * dFdxMatPtr = extData.dFdxMatrixPtr;
830 
831  (*dFdxMatPtr)[li_Pos][APosEquPosNodeOffset] += dkcl1F_dV1;
832  (*dFdxMatPtr)[li_Pos][APosEquNegNodeOffset] += dkcl1F_dV2;
833  (*dFdxMatPtr)[li_Pos][APosEquNNodeOffset] += dkcl1F_dn;
834  (*dFdxMatPtr)[li_Pos][APosEquMNodeOffset] += dkcl1F_dm;
835  (*dFdxMatPtr)[li_Pos][APosEquHNodeOffset] += dkcl1F_dh;
836 
837  (*dFdxMatPtr)[li_Neg][ANegEquPosNodeOffset] += dkcl2F_dV1;
838  (*dFdxMatPtr)[li_Neg][ANegEquNegNodeOffset] += dkcl2F_dV2;
839  (*dFdxMatPtr)[li_Neg][ANegEquNNodeOffset] += dkcl2F_dn;
840  (*dFdxMatPtr)[li_Neg][ANegEquMNodeOffset] += dkcl2F_dm;
841  (*dFdxMatPtr)[li_Neg][ANegEquHNodeOffset] += dkcl2F_dh;
842 
843  (*dFdxMatPtr)[li_nPro][ANEquPosNodeOffset] += dnF_dV1;
844  (*dFdxMatPtr)[li_nPro][ANEquNegNodeOffset] += dnF_dV2;
845  (*dFdxMatPtr)[li_nPro][ANEquNNodeOffset] += dnF_dn;
846 
847  (*dFdxMatPtr)[li_mPro][AMEquPosNodeOffset] += dmF_dV1;
848  (*dFdxMatPtr)[li_mPro][AMEquNegNodeOffset] += dmF_dV2;
849  (*dFdxMatPtr)[li_mPro][AMEquMNodeOffset] += dmF_dm;
850 
851  (*dFdxMatPtr)[li_hPro][AHEquPosNodeOffset] += dhF_dV1;
852  (*dFdxMatPtr)[li_hPro][AHEquNegNodeOffset] += dhF_dV2;
853  (*dFdxMatPtr)[li_hPro][AHEquHNodeOffset] += dhF_dh;
854 
855  return bsuccess;
856 }
857 
858 //-----------------------------------------------------------------------------
859 // Function : Instance::setIC
860 // Purpose :
861 // Special Notes :
862 // Scope : public
863 // Creator : Christy Warrender, SNL, Cognitive Modeling
864 // Creation Date : 06/22/12
865 //-----------------------------------------------------------------------------
867 {
868  bool bsuccess = true;
869 
870  return bsuccess;
871 }
872 
873 //-----------------------------------------------------------------------------
874 // Function : Instance::varTypes
875 // Purpose :
876 // Special Notes :
877 // Scope : public
878 // Creator : Christy Warrender, SNL, Cognitive Modeling
879 // Creation Date : 06/22/12
880 //-----------------------------------------------------------------------------
881 void Instance::varTypes( std::vector<char> & varTypeVec )
882 {
883  //varTypeVec.resize(1);
884  //varTypeVec[0] = 'I';
885 }
886 
887 
888 //-----------------------------------------------------------------------------
889 // Function : Model::processParams
890 // Purpose :
891 // Special Notes :
892 // Scope : public
893 // Creator : Christy Warrender, SNL, Cognitive Modeling
894 // Creation Date : 06/22/12
895 //-----------------------------------------------------------------------------
897 {
898  return true;
899 }
900 
901 //----------------------------------------------------------------------------
902 // Function : Model::processInstanceParams
903 // Purpose :
904 // Special Notes :
905 // Scope : public
906 // Creator : Christy Warrender, SNL, Cognitive Modeling
907 // Creation Date : 06/22/12
908 //----------------------------------------------------------------------------
910 {
911 
912  std::vector<Instance*>::iterator iter;
913  std::vector<Instance*>::iterator first = instanceContainer.begin();
914  std::vector<Instance*>::iterator last = instanceContainer.end();
915 
916  for (iter=first; iter!=last; ++iter)
917  {
918  (*iter)->processParams();
919  }
920 
921  return true;
922 }
923 
924 //-----------------------------------------------------------------------------
925 // Function : Model::Model
926 // Purpose : block constructor
927 // Special Notes :
928 // Scope : public
929 // Creator : Christy Warrender, SNL, Cognitive Modeling
930 // Creation Date : 06/22/12
931 //-----------------------------------------------------------------------------
933  const Configuration & configuration,
934  const ModelBlock & MB,
935  const FactoryBlock & factory_block)
936  : DeviceModel(MB, configuration.getModelParameters(), factory_block)
937 {
938 
939  // Set params to constant default values:
940  setDefaultParams ();
941 
942  // Set params according to .model line and constant defaults from metadata:
943  setModParams (MB.params);
944 
945  // Set any non-constant parameter defaults:
946  //if (!given("TNOM"))
947  // tnom = getDeviceOptions().tnom;
948 
949  // Calculate any parameters specified as expressions:
951 
952  // calculate dependent (ie computed) params and check for errors:
953 
954  processParams ();
955 }
956 
957 //-----------------------------------------------------------------------------
958 // Function : Model::~Model
959 // Purpose : destructor
960 // Special Notes :
961 // Scope : public
962 // Creator : Christy Warrender, SNL, Cognitive Modeling
963 // Creation Date : 06/22/12
964 //-----------------------------------------------------------------------------
966 {
967  std::vector<Instance*>::iterator iter;
968  std::vector<Instance*>::iterator first = instanceContainer.begin();
969  std::vector<Instance*>::iterator last = instanceContainer.end();
970 
971  for (iter=first; iter!=last; ++iter)
972  {
973  delete (*iter);
974  }
975 }
976 
977 // additional Declarations
978 
979 //-----------------------------------------------------------------------------
980 // Function : Model::printOutInstances
981 // Purpose : debugging tool.
982 // Special Notes :
983 // Scope : public
984 // Creator : Christy Warrender, SNL, Cognitive Modeling
985 // Creation Date : 06/22/12
986 //-----------------------------------------------------------------------------
987 std::ostream &Model::printOutInstances(std::ostream &os) const
988 {
989  std::vector<Instance*>::const_iterator iter;
990  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
991  std::vector<Instance*>::const_iterator last = instanceContainer.end();
992 
993  int i, isize;
994  isize = instanceContainer.size();
995 
996  os << std::endl;
997  os << "Number of Neuron instances: " << isize << std::endl;
998  os << " name=\t\tmodelName\tParameters" << std::endl;
999  for (i=0, iter=first; iter!=last; ++iter, ++i)
1000  {
1001  os << " " << i << ": " << (*iter)->getName() << "\t";
1002  os << getName();
1003  os << std::endl;
1004  }
1005 
1006  os << std::endl;
1007  return os;
1008 }
1009 
1010 //-----------------------------------------------------------------------------
1011 // Function : Model::forEachInstance
1012 // Purpose :
1013 // Special Notes :
1014 // Scope : public
1015 // Creator : David Baur
1016 // Creation Date : 2/4/2014
1017 //-----------------------------------------------------------------------------
1018 /// Apply a device instance "op" to all instances associated with this
1019 /// model
1020 ///
1021 /// @param[in] op Operator to apply to all instances.
1022 ///
1023 ///
1024 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
1025 {
1026  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1027  op(*it);
1028 }
1029 
1030 
1031 
1032 //-----------------------------------------------------------------------------
1033 // Function : Master::updateState
1034 // Purpose :
1035 // Special Notes :
1036 // Scope : public
1037 // Creator : Christy Warrender, SNL, Cognitive Modeling
1038 // Creation Date : 06/22/12
1039 //-----------------------------------------------------------------------------
1040 bool Master::updateState (double * solVec, double * staVec, double * stoVec)
1041 {
1042  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
1043  {
1044  // just call the instance level update state
1045  (*it)->updatePrimaryState();
1046  }
1047  return true;
1048 }
1049 
1050 Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
1051 {
1052 
1053  return new Master(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
1054 }
1055 
1057 {
1059  .registerDevice("neuron", 9)
1060  .registerModelType("neuron", 9);
1061 }
1062 
1063 } // namespace Neuron9
1064 } // namespace Device
1065 } // namespace Xyce