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