Xyce  6.1
N_DEV_Neuron4.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-2015 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$
27 //
28 // Purpose :
29 //
30 // Special Notes :
31 //
32 // Creator : Richard Schiek, Electrical and Microsytem Modeling
33 //
34 // Creation Date : 06/10/09
35 //
36 // Revision Information:
37 // ---------------------
38 //
39 // Revision Number: $Revision$
40 //
41 // Revision Date : $Date$
42 //
43 // Current Owner : $Author$
44 //-------------------------------------------------------------------------
45 
46 #include <Xyce_config.h>
47 
48 
49 // ---------- Standard Includes ----------
50 
51 
52 // ---------- Xyce Includes ----------
53 #include <N_DEV_DeviceOptions.h>
54 #include <N_DEV_DeviceMaster.h>
55 #include <N_DEV_ExternData.h>
56 #include <N_DEV_MatrixLoadData.h>
57 #include <N_DEV_Neuron4.h>
58 #include <N_DEV_SolverState.h>
59 #include <N_DEV_Message.h>
60 #include <N_ERH_ErrorMgr.h>
61 
62 #include <N_DEV_Neuron.h>
63 
64 #include <N_LAS_Vector.h>
65 #include <N_LAS_Matrix.h>
66 #include <N_UTL_FeatureTest.h>
67 #include <N_UTL_Math.h>
68 
69 namespace Xyce {
70 namespace Device {
71 
72 
73 namespace Neuron4 {
74 
75 
77 {
78  p.addPar ("R",0.0,&Neuron4::Instance::rInt)
79  .setGivenMember(&Neuron4::Instance::rIntGiven)
80  .setUnit(U_OHMMM1)
81  .setCategory(CAT_NONE)
82  .setDescription("Intracellular resistivity");
83 
85  .setGivenMember(&Neuron4::Instance::radiusGiven)
86  .setUnit(U_METER)
87  .setCategory(CAT_NONE)
88  .setDescription("Segment radius");
89 
91  .setGivenMember(&Neuron4::Instance::lengthGiven)
92  .setUnit(U_METER)
93  .setCategory(CAT_NONE)
94  .setDescription("Cable length");
95 
96  p.addPar ("RPS",1.0e-6,&Neuron4::Instance::rIntPrevious)
97  .setGivenMember(&Neuron4::Instance::rIntPreviousGiven)
98  .setUnit(U_OHMMM1)
99  .setCategory(CAT_NONE)
100  .setDescription("Previous segment,intracellular resistivity");
101 
104  .setUnit(U_METER)
105  .setCategory(CAT_NONE)
106  .setDescription("Previous segment,segment radius");
107 
110  .setUnit(U_METER)
111  .setCategory(CAT_NONE)
112  .setDescription("Previous segment length");
113 
114  p.addPar ("RNS",1.0e-6,&Neuron4::Instance::rIntNext)
115  .setGivenMember(&Neuron4::Instance::rIntNextGiven)
116  .setUnit(U_OHMMM1)
117  .setCategory(CAT_NONE)
118  .setDescription("Next segment,intracellular resistivity");
119 
121  .setGivenMember(&Neuron4::Instance::radiusNextGiven)
122  .setUnit(U_METER)
123  .setCategory(CAT_NONE)
124  .setDescription("Next segment,segment radius");
125 
127  .setGivenMember(&Neuron4::Instance::lengthNextGiven)
128  .setUnit(U_METER)
129  .setCategory(CAT_NONE)
130  .setDescription("Next segment length");
131 
133  .setGivenMember(&Neuron4::Instance::nSegGiven)
134  .setUnit(U_NONE)
135  .setCategory(CAT_NONE)
136  .setDescription("Number of segments");
137 }
138 
140 {
141  p.addPar ("CMEM",0.0,&Neuron4::Model::cMem)
142  .setGivenMember(&Neuron4::Model::cMemGiven)
143  .setUnit(U_FARAD)
144  .setCategory(CAT_NONE)
145  .setDescription("Membrane capacitance");
146 
147  p.addPar ("GMEM",0.0,&Neuron4::Model::gMem)
148  .setGivenMember(&Neuron4::Model::gMemGiven)
149  .setUnit(U_OHMM1)
150  .setCategory(CAT_NONE)
151  .setDescription("Membrane conductance");
152 
153  p.addPar ("VREST",0.0,&Neuron4::Model::vRest)
154  .setGivenMember(&Neuron4::Model::vRestGiven)
155  .setUnit(U_VOLT)
156  .setCategory(CAT_NONE)
157  .setDescription("Resting potential");
158 
159  p.addPar ("EK",0.0,&Neuron4::Model::eK)
160  .setGivenMember(&Neuron4::Model::eKGiven)
161  .setUnit(U_VOLT)
162  .setCategory(CAT_NONE)
163  .setDescription("Potassium resting potential");
164 
165  p.addPar ("GK",0.0,&Neuron4::Model::gK)
166  .setGivenMember(&Neuron4::Model::gKGiven)
167  .setUnit(U_OHMM1)
168  .setCategory(CAT_NONE)
169  .setDescription("Potassium base conductance");
170 
171  p.addPar ("ENA",0.0,&Neuron4::Model::eNa)
172  .setGivenMember(&Neuron4::Model::eNaGiven)
173  .setUnit(U_VOLT)
174  .setCategory(CAT_NONE)
175  .setDescription("Sodium resting potential");
176 
177  p.addPar ("GNA",0.0,&Neuron4::Model::gNa)
178  .setGivenMember(&Neuron4::Model::gNaGiven)
179  .setUnit(U_OHMM1)
180  .setCategory(CAT_NONE)
181  .setDescription("Sodium base conductance");
182 
183  p.addPar ("EA",0.0,&Neuron4::Model::eA)
184  .setGivenMember(&Neuron4::Model::eAGiven)
185  .setUnit(U_CM)
186  .setCategory(CAT_NONE)
187  .setDescription("a-current rest potential");
188 
189  p.addPar ("GA",0.0,&Neuron4::Model::gA)
190  .setGivenMember(&Neuron4::Model::gAGiven)
191  .setUnit(U_NONE)
192  .setCategory(CAT_NONE)
193  .setDescription("a-current base conductance");
194 
195  p.addPar ("ECA",0.0,&Neuron4::Model::eCa)
196  .setGivenMember(&Neuron4::Model::eCaGiven)
197  .setUnit(U_NONE)
198  .setCategory(CAT_NONE)
199  .setDescription("Calcium rest potential");
200 
201  p.addPar ("GCA",0.0,&Neuron4::Model::gCa)
202  .setGivenMember(&Neuron4::Model::gCaGiven)
203  .setUnit(U_OHMM1)
204  .setCategory(CAT_NONE)
205  .setDescription("Calcium base conductance");
206 
207  p.addPar ("EKCA",0.0,&Neuron4::Model::eKCa)
208  .setGivenMember(&Neuron4::Model::eKCaGiven)
209  .setUnit(U_OHMM1)
210  .setCategory(CAT_NONE)
211  .setDescription("Potassium-calcium rest potential");
212 
213  p.addPar ("GKCA",0.0,&Neuron4::Model::gKCa)
214  .setGivenMember(&Neuron4::Model::gKCaGiven)
215  .setUnit(U_OHMM1)
216  .setCategory(CAT_NONE)
217  .setDescription("Potassium-calcium base conductance");
218 
219  p.addPar ("CAINIT",0.0,&Neuron4::Model::CaInit)
220  .setGivenMember(&Neuron4::Model::CaInitGiven)
221  .setUnit(U_OHMM1)
222  .setCategory(CAT_NONE)
223  .setDescription("initial intra-cellular calcium concentration");
224 
225  p.addPar ("CAGAMMA",0.0,&Neuron4::Model::CaGamma)
226  .setGivenMember(&Neuron4::Model::CaGammaGiven)
227  .setUnit(U_OHMM1)
228  .setCategory(CAT_NONE)
229  .setDescription("calcium current to concentration multiplier");
230 
231  p.addPar ("CATAU",0.0,&Neuron4::Model::CaTau)
232  .setGivenMember(&Neuron4::Model::CaTauGiven)
233  .setUnit(U_OHMM1)
234  .setCategory(CAT_NONE)
235  .setDescription("calcium removal time constant");
236 
237  p.addPar ("R",0.0,&Neuron4::Model::rInt)
238  .setGivenMember(&Neuron4::Model::rIntGiven)
239  .setUnit(U_OHMMM1)
240  .setCategory(CAT_NONE)
241  .setDescription("Intracellular resistivity");
242 
243  p.addPar ("A",0.0,&Neuron4::Model::radius)
244  .setGivenMember(&Neuron4::Model::radiusGiven)
245  .setUnit(U_METER)
246  .setCategory(CAT_NONE)
247  .setDescription("Segment radius");
248 
249  p.addPar ("L",0.0,&Neuron4::Model::length)
250  .setGivenMember(&Neuron4::Model::lengthGiven)
251  .setUnit(U_METER)
252  .setCategory(CAT_NONE)
253  .setDescription("Cable length");
254 
255  p.addPar ("RPS",1.0e-6,&Neuron4::Model::rIntPrevious)
256  .setGivenMember(&Neuron4::Model::rIntPreviousGiven)
257  .setUnit(U_OHMMM1)
258  .setCategory(CAT_NONE)
259  .setDescription("Previous segment,intracellular resistivity");
260 
262  .setGivenMember(&Neuron4::Model::radiusPreviousGiven)
263  .setUnit(U_METER)
264  .setCategory(CAT_NONE)
265  .setDescription("Previous segment,segment radius");
266 
268  .setGivenMember(&Neuron4::Model::lengthPreviousGiven)
269  .setUnit(U_METER)
270  .setCategory(CAT_NONE)
271  .setDescription("Previous segment length");
272 
273  p.addPar ("RNS",1.0e-6,&Neuron4::Model::rIntNext)
274  .setGivenMember(&Neuron4::Model::rIntNextGiven)
275  .setUnit(U_OHMMM1)
276  .setCategory(CAT_NONE)
277  .setDescription("Next segment,intracellular resistivity");
278 
279  p.addPar ("ANS",0.0,&Neuron4::Model::radiusNext)
280  .setGivenMember(&Neuron4::Model::radiusNextGiven)
281  .setUnit(U_METER)
282  .setCategory(CAT_NONE)
283  .setDescription("Next segment,segment radius");
284 
285  p.addPar ("LNS",0.0,&Neuron4::Model::lengthNext)
286  .setGivenMember(&Neuron4::Model::lengthNextGiven)
287  .setUnit(U_METER)
288  .setCategory(CAT_NONE)
289  .setDescription("Next segment length");
290 
291  p.addPar("N",0,&Neuron4::Model::nSeg)
292  .setGivenMember(&Neuron4::Model::nSegGiven)
293  .setUnit(U_NONE)
294  .setCategory(CAT_NONE)
295  .setDescription("Number of segments");
296 }
297 
298 
299 // Class Instance
300 //-----------------------------------------------------------------------------
301 // Function : Instance::processParams
302 // Purpose :
303 // Special Notes :
304 // Scope : public
305 // Creator : Richard Schiek, Electrical and Microsytem Modeling
306 // Creation Date : 06/10/09
307 //-----------------------------------------------------------------------------
309 {
310  // If there are any time dependent parameters, set their values at for
311  // the current time.
312 
313  // pull unspecified params out of the model if they weren't specified here
314  if( !nSegGiven )
315  {
316  if ( model_.nSegGiven )
317  {
318  nSeg = model_.nSeg;
319  }
320  else
321  {
322  nSeg = 10;
323  }
324  }
325 
326  if( !rIntGiven && model_.rIntGiven )
327  {
328  rInt = model_.rInt;
329  }
330  if( !radiusGiven && model_.radiusGiven )
331  {
332  radius = model_.radius;
333  }
334  if( !lengthGiven && model_.lengthGiven )
335  {
336  length = model_.length;
337  }
338 
339  // if nSeg is still unknown then estimate it via lambda-d rule (TO DO)
340 
341  // now that nSeg, length and radius are set calculate segment area
342  segArea = 2.0 * M_PI * radius * length / nSeg;
343 
344  return true;
345 }
346 
347 //-----------------------------------------------------------------------------
348 // Function : Instance::updateTemperature
349 // Purpose :
350 // Special Notes :
351 // Scope : public
352 // Creator : Richard Schiek, Electrical and Microsytem Modeling
353 // Creation Date : 06/10/09
354 //-----------------------------------------------------------------------------
355 bool Instance::updateTemperature ( const double & temp)
356 {
357  bool bsuccess = true;
358  return bsuccess;
359 }
360 
361 //-----------------------------------------------------------------------------
362 // Function : Instance::Instance
363 // Purpose : constructor
364 // Special Notes :
365 // Scope : public
366 // Creator : Richard Schiek, Electrical and Microsytem Modeling
367 // Creation Date : 06/10/09
368 //-----------------------------------------------------------------------------
370  const Configuration & configuration,
371  const InstanceBlock & IB,
372  Model & Miter,
373  const FactoryBlock & factory_block)
374  : DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
375  model_(Miter),
376  rInt(0.0),
377  radius(0.0),
378  length(0.0),
379  segArea(0.0),
380  nSeg(0),
381  rIntGiven(false),
382  radiusGiven(false),
383  lengthGiven(false),
384  nSegGiven(false),
385  rIntPrevious(0.0),
386  radiusPrevious(0.0),
387  lengthPrevious(0.0),
388  rIntNext(0.0),
389  radiusNext(0.0),
390  lengthNext(0.0),
391  rIntPreviousGiven(false),
392  radiusPreviousGiven(false),
393  lengthPreviousGiven(false),
394  rIntNextGiven(false),
395  radiusNextGiven(false),
396  lengthNextGiven(false),
397  kcl1Fvalue(0.0),
398  kcl2Fvalue(0.0),
399  dkcl1F_dVin(0.0),
400  dkcl1F_dVs0(0.0),
401  dkcl2F_dVout(0.0),
402  dkcl2F_dVsn(0.0),
403  li_Pos(0),
404  li_Neg(0),
405  APosEquPosNodeOffset(0),
406  APosEquNextNodeOffset(0),
407  ANegEquNegNodeOffset(0),
408  ANegEquLastNodeOffset(0)
409 {
410  // we have pased the model and instance parameters so now we can calculate
411  // the number of internal vars
412  numExtVars = 2; // input and output voltage
413 
414  // Set params to constant default values:
415  setDefaultParams ();
416 
417  // Set params according to instance line
418  setParams (IB.params);
419 
420  // Set any non-constant parameter defaults:
421 
422  //if (!given("TEMP"))
423  // temp = getDeviceOptions().temp.dVal();
424 
425  // Calculate any parameters specified as expressions:
427 
428  // calculate dependent (ie computed) params and check for errors:
429  processParams ();
430 
431  // now we can calculate the number of internal vars
432  numIntVars = nSeg * 10; // ion channel vars + one internal voltage node var for each segment
433  numStateVars = nSeg * 2; // two currents per segment
434  int numVars = numExtVars + numIntVars;
435 
436  //
437  // i(n) - I(n)/A - g(n,n+1) * (V(n+1) - V(n)) - g(n,n-1) * (V(n-1) - V(n)) + Cm dV(n)/d(t) = 0
438  //
439  // Vin : g(0,1) * (V(1) - Vin ) = 0
440  // Vout : g(n,n-1) * (V(n-1) - Vout) = 0
441  // Vnode : i(n) - I(n)/A - g(n,n+1) * (V(n+1) - V(n)) - g(n,n-1) * (V(n-1) - V(n)) + Cm dV(n)/d(t) = 0
442  // plus node supporting equations (a, b, m)
443  //
444  // jacobian format
445  // Vin Vout V1 n m h a b M H c Ca V2 n m h V(nSeg) n m h
446  // kcl Vin -g(0,1) g(0,1)
447  // kcl Vout -g(n,n-1) g(n,n-1)
448  // kcl V1 yes yes yes yes yes y y y y y yes
449  // n yes yes
450  // m yes yes
451  // h yes yes
452  // a yes yes
453  // b yes yes
454  // M yes yes
455  // H yes yes
456  // c yes yes yes
457  // Ca yes yes yes yes
458  //
459  //
460  // jacobian element count by row:
461  // vin: 2
462  // vout: 2
463  // v1: 11
464  // n1: 2
465  // m1: 2
466  // h1: 2
467  // a1: 2
468  // b1: 2
469  // M1: 2
470  // H1: 2
471  // c1: 3
472  // Ca1: 4
473  //
474  // set up jacStamp
475  if( jacStamp.empty() ) // redundant as jacStamp is not static for this device
476  { // it can't be as each cable may have a different number of nodes
477  jacStamp.resize(numVars);
478  jacStamp[0].resize(2);
479  jacStamp[0][0] = 0;
480  jacStamp[0][1] = 1;
481  jacStamp[1].resize(2);
482  jacStamp[1][0] = 1;
483  jacStamp[1][1] = numVars - 10;
484  for( int i=2; i<numVars; i+=10)
485  {
486  jacStamp[i].resize(11);
487  if( i == 2 )
488  {
489  jacStamp[i][0] = 0; // v_in
490  }
491  else
492  {
493  jacStamp[i][0] = i-10; // v_prev
494  }
495  jacStamp[i][1] = i; // v
496  jacStamp[i][2] = i+1; // n
497  jacStamp[i][3] = i+2; // m
498  jacStamp[i][4] = i+3; // h
499  jacStamp[i][5] = i+4; // a
500  jacStamp[i][6] = i+5; // b
501  jacStamp[i][7] = i+6; // M
502  jacStamp[i][8] = i+7; // H
503  jacStamp[i][9] = i+8; // c
504  if( i==(numVars-10) )
505  {
506  jacStamp[i][10] = 1; // v_out
507  }
508  else
509  {
510  jacStamp[i][10] = i+10; // v_next
511  }
512  jacStamp[i+1].resize(2); // n
513  jacStamp[i+1][0] = i;
514  jacStamp[i+1][1] = i+1;
515  jacStamp[i+2].resize(2); // m
516  jacStamp[i+2][0] = i;
517  jacStamp[i+2][1] = i+2;
518  jacStamp[i+3].resize(2); // h
519  jacStamp[i+3][0] = i;
520  jacStamp[i+3][1] = i+3;
521  jacStamp[i+4].resize(2); // a
522  jacStamp[i+4][0] = i;
523  jacStamp[i+4][1] = i+4;
524  jacStamp[i+5].resize(2); // b
525  jacStamp[i+5][0] = i;
526  jacStamp[i+5][1] = i+5;
527  jacStamp[i+6].resize(2); // M
528  jacStamp[i+6][0] = i;
529  jacStamp[i+6][1] = i+6;
530  jacStamp[i+7].resize(2); // H
531  jacStamp[i+7][0] = i;
532  jacStamp[i+7][1] = i+7;
533  jacStamp[i+8].resize(3); // c
534  jacStamp[i+8][0] = i;
535  jacStamp[i+8][1] = i+8;
536  jacStamp[i+8][2] = i+9;
537  jacStamp[i+9].resize(4); // ca
538  jacStamp[i+9][0] = i;
539  jacStamp[i+9][1] = i+6;
540  jacStamp[i+9][2] = i+7;
541  jacStamp[i+9][3] = i+9;
542 
543  }
544 
545  }
546 
547  /*
548  // print out jacStamp
549  int numRows = jacStamp.size();
550  for( int i=0; i< numRows; i++ )
551  {
552  int numCol = jacStamp[i].size();
553  Xyce::dout() << "jacStamp[ " << i << " ] = { ";
554  for(int j=0; j<numCol; j++)
555  {
556  Xyce::dout() << jacStamp[i][j] << " ";
557  }
558  Xyce::dout() << " } " << std::endl;
559  }
560  Xyce::dout() << std::endl;
561  */
562 
563  // calculate segment conductivities used in load calls:
564  // Note: conductivity to the previous and next segment is not symmetric if the segment length and/or radius is not are not equal
565  // the full formula is:
566  // g(n,n') = radius * (radius')^2 / ( rInt segLength * ( segLength * (radius')^2 + segLength' * (radius)^2 ) )
567  //
568  // equation 6.30 Theoretical neuroscience: computational and mathematical modeling of neural systems, Peter Dayan and L. F. Abbot 2001
569  // If we allow variable segment lengths and radii then we'll need to update this calculation
570  //
571  // Note: the above equation has the wrong units unless rInt (which is Ohm Length) is rLong (which is Ohm/Length).
572  //
573  gForward.resize(nSeg);
574  gBackward.resize(nSeg);
575  double segLength = length / nSeg;
576  double rLong = rInt / (M_PI * radius * radius); // longitudinal resistivity (ohm/length)
577  gBackward[0] = radius * (radiusPrevious * radiusPrevious) / (rLong * segLength * ( segLength * radiusPrevious * radiusPrevious + lengthPrevious * radius * radius ));
578  gForward[0] = radius * (radius * radius) / (rLong * segLength * ( segLength * radius * radius + segLength * radius * radius ));
579  gBackward[nSeg-1] = radius * (radius * radius) / (rLong * segLength * ( segLength * radius * radius + segLength * radius * radius ));
580  gForward[nSeg-1] = radius * (radiusNext * radiusNext) / (rLong * segLength * ( segLength * radiusNext * radiusNext + lengthNext * radius * radius ));
581  for(int i=1; i<(nSeg-1); i++)
582  {
583  gBackward[i] = radius * (radius * radius) / (rLong * segLength * ( segLength * radius * radius + segLength * radius * radius ));
584  gForward[i] = gBackward[i];
585  }
586  // gForward.resize(nSeg);
587  // gBackward.resize(nSeg);
588  // double segLength = length / nSeg;
589  // gBackward[0] = radius * (radiusPrevious * radiusPrevious) / (rInt * segLength * ( segLength * radiusPrevious * radiusPrevious + lengthPrevious * radius * radius ));
590  // gForward[0] = radius * (radius * radius) / (rInt * segLength * ( segLength * radius * radius + segLength * radius * radius ));
591  // gBackward[nSeg-1] = radius * (radius * radius) / (rInt * segLength * ( segLength * radius * radius + segLength * radius * radius ));
592  // gForward[nSeg-1] = radius * (radiusNext * radiusNext) / (rInt * segLength * ( segLength * radiusNext * radiusNext + lengthNext * radius * radius ));
593  // for(int i=1; i<(nSeg-1); i++)
594  // {
595  // gBackward[i] = radius * (radius * radius) / (rInt * segLength * ( segLength * radius * radius + segLength * radius * radius ));
596  // gForward[i] = gBackward[i];
597  // }
598 
599  // allocate space for load and jacobian terms per segment
600  // variable indecies loads
601  li_Vol.resize(nSeg);
602  li_nPro.resize(nSeg);
603  li_mPro.resize(nSeg);
604  li_hPro.resize(nSeg);
605  li_aPro.resize(nSeg);
606  li_bPro.resize(nSeg);
607  li_MPro.resize(nSeg);
608  li_HPro.resize(nSeg);
609  li_cPro.resize(nSeg);
610  li_CaPro.resize(nSeg);
611  li_KCurrentState.resize(nSeg);
612  li_NaCurrentState.resize(nSeg);
613  segFvalue.resize(nSeg);
614  segQvalue.resize(nSeg);
615  segNEquFvalue.resize(nSeg);
616  segNEquQvalue.resize(nSeg);
617  segMEquFvalue.resize(nSeg);
618  segMEquQvalue.resize(nSeg);
619  segHEquFvalue.resize(nSeg);
620  segHEquQvalue.resize(nSeg);
621  segAEquFvalue.resize(nSeg);
622  segAEquQvalue.resize(nSeg);
623  segBEquFvalue.resize(nSeg);
624  segBEquQvalue.resize(nSeg);
625  segM_EquFvalue.resize(nSeg);
626  segM_EquQvalue.resize(nSeg);
627  segH_EquFvalue.resize(nSeg);
628  segH_EquQvalue.resize(nSeg);
629  segCEquFvalue.resize(nSeg);
630  segCEquQvalue.resize(nSeg);
631  segCaEquFvalue.resize(nSeg);
632  segCaEquQvalue.resize(nSeg);
633 
634  // jacobian elements
635  segF_dVp.resize(nSeg);
636  segF_dV.resize(nSeg);
637  segF_dVn.resize(nSeg);
638  segF_dn.resize(nSeg);
639  segF_dm.resize(nSeg);
640  segF_dh.resize(nSeg);
641  segF_da.resize(nSeg);
642  segF_db.resize(nSeg);
643  segF_dM.resize(nSeg);
644  segF_dH.resize(nSeg);
645  segF_dc.resize(nSeg);
646  segQ_dV.resize(nSeg);
647  dnF_dV.resize(nSeg);
648  dnF_dn.resize(nSeg);
649  dnQ_dn.resize(nSeg);
650  dmF_dV.resize(nSeg);
651  dmF_dm.resize(nSeg);
652  dmQ_dm.resize(nSeg);
653  dhF_dV.resize(nSeg);
654  dhF_dh.resize(nSeg);
655  dhQ_dh.resize(nSeg);
656  daF_dV.resize(nSeg);
657  daF_da.resize(nSeg);
658  daQ_da.resize(nSeg);
659  dbF_dV.resize(nSeg);
660  dbF_db.resize(nSeg);
661  dbQ_db.resize(nSeg);
662  dMF_dV.resize(nSeg);
663  dMF_dM.resize(nSeg);
664  dMQ_dM.resize(nSeg);
665  dHF_dV.resize(nSeg);
666  dHF_dH.resize(nSeg);
667  dHQ_dH.resize(nSeg);
668  dcF_dV.resize(nSeg);
669  dcF_dc.resize(nSeg);
670  dcF_dCa.resize(nSeg);
671  dcQ_dc.resize(nSeg);
672  dCaF_dV.resize(nSeg);
673  dCaF_dM.resize(nSeg);
674  dCaF_dH.resize(nSeg);
675  dCaF_dCa.resize(nSeg);
676  dCaQ_dCa.resize(nSeg);
677 
678  // state vars
679  potassiumCurrent.resize(nSeg);
680  sodiumCurrent.resize(nSeg);
681 
682 }
683 
684 //-----------------------------------------------------------------------------
685 // Function : Instance::~Instance
686 // Purpose : destructor
687 // Special Notes :
688 // Scope : public
689 // Creator : Richard Schiek, Electrical and Microsytem Modeling
690 // Creation Date : 06/10/09
691 //-----------------------------------------------------------------------------
693 {
694 }
695 
696 //-----------------------------------------------------------------------------
697 // Function : Instance::registerLIDs
698 // Purpose :
699 // Special Notes :
700 // Scope : public
701 // Creator : Richard Schiek, Electrical and Microsytem Modeling
702 // Creation Date : 06/10/09
703 //-----------------------------------------------------------------------------
704 void Instance::registerLIDs(const std::vector<int> & intLIDVecRef,
705  const std::vector<int> & extLIDVecRef)
706 {
707  AssertLIDs(intLIDVecRef.size() == numIntVars);
708  AssertLIDs(extLIDVecRef.size() == numExtVars);
709 
710  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
711  {
712  Xyce::dout() << std::endl << section_divider << std::endl;
713  Xyce::dout() << " Instance::registerLIDs" << std::endl;
714  Xyce::dout() << " name = " << getName() << std::endl;
715  }
716 
717  // copy over the global ID lists.
718  intLIDVec = intLIDVecRef;
719  extLIDVec = extLIDVecRef;
720 
721  li_Pos = extLIDVec[0];
722  li_Neg = extLIDVec[1];
723  for( int i=0, j=0; i<nSeg; i++, j+=10)
724  {
725  li_Vol[i] = intLIDVec[j];
726  li_nPro[i] = intLIDVec[j+1];
727  li_mPro[i] = intLIDVec[j+2];
728  li_hPro[i] = intLIDVec[j+3];
729  li_aPro[i] = intLIDVec[j+4];
730  li_bPro[i] = intLIDVec[j+5];
731  li_MPro[i] = intLIDVec[j+6];
732  li_HPro[i] = intLIDVec[j+7];
733  li_cPro[i] = intLIDVec[j+8];
734  li_CaPro[i] = intLIDVec[j+9];
735  }
736 
737  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) )
738  {
739  Xyce::dout() << " li_Pos = " << li_Pos << std::endl
740  << " li_Neg = " << li_Neg << std::endl;
741  for( int i=0; i<nSeg; i++ )
742  {
743  Xyce::dout() << " li_Vol[ " << i << " ] = " << li_Vol[i] << std::endl
744  << " li_nPro[ " << i << " ] = " << li_nPro[i] << std::endl
745  << " li_mPro[ " << i << " ] = " << li_mPro[i] << std::endl
746  << " li_hPro[ " << i << " ] = " << li_hPro[i] << std::endl
747  << " li_aPro[ " << i << " ] = " << li_aPro[i] << std::endl
748  << " li_bPro[ " << i << " ] = " << li_bPro[i] << std::endl
749  << " li_MPro[ " << i << " ] = " << li_MPro[i] << std::endl
750  << " li_HPro[ " << i << " ] = " << li_HPro[i] << std::endl
751  << " li_cPro[ " << i << " ] = " << li_cPro[i] << std::endl
752  << " li_CaPro[ " << i << " ] = " << li_CaPro[i] << std::endl;
753  }
754  }
755 
756  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) )
757  {
758  Xyce::dout() << section_divider << std::endl;
759  }
760 
761 }
762 
763 //-----------------------------------------------------------------------------
764 // Function : Instance::loadNodeSymbols
765 // Purpose :
766 // Special Notes :
767 // Scope : public
768 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
769 // Creation Date : 05/13/05
770 //-----------------------------------------------------------------------------
771 void Instance::loadNodeSymbols(Util::SymbolTable &symbol_table) const
772 {
773  for (int i = 0; i < nSeg; i++)
774  {
775  std::ostringstream segNumber;
776  segNumber << i;
777  addInternalNode(symbol_table, li_Vol[i], getName(), "V" + segNumber.str());
778  addInternalNode(symbol_table, li_nPro[i], getName(), "N" + segNumber.str());
779  addInternalNode(symbol_table, li_mPro[i], getName(), "M" + segNumber.str());
780  addInternalNode(symbol_table, li_hPro[i], getName(), "H" + segNumber.str());
781  addInternalNode(symbol_table, li_aPro[i], getName(), "A" + segNumber.str());
782  addInternalNode(symbol_table, li_bPro[i], getName(), "B" + segNumber.str());
783  addInternalNode(symbol_table, li_MPro[i], getName(), "M_" + segNumber.str());
784  addInternalNode(symbol_table, li_HPro[i], getName(), "H_" + segNumber.str());
785  addInternalNode(symbol_table, li_cPro[i], getName(), "C" + segNumber.str());
786  addInternalNode(symbol_table, li_CaPro[i], getName(), "Ca" + segNumber.str());
787  }
788 }
789 
790 //-----------------------------------------------------------------------------
791 // Function : Instance::registerStateLIDs
792 // Purpose :
793 // Special Notes :
794 // Scope : public
795 // Creator : Richard Schiek, Electrical and Microsytem Modeling
796 // Creation Date : 06/10/09
797 //-----------------------------------------------------------------------------
798 void Instance::registerStateLIDs( const std::vector<int> & staLIDVecRef )
799 {
800  AssertLIDs(staLIDVecRef.size() == numStateVars);
801 
802  // copy over the global ID lists.
803  staLIDVec = staLIDVecRef;
804 
805  for( int i=0, j=0; i<nSeg; i++, j+=2)
806  {
807  li_KCurrentState[i] = staLIDVec[j];
808  li_NaCurrentState[i] = staLIDVec[j+1];
809  }
810 
811 }
812 
813 //-----------------------------------------------------------------------------
814 // Function : Instance::jacobianStamp
815 // Purpose :
816 // Special Notes :
817 // Scope : public
818 // Creator : Richard Schiek, Electrical and Microsytem Modeling
819 // Creation Date : 06/10/09
820 //-----------------------------------------------------------------------------
821 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
822 {
823  return jacStamp;
824 }
825 
826 //-----------------------------------------------------------------------------
827 // Function : Instance::registerJacLIDs
828 // Purpose :
829 // Special Notes :
830 // Scope : public
831 // Creator : Richard Schiek, Electrical and Microsytem Modeling
832 // Creation Date : 06/10/09
833 //-----------------------------------------------------------------------------
834 void Instance::registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec )
835 {
836  DeviceInstance::registerJacLIDs( jacLIDVec );
837 
838  // external terminals
839  APosEquPosNodeOffset = jacLIDVec[0][0];
840  APosEquNextNodeOffset = jacLIDVec[0][1];
841  ANegEquNegNodeOffset = jacLIDVec[1][0];
842  ANegEquLastNodeOffset = jacLIDVec[1][1];
843  /*
844  Xyce::dout() << "APosEquPosNodeOffset = " << APosEquPosNodeOffset << std::endl;
845  Xyce::dout() << "APosEquNextNodeOffset = " << APosEquNextNodeOffset << std::endl;
846  Xyce::dout() << "ANegEquNegNodeOffset = " << ANegEquNegNodeOffset << std::endl;
847  Xyce::dout() << "ANegEquLastNodeOffset = " << ANegEquLastNodeOffset << std::endl;
848  */
849 
850  // internal variables
851  SegVEqnVpreOffset.resize(nSeg);
852  SegVEqnVsegOffset.resize(nSeg);
853  SegVEqnVnexOffset.resize(nSeg);
854  SegVEqnNOffset.resize(nSeg);
855  SegVEqnMOffset.resize(nSeg);
856  SegVEqnHOffset.resize(nSeg);
857  NEquVNodeOffset.resize(nSeg);
858  NEquNNodeOffset.resize(nSeg);
859  MEquVNodeOffset.resize(nSeg);
860  MEquMNodeOffset.resize(nSeg);
861  HEquVNodeOffset.resize(nSeg);
862  HEquHNodeOffset.resize(nSeg);
863  AEquVNodeOffset.resize(nSeg);
864  AEquANodeOffset.resize(nSeg);
865  BEquVNodeOffset.resize(nSeg);
866  BEquBNodeOffset.resize(nSeg);
867  M_EquVNodeOffset.resize(nSeg);
868  M_EquM_NodeOffset.resize(nSeg);
869  H_EquVNodeOffset.resize(nSeg);
870  H_EquH_NodeOffset.resize(nSeg);
871  CEquVNodeOffset.resize(nSeg);
872  CEquCNodeOffset.resize(nSeg);
873  CEquCaNodeOffset.resize(nSeg);
874  CaEquVNodeOffset.resize(nSeg);
875  CaEquM_NodeOffset.resize(nSeg);
876  CaEquH_NodeOffset.resize(nSeg);
877  CaEquCaNodeOffset.resize(nSeg);
878 
879  for(int i=0, j=2; i<nSeg; i++, j+=10 )
880  {
881  SegVEqnVpreOffset[i] = jacLIDVec[j][0];
882  SegVEqnVsegOffset[i] = jacLIDVec[j][1];
883  SegVEqnNOffset[i] = jacLIDVec[j][2];
884  SegVEqnMOffset[i] = jacLIDVec[j][3];
885  SegVEqnHOffset[i] = jacLIDVec[j][4];
886  SegVEqnVnexOffset[i] = jacLIDVec[j][5];
887 
888  NEquVNodeOffset[i] = jacLIDVec[j+1][0];
889  NEquNNodeOffset[i] = jacLIDVec[j+1][1];
890  MEquVNodeOffset[i] = jacLIDVec[j+2][0];
891  MEquMNodeOffset[i] = jacLIDVec[j+2][1];
892  HEquVNodeOffset[i] = jacLIDVec[j+3][0];
893  HEquHNodeOffset[i] = jacLIDVec[j+3][1];
894  AEquVNodeOffset[i] = jacLIDVec[j+4][0];
895  AEquANodeOffset[i] = jacLIDVec[j+4][1];
896  BEquVNodeOffset[i] = jacLIDVec[j+5][0];
897  BEquBNodeOffset[i] = jacLIDVec[j+5][1];
898  M_EquVNodeOffset[i] = jacLIDVec[j+6][0];
899  M_EquM_NodeOffset[i] = jacLIDVec[j+6][1];
900  H_EquVNodeOffset[i] = jacLIDVec[j+7][0];
901  H_EquH_NodeOffset[i] = jacLIDVec[j+7][1];
902  CEquVNodeOffset[i] = jacLIDVec[j+8][0];
903  CEquCNodeOffset[i] = jacLIDVec[j+8][1];
904  CEquCaNodeOffset[i] = jacLIDVec[j+8][2];
905  CaEquVNodeOffset[i] = jacLIDVec[j+9][0];
906  CaEquM_NodeOffset[i] = jacLIDVec[j+9][1];
907  CaEquH_NodeOffset[i] = jacLIDVec[j+9][2];
908  CaEquCaNodeOffset[i] = jacLIDVec[j+9][3];
909 
910  /*
911  Xyce::dout() << SegVEqnVpreOffset[i] << ", "
912  << SegVEqnVsegOffset[i] << ", "
913  << SegVEqnNOffset[i] << ", "
914  << SegVEqnMOffset[i] << ", "
915  << SegVEqnHOffset[i] << ", "
916  << SegVEqnVnexOffset[i] << ", "
917  << NEquVNodeOffset[i] << ", "
918  << NEquNNodeOffset[i] << ", "
919  << MEquVNodeOffset[i] << ", "
920  << MEquMNodeOffset[i] << ", "
921  << HEquVNodeOffset[i] << ", "
922  << HEquHNodeOffset[i] << std::endl;
923  */
924  }
925 }
926 
927 
928 //-----------------------------------------------------------------------------
929 // Function : Instance::updateIntermediateVars
930 // Purpose :
931 // Special Notes :
932 // Scope : public
933 // Creator : Richard Schiek, Electrical and Microsytem Modeling
934 // Creation Date : 06/10/09
935 //-----------------------------------------------------------------------------
937 {
938  bool bsuccess = true;
939 
940  // here we take the current solutions for V1, V2, n, m and h
941  // and use those to calculate all the terms needed for the next
942  // load cycle (F, Q, dFdX, dQdX)
943  Linear::Vector * solVectorPtr = extData.nextSolVectorPtr;
944 
945  double vIn = (*solVectorPtr)[li_Pos];
946  double vOut = (*solVectorPtr)[li_Neg];
947 
948  // take care of the input and output nodes as they are different
949  kcl1Fvalue = gForward[0] * ((*solVectorPtr)[li_Vol[0]] - vIn );
950  dkcl1F_dVin = -gForward[0];
951  dkcl1F_dVs0 = gForward[0];
952  kcl2Fvalue = gBackward[nSeg-1] * ((*solVectorPtr)[li_Vol[nSeg-1]] - vOut );
955 
956  // loop over segments getting all the load and jacobian terms for each segment
957  for( int i=0; i<nSeg; i++ )
958  {
959  // for this segment get the values of the local vars
960  double vSeg = (*solVectorPtr)[li_Vol[i]];
961  double vNext = 0.0;
962  if (i == (nSeg - 1))
963  {
964  vNext = vOut;
965  }
966  else
967  {
968  vNext = (*solVectorPtr)[li_Vol[i+1]];
969  }
970  double vPrev = 0.0;
971  if (i == 0 )
972  {
973  vPrev = vIn;
974  }
975  else
976  {
977  vPrev = (*solVectorPtr)[li_Vol[i-1]];
978  }
979  double nVarSeg = (*solVectorPtr)[li_nPro[i]];
980  double mVarSeg = (*solVectorPtr)[li_mPro[i]];
981  double hVarSeg = (*solVectorPtr)[li_hPro[i]];
982  double aVarSeg = (*solVectorPtr)[li_aPro[i]];
983  double bVarSeg = (*solVectorPtr)[li_bPro[i]];
984  double M_VarSeg = (*solVectorPtr)[li_MPro[i]];
985  double H_VarSeg = (*solVectorPtr)[li_HPro[i]];
986  double cVarSeg = (*solVectorPtr)[li_cPro[i]];
987  double CaVarSeg = (*solVectorPtr)[li_CaPro[i]];
988 
989  // do the voltage equation for this node
990  // get function and derivative values as we go.
991  {
992  // F part
993  // use scoping to avoid lots of similar variable names
994  const int numDeriv = 11;
995  Sacado::Fad::SFad<double,11> vVar ( numDeriv, 0, vSeg );
996  Sacado::Fad::SFad<double,11> vVpr ( numDeriv, 1, vPrev );
997  Sacado::Fad::SFad<double,11> vVne ( numDeriv, 2, vNext );
998  Sacado::Fad::SFad<double,11> nVar ( numDeriv, 3, nVarSeg );
999  Sacado::Fad::SFad<double,11> mVar ( numDeriv, 4, mVarSeg );
1000  Sacado::Fad::SFad<double,11> hVar ( numDeriv, 5, hVarSeg );
1001  Sacado::Fad::SFad<double,11> aVar ( numDeriv, 6, aVarSeg );
1002  Sacado::Fad::SFad<double,11> bVar ( numDeriv, 7, bVarSeg );
1003  Sacado::Fad::SFad<double,11> M_Var( numDeriv, 8, M_VarSeg );
1004  Sacado::Fad::SFad<double,11> H_Var( numDeriv, 9, H_VarSeg );
1005  Sacado::Fad::SFad<double,11> cVar ( numDeriv, 10, cVarSeg );
1006 
1007  // parameters
1008  Sacado::Fad::SFad<double,11> gPrev( gBackward[i] );
1009  Sacado::Fad::SFad<double,11> gNext( gForward[i] );
1010  Sacado::Fad::SFad<double,11> gMemVar( model_.gMem * segArea );
1011  Sacado::Fad::SFad<double,11> vRestVar( model_.vRest );
1012  Sacado::Fad::SFad<double,11> gKVar( model_.gK * segArea );
1013  Sacado::Fad::SFad<double,11> eKVar( model_.eK );
1014  Sacado::Fad::SFad<double,11> gNaVar( model_.gNa * segArea );
1015  Sacado::Fad::SFad<double,11> eNaVar( model_.eNa );
1016  Sacado::Fad::SFad<double,11> gAVar( model_.gA * segArea );
1017  Sacado::Fad::SFad<double,11> eAVar( model_.eA );
1018  Sacado::Fad::SFad<double,11> gCaVar( model_.gCa * segArea );
1019  Sacado::Fad::SFad<double,11> eCaVar( model_.eCa );
1020  Sacado::Fad::SFad<double,11> gKCaVar( model_.gKCa * segArea );
1021  Sacado::Fad::SFad<double,11> CaInitVar( model_.CaInit );
1022  Sacado::Fad::SFad<double,11> CaGammaVar( model_.CaGamma );
1023  Sacado::Fad::SFad<double,11> CaTauVar( model_.CaTau );
1024 
1025  // compute the vaud and derivative terms for KCL 1 F
1026  Sacado::Fad::SFad<double,11> resultFad;
1027  resultFad = kcl1EquF( vVar, vVpr, vVne, nVar, mVar, hVar, aVar, bVar, M_Var, H_Var, cVar, gPrev, gNext, gMemVar, vRestVar, gKVar, eKVar, gNaVar, eNaVar, gAVar, eAVar, gCaVar, eCaVar, gKCaVar);
1028 
1029  segFvalue[i] = resultFad.val();
1030  segF_dV[i] = resultFad.dx(0);
1031  segF_dVp[i] = resultFad.dx(1);
1032  segF_dVn[i] = resultFad.dx(2);
1033  segF_dn[i] = resultFad.dx(3);
1034  segF_dm[i] = resultFad.dx(4);
1035  segF_dh[i] = resultFad.dx(5);
1036  segF_da[i] = resultFad.dx(6);
1037  segF_db[i] = resultFad.dx(7);
1038  segF_dM[i] = resultFad.dx(8);
1039  segF_dH[i] = resultFad.dx(9);
1040  segF_dc[i] = resultFad.dx(10);
1041  }
1042  {
1043  // Q part
1044  const int numDeriv = 1;
1045  Sacado::Fad::SFad<double,1> vVar( numDeriv, 0, vSeg );
1046 
1047  // parameters
1048  Sacado::Fad::SFad<double,1> cMemVar( model_.cMem * segArea );
1049 
1050  Sacado::Fad::SFad<double,1> resultFad;
1051  resultFad = kcl1EquQ( vVar, cMemVar );
1052  segQvalue[i] = resultFad.val();
1053  segQ_dV[i] = resultFad.dx(0);
1054 
1055  }
1056 
1057  // n - equation
1058  {
1059  const int numDeriv = 2;
1060  Sacado::Fad::SFad<double,2> vVar( numDeriv, 0, vSeg );
1061  Sacado::Fad::SFad<double,2> nVar( numDeriv, 1, nVarSeg );
1062  // parameter
1063  Sacado::Fad::SFad<double,2> vRestVar( model_.vRest );
1064 
1065  Sacado::Fad::SFad<double,2> resultFad = nEquF( vVar, nVar, vRestVar);
1066  segNEquFvalue[i] = resultFad.val();
1067  dnF_dV[i] = resultFad.dx(0);
1068  dnF_dn[i] = resultFad.dx(1);
1069  }
1070  {
1071  const int numDeriv = 1;
1072  Sacado::Fad::SFad<double,1> nVar( numDeriv, 0, nVarSeg );
1073 
1074  Sacado::Fad::SFad<double,1> resultFad = nEquQ( nVar );
1075  segNEquQvalue[i] = resultFad.val();
1076  dnQ_dn[i] = resultFad.dx(0);
1077  }
1078 
1079  // m - equation
1080  {
1081  const int numDeriv = 2;
1082  Sacado::Fad::SFad<double,2> vVar( numDeriv, 0, vSeg );
1083  Sacado::Fad::SFad<double,2> mVar( numDeriv, 1, mVarSeg );
1084  // parameter
1085  Sacado::Fad::SFad<double,2> vRestVar( model_.vRest );
1086 
1087  Sacado::Fad::SFad<double,2> resultFad = mEquF( vVar, mVar, vRestVar );
1088  segMEquFvalue[i] = resultFad.val();
1089  dmF_dV[i] = resultFad.dx(0);
1090  dmF_dm[i] = resultFad.dx(1);
1091  }
1092  {
1093  const int numDeriv = 1;
1094  Sacado::Fad::SFad<double,1> mVar( numDeriv, 0, mVarSeg );
1095 
1096  Sacado::Fad::SFad<double,1> resultFad = mEquQ( mVar );
1097  segMEquQvalue[i] = resultFad.val();
1098  dmQ_dm[i] = resultFad.dx(0);
1099  }
1100 
1101  // h - equation
1102  {
1103  const int numDeriv = 2;
1104  Sacado::Fad::SFad<double,2> vVar( numDeriv, 0, vSeg );
1105  Sacado::Fad::SFad<double,2> hVar( numDeriv, 1, hVarSeg );
1106  // parameter
1107  Sacado::Fad::SFad<double,2> vRestVar( model_.vRest );
1108 
1109  Sacado::Fad::SFad<double,2> resultFad = hEquF( vVar, hVar, vRestVar );
1110  segHEquFvalue[i] = resultFad.val();
1111  dhF_dV[i] = resultFad.dx(0);
1112  dhF_dh[i] = resultFad.dx(1);
1113  }
1114  {
1115  const int numDeriv = 1;
1116  Sacado::Fad::SFad<double,1> hVar( numDeriv, 0, hVarSeg );
1117 
1118  Sacado::Fad::SFad<double,1> resultFad = hEquQ( hVar );
1119  segHEquQvalue[i] = resultFad.val();
1120  dhQ_dh[i] = resultFad.dx(0);
1121  }
1122 
1123  // a - equation
1124  {
1125  const int numDeriv = 2;
1126  Sacado::Fad::SFad<double,2> vVar( numDeriv, 0, vSeg );
1127  Sacado::Fad::SFad<double,2> aVar( numDeriv, 1, aVarSeg );
1128  // parameter
1129  Sacado::Fad::SFad<double,2> vRestVar( model_.vRest );
1130 
1131  Sacado::Fad::SFad<double,2> resultFad = aEquF( vVar, aVar, vRestVar );
1132  segAEquFvalue[i] = resultFad.val();
1133  daF_dV[i] = resultFad.dx(0);
1134  daF_da[i] = resultFad.dx(1);
1135  }
1136  {
1137  const int numDeriv = 1;
1138  Sacado::Fad::SFad<double,1> aVar( numDeriv, 0, aVarSeg );
1139 
1140  Sacado::Fad::SFad<double,1> resultFad = aEquQ( aVar );
1141  segAEquQvalue[i] = resultFad.val();
1142  daQ_da[i] = resultFad.dx(0);
1143  }
1144 
1145  // b - equation
1146  {
1147  const int numDeriv = 2;
1148  Sacado::Fad::SFad<double,2> vVar( numDeriv, 0, vSeg );
1149  Sacado::Fad::SFad<double,2> bVar( numDeriv, 1, bVarSeg );
1150  // parameter
1151  Sacado::Fad::SFad<double,2> vRestVar( model_.vRest );
1152 
1153  Sacado::Fad::SFad<double,2> resultFad = bEquF( vVar, bVar, vRestVar );
1154  segBEquFvalue[i] = resultFad.val();
1155  dbF_dV[i] = resultFad.dx(0);
1156  dbF_db[i] = resultFad.dx(1);
1157  }
1158  {
1159  const int numDeriv = 1;
1160  Sacado::Fad::SFad<double,1> bVar( numDeriv, 0, bVarSeg );
1161 
1162  Sacado::Fad::SFad<double,1> resultFad = bEquQ( bVar );
1163  segBEquQvalue[i] = resultFad.val();
1164  dbQ_db[i] = resultFad.dx(0);
1165  }
1166 
1167  // M - equation
1168  {
1169  const int numDeriv = 2;
1170  Sacado::Fad::SFad<double,2> vVar( numDeriv, 0, vSeg );
1171  Sacado::Fad::SFad<double,2> M_Var( numDeriv, 1, M_VarSeg );
1172  // parameter
1173  Sacado::Fad::SFad<double,2> vRestVar( model_.vRest );
1174 
1175  Sacado::Fad::SFad<double,2> resultFad = M_EquF( vVar, M_Var, vRestVar );
1176  segM_EquFvalue[i] = resultFad.val();
1177  dMF_dV[i] = resultFad.dx(0);
1178  dMF_dM[i] = resultFad.dx(1);
1179  }
1180  {
1181  const int numDeriv = 1;
1182  Sacado::Fad::SFad<double,1> M_Var( numDeriv, 0, M_VarSeg );
1183 
1184  Sacado::Fad::SFad<double,1> resultFad = M_EquQ( M_Var );
1185  segM_EquQvalue[i] = resultFad.val();
1186  dMQ_dM[i] = resultFad.dx(0);
1187  }
1188 
1189  // H - equation
1190  {
1191  const int numDeriv = 2;
1192  Sacado::Fad::SFad<double,2> vVar( numDeriv, 0, vSeg );
1193  Sacado::Fad::SFad<double,2> H_Var( numDeriv, 1, H_VarSeg );
1194  // parameter
1195  Sacado::Fad::SFad<double,2> vRestVar( model_.vRest );
1196 
1197  Sacado::Fad::SFad<double,2> resultFad = H_EquF( vVar, H_Var, vRestVar );
1198  segH_EquFvalue[i] = resultFad.val();
1199  dHF_dV[i] = resultFad.dx(0);
1200  dHF_dH[i] = resultFad.dx(1);
1201  }
1202  {
1203  const int numDeriv = 1;
1204  Sacado::Fad::SFad<double,1> H_Var( numDeriv, 0, H_VarSeg );
1205 
1206  Sacado::Fad::SFad<double,1> resultFad = H_EquQ( H_Var );
1207  segH_EquQvalue[i] = resultFad.val();
1208  dHQ_dH[i] = resultFad.dx(0);
1209  }
1210 
1211  // c - equation
1212  {
1213  const int numDeriv = 3;
1214  Sacado::Fad::SFad<double,3> vVar( numDeriv, 0, vSeg );
1215  Sacado::Fad::SFad<double,3> cVar( numDeriv, 1, cVarSeg );
1216  Sacado::Fad::SFad<double,3> CaVar( numDeriv, 2, CaVarSeg );
1217  // parameter
1218  Sacado::Fad::SFad<double,3> vRestVar( model_.vRest );
1219 
1220  Sacado::Fad::SFad<double,3> resultFad = C_EquF( vVar, cVar, CaVar, vRestVar );
1221  segCEquFvalue[i] = resultFad.val();
1222  dcF_dV[i] = resultFad.dx(0);
1223  dcF_dc[i] = resultFad.dx(1);
1224  dcF_dCa[i] = resultFad.dx(2);
1225  }
1226  {
1227  const int numDeriv = 1;
1228  Sacado::Fad::SFad<double,1> cVar( numDeriv, 0, cVarSeg );
1229 
1230  Sacado::Fad::SFad<double,1> resultFad = C_EquQ( cVar );
1231  segCEquQvalue[i] = resultFad.val();
1232  dcQ_dc[i] = resultFad.dx(0);
1233  }
1234 
1235  // Ca - equation
1236  {
1237  const int numDeriv = 4;
1238  Sacado::Fad::SFad<double,4> vVar( numDeriv, 0, vSeg );
1239  Sacado::Fad::SFad<double,4> M_Var( numDeriv, 1, M_VarSeg );
1240  Sacado::Fad::SFad<double,4> H_Var( numDeriv, 2, H_VarSeg );
1241  Sacado::Fad::SFad<double,4> CaVar( numDeriv, 3, CaVarSeg );
1242  // parameter
1243  Sacado::Fad::SFad<double,4> gCaVar( model_.gCa );
1244  Sacado::Fad::SFad<double,4> eCaVar( model_.gCa );
1245  Sacado::Fad::SFad<double,4> CaGammaVar( model_.CaGamma );
1246  Sacado::Fad::SFad<double,4> CaTauVar( model_.CaTau );
1247 
1248  Sacado::Fad::SFad<double,4> resultFad = Ca_EquF( vVar, M_Var, H_Var, CaVar, gCaVar, eCaVar, CaGammaVar, CaTauVar );
1249  segCaEquFvalue[i] = resultFad.val();
1250  dCaF_dV[i] = resultFad.dx(0);
1251  dCaF_dM[i] = resultFad.dx(1);
1252  dCaF_dH[i] = resultFad.dx(2);
1253  dCaF_dCa[i] = resultFad.dx(3);
1254  }
1255  {
1256  const int numDeriv = 1;
1257  Sacado::Fad::SFad<double,1> CaVar( numDeriv, 0, CaVarSeg );
1258 
1259  Sacado::Fad::SFad<double,1> resultFad = Ca_EquQ( CaVar );
1260  segCaEquQvalue[i] = resultFad.val();
1261  dCaQ_dCa[i] = resultFad.dx(0);
1262  }
1263 
1264 
1265  }
1266 
1267 #if 0
1268  //Xyce::dout() << "Instance::updateIntermediateVars()" << std::endl;
1269 
1270  bool bsuccess = true;
1271 
1272  // here we take the current solutions for V1, V2, n, m and h
1273  // and use those to calculate all the terms needed for the next
1274  // load cycle (F, Q, dFdX, dQdX)
1275 
1276  Linear::Vector * solVectorPtr = extData.nextSolVectorPtr;
1277 
1278  // use suffix "now" to to clarify that this for the latest solution
1279  double v1Now = (*solVectorPtr)[li_Pos];
1280  double v2Now = (*solVectorPtr)[li_Neg];
1281  double nNow = (*solVectorPtr)[li_nPro];
1282  double mNow = (*solVectorPtr)[li_mPro];
1283  double hNow = (*solVectorPtr)[li_hPro];
1284  double aNow = (*solVectorPtr)[li_aPro];
1285  double bNow = (*solVectorPtr)[li_bPro];
1286  double M_Now = (*solVectorPtr)[li_M_Pro];
1287  double H_Now = (*solVectorPtr)[li_H_Pro];
1288  double cNow = (*solVectorPtr)[li_cPro];
1289  double CaNow = (*solVectorPtr)[li_CaPro];
1290 
1291  // get function and derivative values
1292  // independent variables
1293  // use scoping to avoid lots of similar variable names
1294  {
1295  Sacado::Fad::SFad<double,10> v1Var( 10, 0, v1Now );
1296  Sacado::Fad::SFad<double,10> v2Var( 10, 1, v2Now );
1297  Sacado::Fad::SFad<double,10> nVar( 10, 2, nNow );
1298  Sacado::Fad::SFad<double,10> mVar( 10, 3, mNow );
1299  Sacado::Fad::SFad<double,10> hVar( 10, 4, hNow );
1300  Sacado::Fad::SFad<double,10> aVar( 10, 5, aNow );
1301  Sacado::Fad::SFad<double,10> bVar( 10, 6, bNow );
1302  Sacado::Fad::SFad<double,10> M_Var( 10, 7, M_Now );
1303  Sacado::Fad::SFad<double,10> H_Var( 10, 8, H_Now );
1304  Sacado::Fad::SFad<double,10> cVar( 10, 9, cNow );
1305 
1306  // parameters from the model that we'll need.
1307  Sacado::Fad::SFad<double,10> gMemVar( model_.gMem );
1308  Sacado::Fad::SFad<double,10> vRestVar( model_.vRest );
1309  Sacado::Fad::SFad<double,10> gKVar( model_.gK );
1310  Sacado::Fad::SFad<double,10> eKVar( model_.eK );
1311  Sacado::Fad::SFad<double,10> gNaVar( model_.gNa );
1312  Sacado::Fad::SFad<double,10> eNaVar( model_.eNa );
1313  Sacado::Fad::SFad<double,10> gAVar( model_.gA );
1314  Sacado::Fad::SFad<double,10> eAVar( model_.eA );
1315  Sacado::Fad::SFad<double,10> gCaVar( model_.gCa );
1316  Sacado::Fad::SFad<double,10> eCaVar( model_.gCa );
1317  Sacado::Fad::SFad<double,10> gKCaVar( model_.gKCa );
1318  Sacado::Fad::SFad<double,10> CaInitVar( model_.CaInit );
1319  Sacado::Fad::SFad<double,10> CaGammaVar( model_.CaGamma );
1320  Sacado::Fad::SFad<double,10> CaTauVar( model_.CaTau );
1321 
1322  // compute the vaud and derivative terms for KCL 1 F
1323  Sacado::Fad::SFad<double,10> resultFad;
1324  resultFad = kcl1EquF( v1Var, v2Var, nVar, mVar, hVar, aVar, bVar, M_Var, H_Var, cVar, gMemVar, vRestVar, gKVar, eKVar, gNaVar, eNaVar, gAVar, eAVar, gCaVar, eCaVar, gKCaVar);
1325  kcl1Fvalue = resultFad.val();
1326  dkcl1F_dV1 = resultFad.dx(0);
1327  dkcl1F_dV2 = resultFad.dx(1);
1328  dkcl1F_dn = resultFad.dx(2);
1329  dkcl1F_dm = resultFad.dx(3);
1330  dkcl1F_dh = resultFad.dx(4);
1331  dkcl1F_da = resultFad.dx(5);
1332  dkcl1F_db = resultFad.dx(6);
1333  dkcl1F_dM = resultFad.dx(7);
1334  dkcl1F_dH = resultFad.dx(8);
1335  dkcl1F_dc = resultFad.dx(9);
1336 
1337  // compute the vaud and derivative terms for KCL 2 F
1338  resultFad = kcl2EquF( v1Var, v2Var, nVar, mVar, hVar, aVar, bVar, M_Var, H_Var, cVar, gMemVar, vRestVar, gKVar, eKVar, gNaVar, eNaVar, gAVar, eAVar, gCaVar, eCaVar, gKCaVar);
1339  kcl2Fvalue = resultFad.val();
1340  dkcl2F_dV1 = resultFad.dx(0);
1341  dkcl2F_dV2 = resultFad.dx(1);
1342  dkcl2F_dn = resultFad.dx(2);
1343  dkcl2F_dm = resultFad.dx(3);
1344  dkcl2F_dh = resultFad.dx(4);
1345  dkcl2F_da = resultFad.dx(5);
1346  dkcl2F_db = resultFad.dx(6);
1347  dkcl2F_dM = resultFad.dx(7);
1348  dkcl2F_dH = resultFad.dx(8);
1349  dkcl2F_dc = resultFad.dx(9);
1350  }
1351 
1352  {
1353  Sacado::Fad::SFad<double,2> v1Var( 2, 0, v1Now );
1354  Sacado::Fad::SFad<double,2> v2Var( 2, 1, v2Now );
1355 
1356  // parameters
1357  Sacado::Fad::SFad<double,2> cMemVar( model_.cMem );
1358 
1359  Sacado::Fad::SFad<double,2> resultFad;
1360  resultFad = kcl1EquQ( v1Var, v2Var, cMemVar );
1361  kcl1Qvalue = resultFad.val();
1362  dkcl1Q_dV1 = resultFad.dx(0);
1363  dkcl1Q_dV2 = resultFad.dx(1);
1364 
1365  resultFad = kcl2EquQ( v1Var, v2Var, cMemVar );
1366  kcl2Qvalue = resultFad.val();
1367  dkcl2Q_dV1 = resultFad.dx(0);
1368  dkcl2Q_dV2 = resultFad.dx(1);
1369  }
1370 
1371  // n - equation
1372  {
1373  Sacado::Fad::SFad<double,2> v1Var( 2, 0, v1Now );
1374  Sacado::Fad::SFad<double,2> nVar( 2, 1, nNow );
1375  // parameter
1376  Sacado::Fad::SFad<double,2> vRestVar( model_.vRest );
1377 
1378  Sacado::Fad::SFad<double,2> resultFad = nEquF( v1Var, nVar, vRestVar);
1379  nEquFvalue = resultFad.val();
1380  dnF_dV1 = resultFad.dx(0);
1381  dnF_dn = resultFad.dx(1);
1382  }
1383 
1384  {
1385  Sacado::Fad::SFad<double,1> nVar( 1, 0, nNow );
1386 
1387  Sacado::Fad::SFad<double,1> resultFad = nEquQ( nVar );
1388  nEquQvalue = resultFad.val();
1389  dnQ_dn = resultFad.dx(0);
1390  }
1391 
1392  // m - equation
1393  {
1394  Sacado::Fad::SFad<double,2> v1Var( 2, 0, v1Now );
1395  Sacado::Fad::SFad<double,2> mVar( 2, 1, mNow );
1396  // parameter
1397  Sacado::Fad::SFad<double,2> vRestVar( model_.vRest );
1398 
1399  Sacado::Fad::SFad<double,2> resultFad = mEquF( v1Var, mVar, vRestVar );
1400  mEquFvalue = resultFad.val();
1401  dmF_dV1 = resultFad.dx(0);
1402  dmF_dm = resultFad.dx(1);
1403  }
1404  {
1405  Sacado::Fad::SFad<double,1> mVar( 1, 0, mNow );
1406 
1407  Sacado::Fad::SFad<double,1> resultFad = mEquQ( mVar );
1408  mEquQvalue = resultFad.val();
1409  dmQ_dm = resultFad.dx(0);
1410  }
1411 
1412  // h - equation
1413  {
1414  Sacado::Fad::SFad<double,2> v1Var( 2, 0, v1Now );
1415  Sacado::Fad::SFad<double,2> hVar( 2, 1, hNow );
1416  // parameter
1417  Sacado::Fad::SFad<double,2> vRestVar( model_.vRest );
1418 
1419  Sacado::Fad::SFad<double,2> resultFad = hEquF( v1Var, hVar, vRestVar );
1420  hEquFvalue = resultFad.val();
1421  dhF_dV1 = resultFad.dx(0);
1422  dhF_dh = resultFad.dx(1);
1423  }
1424  {
1425  Sacado::Fad::SFad<double,1> hVar( 1, 0, hNow );
1426 
1427  Sacado::Fad::SFad<double,1> resultFad = hEquQ( hVar );
1428  hEquQvalue = resultFad.val();
1429  dhQ_dh = resultFad.dx(0);
1430  }
1431 
1432  // a - equation
1433  {
1434  Sacado::Fad::SFad<double,2> v1Var( 2, 0, v1Now );
1435  Sacado::Fad::SFad<double,2> aVar( 2, 1, aNow );
1436  // parameter
1437  Sacado::Fad::SFad<double,2> vRestVar( model_.vRest );
1438 
1439  Sacado::Fad::SFad<double,2> resultFad = aEquF( v1Var, aVar, vRestVar );
1440  aEquFvalue = resultFad.val();
1441  daF_dV1 = resultFad.dx(0);
1442  daF_da = resultFad.dx(1);
1443  }
1444  {
1445  Sacado::Fad::SFad<double,1> aVar( 1, 0, aNow );
1446 
1447  Sacado::Fad::SFad<double,1> resultFad = aEquQ( aVar );
1448  aEquQvalue = resultFad.val();
1449  daQ_da = resultFad.dx(0);
1450  }
1451 
1452  // b - equation
1453  {
1454  Sacado::Fad::SFad<double,2> v1Var( 2, 0, v1Now );
1455  Sacado::Fad::SFad<double,2> bVar( 2, 1, bNow );
1456  // parameter
1457  Sacado::Fad::SFad<double,2> vRestVar( model_.vRest );
1458 
1459  Sacado::Fad::SFad<double,2> resultFad = bEquF( v1Var, bVar, vRestVar );
1460  bEquFvalue = resultFad.val();
1461  dbF_dV1 = resultFad.dx(0);
1462  dbF_db = resultFad.dx(1);
1463  }
1464  {
1465  Sacado::Fad::SFad<double,1> bVar( 1, 0, bNow );
1466 
1467  Sacado::Fad::SFad<double,1> resultFad = aEquQ( bVar );
1468  bEquQvalue = resultFad.val();
1469  dbQ_db = resultFad.dx(0);
1470  }
1471 
1472  // M - equation
1473  {
1474  Sacado::Fad::SFad<double,2> v1Var( 2, 0, v1Now );
1475  Sacado::Fad::SFad<double,2> M_Var( 2, 1, M_Now );
1476  // parameter
1477  Sacado::Fad::SFad<double,2> vRestVar( model_.vRest );
1478 
1479  Sacado::Fad::SFad<double,2> resultFad = M_EquF( v1Var, M_Var, vRestVar );
1480  M_EquFvalue = resultFad.val();
1481  dMF_dV1 = resultFad.dx(0);
1482  dMF_dM = resultFad.dx(1);
1483  }
1484  {
1485  Sacado::Fad::SFad<double,1> M_Var( 1, 0, M_Now );
1486 
1487  Sacado::Fad::SFad<double,1> resultFad = aEquQ( M_Var );
1488  M_EquQvalue = resultFad.val();
1489  dMQ_dM = resultFad.dx(0);
1490  }
1491 
1492  // H - equation
1493  {
1494  Sacado::Fad::SFad<double,2> v1Var( 2, 0, v1Now );
1495  Sacado::Fad::SFad<double,2> H_Var( 2, 1, H_Now );
1496  // parameter
1497  Sacado::Fad::SFad<double,2> vRestVar( model_.vRest );
1498 
1499  Sacado::Fad::SFad<double,2> resultFad = H_EquF( v1Var, H_Var, vRestVar );
1500  H_EquFvalue = resultFad.val();
1501  dHF_dV1 = resultFad.dx(0);
1502  dHF_dH = resultFad.dx(1);
1503  }
1504  {
1505  Sacado::Fad::SFad<double,1> H_Var( 1, 0, H_Now );
1506 
1507  Sacado::Fad::SFad<double,1> resultFad = H_EquQ( H_Var );
1508  H_EquQvalue = resultFad.val();
1509  dHQ_dH = resultFad.dx(0);
1510  }
1511 
1512  // c - equation
1513  {
1514  Sacado::Fad::SFad<double,3> v1Var( 3, 0, v1Now );
1515  Sacado::Fad::SFad<double,3> cVar( 3, 1, cNow );
1516  Sacado::Fad::SFad<double,3> CaVar( 3, 2, CaNow );
1517  // parameter
1518  Sacado::Fad::SFad<double,3> vRestVar( model_.vRest );
1519 
1520  Sacado::Fad::SFad<double,3> resultFad = C_EquF( v1Var, cVar, CaVar, vRestVar );
1521  cEquFvalue = resultFad.val();
1522  dcF_dV1 = resultFad.dx(0);
1523  dcF_dc = resultFad.dx(1);
1524  dcF_dCa = resultFad.dx(2);
1525  }
1526  {
1527  Sacado::Fad::SFad<double,1> cVar( 1, 0, cNow );
1528 
1529  Sacado::Fad::SFad<double,1> resultFad = C_EquQ( cVar );
1530  cEquQvalue = resultFad.val();
1531  dcQ_dc = resultFad.dx(0);
1532  }
1533 
1534  // Ca - equation
1535  {
1536  Sacado::Fad::SFad<double,5> v1Var( 5, 0, v1Now );
1537  Sacado::Fad::SFad<double,5> v2Var( 5, 1, v2Now );
1538  Sacado::Fad::SFad<double,5> M_Var( 5, 2, M_Now );
1539  Sacado::Fad::SFad<double,5> H_Var( 5, 3, H_Now );
1540  Sacado::Fad::SFad<double,5> CaVar( 5, 4, CaNow );
1541 
1542  // parameter
1543  Sacado::Fad::SFad<double,5> gCaVar( model_.gCa );
1544  Sacado::Fad::SFad<double,5> eCaVar( model_.gCa );
1545  Sacado::Fad::SFad<double,5> CaGammaVar( model_.CaGamma );
1546  Sacado::Fad::SFad<double,5> CaTauVar( model_.CaTau );
1547 
1548  Sacado::Fad::SFad<double,5> resultFad = Ca_EquF( v1Var, v2Var, M_Var, H_Var, CaVar, gCaVar, eCaVar, CaGammaVar, CaTauVar );
1549  CaEquFvalue = resultFad.val();
1550  dCaF_dV1 = resultFad.dx(0);
1551  dCaF_dV2 = resultFad.dx(1);
1552  dCaF_dM = resultFad.dx(2);
1553  dCaF_dH = resultFad.dx(3);
1554  dCaF_dCa = resultFad.dx(4);
1555  }
1556  {
1557  Sacado::Fad::SFad<double,1> CaVar( 1, 0, CaNow );
1558 
1559  Sacado::Fad::SFad<double,1> resultFad = Ca_EquQ( CaVar );
1560  CaEquQvalue = resultFad.val();
1561  dCaQ_dCa = resultFad.dx(0);
1562  }
1563  // calculate potassium current
1564  potassiumCurrent = model_.gK * pow(nNow, 4.0) * (v1Now - v2Now - model_.eK);
1565 
1566  // calculate sodium current
1567  sodiumCurrent = model_.gNa * pow(mNow, 3.0) * hNow * (v1Now - v2Now - model_.eNa);
1568 
1569 
1570  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
1571  {
1572  Xyce::dout() << "Instance::updateIntermediateVars()" << std::endl
1573  << "v1 = " << v1Now << std::endl
1574  << "v2 = " << v2Now << std::endl
1575  << "nNow = " << nNow << std::endl
1576  << "mNow = " << mNow << std::endl
1577  << "hNow = " << hNow << std::endl
1578  << "aNow = " << aNow << std::endl
1579  << "bNow = " << bNow << std::endl
1580  << "M_Now = " << M_Now << std::endl
1581  << "H_Now = " << H_Now << std::endl
1582  << "cNow = " << cNow << std::endl
1583  << "CaNow = " << CaNow << std::endl
1584  << "kcl1Fvalue = " << kcl1Fvalue << std::endl
1585  << "dkcl1F_dV1 = " << dkcl1F_dV1 << std::endl
1586  << "dkcl1F_dV2 = " << dkcl1F_dV2 << std::endl
1587  << "dkcl1F_dn = " << dkcl1F_dn << std::endl
1588  << "dkcl1F_dm = " << dkcl1F_dm << std::endl
1589  << "dkcl1F_dh = " << dkcl1F_dh << std::endl
1590  << "kcl2Fvalue = " << kcl2Fvalue << std::endl
1591  << "dkcl2F_dV1 = " << dkcl2F_dV1 << std::endl
1592  << "dkcl2F_dV2 = " << dkcl2F_dV2 << std::endl
1593  << "dkcl2F_dn = " << dkcl2F_dn << std::endl
1594  << "dkcl2F_dm = " << dkcl2F_dm << std::endl
1595  << "dkcl2F_dh = " << dkcl2F_dh << std::endl
1596  << "alphaN = " << alphaN<double>( v1Now ) << std::endl
1597  << "betaN = " << betaN<double>( v1Now ) << std::endl
1598  << "nEquFvalue = " << nEquFvalue << std::endl
1599  << "dnF_dV1 = " << dnF_dV1 << std::endl
1600  << "dnF_dn = " << dnF_dn << std::endl
1601  << "nEquQvalue = " << nEquQvalue << std::endl
1602  << "dnQ_dn = " << dnQ_dn << std::endl
1603  << "alphaM = " << alphaM<double>( v1Now ) << std::endl
1604  << "betaM = " << betaM<double>( v1Now ) << std::endl
1605  << "mEquFvalue = " << mEquFvalue << std::endl
1606  << "dmF_dV1 = " << dmF_dV1 << std::endl
1607  << "dmF_dm = " << dmF_dm << std::endl
1608  << "mEquQvalue = " << mEquQvalue << std::endl
1609  << "dmQ_dm = " << dmQ_dm << std::endl
1610  << "alphaH = " << alphaH<double>( v1Now ) << std::endl
1611  << "betaH = " << betaH<double>( v1Now ) << std::endl
1612  << "hEquFvalue = " << hEquFvalue << std::endl
1613  << "dhF_dV1 = " << dhF_dV1 << std::endl
1614  << "dhF_dh = " << dhF_dh << std::endl
1615  << "hEquQvalue = " << hEquQvalue << std::endl
1616  << "dhQ_dh = " << dhQ_dh << std::endl
1617 
1618  << "aInf = " << aInf<double>( v1Now ) << std::endl
1619  << "aTau = " << aTau<double>( v1Now ) << std::endl
1620  << "aEquFvalue = " << aEquFvalue << std::endl
1621  << "daF_dV1 = " << daF_dV1 << std::endl
1622  << "daF_da = " << daF_da << std::endl
1623  << "aEquQvalue = " << aEquQvalue << std::endl
1624  << "daQ_da = " << daQ_da << std::endl
1625 
1626  << "bInf = " << bInf<double>( v1Now ) << std::endl
1627  << "bTau = " << bTau<double>( v1Now ) << std::endl
1628  << "bEquFvalue = " << bEquFvalue << std::endl
1629  << "dbF_dV1 = " << dbF_dV1 << std::endl
1630  << "dbF_db = " << dbF_db << std::endl
1631  << "bEquQvalue = " << bEquQvalue << std::endl
1632  << "dbQ_db = " << dbQ_db << std::endl
1633 
1634  << "M_Inf = " << M_Inf<double>( v1Now ) << std::endl
1635  << "M_Tau = " << M_Tau<double>( v1Now ) << std::endl
1636  << "M_EquFvalue = " << M_EquFvalue << std::endl
1637  << "dMF_dV1 = " << dMF_dV1 << std::endl
1638  << "dMF_dM = " << dMF_dM << std::endl
1639  << "M_EquQvalue = " << M_EquQvalue << std::endl
1640  << "dMQ_dM = " << dMQ_dM << std::endl
1641 
1642  << "H_Inf = " << H_Inf<double>( v1Now ) << std::endl
1643  << "H_Tau = " << H_Tau<double>( v1Now ) << std::endl
1644  << "H_EquFvalue = " << H_EquFvalue << std::endl
1645  << "dHF_dV1 = " << dHF_dV1 << std::endl
1646  << "dHF_dH = " << dHF_dH << std::endl
1647  << "H_EquQvalue = " << H_EquQvalue << std::endl
1648  << "dHQ_dH = " << dHQ_dH << std::endl
1649 
1650  << "cEquFvalue = " << cEquFvalue << std::endl
1651  << "dcF_dV1 = " << dcF_dV1 << std::endl
1652  << "dcF_dc = " << dcF_dc << std::endl
1653  << "cEquQvalue = " << cEquQvalue << std::endl
1654  << "dcQ_dc = " << dcQ_dc << std::endl
1655 
1656  << "CaEquFvalue = " << CaEquFvalue << std::endl
1657  << "dCaF_dV1 = " << dCaF_dV1 << std::endl
1658  << "dCaF_dV2 = " << dCaF_dV2 << std::endl
1659  << "dCaF_dM = " << dCaF_dM << std::endl
1660  << "dCaF_dH = " << dCaF_dH << std::endl
1661  << "dCaF_dCa = " << dCaF_dCa << std::endl
1662  << "CaEquQvalue = " << CaEquQvalue << std::endl
1663  << "dCaQ_dCa = " << dCaQ_dCa << std::endl
1664 
1665  << std::endl;
1666  }
1667 
1668 #endif
1669  return bsuccess;
1670 }
1671 //-----------------------------------------------------------------------------
1672 // Function : Instance::updatePrimaryState
1673 // Purpose :
1674 // Special Notes :
1675 // Scope : public
1676 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1677 // Creation Date : 06/10/09
1678 //-----------------------------------------------------------------------------
1680 {
1681  bool bsuccess = true;
1682 
1684 
1685  Linear::Vector * solVectorPtr = extData.nextSolVectorPtr;
1686  Linear::Vector * staVectorPtr = extData.nextStaVectorPtr;
1687 
1688  for( int i=0; i<nSeg; i++)
1689  {
1690  (*staVectorPtr)[li_KCurrentState[i]] = potassiumCurrent[i];
1691  (*staVectorPtr)[li_NaCurrentState[i]] = sodiumCurrent[i];
1692  }
1693 
1694  return bsuccess;
1695 }
1696 
1697 //-----------------------------------------------------------------------------
1698 // Function : Instance::updateSecondaryState
1699 // Purpose :
1700 // Special Notes :
1701 // Scope : public
1702 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1703 // Creation Date : 06/10/09
1704 //-----------------------------------------------------------------------------
1706 {
1707  bool bsuccess = true;
1708 
1709  return bsuccess;
1710 }
1711 
1712 //-----------------------------------------------------------------------------
1713 // Function : Instance::loadDAEQVector
1714 //
1715 // Purpose : Loads the Q-vector contributions for a single
1716 // Neuron 4 instance.
1717 //
1718 // Special Notes : The "Q" vector is part of a standard DAE formalism in
1719 // which the system of equations is represented as:
1720 //
1721 // f(x) = dQ(x)/dt + F(x) - B(t) = 0
1722 //
1723 // Scope : public
1724 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1725 // Creation Date : 06/10/09
1726 //-----------------------------------------------------------------------------
1728 {
1729  bool bsuccess = true;
1730 
1731  Linear::Vector * daeQVecPtr = extData.daeQVectorPtr;
1732 
1733  for( int i=0; i<nSeg ; i++)
1734  {
1735  (*daeQVecPtr)[li_Vol[i]] += segQvalue[i];
1736  (*daeQVecPtr)[li_nPro[i]] += segNEquQvalue[i];
1737  (*daeQVecPtr)[li_mPro[i]] += segMEquQvalue[i];
1738  (*daeQVecPtr)[li_hPro[i]] += segHEquQvalue[i];
1739  (*daeQVecPtr)[li_aPro[i]] += segAEquQvalue[i];
1740  (*daeQVecPtr)[li_bPro[i]] += segBEquQvalue[i];
1741  (*daeQVecPtr)[li_MPro[i]] += segM_EquQvalue[i];
1742  (*daeQVecPtr)[li_HPro[i]] += segH_EquQvalue[i];
1743  (*daeQVecPtr)[li_cPro[i]] += segCEquQvalue[i];
1744  (*daeQVecPtr)[li_CaPro[i]] += segCaEquQvalue[i];
1745  }
1746 
1747  return bsuccess;
1748 }
1749 
1750 
1751 
1752 //-----------------------------------------------------------------------------
1753 // Function : Instance::loadDAEFVector
1754 //
1755 // Purpose : Loads the F-vector contributions for a single
1756 // instance.
1757 //
1758 // Special Notes :
1759 //
1760 // Scope : public
1761 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1762 // Creation Date : 06/10/09
1763 //-----------------------------------------------------------------------------
1765 {
1766  bool bsuccess=true;
1767 
1768  Linear::Vector * daeFVecPtr = extData.daeFVectorPtr;
1769 
1770  (*daeFVecPtr)[li_Pos] += kcl1Fvalue;
1771  (*daeFVecPtr)[li_Neg] += kcl2Fvalue;
1772 
1773  for( int i=0; i<nSeg ; i++)
1774  {
1775  (*daeFVecPtr)[li_Vol[i]] += segFvalue[i];
1776  (*daeFVecPtr)[li_nPro[i]] += segNEquFvalue[i];
1777  (*daeFVecPtr)[li_mPro[i]] += segMEquFvalue[i];
1778  (*daeFVecPtr)[li_hPro[i]] += segHEquFvalue[i];
1779  (*daeFVecPtr)[li_aPro[i]] += segAEquFvalue[i];
1780  (*daeFVecPtr)[li_bPro[i]] += segBEquFvalue[i];
1781  (*daeFVecPtr)[li_MPro[i]] += segM_EquFvalue[i];
1782  (*daeFVecPtr)[li_HPro[i]] += segH_EquFvalue[i];
1783  (*daeFVecPtr)[li_cPro[i]] += segCEquFvalue[i];
1784  (*daeFVecPtr)[li_CaPro[i]] += segCaEquFvalue[i];
1785  }
1786 
1787  return bsuccess;
1788 }
1789 
1790 //-----------------------------------------------------------------------------
1791 // Function : Instance::loadDAEdQdx
1792 //
1793 // Purpose : Loads the Q-vector contributions for a single
1794 // instance.
1795 // Scope : public
1796 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1797 // Creation Date : 06/10/09
1798 //-----------------------------------------------------------------------------
1800 {
1801  bool bsuccess = true;
1802 
1803  Linear::Matrix * dQdxMatPtr = extData.dQdxMatrixPtr;
1804 
1805  for( int i=0; i<nSeg ; i++)
1806  {
1807  (*dQdxMatPtr)[li_Vol[i]][SegVEqnVsegOffset[i]] += segQ_dV[i];
1808  (*dQdxMatPtr)[li_nPro[i]][NEquNNodeOffset[i]] += dnQ_dn[i];
1809  (*dQdxMatPtr)[li_mPro[i]][MEquMNodeOffset[i]] += dmQ_dm[i];
1810  (*dQdxMatPtr)[li_hPro[i]][HEquHNodeOffset[i]] += dhQ_dh[i];
1811  (*dQdxMatPtr)[li_aPro[i]][AEquANodeOffset[i]] += daQ_da[i];
1812  (*dQdxMatPtr)[li_bPro[i]][BEquBNodeOffset[i]] += dbQ_db[i];
1813  (*dQdxMatPtr)[li_MPro[i]][M_EquM_NodeOffset[i]] += dMQ_dM[i];
1814  (*dQdxMatPtr)[li_HPro[i]][H_EquH_NodeOffset[i]] += dHQ_dH[i];
1815  (*dQdxMatPtr)[li_cPro[i]][CEquCNodeOffset[i]] += dcQ_dc[i];
1816  (*dQdxMatPtr)[li_CaPro[i]][CaEquCaNodeOffset[i]] += dCaQ_dCa[i];
1817  }
1818 
1819  return bsuccess;
1820 }
1821 
1822 
1823 
1824 //-----------------------------------------------------------------------------
1825 // Function : Instance::loadDAEdFdx ()
1826 //
1827 // Purpose : Loads the F-vector contributions for a single
1828 // Neuron 4 instance.
1829 //
1830 // Special Notes : This is an algebraic constaint.
1831 //
1832 // Scope : public
1833 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1834 // Creation Date : 06/10/09
1835 //-----------------------------------------------------------------------------
1837 {
1838  bool bsuccess = true;
1839 
1840  Linear::Matrix * dFdxMatPtr = extData.dFdxMatrixPtr;
1841 
1842  (*dFdxMatPtr)[li_Pos][APosEquPosNodeOffset] += dkcl1F_dVin;
1843  (*dFdxMatPtr)[li_Pos][APosEquNextNodeOffset] += dkcl1F_dVs0;
1844 
1845  (*dFdxMatPtr)[li_Neg][ANegEquNegNodeOffset] += dkcl2F_dVout;
1846  (*dFdxMatPtr)[li_Neg][ANegEquLastNodeOffset] += dkcl2F_dVsn;
1847 
1848  for( int i=0; i<nSeg ; i++)
1849  {
1850  (*dFdxMatPtr)[li_Vol[i]][SegVEqnVpreOffset[i]] += segF_dVp[i];
1851  (*dFdxMatPtr)[li_Vol[i]][SegVEqnVsegOffset[i]] += segF_dV[i];
1852  (*dFdxMatPtr)[li_Vol[i]][SegVEqnVnexOffset[i]] += segF_dVn[i];
1853  (*dFdxMatPtr)[li_Vol[i]][SegVEqnNOffset[i]] += segF_dn[i];
1854  (*dFdxMatPtr)[li_Vol[i]][SegVEqnMOffset[i]] += segF_dm[i];
1855  (*dFdxMatPtr)[li_Vol[i]][SegVEqnHOffset[i]] += segF_dh[i];
1856 
1857  (*dFdxMatPtr)[li_nPro[i]][NEquVNodeOffset[i]] += dnF_dV[i];
1858  (*dFdxMatPtr)[li_nPro[i]][NEquNNodeOffset[i]] += dnF_dn[i];
1859  (*dFdxMatPtr)[li_mPro[i]][MEquVNodeOffset[i]] += dmF_dV[i];
1860  (*dFdxMatPtr)[li_mPro[i]][MEquMNodeOffset[i]] += dmF_dm[i];
1861  (*dFdxMatPtr)[li_hPro[i]][HEquVNodeOffset[i]] += dhF_dV[i];
1862  (*dFdxMatPtr)[li_hPro[i]][HEquHNodeOffset[i]] += dhF_dh[i];
1863 
1864  (*dFdxMatPtr)[li_aPro[i]][AEquVNodeOffset[i]] += daF_dV[i];
1865  (*dFdxMatPtr)[li_aPro[i]][AEquANodeOffset[i]] += daF_da[i];
1866 
1867  (*dFdxMatPtr)[li_bPro[i]][BEquVNodeOffset[i]] += dbF_dV[i];
1868  (*dFdxMatPtr)[li_bPro[i]][BEquBNodeOffset[i]] += dbF_db[i];
1869 
1870  (*dFdxMatPtr)[li_MPro[i]][M_EquVNodeOffset[i]] += dMF_dV[i];
1871  (*dFdxMatPtr)[li_MPro[i]][M_EquM_NodeOffset[i]] += dMF_dM[i];
1872 
1873  (*dFdxMatPtr)[li_HPro[i]][H_EquVNodeOffset[i]] += dHF_dV[i];
1874  (*dFdxMatPtr)[li_HPro[i]][H_EquH_NodeOffset[i]] += dHF_dH[i];
1875 
1876  (*dFdxMatPtr)[li_cPro[i]][CEquVNodeOffset[i]] += dcF_dV[i];
1877  (*dFdxMatPtr)[li_cPro[i]][CEquCNodeOffset[i]] += dcF_dc[i];
1878  (*dFdxMatPtr)[li_cPro[i]][CEquCaNodeOffset[i]] += dcF_dCa[i];
1879 
1880  (*dFdxMatPtr)[li_CaPro[i]][CaEquVNodeOffset[i]] += dCaF_dV[i];
1881  (*dFdxMatPtr)[li_CaPro[i]][CaEquM_NodeOffset[i]] += dCaF_dM[i];
1882  (*dFdxMatPtr)[li_CaPro[i]][CaEquH_NodeOffset[i]] += dCaF_dH[i];
1883  (*dFdxMatPtr)[li_CaPro[i]][CaEquCaNodeOffset[i]] += dCaF_dCa[i];
1884 
1885  }
1886 
1887  return bsuccess;
1888 }
1889 
1890 //-----------------------------------------------------------------------------
1891 // Function : Instance::setIC
1892 // Purpose :
1893 // Special Notes :
1894 // Scope : public
1895 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1896 // Creation Date : 06/10/09
1897 //-----------------------------------------------------------------------------
1899 {
1900  bool bsuccess = true;
1901 
1902  return bsuccess;
1903 }
1904 
1905 //-----------------------------------------------------------------------------
1906 // Function : Instance::varTypes
1907 // Purpose :
1908 // Special Notes :
1909 // Scope : public
1910 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1911 // Creation Date : 06/10/09
1912 //-----------------------------------------------------------------------------
1913 void Instance::varTypes( std::vector<char> & varTypeVec )
1914 {
1915  //varTypeVec.resize(1);
1916  //varTypeVec[0] = 'I';
1917 }
1918 
1919 
1920 //-----------------------------------------------------------------------------
1921 // Function : Model::processParams
1922 // Purpose :
1923 // Special Notes :
1924 // Scope : public
1925 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1926 // Creation Date : 06/10/09
1927 //-----------------------------------------------------------------------------
1929 {
1930  return true;
1931 }
1932 
1933 //----------------------------------------------------------------------------
1934 // Function : Model::processInstanceParams
1935 // Purpose :
1936 // Special Notes :
1937 // Scope : public
1938 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1939 // Creation Date : 06/10/09
1940 //----------------------------------------------------------------------------
1942 {
1943 
1944  std::vector<Instance*>::iterator iter;
1945  std::vector<Instance*>::iterator first = instanceContainer.begin();
1946  std::vector<Instance*>::iterator last = instanceContainer.end();
1947 
1948  for (iter=first; iter!=last; ++iter)
1949  {
1950  (*iter)->processParams();
1951  }
1952 
1953  return true;
1954 }
1955 
1956 //-----------------------------------------------------------------------------
1957 // Function : Model::Model
1958 // Purpose : block constructor
1959 // Special Notes :
1960 // Scope : public
1961 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1962 // Creation Date : 06/10/09
1963 //-----------------------------------------------------------------------------
1965  const Configuration & configuration,
1966  const ModelBlock & MB,
1967  const FactoryBlock & factory_block)
1968  : DeviceModel(MB, configuration.getModelParameters(), factory_block)
1969 {
1970 
1971  // Set params to constant default values:
1972  setDefaultParams ();
1973 
1974  // Set params according to .model line and constant defaults from metadata:
1975  setModParams (MB.params);
1976 
1977  // Set any non-constant parameter defaults:
1978  //if (!given("TNOM"))
1979  // tnom = getDeviceOptions().tnom;
1980 
1981  // Calculate any parameters specified as expressions:
1983 
1984  // calculate dependent (ie computed) params and check for errors:
1985  processParams ();
1986 }
1987 
1988 //-----------------------------------------------------------------------------
1989 // Function : Model::~Model
1990 // Purpose : destructor
1991 // Special Notes :
1992 // Scope : public
1993 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1994 // Creation Date : 06/10/09
1995 //-----------------------------------------------------------------------------
1997 {
1998  std::vector<Instance*>::iterator iter;
1999  std::vector<Instance*>::iterator first = instanceContainer.begin();
2000  std::vector<Instance*>::iterator last = instanceContainer.end();
2001 
2002  for (iter=first; iter!=last; ++iter)
2003  {
2004  delete (*iter);
2005  }
2006 
2007 }
2008 
2009 // additional Declarations
2010 
2011 //-----------------------------------------------------------------------------
2012 // Function : Model::printOutInstances
2013 // Purpose : debugging tool.
2014 // Special Notes :
2015 // Scope : public
2016 // Creator : Richard Schiek, Electrical and Microsytem Modeling
2017 // Creation Date : 06/10/09
2018 //-----------------------------------------------------------------------------
2019 std::ostream &Model::printOutInstances(std::ostream &os) const
2020 {
2021  std::vector<Instance*>::const_iterator iter;
2022  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
2023  std::vector<Instance*>::const_iterator last = instanceContainer.end();
2024 
2025  int i, isize;
2026  isize = instanceContainer.size();
2027 
2028  os << std::endl;
2029  os << "Number of Neuron instances: " << isize << std::endl;
2030  os << " name=\t\tmodelName\tParameters" << std::endl;
2031  for (i=0, iter=first; iter!=last; ++iter, ++i)
2032  {
2033  os << " " << i << ": " << (*iter)->getName() << "\t";
2034  os << getName();
2035  os << std::endl;
2036  }
2037 
2038  os << std::endl;
2039  return os;
2040 }
2041 
2042 //-----------------------------------------------------------------------------
2043 // Function : Model::forEachInstance
2044 // Purpose :
2045 // Special Notes :
2046 // Scope : public
2047 // Creator : David Baur
2048 // Creation Date : 2/4/2014
2049 //-----------------------------------------------------------------------------
2050 /// Apply a device instance "op" to all instances associated with this
2051 /// model
2052 ///
2053 /// @param[in] op Operator to apply to all instances.
2054 ///
2055 ///
2056 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
2057 {
2058  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
2059  op(*it);
2060 }
2061 
2062 
2063 Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
2064 {
2065 
2066  return new DeviceMaster<Traits>( configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
2067 }
2068 
2070 {
2072  .registerDevice("neuron", 4)
2073  .registerModelType("neuron", 4);
2074 }
2075 
2076 } // namespace Neuron4
2077 } // namespace Device
2078 } // namespace Xyce
const InstanceName & getName() const
static ScalarT bEquQ(const ScalarT &b)
std::vector< double > segHEquFvalue
bool updateTemperature(const double &temp_tmp)
std::vector< double > dmF_dV
std::vector< double > segBEquFvalue
std::vector< int > SegVEqnVsegOffset
std::vector< int > li_NaCurrentState
std::vector< double > dCaQ_dCa
const SolverState & solverState_
std::vector< double > dCaF_dM
bool processInstanceParams()
processInstanceParams
Descriptor & addPar(const char *parName, T default_value, T U::*varPtr)
Adds the parameter description to the parameter map.
Definition: N_DEV_Pars.h:1429
std::vector< double > dMF_dM
std::vector< double > segAEquFvalue
std::vector< double > dnF_dn
std::vector< double > dcF_dV
Linear::Vector * nextSolVectorPtr
Linear::Vector * daeQVectorPtr
std::vector< double > dnQ_dn
Pure virtual class to augment a linear system.
void addInternalNode(Util::SymbolTable &symbol_table, int index, const InstanceName &instance_name, const std::string &lead_name)
std::vector< int > li_KCurrentState
std::vector< int > MEquVNodeOffset
std::vector< double > dcF_dc
std::vector< double > segF_dM
std::vector< Instance * > instanceContainer
std::vector< double > segFvalue
std::vector< double > segH_EquFvalue
#define AssertLIDs(cmp)
std::vector< double > gForward
static ScalarT M_EquQ(const ScalarT &M)
void registerStateLIDs(const std::vector< int > &staLIDVecRef)
static ScalarT nEquQ(const ScalarT &n)
std::vector< double > segF_dn
std::vector< int > CEquCNodeOffset
std::vector< double > dhF_dV
virtual void registerJacLIDs(const JacobianStamp &jacLIDVec)
virtual std::ostream & printOutInstances(std::ostream &os) const
std::vector< int > HEquHNodeOffset
std::vector< int > CaEquVNodeOffset
std::vector< double > dbQ_db
std::vector< int > BEquBNodeOffset
std::vector< double > dcF_dCa
std::vector< double > segM_EquQvalue
std::vector< double > segQ_dV
std::vector< int > CaEquCaNodeOffset
Instance(const Configuration &configuration, const InstanceBlock &IB, Model &Miter, const FactoryBlock &factory_block)
std::vector< int > CaEquM_NodeOffset
std::vector< double > dmQ_dm
std::vector< int > M_EquM_NodeOffset
std::vector< Param > params
Parameters from the line.
std::vector< double > dHF_dV
virtual void forEachInstance(DeviceInstanceOp &op) const
Apply a device instance "op" to all instances associated with this model.
std::vector< int > MEquMNodeOffset
std::vector< double > dmF_dm
std::vector< double > dCaF_dCa
void setParams(const std::vector< Param > &params)
std::vector< int > NEquVNodeOffset
const std::string & getName() const
const std::vector< std::vector< int > > & jacobianStamp() const
std::vector< double > segF_dc
static ScalarT mEquQ(const ScalarT &m)
static ScalarT C_EquQ(const ScalarT &C)
std::vector< double > segNEquQvalue
The FactoryBlock contains parameters needed by the device, instance and model creation functions...
std::vector< double > potassiumCurrent
std::vector< double > segMEquFvalue
static ScalarT hEquQ(const ScalarT &h)
std::vector< double > gBackward
static ScalarT aEquF(const ScalarT &Vn1, const ScalarT &a, const ScalarT &Vrest)
std::vector< double > segF_dh
std::vector< double > segF_db
void varTypes(std::vector< char > &varTypeVec)
const DeviceOptions & deviceOptions_
static ScalarT bEquF(const ScalarT &Vn1, const ScalarT &b, const ScalarT &Vrest)
std::vector< double > segMEquQvalue
std::vector< double > dMF_dV
std::vector< double > segF_dVn
Linear::Vector * nextStaVectorPtr
static Config< T > & addConfiguration()
Adds the device to the Xyce device configuration.
std::vector< double > dCaF_dH
std::vector< double > dbF_dV
std::vector< double > segF_dH
Linear::Matrix * dFdxMatrixPtr
std::vector< double > daF_dV
static ScalarT H_EquQ(const ScalarT &H)
std::vector< double > segF_dVp
static ScalarT aEquQ(const ScalarT &a)
The Device class is an interface for device implementations.
Definition: N_DEV_Device.h:101
static ScalarT kcl1EquQ(const ScalarT &VSeg, const ScalarT &memC)
std::vector< double > segF_dV
std::vector< int > M_EquVNodeOffset
void loadNodeSymbols(Util::SymbolTable &symbol_table) const
Populates and returns the store name map.
std::vector< double > dMQ_dM
std::vector< double > dnF_dV
std::vector< double > segF_dm
Class Configuration contains device configuration data.
static ScalarT mEquF(const ScalarT &Vn1, const ScalarT &m, const ScalarT &Vrest)
std::vector< double > segBEquQvalue
std::vector< int > CEquVNodeOffset
std::vector< double > segH_EquQvalue
std::vector< double > daQ_da
std::vector< int > H_EquVNodeOffset
std::vector< int > AEquANodeOffset
std::vector< int > SegVEqnVnexOffset
std::vector< double > dhQ_dh
static ScalarT kcl2EquQ(const ScalarT &Vn1, const ScalarT &Vn2, const ScalarT &memC)
std::vector< double > segCaEquQvalue
static void loadInstanceParameters(ParametricData< Instance > &instance_parameters)
Definition: N_DEV_Neuron4.C:76
const SolverState & getSolverState() const
std::vector< double > segNEquFvalue
#define M_PI
std::vector< double > dHF_dH
static ScalarT C_EquF(const ScalarT &Vn1, const ScalarT &C, const ScalarT &CaConc, const ScalarT &Vrest)
void registerJacLIDs(const std::vector< std::vector< int > > &jacLIDVec)
static ScalarT nEquF(const ScalarT &Vn1, const ScalarT &n, const ScalarT &Vrest)
std::vector< double > daF_da
Linear::Vector * daeFVectorPtr
std::vector< double > segCEquQvalue
static ScalarT Ca_EquF(const ScalarT &Vn1, const ScalarT &MC, const ScalarT &HC, const ScalarT &Ca, const ScalarT &CaTg, const ScalarT &CaE, const ScalarT &CaGamma, const ScalarT &CaTau)
static Device * factory(const Configuration &configuration, const FactoryBlock &factory_block)
std::vector< double > segAEquQvalue
std::vector< double > sodiumCurrent
std::vector< int > SegVEqnMOffset
std::vector< int > SegVEqnVpreOffset
std::vector< int > CEquCaNodeOffset
std::vector< double > dhF_dh
std::vector< int > AEquVNodeOffset
static ScalarT kcl1EquF(const ScalarT &VSeg, const ScalarT &VSegP, const ScalarT &VSegN, const ScalarT &n, const ScalarT &m, const ScalarT &h, const ScalarT &a, const ScalarT &b, const ScalarT &MC, const ScalarT &HC, const ScalarT &CC, const ScalarT &gPrev, const ScalarT &gNext, const ScalarT &memG, const ScalarT &restV, const ScalarT &Kg, const ScalarT &Ke, const ScalarT &NaG, const ScalarT &NaE, const ScalarT &Ag, const ScalarT &Ae, const ScalarT &CaTg, const ScalarT &CaE, const ScalarT &KCaG)
std::vector< int > SegVEqnHOffset
static ScalarT kcl2EquF(const ScalarT &Vn1, const ScalarT &Vn2, const ScalarT &n, const ScalarT &m, const ScalarT &h, const ScalarT &a, const ScalarT &b, const ScalarT &MC, const ScalarT &HC, const ScalarT &CC, const ScalarT &memG, const ScalarT &restV, const ScalarT &Kg, const ScalarT &Ke, const ScalarT &NaG, const ScalarT &NaE, const ScalarT &Ag, const ScalarT &Ae, const ScalarT &CaTg, const ScalarT &CaE, const ScalarT &KCaG)
std::vector< double > dHQ_dH
std::vector< double > segM_EquFvalue
ModelBlock represents a .MODEL line from the netlist.
std::vector< std::vector< int > > jacStamp
Manages parameter binding for class C.
Definition: N_DEV_Pars.h:214
std::vector< int > HEquVNodeOffset
InstanceBlock represent a device instance line from the netlist.
static ScalarT M_EquF(const ScalarT &Vn1, const ScalarT &M, const ScalarT &Vrest)
std::vector< Param > params
Linear::Matrix * dQdxMatrixPtr
std::vector< double > dCaF_dV
static ScalarT H_EquF(const ScalarT &Vn1, const ScalarT &H, const ScalarT &Vrest)
static ScalarT Ca_EquQ(const ScalarT &Ca)
std::vector< double > segQvalue
std::vector< double > segCaEquFvalue
std::vector< int > H_EquH_NodeOffset
std::vector< double > segHEquQvalue
static void loadModelParameters(ParametricData< Model > &model_parameters)
std::vector< double > segCEquFvalue
std::vector< int > BEquVNodeOffset
static ScalarT hEquF(const ScalarT &Vn1, const ScalarT &h, const ScalarT &Vrest)
std::vector< int > CaEquH_NodeOffset
std::vector< int > SegVEqnNOffset
bool processParams()
processParams
void registerLIDs(const std::vector< int > &intLIDVecRef, const std::vector< int > &extLIDVecRef)
std::vector< double > segF_da
std::vector< double > dbF_db
void setModParams(const std::vector< Param > &params)
std::vector< int > NEquNNodeOffset
std::vector< double > dcQ_dc