Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_DEV_Neuron2.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_Neuron2.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.42 $
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_Neuron2.h>
59 #include <N_DEV_SolverState.h>
60 #include <N_DEV_Message.h>
61 #include <N_ERH_ErrorMgr.h>
62 
63 #include <N_LAS_Vector.h>
64 #include <N_LAS_Matrix.h>
65 
66 namespace Xyce {
67 namespace Device {
68 
69 
70 namespace Neuron2 {
71 
72 
74 {
75 }
76 
78 {
79  // Set up map for normal (double) param variables:
80  p.addPar ("CMEM", 0.0, false, ParameterType::NO_DEP,
83  U_FARAD, CAT_NONE, "Membrane capacitance");
84 
85  p.addPar ("GMEM", 0.0, false, ParameterType::NO_DEP,
88  U_OHMM1, CAT_NONE, "Membrane conductance");
89 
90  p.addPar ("VREST", 0.0, false, ParameterType::NO_DEP,
93  U_VOLT, CAT_NONE, "Resting potential");
94 
95  p.addPar ("EK", 0.0, false, ParameterType::NO_DEP,
98  U_VOLT, CAT_NONE, "Potassium resting potential");
99 
100  p.addPar ("GK", 0.0, false, ParameterType::NO_DEP,
103  U_OHMM1, CAT_NONE, "Potassium base conductance");
104 
105  p.addPar ("ENA", 0.0, false, ParameterType::NO_DEP,
108  U_VOLT, CAT_NONE, "Sodium resting potential");
109 
110  p.addPar ("GNA", 0.0, false, ParameterType::NO_DEP,
113  U_OHMM1, CAT_NONE, "Sodium base conductance");
114 
115  p.addPar ("EA", 0.0, false, ParameterType::NO_DEP,
118  U_CM, CAT_NONE, "a-current rest potential");
119 
120  p.addPar ("GA",0.0, false, ParameterType::NO_DEP,
123  U_NONE, CAT_NONE, "a-current base conductance");
124 
125  p.addPar ("ECA", 0.0, false, ParameterType::NO_DEP,
128  U_NONE, CAT_NONE, "Calcium rest potential");
129 
130  p.addPar ("GCA", 0.0, false, ParameterType::NO_DEP,
133  U_OHMM1, CAT_NONE, "Calcium base conductance");
134 
135  p.addPar ("EKCA", 0.0, false, ParameterType::NO_DEP,
138  U_OHMM1, CAT_NONE, "Potassium-calcium rest potential");
139 
140  p.addPar ("GKCA", 0.0, false, ParameterType::NO_DEP,
143  U_OHMM1, CAT_NONE, "Potassium-calcium base conductance");
144 
145  p.addPar ("CAINIT", 0.0, false, ParameterType::NO_DEP,
148  U_OHMM1, CAT_NONE, "initial intra-cellular calcium concentration");
149 
150  p.addPar ("CAGAMMA", 0.0, false, ParameterType::NO_DEP,
153  U_OHMM1, CAT_NONE, "calcium current to concentration multiplier");
154 
155  p.addPar ("CATAU", 0.0, false, ParameterType::NO_DEP,
158  U_OHMM1, CAT_NONE, "calcium removal time constant");
159 }
160 
161 
162 
163 //
164 // static class member inits
165 //
166 std::vector< std::vector<int> > Instance::jacStamp;
167 
168 // Class Instance
169 //-----------------------------------------------------------------------------
170 // Function : Instance::processParams
171 // Purpose :
172 // Special Notes :
173 // Scope : public
174 // Creator : Richard Schiek, Electrical and Microsytem Modeling
175 // Creation Date : 01/02/08
176 //-----------------------------------------------------------------------------
178 {
179  // If there are any time dependent parameters, set their values at for
180  // the current time.
181 
182  // now set the temperature related stuff.
183  //updateTemperature(temp);
184 
185  return true;
186 }
187 
188 //-----------------------------------------------------------------------------
189 // Function : Instance::updateTemperature
190 // Purpose :
191 // Special Notes :
192 // Scope : public
193 // Creator : Richard Schiek, Electrical and Microsytem Modeling
194 // Creation Date : 01/02/08
195 //-----------------------------------------------------------------------------
196 bool Instance::updateTemperature ( const double & temp)
197 {
198  bool bsuccess = true;
199  return bsuccess;
200 }
201 
202 //-----------------------------------------------------------------------------
203 // Function : Instance::Instance
204 // Purpose : constructor
205 // Special Notes :
206 // Scope : public
207 // Creator : Richard Schiek, Electrical and Microsytem Modeling
208 // Creation Date : 01/02/08
209 //-----------------------------------------------------------------------------
211  const Configuration & configuration,
212  const InstanceBlock & IB,
213  Model & Miter,
214  const FactoryBlock & factory_block)
215  : DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
216  model_(Miter),
217  kcl1Fvalue(0.0),
218  kcl1Qvalue(0.0),
219  kcl2Fvalue(0.0),
220  kcl2Qvalue(0.0),
221  nEquFvalue(0.0),
222  nEquQvalue(0.0),
223  mEquFvalue(0.0),
224  mEquQvalue(0.0),
225  hEquFvalue(0.0),
226  hEquQvalue(0.0),
227  dkcl1F_dV1(0.0),
228  dkcl1F_dV2(0.0),
229  dkcl1F_dn(0.0),
230  dkcl1F_dm(0.0),
231  dkcl1F_dh(0.0),
232  dkcl1Q_dV1(0.0),
233  dkcl1Q_dV2(0.0),
234  dkcl2F_dV1(0.0),
235  dkcl2F_dV2(0.0),
236  dkcl2F_dn(0.0),
237  dkcl2F_dm(0.0),
238  dkcl2F_dh(0.0),
239  dkcl2Q_dV1(0.0),
240  dkcl2Q_dV2(0.0),
241  dnF_dV1(0.0),
242  dnF_dn(0.0),
243  dnQ_dn(0.0),
244  dmF_dV1(0.0),
245  dmF_dm(0.0),
246  dmQ_dm(0.0),
247  dhF_dV1(0.0),
248  dhF_dh(0.0),
249  dhQ_dh(0.0)
250 {
251  numExtVars = 2;
252  numIntVars = 9;
253  numStateVars = 2;
254 
255  // set up jacStamp
256  if( jacStamp.empty() )
257  {
258  jacStamp.resize(11);
259  jacStamp[0].resize(10); // kcl 1
260  jacStamp[0][0] = 0;
261  jacStamp[0][1] = 1;
262  jacStamp[0][2] = 2;
263  jacStamp[0][3] = 3;
264  jacStamp[0][4] = 4;
265  jacStamp[0][5] = 5;
266  jacStamp[0][6] = 6;
267  jacStamp[0][7] = 7;
268  jacStamp[0][8] = 8;
269  jacStamp[0][9] = 9;
270  jacStamp[1].resize(10); // kcl 2
271  jacStamp[1][0] = 0;
272  jacStamp[1][1] = 1;
273  jacStamp[1][2] = 2;
274  jacStamp[1][3] = 3;
275  jacStamp[1][4] = 4;
276  jacStamp[1][5] = 5;
277  jacStamp[1][6] = 6;
278  jacStamp[1][7] = 7;
279  jacStamp[1][8] = 8;
280  jacStamp[1][9] = 9;
281  jacStamp[2].resize(2); // n equation
282  jacStamp[2][0] = 0;
283  jacStamp[2][1] = 2;
284  jacStamp[3].resize(2); // m equation
285  jacStamp[3][0] = 0;
286  jacStamp[3][1] = 3;
287  jacStamp[4].resize(2); // h equation
288  jacStamp[4][0] = 0;
289  jacStamp[4][1] = 4;
290  jacStamp[5].resize(2); // a equation
291  jacStamp[5][0] = 0;
292  jacStamp[5][1] = 5;
293  jacStamp[6].resize(2); // b equation
294  jacStamp[6][0] = 0;
295  jacStamp[6][1] = 6;
296  jacStamp[7].resize(2); // M equation
297  jacStamp[7][0] = 0;
298  jacStamp[7][1] = 7;
299  jacStamp[8].resize(2); // H equation
300  jacStamp[8][0] = 0;
301  jacStamp[8][1] = 8;
302  jacStamp[9].resize(3); // c equation
303  jacStamp[9][0] = 0;
304  jacStamp[9][1] = 9;
305  jacStamp[9][2] = 10;
306  jacStamp[10].resize(5); // Ca equation
307  jacStamp[10][0] = 0;
308  jacStamp[10][1] = 1;
309  jacStamp[10][2] = 7;
310  jacStamp[10][3] = 8;
311  jacStamp[10][4] = 10;
312  }
313 
314  // Set params to constant default values:
315  setDefaultParams ();
316 
317  // Set params according to instance line and constant defaults from metadata:
318  // there are no params for this device as yet, so calling setParams causes
319  // the code to exit.
320  // setParams (IB.params);
321 
322  // Set any non-constant parameter defaults:
323 
324  //if (!given("TEMP"))
325  // temp = getDeviceOptions().temp.dVal();
326 
327  // Calculate any parameters specified as expressions:
329 
330  // calculate dependent (ie computed) params and check for errors:
331  processParams ();
332 
333 }
334 
335 //-----------------------------------------------------------------------------
336 // Function : Instance::~Instance
337 // Purpose : destructor
338 // Special Notes :
339 // Scope : public
340 // Creator : Richard Schiek, Electrical and Microsytem Modeling
341 // Creation Date : 01/02/08
342 //-----------------------------------------------------------------------------
344 {
345 }
346 
347 //-----------------------------------------------------------------------------
348 // Function : Instance::registerLIDs
349 // Purpose :
350 // Special Notes :
351 // Scope : public
352 // Creator : Richard Schiek, Electrical and Microsytem Modeling
353 // Creation Date : 01/02/08
354 //-----------------------------------------------------------------------------
355 void Instance::registerLIDs(const std::vector<int> & intLIDVecRef,
356  const std::vector<int> & extLIDVecRef)
357 {
358  AssertLIDs(intLIDVecRef.size() == numIntVars);
359  AssertLIDs(extLIDVecRef.size() == numExtVars);
360 
361 #ifdef Xyce_DEBUG_DEVICE
362  if (getDeviceOptions().debugLevel > 0)
363  {
364  Xyce::dout() << std::endl << section_divider << std::endl;
365  Xyce::dout() << " Instance::registerLIDs" << std::endl;
366  Xyce::dout() << " name = " << getName() << std::endl;
367  }
368 #endif
369 
370  // copy over the global ID lists.
371  intLIDVec = intLIDVecRef;
372  extLIDVec = extLIDVecRef;
373 
374  li_Pos = extLIDVec[0];
375  li_Neg = extLIDVec[1];
376  li_nPro = intLIDVec[0];
377  li_mPro = intLIDVec[1];
378  li_hPro = intLIDVec[2];
379  li_aPro = intLIDVec[3];
380  li_bPro = intLIDVec[4];
381  li_M_Pro = intLIDVec[5];
382  li_H_Pro = intLIDVec[6];
383  li_cPro = intLIDVec[7];
384  li_CaPro = intLIDVec[8];
385 
386 #ifdef Xyce_DEBUG_DEVICE
387  if (getDeviceOptions().debugLevel > 0 )
388  {
389  Xyce::dout() << " li_Pos = " << li_Pos << std::endl
390  << " li_Neg = " << li_Neg << std::endl
391  << " li_nPro = " << li_nPro << std::endl
392  << " li_mPro = " << li_mPro << std::endl
393  << " li_hPro = " << li_hPro << std::endl
394  << " li_aPro = " << li_aPro << std::endl
395  << " li_bPro = " << li_bPro << std::endl
396  << " li_M_Pro = " << li_M_Pro << std::endl
397  << " li_H_Pro = " << li_H_Pro << std::endl
398  << " li_cPro = " << li_cPro << std::endl
399  << " li_CaPro = " << li_CaPro << std::endl;
400  }
401 #endif
402 
403 #ifdef Xyce_DEBUG_DEVICE
404  if (getDeviceOptions().debugLevel > 0 )
405  {
406  Xyce::dout() << section_divider << std::endl;
407  }
408 #endif
409 }
410 
411 //-----------------------------------------------------------------------------
412 // Function : Instance::getIntNameMap
413 // Purpose :
414 // Special Notes :
415 // Scope : public
416 // Creator : Richard Schiek, Electrical and Microsytem Modeling
417 // Creation Date : 01/02/08
418 //-----------------------------------------------------------------------------
419 std::map<int,std::string> & Instance::getIntNameMap ()
420 {
421  // set up the internal name map, if it hasn't been already.
422  if (intNameMap.empty ())
423  {
433 
434  }
435  return intNameMap;
436 }
437 
438 //-----------------------------------------------------------------------------
439 // Function : Instance::registerStateLIDs
440 // Purpose :
441 // Special Notes :
442 // Scope : public
443 // Creator : Richard Schiek, Electrical and Microsytem Modeling
444 // Creation Date : 01/02/08
445 //-----------------------------------------------------------------------------
446 void Instance::registerStateLIDs( const std::vector<int> & staLIDVecRef )
447 {
448  AssertLIDs(staLIDVecRef.size() == numStateVars);
449 
450  // copy over the global ID lists.
451  staLIDVec = staLIDVecRef;
452 
453  li_KCurrentState = staLIDVec[0];
454  li_NaCurrentState = staLIDVec[1];
455 
456 }
457 
458 //-----------------------------------------------------------------------------
459 // Function : Instance::loadDeviceMask
460 //
461 // Purpose : Loads the zero elements of the device mask
462 //
463 // Special Notes : elements of the error vector associated with zero
464 // elements of the mask will not be included in weighted
465 // norms by the time integrator.
466 //
467 // Scope : public
468 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
469 // Creation Date : 01/19/07
470 //-----------------------------------------------------------------------------
472 {
473  bool returnVal=false;
474  N_LAS_Vector * maskVectorPtr = extData.deviceMaskVectorPtr;
475 
476 // Xyce::dout() << "Masking n, m and h" << std::endl;
477 // (*maskVectorPtr)[li_nPro] = 0.0;
478 // (*maskVectorPtr)[li_mPro] = 0.0;
479 // (*maskVectorPtr)[li_hPro] = 0.0;
480 // returnVal = true;
481 
482  return (returnVal);
483 }
484 
485 //-----------------------------------------------------------------------------
486 // Function : Instance::jacobianStamp
487 // Purpose :
488 // Special Notes :
489 // Scope : public
490 // Creator : Richard Schiek, Electrical and Microsytem Modeling
491 // Creation Date : 01/02/08
492 //-----------------------------------------------------------------------------
493 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
494 {
495  return jacStamp;
496 }
497 
498 //-----------------------------------------------------------------------------
499 // Function : Instance::registerJacLIDs
500 // Purpose :
501 // Special Notes :
502 // Scope : public
503 // Creator : Richard Schiek, Electrical and Microsytem Modeling
504 // Creation Date : 01/02/08
505 //-----------------------------------------------------------------------------
506 void Instance::registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec )
507 {
508  DeviceInstance::registerJacLIDs( jacLIDVec );
509 
510  APosEquPosNodeOffset = jacLIDVec[0][0];
511  APosEquNegNodeOffset = jacLIDVec[0][1];
512  APosEquNNodeOffset = jacLIDVec[0][2];
513  APosEquMNodeOffset = jacLIDVec[0][3];
514  APosEquHNodeOffset = jacLIDVec[0][4];
515  APosEquANodeOffset = jacLIDVec[0][5];
516  APosEquBNodeOffset = jacLIDVec[0][6];
517  APosEquM_NodeOffset = jacLIDVec[0][7];
518  APosEquH_NodeOffset = jacLIDVec[0][8];
519  APosEquCNodeOffset = jacLIDVec[0][9];
520 
521  ANegEquPosNodeOffset = jacLIDVec[1][0];
522  ANegEquNegNodeOffset = jacLIDVec[1][1];
523  ANegEquNNodeOffset = jacLIDVec[1][2];
524  ANegEquMNodeOffset = jacLIDVec[1][3];
525  ANegEquHNodeOffset = jacLIDVec[1][4];
526  ANegEquANodeOffset = jacLIDVec[1][5];
527  ANegEquBNodeOffset = jacLIDVec[1][6];
528  ANegEquM_NodeOffset = jacLIDVec[1][7];
529  ANegEquH_NodeOffset = jacLIDVec[1][8];
530  ANegEquCNodeOffset = jacLIDVec[1][9];
531 
532  ANEquPosNodeOffset = jacLIDVec[2][0];
533  ANEquNNodeOffset = jacLIDVec[2][1];
534 
535  AMEquPosNodeOffset = jacLIDVec[3][0];
536  AMEquMNodeOffset = jacLIDVec[3][1];
537 
538  AHEquPosNodeOffset = jacLIDVec[4][0];
539  AHEquHNodeOffset = jacLIDVec[4][1];
540 
541  AAEquPosNodeOffset = jacLIDVec[5][0];
542  AAEquANodeOffset = jacLIDVec[5][1];
543 
544  ABEquPosNodeOffset = jacLIDVec[6][0];
545  ABEquBNodeOffset = jacLIDVec[6][1];
546 
547  AM_EquPosNodeOffset = jacLIDVec[7][0];
548  AM_EquM_NodeOffset = jacLIDVec[7][1];
549 
550  AH_EquPosNodeOffset = jacLIDVec[8][0];
551  AH_EquH_NodeOffset = jacLIDVec[8][1];
552 
553  ACEquPosNodeOffset = jacLIDVec[9][0];
554  ACEquCNodeOffset = jacLIDVec[9][1];
555  ACEquCaNodeOffset = jacLIDVec[9][2];
556 
557  ACaEquPosNodeOffset = jacLIDVec[10][0];
558  ACaEquNegNodeOffset = jacLIDVec[10][1];
559  ACaEquM_NodeOffset = jacLIDVec[10][2];
560  ACaEquH_NodeOffset = jacLIDVec[10][3];
561  ACaEquCaNodeOffset = jacLIDVec[10][4];
562 
563 }
564 
565 
566 //-----------------------------------------------------------------------------
567 // Function : Instance::updateIntermediateVars
568 // Purpose :
569 // Special Notes :
570 // Scope : public
571 // Creator : Richard Schiek, Electrical and Microsytem Modeling
572 // Creation Date : 01/02/08
573 //-----------------------------------------------------------------------------
575 {
576  //Xyce::dout() << "Instance::updateIntermediateVars()" << std::endl;
577 
578  bool bsuccess = true;
579 
580  // here we take the current solutions for V1, V2, n, m and h
581  // and use those to calculate all the terms needed for the next
582  // load cycle (F, Q, dFdX, dQdX)
583  N_LAS_Vector * solVectorPtr = extData.nextSolVectorPtr;
584 
585  // use suffix "now" to to clarify that this for the latest solution
586  double v1Now = (*solVectorPtr)[li_Pos];
587  double v2Now = (*solVectorPtr)[li_Neg];
588  double nNow = (*solVectorPtr)[li_nPro];
589  double mNow = (*solVectorPtr)[li_mPro];
590  double hNow = (*solVectorPtr)[li_hPro];
591  double aNow = (*solVectorPtr)[li_aPro];
592  double bNow = (*solVectorPtr)[li_bPro];
593  double M_Now = (*solVectorPtr)[li_M_Pro];
594  double H_Now = (*solVectorPtr)[li_H_Pro];
595  double cNow = (*solVectorPtr)[li_cPro];
596  double CaNow = (*solVectorPtr)[li_CaPro];
597 
598  // get function and derivative values
599  // independent variables
600  // use scoping to avoid lots of similar variable names
601  {
602  Sacado::Fad::SFad<double,10> v1Var( 10, 0, v1Now );
603  Sacado::Fad::SFad<double,10> v2Var( 10, 1, v2Now );
604  Sacado::Fad::SFad<double,10> nVar( 10, 2, nNow );
605  Sacado::Fad::SFad<double,10> mVar( 10, 3, mNow );
606  Sacado::Fad::SFad<double,10> hVar( 10, 4, hNow );
607  Sacado::Fad::SFad<double,10> aVar( 10, 5, aNow );
608  Sacado::Fad::SFad<double,10> bVar( 10, 6, bNow );
609  Sacado::Fad::SFad<double,10> M_Var( 10, 7, M_Now );
610  Sacado::Fad::SFad<double,10> H_Var( 10, 8, H_Now );
611  Sacado::Fad::SFad<double,10> cVar( 10, 9, cNow );
612 
613  // parameters from the model that we'll need.
614  Sacado::Fad::SFad<double,10> gMemVar( model_.gMem );
615  Sacado::Fad::SFad<double,10> vRestVar( model_.vRest );
616  Sacado::Fad::SFad<double,10> gKVar( model_.gK );
617  Sacado::Fad::SFad<double,10> eKVar( model_.eK );
618  Sacado::Fad::SFad<double,10> gNaVar( model_.gNa );
619  Sacado::Fad::SFad<double,10> eNaVar( model_.eNa );
620  Sacado::Fad::SFad<double,10> gAVar( model_.gA );
621  Sacado::Fad::SFad<double,10> eAVar( model_.eA );
622  Sacado::Fad::SFad<double,10> gCaVar( model_.gCa );
623  Sacado::Fad::SFad<double,10> eCaVar( model_.eCa );
624  Sacado::Fad::SFad<double,10> gKCaVar( model_.gKCa );
625  Sacado::Fad::SFad<double,10> CaInitVar( model_.CaInit );
626  Sacado::Fad::SFad<double,10> CaGammaVar( model_.CaGamma );
627  Sacado::Fad::SFad<double,10> CaTauVar( model_.CaTau );
628 
629  // compute the vaud and derivative terms for KCL 1 F
630  Sacado::Fad::SFad<double,10> resultFad;
631  resultFad = kcl1EquF( v1Var, v2Var, nVar, mVar, hVar, aVar, bVar, M_Var, H_Var, cVar, gMemVar, vRestVar, gKVar, eKVar, gNaVar, eNaVar, gAVar, eAVar, gCaVar, eCaVar, gKCaVar);
632  kcl1Fvalue = resultFad.val();
633  dkcl1F_dV1 = resultFad.dx(0);
634  dkcl1F_dV2 = resultFad.dx(1);
635  dkcl1F_dn = resultFad.dx(2);
636  dkcl1F_dm = resultFad.dx(3);
637  dkcl1F_dh = resultFad.dx(4);
638  dkcl1F_da = resultFad.dx(5);
639  dkcl1F_db = resultFad.dx(6);
640  dkcl1F_dM = resultFad.dx(7);
641  dkcl1F_dH = resultFad.dx(8);
642  dkcl1F_dc = resultFad.dx(9);
643 
644  // compute the vaud and derivative terms for KCL 2 F
645  resultFad = kcl2EquF( v1Var, v2Var, nVar, mVar, hVar, aVar, bVar, M_Var, H_Var, cVar, gMemVar, vRestVar, gKVar, eKVar, gNaVar, eNaVar, gAVar, eAVar, gCaVar, eCaVar, gKCaVar);
646  kcl2Fvalue = resultFad.val();
647  dkcl2F_dV1 = resultFad.dx(0);
648  dkcl2F_dV2 = resultFad.dx(1);
649  dkcl2F_dn = resultFad.dx(2);
650  dkcl2F_dm = resultFad.dx(3);
651  dkcl2F_dh = resultFad.dx(4);
652  dkcl2F_da = resultFad.dx(5);
653  dkcl2F_db = resultFad.dx(6);
654  dkcl2F_dM = resultFad.dx(7);
655  dkcl2F_dH = resultFad.dx(8);
656  dkcl2F_dc = resultFad.dx(9);
657  }
658 
659  {
660  Sacado::Fad::SFad<double,2> v1Var( 2, 0, v1Now );
661  Sacado::Fad::SFad<double,2> v2Var( 2, 1, v2Now );
662 
663  // parameters
664  Sacado::Fad::SFad<double,2> cMemVar( model_.cMem );
665 
666  Sacado::Fad::SFad<double,2> resultFad;
667  resultFad = kcl1EquQ( v1Var, v2Var, cMemVar );
668  kcl1Qvalue = resultFad.val();
669  dkcl1Q_dV1 = resultFad.dx(0);
670  dkcl1Q_dV2 = resultFad.dx(1);
671 
672  resultFad = kcl2EquQ( v1Var, v2Var, cMemVar );
673  kcl2Qvalue = resultFad.val();
674  dkcl2Q_dV1 = resultFad.dx(0);
675  dkcl2Q_dV2 = resultFad.dx(1);
676  }
677 
678  // n - equation
679  {
680  Sacado::Fad::SFad<double,2> v1Var( 2, 0, v1Now );
681  Sacado::Fad::SFad<double,2> nVar( 2, 1, nNow );
682  // parameter
683  Sacado::Fad::SFad<double,2> vRestVar( model_.vRest );
684 
685  Sacado::Fad::SFad<double,2> resultFad = nEquF( v1Var, nVar, vRestVar);
686  nEquFvalue = resultFad.val();
687  dnF_dV1 = resultFad.dx(0);
688  dnF_dn = resultFad.dx(1);
689  }
690 
691  {
692  Sacado::Fad::SFad<double,1> nVar( 1, 0, nNow );
693 
694  Sacado::Fad::SFad<double,1> resultFad = nEquQ( nVar );
695  nEquQvalue = resultFad.val();
696  dnQ_dn = resultFad.dx(0);
697  }
698 
699  // m - equation
700  {
701  Sacado::Fad::SFad<double,2> v1Var( 2, 0, v1Now );
702  Sacado::Fad::SFad<double,2> mVar( 2, 1, mNow );
703  // parameter
704  Sacado::Fad::SFad<double,2> vRestVar( model_.vRest );
705 
706  Sacado::Fad::SFad<double,2> resultFad = mEquF( v1Var, mVar, vRestVar );
707  mEquFvalue = resultFad.val();
708  dmF_dV1 = resultFad.dx(0);
709  dmF_dm = resultFad.dx(1);
710  }
711  {
712  Sacado::Fad::SFad<double,1> mVar( 1, 0, mNow );
713 
714  Sacado::Fad::SFad<double,1> resultFad = mEquQ( mVar );
715  mEquQvalue = resultFad.val();
716  dmQ_dm = resultFad.dx(0);
717  }
718 
719  // h - equation
720  {
721  Sacado::Fad::SFad<double,2> v1Var( 2, 0, v1Now );
722  Sacado::Fad::SFad<double,2> hVar( 2, 1, hNow );
723  // parameter
724  Sacado::Fad::SFad<double,2> vRestVar( model_.vRest );
725 
726  Sacado::Fad::SFad<double,2> resultFad = hEquF( v1Var, hVar, vRestVar );
727  hEquFvalue = resultFad.val();
728  dhF_dV1 = resultFad.dx(0);
729  dhF_dh = resultFad.dx(1);
730  }
731  {
732  Sacado::Fad::SFad<double,1> hVar( 1, 0, hNow );
733 
734  Sacado::Fad::SFad<double,1> resultFad = hEquQ( hVar );
735  hEquQvalue = resultFad.val();
736  dhQ_dh = resultFad.dx(0);
737  }
738 
739  // a - equation
740  {
741  Sacado::Fad::SFad<double,2> v1Var( 2, 0, v1Now );
742  Sacado::Fad::SFad<double,2> aVar( 2, 1, aNow );
743  // parameter
744  Sacado::Fad::SFad<double,2> vRestVar( model_.vRest );
745 
746  Sacado::Fad::SFad<double,2> resultFad = aEquF( v1Var, aVar, vRestVar );
747  aEquFvalue = resultFad.val();
748  daF_dV1 = resultFad.dx(0);
749  daF_da = resultFad.dx(1);
750  }
751  {
752  Sacado::Fad::SFad<double,1> aVar( 1, 0, aNow );
753 
754  Sacado::Fad::SFad<double,1> resultFad = aEquQ( aVar );
755  aEquQvalue = resultFad.val();
756  daQ_da = resultFad.dx(0);
757  }
758 
759  // b - equation
760  {
761  Sacado::Fad::SFad<double,2> v1Var( 2, 0, v1Now );
762  Sacado::Fad::SFad<double,2> bVar( 2, 1, bNow );
763  // parameter
764  Sacado::Fad::SFad<double,2> vRestVar( model_.vRest );
765 
766  Sacado::Fad::SFad<double,2> resultFad = bEquF( v1Var, bVar, vRestVar );
767  bEquFvalue = resultFad.val();
768  dbF_dV1 = resultFad.dx(0);
769  dbF_db = resultFad.dx(1);
770  }
771  {
772  Sacado::Fad::SFad<double,1> bVar( 1, 0, bNow );
773 
774  Sacado::Fad::SFad<double,1> resultFad = aEquQ( bVar );
775  bEquQvalue = resultFad.val();
776  dbQ_db = resultFad.dx(0);
777  }
778 
779  // M - equation
780  {
781  Sacado::Fad::SFad<double,2> v1Var( 2, 0, v1Now );
782  Sacado::Fad::SFad<double,2> M_Var( 2, 1, M_Now );
783  // parameter
784  Sacado::Fad::SFad<double,2> vRestVar( model_.vRest );
785 
786  Sacado::Fad::SFad<double,2> resultFad = M_EquF( v1Var, M_Var, vRestVar );
787  M_EquFvalue = resultFad.val();
788  dMF_dV1 = resultFad.dx(0);
789  dMF_dM = resultFad.dx(1);
790  }
791  {
792  Sacado::Fad::SFad<double,1> M_Var( 1, 0, M_Now );
793 
794  Sacado::Fad::SFad<double,1> resultFad = aEquQ( M_Var );
795  M_EquQvalue = resultFad.val();
796  dMQ_dM = resultFad.dx(0);
797  }
798 
799  // H - equation
800  {
801  Sacado::Fad::SFad<double,2> v1Var( 2, 0, v1Now );
802  Sacado::Fad::SFad<double,2> H_Var( 2, 1, H_Now );
803  // parameter
804  Sacado::Fad::SFad<double,2> vRestVar( model_.vRest );
805 
806  Sacado::Fad::SFad<double,2> resultFad = H_EquF( v1Var, H_Var, vRestVar );
807  H_EquFvalue = resultFad.val();
808  dHF_dV1 = resultFad.dx(0);
809  dHF_dH = resultFad.dx(1);
810  }
811  {
812  Sacado::Fad::SFad<double,1> H_Var( 1, 0, H_Now );
813 
814  Sacado::Fad::SFad<double,1> resultFad = H_EquQ( H_Var );
815  H_EquQvalue = resultFad.val();
816  dHQ_dH = resultFad.dx(0);
817  }
818 
819  // c - equation
820  {
821  Sacado::Fad::SFad<double,3> v1Var( 3, 0, v1Now );
822  Sacado::Fad::SFad<double,3> cVar( 3, 1, cNow );
823  Sacado::Fad::SFad<double,3> CaVar( 3, 2, CaNow );
824  // parameter
825  Sacado::Fad::SFad<double,3> vRestVar( model_.vRest );
826 
827  Sacado::Fad::SFad<double,3> resultFad = C_EquF( v1Var, cVar, CaVar, vRestVar );
828  cEquFvalue = resultFad.val();
829  dcF_dV1 = resultFad.dx(0);
830  dcF_dc = resultFad.dx(1);
831  dcF_dCa = resultFad.dx(2);
832  }
833  {
834  Sacado::Fad::SFad<double,1> cVar( 1, 0, cNow );
835 
836  Sacado::Fad::SFad<double,1> resultFad = C_EquQ( cVar );
837  cEquQvalue = resultFad.val();
838  dcQ_dc = resultFad.dx(0);
839  }
840 
841  // Ca - equation
842  {
843  Sacado::Fad::SFad<double,5> v1Var( 5, 0, v1Now );
844  Sacado::Fad::SFad<double,5> v2Var( 5, 1, v2Now );
845  Sacado::Fad::SFad<double,5> M_Var( 5, 2, M_Now );
846  Sacado::Fad::SFad<double,5> H_Var( 5, 3, H_Now );
847  Sacado::Fad::SFad<double,5> CaVar( 5, 4, CaNow );
848 
849  // parameter
850  Sacado::Fad::SFad<double,5> gCaVar( model_.gCa );
851  Sacado::Fad::SFad<double,5> eCaVar( model_.gCa );
852  Sacado::Fad::SFad<double,5> CaGammaVar( model_.CaGamma );
853  Sacado::Fad::SFad<double,5> CaTauVar( model_.CaTau );
854 
855  Sacado::Fad::SFad<double,5> resultFad = Ca_EquF( v1Var, v2Var, M_Var, H_Var, CaVar, gCaVar, eCaVar, CaGammaVar, CaTauVar );
856  CaEquFvalue = resultFad.val();
857  dCaF_dV1 = resultFad.dx(0);
858  dCaF_dV2 = resultFad.dx(1);
859  dCaF_dM = resultFad.dx(2);
860  dCaF_dH = resultFad.dx(3);
861  dCaF_dCa = resultFad.dx(4);
862  }
863  {
864  Sacado::Fad::SFad<double,1> CaVar( 1, 0, CaNow );
865 
866  Sacado::Fad::SFad<double,1> resultFad = Ca_EquQ( CaVar );
867  CaEquQvalue = resultFad.val();
868  dCaQ_dCa = resultFad.dx(0);
869  }
870  // calculate potassium current
871  potassiumCurrent = model_.gK * pow(nNow, 4.0) * (v1Now - v2Now - model_.eK);
872 
873  // calculate sodium current
874  sodiumCurrent = model_.gNa * pow(mNow, 3.0) * hNow * (v1Now - v2Now - model_.eNa);
875 
876 
877 #ifdef Xyce_DEBUG_DEVICE
879  {
880  Xyce::dout() << "Instance::updateIntermediateVars()" << std::endl
881  << "v1 = " << v1Now << std::endl
882  << "v2 = " << v2Now << std::endl
883  << "nNow = " << nNow << std::endl
884  << "mNow = " << mNow << std::endl
885  << "hNow = " << hNow << std::endl
886  << "aNow = " << aNow << std::endl
887  << "bNow = " << bNow << std::endl
888  << "M_Now = " << M_Now << std::endl
889  << "H_Now = " << H_Now << std::endl
890  << "cNow = " << cNow << std::endl
891  << "CaNow = " << CaNow << std::endl
892  << "kcl1Fvalue = " << kcl1Fvalue << std::endl
893  << "dkcl1F_dV1 = " << dkcl1F_dV1 << std::endl
894  << "dkcl1F_dV2 = " << dkcl1F_dV2 << std::endl
895  << "dkcl1F_dn = " << dkcl1F_dn << std::endl
896  << "dkcl1F_dm = " << dkcl1F_dm << std::endl
897  << "dkcl1F_dh = " << dkcl1F_dh << std::endl
898  << "kcl2Fvalue = " << kcl2Fvalue << std::endl
899  << "dkcl2F_dV1 = " << dkcl2F_dV1 << std::endl
900  << "dkcl2F_dV2 = " << dkcl2F_dV2 << std::endl
901  << "dkcl2F_dn = " << dkcl2F_dn << std::endl
902  << "dkcl2F_dm = " << dkcl2F_dm << std::endl
903  << "dkcl2F_dh = " << dkcl2F_dh << std::endl
904  << "alphaN = " << alphaN<double>( v1Now ) << std::endl
905  << "betaN = " << betaN<double>( v1Now ) << std::endl
906  << "nEquFvalue = " << nEquFvalue << std::endl
907  << "dnF_dV1 = " << dnF_dV1 << std::endl
908  << "dnF_dn = " << dnF_dn << std::endl
909  << "nEquQvalue = " << nEquQvalue << std::endl
910  << "dnQ_dn = " << dnQ_dn << std::endl
911  << "alphaM = " << alphaM<double>( v1Now ) << std::endl
912  << "betaM = " << betaM<double>( v1Now ) << std::endl
913  << "mEquFvalue = " << mEquFvalue << std::endl
914  << "dmF_dV1 = " << dmF_dV1 << std::endl
915  << "dmF_dm = " << dmF_dm << std::endl
916  << "mEquQvalue = " << mEquQvalue << std::endl
917  << "dmQ_dm = " << dmQ_dm << std::endl
918  << "alphaH = " << alphaH<double>( v1Now ) << std::endl
919  << "betaH = " << betaH<double>( v1Now ) << std::endl
920  << "hEquFvalue = " << hEquFvalue << std::endl
921  << "dhF_dV1 = " << dhF_dV1 << std::endl
922  << "dhF_dh = " << dhF_dh << std::endl
923  << "hEquQvalue = " << hEquQvalue << std::endl
924  << "dhQ_dh = " << dhQ_dh << std::endl
925 
926  << "aInf = " << aInf<double>( v1Now ) << std::endl
927  << "aTau = " << aTau<double>( v1Now ) << std::endl
928  << "aEquFvalue = " << aEquFvalue << std::endl
929  << "daF_dV1 = " << daF_dV1 << std::endl
930  << "daF_da = " << daF_da << std::endl
931  << "aEquQvalue = " << aEquQvalue << std::endl
932  << "daQ_da = " << daQ_da << std::endl
933 
934  << "bInf = " << bInf<double>( v1Now ) << std::endl
935  << "bTau = " << bTau<double>( v1Now ) << std::endl
936  << "bEquFvalue = " << bEquFvalue << std::endl
937  << "dbF_dV1 = " << dbF_dV1 << std::endl
938  << "dbF_db = " << dbF_db << std::endl
939  << "bEquQvalue = " << bEquQvalue << std::endl
940  << "dbQ_db = " << dbQ_db << std::endl
941 
942  << "M_Inf = " << M_Inf<double>( v1Now ) << std::endl
943  << "M_Tau = " << M_Tau<double>( v1Now ) << std::endl
944  << "M_EquFvalue = " << M_EquFvalue << std::endl
945  << "dMF_dV1 = " << dMF_dV1 << std::endl
946  << "dMF_dM = " << dMF_dM << std::endl
947  << "M_EquQvalue = " << M_EquQvalue << std::endl
948  << "dMQ_dM = " << dMQ_dM << std::endl
949 
950  << "H_Inf = " << H_Inf<double>( v1Now ) << std::endl
951  << "H_Tau = " << H_Tau<double>( v1Now ) << std::endl
952  << "H_EquFvalue = " << H_EquFvalue << std::endl
953  << "dHF_dV1 = " << dHF_dV1 << std::endl
954  << "dHF_dH = " << dHF_dH << std::endl
955  << "H_EquQvalue = " << H_EquQvalue << std::endl
956  << "dHQ_dH = " << dHQ_dH << std::endl
957 
958  << "cEquFvalue = " << cEquFvalue << std::endl
959  << "dcF_dV1 = " << dcF_dV1 << std::endl
960  << "dcF_dc = " << dcF_dc << std::endl
961  << "cEquQvalue = " << cEquQvalue << std::endl
962  << "dcQ_dc = " << dcQ_dc << std::endl
963 
964  << "CaEquFvalue = " << CaEquFvalue << std::endl
965  << "dCaF_dV1 = " << dCaF_dV1 << std::endl
966  << "dCaF_dV2 = " << dCaF_dV2 << std::endl
967  << "dCaF_dM = " << dCaF_dM << std::endl
968  << "dCaF_dH = " << dCaF_dH << std::endl
969  << "dCaF_dCa = " << dCaF_dCa << std::endl
970  << "CaEquQvalue = " << CaEquQvalue << std::endl
971  << "dCaQ_dCa = " << dCaQ_dCa << std::endl
972 
973  << std::endl;
974  }
975 #endif
976 
977 
978  return bsuccess;
979 }
980 //-----------------------------------------------------------------------------
981 // Function : Instance::updatePrimaryState
982 // Purpose :
983 // Special Notes :
984 // Scope : public
985 // Creator : Richard Schiek, Electrical and Microsytem Modeling
986 // Creation Date : 01/02/08
987 //-----------------------------------------------------------------------------
989 {
990  bool bsuccess = true;
991 
993 
994  N_LAS_Vector * solVectorPtr = extData.nextSolVectorPtr;
995  N_LAS_Vector * staVectorPtr = extData.nextStaVectorPtr;
996 
997  (*staVectorPtr)[li_KCurrentState] = potassiumCurrent;
998  (*staVectorPtr)[li_NaCurrentState] = sodiumCurrent;
999 
1000  return bsuccess;
1001 }
1002 
1003 //-----------------------------------------------------------------------------
1004 // Function : Instance::updateSecondaryState
1005 // Purpose :
1006 // Special Notes :
1007 // Scope : public
1008 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1009 // Creation Date : 01/02/08
1010 //-----------------------------------------------------------------------------
1012 {
1013  bool bsuccess = true;
1014 
1015  return bsuccess;
1016 }
1017 
1018 //-----------------------------------------------------------------------------
1019 // Function : Instance::loadDAEQVector
1020 //
1021 // Purpose : Loads the Q-vector contributions for a single
1022 // Neuron2 instance.
1023 //
1024 // Special Notes : The "Q" vector is part of a standard DAE formalism in
1025 // which the system of equations is represented as:
1026 //
1027 // f(x) = dQ(x)/dt + F(x) - B(t) = 0
1028 //
1029 // Scope : public
1030 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1031 // Creation Date : 01/02/08
1032 //-----------------------------------------------------------------------------
1034 {
1035  bool bsuccess = true;
1036 
1037  N_LAS_Vector * daeQVecPtr = extData.daeQVectorPtr;
1038 
1039  (*daeQVecPtr)[li_Pos] += kcl1Qvalue;
1040  (*daeQVecPtr)[li_Neg] += kcl2Qvalue;
1041  (*daeQVecPtr)[li_nPro] += nEquQvalue;
1042  (*daeQVecPtr)[li_mPro] += mEquQvalue;
1043  (*daeQVecPtr)[li_hPro] += hEquQvalue;
1044  (*daeQVecPtr)[li_aPro] += aEquQvalue;
1045  (*daeQVecPtr)[li_bPro] += bEquQvalue;
1046  (*daeQVecPtr)[li_M_Pro] += M_EquQvalue;
1047  (*daeQVecPtr)[li_H_Pro] += H_EquQvalue;
1048  (*daeQVecPtr)[li_cPro] += cEquQvalue;
1049  (*daeQVecPtr)[li_CaPro] += CaEquQvalue;
1050 
1051  return bsuccess;
1052 }
1053 
1054 
1055 
1056 //-----------------------------------------------------------------------------
1057 // Function : Instance::loadDAEFVector
1058 //
1059 // Purpose : Loads the F-vector contributions for a single
1060 // Neuron2 instance.
1061 //
1062 // Special Notes :
1063 //
1064 // Scope : public
1065 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1066 // Creation Date : 01/02/08
1067 //-----------------------------------------------------------------------------
1069 {
1070  bool bsuccess=true;
1071 
1072  N_LAS_Vector * daeFVecPtr = extData.daeFVectorPtr;
1073 
1074  (*daeFVecPtr)[li_Pos] += kcl1Fvalue;
1075  (*daeFVecPtr)[li_Neg] += kcl2Fvalue;
1076  (*daeFVecPtr)[li_nPro] += nEquFvalue;
1077  (*daeFVecPtr)[li_mPro] += mEquFvalue;
1078  (*daeFVecPtr)[li_hPro] += hEquFvalue;
1079  (*daeFVecPtr)[li_aPro] += aEquFvalue;
1080  (*daeFVecPtr)[li_bPro] += bEquFvalue;
1081  (*daeFVecPtr)[li_M_Pro] += M_EquFvalue;
1082  (*daeFVecPtr)[li_H_Pro] += H_EquFvalue;
1083  (*daeFVecPtr)[li_cPro] += cEquFvalue;
1084  (*daeFVecPtr)[li_CaPro] += CaEquFvalue;
1085 
1086  return bsuccess;
1087 }
1088 
1089 //-----------------------------------------------------------------------------
1090 // Function : Instance::loadDAEdQdx
1091 //
1092 // Purpose : Loads the Q-vector contributions for a single
1093 // Neuron 2 instance.
1094 // Scope : public
1095 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1096 // Creation Date : 01/02/08
1097 //-----------------------------------------------------------------------------
1099 {
1100  bool bsuccess = true;
1101 
1102  N_LAS_Matrix * dQdxMatPtr = extData.dQdxMatrixPtr;
1103 
1104  (*dQdxMatPtr)[li_Pos][APosEquPosNodeOffset] += dkcl1Q_dV1;
1105  (*dQdxMatPtr)[li_Pos][APosEquNegNodeOffset] += dkcl1Q_dV2;
1106 
1107  (*dQdxMatPtr)[li_Neg][ANegEquPosNodeOffset] += dkcl2Q_dV1;
1108  (*dQdxMatPtr)[li_Neg][ANegEquNegNodeOffset] += dkcl2Q_dV2;
1109 
1110  (*dQdxMatPtr)[li_nPro][ANEquNNodeOffset] += dnQ_dn;
1111  (*dQdxMatPtr)[li_mPro][AMEquMNodeOffset] += dmQ_dm;
1112  (*dQdxMatPtr)[li_hPro][AHEquHNodeOffset] += dhQ_dh;
1113  (*dQdxMatPtr)[li_aPro][AAEquANodeOffset] += daQ_da;
1114  (*dQdxMatPtr)[li_bPro][ABEquBNodeOffset] += dbQ_db;
1115  (*dQdxMatPtr)[li_M_Pro][AM_EquM_NodeOffset] += dMQ_dM;
1116  (*dQdxMatPtr)[li_H_Pro][AH_EquH_NodeOffset] += dHQ_dH;
1117  (*dQdxMatPtr)[li_cPro][ACEquCNodeOffset] += dcQ_dc;
1118  (*dQdxMatPtr)[li_CaPro][ACaEquCaNodeOffset] += dCaQ_dCa;
1119 
1120  return bsuccess;
1121 }
1122 
1123 
1124 
1125 //-----------------------------------------------------------------------------
1126 // Function : Instance::loadDAEdFdx ()
1127 //
1128 // Purpose : Loads the F-vector contributions for a single
1129 // Neuron 2 instance.
1130 //
1131 // Special Notes : This is an algebraic constaint.
1132 //
1133 // Scope : public
1134 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1135 // Creation Date : 01/02/08
1136 //-----------------------------------------------------------------------------
1138 {
1139  bool bsuccess = true;
1140 
1141  N_LAS_Matrix * dFdxMatPtr = extData.dFdxMatrixPtr;
1142 
1143  (*dFdxMatPtr)[li_Pos][APosEquPosNodeOffset] += dkcl1F_dV1;
1144  (*dFdxMatPtr)[li_Pos][APosEquNegNodeOffset] += dkcl1F_dV2;
1145  (*dFdxMatPtr)[li_Pos][APosEquNNodeOffset] += dkcl1F_dn;
1146  (*dFdxMatPtr)[li_Pos][APosEquMNodeOffset] += dkcl1F_dm;
1147  (*dFdxMatPtr)[li_Pos][APosEquHNodeOffset] += dkcl1F_dh;
1148  (*dFdxMatPtr)[li_Pos][APosEquANodeOffset] += dkcl1F_da;
1149  (*dFdxMatPtr)[li_Pos][APosEquBNodeOffset] += dkcl1F_db;
1150  (*dFdxMatPtr)[li_Pos][APosEquM_NodeOffset] += dkcl1F_dM;
1151  (*dFdxMatPtr)[li_Pos][APosEquH_NodeOffset] += dkcl1F_dH;
1152  (*dFdxMatPtr)[li_Pos][APosEquCNodeOffset] += dkcl1F_dc;
1153 
1154  (*dFdxMatPtr)[li_Neg][ANegEquPosNodeOffset] += dkcl2F_dV1;
1155  (*dFdxMatPtr)[li_Neg][ANegEquNegNodeOffset] += dkcl2F_dV2;
1156  (*dFdxMatPtr)[li_Neg][ANegEquNNodeOffset] += dkcl2F_dn;
1157  (*dFdxMatPtr)[li_Neg][ANegEquMNodeOffset] += dkcl2F_dm;
1158  (*dFdxMatPtr)[li_Neg][ANegEquHNodeOffset] += dkcl2F_dh;
1159  (*dFdxMatPtr)[li_Neg][ANegEquANodeOffset] += dkcl2F_da;
1160  (*dFdxMatPtr)[li_Neg][ANegEquBNodeOffset] += dkcl2F_db;
1161  (*dFdxMatPtr)[li_Neg][ANegEquM_NodeOffset] += dkcl2F_dM;
1162  (*dFdxMatPtr)[li_Neg][ANegEquH_NodeOffset] += dkcl2F_dH;
1163  (*dFdxMatPtr)[li_Neg][ANegEquCNodeOffset] += dkcl2F_dc;
1164 
1165  (*dFdxMatPtr)[li_nPro][ANEquPosNodeOffset] += dnF_dV1;
1166  (*dFdxMatPtr)[li_nPro][ANEquNNodeOffset] += dnF_dn;
1167 
1168  (*dFdxMatPtr)[li_mPro][AMEquPosNodeOffset] += dmF_dV1;
1169  (*dFdxMatPtr)[li_mPro][AMEquMNodeOffset] += dmF_dm;
1170 
1171  (*dFdxMatPtr)[li_hPro][AHEquPosNodeOffset] += dhF_dV1;
1172  (*dFdxMatPtr)[li_hPro][AHEquHNodeOffset] += dhF_dh;
1173 
1174  (*dFdxMatPtr)[li_aPro][AAEquPosNodeOffset] += daF_dV1;
1175  (*dFdxMatPtr)[li_aPro][AAEquANodeOffset] += daF_da;
1176 
1177  (*dFdxMatPtr)[li_bPro][ABEquPosNodeOffset] += dbF_dV1;
1178  (*dFdxMatPtr)[li_bPro][ABEquBNodeOffset] += dbF_db;
1179 
1180  (*dFdxMatPtr)[li_M_Pro][AM_EquPosNodeOffset] += dMF_dV1;
1181  (*dFdxMatPtr)[li_M_Pro][AM_EquM_NodeOffset] += dMF_dM;
1182 
1183  (*dFdxMatPtr)[li_H_Pro][AH_EquPosNodeOffset] += dHF_dV1;
1184  (*dFdxMatPtr)[li_H_Pro][AH_EquH_NodeOffset] += dHF_dH;
1185 
1186  (*dFdxMatPtr)[li_cPro][ACEquPosNodeOffset] += dcF_dV1;
1187  (*dFdxMatPtr)[li_cPro][ACEquCNodeOffset] += dcF_dc;
1188  (*dFdxMatPtr)[li_cPro][ACEquCaNodeOffset] += dcF_dCa;
1189 
1190  (*dFdxMatPtr)[li_CaPro][ACaEquPosNodeOffset] += dCaF_dV1;
1191  (*dFdxMatPtr)[li_CaPro][ACaEquNegNodeOffset] += dCaF_dV2;
1192  (*dFdxMatPtr)[li_CaPro][ACaEquM_NodeOffset] += dCaF_dM;
1193  (*dFdxMatPtr)[li_CaPro][ACaEquH_NodeOffset] += dCaF_dH;
1194  (*dFdxMatPtr)[li_CaPro][ACaEquCaNodeOffset] += dCaF_dCa;
1195 
1196  return bsuccess;
1197 }
1198 
1199 //-----------------------------------------------------------------------------
1200 // Function : Instance::setIC
1201 // Purpose :
1202 // Special Notes :
1203 // Scope : public
1204 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1205 // Creation Date : 01/02/08
1206 //-----------------------------------------------------------------------------
1208 {
1209  bool bsuccess = true;
1210 
1211  return bsuccess;
1212 }
1213 
1214 //-----------------------------------------------------------------------------
1215 // Function : Instance::varTypes
1216 // Purpose :
1217 // Special Notes :
1218 // Scope : public
1219 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1220 // Creation Date : 01/02/08
1221 //-----------------------------------------------------------------------------
1222 void Instance::varTypes( std::vector<char> & varTypeVec )
1223 {
1224  //varTypeVec.resize(1);
1225  //varTypeVec[0] = 'I';
1226 }
1227 
1228 
1229 //-----------------------------------------------------------------------------
1230 // Function : Model::processParams
1231 // Purpose :
1232 // Special Notes :
1233 // Scope : public
1234 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1235 // Creation Date : 01/02/08
1236 //-----------------------------------------------------------------------------
1238 {
1239  return true;
1240 }
1241 
1242 //----------------------------------------------------------------------------
1243 // Function : Model::processInstanceParams
1244 // Purpose :
1245 // Special Notes :
1246 // Scope : public
1247 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1248 // Creation Date : 01/02/08
1249 //----------------------------------------------------------------------------
1251 {
1252 
1253  std::vector<Instance*>::iterator iter;
1254  std::vector<Instance*>::iterator first = instanceContainer.begin();
1255  std::vector<Instance*>::iterator last = instanceContainer.end();
1256 
1257  for (iter=first; iter!=last; ++iter)
1258  {
1259  (*iter)->processParams();
1260  }
1261 
1262  return true;
1263 }
1264 
1265 //-----------------------------------------------------------------------------
1266 // Function : Model::Model
1267 // Purpose : block constructor
1268 // Special Notes :
1269 // Scope : public
1270 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1271 // Creation Date : 01/02/08
1272 //-----------------------------------------------------------------------------
1274  const Configuration & configuration,
1275  const ModelBlock & MB,
1276  const FactoryBlock & factory_block)
1277  : DeviceModel(MB, configuration.getModelParameters(), factory_block)
1278 {
1279 
1280  // Set params to constant default values:
1281  setDefaultParams ();
1282 
1283  // Set params according to .model line and constant defaults from metadata:
1284  setModParams (MB.params);
1285 
1286  // Set any non-constant parameter defaults:
1287  //if (!given("TNOM"))
1288  // tnom = getDeviceOptions().tnom;
1289 
1290  // Calculate any parameters specified as expressions:
1292 
1293  // calculate dependent (ie computed) params and check for errors:
1294 
1295  processParams ();
1296 }
1297 
1298 //-----------------------------------------------------------------------------
1299 // Function : Model::~Model
1300 // Purpose : destructor
1301 // Special Notes :
1302 // Scope : public
1303 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1304 // Creation Date : 01/02/08
1305 //-----------------------------------------------------------------------------
1307 {
1308  std::vector<Instance*>::iterator iter;
1309  std::vector<Instance*>::iterator first = instanceContainer.begin();
1310  std::vector<Instance*>::iterator last = instanceContainer.end();
1311 
1312  for (iter=first; iter!=last; ++iter)
1313  {
1314  delete (*iter);
1315  }
1316 
1317 }
1318 
1319 // additional Declarations
1320 
1321 //-----------------------------------------------------------------------------
1322 // Function : Model::printOutInstances
1323 // Purpose : debugging tool.
1324 // Special Notes :
1325 // Scope : public
1326 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1327 // Creation Date : 01/02/08
1328 //-----------------------------------------------------------------------------
1329 std::ostream &Model::printOutInstances(std::ostream &os) const
1330 {
1331  std::vector<Instance*>::const_iterator iter;
1332  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
1333  std::vector<Instance*>::const_iterator last = instanceContainer.end();
1334 
1335  int i, isize;
1336  isize = instanceContainer.size();
1337 
1338  os << std::endl;
1339  os << "Number of Neuron instances: " << isize << std::endl;
1340  os << " name=\t\tmodelName\tParameters" << std::endl;
1341  for (i=0, iter=first; iter!=last; ++iter, ++i)
1342  {
1343  os << " " << i << ": " << (*iter)->getName() << "\t";
1344  os << getName();
1345  os << std::endl;
1346  }
1347 
1348  os << std::endl;
1349  return os;
1350 }
1351 
1352 //-----------------------------------------------------------------------------
1353 // Function : Model::forEachInstance
1354 // Purpose :
1355 // Special Notes :
1356 // Scope : public
1357 // Creator : David Baur
1358 // Creation Date : 2/4/2014
1359 //-----------------------------------------------------------------------------
1360 /// Apply a device instance "op" to all instances associated with this
1361 /// model
1362 ///
1363 /// @param[in] op Operator to apply to all instances.
1364 ///
1365 ///
1366 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
1367 {
1368  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1369  op(*it);
1370 }
1371 
1372 
1373 Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
1374 {
1375 
1376  return new DeviceMaster<Traits>(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
1377 }
1378 
1380 {
1382  .registerDevice("neuron", 2)
1383  .registerModelType("neuron", 2);
1384 }
1385 
1386 } // namespace Neuron2
1387 } // namespace Device
1388 } // namespace Xyce