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