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