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