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.40.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_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  {
424  std::string tmpstr;
425  std::ostringstream segNumber;
426 
427  tmpstr = getName() + "_" + "N";
428  spiceInternalName (tmpstr);
429  intNameMap[ li_nPro ] = tmpstr;
430 
431  tmpstr = getName() + "_" + "M";
432  spiceInternalName (tmpstr);
433  intNameMap[ li_mPro ] = tmpstr;
434 
435  tmpstr = getName() + "_" + "H";
436  spiceInternalName (tmpstr);
437  intNameMap[ li_hPro ] = tmpstr;
438 
439  tmpstr = getName() + "_" + "A";
440  spiceInternalName (tmpstr);
441  intNameMap[ li_aPro ] = tmpstr;
442 
443  tmpstr = getName() + "_" + "B";
444  spiceInternalName (tmpstr);
445  intNameMap[ li_bPro ] = tmpstr;
446 
447  tmpstr = getName() + "_" + "M_";
448  spiceInternalName (tmpstr);
449  intNameMap[ li_M_Pro ] = tmpstr;
450 
451  tmpstr = getName() + "_" + "H_";
452  spiceInternalName (tmpstr);
453  intNameMap[ li_H_Pro ] = tmpstr;
454 
455  tmpstr = getName() + "_" + "C";
456  spiceInternalName (tmpstr);
457  intNameMap[ li_cPro ] = tmpstr;
458 
459  tmpstr = getName() + "_" + "Ca";
460  spiceInternalName (tmpstr);
461  intNameMap[ li_CaPro ] = tmpstr;
462 
463  }
464  return intNameMap;
465 }
466 
467 //-----------------------------------------------------------------------------
468 // Function : Instance::registerStateLIDs
469 // Purpose :
470 // Special Notes :
471 // Scope : public
472 // Creator : Richard Schiek, Electrical and Microsytem Modeling
473 // Creation Date : 01/02/08
474 //-----------------------------------------------------------------------------
475 void Instance::registerStateLIDs( const std::vector<int> & staLIDVecRef )
476 {
477  AssertLIDs(staLIDVecRef.size() == numStateVars);
478 
479  // copy over the global ID lists.
480  staLIDVec = staLIDVecRef;
481 
482  li_KCurrentState = staLIDVec[0];
483  li_NaCurrentState = staLIDVec[1];
484 
485 }
486 
487 //-----------------------------------------------------------------------------
488 // Function : Instance::loadDeviceMask
489 //
490 // Purpose : Loads the zero elements of the device mask
491 //
492 // Special Notes : elements of the error vector associated with zero
493 // elements of the mask will not be included in weighted
494 // norms by the time integrator.
495 //
496 // Scope : public
497 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
498 // Creation Date : 01/19/07
499 //-----------------------------------------------------------------------------
501 {
502  bool returnVal=false;
503  N_LAS_Vector * maskVectorPtr = extData.deviceMaskVectorPtr;
504 
505 // Xyce::dout() << "Masking n, m and h" << std::endl;
506 // (*maskVectorPtr)[li_nPro] = 0.0;
507 // (*maskVectorPtr)[li_mPro] = 0.0;
508 // (*maskVectorPtr)[li_hPro] = 0.0;
509 // returnVal = true;
510 
511  return (returnVal);
512 }
513 
514 //-----------------------------------------------------------------------------
515 // Function : Instance::jacobianStamp
516 // Purpose :
517 // Special Notes :
518 // Scope : public
519 // Creator : Richard Schiek, Electrical and Microsytem Modeling
520 // Creation Date : 01/02/08
521 //-----------------------------------------------------------------------------
522 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
523 {
524  return jacStamp;
525 }
526 
527 //-----------------------------------------------------------------------------
528 // Function : Instance::registerJacLIDs
529 // Purpose :
530 // Special Notes :
531 // Scope : public
532 // Creator : Richard Schiek, Electrical and Microsytem Modeling
533 // Creation Date : 01/02/08
534 //-----------------------------------------------------------------------------
535 void Instance::registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec )
536 {
537  DeviceInstance::registerJacLIDs( jacLIDVec );
538 
539  APosEquPosNodeOffset = jacLIDVec[0][0];
540  APosEquNegNodeOffset = jacLIDVec[0][1];
541  APosEquNNodeOffset = jacLIDVec[0][2];
542  APosEquMNodeOffset = jacLIDVec[0][3];
543  APosEquHNodeOffset = jacLIDVec[0][4];
544  APosEquANodeOffset = jacLIDVec[0][5];
545  APosEquBNodeOffset = jacLIDVec[0][6];
546  APosEquM_NodeOffset = jacLIDVec[0][7];
547  APosEquH_NodeOffset = jacLIDVec[0][8];
548  APosEquCNodeOffset = jacLIDVec[0][9];
549 
550  ANegEquPosNodeOffset = jacLIDVec[1][0];
551  ANegEquNegNodeOffset = jacLIDVec[1][1];
552  ANegEquNNodeOffset = jacLIDVec[1][2];
553  ANegEquMNodeOffset = jacLIDVec[1][3];
554  ANegEquHNodeOffset = jacLIDVec[1][4];
555  ANegEquANodeOffset = jacLIDVec[1][5];
556  ANegEquBNodeOffset = jacLIDVec[1][6];
557  ANegEquM_NodeOffset = jacLIDVec[1][7];
558  ANegEquH_NodeOffset = jacLIDVec[1][8];
559  ANegEquCNodeOffset = jacLIDVec[1][9];
560 
561  ANEquPosNodeOffset = jacLIDVec[2][0];
562  ANEquNNodeOffset = jacLIDVec[2][1];
563 
564  AMEquPosNodeOffset = jacLIDVec[3][0];
565  AMEquMNodeOffset = jacLIDVec[3][1];
566 
567  AHEquPosNodeOffset = jacLIDVec[4][0];
568  AHEquHNodeOffset = jacLIDVec[4][1];
569 
570  AAEquPosNodeOffset = jacLIDVec[5][0];
571  AAEquANodeOffset = jacLIDVec[5][1];
572 
573  ABEquPosNodeOffset = jacLIDVec[6][0];
574  ABEquBNodeOffset = jacLIDVec[6][1];
575 
576  AM_EquPosNodeOffset = jacLIDVec[7][0];
577  AM_EquM_NodeOffset = jacLIDVec[7][1];
578 
579  AH_EquPosNodeOffset = jacLIDVec[8][0];
580  AH_EquH_NodeOffset = jacLIDVec[8][1];
581 
582  ACEquPosNodeOffset = jacLIDVec[9][0];
583  ACEquCNodeOffset = jacLIDVec[9][1];
584  ACEquCaNodeOffset = jacLIDVec[9][2];
585 
586  ACaEquPosNodeOffset = jacLIDVec[10][0];
587  ACaEquNegNodeOffset = jacLIDVec[10][1];
588  ACaEquM_NodeOffset = jacLIDVec[10][2];
589  ACaEquH_NodeOffset = jacLIDVec[10][3];
590  ACaEquCaNodeOffset = jacLIDVec[10][4];
591 
592 }
593 
594 
595 //-----------------------------------------------------------------------------
596 // Function : Instance::updateIntermediateVars
597 // Purpose :
598 // Special Notes :
599 // Scope : public
600 // Creator : Richard Schiek, Electrical and Microsytem Modeling
601 // Creation Date : 01/02/08
602 //-----------------------------------------------------------------------------
604 {
605  //Xyce::dout() << "Instance::updateIntermediateVars()" << std::endl;
606 
607  bool bsuccess = true;
608 
609  // here we take the current solutions for V1, V2, n, m and h
610  // and use those to calculate all the terms needed for the next
611  // load cycle (F, Q, dFdX, dQdX)
612  N_LAS_Vector * solVectorPtr = extData.nextSolVectorPtr;
613 
614  // use suffix "now" to to clarify that this for the latest solution
615  double v1Now = (*solVectorPtr)[li_Pos];
616  double v2Now = (*solVectorPtr)[li_Neg];
617  double nNow = (*solVectorPtr)[li_nPro];
618  double mNow = (*solVectorPtr)[li_mPro];
619  double hNow = (*solVectorPtr)[li_hPro];
620  double aNow = (*solVectorPtr)[li_aPro];
621  double bNow = (*solVectorPtr)[li_bPro];
622  double M_Now = (*solVectorPtr)[li_M_Pro];
623  double H_Now = (*solVectorPtr)[li_H_Pro];
624  double cNow = (*solVectorPtr)[li_cPro];
625  double CaNow = (*solVectorPtr)[li_CaPro];
626 
627  // get function and derivative values
628  // independent variables
629  // use scoping to avoid lots of similar variable names
630  {
631  Sacado::Fad::SFad<double,10> v1Var( 10, 0, v1Now );
632  Sacado::Fad::SFad<double,10> v2Var( 10, 1, v2Now );
633  Sacado::Fad::SFad<double,10> nVar( 10, 2, nNow );
634  Sacado::Fad::SFad<double,10> mVar( 10, 3, mNow );
635  Sacado::Fad::SFad<double,10> hVar( 10, 4, hNow );
636  Sacado::Fad::SFad<double,10> aVar( 10, 5, aNow );
637  Sacado::Fad::SFad<double,10> bVar( 10, 6, bNow );
638  Sacado::Fad::SFad<double,10> M_Var( 10, 7, M_Now );
639  Sacado::Fad::SFad<double,10> H_Var( 10, 8, H_Now );
640  Sacado::Fad::SFad<double,10> cVar( 10, 9, cNow );
641 
642  // parameters from the model that we'll need.
643  Sacado::Fad::SFad<double,10> gMemVar( model_.gMem );
644  Sacado::Fad::SFad<double,10> vRestVar( model_.vRest );
645  Sacado::Fad::SFad<double,10> gKVar( model_.gK );
646  Sacado::Fad::SFad<double,10> eKVar( model_.eK );
647  Sacado::Fad::SFad<double,10> gNaVar( model_.gNa );
648  Sacado::Fad::SFad<double,10> eNaVar( model_.eNa );
649  Sacado::Fad::SFad<double,10> gAVar( model_.gA );
650  Sacado::Fad::SFad<double,10> eAVar( model_.eA );
651  Sacado::Fad::SFad<double,10> gCaVar( model_.gCa );
652  Sacado::Fad::SFad<double,10> eCaVar( model_.eCa );
653  Sacado::Fad::SFad<double,10> gKCaVar( model_.gKCa );
654  Sacado::Fad::SFad<double,10> CaInitVar( model_.CaInit );
655  Sacado::Fad::SFad<double,10> CaGammaVar( model_.CaGamma );
656  Sacado::Fad::SFad<double,10> CaTauVar( model_.CaTau );
657 
658  // compute the vaud and derivative terms for KCL 1 F
659  Sacado::Fad::SFad<double,10> resultFad;
660  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);
661  kcl1Fvalue = resultFad.val();
662  dkcl1F_dV1 = resultFad.dx(0);
663  dkcl1F_dV2 = resultFad.dx(1);
664  dkcl1F_dn = resultFad.dx(2);
665  dkcl1F_dm = resultFad.dx(3);
666  dkcl1F_dh = resultFad.dx(4);
667  dkcl1F_da = resultFad.dx(5);
668  dkcl1F_db = resultFad.dx(6);
669  dkcl1F_dM = resultFad.dx(7);
670  dkcl1F_dH = resultFad.dx(8);
671  dkcl1F_dc = resultFad.dx(9);
672 
673  // compute the vaud and derivative terms for KCL 2 F
674  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);
675  kcl2Fvalue = resultFad.val();
676  dkcl2F_dV1 = resultFad.dx(0);
677  dkcl2F_dV2 = resultFad.dx(1);
678  dkcl2F_dn = resultFad.dx(2);
679  dkcl2F_dm = resultFad.dx(3);
680  dkcl2F_dh = resultFad.dx(4);
681  dkcl2F_da = resultFad.dx(5);
682  dkcl2F_db = resultFad.dx(6);
683  dkcl2F_dM = resultFad.dx(7);
684  dkcl2F_dH = resultFad.dx(8);
685  dkcl2F_dc = resultFad.dx(9);
686  }
687 
688  {
689  Sacado::Fad::SFad<double,2> v1Var( 2, 0, v1Now );
690  Sacado::Fad::SFad<double,2> v2Var( 2, 1, v2Now );
691 
692  // parameters
693  Sacado::Fad::SFad<double,2> cMemVar( model_.cMem );
694 
695  Sacado::Fad::SFad<double,2> resultFad;
696  resultFad = kcl1EquQ( v1Var, v2Var, cMemVar );
697  kcl1Qvalue = resultFad.val();
698  dkcl1Q_dV1 = resultFad.dx(0);
699  dkcl1Q_dV2 = resultFad.dx(1);
700 
701  resultFad = kcl2EquQ( v1Var, v2Var, cMemVar );
702  kcl2Qvalue = resultFad.val();
703  dkcl2Q_dV1 = resultFad.dx(0);
704  dkcl2Q_dV2 = resultFad.dx(1);
705  }
706 
707  // n - equation
708  {
709  Sacado::Fad::SFad<double,2> v1Var( 2, 0, v1Now );
710  Sacado::Fad::SFad<double,2> nVar( 2, 1, nNow );
711  // parameter
712  Sacado::Fad::SFad<double,2> vRestVar( model_.vRest );
713 
714  Sacado::Fad::SFad<double,2> resultFad = nEquF( v1Var, nVar, vRestVar);
715  nEquFvalue = resultFad.val();
716  dnF_dV1 = resultFad.dx(0);
717  dnF_dn = resultFad.dx(1);
718  }
719 
720  {
721  Sacado::Fad::SFad<double,1> nVar( 1, 0, nNow );
722 
723  Sacado::Fad::SFad<double,1> resultFad = nEquQ( nVar );
724  nEquQvalue = resultFad.val();
725  dnQ_dn = resultFad.dx(0);
726  }
727 
728  // m - equation
729  {
730  Sacado::Fad::SFad<double,2> v1Var( 2, 0, v1Now );
731  Sacado::Fad::SFad<double,2> mVar( 2, 1, mNow );
732  // parameter
733  Sacado::Fad::SFad<double,2> vRestVar( model_.vRest );
734 
735  Sacado::Fad::SFad<double,2> resultFad = mEquF( v1Var, mVar, vRestVar );
736  mEquFvalue = resultFad.val();
737  dmF_dV1 = resultFad.dx(0);
738  dmF_dm = resultFad.dx(1);
739  }
740  {
741  Sacado::Fad::SFad<double,1> mVar( 1, 0, mNow );
742 
743  Sacado::Fad::SFad<double,1> resultFad = mEquQ( mVar );
744  mEquQvalue = resultFad.val();
745  dmQ_dm = resultFad.dx(0);
746  }
747 
748  // h - equation
749  {
750  Sacado::Fad::SFad<double,2> v1Var( 2, 0, v1Now );
751  Sacado::Fad::SFad<double,2> hVar( 2, 1, hNow );
752  // parameter
753  Sacado::Fad::SFad<double,2> vRestVar( model_.vRest );
754 
755  Sacado::Fad::SFad<double,2> resultFad = hEquF( v1Var, hVar, vRestVar );
756  hEquFvalue = resultFad.val();
757  dhF_dV1 = resultFad.dx(0);
758  dhF_dh = resultFad.dx(1);
759  }
760  {
761  Sacado::Fad::SFad<double,1> hVar( 1, 0, hNow );
762 
763  Sacado::Fad::SFad<double,1> resultFad = hEquQ( hVar );
764  hEquQvalue = resultFad.val();
765  dhQ_dh = resultFad.dx(0);
766  }
767 
768  // a - equation
769  {
770  Sacado::Fad::SFad<double,2> v1Var( 2, 0, v1Now );
771  Sacado::Fad::SFad<double,2> aVar( 2, 1, aNow );
772  // parameter
773  Sacado::Fad::SFad<double,2> vRestVar( model_.vRest );
774 
775  Sacado::Fad::SFad<double,2> resultFad = aEquF( v1Var, aVar, vRestVar );
776  aEquFvalue = resultFad.val();
777  daF_dV1 = resultFad.dx(0);
778  daF_da = resultFad.dx(1);
779  }
780  {
781  Sacado::Fad::SFad<double,1> aVar( 1, 0, aNow );
782 
783  Sacado::Fad::SFad<double,1> resultFad = aEquQ( aVar );
784  aEquQvalue = resultFad.val();
785  daQ_da = resultFad.dx(0);
786  }
787 
788  // b - equation
789  {
790  Sacado::Fad::SFad<double,2> v1Var( 2, 0, v1Now );
791  Sacado::Fad::SFad<double,2> bVar( 2, 1, bNow );
792  // parameter
793  Sacado::Fad::SFad<double,2> vRestVar( model_.vRest );
794 
795  Sacado::Fad::SFad<double,2> resultFad = bEquF( v1Var, bVar, vRestVar );
796  bEquFvalue = resultFad.val();
797  dbF_dV1 = resultFad.dx(0);
798  dbF_db = resultFad.dx(1);
799  }
800  {
801  Sacado::Fad::SFad<double,1> bVar( 1, 0, bNow );
802 
803  Sacado::Fad::SFad<double,1> resultFad = aEquQ( bVar );
804  bEquQvalue = resultFad.val();
805  dbQ_db = resultFad.dx(0);
806  }
807 
808  // M - equation
809  {
810  Sacado::Fad::SFad<double,2> v1Var( 2, 0, v1Now );
811  Sacado::Fad::SFad<double,2> M_Var( 2, 1, M_Now );
812  // parameter
813  Sacado::Fad::SFad<double,2> vRestVar( model_.vRest );
814 
815  Sacado::Fad::SFad<double,2> resultFad = M_EquF( v1Var, M_Var, vRestVar );
816  M_EquFvalue = resultFad.val();
817  dMF_dV1 = resultFad.dx(0);
818  dMF_dM = resultFad.dx(1);
819  }
820  {
821  Sacado::Fad::SFad<double,1> M_Var( 1, 0, M_Now );
822 
823  Sacado::Fad::SFad<double,1> resultFad = aEquQ( M_Var );
824  M_EquQvalue = resultFad.val();
825  dMQ_dM = resultFad.dx(0);
826  }
827 
828  // H - equation
829  {
830  Sacado::Fad::SFad<double,2> v1Var( 2, 0, v1Now );
831  Sacado::Fad::SFad<double,2> H_Var( 2, 1, H_Now );
832  // parameter
833  Sacado::Fad::SFad<double,2> vRestVar( model_.vRest );
834 
835  Sacado::Fad::SFad<double,2> resultFad = H_EquF( v1Var, H_Var, vRestVar );
836  H_EquFvalue = resultFad.val();
837  dHF_dV1 = resultFad.dx(0);
838  dHF_dH = resultFad.dx(1);
839  }
840  {
841  Sacado::Fad::SFad<double,1> H_Var( 1, 0, H_Now );
842 
843  Sacado::Fad::SFad<double,1> resultFad = H_EquQ( H_Var );
844  H_EquQvalue = resultFad.val();
845  dHQ_dH = resultFad.dx(0);
846  }
847 
848  // c - equation
849  {
850  Sacado::Fad::SFad<double,3> v1Var( 3, 0, v1Now );
851  Sacado::Fad::SFad<double,3> cVar( 3, 1, cNow );
852  Sacado::Fad::SFad<double,3> CaVar( 3, 2, CaNow );
853  // parameter
854  Sacado::Fad::SFad<double,3> vRestVar( model_.vRest );
855 
856  Sacado::Fad::SFad<double,3> resultFad = C_EquF( v1Var, cVar, CaVar, vRestVar );
857  cEquFvalue = resultFad.val();
858  dcF_dV1 = resultFad.dx(0);
859  dcF_dc = resultFad.dx(1);
860  dcF_dCa = resultFad.dx(2);
861  }
862  {
863  Sacado::Fad::SFad<double,1> cVar( 1, 0, cNow );
864 
865  Sacado::Fad::SFad<double,1> resultFad = C_EquQ( cVar );
866  cEquQvalue = resultFad.val();
867  dcQ_dc = resultFad.dx(0);
868  }
869 
870  // Ca - equation
871  {
872  Sacado::Fad::SFad<double,5> v1Var( 5, 0, v1Now );
873  Sacado::Fad::SFad<double,5> v2Var( 5, 1, v2Now );
874  Sacado::Fad::SFad<double,5> M_Var( 5, 2, M_Now );
875  Sacado::Fad::SFad<double,5> H_Var( 5, 3, H_Now );
876  Sacado::Fad::SFad<double,5> CaVar( 5, 4, CaNow );
877 
878  // parameter
879  Sacado::Fad::SFad<double,5> gCaVar( model_.gCa );
880  Sacado::Fad::SFad<double,5> eCaVar( model_.gCa );
881  Sacado::Fad::SFad<double,5> CaGammaVar( model_.CaGamma );
882  Sacado::Fad::SFad<double,5> CaTauVar( model_.CaTau );
883 
884  Sacado::Fad::SFad<double,5> resultFad = Ca_EquF( v1Var, v2Var, M_Var, H_Var, CaVar, gCaVar, eCaVar, CaGammaVar, CaTauVar );
885  CaEquFvalue = resultFad.val();
886  dCaF_dV1 = resultFad.dx(0);
887  dCaF_dV2 = resultFad.dx(1);
888  dCaF_dM = resultFad.dx(2);
889  dCaF_dH = resultFad.dx(3);
890  dCaF_dCa = resultFad.dx(4);
891  }
892  {
893  Sacado::Fad::SFad<double,1> CaVar( 1, 0, CaNow );
894 
895  Sacado::Fad::SFad<double,1> resultFad = Ca_EquQ( CaVar );
896  CaEquQvalue = resultFad.val();
897  dCaQ_dCa = resultFad.dx(0);
898  }
899  // calculate potassium current
900  potassiumCurrent = model_.gK * pow(nNow, 4.0) * (v1Now - v2Now - model_.eK);
901 
902  // calculate sodium current
903  sodiumCurrent = model_.gNa * pow(mNow, 3.0) * hNow * (v1Now - v2Now - model_.eNa);
904 
905 
906 #ifdef Xyce_DEBUG_DEVICE
908  {
909  Xyce::dout() << "Instance::updateIntermediateVars()" << std::endl
910  << "v1 = " << v1Now << std::endl
911  << "v2 = " << v2Now << std::endl
912  << "nNow = " << nNow << std::endl
913  << "mNow = " << mNow << std::endl
914  << "hNow = " << hNow << std::endl
915  << "aNow = " << aNow << std::endl
916  << "bNow = " << bNow << std::endl
917  << "M_Now = " << M_Now << std::endl
918  << "H_Now = " << H_Now << std::endl
919  << "cNow = " << cNow << std::endl
920  << "CaNow = " << CaNow << std::endl
921  << "kcl1Fvalue = " << kcl1Fvalue << std::endl
922  << "dkcl1F_dV1 = " << dkcl1F_dV1 << std::endl
923  << "dkcl1F_dV2 = " << dkcl1F_dV2 << std::endl
924  << "dkcl1F_dn = " << dkcl1F_dn << std::endl
925  << "dkcl1F_dm = " << dkcl1F_dm << std::endl
926  << "dkcl1F_dh = " << dkcl1F_dh << std::endl
927  << "kcl2Fvalue = " << kcl2Fvalue << std::endl
928  << "dkcl2F_dV1 = " << dkcl2F_dV1 << std::endl
929  << "dkcl2F_dV2 = " << dkcl2F_dV2 << std::endl
930  << "dkcl2F_dn = " << dkcl2F_dn << std::endl
931  << "dkcl2F_dm = " << dkcl2F_dm << std::endl
932  << "dkcl2F_dh = " << dkcl2F_dh << std::endl
933  << "alphaN = " << alphaN<double>( v1Now ) << std::endl
934  << "betaN = " << betaN<double>( v1Now ) << std::endl
935  << "nEquFvalue = " << nEquFvalue << std::endl
936  << "dnF_dV1 = " << dnF_dV1 << std::endl
937  << "dnF_dn = " << dnF_dn << std::endl
938  << "nEquQvalue = " << nEquQvalue << std::endl
939  << "dnQ_dn = " << dnQ_dn << std::endl
940  << "alphaM = " << alphaM<double>( v1Now ) << std::endl
941  << "betaM = " << betaM<double>( v1Now ) << std::endl
942  << "mEquFvalue = " << mEquFvalue << std::endl
943  << "dmF_dV1 = " << dmF_dV1 << std::endl
944  << "dmF_dm = " << dmF_dm << std::endl
945  << "mEquQvalue = " << mEquQvalue << std::endl
946  << "dmQ_dm = " << dmQ_dm << std::endl
947  << "alphaH = " << alphaH<double>( v1Now ) << std::endl
948  << "betaH = " << betaH<double>( v1Now ) << std::endl
949  << "hEquFvalue = " << hEquFvalue << std::endl
950  << "dhF_dV1 = " << dhF_dV1 << std::endl
951  << "dhF_dh = " << dhF_dh << std::endl
952  << "hEquQvalue = " << hEquQvalue << std::endl
953  << "dhQ_dh = " << dhQ_dh << std::endl
954 
955  << "aInf = " << aInf<double>( v1Now ) << std::endl
956  << "aTau = " << aTau<double>( v1Now ) << std::endl
957  << "aEquFvalue = " << aEquFvalue << std::endl
958  << "daF_dV1 = " << daF_dV1 << std::endl
959  << "daF_da = " << daF_da << std::endl
960  << "aEquQvalue = " << aEquQvalue << std::endl
961  << "daQ_da = " << daQ_da << std::endl
962 
963  << "bInf = " << bInf<double>( v1Now ) << std::endl
964  << "bTau = " << bTau<double>( v1Now ) << std::endl
965  << "bEquFvalue = " << bEquFvalue << std::endl
966  << "dbF_dV1 = " << dbF_dV1 << std::endl
967  << "dbF_db = " << dbF_db << std::endl
968  << "bEquQvalue = " << bEquQvalue << std::endl
969  << "dbQ_db = " << dbQ_db << std::endl
970 
971  << "M_Inf = " << M_Inf<double>( v1Now ) << std::endl
972  << "M_Tau = " << M_Tau<double>( v1Now ) << std::endl
973  << "M_EquFvalue = " << M_EquFvalue << std::endl
974  << "dMF_dV1 = " << dMF_dV1 << std::endl
975  << "dMF_dM = " << dMF_dM << std::endl
976  << "M_EquQvalue = " << M_EquQvalue << std::endl
977  << "dMQ_dM = " << dMQ_dM << std::endl
978 
979  << "H_Inf = " << H_Inf<double>( v1Now ) << std::endl
980  << "H_Tau = " << H_Tau<double>( v1Now ) << std::endl
981  << "H_EquFvalue = " << H_EquFvalue << std::endl
982  << "dHF_dV1 = " << dHF_dV1 << std::endl
983  << "dHF_dH = " << dHF_dH << std::endl
984  << "H_EquQvalue = " << H_EquQvalue << std::endl
985  << "dHQ_dH = " << dHQ_dH << std::endl
986 
987  << "cEquFvalue = " << cEquFvalue << std::endl
988  << "dcF_dV1 = " << dcF_dV1 << std::endl
989  << "dcF_dc = " << dcF_dc << std::endl
990  << "cEquQvalue = " << cEquQvalue << std::endl
991  << "dcQ_dc = " << dcQ_dc << std::endl
992 
993  << "CaEquFvalue = " << CaEquFvalue << std::endl
994  << "dCaF_dV1 = " << dCaF_dV1 << std::endl
995  << "dCaF_dV2 = " << dCaF_dV2 << std::endl
996  << "dCaF_dM = " << dCaF_dM << std::endl
997  << "dCaF_dH = " << dCaF_dH << std::endl
998  << "dCaF_dCa = " << dCaF_dCa << std::endl
999  << "CaEquQvalue = " << CaEquQvalue << std::endl
1000  << "dCaQ_dCa = " << dCaQ_dCa << std::endl
1001 
1002  << std::endl;
1003  }
1004 #endif
1005 
1006 
1007  return bsuccess;
1008 }
1009 //-----------------------------------------------------------------------------
1010 // Function : Instance::updatePrimaryState
1011 // Purpose :
1012 // Special Notes :
1013 // Scope : public
1014 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1015 // Creation Date : 01/02/08
1016 //-----------------------------------------------------------------------------
1018 {
1019  bool bsuccess = true;
1020 
1022 
1023  N_LAS_Vector * solVectorPtr = extData.nextSolVectorPtr;
1024  N_LAS_Vector * staVectorPtr = extData.nextStaVectorPtr;
1025 
1026  (*staVectorPtr)[li_KCurrentState] = potassiumCurrent;
1027  (*staVectorPtr)[li_NaCurrentState] = sodiumCurrent;
1028 
1029  return bsuccess;
1030 }
1031 
1032 //-----------------------------------------------------------------------------
1033 // Function : Instance::updateSecondaryState
1034 // Purpose :
1035 // Special Notes :
1036 // Scope : public
1037 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1038 // Creation Date : 01/02/08
1039 //-----------------------------------------------------------------------------
1041 {
1042  bool bsuccess = true;
1043 
1044  return bsuccess;
1045 }
1046 
1047 //-----------------------------------------------------------------------------
1048 // Function : Instance::loadDAEQVector
1049 //
1050 // Purpose : Loads the Q-vector contributions for a single
1051 // Neuron2 instance.
1052 //
1053 // Special Notes : The "Q" vector is part of a standard DAE formalism in
1054 // which the system of equations is represented as:
1055 //
1056 // f(x) = dQ(x)/dt + F(x) - B(t) = 0
1057 //
1058 // Scope : public
1059 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1060 // Creation Date : 01/02/08
1061 //-----------------------------------------------------------------------------
1063 {
1064  bool bsuccess = true;
1065 
1066  N_LAS_Vector * daeQVecPtr = extData.daeQVectorPtr;
1067 
1068  (*daeQVecPtr)[li_Pos] += kcl1Qvalue;
1069  (*daeQVecPtr)[li_Neg] += kcl2Qvalue;
1070  (*daeQVecPtr)[li_nPro] += nEquQvalue;
1071  (*daeQVecPtr)[li_mPro] += mEquQvalue;
1072  (*daeQVecPtr)[li_hPro] += hEquQvalue;
1073  (*daeQVecPtr)[li_aPro] += aEquQvalue;
1074  (*daeQVecPtr)[li_bPro] += bEquQvalue;
1075  (*daeQVecPtr)[li_M_Pro] += M_EquQvalue;
1076  (*daeQVecPtr)[li_H_Pro] += H_EquQvalue;
1077  (*daeQVecPtr)[li_cPro] += cEquQvalue;
1078  (*daeQVecPtr)[li_CaPro] += CaEquQvalue;
1079 
1080  return bsuccess;
1081 }
1082 
1083 
1084 
1085 //-----------------------------------------------------------------------------
1086 // Function : Instance::loadDAEFVector
1087 //
1088 // Purpose : Loads the F-vector contributions for a single
1089 // Neuron2 instance.
1090 //
1091 // Special Notes :
1092 //
1093 // Scope : public
1094 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1095 // Creation Date : 01/02/08
1096 //-----------------------------------------------------------------------------
1098 {
1099  bool bsuccess=true;
1100 
1101  N_LAS_Vector * daeFVecPtr = extData.daeFVectorPtr;
1102 
1103  (*daeFVecPtr)[li_Pos] += kcl1Fvalue;
1104  (*daeFVecPtr)[li_Neg] += kcl2Fvalue;
1105  (*daeFVecPtr)[li_nPro] += nEquFvalue;
1106  (*daeFVecPtr)[li_mPro] += mEquFvalue;
1107  (*daeFVecPtr)[li_hPro] += hEquFvalue;
1108  (*daeFVecPtr)[li_aPro] += aEquFvalue;
1109  (*daeFVecPtr)[li_bPro] += bEquFvalue;
1110  (*daeFVecPtr)[li_M_Pro] += M_EquFvalue;
1111  (*daeFVecPtr)[li_H_Pro] += H_EquFvalue;
1112  (*daeFVecPtr)[li_cPro] += cEquFvalue;
1113  (*daeFVecPtr)[li_CaPro] += CaEquFvalue;
1114 
1115  return bsuccess;
1116 }
1117 
1118 //-----------------------------------------------------------------------------
1119 // Function : Instance::loadDAEdQdx
1120 //
1121 // Purpose : Loads the Q-vector contributions for a single
1122 // Neuron 2 instance.
1123 // Scope : public
1124 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1125 // Creation Date : 01/02/08
1126 //-----------------------------------------------------------------------------
1128 {
1129  bool bsuccess = true;
1130 
1131  N_LAS_Matrix * dQdxMatPtr = extData.dQdxMatrixPtr;
1132 
1133  (*dQdxMatPtr)[li_Pos][APosEquPosNodeOffset] += dkcl1Q_dV1;
1134  (*dQdxMatPtr)[li_Pos][APosEquNegNodeOffset] += dkcl1Q_dV2;
1135 
1136  (*dQdxMatPtr)[li_Neg][ANegEquPosNodeOffset] += dkcl2Q_dV1;
1137  (*dQdxMatPtr)[li_Neg][ANegEquNegNodeOffset] += dkcl2Q_dV2;
1138 
1139  (*dQdxMatPtr)[li_nPro][ANEquNNodeOffset] += dnQ_dn;
1140  (*dQdxMatPtr)[li_mPro][AMEquMNodeOffset] += dmQ_dm;
1141  (*dQdxMatPtr)[li_hPro][AHEquHNodeOffset] += dhQ_dh;
1142  (*dQdxMatPtr)[li_aPro][AAEquANodeOffset] += daQ_da;
1143  (*dQdxMatPtr)[li_bPro][ABEquBNodeOffset] += dbQ_db;
1144  (*dQdxMatPtr)[li_M_Pro][AM_EquM_NodeOffset] += dMQ_dM;
1145  (*dQdxMatPtr)[li_H_Pro][AH_EquH_NodeOffset] += dHQ_dH;
1146  (*dQdxMatPtr)[li_cPro][ACEquCNodeOffset] += dcQ_dc;
1147  (*dQdxMatPtr)[li_CaPro][ACaEquCaNodeOffset] += dCaQ_dCa;
1148 
1149  return bsuccess;
1150 }
1151 
1152 
1153 
1154 //-----------------------------------------------------------------------------
1155 // Function : Instance::loadDAEdFdx ()
1156 //
1157 // Purpose : Loads the F-vector contributions for a single
1158 // Neuron 2 instance.
1159 //
1160 // Special Notes : This is an algebraic constaint.
1161 //
1162 // Scope : public
1163 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1164 // Creation Date : 01/02/08
1165 //-----------------------------------------------------------------------------
1167 {
1168  bool bsuccess = true;
1169 
1170  N_LAS_Matrix * dFdxMatPtr = extData.dFdxMatrixPtr;
1171 
1172  (*dFdxMatPtr)[li_Pos][APosEquPosNodeOffset] += dkcl1F_dV1;
1173  (*dFdxMatPtr)[li_Pos][APosEquNegNodeOffset] += dkcl1F_dV2;
1174  (*dFdxMatPtr)[li_Pos][APosEquNNodeOffset] += dkcl1F_dn;
1175  (*dFdxMatPtr)[li_Pos][APosEquMNodeOffset] += dkcl1F_dm;
1176  (*dFdxMatPtr)[li_Pos][APosEquHNodeOffset] += dkcl1F_dh;
1177  (*dFdxMatPtr)[li_Pos][APosEquANodeOffset] += dkcl1F_da;
1178  (*dFdxMatPtr)[li_Pos][APosEquBNodeOffset] += dkcl1F_db;
1179  (*dFdxMatPtr)[li_Pos][APosEquM_NodeOffset] += dkcl1F_dM;
1180  (*dFdxMatPtr)[li_Pos][APosEquH_NodeOffset] += dkcl1F_dH;
1181  (*dFdxMatPtr)[li_Pos][APosEquCNodeOffset] += dkcl1F_dc;
1182 
1183  (*dFdxMatPtr)[li_Neg][ANegEquPosNodeOffset] += dkcl2F_dV1;
1184  (*dFdxMatPtr)[li_Neg][ANegEquNegNodeOffset] += dkcl2F_dV2;
1185  (*dFdxMatPtr)[li_Neg][ANegEquNNodeOffset] += dkcl2F_dn;
1186  (*dFdxMatPtr)[li_Neg][ANegEquMNodeOffset] += dkcl2F_dm;
1187  (*dFdxMatPtr)[li_Neg][ANegEquHNodeOffset] += dkcl2F_dh;
1188  (*dFdxMatPtr)[li_Neg][ANegEquANodeOffset] += dkcl2F_da;
1189  (*dFdxMatPtr)[li_Neg][ANegEquBNodeOffset] += dkcl2F_db;
1190  (*dFdxMatPtr)[li_Neg][ANegEquM_NodeOffset] += dkcl2F_dM;
1191  (*dFdxMatPtr)[li_Neg][ANegEquH_NodeOffset] += dkcl2F_dH;
1192  (*dFdxMatPtr)[li_Neg][ANegEquCNodeOffset] += dkcl2F_dc;
1193 
1194  (*dFdxMatPtr)[li_nPro][ANEquPosNodeOffset] += dnF_dV1;
1195  (*dFdxMatPtr)[li_nPro][ANEquNNodeOffset] += dnF_dn;
1196 
1197  (*dFdxMatPtr)[li_mPro][AMEquPosNodeOffset] += dmF_dV1;
1198  (*dFdxMatPtr)[li_mPro][AMEquMNodeOffset] += dmF_dm;
1199 
1200  (*dFdxMatPtr)[li_hPro][AHEquPosNodeOffset] += dhF_dV1;
1201  (*dFdxMatPtr)[li_hPro][AHEquHNodeOffset] += dhF_dh;
1202 
1203  (*dFdxMatPtr)[li_aPro][AAEquPosNodeOffset] += daF_dV1;
1204  (*dFdxMatPtr)[li_aPro][AAEquANodeOffset] += daF_da;
1205 
1206  (*dFdxMatPtr)[li_bPro][ABEquPosNodeOffset] += dbF_dV1;
1207  (*dFdxMatPtr)[li_bPro][ABEquBNodeOffset] += dbF_db;
1208 
1209  (*dFdxMatPtr)[li_M_Pro][AM_EquPosNodeOffset] += dMF_dV1;
1210  (*dFdxMatPtr)[li_M_Pro][AM_EquM_NodeOffset] += dMF_dM;
1211 
1212  (*dFdxMatPtr)[li_H_Pro][AH_EquPosNodeOffset] += dHF_dV1;
1213  (*dFdxMatPtr)[li_H_Pro][AH_EquH_NodeOffset] += dHF_dH;
1214 
1215  (*dFdxMatPtr)[li_cPro][ACEquPosNodeOffset] += dcF_dV1;
1216  (*dFdxMatPtr)[li_cPro][ACEquCNodeOffset] += dcF_dc;
1217  (*dFdxMatPtr)[li_cPro][ACEquCaNodeOffset] += dcF_dCa;
1218 
1219  (*dFdxMatPtr)[li_CaPro][ACaEquPosNodeOffset] += dCaF_dV1;
1220  (*dFdxMatPtr)[li_CaPro][ACaEquNegNodeOffset] += dCaF_dV2;
1221  (*dFdxMatPtr)[li_CaPro][ACaEquM_NodeOffset] += dCaF_dM;
1222  (*dFdxMatPtr)[li_CaPro][ACaEquH_NodeOffset] += dCaF_dH;
1223  (*dFdxMatPtr)[li_CaPro][ACaEquCaNodeOffset] += dCaF_dCa;
1224 
1225  return bsuccess;
1226 }
1227 
1228 //-----------------------------------------------------------------------------
1229 // Function : Instance::setIC
1230 // Purpose :
1231 // Special Notes :
1232 // Scope : public
1233 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1234 // Creation Date : 01/02/08
1235 //-----------------------------------------------------------------------------
1237 {
1238  bool bsuccess = true;
1239 
1240  return bsuccess;
1241 }
1242 
1243 //-----------------------------------------------------------------------------
1244 // Function : Instance::varTypes
1245 // Purpose :
1246 // Special Notes :
1247 // Scope : public
1248 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1249 // Creation Date : 01/02/08
1250 //-----------------------------------------------------------------------------
1251 void Instance::varTypes( std::vector<char> & varTypeVec )
1252 {
1253  //varTypeVec.resize(1);
1254  //varTypeVec[0] = 'I';
1255 }
1256 
1257 
1258 //-----------------------------------------------------------------------------
1259 // Function : Model::processParams
1260 // Purpose :
1261 // Special Notes :
1262 // Scope : public
1263 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1264 // Creation Date : 01/02/08
1265 //-----------------------------------------------------------------------------
1267 {
1268  return true;
1269 }
1270 
1271 //----------------------------------------------------------------------------
1272 // Function : Model::processInstanceParams
1273 // Purpose :
1274 // Special Notes :
1275 // Scope : public
1276 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1277 // Creation Date : 01/02/08
1278 //----------------------------------------------------------------------------
1280 {
1281 
1282  std::vector<Instance*>::iterator iter;
1283  std::vector<Instance*>::iterator first = instanceContainer.begin();
1284  std::vector<Instance*>::iterator last = instanceContainer.end();
1285 
1286  for (iter=first; iter!=last; ++iter)
1287  {
1288  (*iter)->processParams();
1289  }
1290 
1291  return true;
1292 }
1293 
1294 //-----------------------------------------------------------------------------
1295 // Function : Model::Model
1296 // Purpose : block constructor
1297 // Special Notes :
1298 // Scope : public
1299 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1300 // Creation Date : 01/02/08
1301 //-----------------------------------------------------------------------------
1303  const Configuration & configuration,
1304  const ModelBlock & MB,
1305  const FactoryBlock & factory_block)
1306  : DeviceModel(MB, configuration.getModelParameters(), factory_block)
1307 {
1308 
1309  // Set params to constant default values:
1310  setDefaultParams ();
1311 
1312  // Set params according to .model line and constant defaults from metadata:
1313  setModParams (MB.params);
1314 
1315  // Set any non-constant parameter defaults:
1316  //if (!given("TNOM"))
1317  // tnom = getDeviceOptions().tnom;
1318 
1319  // Calculate any parameters specified as expressions:
1321 
1322  // calculate dependent (ie computed) params and check for errors:
1323 
1324  processParams ();
1325 }
1326 
1327 //-----------------------------------------------------------------------------
1328 // Function : Model::~Model
1329 // Purpose : destructor
1330 // Special Notes :
1331 // Scope : public
1332 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1333 // Creation Date : 01/02/08
1334 //-----------------------------------------------------------------------------
1336 {
1337  std::vector<Instance*>::iterator iter;
1338  std::vector<Instance*>::iterator first = instanceContainer.begin();
1339  std::vector<Instance*>::iterator last = instanceContainer.end();
1340 
1341  for (iter=first; iter!=last; ++iter)
1342  {
1343  delete (*iter);
1344  }
1345 
1346 }
1347 
1348 // additional Declarations
1349 
1350 //-----------------------------------------------------------------------------
1351 // Function : Model::printOutInstances
1352 // Purpose : debugging tool.
1353 // Special Notes :
1354 // Scope : public
1355 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1356 // Creation Date : 01/02/08
1357 //-----------------------------------------------------------------------------
1358 std::ostream &Model::printOutInstances(std::ostream &os) const
1359 {
1360  std::vector<Instance*>::const_iterator iter;
1361  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
1362  std::vector<Instance*>::const_iterator last = instanceContainer.end();
1363 
1364  int i, isize;
1365  isize = instanceContainer.size();
1366 
1367  os << std::endl;
1368  os << "Number of Neuron instances: " << isize << std::endl;
1369  os << " name=\t\tmodelName\tParameters" << std::endl;
1370  for (i=0, iter=first; iter!=last; ++iter, ++i)
1371  {
1372  os << " " << i << ": " << (*iter)->getName() << "\t";
1373  os << getName();
1374  os << std::endl;
1375  }
1376 
1377  os << std::endl;
1378  return os;
1379 }
1380 
1381 //-----------------------------------------------------------------------------
1382 // Function : Model::forEachInstance
1383 // Purpose :
1384 // Special Notes :
1385 // Scope : public
1386 // Creator : David Baur
1387 // Creation Date : 2/4/2014
1388 //-----------------------------------------------------------------------------
1389 /// Apply a device instance "op" to all instances associated with this
1390 /// model
1391 ///
1392 /// @param[in] op Operator to apply to all instances.
1393 ///
1394 ///
1395 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
1396 {
1397  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1398  op(*it);
1399 }
1400 
1401 
1402 Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
1403 {
1404 
1405  return new DeviceMaster<Traits>(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
1406 }
1407 
1409 {
1411  .registerDevice("neuron", 2)
1412  .registerModelType("neuron", 2);
1413 }
1414 
1415 } // namespace Neuron2
1416 } // namespace Device
1417 } // namespace Xyce