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