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.22.2.2 $
40 //
41 // Revision Date : $Date: 2014/03/06 23:33:43 $
42 //
43 // Current Owner : $Author: tvrusso $
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  {
510  std::string tmpstr;
511  tmpstr = getName() + "_" + "U" ;
512  spiceInternalName (tmpstr);
513  Xyce::dout() << tmpstr << std::endl;
514  intNameMap[ li_U ] = tmpstr;
515  }
516 
517  return intNameMap;
518 }
519 
520 //-----------------------------------------------------------------------------
521 // Function : Instance::registerStateLIDs
522 // Purpose :
523 // Special Notes :
524 // Scope : public
525 // Creator : Richard Schiek, Electrical Systems Modeling
526 // Creation Date : 03/08/2012
527 //-----------------------------------------------------------------------------
528 void Instance::registerStateLIDs( const std::vector<int> & staLIDVecRef )
529 {
530  AssertLIDs(staLIDVecRef.size() == numStateVars);
531 }
532 
533 //-----------------------------------------------------------------------------
534 // Function : Instance::loadDeviceMask
535 //
536 // Purpose : Loads the zero elements of the device mask
537 //
538 // Special Notes : elements of the error vector associated with zero
539 // elements of the mask will not be included in weighted
540 // norms by the time integrator.
541 //
542 // Scope : public
543 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
544 // Creation Date : 03/08/2012
545 //-----------------------------------------------------------------------------
547 {
548  // no masking so return false
549  return false;
550 
551  //bool returnVal=false;
552  //N_LAS_Vector * maskVectorPtr = extData.deviceMaskVectorPtr;
553  //
554  // return (returnVal);
555 }
556 
557 //-----------------------------------------------------------------------------
558 // Function : Instance::jacobianStamp
559 // Purpose :
560 // Special Notes :
561 // Scope : public
562 // Creator : Richard Schiek, Electrical Systems Modeling
563 // Creation Date : 03/08/2012
564 //-----------------------------------------------------------------------------
565 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
566 {
567  return jacStamp;
568 }
569 
570 //-----------------------------------------------------------------------------
571 // Function : Instance::registerJacLIDs
572 // Purpose :
573 // Special Notes :
574 // Scope : public
575 // Creator : Richard Schiek, Electrical Systems Modeling
576 // Creation Date : 03/08/2012
577 //-----------------------------------------------------------------------------
578 void Instance::registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec )
579 {
580  DeviceInstance::registerJacLIDs( jacLIDVec );
581 
582  vEquVOffset = jacLIDVec[0][0];
583  vEquUOffset = jacLIDVec[0][1];
584  uEquVOffset = jacLIDVec[1][0];
585  uEquUOffset = jacLIDVec[1][1];
586 }
587 
588 
589 //-----------------------------------------------------------------------------
590 // Function : Instance::updateIntermediateVars
591 // Purpose :
592 // Special Notes :
593 // Scope : public
594 // Creator : Richard Schiek, Electrical Systems Modeling
595 // Creation Date : 03/08/2012
596 //-----------------------------------------------------------------------------
598 {
599  bool bsuccess = true;
600 
601  // here we take the current solutions for V1, V2, n, m and h
602  // and use those to calculate all the terms needed for the next
603  // load cycle (F, Q, dFdX, dQdX)
604  N_LAS_Vector * solVectorPtr = extData.nextSolVectorPtr;
605 
606  double vVal = (*solVectorPtr)[li_V];
607  double uVal = (*solVectorPtr)[li_U];
608 
609  // not sure if I need to do this as it should just
610  // fall out of the solution when d/dt = 0. Possibly
611  // it doesn't because there are two solutions when d/dt = 0,
612  // either vVal = Vr or vVal = Vt we want vVal=Vr.
613  if( getSolverState().dcopFlag )
614  {
615  // vVal - Vr = 0 and uVal=0
616  vEquFvalue = vVal - Vr;
617  vEquQvalue = - memCap * vVal;
618  vEqudFdv = 1.0;
619  vEqudFdu = 0.0;
620  vEqudQdv = - memCap;
621  uEquFvalue = uVal*uscale;
622  uEquQvalue = -uVal*uscale;
623  uEqudFdv = 0.0;
624  uEqudFdu = 1.0*uscale;
625  uEqudQdu = uscale;
626  }
627  else
628  {
629  // need to cacth case where v> Vpeak
630  if( !resetting && (vVal >= Vpeak) )
631  {
632  resetting = true;
633  uPeak = uVal;
634  // ask the device manager to call a breakpoint at this step (discontinuity step)
635  //extData.devMgrPtr->declareCurrentStepAsBreakpoint();
636  }
637  else
638  {
639  // only break out of the resetting phase at the start of a newton solve
640  if( (getSolverState().newtonIter == 0 ) && (vVal <= (c+0.0001) ) && (uVal >= (uPeak + (d-1.0e-13)/uscale) ))
641  {
642  // reset is done, go back to old form
643  resetting = false;
644  }
645  }
646 
647  if ( resetting )
648  {
649  //extData.devMgrPtr->declareCurrentStepAsBreakpoint();
650 #if 0
651  Xyce::dout() << "In resetting section uPeak + d = " << (uPeak+d*uscale) << " u - (uP +d) = " << (uVal - (uPeak + d*uscale)) << std::endl;
652  // in this case vVal - c = 0 and uVal = uVal + d
653  vEquFvalue = vVal - c;
654  vEquQvalue = 0.0;
655  vEqudFdv = 1.0;
656  vEqudFdu = 0.0;
657  vEqudQdv = 0.0;
658  uEquFvalue = uscale * (uVal - (uPeak + d*uscale));
659  uEquQvalue = 0.0;
660  uEqudFdv = 0.0;
661  uEqudFdu = uscale;
662  uEqudQdu = 0.0;
663  if( vVal <= c )
664  {
665  // reset is done, go back to old form
666  resetting = false;
667  }
668 #endif
669 //#if 0
670 
671  //Xyce::dout() << "In resetting section. (uPeak*uscale + d) = " << (uPeak + d/uscale) << std::endl;
672  vEquFvalue = -fallRate*(vVal - c) - uVal*uscale;
673  vEquQvalue = -memCap* vVal;
674  vEqudFdv = -fallRate;
675  vEqudFdu = -uscale;
676  vEqudQdv = -memCap;
677 
678  uEquFvalue = -fallRate*(uVal - (uPeak + d/uscale) );
679  uEquQvalue = -uVal;
680  uEqudFdv = 0.0;
681  uEqudFdu = -fallRate;
682  uEqudQdu = -1.0;
683 
684 //#endif
685  }
686  else
687  {
688  //Xyce::dout() << "In normal section." << std::endl;
689  vEquFvalue = k * (vVal - Vr) * (vVal - Vt) - uVal*uscale;
690  vEquQvalue = - memCap * vVal;
691  vEqudFdv = k * ( 2*vVal - Vt - Vr);
692  vEqudFdu = -uscale;
693  vEqudQdv = -memCap;
694 
695  uEquFvalue = a * ( b * (vVal - Vr)/uscale - uVal );
696  uEquQvalue = -uVal;
697  uEqudFdv = a * b / uscale;
698  uEqudFdu = -a;
699  uEqudQdu = -1.0;
700  }
701 
702 
703  }
704 
705  /*
706  Xyce::dout() << "Instance::updateIntermediateVars()" << std::endl
707  << "vEquFvalue = " << vEquFvalue << std::endl
708  << "vEquQvalue = " << vEquQvalue << std::endl
709  << "vEqudFdv = " << vEqudFdv << std::endl
710  << "vEqudFdu = " << vEqudFdu << std::endl
711  << "vEqudQdv = " << vEqudQdv << std::endl
712  << "uEquFvalue = " << uEquFvalue << std::endl
713  << "uEquQvalue = " << uEquQvalue << std::endl
714  << "uEqudFdv = " << uEqudFdv << std::endl
715  << "uEqudFdu = " << uEqudFdu << std::endl
716  << "uEqudQdu = " << uEqudQdu << std::endl
717  << "vVal = " << vVal << std::endl
718  << "uVal = " << uVal << std::endl;
719  */
720  return bsuccess;
721 }
722 
723 /*
724  this approach can be problematic if many of these devices are out of
725  phase and issueing breakpoints all the time. Thus, not very workable -- RLS
726 //-----------------------------------------------------------------------------
727 // Function : Instance::getInstanceBreakPoints
728 // Purpose :
729 // Special Notes :
730 // Scope : public
731 // Creator : Richard Schiek, Electrical Systems Modeling
732 // Creation Date : 03/08/2012
733 //-----------------------------------------------------------------------------
734 bool Instance::getInstanceBreakPoints(
735 std::vector<N_UTL_BreakPoint> &breakPointTimes)
736 {
737 breakPointTimes.push_back(breakPoint);
738 return true;
739 }
740 */
741 
742 //-----------------------------------------------------------------------------
743 // Function : Instance::updatePrimaryState
744 // Purpose :
745 // Special Notes :
746 // Scope : public
747 // Creator : Richard Schiek, Electrical Systems Modeling
748 // Creation Date : 03/08/2012
749 //-----------------------------------------------------------------------------
751 {
752  bool bsuccess = true;
753 
755 
756  return bsuccess;
757 }
758 
759 //-----------------------------------------------------------------------------
760 // Function : Instance::updateSecondaryState
761 // Purpose :
762 // Special Notes :
763 // Scope : public
764 // Creator : Richard Schiek, Electrical Systems Modeling
765 // Creation Date : 03/08/2012
766 //-----------------------------------------------------------------------------
768 {
769  bool bsuccess = true;
770 
771  return bsuccess;
772 }
773 
774 //-----------------------------------------------------------------------------
775 // Function : Instance::loadDAEQVector
776 //
777 // Purpose : Loads the Q-vector contributions for a single
778 // Neuron 7 instance.
779 //
780 // Special Notes : The "Q" vector is part of a standard DAE formalism in
781 // which the system of equations is represented as:
782 //
783 // f(x) = dQ(x)/dt + F(x) - B(t) = 0
784 //
785 // Scope : public
786 // Creator : Richard Schiek, Electrical Systems Modeling
787 // Creation Date : 03/08/2012
788 //-----------------------------------------------------------------------------
790 {
791  bool bsuccess = true;
792 
793  N_LAS_Vector * daeQVecPtr = extData.daeQVectorPtr;
794  (*daeQVecPtr)[li_V] += vEquQvalue;
795  (*daeQVecPtr)[li_U] += uEquQvalue;
796 
797  return bsuccess;
798 }
799 
800 //-----------------------------------------------------------------------------
801 // Function : Instance::loadDAEFVector
802 //
803 // Purpose : Loads the F-vector contributions for a single
804 // Neuron 7 instance.
805 //
806 // Special Notes :
807 //
808 // Scope : public
809 // Creator : Richard Schiek, Electrical Systems Modeling
810 // Creation Date : 03/08/2012
811 //-----------------------------------------------------------------------------
813 {
814  bool bsuccess=true;
815 
816  N_LAS_Vector * daeFVecPtr = extData.daeFVectorPtr;
817 
818  (*daeFVecPtr)[li_V] += vEquFvalue;
819  (*daeFVecPtr)[li_U] += uEquFvalue;
820 
821  return bsuccess;
822 }
823 
824 //-----------------------------------------------------------------------------
825 // Function : Instance::loadDAEdQdx
826 //
827 // Purpose : Loads the Q-vector contributions for a single
828 // Neuron 7 instance.
829 // Scope : public
830 // Creator : Richard Schiek, Electrical Systems Modeling
831 // Creation Date : 03/08/2012
832 //-----------------------------------------------------------------------------
834 {
835  bool bsuccess = true;
836 
837  N_LAS_Matrix * dQdxMatPtr = extData.dQdxMatrixPtr;
838 
839  (*dQdxMatPtr)[li_V][vEquVOffset] += vEqudQdv;
840  (*dQdxMatPtr)[li_U][uEquUOffset] += uEqudQdu;
841 
842  return bsuccess;
843 }
844 
845 
846 
847 //-----------------------------------------------------------------------------
848 // Function : Instance::loadDAEdFdx ()
849 //
850 // Purpose : Loads the F-vector contributions for a single
851 // Neuron 7 instance.
852 //
853 // Special Notes : This is an algebraic constaint.
854 //
855 // Scope : public
856 // Creator : Richard Schiek, Electrical Systems Modeling
857 // Creation Date : 03/08/2012
858 //-----------------------------------------------------------------------------
860 {
861  bool bsuccess = true;
862 
863  N_LAS_Matrix * dFdxMatPtr = extData.dFdxMatrixPtr;
864 
865  (*dFdxMatPtr)[li_V][vEquVOffset] += vEqudFdv;
866  (*dFdxMatPtr)[li_V][vEquUOffset] += vEqudFdu;
867 
868  (*dFdxMatPtr)[li_U][uEquVOffset] += uEqudFdv;
869  (*dFdxMatPtr)[li_U][uEquUOffset] += uEqudFdu;
870 
871  return bsuccess;
872 }
873 
874 //-----------------------------------------------------------------------------
875 // Function : Instance::setIC
876 // Purpose :
877 // Special Notes :
878 // Scope : public
879 // Creator : Richard Schiek, Electrical Systems Modeling
880 // Creation Date : 03/08/2012
881 //-----------------------------------------------------------------------------
883 {
884  bool bsuccess = true;
885 
886  return bsuccess;
887 }
888 
889 //-----------------------------------------------------------------------------
890 // Function : Instance::varTypes
891 // Purpose :
892 // Special Notes :
893 // Scope : public
894 // Creator : Richard Schiek, Electrical Systems Modeling
895 // Creation Date : 03/08/2012
896 //-----------------------------------------------------------------------------
897 void Instance::varTypes( std::vector<char> & varTypeVec )
898 {
899  //varTypeVec.resize(1);
900  //varTypeVec[0] = 'I';
901 }
902 
903 
904 //-----------------------------------------------------------------------------
905 // Function : Model::Model
906 // Purpose : block constructor
907 // Special Notes :
908 // Scope : public
909 // Creator : Richard Schiek, Electrical Systems Modeling
910 // Creation Date : 03/08/2012
911 //-----------------------------------------------------------------------------
913  const Configuration & configuration,
914  const ModelBlock & MB,
915  const FactoryBlock & factory_block)
916  : DeviceModel(MB, configuration.getModelParameters(), factory_block),
917  memCap(0.0),
918  Vt(0.0),
919  Vr(0.0),
920  Vpeak(0.0),
921  k(0.0),
922  a(0.0),
923  b(0.0),
924  c(0.0),
925  d(0.0),
926  uscale(1.0e-9),
927  fallRate(1.0e3),
928  memCapGiven(false),
929  VtGiven(false),
930  VrGiven(false),
931  VpeakGiven(false),
932  kGiven(false),
933  aGiven(false),
934  bGiven(false),
935  cGiven(false),
936  dGiven(false),
937  uscaleGiven(false),
938  fallRateGiven(false)
939 {
940 
941  /*
942  Xyce::dout() << "Model::Model" << std::endl
943  << "memC = " << memCap << std::endl
944  << "Vt = " << Vt << std::endl
945  << "Vr = " << Vr << std::endl
946  << "Vp = " << Vpeak << std::endl
947  << "k = " << k << std::endl
948  << "a = " << a << std::endl
949  << "b = " << b << std::endl
950  << "c = " << c << std::endl
951  << "d = " << d << std::endl
952  << "uscale = " << uscale << std::endl
953  << "fallRate = " << fallRate << std::endl;
954  */
955 
956  // Set params to constant default values:
957  setDefaultParams ();
958 
959  // Set params according to .model line and constant defaults from metadata:
960  setModParams (MB.params);
961 
962  // Set any non-constant parameter defaults:
963  //if (!given("TNOM"))
964  // tnom = getDeviceOptions().tnom;
965 
966  // Calculate any parameters specified as expressions:
968 
969  // calculate dependent (ie computed) params and check for errors:
970 
971  processParams ();
972 }
973 
974 
975 //-----------------------------------------------------------------------------
976 // Function : Model::~Model
977 // Purpose : destructor
978 // Special Notes :
979 // Scope : public
980 // Creator : Richard Schiek, Electrical Systems Modeling
981 // Creation Date : 03/08/2012
982 //-----------------------------------------------------------------------------
984 {
985  std::vector<Instance*>::iterator iter;
986  std::vector<Instance*>::iterator first = instanceContainer.begin();
987  std::vector<Instance*>::iterator last = instanceContainer.end();
988 
989  for (iter=first; iter!=last; ++iter)
990  {
991  delete (*iter);
992  }
993 
994 }
995 
996 // additional Declarations
997 //-----------------------------------------------------------------------------
998 // Function : Model::processParams
999 // Purpose :
1000 // Special Notes :
1001 // Scope : public
1002 // Creator : Richard Schiek, Electrical Systems Modeling
1003 // Creation Date : 03/08/2012
1004 //-----------------------------------------------------------------------------
1006 {
1007  return true;
1008 }
1009 
1010 //----------------------------------------------------------------------------
1011 // Function : Model::processInstanceParams
1012 // Purpose :
1013 // Special Notes :
1014 // Scope : public
1015 // Creator : Richard Schiek, Electrical Systems Modeling
1016 // Creation Date : 03/08/2012
1017 //----------------------------------------------------------------------------
1019 {
1020 
1021  std::vector<Instance*>::iterator iter;
1022  std::vector<Instance*>::iterator first = instanceContainer.begin();
1023  std::vector<Instance*>::iterator last = instanceContainer.end();
1024 
1025  for (iter=first; iter!=last; ++iter)
1026  {
1027  (*iter)->processParams();
1028  }
1029 
1030  return true;
1031 }
1032 //-----------------------------------------------------------------------------
1033 // Function : Model::printOutInstances
1034 // Purpose : debugging tool.
1035 // Special Notes :
1036 // Scope : public
1037 // Creator : Richard Schiek, Electrical Systems Modeling
1038 // Creation Date : 03/08/2012
1039 //-----------------------------------------------------------------------------
1040 std::ostream &Model::printOutInstances(std::ostream &os) const
1041 {
1042  std::vector<Instance*>::const_iterator iter;
1043  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
1044  std::vector<Instance*>::const_iterator last = instanceContainer.end();
1045 
1046  int i, isize;
1047  isize = instanceContainer.size();
1048 
1049  os << std::endl;
1050  os << "Number of Neuron instances: " << isize << std::endl;
1051  os << " name=\t\tmodelName\tParameters" << std::endl;
1052  for (i=0, iter=first; iter!=last; ++iter, ++i)
1053  {
1054  os << " " << i << ": " << (*iter)->getName() << "\t";
1055  os << getName();
1056  os << std::endl;
1057  }
1058 
1059  os << std::endl;
1060  return os;
1061 }
1062 
1063 //-----------------------------------------------------------------------------
1064 // Function : Model::forEachInstance
1065 // Purpose :
1066 // Special Notes :
1067 // Scope : public
1068 // Creator : David Baur
1069 // Creation Date : 2/4/2014
1070 //-----------------------------------------------------------------------------
1071 /// Apply a device instance "op" to all instances associated with this
1072 /// model
1073 ///
1074 /// @param[in] op Operator to apply to all instances.
1075 ///
1076 ///
1077 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
1078 {
1079  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1080  op(*it);
1081 }
1082 
1083 
1084 Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
1085 {
1086 
1087  return new DeviceMaster<Traits>(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
1088 }
1089 
1091 {
1093  .registerDevice("neuron", 8)
1094  .registerModelType("neuron", 8);
1095 }
1096 
1097 } // namespace Neuron8
1098 } // namespace Device
1099 } // namespace Xyce