Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_DEV_Neuron7.C
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2 // Copyright Notice
3 //
4 // Copyright 2002 Sandia Corporation. Under the terms
5 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
6 // Government retains certain rights in this software.
7 //
8 // Xyce(TM) Parallel Electrical Simulator
9 // Copyright (C) 2002-2011 Sandia Corporation
10 //
11 // This program is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation, either version 3 of the License, or
14 // (at your option) any later version.
15 //
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 //-----------------------------------------------------------------------------
24 
25 //-------------------------------------------------------------------------
26 // Filename : $RCSfile: N_DEV_Neuron7.C,v $
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: 1.31 $
40 //
41 // Revision Date : $Date: 2014/05/13 14:50:39 $
42 //
43 // Current Owner : $Author: dgbaur $
44 //-------------------------------------------------------------------------
45 
46 #include <Xyce_config.h>
47 
48 #include <N_UTL_Misc.h>
49 
50 #include <N_DEV_DeviceOptions.h>
51 #include <N_DEV_DeviceMaster.h>
52 #include <N_DEV_ExternData.h>
53 #include <N_DEV_MatrixLoadData.h>
54 #include <N_DEV_Neuron7.h>
56 #include <N_DEV_SolverState.h>
57 #include <N_DEV_Message.h>
58 #include <N_ERH_ErrorMgr.h>
59 
60 #include <N_DEV_Neuron.h>
61 
62 #include <N_LAS_Vector.h>
63 #include <N_LAS_Matrix.h>
64 
65 namespace Xyce {
66 namespace Device {
67 
68 
69 namespace Neuron7 {
70 
71 
73 {
74 // Set up map for normal (double) param variables:
75  p.addPar ("MEMC", 0.0, false, ParameterType::NO_DEP,
78  U_FARAD, CAT_NONE, "Membrane capacitance");
79 
80  p.addPar ("VT", 0.0, false, ParameterType::NO_DEP,
83  U_VOLT, CAT_NONE, "Instantaneous threshold voltage");
84 
85  p.addPar ("VR", 0.0, false, ParameterType::NO_DEP,
88  U_VOLT, CAT_NONE, "Resting membrane potential");
89 
90  p.addPar ("VP", 0.0, false, ParameterType::NO_DEP,
93  U_VOLT, CAT_NONE, "Peak voltage");
94 
95  p.addPar ("K", 0.0, false, ParameterType::NO_DEP,
98  U_NONE, CAT_NONE, "instanceing parameter");
99 
100  p.addPar ("A", 0.0, false, ParameterType::NO_DEP,
103  U_NONE, CAT_NONE, "instanceing parameter");
104 
105  p.addPar ("B", 0.0, false, ParameterType::NO_DEP,
108  U_NONE, CAT_NONE, "instanceing parameter");
109 
110  p.addPar ("C", 0.0, false, ParameterType::NO_DEP,
113  U_NONE, CAT_NONE, "instanceing parameter");
114 
115  p.addPar ("D", 0.0, false, ParameterType::NO_DEP,
118  U_NONE, CAT_NONE, "instanceing parameter");
119 
120  p.addPar ("USCALE", 1.0e-9, false, ParameterType::NO_DEP,
123  U_NONE, CAT_NONE, "scaling for u variable");
124 
125  p.addPar ("FALLRATE", 1.0e3, false, ParameterType::NO_DEP,
128  U_NONE, CAT_NONE, "recovery rate");
129 }
130 
132 {
133  p.addPar ("MEMC", 0.0, false, ParameterType::NO_DEP,
136  U_FARAD, CAT_NONE, "Membrane capacitance");
137 
138  p.addPar ("VT", 0.0, false, ParameterType::NO_DEP,
141  U_VOLT, CAT_NONE, "Instantaneous threshold voltage");
142 
143  p.addPar ("VR", 0.0, false, ParameterType::NO_DEP,
146  U_VOLT, CAT_NONE, "Resting membrane potential");
147 
148  p.addPar ("VP", 0.0, false, ParameterType::NO_DEP,
151  U_VOLT, CAT_NONE, "Peak voltage");
152 
153  p.addPar ("K", 0.0, false, ParameterType::NO_DEP,
156  U_NONE, CAT_NONE, "Neuron7::Modeling parameter");
157 
158  p.addPar ("A", 0.0, false, ParameterType::NO_DEP,
161  U_NONE, CAT_NONE, "Neuron7::Modeling parameter");
162 
163  p.addPar ("B", 0.0, false, ParameterType::NO_DEP,
166  U_NONE, CAT_NONE, "Neuron7::Modeling parameter");
167 
168  p.addPar ("C", 0.0, false, ParameterType::NO_DEP,
171  U_NONE, CAT_NONE, "Neuron7::Modeling parameter");
172 
173  p.addPar ("D", 0.0, false, ParameterType::NO_DEP,
176  U_NONE, CAT_NONE, "Neuron7::Modeling parameter");
177 
178  p.addPar ("USCALE", 1.0e-9, false, ParameterType::NO_DEP,
181  U_NONE, CAT_NONE, "scaling for u variable");
182 
183  p.addPar ("FALLRATE", 1.0e3, false, ParameterType::NO_DEP,
186  U_NONE, CAT_NONE, "recovery rate");
187 }
188 
189 
190 
191 //
192 // static class member inits
193 //
194 std::vector< std::vector<int> > Instance::jacStamp;
195 
196 // Class Instance
197 
198 //-----------------------------------------------------------------------------
199 // Function : Instance::Instance
200 // Purpose : constructor
201 // Special Notes :
202 // Scope : public
203 // Creator : Richard Schiek, Electrical and Microsytem Modeling
204 // Creation Date : 06/10/09
205 //-----------------------------------------------------------------------------
207  const Configuration & configuration,
208  const InstanceBlock & IB,
209  Model & Miter,
210  const FactoryBlock & factory_block)
211  : DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
212  model_(Miter),
213  memCap(0.0),
214  Vt(0.0),
215  Vr(0.0),
216  Vpeak(0.0),
217  k(0.0),
218  a(0.0),
219  b(0.0),
220  c(0.0),
221  d(0.0),
222  uscale(1.0e-9),
223  fallRate(1.0e3),
224  memCapGiven(false),
225  VtGiven(false),
226  VrGiven(false),
227  VpeakGiven(false),
228  kGiven(false),
229  aGiven(false),
230  bGiven(false),
231  cGiven(false),
232  dGiven(false),
233  uscaleGiven(false),
234  fallRateGiven(false),
235  vEquFvalue(0.0),
236  vEquQvalue(0.0),
237  vEqudFdv(0.0),
238  vEqudFdu(0.0),
239  vEqudQdv(0.0),
240  uEquFvalue(0.0),
241  uEquQvalue(0.0),
242  uEqudFdv(0.0),
243  uEqudFdu(0.0),
244  uEqudQdu(0.0),
245  resetting(false),
246  uPeak(0.0),
247  li_V(-1),
248  li_U(-1),
249  vEquVOffset(-1),
250  vEquUOffset(-1),
251  uEquVOffset(-1),
252  uEquUOffset(-1)
253 {
254  numExtVars = 1; // membrane voltage
255 
256  // Set params to constant default values:
257  setDefaultParams ();
258 
259  // Set params according to instance line
260  setParams (IB.params);
261 
262  // Set any non-constant parameter defaults:
263 
264  //if (!given("TEMP"))
265  // temp = getDeviceOptions().temp.dVal();
266 
267  // Calculate any parameters specified as expressions:
269 
270  // calculate dependent (ie computed) params and check for errors:
271  processParams ();
272 
273  // pull unspecified params out of the model if they weren't specified here
274  if( !memCapGiven && model_.memCapGiven )
275  {
276  memCap = model_.memCap;
277  memCapGiven = true;
278  }
279  if( !VtGiven && model_.VtGiven )
280  {
281  Vt = model_.Vt;
282  VtGiven = true;
283  }
284  if( !VrGiven && model_.VrGiven )
285  {
286  Vr = model_.Vr;
287  VrGiven = true;
288  }
289  if( !VpeakGiven && model_.VpeakGiven )
290  {
291  Vpeak = model_.Vpeak;
292  VpeakGiven = true;
293  }
294  if( !kGiven && model_.kGiven )
295  {
296  k = model_.k;
297  kGiven = true;
298  }
299  if( !aGiven && model_.aGiven )
300  {
301  a = model_.a;
302  aGiven = true;
303  }
304  if( !bGiven && model_.bGiven )
305  {
306  b = model_.b;
307  bGiven = true;
308  }
309  if( !cGiven && model_.cGiven )
310  {
311  c = model_.c;
312  cGiven = true;
313  }
314  if( !dGiven && model_.dGiven )
315  {
316  d = model_.d;
317  dGiven = true;
318  }
319  if( !uscaleGiven && model_.uscaleGiven )
320  {
321  uscale = model_.uscale;
322  uscaleGiven = true;
323  }
325  {
327  fallRateGiven = true;
328  }
329 
330  /*
331  Xyce::dout() << "Instance::Instance" << std::endl
332  << "memC = " << memCap << std::endl
333  << "Vt = " << Vt << std::endl
334  << "Vr = " << Vr << std::endl
335  << "Vp = " << Vpeak << std::endl
336  << "k = " << k << std::endl
337  << "a = " << a << std::endl
338  << "b = " << b << std::endl
339  << "c = " << c << std::endl
340  << "d = " << d << std::endl
341  << "uscale = " << uscale << std::endl
342  << "fallRate = " << fallRate << std::endl;
343  */
344 
345  numIntVars = 1; // u
346  numStateVars = 0;
347 
348  // total up number of vars.
349  int numVars = numExtVars + numIntVars;
350 
351 
352  //
353  // equations are:
354  // v equation
355  // k * (v-Vr) * (v-Vt) - u + I - C dv/dt = 0
356  // u euqtion
357  // a * ( b * (v-Vr) - u ) - du/dt = 0
358 
359  // df/dx
360  // V u
361  // Vequ 2k V - Vt - Vr -1
362  // Uequ a b -a
363  //
364  // dq/dx
365  // V u
366  // Vequ -memCap 0
367  // Uequ 0 -1
368  //
369  // so jacStamp is dense.
370 
371 
372  // set up jacStamp
373  if( jacStamp.empty() )
374  {
375  jacStamp.resize(2);
376  jacStamp[0].resize(2);
377  jacStamp[0][0] = 0;
378  jacStamp[0][1] = 1;
379  jacStamp[1].resize(2);
380  jacStamp[1][0] = 0;
381  jacStamp[1][1] = 1;
382  }
383 
384  /*
385  // print out jacStamp
386  Xyce::dout() << "jacStamp for Neuron6" << std::endl;
387  int numRows = jacStamp.size();
388  for( int i=0; i< numRows; i++ )
389  {
390  int numCol = jacStamp[i].size();
391  Xyce::dout() << "jacStamp[ " << i << " ] = { ";
392  for(int j=0; j<numCol; j++)
393  {
394  Xyce::dout() << jacStamp[i][j] << " ";
395  }
396  Xyce::dout() << " } " << std::endl;
397  }
398  Xyce::dout() << std::endl;
399  */
400 
401 }
402 
403 //-----------------------------------------------------------------------------
404 // Function : Instance::~Instance
405 // Purpose : destructor
406 // Special Notes :
407 // Scope : public
408 // Creator : Richard Schiek, Electrical and Microsytem Modeling
409 // Creation Date : 06/10/09
410 //-----------------------------------------------------------------------------
412 {
413 }
414 
415 //-----------------------------------------------------------------------------
416 // Function : Instance::processParams
417 // Purpose :
418 // Special Notes :
419 // Scope : public
420 // Creator : Richard Schiek, Electrical and Microsytem Modeling
421 // Creation Date : 06/10/09
422 //-----------------------------------------------------------------------------
424 {
425  // If there are any time dependent parameters, set their values at for
426  // the current time.
427 
428  // now set the temperature related stuff.
429  //updateTemperature(temp);
430 
431  return true;
432 }
433 
434 //-----------------------------------------------------------------------------
435 // Function : Instance::updateTemperature
436 // Purpose :
437 // Special Notes :
438 // Scope : public
439 // Creator : Richard Schiek, Electrical and Microsytem Modeling
440 // Creation Date : 06/10/09
441 //-----------------------------------------------------------------------------
442 bool Instance::updateTemperature ( const double & temp)
443 {
444  bool bsuccess = true;
445  return bsuccess;
446 }
447 
448 //-----------------------------------------------------------------------------
449 // Function : Instance::registerLIDs
450 // Purpose :
451 // Special Notes :
452 // Scope : public
453 // Creator : Richard Schiek, Electrical and Microsytem Modeling
454 // Creation Date : 06/10/09
455 //-----------------------------------------------------------------------------
456 void Instance::registerLIDs(const std::vector<int> & intLIDVecRef,
457  const std::vector<int> & extLIDVecRef)
458 {
459  AssertLIDs(intLIDVecRef.size() == numIntVars);
460  AssertLIDs(extLIDVecRef.size() == numExtVars);
461 
462 #ifdef Xyce_DEBUG_DEVICE
463  if (getDeviceOptions().debugLevel > 0)
464  {
465  Xyce::dout() << std::endl << section_divider << std::endl;
466  Xyce::dout() << " Instance::registerLIDs" << std::endl;
467  Xyce::dout() << " name = " << getName() << std::endl;
468  }
469 #endif
470 
471  // copy over the global ID lists.
472  intLIDVec = intLIDVecRef;
473  extLIDVec = extLIDVecRef;
474 
475  li_V = extLIDVec[0];
476  li_U = intLIDVec[0];
477 
478 #ifdef Xyce_DEBUG_DEVICE
479  if (getDeviceOptions().debugLevel > 0 )
480  {
481  Xyce::dout() << " li_V = " << li_V << std::endl
482  << " li_U = " << li_U << std::endl;
483 
484  }
485 #endif
486 
487 #ifdef Xyce_DEBUG_DEVICE
488  if (getDeviceOptions().debugLevel > 0 )
489  {
490  Xyce::dout() << section_divider << std::endl;
491  }
492 #endif
493 
494 }
495 
496 //-----------------------------------------------------------------------------
497 // Function : Instance::getIntNameMap
498 // Purpose :
499 // Special Notes :
500 // Scope : public
501 // Creator : Richard Schiek, Electrical and Microsytem Modeling
502 // Creation Date : 06/10/09
503 //-----------------------------------------------------------------------------
504 std::map<int,std::string> & Instance::getIntNameMap ()
505 {
506  // set up the internal name map, if it hasn't been already.
507  if (intNameMap.empty ())
508  {
510  }
511 
512  return intNameMap;
513 }
514 
515 //-----------------------------------------------------------------------------
516 // Function : Instance::registerStateLIDs
517 // Purpose :
518 // Special Notes :
519 // Scope : public
520 // Creator : Richard Schiek, Electrical and Microsytem Modeling
521 // Creation Date : 06/10/09
522 //-----------------------------------------------------------------------------
523 void Instance::registerStateLIDs( const std::vector<int> & staLIDVecRef )
524 {
525  AssertLIDs(staLIDVecRef.size() == numStateVars);
526 }
527 
528 //-----------------------------------------------------------------------------
529 // Function : Instance::loadDeviceMask
530 //
531 // Purpose : Loads the zero elements of the device mask
532 //
533 // Special Notes : elements of the error vector associated with zero
534 // elements of the mask will not be included in weighted
535 // norms by the time integrator.
536 //
537 // Scope : public
538 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
539 // Creation Date : 06/10/09
540 //-----------------------------------------------------------------------------
542 {
543  // no masking so return false
544  return false;
545 
546  //bool returnVal=false;
547  //N_LAS_Vector * maskVectorPtr = extData.deviceMaskVectorPtr;
548  //
549  // return (returnVal);
550 }
551 
552 //-----------------------------------------------------------------------------
553 // Function : Instance::jacobianStamp
554 // Purpose :
555 // Special Notes :
556 // Scope : public
557 // Creator : Richard Schiek, Electrical and Microsytem Modeling
558 // Creation Date : 06/10/09
559 //-----------------------------------------------------------------------------
560 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
561 {
562  return jacStamp;
563 }
564 
565 //-----------------------------------------------------------------------------
566 // Function : Instance::registerJacLIDs
567 // Purpose :
568 // Special Notes :
569 // Scope : public
570 // Creator : Richard Schiek, Electrical and Microsytem Modeling
571 // Creation Date : 06/10/09
572 //-----------------------------------------------------------------------------
573 void Instance::registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec )
574 {
575  DeviceInstance::registerJacLIDs( jacLIDVec );
576 
577  vEquVOffset = jacLIDVec[0][0];
578  vEquUOffset = jacLIDVec[0][1];
579  uEquVOffset = jacLIDVec[1][0];
580  uEquUOffset = jacLIDVec[1][1];
581 }
582 
583 
584 //-----------------------------------------------------------------------------
585 // Function : Instance::updateIntermediateVars
586 // Purpose :
587 // Special Notes :
588 // Scope : public
589 // Creator : Richard Schiek, Electrical and Microsytem Modeling
590 // Creation Date : 06/10/09
591 //-----------------------------------------------------------------------------
593 {
594  bool bsuccess = true;
595 
596  // here we take the current solutions for V1, V2, n, m and h
597  // and use those to calculate all the terms needed for the next
598  // load cycle (F, Q, dFdX, dQdX)
599  N_LAS_Vector * solVectorPtr = extData.nextSolVectorPtr;
600 
601  double vVal = (*solVectorPtr)[li_V];
602  double uVal = (*solVectorPtr)[li_U];
603 
604  // not sure if I need to do this as it should just
605  // fall out of the solution when d/dt = 0. Possibly
606  // it doesn't because there are two solutions when d/dt = 0,
607  // either vVal = Vr or vVal = Vt we want vVal=Vr.
608  if( getSolverState().dcopFlag )
609  {
610  // vVal - Vr = 0 and uVal=0
611  vEquFvalue = vVal - Vr;
612  vEquQvalue = - memCap * vVal;
613  vEqudFdv = 1.0;
614  vEqudFdu = 0.0;
615  vEqudQdv = - memCap;
616  uEquFvalue = uVal*uscale;
617  uEquQvalue = -uVal*uscale;
618  uEqudFdv = 0.0;
619  uEqudFdu = 1.0*uscale;
620  uEqudQdu = uscale;
621  }
622  else
623  {
624  // need to cacth case where v> Vpeak
625  if( !resetting && (vVal >= Vpeak) )
626  {
627  resetting = true;
628  uPeak = uVal;
629  // ask the device manager to call a breakpoint at this step (discontinuity step)
630  //extData.devMgrPtr->declareCurrentStepAsBreakpoint();
631  }
632  else
633  {
634  // only break out of the resetting phase at the start of a newton solve
635  if( (getSolverState().newtonIter == 0 ) && (vVal <= (c+0.0001) ) && (uVal >= (uPeak + (d-1.0e-13)/uscale) ))
636  {
637  // reset is done, go back to old form
638  resetting = false;
639  }
640  }
641 
642  if ( resetting )
643  {
644  //extData.devMgrPtr->declareCurrentStepAsBreakpoint();
645 #if 0
646  Xyce::dout() << "In resetting section uPeak + d = " << (uPeak+d*uscale) << " u - (uP +d) = " << (uVal - (uPeak + d*uscale)) << std::endl;
647  // in this case vVal - c = 0 and uVal = uVal + d
648  vEquFvalue = vVal - c;
649  vEquQvalue = 0.0;
650  vEqudFdv = 1.0;
651  vEqudFdu = 0.0;
652  vEqudQdv = 0.0;
653  uEquFvalue = uscale * (uVal - (uPeak + d*uscale));
654  uEquQvalue = 0.0;
655  uEqudFdv = 0.0;
656  uEqudFdu = uscale;
657  uEqudQdu = 0.0;
658  if( vVal <= c )
659  {
660  // reset is done, go back to old form
661  resetting = false;
662  }
663 #endif
664 //#if 0
665 
666  //Xyce::dout() << "In resetting section. (uPeak*uscale + d) = " << (uPeak + d/uscale) << std::endl;
667  vEquFvalue = -fallRate*(vVal - c) - uVal*uscale;
668  vEquQvalue = -memCap* vVal;
669  vEqudFdv = -fallRate;
670  vEqudFdu = -uscale;
671  vEqudQdv = -memCap;
672 
673  uEquFvalue = -fallRate*(uVal - (uPeak + d/uscale) );
674  uEquQvalue = -uVal;
675  uEqudFdv = 0.0;
676  uEqudFdu = -fallRate;
677  uEqudQdu = -1.0;
678 
679 //#endif
680  }
681  else
682  {
683  //Xyce::dout() << "In normal section." << std::endl;
684  vEquFvalue = k * (vVal - Vr) * (vVal - Vt) - uVal*uscale;
685  vEquQvalue = - memCap * vVal;
686  vEqudFdv = k * ( 2*vVal - Vt - Vr);
687  vEqudFdu = -uscale;
688  vEqudQdv = -memCap;
689 
690  uEquFvalue = a * ( b * (vVal - Vr)/uscale - uVal );
691  uEquQvalue = -uVal;
692  uEqudFdv = a * b / uscale;
693  uEqudFdu = -a;
694  uEqudQdu = -1.0;
695  }
696 
697 
698  }
699 
700  /*
701  Xyce::dout() << "Instance::updateIntermediateVars()" << std::endl
702  << "vEquFvalue = " << vEquFvalue << std::endl
703  << "vEquQvalue = " << vEquQvalue << std::endl
704  << "vEqudFdv = " << vEqudFdv << std::endl
705  << "vEqudFdu = " << vEqudFdu << std::endl
706  << "vEqudQdv = " << vEqudQdv << std::endl
707  << "uEquFvalue = " << uEquFvalue << std::endl
708  << "uEquQvalue = " << uEquQvalue << std::endl
709  << "uEqudFdv = " << uEqudFdv << std::endl
710  << "uEqudFdu = " << uEqudFdu << std::endl
711  << "uEqudQdu = " << uEqudQdu << std::endl
712  << "vVal = " << vVal << std::endl
713  << "uVal = " << uVal << std::endl;
714  */
715  return bsuccess;
716 }
717 
718 /*
719  this approach can be problematic if many of these devices are out of
720  phase and issueing breakpoints all the time. Thus, not very workable -- RLS
721 //-----------------------------------------------------------------------------
722 // Function : Instance::getInstanceBreakPoints
723 // Purpose :
724 // Special Notes :
725 // Scope : public
726 // Creator : Richard Schiek, Electrical and Microsytem Modeling
727 // Creation Date : 06/10/09
728 //-----------------------------------------------------------------------------
729 bool Instance::getInstanceBreakPoints(
730 std::vector<N_UTL_BreakPoint> &breakPointTimes)
731 {
732 breakPointTimes.push_back(breakPoint);
733 return true;
734 }
735 */
736 
737 //-----------------------------------------------------------------------------
738 // Function : Instance::updatePrimaryState
739 // Purpose :
740 // Special Notes :
741 // Scope : public
742 // Creator : Richard Schiek, Electrical and Microsytem Modeling
743 // Creation Date : 06/10/09
744 //-----------------------------------------------------------------------------
746 {
747  bool bsuccess = true;
748 
750 
751  return bsuccess;
752 }
753 
754 //-----------------------------------------------------------------------------
755 // Function : Instance::updateSecondaryState
756 // Purpose :
757 // Special Notes :
758 // Scope : public
759 // Creator : Richard Schiek, Electrical and Microsytem Modeling
760 // Creation Date : 06/10/09
761 //-----------------------------------------------------------------------------
763 {
764  bool bsuccess = true;
765 
766  return bsuccess;
767 }
768 
769 //-----------------------------------------------------------------------------
770 // Function : Instance::loadDAEQVector
771 //
772 // Purpose : Loads the Q-vector contributions for a single
773 // Neuron 7 instance.
774 //
775 // Special Notes : The "Q" vector is part of a standard DAE formalism in
776 // which the system of equations is represented as:
777 //
778 // f(x) = dQ(x)/dt + F(x) - B(t) = 0
779 //
780 // Scope : public
781 // Creator : Richard Schiek, Electrical and Microsytem Modeling
782 // Creation Date : 06/10/09
783 //-----------------------------------------------------------------------------
785 {
786  bool bsuccess = true;
787 
788  N_LAS_Vector * daeQVecPtr = extData.daeQVectorPtr;
789  (*daeQVecPtr)[li_V] += vEquQvalue;
790  (*daeQVecPtr)[li_U] += uEquQvalue;
791 
792  return bsuccess;
793 }
794 
795 //-----------------------------------------------------------------------------
796 // Function : Instance::loadDAEFVector
797 //
798 // Purpose : Loads the F-vector contributions for a single
799 // Neuron 7 instance.
800 //
801 // Special Notes :
802 //
803 // Scope : public
804 // Creator : Richard Schiek, Electrical and Microsytem Modeling
805 // Creation Date : 06/10/09
806 //-----------------------------------------------------------------------------
808 {
809  bool bsuccess=true;
810 
811  N_LAS_Vector * daeFVecPtr = extData.daeFVectorPtr;
812 
813  (*daeFVecPtr)[li_V] += vEquFvalue;
814  (*daeFVecPtr)[li_U] += uEquFvalue;
815 
816  return bsuccess;
817 }
818 
819 //-----------------------------------------------------------------------------
820 // Function : Instance::loadDAEdQdx
821 //
822 // Purpose : Loads the Q-vector contributions for a single
823 // Neuron 7 instance.
824 // Scope : public
825 // Creator : Richard Schiek, Electrical and Microsytem Modeling
826 // Creation Date : 06/10/09
827 //-----------------------------------------------------------------------------
829 {
830  bool bsuccess = true;
831 
832  N_LAS_Matrix * dQdxMatPtr = extData.dQdxMatrixPtr;
833 
834  (*dQdxMatPtr)[li_V][vEquVOffset] += vEqudQdv;
835  (*dQdxMatPtr)[li_U][uEquUOffset] += uEqudQdu;
836 
837  return bsuccess;
838 }
839 
840 
841 
842 //-----------------------------------------------------------------------------
843 // Function : Instance::loadDAEdFdx ()
844 //
845 // Purpose : Loads the F-vector contributions for a single
846 // Neuron 7 instance.
847 //
848 // Special Notes : This is an algebraic constaint.
849 //
850 // Scope : public
851 // Creator : Richard Schiek, Electrical and Microsytem Modeling
852 // Creation Date : 06/10/09
853 //-----------------------------------------------------------------------------
855 {
856  bool bsuccess = true;
857 
858  N_LAS_Matrix * dFdxMatPtr = extData.dFdxMatrixPtr;
859 
860  (*dFdxMatPtr)[li_V][vEquVOffset] += vEqudFdv;
861  (*dFdxMatPtr)[li_V][vEquUOffset] += vEqudFdu;
862 
863  (*dFdxMatPtr)[li_U][uEquVOffset] += uEqudFdv;
864  (*dFdxMatPtr)[li_U][uEquUOffset] += uEqudFdu;
865 
866  return bsuccess;
867 }
868 
869 //-----------------------------------------------------------------------------
870 // Function : Instance::setIC
871 // Purpose :
872 // Special Notes :
873 // Scope : public
874 // Creator : Richard Schiek, Electrical and Microsytem Modeling
875 // Creation Date : 06/10/09
876 //-----------------------------------------------------------------------------
878 {
879  bool bsuccess = true;
880 
881  return bsuccess;
882 }
883 
884 //-----------------------------------------------------------------------------
885 // Function : Instance::varTypes
886 // Purpose :
887 // Special Notes :
888 // Scope : public
889 // Creator : Richard Schiek, Electrical and Microsytem Modeling
890 // Creation Date : 06/10/09
891 //-----------------------------------------------------------------------------
892 void Instance::varTypes( std::vector<char> & varTypeVec )
893 {
894  //varTypeVec.resize(1);
895  //varTypeVec[0] = 'I';
896 }
897 
898 
899 //-----------------------------------------------------------------------------
900 // Function : Model::Model
901 // Purpose : block constructor
902 // Special Notes :
903 // Scope : public
904 // Creator : Richard Schiek, Electrical and Microsytem Modeling
905 // Creation Date : 06/10/09
906 //-----------------------------------------------------------------------------
908  const Configuration & configuration,
909  const ModelBlock & MB,
910  const FactoryBlock & factory_block)
911  : DeviceModel(MB, configuration.getModelParameters(), factory_block),
912  memCap(0.0),
913  Vt(0.0),
914  Vr(0.0),
915  Vpeak(0.0),
916  k(0.0),
917  a(0.0),
918  b(0.0),
919  c(0.0),
920  d(0.0),
921  uscale(1.0e-9),
922  fallRate(1.0e3),
923  memCapGiven(false),
924  VtGiven(false),
925  VrGiven(false),
926  VpeakGiven(false),
927  kGiven(false),
928  aGiven(false),
929  bGiven(false),
930  cGiven(false),
931  dGiven(false),
932  uscaleGiven(false),
933  fallRateGiven(false)
934 {
935 
936  /*
937  Xyce::dout() << "Model::Model" << std::endl
938  << "memC = " << memCap << std::endl
939  << "Vt = " << Vt << std::endl
940  << "Vr = " << Vr << std::endl
941  << "Vp = " << Vpeak << std::endl
942  << "k = " << k << std::endl
943  << "a = " << a << std::endl
944  << "b = " << b << std::endl
945  << "c = " << c << std::endl
946  << "d = " << d << std::endl
947  << "uscale = " << uscale << std::endl
948  << "fallRate = " << fallRate << std::endl;
949  */
950 
951  // Set params to constant default values:
952  setDefaultParams ();
953 
954  // Set params according to .model line and constant defaults from metadata:
955  setModParams (MB.params);
956 
957  // Set any non-constant parameter defaults:
958  //if (!given("TNOM"))
959  // tnom = getDeviceOptions().tnom;
960 
961  // Calculate any parameters specified as expressions:
963 
964  // calculate dependent (ie computed) params and check for errors:
965 
966  processParams ();
967 }
968 
969 
970 //-----------------------------------------------------------------------------
971 // Function : Model::~Model
972 // Purpose : destructor
973 // Special Notes :
974 // Scope : public
975 // Creator : Richard Schiek, Electrical and Microsytem Modeling
976 // Creation Date : 06/10/09
977 //-----------------------------------------------------------------------------
979 {
980  std::vector<Instance*>::iterator iter;
981  std::vector<Instance*>::iterator first = instanceContainer.begin();
982  std::vector<Instance*>::iterator last = instanceContainer.end();
983 
984  for (iter=first; iter!=last; ++iter)
985  {
986  delete (*iter);
987  }
988 
989 }
990 
991 // additional Declarations
992 //-----------------------------------------------------------------------------
993 // Function : Model::processParams
994 // Purpose :
995 // Special Notes :
996 // Scope : public
997 // Creator : Richard Schiek, Electrical and Microsytem Modeling
998 // Creation Date : 06/10/09
999 //-----------------------------------------------------------------------------
1001 {
1002  return true;
1003 }
1004 
1005 //----------------------------------------------------------------------------
1006 // Function : Model::processInstanceParams
1007 // Purpose :
1008 // Special Notes :
1009 // Scope : public
1010 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1011 // Creation Date : 06/10/09
1012 //----------------------------------------------------------------------------
1014 {
1015 
1016  std::vector<Instance*>::iterator iter;
1017  std::vector<Instance*>::iterator first = instanceContainer.begin();
1018  std::vector<Instance*>::iterator last = instanceContainer.end();
1019 
1020  for (iter=first; iter!=last; ++iter)
1021  {
1022  (*iter)->processParams();
1023  }
1024 
1025  return true;
1026 }
1027 //-----------------------------------------------------------------------------
1028 // Function : Model::printOutInstances
1029 // Purpose : debugging tool.
1030 // Special Notes :
1031 // Scope : public
1032 // Creator : Richard Schiek, Electrical and Microsytem Modeling
1033 // Creation Date : 06/10/09
1034 //-----------------------------------------------------------------------------
1035 std::ostream &Model::printOutInstances(std::ostream &os) const
1036 {
1037  std::vector<Instance*>::const_iterator iter;
1038  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
1039  std::vector<Instance*>::const_iterator last = instanceContainer.end();
1040 
1041  int i, isize;
1042  isize = instanceContainer.size();
1043 
1044  os << std::endl;
1045  os << "Number of Neuron instances: " << isize << std::endl;
1046  os << " name=\t\tmodelName\tParameters" << std::endl;
1047  for (i=0, iter=first; iter!=last; ++iter, ++i)
1048  {
1049  os << " " << i << ": " << (*iter)->getName() << "\t";
1050  os << getName();
1051  os << std::endl;
1052  }
1053 
1054  os << std::endl;
1055  return os;
1056 }
1057 
1058 //-----------------------------------------------------------------------------
1059 // Function : Model::forEachInstance
1060 // Purpose :
1061 // Special Notes :
1062 // Scope : public
1063 // Creator : David Baur
1064 // Creation Date : 2/4/2014
1065 //-----------------------------------------------------------------------------
1066 /// Apply a device instance "op" to all instances associated with this
1067 /// model
1068 ///
1069 /// @param[in] op Operator to apply to all instances.
1070 ///
1071 ///
1072 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
1073 {
1074  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1075  op(*it);
1076 }
1077 
1078 
1079 Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
1080 {
1081 
1082  return new DeviceMaster<Traits>(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
1083 }
1084 
1086 {
1088  .registerDevice("neuron", 7)
1089  .registerModelType("neuron", 7);
1090 }
1091 
1092 } // namespace Neuron2
1093 } // namespace Device
1094 } // namespace Xyce