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