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.25.2.2 $
40 //
41 // Revision Date : $Date: 2014/03/06 23:33:43 $
42 //
43 // Current Owner : $Author: tvrusso $
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  {
359  std::string tmpstr;
360 
361  tmpstr = getName() + "_N";
362  spiceInternalName (tmpstr);
363  intNameMap[ li_nPro ] = tmpstr;
364  tmpstr = getName() + "_M";
365  spiceInternalName (tmpstr);
366  intNameMap[ li_mPro ] = tmpstr;
367  tmpstr = getName() + "_H";
368  spiceInternalName (tmpstr);
369  intNameMap[ li_hPro ] = tmpstr;
370  }
371  return intNameMap;
372 }
373 
374 //-----------------------------------------------------------------------------
375 // Function : Instance::registerStateLIDs
376 // Purpose :
377 // Special Notes :
378 // Scope : public
379 // Creator : Christy Warrender, SNL, Cognitive Modeling
380 // Creation Date : 06/22/12
381 //-----------------------------------------------------------------------------
382 void Instance::registerStateLIDs( const std::vector<int> & staLIDVecRef )
383 {
384  AssertLIDs(staLIDVecRef.size() == numStateVars);
385 
386  // copy over the global ID lists.
387  staLIDVec = staLIDVecRef;
388 
389  li_KCurrentState = staLIDVec[0];
390  li_NaCurrentState = staLIDVec[1];
391 
392 }
393 
394 //-----------------------------------------------------------------------------
395 // Function : Instance::loadDeviceMask
396 //
397 // Purpose : Loads the zero elements of the device mask
398 //
399 // Special Notes : elements of the error vector associated with zero
400 // elements of the mask will not be included in weighted
401 // norms by the time integrator.
402 //
403 // Scope : public
404 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
405 // Creation Date : 01/19/07
406 //-----------------------------------------------------------------------------
408 {
409  bool returnVal=false;
410  N_LAS_Vector * maskVectorPtr = extData.deviceMaskVectorPtr;
411 
412 // Xyce::dout() << "Masking n, m and h" << std::endl;
413 // (*maskVectorPtr)[li_nPro] = 0.0;
414 // (*maskVectorPtr)[li_mPro] = 0.0;
415 // (*maskVectorPtr)[li_hPro] = 0.0;
416 // returnVal = true;
417 
418  return (returnVal);
419 }
420 
421 //-----------------------------------------------------------------------------
422 // Function : Instance::jacobianStamp
423 // Purpose :
424 // Special Notes :
425 // Scope : public
426 // Creator : Christy Warrender, SNL, Cognitive Modeling
427 // Creation Date : 06/22/12
428 //-----------------------------------------------------------------------------
429 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
430 {
431  return jacStamp;
432 }
433 
434 //-----------------------------------------------------------------------------
435 // Function : Instance::registerJacLIDs
436 // Purpose :
437 // Special Notes :
438 // Scope : public
439 // Creator : Christy Warrender, SNL, Cognitive Modeling
440 // Creation Date : 06/22/12
441 //-----------------------------------------------------------------------------
442 void Instance::registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec )
443 {
444  DeviceInstance::registerJacLIDs( jacLIDVec );
445 
446  APosEquPosNodeOffset = jacLIDVec[0][0];
447  APosEquNegNodeOffset = jacLIDVec[0][1];
448  APosEquNNodeOffset = jacLIDVec[0][2];
449  APosEquMNodeOffset = jacLIDVec[0][3];
450  APosEquHNodeOffset = jacLIDVec[0][4];
451 
452  ANegEquPosNodeOffset = jacLIDVec[1][0];
453  ANegEquNegNodeOffset = jacLIDVec[1][1];
454  ANegEquNNodeOffset = jacLIDVec[1][2];
455  ANegEquMNodeOffset = jacLIDVec[1][3];
456  ANegEquHNodeOffset = jacLIDVec[1][4];
457 
458  ANEquPosNodeOffset = jacLIDVec[2][0];
459  ANEquNegNodeOffset = jacLIDVec[2][1];
460  ANEquNNodeOffset = jacLIDVec[2][2];
461 
462  AMEquPosNodeOffset = jacLIDVec[3][0];
463  AMEquNegNodeOffset = jacLIDVec[3][1];
464  AMEquMNodeOffset = jacLIDVec[3][2];
465 
466  AHEquPosNodeOffset = jacLIDVec[4][0];
467  AHEquNegNodeOffset = jacLIDVec[4][1];
468  AHEquHNodeOffset = jacLIDVec[4][2];
469 }
470 
471 
472 //-----------------------------------------------------------------------------
473 // Function : Instance::updateIntermediateVars
474 // Purpose :
475 // Special Notes :
476 // Scope : public
477 // Creator : Christy Warrender, SNL, Cognitive Modeling
478 // Creation Date : 06/22/12
479 //-----------------------------------------------------------------------------
481 {
482  //Xyce::dout() << "Instance::updateIntermediateVars()" << std::endl;
483 
484  bool bsuccess = true;
485 
486  // here we take the current solutions for V1, V2, n, m and h
487  // and use those to calculate all the terms needed for the next
488  // load cycle (F, Q, dFdX, dQdX)
489  N_LAS_Vector * solVectorPtr = extData.nextSolVectorPtr;
490 
491  // use suffix "now" to to clarify that this for the latest solution
492  double v1Now = (*solVectorPtr)[li_Pos];
493  double v2Now = (*solVectorPtr)[li_Neg];
494  double nNow = (*solVectorPtr)[li_nPro];
495  double mNow = (*solVectorPtr)[li_mPro];
496  double hNow = (*solVectorPtr)[li_hPro];
497 
498  // get function and derivative values
499  // independent variables
500  // use scoping to avoid lots of similar variable names
501 
502  // kcl F
503  {
504  const int numDeriv = 5;
505  Sacado::Fad::SFad<double,5> v1Var( numDeriv, 0, v1Now );
506  Sacado::Fad::SFad<double,5> v2Var( numDeriv, 1, v2Now );
507  Sacado::Fad::SFad<double,5> nVar( numDeriv, 2, nNow );
508  Sacado::Fad::SFad<double,5> mVar( numDeriv, 3, mNow );
509  Sacado::Fad::SFad<double,5> hVar( numDeriv, 4, hNow );
510  // parameters
511  Sacado::Fad::SFad<double,5> gMemVar( model_.gMem );
512  Sacado::Fad::SFad<double,5> eLeakVar( model_.eLeak );
513  Sacado::Fad::SFad<double,5> gKVar( model_.gK );
514  Sacado::Fad::SFad<double,5> eKVar( model_.eK );
515  Sacado::Fad::SFad<double,5> gNaVar( model_.gNa );
516  Sacado::Fad::SFad<double,5> eNaVar( model_.eNa );
517 
518  // compute the vaud and derivative terms for KCL 1 F
519  Sacado::Fad::SFad<double,5> resultFad;
520  resultFad = kcl1EquF( v1Var, v2Var, nVar, mVar, hVar, gMemVar, eLeakVar, gKVar, eKVar, gNaVar, eNaVar );
521  kcl1Fvalue = resultFad.val();
522  dkcl1F_dV1 = resultFad.dx(0);
523  dkcl1F_dV2 = resultFad.dx(1);
524  dkcl1F_dn = resultFad.dx(2);
525  dkcl1F_dm = resultFad.dx(3);
526  dkcl1F_dh = resultFad.dx(4);
527 
528  // compute the vaud and derivative terms for KCL 2 F
529  resultFad = kcl2EquF( v1Var, v2Var, nVar, mVar, hVar, gMemVar, eLeakVar, gKVar, eKVar, gNaVar, eNaVar );
530  kcl2Fvalue = resultFad.val();
531  dkcl2F_dV1 = resultFad.dx(0);
532  dkcl2F_dV2 = resultFad.dx(1);
533  dkcl2F_dn = resultFad.dx(2);
534  dkcl2F_dm = resultFad.dx(3);
535  dkcl2F_dh = resultFad.dx(4);
536  }
537 
538  // kcl Q
539  {
540  const int numDeriv = 2;
541  Sacado::Fad::SFad<double,2> v1Var( numDeriv, 0, v1Now );
542  Sacado::Fad::SFad<double,2> v2Var( numDeriv, 1, v2Now );
543 
544  // parameters
545  Sacado::Fad::SFad<double,2> cMemVar( model_.cMem );
546 
547  Sacado::Fad::SFad<double,2> resultFad;
548  resultFad = kcl1EquQ( v1Var, v2Var, cMemVar );
549  kcl1Qvalue = resultFad.val();
550  dkcl1Q_dV1 = resultFad.dx(0);
551  dkcl1Q_dV2 = resultFad.dx(1);
552 
553  resultFad = kcl2EquQ( v1Var, v2Var, cMemVar );
554  kcl2Qvalue = resultFad.val();
555  dkcl2Q_dV1 = resultFad.dx(0);
556  dkcl2Q_dV2 = resultFad.dx(1);
557  }
558 
559  // n - equation
560  {
561  const int numDeriv = 3;
562  Sacado::Fad::SFad<double,3> v1Var( numDeriv, 0, v1Now );
563  Sacado::Fad::SFad<double,3> v2Var( numDeriv, 1, v2Now );
564  Sacado::Fad::SFad<double,3> nVar( numDeriv, 2, nNow );
565  // parameter
566  Sacado::Fad::SFad<double,3> vRestVar( model_.vRest );
567 
568  Sacado::Fad::SFad<double,3> resultFad = nEquF( v1Var, v2Var, nVar, vRestVar);
569  nEquFvalue = resultFad.val();
570  dnF_dV1 = resultFad.dx(0);
571  dnF_dV2 = resultFad.dx(1);
572  dnF_dn = resultFad.dx(2);
573  }
574  {
575  const int numDeriv = 1;
576  Sacado::Fad::SFad<double,1> nVar( numDeriv, 0, nNow );
577 
578  Sacado::Fad::SFad<double,1> resultFad = nEquQ( nVar );
579  nEquQvalue = resultFad.val();
580  dnQ_dn = resultFad.dx(0);
581  }
582 
583  // m - equation
584  {
585  const int numDeriv = 3;
586  Sacado::Fad::SFad<double,3> v1Var( numDeriv, 0, v1Now );
587  Sacado::Fad::SFad<double,3> v2Var( numDeriv, 1, v2Now );
588  Sacado::Fad::SFad<double,3> mVar( numDeriv, 2, mNow );
589  // parameter
590  Sacado::Fad::SFad<double,3> vRestVar( model_.vRest );
591 
592  Sacado::Fad::SFad<double,3> resultFad = mEquF( v1Var, v2Var, mVar, vRestVar );
593  mEquFvalue = resultFad.val();
594  dmF_dV1 = resultFad.dx(0);
595  dmF_dV2 = resultFad.dx(1);
596  dmF_dm = resultFad.dx(2);
597  }
598  {
599  const int numDeriv = 1;
600  Sacado::Fad::SFad<double,1> mVar( numDeriv, 0, mNow );
601 
602  Sacado::Fad::SFad<double,1> resultFad = mEquQ( mVar );
603  mEquQvalue = resultFad.val();
604  dmQ_dm = resultFad.dx(0);
605  }
606 
607  // h - equation
608  {
609  const int numDeriv = 3;
610  Sacado::Fad::SFad<double,3> v1Var( numDeriv, 0, v1Now );
611  Sacado::Fad::SFad<double,3> v2Var( numDeriv, 1, v2Now );
612  Sacado::Fad::SFad<double,3> hVar( numDeriv, 2, hNow );
613  // parameter
614  Sacado::Fad::SFad<double,3> vRestVar( model_.vRest );
615 
616  Sacado::Fad::SFad<double,3> resultFad = hEquF( v1Var, v2Var, hVar, vRestVar );
617  hEquFvalue = resultFad.val();
618  dhF_dV1 = resultFad.dx(0);
619  dhF_dV2 = resultFad.dx(1);
620  dhF_dh = resultFad.dx(2);
621  }
622  {
623  const int numDeriv = 1;
624  Sacado::Fad::SFad<double,1> hVar( numDeriv, 0, hNow );
625 
626  Sacado::Fad::SFad<double,1> resultFad = hEquQ( hVar );
627  hEquQvalue = resultFad.val();
628  dhQ_dh = resultFad.dx(0);
629  }
630 
631  // calculate potassium current
632  potassiumCurrent = model_.gK * pow(nNow, 4.0) * (v1Now - v2Now - model_.eK);
633 
634  // calculate sodium current
635  sodiumCurrent = model_.gNa * pow(mNow, 3.0) * hNow * (v1Now - v2Now - model_.eNa);
636 
637 #ifdef Xyce_DEBUG_DEVICE
639  {
640  double vRest = model_.vRest;
641  Xyce::dout() << "Instance::updateIntermediateVars()" << std::endl
642  << "vRest(input) = " << vRest << std::endl
643  << "v1 = " << v1Now << std::endl
644  << "v2 = " << v2Now << std::endl
645  << "nNow = " << nNow << std::endl
646  << "mNow = " << mNow << std::endl
647  << "hNow = " << hNow << std::endl
648  << "kcl1Fvalue = " << kcl1Fvalue << std::endl
649  << "dkcl1F_dV1 = " << dkcl1F_dV1 << std::endl
650  << "dkcl1F_dV2 = " << dkcl1F_dV2 << std::endl
651  << "dkcl1F_dn = " << dkcl1F_dn << std::endl
652  << "dkcl1F_dm = " << dkcl1F_dm << std::endl
653  << "dkcl1F_dh = " << dkcl1F_dh << std::endl
654  << "kcl2Fvalue = " << kcl2Fvalue << std::endl
655  << "dkcl2F_dV1 = " << dkcl2F_dV1 << std::endl
656  << "dkcl2F_dV2 = " << dkcl2F_dV2 << std::endl
657  << "dkcl2F_dn = " << dkcl2F_dn << std::endl
658  << "dkcl2F_dm = " << dkcl2F_dm << std::endl
659  << "dkcl2F_dh = " << dkcl2F_dh << std::endl
660  << "alphaN = " << alphaN<double>( v1Now, v2Now, vRest) << std::endl
661  << "betaN = " << betaN<double>( v1Now, v2Now, vRest) << std::endl
662  << "nEquFvalue = " << nEquFvalue << std::endl
663  << "dnF_dV1 = " << dnF_dV1 << std::endl
664  << "dnF_dV2 = " << dnF_dV2 << std::endl
665  << "dnF_dn = " << dnF_dn << std::endl
666  << "nEquQvalue = " << nEquQvalue << std::endl
667  << "dnQ_dn = " << dnQ_dn << std::endl
668  << "alphaM = " << alphaM<double>( v1Now, v2Now, vRest) << std::endl
669  << "betaM = " << betaM<double>( v1Now, v2Now, vRest) << std::endl
670  << "mEquFvalue = " << mEquFvalue << std::endl
671  << "dmF_dV1 = " << dmF_dV1 << std::endl
672  << "dmF_dV2 = " << dmF_dV2 << std::endl
673  << "dmF_dm = " << dmF_dm << std::endl
674  << "mEquQvalue = " << mEquQvalue << std::endl
675  << "dmQ_dm = " << dmQ_dm << std::endl
676  << "alphaH = " << alphaH<double>( v1Now, v2Now, vRest) << std::endl
677  << "betaH = " << betaH<double>( v1Now, v2Now, vRest) << std::endl
678  << "hEquFvalue = " << hEquFvalue << std::endl
679  << "dhF_dV1 = " << dhF_dV1 << std::endl
680  << "dhF_dV2 = " << dhF_dV2 << std::endl
681  << "dhF_dh = " << dhF_dh << std::endl
682  << "hEquQvalue = " << hEquQvalue << std::endl
683  << "dhQ_dh = " << dhQ_dh << std::endl
684  << std::endl;
685  }
686 #endif
687 
688  return bsuccess;
689 }
690 //-----------------------------------------------------------------------------
691 // Function : Instance::updatePrimaryState
692 // Purpose :
693 // Special Notes :
694 // Scope : public
695 // Creator : Christy Warrender, SNL, Cognitive Modeling
696 // Creation Date : 06/22/12
697 //-----------------------------------------------------------------------------
699 {
700  bool bsuccess = true;
701 
703 
704  N_LAS_Vector * solVectorPtr = extData.nextSolVectorPtr;
705  N_LAS_Vector * staVectorPtr = extData.nextStaVectorPtr;
706 
707  (*staVectorPtr)[li_KCurrentState] = potassiumCurrent;
708  (*staVectorPtr)[li_NaCurrentState] = sodiumCurrent;
709 
710  return bsuccess;
711 }
712 
713 //-----------------------------------------------------------------------------
714 // Function : Instance::updateSecondaryState
715 // Purpose :
716 // Special Notes :
717 // Scope : public
718 // Creator : Christy Warrender, SNL, Cognitive Modeling
719 // Creation Date : 06/22/12
720 //-----------------------------------------------------------------------------
722 {
723  bool bsuccess = true;
724  N_LAS_Vector * staVectorPtr = extData.nextStaVectorPtr;
725 
726  return bsuccess;
727 }
728 
729 //-----------------------------------------------------------------------------
730 // Function : Instance::loadDAEQVector
731 //
732 // Purpose : Loads the Q-vector contributions for a single
733 // Neuron instance.
734 //
735 // Special Notes : The "Q" vector is part of a standard DAE formalism in
736 // which the system of equations is represented as:
737 //
738 // f(x) = dQ(x)/dt + F(x) - B(t) = 0
739 //
740 // Scope : public
741 // Creator : Christy Warrender, SNL, Cognitive Modeling
742 // Creation Date : 06/22/12
743 //-----------------------------------------------------------------------------
745 {
746  bool bsuccess = true;
747 
748  N_LAS_Vector * daeQVecPtr = extData.daeQVectorPtr;
749 
750  (*daeQVecPtr)[li_Pos] += kcl1Qvalue;
751  (*daeQVecPtr)[li_Neg] += kcl2Qvalue;
752  (*daeQVecPtr)[li_nPro] += nEquQvalue;
753  (*daeQVecPtr)[li_mPro] += mEquQvalue;
754  (*daeQVecPtr)[li_hPro] += hEquQvalue;
755 
756  return bsuccess;
757 }
758 
759 
760 
761 //-----------------------------------------------------------------------------
762 // Function : Instance::loadDAEFVector
763 //
764 // Purpose : Loads the F-vector contributions for a single
765 // Neuron instance.
766 //
767 // Special Notes :
768 //
769 //
770 // Scope : public
771 // Creator : Christy Warrender, SNL, Cognitive Modeling
772 // Creation Date : 06/22/12
773 //-----------------------------------------------------------------------------
775 {
776  bool bsuccess=true;
777 
778  N_LAS_Vector * daeFVecPtr = extData.daeFVectorPtr;
779 
780  (*daeFVecPtr)[li_Pos] += kcl1Fvalue;
781  (*daeFVecPtr)[li_Neg] += kcl2Fvalue;
782  (*daeFVecPtr)[li_nPro] += nEquFvalue;
783  (*daeFVecPtr)[li_mPro] += mEquFvalue;
784  (*daeFVecPtr)[li_hPro] += hEquFvalue;
785 
786  return bsuccess;
787 }
788 
789 //-----------------------------------------------------------------------------
790 // Function : Instance::loadDAEdQdx
791 //
792 // Purpose : Loads the Q-vector contributions for a single
793 // Neuron instance.
794 // Scope : public
795 // Creator : Christy Warrender, SNL, Cognitive Modeling
796 // Creation Date : 06/22/12
797 //-----------------------------------------------------------------------------
799 {
800  bool bsuccess = true;
801 
802  N_LAS_Matrix * dQdxMatPtr = extData.dQdxMatrixPtr;
803 
804  (*dQdxMatPtr)[li_Pos][APosEquPosNodeOffset] += dkcl1Q_dV1;
805  (*dQdxMatPtr)[li_Pos][APosEquNegNodeOffset] += dkcl1Q_dV2;
806 
807  (*dQdxMatPtr)[li_Neg][ANegEquPosNodeOffset] += dkcl2Q_dV1;
808  (*dQdxMatPtr)[li_Neg][ANegEquNegNodeOffset] += dkcl2Q_dV2;
809 
810  (*dQdxMatPtr)[li_nPro][ANEquNNodeOffset] += dnQ_dn;
811 
812  (*dQdxMatPtr)[li_mPro][AMEquMNodeOffset] += dmQ_dm;
813 
814  (*dQdxMatPtr)[li_hPro][AHEquHNodeOffset] += dhQ_dh;
815 
816  return bsuccess;
817 }
818 
819 
820 
821 //-----------------------------------------------------------------------------
822 // Function : Instance::loadDAEdFdx ()
823 //
824 // Purpose : Loads the F-vector contributions for a single
825 // Neuron instance.
826 //
827 // Special Notes : This is an algebraic constaint.
828 //
829 // Scope : public
830 // Creator : Christy Warrender, SNL, Cognitive Modeling
831 // Creation Date : 06/22/12
832 //-----------------------------------------------------------------------------
834 {
835  bool bsuccess = true;
836 
837  N_LAS_Matrix * dFdxMatPtr = extData.dFdxMatrixPtr;
838 
839  (*dFdxMatPtr)[li_Pos][APosEquPosNodeOffset] += dkcl1F_dV1;
840  (*dFdxMatPtr)[li_Pos][APosEquNegNodeOffset] += dkcl1F_dV2;
841  (*dFdxMatPtr)[li_Pos][APosEquNNodeOffset] += dkcl1F_dn;
842  (*dFdxMatPtr)[li_Pos][APosEquMNodeOffset] += dkcl1F_dm;
843  (*dFdxMatPtr)[li_Pos][APosEquHNodeOffset] += dkcl1F_dh;
844 
845  (*dFdxMatPtr)[li_Neg][ANegEquPosNodeOffset] += dkcl2F_dV1;
846  (*dFdxMatPtr)[li_Neg][ANegEquNegNodeOffset] += dkcl2F_dV2;
847  (*dFdxMatPtr)[li_Neg][ANegEquNNodeOffset] += dkcl2F_dn;
848  (*dFdxMatPtr)[li_Neg][ANegEquMNodeOffset] += dkcl2F_dm;
849  (*dFdxMatPtr)[li_Neg][ANegEquHNodeOffset] += dkcl2F_dh;
850 
851  (*dFdxMatPtr)[li_nPro][ANEquPosNodeOffset] += dnF_dV1;
852  (*dFdxMatPtr)[li_nPro][ANEquNegNodeOffset] += dnF_dV2;
853  (*dFdxMatPtr)[li_nPro][ANEquNNodeOffset] += dnF_dn;
854 
855  (*dFdxMatPtr)[li_mPro][AMEquPosNodeOffset] += dmF_dV1;
856  (*dFdxMatPtr)[li_mPro][AMEquNegNodeOffset] += dmF_dV2;
857  (*dFdxMatPtr)[li_mPro][AMEquMNodeOffset] += dmF_dm;
858 
859  (*dFdxMatPtr)[li_hPro][AHEquPosNodeOffset] += dhF_dV1;
860  (*dFdxMatPtr)[li_hPro][AHEquNegNodeOffset] += dhF_dV2;
861  (*dFdxMatPtr)[li_hPro][AHEquHNodeOffset] += dhF_dh;
862 
863  return bsuccess;
864 }
865 
866 //-----------------------------------------------------------------------------
867 // Function : Instance::setIC
868 // Purpose :
869 // Special Notes :
870 // Scope : public
871 // Creator : Christy Warrender, SNL, Cognitive Modeling
872 // Creation Date : 06/22/12
873 //-----------------------------------------------------------------------------
875 {
876  bool bsuccess = true;
877 
878  return bsuccess;
879 }
880 
881 //-----------------------------------------------------------------------------
882 // Function : Instance::varTypes
883 // Purpose :
884 // Special Notes :
885 // Scope : public
886 // Creator : Christy Warrender, SNL, Cognitive Modeling
887 // Creation Date : 06/22/12
888 //-----------------------------------------------------------------------------
889 void Instance::varTypes( std::vector<char> & varTypeVec )
890 {
891  //varTypeVec.resize(1);
892  //varTypeVec[0] = 'I';
893 }
894 
895 
896 //-----------------------------------------------------------------------------
897 // Function : Model::processParams
898 // Purpose :
899 // Special Notes :
900 // Scope : public
901 // Creator : Christy Warrender, SNL, Cognitive Modeling
902 // Creation Date : 06/22/12
903 //-----------------------------------------------------------------------------
905 {
906  return true;
907 }
908 
909 //----------------------------------------------------------------------------
910 // Function : Model::processInstanceParams
911 // Purpose :
912 // Special Notes :
913 // Scope : public
914 // Creator : Christy Warrender, SNL, Cognitive Modeling
915 // Creation Date : 06/22/12
916 //----------------------------------------------------------------------------
918 {
919 
920  std::vector<Instance*>::iterator iter;
921  std::vector<Instance*>::iterator first = instanceContainer.begin();
922  std::vector<Instance*>::iterator last = instanceContainer.end();
923 
924  for (iter=first; iter!=last; ++iter)
925  {
926  (*iter)->processParams();
927  }
928 
929  return true;
930 }
931 
932 //-----------------------------------------------------------------------------
933 // Function : Model::Model
934 // Purpose : block constructor
935 // Special Notes :
936 // Scope : public
937 // Creator : Christy Warrender, SNL, Cognitive Modeling
938 // Creation Date : 06/22/12
939 //-----------------------------------------------------------------------------
941  const Configuration & configuration,
942  const ModelBlock & MB,
943  const FactoryBlock & factory_block)
944  : DeviceModel(MB, configuration.getModelParameters(), factory_block)
945 {
946 
947  // Set params to constant default values:
948  setDefaultParams ();
949 
950  // Set params according to .model line and constant defaults from metadata:
951  setModParams (MB.params);
952 
953  // Set any non-constant parameter defaults:
954  //if (!given("TNOM"))
955  // tnom = getDeviceOptions().tnom;
956 
957  // Calculate any parameters specified as expressions:
959 
960  // calculate dependent (ie computed) params and check for errors:
961 
962  processParams ();
963 }
964 
965 //-----------------------------------------------------------------------------
966 // Function : Model::~Model
967 // Purpose : destructor
968 // Special Notes :
969 // Scope : public
970 // Creator : Christy Warrender, SNL, Cognitive Modeling
971 // Creation Date : 06/22/12
972 //-----------------------------------------------------------------------------
974 {
975  std::vector<Instance*>::iterator iter;
976  std::vector<Instance*>::iterator first = instanceContainer.begin();
977  std::vector<Instance*>::iterator last = instanceContainer.end();
978 
979  for (iter=first; iter!=last; ++iter)
980  {
981  delete (*iter);
982  }
983 }
984 
985 // additional Declarations
986 
987 //-----------------------------------------------------------------------------
988 // Function : Model::printOutInstances
989 // Purpose : debugging tool.
990 // Special Notes :
991 // Scope : public
992 // Creator : Christy Warrender, SNL, Cognitive Modeling
993 // Creation Date : 06/22/12
994 //-----------------------------------------------------------------------------
995 std::ostream &Model::printOutInstances(std::ostream &os) const
996 {
997  std::vector<Instance*>::const_iterator iter;
998  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
999  std::vector<Instance*>::const_iterator last = instanceContainer.end();
1000 
1001  int i, isize;
1002  isize = instanceContainer.size();
1003 
1004  os << std::endl;
1005  os << "Number of Neuron instances: " << isize << std::endl;
1006  os << " name=\t\tmodelName\tParameters" << std::endl;
1007  for (i=0, iter=first; iter!=last; ++iter, ++i)
1008  {
1009  os << " " << i << ": " << (*iter)->getName() << "\t";
1010  os << getName();
1011  os << std::endl;
1012  }
1013 
1014  os << std::endl;
1015  return os;
1016 }
1017 
1018 //-----------------------------------------------------------------------------
1019 // Function : Model::forEachInstance
1020 // Purpose :
1021 // Special Notes :
1022 // Scope : public
1023 // Creator : David Baur
1024 // Creation Date : 2/4/2014
1025 //-----------------------------------------------------------------------------
1026 /// Apply a device instance "op" to all instances associated with this
1027 /// model
1028 ///
1029 /// @param[in] op Operator to apply to all instances.
1030 ///
1031 ///
1032 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
1033 {
1034  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1035  op(*it);
1036 }
1037 
1038 
1039 
1040 //-----------------------------------------------------------------------------
1041 // Function : Master::updateState
1042 // Purpose :
1043 // Special Notes :
1044 // Scope : public
1045 // Creator : Christy Warrender, SNL, Cognitive Modeling
1046 // Creation Date : 06/22/12
1047 //-----------------------------------------------------------------------------
1048 bool Master::updateState (double * solVec, double * staVec, double * stoVec)
1049 {
1050  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
1051  {
1052  // just call the instance level update state
1053  (*it)->updatePrimaryState();
1054  }
1055  return true;
1056 }
1057 
1058 Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
1059 {
1060 
1061  return new Master(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
1062 }
1063 
1065 {
1067  .registerDevice("neuron", 9)
1068  .registerModelType("neuron", 9);
1069 }
1070 
1071 } // namespace Neuron9
1072 } // namespace Device
1073 } // namespace Xyce